2 * Copyright (c) 2009 The NetBSD Foundation, Inc.
5 * This code is derived from software contributed to The NetBSD Foundation
6 * by Alistair Crooks (agc@NetBSD.org)
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
17 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
18 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
19 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
20 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
21 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
22 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
23 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
24 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
25 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
26 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27 * POSSIBILITY OF SUCH DAMAGE.
30 * Copyright (c) 2005-2008 Nominet UK (www.nic.uk)
31 * All rights reserved.
32 * Contributors: Ben Laurie, Rachel Willmer. The Contributors have asserted
33 * their moral rights under the UK Copyright Design and Patents Act 1988 to
34 * be recorded as the authors of this copyright work.
36 * Licensed under the Apache License, Version 2.0 (the "License"); you may not
37 * use this file except in compliance with the License.
39 * You may obtain a copy of the License at
40 * http://www.apache.org/licenses/LICENSE-2.0
42 * Unless required by applicable law or agreed to in writing, software
43 * distributed under the License is distributed on an "AS IS" BASIS,
44 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
46 * See the License for the specific language governing permissions and
47 * limitations under the License.
52 #ifdef HAVE_SYS_CDEFS_H
53 #include <sys/cdefs.h>
56 #if defined(__NetBSD__)
57 __COPYRIGHT("@(#) Copyright (c) 2009 The NetBSD Foundation, Inc. All rights reserved.");
58 __RCSID("$NetBSD: verify.c,v 1.1 2009/06/09 00:51:03 agc Exp $");
61 #include <sys/types.h>
63 #include <sys/param.h>
65 #ifdef HAVE_SYS_RESOURCE_H
66 #include <sys/resource.h>
71 #ifdef HAVE_OPENSSL_AES_H
72 #include <openssl/aes.h>
75 #ifdef HAVE_OPENSSL_CAST_H
76 #include <openssl/cast.h>
79 #ifdef HAVE_OPENSSL_DES_H
80 #include <openssl/des.h>
83 #ifdef HAVE_OPENSSL_DSA_H
84 #include <openssl/dsa.h>
87 #ifdef HAVE_OPENSSL_ERR_H
88 #include <openssl/err.h>
91 #ifdef HAVE_OPENSSL_IDEA_H
92 #include <openssl/idea.h>
95 #ifdef HAVE_OPENSSL_MD5_H
96 #include <openssl/md5.h>
99 #ifdef HAVE_OPENSSL_SHA_H
100 #include <openssl/sha.h>
104 #ifdef HAVE_COMMONCRYPTO_COMMONDIGEST_H
105 #undef MD5_DIGEST_LENGTH
106 #undef SHA_DIGEST_LENGTH
107 #define COMMON_DIGEST_FOR_OPENSSL 1
108 #include <CommonCrypto/CommonDigest.h>
111 #ifdef HAVE_OPENSSL_RAND_H
112 #include <openssl/rand.h>
115 #ifdef HAVE_OPENSSL_RSA_H
116 #include <openssl/rsa.h>
125 #ifdef HAVE_INTTYPES_H
126 #include <inttypes.h>
148 /* external interface */
151 #ifndef NETPGP_AUTOCONF_VERSION
152 #define NETPGP_AUTOCONF_VERSION PACKAGE_VERSION
155 #ifndef NETPGP_MAINTAINER
156 #define NETPGP_MAINTAINER PACKAGE_BUGREPORT
159 /* don't use some digest algorithms */
163 /* development versions have .99 suffix */
164 #define NETPGP_BASE_VERSION "1.99.9"
166 #define NETPGP_VERSION_CAT(a, b) "NetPGP portable " a "/[" b "]"
167 #define NETPGP_VERSION_STRING \
168 NETPGP_VERSION_CAT(NETPGP_BASE_VERSION, NETPGP_AUTOCONF_VERSION)
172 #define OPS_SHA1_HASH_SIZE SHA_DIGEST_LENGTH
173 #define OPS_SHA256_HASH_SIZE SHA256_DIGEST_LENGTH
174 #define OPS_CHECKHASH_SIZE OPS_SHA1_HASH_SIZE
178 MAX_PASSPHRASE_LENGTH
= 256
189 /* if this is defined, we'll use mmap in preference to file ops */
190 #define USE_MMAP_FOR_FILES 1
192 /* for silencing unused parameter warnings */
193 #define __OPS_USED(x) /*LINTED*/(void)&(x)
196 #define __UNCONST(a) ((void *)(unsigned long)(const void *)(a))
199 /* number of elements in an array */
200 #define NETPGP_BUFSIZ 8192
202 /* this struct describes an area of memory allocated/mmapped */
203 typedef struct __ops_memory_t
{
204 uint8_t *buf
; /* pointer to memory */
205 size_t length
; /* length of memory */
206 size_t allocated
; /* size, if allocated */
207 unsigned mmapped
; /* whether buf is mmap-ed */
210 /* Remember to add names to map in errors.c */
212 OPS_E_OK
= 0x0000, /* no error */
213 OPS_E_FAIL
= 0x0001, /* general error */
214 OPS_E_SYSTEM_ERROR
= 0x0002, /* system error, look at errno for
216 OPS_E_UNIMPLEMENTED
= 0x0003, /* feature not yet implemented */
219 OPS_E_R
= 0x1000, /* general reader error */
220 OPS_E_R_READ_FAILED
= OPS_E_R
+ 1,
221 OPS_E_R_EARLY_EOF
= OPS_E_R
+ 2,
222 OPS_E_R_BAD_FORMAT
= OPS_E_R
+ 3, /* For example, malformed
224 OPS_E_R_UNSUPPORTED
= OPS_E_R
+ 4,
225 OPS_E_R_UNCONSUMED_DATA
= OPS_E_R
+ 5,
228 OPS_E_W
= 0x2000, /* general writer error */
229 OPS_E_W_WRITE_FAILED
= OPS_E_W
+ 1,
230 OPS_E_W_WRITE_TOO_SHORT
= OPS_E_W
+ 2,
233 OPS_E_P
= 0x3000, /* general parser error */
234 OPS_E_P_NOT_ENOUGH_DATA
= OPS_E_P
+ 1,
235 OPS_E_P_UNKNOWN_TAG
= OPS_E_P
+ 2,
236 OPS_E_P_PACKET_CONSUMED
= OPS_E_P
+ 3,
237 OPS_E_P_MPI_FORMAT_ERROR
= OPS_E_P
+ 4,
238 OPS_E_P_PACKET_NOT_CONSUMED
= OPS_E_P
+ 5,
239 OPS_E_P_DECOMPRESSION_ERROR
= OPS_E_P
+ 6,
240 OPS_E_P_NO_USERID
= OPS_E_P
+ 7,
243 OPS_E_C
= 0x4000, /* general creator error */
245 /* validation errors */
246 OPS_E_V
= 0x5000, /* general validation error */
247 OPS_E_V_BAD_SIGNATURE
= OPS_E_V
+ 1,
248 OPS_E_V_NO_SIGNATURE
= OPS_E_V
+ 2,
249 OPS_E_V_UNKNOWN_SIGNER
= OPS_E_V
+ 3,
250 OPS_E_V_BAD_HASH
= OPS_E_V
+ 4,
252 /* Algorithm support errors */
253 OPS_E_ALG
= 0x6000, /* general algorithm error */
254 OPS_E_ALG_UNSUPPORTED_SYMMETRIC_ALG
= OPS_E_ALG
+ 1,
255 OPS_E_ALG_UNSUPPORTED_PUBLIC_KEY_ALG
= OPS_E_ALG
+ 2,
256 OPS_E_ALG_UNSUPPORTED_SIGNATURE_ALG
= OPS_E_ALG
+ 3,
257 OPS_E_ALG_UNSUPPORTED_HASH_ALG
= OPS_E_ALG
+ 4,
258 OPS_E_ALG_UNSUPPORTED_COMPRESS_ALG
= OPS_E_ALG
+ 5,
260 /* Protocol errors */
261 OPS_E_PROTO
= 0x7000, /* general protocol error */
262 OPS_E_PROTO_BAD_SYMMETRIC_DECRYPT
= OPS_E_PROTO
+ 2,
263 OPS_E_PROTO_UNKNOWN_SS
= OPS_E_PROTO
+ 3,
264 OPS_E_PROTO_CRITICAL_SS_IGNORED
= OPS_E_PROTO
+ 4,
265 OPS_E_PROTO_BAD_PUBLIC_KEY_VRSN
= OPS_E_PROTO
+ 5,
266 OPS_E_PROTO_BAD_SIGNATURE_VRSN
= OPS_E_PROTO
+ 6,
267 OPS_E_PROTO_BAD_ONE_PASS_SIG_VRSN
= OPS_E_PROTO
+ 7,
268 OPS_E_PROTO_BAD_PKSK_VRSN
= OPS_E_PROTO
+ 8,
269 OPS_E_PROTO_DECRYPTED_MSG_WRONG_LEN
= OPS_E_PROTO
+ 9,
270 OPS_E_PROTO_BAD_SK_CHECKSUM
= OPS_E_PROTO
+ 10
273 /** one entry in a linked list of errors */
274 typedef struct __ops_error_t
{
275 __ops_errcode_t errcode
;
276 int sys_errno
; /* if errcode is OPS_E_SYSTEM_ERROR */
280 struct __ops_error_t
*next
;
283 #define OPS_SYSTEM_ERROR_1(err,code,sys,fmt,arg) do { \
284 __ops_push_error(err,OPS_E_SYSTEM_ERROR,errno,__FILE__,__LINE__,sys);\
285 __ops_push_error(err,code,0,__FILE__,__LINE__,fmt,arg); \
286 } while(/*CONSTCOND*/0)
288 #define OPS_MEMORY_ERROR(err) { \
289 loggit("Memory error"); \
290 } /* \todo placeholder for better error
292 #define OPS_ERROR(err,code,fmt) do { \
293 __ops_push_error(err,code,0,__FILE__,__LINE__,fmt); \
294 } while(/*CONSTCOND*/0)
295 #define OPS_ERROR_1(err,code,fmt,arg) do { \
296 __ops_push_error(err,code,0,__FILE__,__LINE__,fmt,arg); \
297 } while(/*CONSTCOND*/0)
298 #define OPS_ERROR_2(err,code,fmt,arg,arg2) do { \
299 __ops_push_error(err,code,0,__FILE__,__LINE__,fmt,arg,arg2); \
300 } while(/*CONSTCOND*/0)
301 #define OPS_ERROR_3(err,code,fmt,arg,arg2,arg3) do { \
302 __ops_push_error(err,code,0,__FILE__,__LINE__,fmt,arg,arg2,arg3); \
303 } while(/*CONSTCOND*/0)
304 #define OPS_ERROR_4(err,code,fmt,arg,arg2,arg3,arg4) do { \
305 __ops_push_error(err,code,0,__FILE__,__LINE__,fmt,arg,arg2,arg3,arg4); \
306 } while(/*CONSTCOND*/0)
308 /** General-use structure for variable-length data
311 typedef struct __ops_data_t
{
314 uint8_t mmapped
; /* contents need an munmap(2) */
317 /************************************/
318 /* Packet Tags - RFC4880, 4.2 */
319 /************************************/
321 /** Packet Tag - Bit 7 Mask (this bit is always set).
322 * The first byte of a packet is the "Packet Tag". It always
323 * has bit 7 set. This is the mask for it.
327 #define OPS_PTAG_ALWAYS_SET 0x80
329 /** Packet Tag - New Format Flag.
330 * Bit 6 of the Packet Tag is the packet format indicator.
331 * If it is set, the new format is used, if cleared the
332 * old format is used.
336 #define OPS_PTAG_NEW_FORMAT 0x40
339 /** Old Packet Format: Mask for content tag.
340 * In the old packet format bits 5 to 2 (including)
341 * are the content tag. This is the mask to apply
342 * to the packet tag. Note that you need to
343 * shift by #OPS_PTAG_OF_CONTENT_TAG_SHIFT bits.
347 #define OPS_PTAG_OF_CONTENT_TAG_MASK 0x3c
348 /** Old Packet Format: Offset for the content tag.
349 * As described at #OPS_PTAG_OF_CONTENT_TAG_MASK the
350 * content tag needs to be shifted after being masked
351 * out from the Packet Tag.
355 #define OPS_PTAG_OF_CONTENT_TAG_SHIFT 2
356 /** Old Packet Format: Mask for length type.
357 * Bits 1 and 0 of the packet tag are the length type
358 * in the old packet format.
360 * See #__ops_ptag_oldlen_t for the meaning of the values.
364 #define OPS_PTAG_OF_LENGTH_TYPE_MASK 0x03
367 /** Old Packet Format Lengths.
368 * Defines the meanings of the 2 bits for length type in the
374 OPS_PTAG_OLD_LEN_1
= 0x00, /* Packet has a 1 byte length -
375 * header is 2 bytes long. */
376 OPS_PTAG_OLD_LEN_2
= 0x01, /* Packet has a 2 byte length -
377 * header is 3 bytes long. */
378 OPS_PTAG_OLD_LEN_4
= 0x02, /* Packet has a 4 byte
379 * length - header is 5 bytes
381 OPS_PTAG_OLD_LEN_INDETERMINATE
= 0x03 /* Packet has a
382 * indeterminate length. */
383 } __ops_ptag_oldlen_t
;
386 /** New Packet Format: Mask for content tag.
387 * In the new packet format the 6 rightmost bits
388 * are the content tag. This is the mask to apply
389 * to the packet tag. Note that you need to
390 * shift by #OPS_PTAG_NF_CONTENT_TAG_SHIFT bits.
394 #define OPS_PTAG_NF_CONTENT_TAG_MASK 0x3f
395 /** New Packet Format: Offset for the content tag.
396 * As described at #OPS_PTAG_NF_CONTENT_TAG_MASK the
397 * content tag needs to be shifted after being masked
398 * out from the Packet Tag.
402 #define OPS_PTAG_NF_CONTENT_TAG_SHIFT 0
404 /* PTag Content Tags */
405 /***************************/
407 /** Package Tags (aka Content Tags) and signature subpacket types.
408 * This enumerates all rfc-defined packet tag values and the
409 * signature subpacket type values that we understand.
412 * \see RFC4880 5.2.3.1
415 OPS_PTAG_CT_RESERVED
= 0, /* Reserved - a packet tag must
416 * not have this value */
417 OPS_PTAG_CT_PK_SESSION_KEY
= 1, /* Public-Key Encrypted Session
419 OPS_PTAG_CT_SIGNATURE
= 2, /* Signature Packet */
420 OPS_PTAG_CT_SK_SESSION_KEY
= 3, /* Symmetric-Key Encrypted Session
422 OPS_PTAG_CT_1_PASS_SIG
= 4, /* One-Pass Signature
424 OPS_PTAG_CT_SECRET_KEY
= 5, /* Secret Key Packet */
425 OPS_PTAG_CT_PUBLIC_KEY
= 6, /* Public Key Packet */
426 OPS_PTAG_CT_SECRET_SUBKEY
= 7, /* Secret Subkey Packet */
427 OPS_PTAG_CT_COMPRESSED
= 8, /* Compressed Data Packet */
428 OPS_PTAG_CT_SE_DATA
= 9,/* Symmetrically Encrypted Data Packet */
429 OPS_PTAG_CT_MARKER
= 10,/* Marker Packet */
430 OPS_PTAG_CT_LITDATA
= 11, /* Literal Data Packet */
431 OPS_PTAG_CT_TRUST
= 12, /* Trust Packet */
432 OPS_PTAG_CT_USER_ID
= 13, /* User ID Packet */
433 OPS_PTAG_CT_PUBLIC_SUBKEY
= 14, /* Public Subkey Packet */
434 OPS_PTAG_CT_RESERVED2
= 15, /* reserved */
435 OPS_PTAG_CT_RESERVED3
= 16, /* reserved */
436 OPS_PTAG_CT_USER_ATTR
= 17, /* User Attribute Packet */
437 OPS_PTAG_CT_SE_IP_DATA
= 18, /* Sym. Encrypted and Integrity
438 * Protected Data Packet */
439 OPS_PTAG_CT_MDC
= 19, /* Modification Detection Code Packet */
441 OPS_PARSER_PTAG
= 0x100,/* Internal Use: The packet is the "Packet
442 * Tag" itself - used when callback sends
444 OPS_PTAG_RAW_SS
= 0x101,/* Internal Use: content is raw sig subtag */
445 OPS_PTAG_SS_ALL
= 0x102,/* Internal Use: select all subtags */
446 OPS_PARSER_PACKET_END
= 0x103,
448 /* signature subpackets (0x200-2ff) (type+0x200) */
449 /* only those we can parse are listed here */
450 OPS_PTAG_SIG_SUBPKT_BASE
= 0x200, /* Base for signature
451 * subpacket types - All
452 * signature type values
453 * are relative to this
455 OPS_PTAG_SS_CREATION_TIME
= 0x200 + 2, /* signature creation time */
456 OPS_PTAG_SS_EXPIRATION_TIME
= 0x200 + 3, /* signature
459 OPS_PTAG_SS_EXPORT_CERT
= 0x200 + 4, /* exportable certification */
460 OPS_PTAG_SS_TRUST
= 0x200 + 5, /* trust signature */
461 OPS_PTAG_SS_REGEXP
= 0x200 + 6, /* regular expression */
462 OPS_PTAG_SS_REVOCABLE
= 0x200 + 7, /* revocable */
463 OPS_PTAG_SS_KEY_EXPIRY
= 0x200 + 9, /* key expiration
465 OPS_PTAG_SS_RESERVED
= 0x200 + 10, /* reserved */
466 OPS_PTAG_SS_PREFERRED_SKA
= 0x200 + 11, /* preferred symmetric
468 OPS_PTAG_SS_REVOCATION_KEY
= 0x200 + 12, /* revocation key */
469 OPS_PTAG_SS_ISSUER_KEY_ID
= 0x200 + 16, /* issuer key ID */
470 OPS_PTAG_SS_NOTATION_DATA
= 0x200 + 20, /* notation data */
471 OPS_PTAG_SS_PREFERRED_HASH
= 0x200 + 21, /* preferred hash
473 OPS_PTAG_SS_PREF_COMPRESS
= 0x200 + 22, /* preferred
476 OPS_PTAG_SS_KEYSERV_PREFS
= 0x200 + 23, /* key server
478 OPS_PTAG_SS_PREF_KEYSERV
= 0x200 + 24, /* Preferred Key
480 OPS_PTAG_SS_PRIMARY_USER_ID
= 0x200 + 25, /* primary User ID */
481 OPS_PTAG_SS_POLICY_URI
= 0x200 + 26, /* Policy URI */
482 OPS_PTAG_SS_KEY_FLAGS
= 0x200 + 27, /* key flags */
483 OPS_PTAG_SS_SIGNERS_USER_ID
= 0x200 + 28, /* Signer's User ID */
484 OPS_PTAG_SS_REVOCATION_REASON
= 0x200 + 29, /* reason for
486 OPS_PTAG_SS_FEATURES
= 0x200 + 30, /* features */
487 OPS_PTAG_SS_SIGNATURE_TARGET
= 0x200 + 31, /* signature target */
488 OPS_PTAG_SS_EMBEDDED_SIGNATURE
= 0x200 + 32, /* embedded signature */
490 OPS_PTAG_SS_USERDEFINED00
= 0x200 + 100, /* internal or
492 OPS_PTAG_SS_USERDEFINED01
= 0x200 + 101,
493 OPS_PTAG_SS_USERDEFINED02
= 0x200 + 102,
494 OPS_PTAG_SS_USERDEFINED03
= 0x200 + 103,
495 OPS_PTAG_SS_USERDEFINED04
= 0x200 + 104,
496 OPS_PTAG_SS_USERDEFINED05
= 0x200 + 105,
497 OPS_PTAG_SS_USERDEFINED06
= 0x200 + 106,
498 OPS_PTAG_SS_USERDEFINED07
= 0x200 + 107,
499 OPS_PTAG_SS_USERDEFINED08
= 0x200 + 108,
500 OPS_PTAG_SS_USERDEFINED09
= 0x200 + 109,
501 OPS_PTAG_SS_USERDEFINED10
= 0x200 + 110,
503 /* pseudo content types */
504 OPS_PTAG_CT_LITDATA_HEADER
= 0x300,
505 OPS_PTAG_CT_LITDATA_BODY
= 0x300 + 1,
506 OPS_PTAG_CT_SIGNATURE_HEADER
= 0x300 + 2,
507 OPS_PTAG_CT_SIGNATURE_FOOTER
= 0x300 + 3,
508 OPS_PTAG_CT_ARMOUR_HEADER
= 0x300 + 4,
509 OPS_PTAG_CT_ARMOUR_TRAILER
= 0x300 + 5,
510 OPS_PTAG_CT_SIGNED_CLEARTEXT_HEADER
= 0x300 + 6,
511 OPS_PTAG_CT_SIGNED_CLEARTEXT_BODY
= 0x300 + 7,
512 OPS_PTAG_CT_SIGNED_CLEARTEXT_TRAILER
= 0x300 + 8,
513 OPS_PTAG_CT_UNARMOURED_TEXT
= 0x300 + 9,
514 OPS_PTAG_CT_ENCRYPTED_SECRET_KEY
= 0x300 + 10, /* In this case the
518 OPS_PTAG_CT_SE_DATA_HEADER
= 0x300 + 11,
519 OPS_PTAG_CT_SE_DATA_BODY
= 0x300 + 12,
520 OPS_PTAG_CT_SE_IP_DATA_HEADER
= 0x300 + 13,
521 OPS_PTAG_CT_SE_IP_DATA_BODY
= 0x300 + 14,
522 OPS_PTAG_CT_ENCRYPTED_PK_SESSION_KEY
= 0x300 + 15,
524 /* commands to the callback */
525 OPS_GET_PASSPHRASE
= 0x400,
526 OPS_GET_SECKEY
= 0x400 + 1,
529 OPS_PARSER_ERROR
= 0x500, /* Internal Use: Parser Error */
530 OPS_PARSER_ERRCODE
= 0x500 + 1 /* Internal Use: Parser Error
531 * with errcode returned */
532 } __ops_content_tag_t
;
534 /** Structure to hold one parse error string. */
535 typedef struct __ops_parser_error_t
{
536 const char *error
; /* error message. */
537 } __ops_parser_error_t
;
539 /** Structure to hold one error code */
540 typedef struct __ops_parser_errcode_t
{
541 __ops_errcode_t errcode
;
542 } __ops_parser_errcode_t
;
544 /** Structure to hold one packet tag.
547 typedef struct __ops_ptag_t
{
548 unsigned new_format
; /* Whether this packet tag is new
549 * (1) or old format (0) */
550 unsigned type
; /* content_tag value - See
551 * #__ops_content_tag_t for meanings */
552 __ops_ptag_oldlen_t lentype
; /* Length type (#__ops_ptag_oldlen_t)
553 * - only if this packet tag is old
554 * format. Set to 0 if new format. */
555 unsigned length
; /* The length of the packet. This value
556 * is set when we read and compute the length
557 * information, not at the same moment we
558 * create the packet tag structure. Only
559 * defined if #readc is set. *//* XXX: Ben, is this correct? */
560 unsigned position
; /* The position (within the
561 * current reader) of the packet */
562 unsigned size
; /* number of bits */
565 /** Public Key Algorithm Numbers.
566 * OpenPGP assigns a unique Algorithm Number to each algorithm that is part of OpenPGP.
568 * This lists algorithm numbers for public key algorithms.
573 OPS_PKA_RSA
= 1, /* RSA (Encrypt or Sign) */
574 OPS_PKA_RSA_ENCRYPT_ONLY
= 2, /* RSA Encrypt-Only (deprecated -
575 * \see RFC4880 13.5) */
576 OPS_PKA_RSA_SIGN_ONLY
= 3, /* RSA Sign-Only (deprecated -
577 * \see RFC4880 13.5) */
578 OPS_PKA_ELGAMAL
= 16, /* Elgamal (Encrypt-Only) */
579 OPS_PKA_DSA
= 17, /* DSA (Digital Signature Algorithm) */
580 OPS_PKA_RESERVED_ELLIPTIC_CURVE
= 18, /* Reserved for Elliptic
582 OPS_PKA_RESERVED_ECDSA
= 19, /* Reserved for ECDSA */
583 OPS_PKA_ELGAMAL_ENCRYPT_OR_SIGN
= 20, /* Deprecated. */
584 OPS_PKA_RESERVED_DH
= 21, /* Reserved for Diffie-Hellman
585 * (X9.42, as defined for
587 OPS_PKA_PRIVATE00
= 100,/* Private/Experimental Algorithm */
588 OPS_PKA_PRIVATE01
= 101,/* Private/Experimental Algorithm */
589 OPS_PKA_PRIVATE02
= 102,/* Private/Experimental Algorithm */
590 OPS_PKA_PRIVATE03
= 103,/* Private/Experimental Algorithm */
591 OPS_PKA_PRIVATE04
= 104,/* Private/Experimental Algorithm */
592 OPS_PKA_PRIVATE05
= 105,/* Private/Experimental Algorithm */
593 OPS_PKA_PRIVATE06
= 106,/* Private/Experimental Algorithm */
594 OPS_PKA_PRIVATE07
= 107,/* Private/Experimental Algorithm */
595 OPS_PKA_PRIVATE08
= 108,/* Private/Experimental Algorithm */
596 OPS_PKA_PRIVATE09
= 109,/* Private/Experimental Algorithm */
597 OPS_PKA_PRIVATE10
= 110 /* Private/Experimental Algorithm */
598 } __ops_pubkey_alg_t
;
600 /** Structure to hold one DSA public key params.
604 typedef struct __ops_dsa_pubkey_t
{
605 BIGNUM
*p
; /* DSA prime p */
606 BIGNUM
*q
; /* DSA group order q */
607 BIGNUM
*g
; /* DSA group generator g */
608 BIGNUM
*y
; /* DSA public key value y (= g^x mod p
609 * with x being the secret) */
610 } __ops_dsa_pubkey_t
;
612 /** Structure to hold an RSA public key.
616 typedef struct __ops_rsa_pubkey_t
{
617 BIGNUM
*n
; /* RSA public modulus n */
618 BIGNUM
*e
; /* RSA public encryption exponent e */
619 } __ops_rsa_pubkey_t
;
621 /** Structure to hold an ElGamal public key params.
625 typedef struct __ops_elgamal_pubkey_t
{
626 BIGNUM
*p
; /* ElGamal prime p */
627 BIGNUM
*g
; /* ElGamal group generator g */
628 BIGNUM
*y
; /* ElGamal public key value y (= g^x mod p
629 * with x being the secret) */
630 } __ops_elgamal_pubkey_t
;
632 /** Union to hold public key params of any algorithm */
634 __ops_dsa_pubkey_t dsa
; /* A DSA public key */
635 __ops_rsa_pubkey_t rsa
; /* An RSA public key */
636 __ops_elgamal_pubkey_t elgamal
; /* An ElGamal public key */
637 } __ops_pubkey_union_t
;
640 * OpenPGP has two different protocol versions: version 3 and version 4.
645 OPS_V2
= 2, /* Version 2 (essentially the same as v3) */
646 OPS_V3
= 3, /* Version 3 */
647 OPS_V4
= 4 /* Version 4 */
650 /** Structure to hold a pgp public key */
651 typedef struct __ops_pubkey_t
{
652 __ops_version_t version
;/* version of the key (v3, v4...) */
654 /* when the key was created. Note that
655 * interpretation varies with key version. */
657 /* validity period of the key in days since
658 * creation. A value of 0 has a special meaning
659 * indicating this key does not expire. Only used with
661 __ops_pubkey_alg_t alg
; /* Public Key Algorithm type */
662 __ops_pubkey_union_t key
; /* Public Key Parameters */
665 /** Structure to hold data for one RSA secret key
667 typedef struct __ops_rsa_seckey_t
{
672 } __ops_rsa_seckey_t
;
674 /** __ops_dsa_seckey_t */
675 typedef struct __ops_dsa_seckey_t
{
677 } __ops_dsa_seckey_t
;
679 /** __ops_seckey_union_t */
680 typedef union __ops_seckey_union_t
{
681 __ops_rsa_seckey_t rsa
;
682 __ops_dsa_seckey_t dsa
;
683 } __ops_seckey_union_t
;
689 OPS_S2KU_ENCRYPTED_AND_HASHED
= 254,
690 OPS_S2KU_ENCRYPTED
= 255
698 OPS_S2KS_ITERATED_AND_SALTED
= 3
699 } __ops_s2k_specifier_t
;
701 /** Symmetric Key Algorithm Numbers.
702 * OpenPGP assigns a unique Algorithm Number to each algorithm that is
705 * This lists algorithm numbers for symmetric key algorithms.
710 OPS_SA_PLAINTEXT
= 0, /* Plaintext or unencrypted data */
711 OPS_SA_IDEA
= 1, /* IDEA */
712 OPS_SA_TRIPLEDES
= 2, /* TripleDES */
713 OPS_SA_CAST5
= 3, /* CAST5 */
714 OPS_SA_BLOWFISH
= 4, /* Blowfish */
715 OPS_SA_AES_128
= 7, /* AES with 128-bit key (AES) */
716 OPS_SA_AES_192
= 8, /* AES with 192-bit key */
717 OPS_SA_AES_256
= 9, /* AES with 256-bit key */
718 OPS_SA_TWOFISH
= 10 /* Twofish with 256-bit key (TWOFISH) */
721 /** Hashing Algorithm Numbers.
722 * OpenPGP assigns a unique Algorithm Number to each algorithm that is
725 * This lists algorithm numbers for hash algorithms.
730 OPS_HASH_UNKNOWN
= -1, /* used to indicate errors */
731 OPS_HASH_MD5
= 1, /* MD5 */
732 OPS_HASH_SHA1
= 2, /* SHA-1 */
733 OPS_HASH_RIPEMD
= 3, /* RIPEMD160 */
735 OPS_HASH_SHA256
= 8, /* SHA256 */
737 OPS_HASH_SHA384
= 9, /* SHA384 */
739 OPS_HASH_SHA512
= 10, /* SHA512 */
741 OPS_HASH_SHA224
= 11 /* SHA224 */
746 /* Maximum block size for symmetric crypto */
747 #define OPS_MAX_BLOCK_SIZE 16
749 /* Maximum key size for symmetric crypto */
750 #define OPS_MAX_KEY_SIZE 32
752 /* Salt size for hashing */
753 #define OPS_SALT_SIZE 8
756 #define OPS_MAX_HASH_SIZE 64
760 typedef struct __ops_seckey_t
{
761 __ops_pubkey_t pubkey
;
762 __ops_s2k_usage_t s2k_usage
;
763 __ops_s2k_specifier_t s2k_specifier
;
764 __ops_symm_alg_t alg
;
765 __ops_hash_alg_t hash_alg
;
766 uint8_t salt
[OPS_SALT_SIZE
];
768 uint8_t iv
[OPS_MAX_BLOCK_SIZE
];
769 __ops_seckey_union_t key
;
774 /** Structure to hold one trust packet's data */
776 typedef struct __ops_trust_t
{
777 __ops_data_t data
; /* Trust Packet */
780 /** Structure to hold one user id */
781 typedef struct __ops_userid_t
{
782 uint8_t *userid
;/* User ID - UTF-8 string */
785 /** Structure to hold one user attribute */
786 typedef struct __ops_userattr_t
{
787 __ops_data_t data
; /* User Attribute */
791 * OpenPGP defines different signature types that allow giving
792 * different meanings to signatures. Signature types include 0x10 for
793 * generitc User ID certifications (used when Ben signs Weasel's key),
794 * Subkey binding signatures, document signatures, key revocations,
797 * Different types are used in different places, and most make only
798 * sense in their intended location (for instance a subkey binding has
799 * no place on a UserID).
804 OPS_SIG_BINARY
= 0x00, /* Signature of a binary document */
805 OPS_SIG_TEXT
= 0x01, /* Signature of a canonical text document */
806 OPS_SIG_STANDALONE
= 0x02, /* Standalone signature */
808 OPS_CERT_GENERIC
= 0x10,/* Generic certification of a User ID and
809 * Public Key packet */
810 OPS_CERT_PERSONA
= 0x11,/* Persona certification of a User ID and
811 * Public Key packet */
812 OPS_CERT_CASUAL
= 0x12, /* Casual certification of a User ID and
813 * Public Key packet */
814 OPS_CERT_POSITIVE
= 0x13, /* Positive certification of a
815 * User ID and Public Key packet */
817 OPS_SIG_SUBKEY
= 0x18, /* Subkey Binding Signature */
818 OPS_SIG_PRIMARY
= 0x19, /* Primary Key Binding Signature */
819 OPS_SIG_DIRECT
= 0x1f, /* Signature directly on a key */
821 OPS_SIG_REV_KEY
= 0x20, /* Key revocation signature */
822 OPS_SIG_REV_SUBKEY
= 0x28, /* Subkey revocation signature */
823 OPS_SIG_REV_CERT
= 0x30,/* Certification revocation signature */
825 OPS_SIG_TIMESTAMP
= 0x40, /* Timestamp signature */
827 OPS_SIG_3RD_PARTY
= 0x50/* Third-Party Confirmation signature */
830 /** Struct to hold params of an RSA signature */
831 typedef struct __ops_rsa_sig_t
{
832 BIGNUM
*sig
; /* the signature value (m^d % n) */
835 /** Struct to hold params of a DSA signature */
836 typedef struct __ops_dsa_sig_t
{
837 BIGNUM
*r
; /* DSA value r */
838 BIGNUM
*s
; /* DSA value s */
841 /** __ops_elgamal_signature_t */
842 typedef struct __ops_elgamal_sig_t
{
845 } __ops_elgamal_sig_t
;
847 /** Struct to hold data for a private/experimental signature */
848 typedef struct __ops_unknown_sig_t
{
850 } __ops_unknown_sig_t
;
852 /** Union to hold signature params of any algorithm */
854 __ops_rsa_sig_t rsa
;/* An RSA Signature */
855 __ops_dsa_sig_t dsa
;/* A DSA Signature */
856 __ops_elgamal_sig_t elgamal
; /* deprecated */
857 __ops_unknown_sig_t unknown
; /* private or experimental */
860 #define OPS_KEY_ID_SIZE 8
861 #define OPS_FINGERPRINT_SIZE 20
863 /** Struct to hold a signature packet.
868 typedef struct __ops_signinfo_t
{
869 __ops_version_t version
;/* signature version number */
870 __ops_signtype_t type
; /* signature type value */
871 time_t birthtime
; /* creation time of the signature */
872 uint8_t signer
[OPS_KEY_ID_SIZE
];
873 /* Eight-octet key ID of signer */
874 __ops_pubkey_alg_t key_alg
; /* public key algorithm number */
875 __ops_hash_alg_t hash_alg
; /* hashing algorithm number */
876 __ops_sig_union_t sig
; /* signature params */
879 unsigned gotbirthtime
:1;
880 unsigned gotsigner
:1;
883 #define OPS_MIN_HASH_SIZE 16
886 typedef struct __ops_hash_t
{
887 __ops_hash_alg_t alg
; /* algorithm */
888 size_t size
; /* size */
889 const char *name
; /* what it's known as */
890 void (*init
)(struct __ops_hash_t
*); /* initialisation func */
891 void (*add
)(struct __ops_hash_t
*, const uint8_t *, unsigned);
893 unsigned (*finish
)(struct __ops_hash_t
*, uint8_t *);
895 void *data
; /* blob for data */
898 /** Struct used when parsing a signature */
899 typedef struct __ops_sig_t
{
900 __ops_signinfo_t info
; /* The signature information */
901 /* The following fields are only used while parsing the signature */
902 uint8_t hash2
[2]; /* high 2 bytes of hashed value -
904 size_t v4_hashstart
; /* only valid if accumulate
906 __ops_hash_t
*hash
; /* if set, the hash filled in for the data
910 /** The raw bytes of a signature subpacket */
911 typedef struct __ops_ss_raw_t
{
912 __ops_content_tag_t tag
;
917 /** Signature Subpacket : Trust Level */
918 typedef struct __ops_ss_trust_t
{
919 uint8_t level
; /* Trust Level */
920 uint8_t amount
; /* Amount */
923 /** Signature Subpacket : Revocable */
924 typedef struct __ops_ss_revocable_t
{
926 } __ops_ss_revocable_t
;
928 /** Signature Subpacket : Time */
929 typedef struct __ops_ss_time_t
{
933 /** Signature Subpacket : Key ID */
934 typedef struct __ops_ss_key_id_t
{
935 uint8_t keyid
[OPS_KEY_ID_SIZE
];
938 /** Signature Subpacket : Notation Data */
939 typedef struct __ops_ss_notation_t
{
943 } __ops_ss_notation_t
;
945 /** Signature Subpacket : User Defined */
946 typedef struct __ops_ss_userdef_t
{
948 } __ops_ss_userdef_t
;
950 /** Signature Subpacket : Unknown */
951 typedef struct __ops_ss_unknown_t
{
953 } __ops_ss_unknown_t
;
955 /** Signature Subpacket : Preferred Symmetric Key Algorithm */
956 typedef struct __ops_ss_skapref_t
{
959 * Note that value 0 may represent the plaintext algorithm so we
960 * cannot expect data->contents to be a null-terminated list
962 } __ops_ss_skapref_t
;
964 /** Signature Subpacket : Preferrred Hash Algorithm */
965 typedef struct __ops_ss_hashpref_t
{
967 } __ops_ss_hashpref_t
;
969 /** Signature Subpacket : Preferred Compression */
970 typedef struct __ops_ss_zpref_t
{
974 /** Signature Subpacket : Key Flags */
975 typedef struct __ops_ss_key_flags_t
{
977 } __ops_ss_key_flags_t
;
979 /** Signature Subpacket : Key Server Preferences */
980 typedef struct __ops_ss_key_server_prefs_t
{
982 } __ops_ss_key_server_prefs_t
;
984 /** Signature Subpacket : Features */
985 typedef struct __ops_ss_features_t
{
987 } __ops_ss_features_t
;
989 /** Signature Subpacket : Signature Target */
990 typedef struct __ops_ss_sig_target_t
{
991 __ops_pubkey_alg_t pka_alg
;
992 __ops_hash_alg_t hash_alg
;
994 } __ops_ss_sig_target_t
;
996 /** Signature Subpacket : Embedded Signature */
997 typedef struct __ops_ss_embedded_sig_t
{
999 } __ops_ss_embedded_sig_t
;
1001 /** __ops_subpacket_t */
1002 typedef struct __ops_subpacket_t
{
1005 } __ops_subpacket_t
;
1007 /** Types of Compression */
1016 * unlike most structures, this will feed its data as a stream to the
1017 * application instead of directly including it
1019 /** __ops_compressed_t */
1020 typedef struct __ops_compressed_t
{
1022 } __ops_compressed_t
;
1024 /** __ops_one_pass_sig_t */
1025 typedef struct __ops_one_pass_sig_t
{
1027 __ops_signtype_t sig_type
;
1028 __ops_hash_alg_t hash_alg
;
1029 __ops_pubkey_alg_t key_alg
;
1030 uint8_t keyid
[OPS_KEY_ID_SIZE
];
1032 } __ops_one_pass_sig_t
;
1034 /** Signature Subpacket : Primary User ID */
1035 typedef struct __ops_ss_primary_userid_t
{
1036 unsigned primary_userid
;
1037 } __ops_ss_primary_userid_t
;
1039 /** Signature Subpacket : Regexp */
1040 typedef struct __ops_ss_regexp_t
{
1042 } __ops_ss_regexp_t
;
1044 /** Signature Subpacket : Policy URL */
1045 typedef struct __ops_ss_policy_t
{
1047 } __ops_ss_policy_t
;
1049 /** Signature Subpacket : Preferred Key Server */
1050 typedef struct __ops_ss_keyserv_t
{
1052 } __ops_ss_keyserv_t
;
1054 /** Signature Subpacket : Revocation Key */
1055 typedef struct __ops_ss_revocation_key_t
{
1058 uint8_t fingerprint
[OPS_FINGERPRINT_SIZE
];
1059 } __ops_ss_revocation_key_t
;
1061 /** Signature Subpacket : Revocation Reason */
1062 typedef struct __ops_ss_revocation_t
{
1065 } __ops_ss_revocation_t
;
1067 /** litdata_type_t */
1069 OPS_LITDATA_BINARY
= 'b',
1070 OPS_LITDATA_TEXT
= 't',
1071 OPS_LITDATA_UTF8
= 'u',
1072 OPS_LITDATA_LOCAL
= 'l',
1073 OPS_LITDATA_LOCAL2
= '1'
1074 } __ops_litdata_type_t
;
1076 /** __ops_litdata_header_t */
1077 typedef struct __ops_litdata_header_t
{
1078 __ops_litdata_type_t format
;
1081 } __ops_litdata_header_t
;
1083 /** __ops_litdata_body_t */
1084 typedef struct __ops_litdata_body_t
{
1087 __ops_memory_t
*mem
;
1088 } __ops_litdata_body_t
;
1091 typedef struct __ops_mdc_t
{
1096 /** __ops_header_var_t */
1097 typedef struct __ops_header_var_t
{
1100 } __ops_header_var_t
;
1102 /** __ops_headers_t */
1103 typedef struct __ops_headers_t
{
1104 __ops_header_var_t
*headers
;
1108 /** __ops_armour_header_t */
1109 typedef struct __ops_armour_header_t
{
1111 __ops_headers_t headers
;
1112 } __ops_armour_header_t
;
1114 /** __ops_armour_trailer_t */
1115 typedef struct __ops_armour_trailer_t
{
1117 } __ops_armour_trailer_t
;
1119 /** __ops_cleartext_head_t */
1120 typedef struct __ops_cleartext_head_t
{
1121 __ops_headers_t headers
;
1122 } __ops_cleartext_head_t
;
1124 /** __ops_cleartext_body_t */
1125 typedef struct __ops_cleartext_body_t
{
1127 uint8_t data
[8192]; /* \todo fix hard-coded value? */
1128 } __ops_cleartext_body_t
;
1130 /** __ops_cleartext_trailer_t */
1131 typedef struct __ops_cleartext_trailer_t
{
1132 struct __ops_hash_t
*hash
; /* This will not have been
1133 * finalised, but will have seen all
1134 * the cleartext data in canonical
1136 } __ops_cleartext_trailer_t
;
1138 /** __ops_unarmoured_text_t */
1139 typedef struct __ops_unarmoured_text_t
{
1142 } __ops_unarmoured_text_t
;
1145 SE_IP_DATA_VERSION
= 1
1146 } __ops_se_ip_data_version_t
;
1150 } __ops_pk_sesskey_version_t
;
1152 /** __ops_pk_sesskey_params_rsa_t */
1153 typedef struct __ops_pk_sesskey_params_rsa_t
{
1154 BIGNUM
*encrypted_m
;
1156 } __ops_pk_sesskey_params_rsa_t
;
1158 /** __ops_pk_sesskey_params_elgamal_t */
1159 typedef struct __ops_pk_sesskey_params_elgamal_t
{
1161 BIGNUM
*encrypted_m
;
1162 } __ops_pk_sesskey_params_elgamal_t
;
1164 /** __ops_pk_sesskey_params_t */
1166 __ops_pk_sesskey_params_rsa_t rsa
;
1167 __ops_pk_sesskey_params_elgamal_t elgamal
;
1168 } __ops_pk_sesskey_params_t
;
1170 /** __ops_pk_sesskey_t */
1171 typedef struct __ops_pk_sesskey_t
{
1172 __ops_pk_sesskey_version_t version
;
1173 uint8_t keyid
[OPS_KEY_ID_SIZE
];
1174 __ops_pubkey_alg_t alg
;
1175 __ops_pk_sesskey_params_t params
;
1176 __ops_symm_alg_t symm_alg
;
1177 uint8_t key
[OPS_MAX_KEY_SIZE
];
1179 } __ops_pk_sesskey_t
;
1181 /** __ops_seckey_passphrase_t */
1182 typedef struct __ops_seckey_passphrase_t
{
1183 const __ops_seckey_t
*seckey
;
1185 /* point somewhere that gets filled in to work around
1186 * constness of content */
1187 } __ops_seckey_passphrase_t
;
1191 } __ops_se_ip_version_t
;
1193 /** __ops_se_ip_data_header_t */
1194 typedef struct __ops_se_ip_data_header_t
{
1195 __ops_se_ip_version_t version
;
1196 } __ops_se_ip_data_header_t
;
1198 /** __ops_se_ip_data_body_t */
1199 typedef struct __ops_se_ip_data_body_t
{
1201 uint8_t *data
; /* \todo remember to free this */
1202 } __ops_se_ip_data_body_t
;
1204 /** __ops_se_data_body_t */
1205 typedef struct __ops_se_data_body_t
{
1207 uint8_t data
[8192]; /* \todo parameterise this! */
1208 } __ops_se_data_body_t
;
1210 /** __ops_get_seckey_t */
1211 typedef struct __ops_get_seckey_t
{
1212 const __ops_seckey_t
**seckey
;
1213 const __ops_pk_sesskey_t
*pk_sesskey
;
1214 } __ops_get_seckey_t
;
1216 /** __ops_parser_union_content_t */
1218 __ops_parser_error_t error
;
1219 __ops_parser_errcode_t errcode
;
1221 __ops_pubkey_t pubkey
;
1222 __ops_trust_t trust
;
1223 __ops_userid_t userid
;
1224 __ops_userattr_t userattr
;
1226 __ops_ss_raw_t ss_raw
;
1227 __ops_ss_trust_t ss_trust
;
1228 __ops_ss_revocable_t ss_revocable
;
1229 __ops_ss_time_t ss_time
;
1230 __ops_ss_key_id_t ss_issuer
;
1231 __ops_ss_notation_t ss_notation
;
1232 __ops_subpacket_t packet
;
1233 __ops_compressed_t compressed
;
1234 __ops_one_pass_sig_t one_pass_sig
;
1235 __ops_ss_skapref_t ss_skapref
;
1236 __ops_ss_hashpref_t ss_hashpref
;
1237 __ops_ss_zpref_t ss_zpref
;
1238 __ops_ss_key_flags_t ss_key_flags
;
1239 __ops_ss_key_server_prefs_t ss_key_server_prefs
;
1240 __ops_ss_primary_userid_t ss_primary_userid
;
1241 __ops_ss_regexp_t ss_regexp
;
1242 __ops_ss_policy_t ss_policy
;
1243 __ops_ss_keyserv_t ss_keyserv
;
1244 __ops_ss_revocation_key_t ss_revocation_key
;
1245 __ops_ss_userdef_t ss_userdef
;
1246 __ops_ss_unknown_t ss_unknown
;
1247 __ops_litdata_header_t litdata_header
;
1248 __ops_litdata_body_t litdata_body
;
1250 __ops_ss_features_t ss_features
;
1251 __ops_ss_sig_target_t ss_sig_target
;
1252 __ops_ss_embedded_sig_t ss_embedded_sig
;
1253 __ops_ss_revocation_t ss_revocation
;
1254 __ops_seckey_t seckey
;
1255 __ops_userid_t ss_signer
;
1256 __ops_armour_header_t armour_header
;
1257 __ops_armour_trailer_t armour_trailer
;
1258 __ops_cleartext_head_t cleartext_head
;
1259 __ops_cleartext_body_t cleartext_body
;
1260 __ops_cleartext_trailer_t cleartext_trailer
;
1261 __ops_unarmoured_text_t unarmoured_text
;
1262 __ops_pk_sesskey_t pk_sesskey
;
1263 __ops_seckey_passphrase_t skey_passphrase
;
1264 __ops_se_ip_data_header_t se_ip_data_header
;
1265 __ops_se_ip_data_body_t se_ip_data_body
;
1266 __ops_se_data_body_t se_data_body
;
1267 __ops_get_seckey_t get_seckey
;
1270 /** __ops_packet_t */
1271 typedef struct __ops_packet_t
{
1272 __ops_content_tag_t tag
; /* type of contents */
1273 uint8_t critical
; /* for sig subpackets */
1274 __ops_contents_t u
; /* union for contents */
1277 /** __ops_fingerprint_t */
1278 typedef struct __ops_fingerprint_t
{
1279 uint8_t fingerprint
[OPS_FINGERPRINT_SIZE
];
1281 } __ops_fingerprint_t
;
1283 #define DYNARRAY(type, arr) \
1284 unsigned arr##c; unsigned arr##size; type *arr##s
1286 #define EXPAND(str, arr) do { \
1287 if (str->arr##c == str->arr##size) { \
1288 str->arr##size = (str->arr##size * 2) + 10; \
1289 str->arr##s = realloc(str->arr##s, \
1290 str->arr##size * sizeof(*str->arr##s)); \
1292 } while(/*CONSTCOND*/0)
1294 /** __ops_keypair_union_t
1297 __ops_pubkey_t pubkey
;
1298 __ops_seckey_t seckey
;
1299 } __ops_keypair_union_t
;
1302 typedef struct sigpacket_t
{
1303 __ops_userid_t
*userid
;
1304 __ops_subpacket_t
*packet
;
1308 * \todo expand to hold onto subkeys
1310 typedef struct __ops_key_t
{
1311 DYNARRAY(__ops_userid_t
, uid
);
1312 DYNARRAY(__ops_subpacket_t
, packet
);
1313 DYNARRAY(sigpacket_t
, sig
);
1314 uint8_t keyid
[OPS_KEY_ID_SIZE
];
1315 __ops_fingerprint_t fingerprint
;
1316 __ops_content_tag_t type
;
1317 __ops_keypair_union_t key
;
1320 /* this struct defines a number of keys (a keyring) */
1321 typedef struct __ops_keyring_t
{
1322 DYNARRAY(__ops_key_t
, key
);
1325 #define MDC_PKT_TAG 0xd3
1327 typedef struct __ops_io_t
{
1328 void *outs
; /* output file stream */
1329 void *errs
; /* file stream to put error messages */
1332 /** Writer settings */
1333 typedef struct __ops_writer_t
{
1334 unsigned (*writer
)(struct __ops_writer_t
*,
1338 /* the writer itself */
1339 unsigned (*finaliser
)(__ops_error_t
**,
1340 struct __ops_writer_t
*);
1341 /* the writer's finaliser */
1342 void (*destroyer
)(struct __ops_writer_t
*);
1343 /* the writer's destroyer */
1344 void *arg
; /* writer-specific argument */
1345 struct __ops_writer_t
*next
; /* next writer in the stack */
1346 __ops_io_t
*io
; /* IO for errors and output */
1349 typedef struct __ops_output_t
{
1350 __ops_writer_t writer
;
1351 __ops_error_t
*errors
; /* error stack */
1355 typedef struct __ops_crypt_t
{
1356 __ops_symm_alg_t alg
;
1359 void (*set_iv
)(struct __ops_crypt_t
*, const uint8_t *);
1360 void (*set_crypt_key
)(struct __ops_crypt_t
*, const uint8_t *);
1361 void (*base_init
)(struct __ops_crypt_t
*);
1362 void (*decrypt_resync
)(struct __ops_crypt_t
*);
1363 /* encrypt/decrypt one block */
1364 void (*block_encrypt
)(struct __ops_crypt_t
*, void *, const void *);
1365 void (*block_decrypt
)(struct __ops_crypt_t
*, void *, const void *);
1366 /* Standard CFB encrypt/decrypt (as used by Sym Enc Int Prot packets) */
1367 void (*cfb_encrypt
)(struct __ops_crypt_t
*, void *, const void *,
1369 void (*cfb_decrypt
)(struct __ops_crypt_t
*, void *, const void *,
1371 void (*decrypt_finish
)(struct __ops_crypt_t
*);
1372 uint8_t iv
[OPS_MAX_BLOCK_SIZE
];
1373 uint8_t civ
[OPS_MAX_BLOCK_SIZE
];
1374 uint8_t siv
[OPS_MAX_BLOCK_SIZE
];
1375 /* siv is needed for weird v3 resync */
1376 uint8_t key
[OPS_MAX_KEY_SIZE
];
1378 /* num is offset - see openssl _encrypt doco */
1383 /** __ops_region_t */
1384 typedef struct __ops_region_t
{
1385 struct __ops_region_t
*parent
;
1387 unsigned readc
; /* length read */
1389 /* length of last read, only valid in deepest child */
1390 unsigned indeterm
:1;
1393 /** __ops_cb_ret_t */
1401 A reader MUST read at least one byte if it can, and should read up
1402 to the number asked for. Whether it reads more for efficiency is
1403 its own decision, but if it is a stacked reader it should never
1404 read more than the length of the region it operates in (which it
1405 would have to be given when it is stacked).
1407 If a read is short because of EOF, then it should return the short
1408 read (obviously this will be zero on the second attempt, if not the
1409 first). Because a reader is not obliged to do a full read, only a
1410 zero return can be taken as an indication of EOF.
1412 If there is an error, then the callback should be notified, the
1413 error stacked, and -1 should be returned.
1415 Note that although length is a size_t, a reader will never be asked
1416 to read more than INT_MAX in one go.
1419 /** Used to specify whether subpackets should be returned raw, parsed
1422 OPS_PARSE_RAW
, /* Callback Raw */
1423 OPS_PARSE_PARSED
, /* Callback Parsed */
1424 OPS_PARSE_IGNORE
/* Don't callback */
1425 } __ops_parse_type_t
;
1427 /** __ops_cbdata_t */
1428 typedef struct __ops_cbdata_t
{
1429 __ops_cb_ret_t (*cbfunc
)(struct __ops_cbdata_t
*,
1430 const __ops_packet_t
*);
1431 /* callback function */
1432 void *arg
; /* args to pass to callback func */
1433 __ops_error_t
**errors
; /* address of error stack */
1434 struct __ops_cbdata_t
*next
;
1435 __ops_output_t
*output
;/* used if writing out parsed info */
1436 __ops_io_t
*io
; /* error/output messages */
1439 /** __ops_reader_t */
1440 typedef struct __ops_reader_t
{
1441 int (*reader
)(void *, size_t, __ops_error_t
**,
1442 struct __ops_reader_t
*,
1444 void (*destroyer
)(struct __ops_reader_t
*);
1445 void *arg
; /* args to pass to reader function */
1446 unsigned accumulate
:1; /* set to gather packet data */
1447 uint8_t *accumulated
; /* the accumulated data */
1448 unsigned asize
; /* size of the buffer */
1449 unsigned alength
;/* used buffer */
1450 unsigned position
; /* reader-specific offset */
1451 struct __ops_reader_t
*next
;
1452 struct __ops_stream_t
*parent
;/* parent stream structure */
1455 /** __ops_hashtype_t */
1456 typedef struct __ops_hashtype_t
{
1458 uint8_t keyid
[OPS_KEY_ID_SIZE
];
1461 #define NTAGS 0x100 /* == 256 */
1463 /** \brief Structure to hold information about a packet parse.
1465 * This information includes options about the parse:
1466 * - whether the packet contents should be accumulated or not
1467 * - whether signature subpackets should be parsed or left raw
1469 * It contains options specific to the parsing of armoured data:
1470 * - whether headers are allowed in armoured data without a gap
1471 * - whether a blank line is allowed at the start of the armoured data
1473 * It also specifies :
1474 * - the callback function to use and its arguments
1475 * - the reader function to use and its arguments
1477 * It also contains information about the current state of the parse:
1478 * - offset from the beginning
1479 * - the accumulated data, if any
1480 * - the size of the buffer, and how much has been used
1482 * It has a linked list of errors.
1484 typedef struct __ops_stream_t
{
1485 uint8_t ss_raw
[NTAGS
/ 8];
1486 /* 1 bit / sig-subpkt type; set to get raw data */
1487 uint8_t ss_parsed
[NTAGS
/ 8];
1488 /* 1 bit / sig-subpkt type; set to get parsed data */
1489 __ops_reader_t readinfo
;
1490 __ops_cbdata_t cbdata
;
1491 __ops_error_t
*errors
;
1492 void *io
; /* io streams */
1493 __ops_crypt_t decrypt
;
1495 __ops_hashtype_t
*hashes
;
1496 unsigned reading_v3_secret
:1;
1497 unsigned reading_mpi_len
:1;
1498 unsigned exact_read
:1;
1501 typedef struct __ops_validation_t
{
1502 unsigned int validc
;
1503 __ops_signinfo_t
*valids
;
1504 unsigned int invalidc
;
1505 __ops_signinfo_t
*invalids
;
1506 unsigned int unknownc
;
1507 __ops_signinfo_t
*unknowns
;
1508 } __ops_validation_t
;
1510 typedef struct validate_reader_t
{
1511 const __ops_key_t
*key
;
1514 } validate_reader_t
;
1516 /** Struct use with the validate_data_cb callback */
1523 __ops_litdata_body_t litdata_body
;
1524 __ops_cleartext_body_t cleartext_body
;
1526 uint8_t hash
[OPS_MAX_HASH_SIZE
];
1527 __ops_memory_t
*mem
;
1528 const __ops_keyring_t
*keyring
;
1529 validate_reader_t
*reader
;/* reader-specific arg */
1530 __ops_validation_t
*result
;
1532 } validate_data_cb_t
;
1535 OPS_PGP_MESSAGE
= 1,
1536 OPS_PGP_PUBLIC_KEY_BLOCK
,
1537 OPS_PGP_PRIVATE_KEY_BLOCK
,
1538 OPS_PGP_MULTIPART_MESSAGE_PART_X_OF_Y
,
1539 OPS_PGP_MULTIPART_MESSAGE_PART_X
,
1541 } __ops_armor_type_t
;
1543 #define CRC24_INIT 0xb704ceL
1545 /*************************************************************************/
1546 /* code starts here */
1547 /*************************************************************************/
1550 #define vsnprintf _vsnprintf
1554 loggit(const char *fmt
, ...)
1559 va_start(args
, fmt
);
1560 vsnprintf(buf
, sizeof(buf
), fmt
, args
);
1562 printf("netpgpverify: %s\n", buf
);
1565 /* generic grab new storage function */
1567 __ops_new(size_t size
)
1571 if ((vp
= calloc(1, size
)) == NULL
) {
1572 loggit("allocation failure for %" PRIsize
"u bytes", size
);
1577 /* \todo check where userid pointers are copied */
1580 \brief Copy user id, including contents
1581 \param dst Destination User ID
1582 \param src Source User ID
1583 \note If dst already has a userid, it will be freed.
1585 static __ops_userid_t
*
1586 __ops_copy_userid(__ops_userid_t
*dst
, const __ops_userid_t
*src
)
1590 len
= strlen((char *) src
->userid
);
1592 (void) free(dst
->userid
);
1594 dst
->userid
= __ops_new(len
+ 1);
1595 (void) memcpy(dst
->userid
, src
->userid
, len
);
1601 \brief Add User ID to key
1602 \param key Key to which to add User ID
1603 \param userid User ID to add
1604 \return Pointer to new User ID
1606 static __ops_userid_t
*
1607 __ops_add_userid(__ops_key_t
*key
, const __ops_userid_t
*userid
)
1609 __ops_userid_t
*uidp
= NULL
;
1612 uidp
= &key
->uids
[key
->uidc
++];
1613 uidp
->userid
= NULL
;
1614 return __ops_copy_userid(uidp
, userid
);
1619 \brief Copy packet, including contents
1620 \param dst Destination packet
1621 \param src Source packet
1622 \note If dst already has a packet, it will be freed.
1624 static __ops_subpacket_t
*
1625 __ops_copy_packet(__ops_subpacket_t
*dst
, const __ops_subpacket_t
*src
)
1628 (void) free(dst
->raw
);
1630 dst
->raw
= __ops_new(src
->length
);
1631 dst
->length
= src
->length
;
1632 (void) memcpy(dst
->raw
, src
->raw
, src
->length
);
1638 \brief Add packet to key
1639 \param key Key to which to add packet
1640 \param packet Packet to add
1641 \return Pointer to new packet
1643 static __ops_subpacket_t
*
1644 __ops_add_subpacket(__ops_key_t
*key
, const __ops_subpacket_t
*packet
)
1646 __ops_subpacket_t
*pktp
= NULL
;
1648 EXPAND(key
, packet
);
1649 pktp
= &key
->packets
[key
->packetc
++];
1652 return __ops_copy_packet(pktp
, packet
);
1655 static __ops_cb_ret_t
__ops_callback(__ops_cbdata_t
*, const __ops_packet_t
*);
1657 static void __ops_keyid(uint8_t *,
1659 const __ops_pubkey_t
*);
1660 static void __ops_fingerprint(__ops_fingerprint_t
*, const __ops_pubkey_t
*);
1664 __ops_keyring_t
*keyring
;
1667 static const char *__ops_errcode(const __ops_errcode_t
);
1670 * \ingroup Core_Errors
1671 * \brief Pushes the given error on the given errorstack
1672 * \param errstack Error stack to use
1673 * \param errcode Code of error to push
1674 * \param sys_errno System errno (used if errcode=OPS_E_SYSTEM_ERROR)
1675 * \param file Source filename where error occurred
1676 * \param line Line in source file where error occurred
1677 * \param fmt Comment
1682 __ops_push_error(__ops_error_t
**errstack
, __ops_errcode_t errcode
,
1683 int sys_errno
, const char *file
, int line
, const char *fmt
,...)
1685 /* first get the varargs and generate the comment */
1687 unsigned maxbuf
= 128;
1691 if ((comment
= __ops_new(maxbuf
+ 1)) == NULL
) {
1692 loggit("alloc comment failure");
1695 va_start(args
, fmt
);
1696 vsnprintf(comment
, maxbuf
+ 1, fmt
, args
);
1698 /* alloc a new error and add it to the top of the stack */
1699 if ((err
= __ops_new(sizeof(__ops_error_t
))) == NULL
) {
1700 loggit("alloc err failure");
1703 err
->next
= *errstack
;
1706 /* fill in the details */
1707 err
->errcode
= errcode
;
1708 err
->sys_errno
= sys_errno
;
1712 err
->comment
= comment
;
1716 * \ingroup Core_Callbacks
1718 static __ops_cb_ret_t
1719 accumulate_cb(__ops_cbdata_t
*cbdata
, const __ops_packet_t
*pkt
)
1721 const __ops_contents_t
*content
;
1722 const __ops_pubkey_t
*pubkey
;
1723 __ops_keyring_t
*keyring
;
1725 accumulate_t
*accumulate
;
1728 accumulate
= cbdata
->arg
;
1729 keyring
= accumulate
->keyring
;
1730 key
= (keyring
->keyc
> 0) ? &keyring
->keys
[keyring
->keyc
] : NULL
;
1732 case OPS_PTAG_CT_PUBLIC_KEY
:
1733 case OPS_PTAG_CT_SECRET_KEY
:
1734 case OPS_PTAG_CT_ENCRYPTED_SECRET_KEY
:
1735 EXPAND(keyring
, key
);
1736 pubkey
= (pkt
->tag
== OPS_PTAG_CT_PUBLIC_KEY
) ?
1738 &content
->seckey
.pubkey
;
1739 key
= &keyring
->keys
[++keyring
->keyc
];
1740 (void) memset(key
, 0x0, sizeof(*key
));
1741 __ops_keyid(key
->keyid
, OPS_KEY_ID_SIZE
, pubkey
);
1742 __ops_fingerprint(&key
->fingerprint
, pubkey
);
1743 key
->type
= pkt
->tag
;
1744 if (pkt
->tag
== OPS_PTAG_CT_PUBLIC_KEY
) {
1745 key
->key
.pubkey
= *pubkey
;
1747 key
->key
.seckey
= content
->seckey
;
1749 return OPS_KEEP_MEMORY
;
1751 case OPS_PTAG_CT_USER_ID
:
1753 __ops_add_userid(key
, &content
->userid
);
1754 return OPS_KEEP_MEMORY
;
1756 OPS_ERROR(cbdata
->errors
, OPS_E_P_NO_USERID
, "No userid found");
1757 return OPS_KEEP_MEMORY
;
1759 case OPS_PARSER_PACKET_END
:
1761 __ops_add_subpacket(key
, &content
->packet
);
1762 return OPS_KEEP_MEMORY
;
1764 return OPS_RELEASE_MEMORY
;
1766 case OPS_PARSER_ERROR
:
1767 loggit("Error: %s", content
->error
.error
);
1768 return OPS_FINISHED
;
1770 case OPS_PARSER_ERRCODE
:
1771 loggit("parse error: %s",
1772 __ops_errcode(content
->errcode
.errcode
));
1779 /* XXX: we now exclude so many things, we should either drop this or */
1780 /* do something to pass on copies of the stuff we keep */
1781 return __ops_callback(cbdata
->next
, pkt
);
1785 \ingroup Core_ReadPackets
1786 \brief Sets the stream's callback
1787 This is used when adding the first callback in a stack of callbacks.
1788 \sa __ops_callback_push()
1791 __ops_set_callback(__ops_stream_t
*stream
,
1792 __ops_cb_ret_t (*cb
)(__ops_cbdata_t
*, const __ops_packet_t
*),
1795 stream
->cbdata
.cbfunc
= cb
;
1796 stream
->cbdata
.arg
= arg
;
1797 stream
->cbdata
.errors
= &stream
->errors
;
1801 \ingroup Core_ReadPackets
1802 \brief Adds a further callback to a stack of callbacks
1803 \sa __ops_set_callback()
1806 __ops_callback_push(__ops_stream_t
*stream
,
1807 __ops_cb_ret_t (*cb
)(__ops_cbdata_t
*, const __ops_packet_t
*),
1810 __ops_cbdata_t
*cbdata
;
1812 cbdata
= __ops_new(sizeof(*cbdata
));
1813 (void) memcpy(cbdata
, &stream
->cbdata
, sizeof(*cbdata
));
1814 cbdata
->io
= stream
->io
;
1815 stream
->cbdata
.next
= cbdata
;
1816 __ops_set_callback(stream
, cb
, arg
);
1819 static int __ops_parse(__ops_stream_t
*, int);
1822 * \ingroup Core_Parse
1824 * Parse packets from an input stream until EOF or error.
1826 * Key data found in the parsed data is added to #keyring.
1828 * \param keyring Pointer to an existing keyring
1829 * \param parse Options to use when parsing
1833 __ops_parse_and_accumulate(__ops_keyring_t
*keyring
, __ops_stream_t
*parse
)
1835 accumulate_t accumulate
;
1836 const int printerrors
= 1;
1839 if (parse
->readinfo
.accumulate
) {
1840 loggit("__ops_parse_and_accumulate: already init");
1843 (void) memset(&accumulate
, 0x0, sizeof(accumulate
));
1844 accumulate
.keyring
= keyring
;
1845 __ops_callback_push(parse
, accumulate_cb
, &accumulate
);
1846 parse
->readinfo
.accumulate
= 1;
1847 ret
= __ops_parse(parse
, !printerrors
);
1853 * \brief Error Handling
1855 #define ERRNAME(code) { code, #code }
1862 static __ops_map_t errcode_name_map
[] = {
1864 ERRNAME(OPS_E_FAIL
),
1865 ERRNAME(OPS_E_SYSTEM_ERROR
),
1866 ERRNAME(OPS_E_UNIMPLEMENTED
),
1869 ERRNAME(OPS_E_R_READ_FAILED
),
1870 ERRNAME(OPS_E_R_EARLY_EOF
),
1871 ERRNAME(OPS_E_R_BAD_FORMAT
),
1872 ERRNAME(OPS_E_R_UNCONSUMED_DATA
),
1875 ERRNAME(OPS_E_W_WRITE_FAILED
),
1876 ERRNAME(OPS_E_W_WRITE_TOO_SHORT
),
1879 ERRNAME(OPS_E_P_NOT_ENOUGH_DATA
),
1880 ERRNAME(OPS_E_P_UNKNOWN_TAG
),
1881 ERRNAME(OPS_E_P_PACKET_CONSUMED
),
1882 ERRNAME(OPS_E_P_MPI_FORMAT_ERROR
),
1887 ERRNAME(OPS_E_V_BAD_SIGNATURE
),
1888 ERRNAME(OPS_E_V_NO_SIGNATURE
),
1889 ERRNAME(OPS_E_V_UNKNOWN_SIGNER
),
1892 ERRNAME(OPS_E_ALG_UNSUPPORTED_SYMMETRIC_ALG
),
1893 ERRNAME(OPS_E_ALG_UNSUPPORTED_PUBLIC_KEY_ALG
),
1894 ERRNAME(OPS_E_ALG_UNSUPPORTED_SIGNATURE_ALG
),
1895 ERRNAME(OPS_E_ALG_UNSUPPORTED_HASH_ALG
),
1897 ERRNAME(OPS_E_PROTO
),
1898 ERRNAME(OPS_E_PROTO_BAD_SYMMETRIC_DECRYPT
),
1899 ERRNAME(OPS_E_PROTO_UNKNOWN_SS
),
1900 ERRNAME(OPS_E_PROTO_CRITICAL_SS_IGNORED
),
1901 ERRNAME(OPS_E_PROTO_BAD_PUBLIC_KEY_VRSN
),
1902 ERRNAME(OPS_E_PROTO_BAD_SIGNATURE_VRSN
),
1903 ERRNAME(OPS_E_PROTO_BAD_ONE_PASS_SIG_VRSN
),
1904 ERRNAME(OPS_E_PROTO_BAD_PKSK_VRSN
),
1905 ERRNAME(OPS_E_PROTO_DECRYPTED_MSG_WRONG_LEN
),
1906 ERRNAME(OPS_E_PROTO_BAD_SK_CHECKSUM
),
1912 * \ingroup Core_Print
1914 * Searches the given map for the given type.
1915 * Returns a readable string if found, "Unknown" if not.
1918 findtype(int type
, __ops_map_t
*map
)
1922 for (row
= map
; row
->string
!= NULL
; row
++) {
1923 if (row
->type
== type
) {
1931 * \ingroup Core_Errors
1932 * \brief returns error code name
1934 * \return error code name or "Unknown"
1937 __ops_errcode(const __ops_errcode_t errcode
)
1939 return findtype((int) errcode
, errcode_name_map
);
1943 \ingroup Core_Errors
1944 \brief print this error
1945 \param err Error to print
1948 __ops_print_error(__ops_error_t
*err
)
1950 printf("%s:%d: ", err
->file
, err
->line
);
1951 if (err
->errcode
== OPS_E_SYSTEM_ERROR
) {
1952 printf("system error %d returned from %s\n", err
->sys_errno
,
1955 printf("%s, %s\n", __ops_errcode(err
->errcode
), err
->comment
);
1960 \ingroup Core_Errors
1961 \brief Print all errors on stack
1962 \param errstack Error stack to print
1965 __ops_print_errors(__ops_error_t
*errstack
)
1969 for (err
= errstack
; err
!= NULL
; err
= err
->next
) {
1970 __ops_print_error(err
);
1975 \ingroup Core_Errors
1976 \brief Frees all errors on stack
1977 \param errstack Error stack to free
1980 __ops_free_errors(__ops_error_t
*errstack
)
1982 __ops_error_t
*next
;
1984 while (errstack
!= NULL
) {
1985 next
= errstack
->next
;
1986 (void) free(errstack
->comment
);
1987 (void) free(errstack
);
1993 \ingroup HighLevel_Memory
1994 \brief Free memory and associated data
1995 \param mem Memory to free
1996 \note This does not free mem itself
1997 \sa __ops_memory_clear()
1998 \sa __ops_memory_free()
2001 __ops_memory_release(__ops_memory_t
*mem
)
2004 (void) munmap(mem
->buf
, mem
->length
);
2006 (void) free(mem
->buf
);
2013 \ingroup HighLevel_Memory
2014 \brief Free memory ptr and associated memory
2015 \param mem Memory to be freed
2016 \sa __ops_memory_release()
2017 \sa __ops_memory_clear()
2020 __ops_memory_free(__ops_memory_t
*mem
)
2022 __ops_memory_release(mem
);
2026 /* various message digest functions */
2029 md5_init(__ops_hash_t
*hash
)
2032 loggit("md5_init: hash data non-null");
2034 hash
->data
= __ops_new(sizeof(MD5_CTX
));
2035 MD5_Init(hash
->data
);
2039 md5_add(__ops_hash_t
*hash
, const uint8_t *data
, unsigned length
)
2041 MD5_Update(hash
->data
, data
, length
);
2045 md5_finish(__ops_hash_t
*hash
, uint8_t *out
)
2047 MD5_Final(out
, hash
->data
);
2053 static __ops_hash_t __md5
= {
2064 \ingroup Core_Crypto
2065 \brief Initialise to MD5
2066 \param hash Hash to initialise
2069 __ops_hash_md5(__ops_hash_t
*hash
)
2075 sha1_init(__ops_hash_t
*hash
)
2078 loggit("sha1_init: hash data non-null");
2080 hash
->data
= __ops_new(sizeof(SHA_CTX
));
2081 SHA1_Init(hash
->data
);
2085 sha1_add(__ops_hash_t
*hash
, const uint8_t *data
, unsigned length
)
2087 SHA1_Update(hash
->data
, data
, length
);
2091 sha1_finish(__ops_hash_t
*hash
, uint8_t *out
)
2093 SHA1_Final(out
, hash
->data
);
2094 (void) free(hash
->data
);
2096 return OPS_SHA1_HASH_SIZE
;
2099 static __ops_hash_t __sha1
= {
2110 \ingroup Core_Crypto
2111 \brief Initialise to SHA1
2112 \param hash Hash to initialise
2115 __ops_hash_sha1(__ops_hash_t
*hash
)
2121 sha256_init(__ops_hash_t
*hash
)
2124 loggit("sha256_init: hash data non-null");
2126 hash
->data
= __ops_new(sizeof(SHA256_CTX
));
2127 SHA256_Init(hash
->data
);
2131 sha256_add(__ops_hash_t
*hash
, const uint8_t *data
, unsigned length
)
2133 SHA256_Update(hash
->data
, data
, length
);
2137 sha256_finish(__ops_hash_t
*hash
, uint8_t *out
)
2139 SHA256_Final(out
, hash
->data
);
2140 (void) free(hash
->data
);
2142 return SHA256_DIGEST_LENGTH
;
2145 static __ops_hash_t __sha256
= {
2147 SHA256_DIGEST_LENGTH
,
2156 __ops_hash_sha256(__ops_hash_t
*hash
)
2166 sha384_init(__ops_hash_t
*hash
)
2169 loggit("sha384_init: hash data non-null");
2171 hash
->data
= __ops_new(sizeof(SHA512_CTX
));
2172 SHA384_Init(hash
->data
);
2176 sha384_add(__ops_hash_t
*hash
, const uint8_t *data
, unsigned length
)
2178 SHA384_Update(hash
->data
, data
, length
);
2182 sha384_finish(__ops_hash_t
*hash
, uint8_t *out
)
2184 SHA384_Final(out
, hash
->data
);
2185 (void) free(hash
->data
);
2187 return SHA384_DIGEST_LENGTH
;
2190 static __ops_hash_t __sha384
= {
2192 SHA384_DIGEST_LENGTH
,
2201 __ops_hash_sha384(__ops_hash_t
*hash
)
2211 sha512_init(__ops_hash_t
*hash
)
2214 loggit("sha512_init: hash data non-null");
2216 hash
->data
= __ops_new(sizeof(SHA512_CTX
));
2217 SHA512_Init(hash
->data
);
2221 sha512_add(__ops_hash_t
*hash
, const uint8_t *data
, unsigned length
)
2223 SHA512_Update(hash
->data
, data
, length
);
2227 sha512_finish(__ops_hash_t
*hash
, uint8_t *out
)
2229 SHA512_Final(out
, hash
->data
);
2230 (void) free(hash
->data
);
2232 return SHA512_DIGEST_LENGTH
;
2235 static __ops_hash_t __sha512
= {
2237 SHA512_DIGEST_LENGTH
,
2246 __ops_hash_sha512(__ops_hash_t
*hash
)
2257 sha224_init(__ops_hash_t
*hash
)
2260 loggit("sha224_init: hash data non-null");
2262 hash
->data
= __ops_new(sizeof(SHA256_CTX
));
2263 SHA224_Init(hash
->data
);
2267 sha224_add(__ops_hash_t
*hash
, const uint8_t *data
, unsigned length
)
2269 SHA224_Update(hash
->data
, data
, length
);
2273 sha224_finish(__ops_hash_t
*hash
, uint8_t *out
)
2275 SHA224_Final(out
, hash
->data
);
2276 (void) free(hash
->data
);
2278 return SHA224_DIGEST_LENGTH
;
2281 static __ops_hash_t __sha224
= {
2283 SHA224_DIGEST_LENGTH
,
2292 __ops_hash_sha224(__ops_hash_t
*hash
)
2299 \ingroup Core_Hashes
2300 \brief Add to the hash
2301 \param hash Hash to add to
2303 \param length Length of int in bytes
2306 __ops_hash_add_int(__ops_hash_t
*hash
, unsigned n
, unsigned length
)
2311 c
= n
>> (length
* 8);
2312 hash
->add(hash
, &c
, 1);
2316 static void __ops_build_pubkey(const __ops_pubkey_t
*, __ops_memory_t
*);
2319 * \ingroup Core_Keys
2320 * \brief Calculate a public key fingerprint.
2321 * \param fp Where to put the calculated fingerprint
2322 * \param key The key for which the fingerprint is calculated
2326 __ops_fingerprint(__ops_fingerprint_t
*fp
, const __ops_pubkey_t
*key
)
2328 if (key
->version
== 2 || key
->version
== 3) {
2333 if (key
->alg
!= OPS_PKA_RSA
&&
2334 key
->alg
!= OPS_PKA_RSA_ENCRYPT_ONLY
&&
2335 key
->alg
!= OPS_PKA_RSA_SIGN_ONLY
) {
2336 loggit("__ops_fingerprint: bad algorithm");
2339 /* start the md5 digest */
2340 __ops_hash_md5(&md5
);
2342 n
= BN_num_bytes(key
->key
.rsa
.n
);
2343 /* add the digests of the RSA numbers */
2345 BN_bn2bin(key
->key
.rsa
.n
, bn
);
2346 md5
.add(&md5
, bn
, n
);
2348 n
= BN_num_bytes(key
->key
.rsa
.e
);
2350 BN_bn2bin(key
->key
.rsa
.e
, bn
);
2351 md5
.add(&md5
, bn
, n
);
2353 fp
->length
= md5
.finish(&md5
, fp
->fingerprint
);
2355 __ops_memory_t
*mem
;
2359 mem
= __ops_new(sizeof(*mem
));
2360 __ops_build_pubkey(key
, mem
);
2362 __ops_hash_sha1(&sha1
);
2367 __ops_hash_add_int(&sha1
, 0x99, 1);
2368 __ops_hash_add_int(&sha1
, len
, 2);
2369 sha1
.add(&sha1
, mem
->buf
, len
);
2370 sha1
.finish(&sha1
, fp
->fingerprint
);
2372 fp
->length
= OPS_FINGERPRINT_SIZE
;
2374 __ops_memory_free(mem
);
2379 * \ingroup Core_Keys
2380 * \brief Calculate the Key ID from the public key.
2381 * \param keyid Space for the calculated ID to be stored
2382 * \param key The key for which the ID is calculated
2386 __ops_keyid(uint8_t *keyid
, const size_t idlen
, const __ops_pubkey_t
*key
)
2388 if (key
->version
== 2 || key
->version
== 3) {
2389 uint8_t bn
[NETPGP_BUFSIZ
];
2390 unsigned n
= BN_num_bytes(key
->key
.rsa
.n
);
2392 if (n
> sizeof(bn
)) {
2393 loggit("__ops_keyid: bad num bytes");
2396 if (key
->alg
!= OPS_PKA_RSA
&&
2397 key
->alg
!= OPS_PKA_RSA_ENCRYPT_ONLY
&&
2398 key
->alg
!= OPS_PKA_RSA_SIGN_ONLY
) {
2399 loggit("__ops_keyid: bad algorithm");
2402 BN_bn2bin(key
->key
.rsa
.n
, bn
);
2403 (void) memcpy(keyid
, bn
+ n
- idlen
, idlen
);
2405 __ops_fingerprint_t finger
;
2407 __ops_fingerprint(&finger
, key
);
2408 (void) memcpy(keyid
,
2409 finger
.fingerprint
+ finger
.length
- idlen
,
2415 \ingroup Core_Hashes
2416 \brief Setup hash for given hash algorithm
2417 \param hash Hash to set up
2418 \param alg Hash algorithm to use
2421 __ops_hash_any(__ops_hash_t
*hash
, __ops_hash_alg_t alg
)
2425 __ops_hash_md5(hash
);
2429 __ops_hash_sha1(hash
);
2432 case OPS_HASH_SHA256
:
2433 __ops_hash_sha256(hash
);
2437 case OPS_HASH_SHA384
:
2438 __ops_hash_sha384(hash
);
2442 case OPS_HASH_SHA512
:
2443 __ops_hash_sha512(hash
);
2447 case OPS_HASH_SHA224
:
2448 __ops_hash_sha224(hash
);
2453 loggit("__ops_hash_any: bad algorithm");
2458 \ingroup Core_Hashes
2459 \brief Returns size of hash for given hash algorithm
2460 \param alg Hash algorithm to use
2461 \return Size of hash algorithm in bytes
2464 __ops_hash_size(__ops_hash_alg_t alg
)
2473 case OPS_HASH_SHA256
:
2477 case OPS_HASH_SHA224
:
2482 case OPS_HASH_SHA384
:
2486 case OPS_HASH_SHA512
:
2490 loggit("__ops_hash_size: bad algorithm");
2497 \ingroup Core_Hashes
2498 \brief Returns hash enum corresponding to given string
2499 \param hash Text name of hash algorithm i.e. "SHA1"
2500 \returns Corresponding enum i.e. OPS_HASH_SHA1
2502 static __ops_hash_alg_t
2503 __ops_str_to_hash_alg(const char *hash
)
2505 if (strcmp(hash
, "SHA1") == 0) {
2506 return OPS_HASH_SHA1
;
2508 if (strcmp(hash
, "MD5") == 0) {
2509 return OPS_HASH_MD5
;
2511 if (strcmp(hash
, "SHA256") == 0) {
2512 return OPS_HASH_SHA256
;
2516 if (strcmp(hash,"SHA224") == 0) {
2517 return OPS_HASH_SHA224;
2522 if (strcmp(hash
, "SHA384") == 0) {
2523 return OPS_HASH_SHA384
;
2526 if (strcmp(hash
, "SHA512") == 0) {
2527 return OPS_HASH_SHA512
;
2529 return OPS_HASH_UNKNOWN
;
2534 \ingroup Core_Hashes
2535 \brief Calculate hash for MDC packet
2536 \param preamble Preamble to hash
2537 \param sz_preamble Size of preamble
2538 \param plaintext Plaintext to hash
2539 \param sz_plaintext Size of plaintext
2540 \param hashed Resulting hash
2543 __ops_calc_mdc_hash(const uint8_t *preamble
,
2544 const size_t sz_preamble
,
2545 const uint8_t *plaintext
,
2546 const unsigned int sz_plaintext
,
2553 __ops_hash_any(&hash
, OPS_HASH_SHA1
);
2557 hash
.add(&hash
, preamble
, sz_preamble
);
2559 hash
.add(&hash
, plaintext
, sz_plaintext
);
2560 /* MDC packet tag */
2562 hash
.add(&hash
, &c
, 1);
2563 /* MDC packet len */
2564 c
= OPS_SHA1_HASH_SIZE
;
2565 hash
.add(&hash
, &c
, 1);
2568 hash
.finish(&hash
, hashed
);
2572 \ingroup HighLevel_Supported
2573 \brief Is this Hash Algorithm supported?
2574 \param hash_alg Hash Algorithm to check
2575 \return 1 if supported; else 0
2578 __ops_is_hash_alg_supported(const __ops_hash_alg_t
*hash_alg
)
2580 switch (*hash_alg
) {
2583 case OPS_HASH_SHA256
:
2593 \ingroup HighLevel_Memory
2594 \brief Memory to initialise
2595 \param mem memory to initialise
2596 \param needed Size to initialise to
2599 __ops_memory_init(__ops_memory_t
*mem
, size_t needed
)
2603 if (mem
->allocated
< needed
) {
2604 mem
->buf
= realloc(mem
->buf
, needed
);
2605 mem
->allocated
= needed
;
2609 mem
->buf
= __ops_new(needed
);
2610 mem
->allocated
= needed
;
2614 \ingroup HighLevel_Memory
2615 \brief Pad memory to required length
2616 \param mem Memory to use
2617 \param length New size
2620 __ops_memory_pad(__ops_memory_t
*mem
, size_t length
)
2622 if (mem
->allocated
< mem
->length
) {
2623 loggit("__ops_memory_pad: bad alloc in");
2626 if (mem
->allocated
< mem
->length
+ length
) {
2627 mem
->allocated
= (mem
->allocated
* 2) + length
;
2628 mem
->buf
= realloc(mem
->buf
, mem
->allocated
);
2630 if (mem
->allocated
< mem
->length
+ length
) {
2631 loggit("__ops_memory_pad: bad alloc out");
2636 \ingroup HighLevel_Memory
2637 \brief Add data to memory
2638 \param mem Memory to which to add
2639 \param src Data to add
2640 \param length Length of data to add
2643 __ops_memory_add(__ops_memory_t
*mem
, const uint8_t *src
, size_t length
)
2645 __ops_memory_pad(mem
, length
);
2646 (void) memcpy(mem
->buf
+ mem
->length
, src
, length
);
2647 mem
->length
+= length
;
2650 /* read a file into an __ops_memory_t */
2652 __ops_mem_readfile(__ops_memory_t
*mem
, const char *f
)
2658 if ((fp
= fopen(f
, "rb")) == NULL
) {
2659 loggit( "__ops_mem_readfile: can't open \"%s\"", f
);
2662 (void) fstat(fileno(fp
), &st
);
2663 mem
->allocated
= (size_t)st
.st_size
;
2664 mem
->buf
= mmap(NULL
, mem
->allocated
, PROT_READ
,
2665 MAP_FILE
| MAP_PRIVATE
, fileno(fp
), 0);
2666 if (mem
->buf
== MAP_FAILED
) {
2667 /* mmap failed for some reason - try to allocate memory */
2668 if ((mem
->buf
= __ops_new(mem
->allocated
)) == NULL
) {
2669 loggit("__ops_mem_readfile: alloc");
2673 /* read into contents of mem */
2674 for (mem
->length
= 0 ;
2675 (cc
= read(fileno(fp
), &mem
->buf
[mem
->length
],
2676 mem
->allocated
- mem
->length
)) > 0 ;
2677 mem
->length
+= (size_t)cc
) {
2680 mem
->length
= mem
->allocated
;
2684 return (mem
->allocated
== mem
->length
);
2692 * XXX: replace __ops_ptag_t with something more appropriate for limiting reads
2696 * low-level function to read data from reader function
2698 * Use this function, rather than calling the reader directly.
2700 * If the accumulate flag is set in *stream, the function
2701 * adds the read data to the accumulated data, and updates
2702 * the accumulated length. This is useful if, for example,
2703 * the application wants access to the raw data as well as the
2706 * This function will also try to read the entire amount asked for, but not
2707 * if it is over INT_MAX. Obviously many callers will know that they
2708 * never ask for that much and so can avoid the extra complexity of
2709 * dealing with return codes and filled-in lengths.
2717 * \return OPS_R_PARTIAL_READ
2719 * \return OPS_R_EARLY_EOF
2721 * \sa #__ops_reader_ret_t for details of return codes
2725 sub_base_read(void *dest
, size_t length
, __ops_error_t
**errors
,
2726 __ops_reader_t
*readinfo
, __ops_cbdata_t
*cbdata
)
2730 /* reading more than this would look like an error */
2731 if (length
> INT_MAX
) {
2735 for (n
= 0; n
< length
;) {
2738 r
= readinfo
->reader((char *) dest
+ n
, length
- n
, errors
,
2740 if (r
> (int)(length
- n
)) {
2741 loggit("sub_base_read: bad read");
2756 if (readinfo
->accumulate
) {
2757 if (readinfo
->asize
< readinfo
->alength
) {
2758 loggit("sub_base_read: bad size");
2761 if (readinfo
->alength
+ n
> readinfo
->asize
) {
2762 readinfo
->asize
= readinfo
->asize
* 2 + n
;
2763 readinfo
->accumulated
= realloc(readinfo
->accumulated
,
2766 if (readinfo
->asize
< readinfo
->alength
+ n
) {
2767 loggit("sub_base_read: bad realloc");
2770 (void) memcpy(readinfo
->accumulated
+ readinfo
->alength
, dest
,
2773 /* we track length anyway, because it is used for packet offsets */
2774 readinfo
->alength
+= n
;
2775 /* and also the position */
2776 readinfo
->position
+= n
;
2782 __ops_stacked_read(void *dest
, size_t length
, __ops_error_t
**errors
,
2783 __ops_reader_t
*readinfo
, __ops_cbdata_t
*cbdata
)
2785 return sub_base_read(dest
, length
, errors
, readinfo
->next
, cbdata
);
2789 sum16_reader(void *destarg
, size_t length
, __ops_error_t
**errors
,
2790 __ops_reader_t
*readinfo
, __ops_cbdata_t
*cbdata
)
2792 const uint8_t *dest
= destarg
;
2797 arg
= readinfo
->arg
;
2798 r
= __ops_stacked_read(destarg
, length
, errors
, readinfo
, cbdata
);
2802 for (n
= 0; n
< r
; ++n
) {
2803 arg
->sum
= (arg
->sum
+ dest
[n
]) & 0xffff;
2809 sum16_destroyer(__ops_reader_t
*readinfo
)
2811 (void) free(readinfo
->arg
);
2815 * \ingroup Internal_Readers_Generic
2816 * \brief Starts reader stack
2817 * \param stream Parse settings
2818 * \param reader Reader to use
2819 * \param destroyer Destroyer to use
2820 * \param vp Reader-specific arg
2823 __ops_reader_set(__ops_stream_t
*stream
,
2824 int (*reader
)(void *, size_t, __ops_error_t
**,
2825 __ops_reader_t
*, __ops_cbdata_t
*),
2826 void (*destroyer
)(__ops_reader_t
*),
2829 stream
->readinfo
.reader
= reader
;
2830 stream
->readinfo
.destroyer
= destroyer
;
2831 stream
->readinfo
.arg
= vp
;
2835 * \ingroup Internal_Readers_Generic
2836 * \brief Adds to reader stack
2837 * \param stream Parse settings
2838 * \param reader Reader to use
2839 * \param destroyer Reader's destroyer
2840 * \param vp Reader-specific arg
2843 __ops_reader_push(__ops_stream_t
*stream
,
2844 int (*reader
)(void *, size_t, __ops_error_t
**,
2845 __ops_reader_t
*, __ops_cbdata_t
*),
2846 void (*destroyer
)(__ops_reader_t
*),
2849 __ops_reader_t
*readinfo
= __ops_new(sizeof(*readinfo
));
2851 *readinfo
= stream
->readinfo
;
2852 (void) memset(&stream
->readinfo
, 0x0, sizeof(stream
->readinfo
));
2853 stream
->readinfo
.next
= readinfo
;
2854 stream
->readinfo
.parent
= stream
;
2856 /* should copy accumulate flags from other reader? RW */
2857 stream
->readinfo
.accumulate
= readinfo
->accumulate
;
2859 __ops_reader_set(stream
, reader
, destroyer
, vp
);
2863 \ingroup Internal_Readers_Sum16
2864 \param stream Parse settings
2868 __ops_reader_push_sum16(__ops_stream_t
*stream
)
2872 arg
= __ops_new(sizeof(*arg
));
2873 __ops_reader_push(stream
, sum16_reader
, sum16_destroyer
, arg
);
2877 * \ingroup Internal_Readers_Generic
2878 * \brief Removes from reader stack
2879 * \param stream Parse settings
2882 __ops_reader_pop(__ops_stream_t
*stream
)
2884 __ops_reader_t
*next
= stream
->readinfo
.next
;
2886 stream
->readinfo
= *next
;
2891 \ingroup Internal_Readers_Sum16
2892 \param stream Parse settings
2896 __ops_reader_pop_sum16(__ops_stream_t
*stream
)
2901 arg
= stream
->readinfo
.arg
;
2903 __ops_reader_pop(stream
);
2908 /* return the version for the library */
2910 __ops_get_info(const char *type
)
2912 if (strcmp(type
, "version") == 0) {
2913 return NETPGP_VERSION_STRING
;
2915 if (strcmp(type
, "maintainer") == 0) {
2916 return NETPGP_MAINTAINER
;
2923 __ops_dsa_verify(const uint8_t *hash
, size_t hash_length
,
2924 const __ops_dsa_sig_t
*sig
,
2925 const __ops_dsa_pubkey_t
*dsa
)
2932 osig
= DSA_SIG_new();
2940 odsa
->pub_key
= dsa
->y
;
2942 if ((qlen
= BN_num_bytes(odsa
->q
)) < hash_length
) {
2945 ret
= DSA_do_verify(hash
, (int)hash_length
, osig
, odsa
);
2947 loggit("__ops_dsa_verify: DSA verification");
2951 odsa
->p
= odsa
->q
= odsa
->g
= odsa
->pub_key
= NULL
;
2954 osig
->r
= osig
->s
= NULL
;
2961 \ingroup Core_Crypto
2962 \brief Recovers message digest from the signature
2963 \param out Where to write decrypted data to
2964 \param in Encrypted data
2965 \param length Length of encrypted data
2966 \param pubkey RSA public key
2967 \return size of recovered message digest
2970 __ops_rsa_public_decrypt(uint8_t *out
,
2973 const __ops_rsa_pubkey_t
*pubkey
)
2979 orsa
->n
= pubkey
->n
;
2980 orsa
->e
= pubkey
->e
;
2982 n
= RSA_public_decrypt((int)length
, in
, out
, orsa
, RSA_NO_PADDING
);
2984 orsa
->n
= orsa
->e
= NULL
;
2991 \ingroup Core_Crypto
2992 \brief Decrypts RSA-encrypted data
2993 \param out Where to write the plaintext
2994 \param in Encrypted data
2995 \param length Length of encrypted data
2996 \param seckey RSA secret key
2997 \param pubkey RSA public key
2998 \return size of recovered plaintext
3001 __ops_rsa_private_decrypt(uint8_t *out
,
3004 const __ops_rsa_seckey_t
*seckey
,
3005 const __ops_rsa_pubkey_t
*pubkey
)
3011 keypair
= RSA_new();
3012 keypair
->n
= pubkey
->n
; /* XXX: do we need n? */
3013 keypair
->d
= seckey
->d
;
3014 keypair
->p
= seckey
->q
;
3015 keypair
->q
= seckey
->p
;
3018 keypair
->e
= pubkey
->e
;
3019 if (RSA_check_key(keypair
) != 1) {
3020 loggit("RSA_check_key is not set");
3025 n
= RSA_private_decrypt((int)length
, in
, out
, keypair
, RSA_NO_PADDING
);
3029 unsigned long err
= ERR_get_error();
3031 ERR_error_string(err
, &errbuf
[0]);
3032 loggit("openssl error : %s", errbuf
);
3034 keypair
->n
= keypair
->d
= keypair
->p
= keypair
->q
= NULL
;
3041 copy_sig_info(__ops_signinfo_t
*dst
, const __ops_signinfo_t
*src
)
3043 (void) memcpy(dst
, src
, sizeof(*src
));
3044 dst
->v4_hashed
= __ops_new(src
->v4_hashlen
);
3045 (void) memcpy(dst
->v4_hashed
, src
->v4_hashed
, src
->v4_hashlen
);
3049 add_sig_to_list(const __ops_signinfo_t
*sig
, __ops_signinfo_t
**sigs
,
3053 *sigs
= __ops_new((*count
+ 1) * sizeof(__ops_signinfo_t
));
3055 *sigs
= realloc(*sigs
,
3056 (*count
+ 1) * sizeof(__ops_signinfo_t
));
3058 copy_sig_info(&(*sigs
)[*count
], sig
);
3063 \ingroup HighLevel_KeyGeneral
3065 \brief Returns the public key in the given key.
3068 \return Pointer to public key
3070 \note This is not a copy, do not free it after use.
3073 static const __ops_pubkey_t
*
3074 __ops_get_pubkey(const __ops_key_t
*key
)
3076 return (key
->type
== OPS_PTAG_CT_PUBLIC_KEY
) ?
3078 &key
->key
.seckey
.pubkey
;
3082 \ingroup HighLevel_KeyringFind
3084 \brief Finds key in keyring from its Key ID
3086 \param keyring Keyring to be searched
3087 \param keyid ID of required key
3089 \return Pointer to key, if found; NULL, if not found
3091 \note This returns a pointer to the key inside the given keyring,
3092 not a copy. Do not free it after use.
3095 static const __ops_key_t
*
3096 __ops_getkeybyid(const __ops_keyring_t
*keyring
,
3097 const uint8_t keyid
[OPS_KEY_ID_SIZE
])
3101 for (n
= 0; keyring
&& n
< keyring
->keyc
; n
++) {
3102 if (memcmp(keyring
->keys
[n
].keyid
, keyid
,
3103 OPS_KEY_ID_SIZE
) == 0) {
3104 return &keyring
->keys
[n
];
3106 if (memcmp(&keyring
->keys
[n
].keyid
[OPS_KEY_ID_SIZE
/ 2],
3107 keyid
, OPS_KEY_ID_SIZE
/ 2) == 0) {
3108 return &keyring
->keys
[n
];
3115 __ops_check_sig(const uint8_t *, unsigned,
3116 const __ops_sig_t
*,
3117 const __ops_pubkey_t
*);
3119 /* Does the signed hash match the given hash? */
3121 check_binary_sig(const unsigned len
,
3122 const uint8_t *data
,
3123 const __ops_sig_t
*sig
,
3124 const __ops_pubkey_t
*signer
)
3126 uint8_t hashout
[OPS_MAX_HASH_SIZE
];
3128 unsigned int hashedlen
;
3133 __ops_hash_any(&hash
, sig
->info
.hash_alg
);
3135 hash
.add(&hash
, data
, len
);
3136 switch (sig
->info
.version
) {
3138 trailer
[0] = sig
->info
.type
;
3139 trailer
[1] = (unsigned)(sig
->info
.birthtime
) >> 24;
3140 trailer
[2] = (unsigned)(sig
->info
.birthtime
) >> 16;
3141 trailer
[3] = (unsigned)(sig
->info
.birthtime
) >> 8;
3142 trailer
[4] = (uint8_t)(sig
->info
.birthtime
);
3143 hash
.add(&hash
, &trailer
[0], 5);
3147 hash
.add(&hash
, sig
->info
.v4_hashed
, sig
->info
.v4_hashlen
);
3148 trailer
[0] = 0x04; /* version */
3150 hashedlen
= sig
->info
.v4_hashlen
;
3151 trailer
[2] = hashedlen
>> 24;
3152 trailer
[3] = hashedlen
>> 16;
3153 trailer
[4] = hashedlen
>> 8;
3154 trailer
[5] = hashedlen
;
3155 hash
.add(&hash
, trailer
, 6);
3159 loggit("Invalid signature version %d",
3163 n
= hash
.finish(&hash
, hashout
);
3164 return __ops_check_sig(hashout
, n
, sig
, signer
);
3167 static __ops_cb_ret_t
3168 validate_data_cb(__ops_cbdata_t
*cbdata
, const __ops_packet_t
*pkt
)
3170 const __ops_contents_t
*content
= &pkt
->u
;
3171 const __ops_key_t
*signer
;
3172 validate_data_cb_t
*data
;
3173 __ops_error_t
**errors
;
3179 errors
= cbdata
->errors
;
3181 case OPS_PTAG_CT_SIGNED_CLEARTEXT_HEADER
:
3183 * ignore - this gives us the "Armor Header" line "Hash:
3188 case OPS_PTAG_CT_LITDATA_HEADER
:
3192 case OPS_PTAG_CT_LITDATA_BODY
:
3193 data
->data
.litdata_body
= content
->litdata_body
;
3194 data
->type
= LITDATA
;
3195 __ops_memory_add(data
->mem
, data
->data
.litdata_body
.data
,
3196 data
->data
.litdata_body
.length
);
3197 return OPS_KEEP_MEMORY
;
3199 case OPS_PTAG_CT_SIGNED_CLEARTEXT_BODY
:
3200 data
->data
.cleartext_body
= content
->cleartext_body
;
3201 data
->type
= SIGNED_CLEARTEXT
;
3202 __ops_memory_add(data
->mem
, data
->data
.litdata_body
.data
,
3203 data
->data
.litdata_body
.length
);
3204 return OPS_KEEP_MEMORY
;
3206 case OPS_PTAG_CT_SIGNED_CLEARTEXT_TRAILER
:
3207 /* this gives us an __ops_hash_t struct */
3210 case OPS_PTAG_CT_SIGNATURE
: /* V3 sigs */
3211 case OPS_PTAG_CT_SIGNATURE_FOOTER
: /* V4 sigs */
3212 signer
= __ops_getkeybyid(data
->keyring
,
3213 content
->sig
.info
.signer
);
3215 OPS_ERROR(errors
, OPS_E_V_UNKNOWN_SIGNER
,
3217 add_sig_to_list(&content
->sig
.info
,
3218 &data
->result
->unknowns
,
3219 &data
->result
->unknownc
);
3222 switch (content
->sig
.info
.type
) {
3223 case OPS_SIG_BINARY
:
3225 if (data
->mem
->length
== 0 &&
3227 /* check we have seen some data */
3228 /* if not, need to read from detached name */
3230 "netpgp: assuming signed data in \"%s\"",
3232 data
->mem
= __ops_new(sizeof(*data
->mem
));
3233 __ops_mem_readfile(data
->mem
, data
->detachname
);
3235 valid
= check_binary_sig(data
->mem
->length
,
3238 __ops_get_pubkey(signer
));
3242 OPS_ERROR_1(errors
, OPS_E_UNIMPLEMENTED
,
3243 "No Sig Verification type 0x%02x yet\n",
3244 content
->sig
.info
.type
);
3250 add_sig_to_list(&content
->sig
.info
,
3251 &data
->result
->valids
,
3252 &data
->result
->validc
);
3254 OPS_ERROR(errors
, OPS_E_V_BAD_SIGNATURE
,
3256 add_sig_to_list(&content
->sig
.info
,
3257 &data
->result
->invalids
,
3258 &data
->result
->invalidc
);
3263 case OPS_PARSER_PTAG
:
3264 case OPS_PTAG_CT_SIGNATURE_HEADER
:
3265 case OPS_PTAG_CT_ARMOUR_HEADER
:
3266 case OPS_PTAG_CT_ARMOUR_TRAILER
:
3267 case OPS_PTAG_CT_1_PASS_SIG
:
3270 case OPS_PARSER_PACKET_END
:
3274 OPS_ERROR(errors
, OPS_E_V_NO_SIGNATURE
, "No signature");
3277 return OPS_RELEASE_MEMORY
;
3283 * \ingroup HighLevel_Verify
3284 * \brief Indicicates whether any errors were found
3285 * \param result Validation result to check
3286 * \return 0 if any invalid signatures or unknown signers
3287 or no valid signatures; else 1
3290 validate_result_status(__ops_validation_t
*val
)
3292 return val
->validc
&& !val
->invalidc
&& !val
->unknownc
;
3295 /* utility function to zero out memory */
3297 __ops_forget(void *vp
, unsigned size
)
3299 (void) memset(vp
, 0x0, size
);
3303 * \ingroup Core_ReadPackets
3305 * \brief Specifies whether one or more signature
3306 * subpacket types should be returned parsed; or raw; or ignored.
3308 * \param stream Pointer to previously allocated structure
3309 * \param tag Packet tag. OPS_PTAG_SS_ALL for all SS tags; or one individual signature subpacket tag
3310 * \param type Parse type
3311 * \todo Make all packet types optional, not just subpackets */
3313 __ops_stream_options(__ops_stream_t
*stream
,
3314 __ops_content_tag_t tag
,
3315 __ops_parse_type_t type
)
3319 if (tag
== OPS_PTAG_SS_ALL
) {
3322 for (n
= 0; n
< 256; ++n
) {
3323 __ops_stream_options(stream
,
3324 OPS_PTAG_SIG_SUBPKT_BASE
+ n
,
3329 if (tag
< OPS_PTAG_SIG_SUBPKT_BASE
||
3330 tag
> OPS_PTAG_SIG_SUBPKT_BASE
+ NTAGS
- 1) {
3331 loggit("__ops_stream_options: bad tag");
3334 t8
= (tag
- OPS_PTAG_SIG_SUBPKT_BASE
) / 8;
3335 t7
= 1 << ((tag
- OPS_PTAG_SIG_SUBPKT_BASE
) & 7);
3338 stream
->ss_raw
[t8
] |= t7
;
3339 stream
->ss_parsed
[t8
] &= ~t7
;
3342 case OPS_PARSE_PARSED
:
3343 stream
->ss_raw
[t8
] &= ~t7
;
3344 stream
->ss_parsed
[t8
] |= t7
;
3347 case OPS_PARSE_IGNORE
:
3348 stream
->ss_raw
[t8
] &= ~t7
;
3349 stream
->ss_parsed
[t8
] &= ~t7
;
3355 \ingroup Core_ReadPackets
3356 \brief Free __ops_stream_t struct and its contents
3359 __ops_stream_delete(__ops_stream_t
*stream
)
3361 __ops_cbdata_t
*cbdata
;
3362 __ops_cbdata_t
*next
;
3364 for (cbdata
= stream
->cbdata
.next
; cbdata
; cbdata
= next
) {
3365 next
= cbdata
->next
;
3366 (void) free(cbdata
);
3368 if (stream
->readinfo
.destroyer
) {
3369 stream
->readinfo
.destroyer(&stream
->readinfo
);
3371 __ops_free_errors(stream
->errors
);
3372 if (stream
->readinfo
.accumulated
) {
3373 (void) free(stream
->readinfo
.accumulated
);
3375 (void) free(stream
);
3378 static uint8_t prefix_md5
[] = {
3379 0x30, 0x20, 0x30, 0x0C, 0x06, 0x08, 0x2A, 0x86, 0x48, 0x86,
3380 0xF7, 0x0D, 0x02, 0x05, 0x05, 0x00, 0x04, 0x10
3383 static uint8_t prefix_sha1
[] = {
3384 0x30, 0x21, 0x30, 0x09, 0x06, 0x05, 0x2b, 0x0E, 0x03, 0x02,
3385 0x1A, 0x05, 0x00, 0x04, 0x14
3388 static uint8_t prefix_sha256
[] = {
3389 0x30, 0x31, 0x30, 0x0d, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01,
3390 0x65, 0x03, 0x04, 0x02, 0x01, 0x05, 0x00, 0x04, 0x20
3394 rsa_verify(__ops_hash_alg_t type
,
3395 const uint8_t *hash
,
3397 const __ops_rsa_sig_t
*sig
,
3398 const __ops_rsa_pubkey_t
*pubrsa
)
3400 const uint8_t *prefix
;
3404 uint8_t sigbuf
[NETPGP_BUFSIZ
];
3405 uint8_t hashbuf_from_sig
[NETPGP_BUFSIZ
];
3408 prefix
= (const uint8_t *) "";
3409 keysize
= BN_num_bytes(pubrsa
->n
);
3410 /* RSA key can't be bigger than 65535 bits, so... */
3411 if (keysize
> sizeof(hashbuf_from_sig
)) {
3412 loggit("rsa_verify: keysize too big");
3415 if ((unsigned) BN_num_bits(sig
->sig
) > 8 * sizeof(sigbuf
)) {
3416 loggit("rsa_verify: BN_numbits too big");
3419 BN_bn2bin(sig
->sig
, sigbuf
);
3421 n
= __ops_rsa_public_decrypt(hashbuf_from_sig
, sigbuf
,
3422 (unsigned)(BN_num_bits(sig
->sig
) + 7) / 8, pubrsa
);
3425 /* obviously, this includes error returns */
3429 /* XXX: why is there a leading 0? The first byte should be 1... */
3430 /* XXX: because the decrypt should use keysize and not sigsize? */
3431 if (hashbuf_from_sig
[0] != 0 || hashbuf_from_sig
[1] != 1) {
3437 prefix
= prefix_md5
;
3438 plen
= sizeof(prefix_md5
);
3441 prefix
= prefix_sha1
;
3442 plen
= sizeof(prefix_sha1
);
3444 case OPS_HASH_SHA256
:
3445 prefix
= prefix_sha256
;
3446 plen
= sizeof(prefix_sha256
);
3449 loggit("Unknown hash algorithm: %d", type
);
3453 if (keysize
- plen
- hash_length
< 10) {
3457 for (n
= 2; n
< keysize
- plen
- hash_length
- 1; ++n
) {
3458 if (hashbuf_from_sig
[n
] != 0xff) {
3463 if (hashbuf_from_sig
[n
++] != 0) {
3467 return (memcmp(&hashbuf_from_sig
[n
], prefix
, plen
) == 0 &&
3468 memcmp(&hashbuf_from_sig
[n
+ plen
], hash
, hash_length
) == 0);
3472 \ingroup Core_Signature
3473 \brief Checks a signature
3474 \param hash Signature Hash to be checked
3475 \param length Signature Length
3476 \param sig The Signature to be checked
3477 \param signer The signer's public key
3478 \return 1 if good; else 0
3481 __ops_check_sig(const uint8_t *hash
, unsigned length
,
3482 const __ops_sig_t
* sig
,
3483 const __ops_pubkey_t
* signer
)
3488 switch (sig
->info
.key_alg
) {
3490 ret
= __ops_dsa_verify(hash
, length
, &sig
->info
.sig
.dsa
,
3494 ret
= rsa_verify(sig
->info
.hash_alg
, hash
, length
,
3499 loggit("__ops_check_sig: unusual alg");
3507 * return 1 if OK, otherwise 0
3510 base_write(const void *src
, unsigned len
, __ops_output_t
*out
)
3512 return out
->writer
.writer(&out
->writer
, src
, len
, &out
->errors
);
3516 * \ingroup Core_WritePackets
3521 * \return 1 if OK, otherwise 0
3525 __ops_write(__ops_output_t
*output
, const void *src
, unsigned len
)
3527 return base_write(src
, len
, output
);
3531 * \ingroup Core_WritePackets
3535 * \return 1 if OK, otherwise 0
3538 __ops_write_scalar(__ops_output_t
*output
, unsigned n
, unsigned len
)
3544 if (!base_write(&c
, 1, output
)) {
3552 * \ingroup Core_WritePackets
3555 * \return 1 if OK, otherwise 0
3559 __ops_write_mpi(__ops_output_t
*output
, const BIGNUM
*bn
)
3561 uint8_t buf
[NETPGP_BUFSIZ
];
3562 unsigned bits
= (unsigned)BN_num_bits(bn
);
3565 loggit("__ops_write_mpi: too large %u", bits
);
3569 return __ops_write_scalar(output
, bits
, 2) &&
3570 __ops_write(output
, buf
, (bits
+ 7) / 8);
3574 * Note that we support v3 keys here because they're needed for for
3575 * verification - the writer doesn't allow them, though
3578 write_pubkey_body(__ops_output_t
*output
, const __ops_pubkey_t
*key
)
3580 if (!(__ops_write_scalar(output
, (unsigned)key
->version
, 1) &&
3581 __ops_write_scalar(output
, (unsigned)key
->birthtime
, 4))) {
3584 if (key
->version
!= 4 &&
3585 !__ops_write_scalar(output
, key
->days_valid
, 2)) {
3588 if (!__ops_write_scalar(output
, (unsigned)key
->alg
, 1)) {
3593 return __ops_write_mpi(output
, key
->key
.dsa
.p
) &&
3594 __ops_write_mpi(output
, key
->key
.dsa
.q
) &&
3595 __ops_write_mpi(output
, key
->key
.dsa
.g
) &&
3596 __ops_write_mpi(output
, key
->key
.dsa
.y
);
3599 case OPS_PKA_RSA_ENCRYPT_ONLY
:
3600 case OPS_PKA_RSA_SIGN_ONLY
:
3601 return __ops_write_mpi(output
, key
->key
.rsa
.n
) &&
3602 __ops_write_mpi(output
, key
->key
.rsa
.e
);
3604 case OPS_PKA_ELGAMAL
:
3605 return __ops_write_mpi(output
, key
->key
.elgamal
.p
) &&
3606 __ops_write_mpi(output
, key
->key
.elgamal
.g
) &&
3607 __ops_write_mpi(output
, key
->key
.elgamal
.y
);
3609 loggit("write_pubkey_body: bad algorithm");
3616 memory_writer(__ops_writer_t
*writer
,
3619 __ops_error_t
**errors
)
3621 __ops_memory_t
*mem
;
3625 __ops_memory_add(mem
, src
, len
);
3630 * \ingroup Core_Writers
3632 * Set a writer in output. There should not be another writer set.
3634 * \param output The output structure
3638 * \param arg The argument for the writer and destroyer
3641 __ops_writer_set(__ops_output_t
*output
,
3642 unsigned (*writer
)(__ops_writer_t
*, const uint8_t *, unsigned,
3644 unsigned (*finaliser
)(__ops_error_t
**, __ops_writer_t
*),
3645 void (*destroyer
)(__ops_writer_t
*),
3648 if (output
->writer
.writer
) {
3649 loggit("__ops_writer_set: already set");
3651 output
->writer
.writer
= writer
;
3652 output
->writer
.finaliser
= finaliser
;
3653 output
->writer
.destroyer
= destroyer
;
3654 output
->writer
.arg
= arg
;
3660 * \ingroup Core_WritersFirst
3661 * \brief Write to memory
3663 * Set a memory writer.
3665 * \param output The output structure
3666 * \param mem The memory structure
3667 * \note It is the caller's responsiblity to call __ops_memory_free(mem)
3668 * \sa __ops_memory_free()
3671 __ops_writer_set_memory(__ops_output_t
*output
, __ops_memory_t
*mem
)
3673 __ops_writer_set(output
, memory_writer
, NULL
, NULL
, mem
);
3677 writer_info_delete(__ops_writer_t
*writer
)
3679 /* we should have finalised before deleting */
3680 if (writer
->finaliser
) {
3681 loggit("writer_info_delete: not finalised");
3685 writer_info_delete(writer
->next
);
3687 writer
->next
= NULL
;
3689 if (writer
->destroyer
) {
3690 writer
->destroyer(writer
);
3691 writer
->destroyer
= NULL
;
3693 writer
->writer
= NULL
;
3697 * \ingroup Core_Create
3698 * \brief Delete an __ops_output_t strucut and associated resources.
3700 * Delete an __ops_output_t structure. If a writer is active, then
3701 * that is also deleted.
3703 * \param info the structure to be deleted.
3706 __ops_output_delete(__ops_output_t
*output
)
3708 writer_info_delete(&output
->writer
);
3709 (void) free(output
);
3714 * \ingroup Core_Create
3717 * \param make_packet
3720 __ops_build_pubkey(const __ops_pubkey_t
*key
, __ops_memory_t
*out
)
3722 __ops_output_t
*output
;
3724 output
= __ops_new(sizeof(*output
));
3725 __ops_memory_init(out
, 128);
3726 __ops_writer_set_memory(output
, out
);
3727 write_pubkey_body(output
, key
);
3728 __ops_output_delete(output
);
3732 static unsigned __ops_key_size(__ops_symm_alg_t
);
3734 static __ops_map_t pubkeyalgs
[] = {
3735 {OPS_PKA_RSA
, "RSA (Encrypt or Sign)"},
3736 {OPS_PKA_RSA_ENCRYPT_ONLY
, "RSA Encrypt-Only"},
3737 {OPS_PKA_RSA_SIGN_ONLY
, "RSA Sign-Only"},
3738 {OPS_PKA_ELGAMAL
, "Elgamal (Encrypt-Only)"},
3739 {OPS_PKA_DSA
, "DSA"},
3740 {OPS_PKA_RESERVED_ELLIPTIC_CURVE
, "Reserved for Elliptic Curve"},
3741 {OPS_PKA_RESERVED_ECDSA
, "Reserved for ECDSA"},
3742 {OPS_PKA_ELGAMAL_ENCRYPT_OR_SIGN
,
3743 "Reserved (formerly Elgamal Encrypt or Sign"},
3744 {OPS_PKA_RESERVED_DH
, "Reserved for Diffie-Hellman (X9.42)"},
3745 {OPS_PKA_PRIVATE00
, "Private/Experimental"},
3746 {OPS_PKA_PRIVATE01
, "Private/Experimental"},
3747 {OPS_PKA_PRIVATE02
, "Private/Experimental"},
3748 {OPS_PKA_PRIVATE03
, "Private/Experimental"},
3749 {OPS_PKA_PRIVATE04
, "Private/Experimental"},
3750 {OPS_PKA_PRIVATE05
, "Private/Experimental"},
3751 {OPS_PKA_PRIVATE06
, "Private/Experimental"},
3752 {OPS_PKA_PRIVATE07
, "Private/Experimental"},
3753 {OPS_PKA_PRIVATE08
, "Private/Experimental"},
3754 {OPS_PKA_PRIVATE09
, "Private/Experimental"},
3755 {OPS_PKA_PRIVATE10
, "Private/Experimental"},
3759 static __ops_map_t symm_alg_map
[] = {
3760 {OPS_SA_PLAINTEXT
, "Plaintext or unencrypted data"},
3761 {OPS_SA_IDEA
, "IDEA"},
3762 {OPS_SA_TRIPLEDES
, "TripleDES"},
3763 {OPS_SA_CAST5
, "CAST5"},
3764 {OPS_SA_BLOWFISH
, "Blowfish"},
3765 {OPS_SA_AES_128
, "AES (128-bit key)"},
3766 {OPS_SA_AES_192
, "AES (192-bit key)"},
3767 {OPS_SA_AES_256
, "AES (256-bit key)"},
3768 {OPS_SA_TWOFISH
, "Twofish(256-bit key)"},
3773 \ingroup HighLevel_Supported
3774 \brief Is this Symmetric Algorithm supported?
3775 \param alg Symmetric Algorithm to check
3776 \return 1 if supported; else 0
3779 __ops_is_sa_supported(__ops_symm_alg_t alg
)
3782 case OPS_SA_AES_128
:
3783 case OPS_SA_AES_256
:
3785 case OPS_SA_TRIPLEDES
:
3786 #ifndef OPENSSL_NO_IDEA
3792 loggit("\nWarning: %s not supported",
3793 findtype((int) alg
, symm_alg_map
));
3799 \ingroup Core_Create
3800 \brief Calculate the checksum for a session key
3801 \param sesskey Session Key to use
3802 \param cs Checksum to be written
3803 \return 1 if OK; else 0
3806 __ops_calc_sesskey_checksum(__ops_pk_sesskey_t
*sesskey
, uint8_t *cs
)
3809 unsigned long checksum
= 0;
3811 if (!__ops_is_sa_supported(sesskey
->symm_alg
)) {
3815 for (i
= 0; i
< __ops_key_size(sesskey
->symm_alg
); i
++) {
3816 checksum
+= sesskey
->key
[i
];
3818 checksum
= checksum
% 65536;
3820 cs
[0] = (uint8_t)((checksum
>> 8) & 0xff);
3821 cs
[1] = (uint8_t)(checksum
& 0xff);
3827 std_set_iv(__ops_crypt_t
*cryp
, const uint8_t *iv
)
3829 (void) memcpy(cryp
->iv
, iv
, cryp
->blocksize
);
3834 std_set_key(__ops_crypt_t
*cryp
, const uint8_t *key
)
3836 (void) memcpy(cryp
->key
, key
, cryp
->keysize
);
3840 std_resync(__ops_crypt_t
*decrypt
)
3842 if ((size_t) decrypt
->num
== decrypt
->blocksize
) {
3845 memmove(decrypt
->civ
+ decrypt
->blocksize
- decrypt
->num
, decrypt
->civ
,
3846 (unsigned)decrypt
->num
);
3847 (void) memcpy(decrypt
->civ
, decrypt
->siv
+ decrypt
->num
,
3848 decrypt
->blocksize
- decrypt
->num
);
3853 std_finish(__ops_crypt_t
*cryp
)
3855 if (cryp
->encrypt_key
) {
3856 free(cryp
->encrypt_key
);
3857 cryp
->encrypt_key
= NULL
;
3859 if (cryp
->decrypt_key
) {
3860 free(cryp
->decrypt_key
);
3861 cryp
->decrypt_key
= NULL
;
3866 cast5_init(__ops_crypt_t
*cryp
)
3868 if (cryp
->encrypt_key
) {
3869 (void) free(cryp
->encrypt_key
);
3871 cryp
->encrypt_key
= __ops_new(sizeof(CAST_KEY
));
3872 CAST_set_key(cryp
->encrypt_key
, (int)cryp
->keysize
, cryp
->key
);
3873 cryp
->decrypt_key
= __ops_new(sizeof(CAST_KEY
));
3874 CAST_set_key(cryp
->decrypt_key
, (int)cryp
->keysize
, cryp
->key
);
3878 cast5_block_encrypt(__ops_crypt_t
*cryp
, void *out
, const void *in
)
3880 CAST_ecb_encrypt(in
, out
, cryp
->encrypt_key
, CAST_ENCRYPT
);
3884 cast5_block_decrypt(__ops_crypt_t
*cryp
, void *out
, const void *in
)
3886 CAST_ecb_encrypt(in
, out
, cryp
->encrypt_key
, CAST_DECRYPT
);
3890 cast5_cfb_encrypt(__ops_crypt_t
*cryp
, void *out
, const void *in
, size_t count
)
3892 CAST_cfb64_encrypt(in
, out
, (long)count
,
3893 cryp
->encrypt_key
, cryp
->iv
, &cryp
->num
,
3898 cast5_cfb_decrypt(__ops_crypt_t
*cryp
, void *out
, const void *in
, size_t count
)
3900 CAST_cfb64_encrypt(in
, out
, (long)count
,
3901 cryp
->encrypt_key
, cryp
->iv
, &cryp
->num
,
3905 #define TRAILER "","","","",0,NULL,NULL
3907 static __ops_crypt_t cast5
=
3916 cast5_block_encrypt
,
3917 cast5_block_decrypt
,
3924 #ifndef OPENSSL_NO_IDEA
3926 idea_init(__ops_crypt_t
*cryp
)
3928 if (cryp
->keysize
!= IDEA_KEY_LENGTH
) {
3929 loggit("idea_init: keysize wrong");
3933 if (cryp
->encrypt_key
) {
3934 (void) free(cryp
->encrypt_key
);
3936 cryp
->encrypt_key
= __ops_new(sizeof(IDEA_KEY_SCHEDULE
));
3938 /* note that we don't invert the key when decrypting for CFB mode */
3939 idea_set_encrypt_key(cryp
->key
, cryp
->encrypt_key
);
3941 if (cryp
->decrypt_key
) {
3942 (void) free(cryp
->decrypt_key
);
3944 cryp
->decrypt_key
= __ops_new(sizeof(IDEA_KEY_SCHEDULE
));
3946 idea_set_decrypt_key(cryp
->encrypt_key
, cryp
->decrypt_key
);
3950 idea_block_encrypt(__ops_crypt_t
*cryp
, void *out
, const void *in
)
3952 idea_ecb_encrypt(in
, out
, cryp
->encrypt_key
);
3956 idea_block_decrypt(__ops_crypt_t
*cryp
, void *out
, const void *in
)
3958 idea_ecb_encrypt(in
, out
, cryp
->decrypt_key
);
3962 idea_cfb_encrypt(__ops_crypt_t
*cryp
, void *out
, const void *in
, size_t count
)
3964 idea_cfb64_encrypt(in
, out
, (long)count
,
3965 cryp
->encrypt_key
, cryp
->iv
, &cryp
->num
,
3970 idea_cfb_decrypt(__ops_crypt_t
*cryp
, void *out
, const void *in
, size_t count
)
3972 idea_cfb64_encrypt(in
, out
, (long)count
,
3973 cryp
->decrypt_key
, cryp
->iv
, &cryp
->num
,
3977 static const __ops_crypt_t idea
=
3993 #endif /* OPENSSL_NO_IDEA */
3995 /* AES with 128-bit key (AES) */
3997 #define KEYBITS_AES128 128
4000 aes128_init(__ops_crypt_t
*cryp
)
4002 if (cryp
->encrypt_key
) {
4003 (void) free(cryp
->encrypt_key
);
4005 cryp
->encrypt_key
= __ops_new(sizeof(AES_KEY
));
4006 if (AES_set_encrypt_key(cryp
->key
, KEYBITS_AES128
,
4007 cryp
->encrypt_key
)) {
4008 loggit("aes128_init: Error setting encrypt_key");
4011 if (cryp
->decrypt_key
) {
4012 (void) free(cryp
->decrypt_key
);
4014 cryp
->decrypt_key
= __ops_new(sizeof(AES_KEY
));
4015 if (AES_set_decrypt_key(cryp
->key
, KEYBITS_AES128
,
4016 cryp
->decrypt_key
)) {
4017 loggit("aes128_init: Error setting decrypt_key");
4022 aes_block_encrypt(__ops_crypt_t
*cryp
, void *out
, const void *in
)
4024 AES_encrypt(in
, out
, cryp
->encrypt_key
);
4028 aes_block_decrypt(__ops_crypt_t
*cryp
, void *out
, const void *in
)
4030 AES_decrypt(in
, out
, cryp
->decrypt_key
);
4034 aes_cfb_encrypt(__ops_crypt_t
*cryp
, void *out
, const void *in
, size_t count
)
4036 AES_cfb128_encrypt(in
, out
, (unsigned long)count
,
4037 cryp
->encrypt_key
, cryp
->iv
, &cryp
->num
,
4042 aes_cfb_decrypt(__ops_crypt_t
*cryp
, void *out
, const void *in
, size_t count
)
4044 AES_cfb128_encrypt(in
, out
, (unsigned long)count
,
4045 cryp
->encrypt_key
, cryp
->iv
, &cryp
->num
,
4049 static const __ops_crypt_t aes128
=
4066 /* AES with 256-bit key */
4068 #define KEYBITS_AES256 256
4071 aes256_init(__ops_crypt_t
*cryp
)
4073 if (cryp
->encrypt_key
) {
4074 (void) free(cryp
->encrypt_key
);
4076 cryp
->encrypt_key
= __ops_new(sizeof(AES_KEY
));
4077 if (AES_set_encrypt_key(cryp
->key
, KEYBITS_AES256
,
4078 cryp
->encrypt_key
)) {
4079 loggit("aes256_init: Error setting encrypt_key");
4082 if (cryp
->decrypt_key
)
4083 free(cryp
->decrypt_key
);
4084 cryp
->decrypt_key
= __ops_new(sizeof(AES_KEY
));
4085 if (AES_set_decrypt_key(cryp
->key
, KEYBITS_AES256
,
4086 cryp
->decrypt_key
)) {
4087 loggit("aes256_init: Error setting decrypt_key");
4091 static const __ops_crypt_t aes256
=
4111 tripledes_init(__ops_crypt_t
*cryp
)
4113 DES_key_schedule
*keys
;
4116 if (cryp
->encrypt_key
) {
4117 (void) free(cryp
->encrypt_key
);
4119 keys
= cryp
->encrypt_key
= __ops_new(3 * sizeof(DES_key_schedule
));
4121 for (n
= 0; n
< 3; ++n
) {
4122 DES_set_key((DES_cblock
*)(void *)(cryp
->key
+ n
* 8),
4128 tripledes_block_encrypt(__ops_crypt_t
*cryp
, void *out
, const void *in
)
4130 DES_key_schedule
*keys
= cryp
->encrypt_key
;
4132 DES_ecb3_encrypt(__UNCONST(in
), out
, &keys
[0], &keys
[1], &keys
[2],
4137 tripledes_block_decrypt(__ops_crypt_t
*cryp
, void *out
, const void *in
)
4139 DES_key_schedule
*keys
= cryp
->encrypt_key
;
4141 DES_ecb3_encrypt(__UNCONST(in
), out
, &keys
[0], &keys
[1], &keys
[2],
4146 tripledes_cfb_encrypt(__ops_crypt_t
*cryp
, void *out
, const void *in
,
4149 DES_key_schedule
*keys
= cryp
->encrypt_key
;
4151 DES_ede3_cfb64_encrypt(in
, out
, (long)count
,
4152 &keys
[0], &keys
[1], &keys
[2], (DES_cblock
*)(void *)cryp
->iv
,
4153 &cryp
->num
, DES_ENCRYPT
);
4157 tripledes_cfb_decrypt(__ops_crypt_t
*cryp
, void *out
, const void *in
,
4160 DES_key_schedule
*keys
= cryp
->encrypt_key
;
4162 DES_ede3_cfb64_encrypt(in
, out
, (long)count
,
4163 &keys
[0], &keys
[1], &keys
[2], (DES_cblock
*)(void *)cryp
->iv
,
4164 &cryp
->num
, DES_DECRYPT
);
4167 static const __ops_crypt_t tripledes
=
4176 tripledes_block_encrypt
,
4177 tripledes_block_decrypt
,
4178 tripledes_cfb_encrypt
,
4179 tripledes_cfb_decrypt
,
4184 static const __ops_crypt_t
*
4185 get_proto(__ops_symm_alg_t alg
)
4191 #ifndef OPENSSL_NO_IDEA
4194 #endif /* OPENSSL_NO_IDEA */
4196 case OPS_SA_AES_128
:
4199 case OPS_SA_AES_256
:
4202 case OPS_SA_TRIPLEDES
:
4206 loggit("Unknown algorithm: %d (%s)",
4208 findtype((int) alg
, symm_alg_map
));
4215 __ops_key_size(__ops_symm_alg_t alg
)
4217 const __ops_crypt_t
*p
;
4220 return (p
== NULL
) ? 0 : p
->keysize
;
4224 __ops_crypt_any(__ops_crypt_t
*cryp
, __ops_symm_alg_t alg
)
4226 const __ops_crypt_t
*ptr
= get_proto(alg
);
4232 (void) memset(cryp
, 0x0, sizeof(*cryp
));
4238 __ops_block_size(__ops_symm_alg_t alg
)
4240 const __ops_crypt_t
*p
;
4243 return (p
== NULL
) ? 0 : p
->blocksize
;
4247 __ops_decrypt_init(__ops_crypt_t
*decrypt
)
4249 decrypt
->base_init(decrypt
);
4250 decrypt
->block_encrypt(decrypt
, decrypt
->siv
, decrypt
->iv
);
4251 (void) memcpy(decrypt
->civ
, decrypt
->siv
, decrypt
->blocksize
);
4256 __ops_encrypt_init(__ops_crypt_t
*encryp
)
4258 /* \todo should there be a separate __ops_encrypt_init? */
4259 __ops_decrypt_init(encryp
);
4264 __ops_decrypt_se_ip(__ops_crypt_t
*cryp
, void *out
, const void *in
,
4267 if (!__ops_is_sa_supported(cryp
->alg
)) {
4270 cryp
->cfb_decrypt(cryp
, out
, in
, count
);
4271 /* \todo check this number was in fact decrypted */
4276 /**************************************************************************/
4279 #define DECOMPRESS_BUFFER 1024
4283 __ops_region_t
*region
;
4284 uint8_t in
[DECOMPRESS_BUFFER
];
4285 uint8_t out
[DECOMPRESS_BUFFER
];
4286 z_stream zstream
;/* ZIP and ZLIB */
4293 __ops_region_t
*region
;
4294 char in
[DECOMPRESS_BUFFER
];
4295 char out
[DECOMPRESS_BUFFER
];
4296 bz_stream bzstream
; /* BZIP2 */
4307 static unsigned __ops_stacked_limited_read(uint8_t *, unsigned,
4314 * \todo remove code duplication between this and
4315 * bzip2_compressed_data_reader
4318 zlib_compressed_data_reader(void *dest
, size_t length
,
4319 __ops_error_t
**errors
,
4320 __ops_reader_t
*readinfo
,
4321 __ops_cbdata_t
*cbdata
)
4323 z_decompress_t
*z
= readinfo
->arg
;
4328 if (z
->type
!= OPS_C_ZIP
&& z
->type
!= OPS_C_ZLIB
) {
4329 loggit("zlib_compressed_data_reader: weird type %d",
4334 if (z
->inflate_ret
== Z_STREAM_END
&&
4335 z
->zstream
.next_out
== &z
->out
[z
->offset
]) {
4339 if (z
->region
->readc
== z
->region
->length
) {
4340 if (z
->inflate_ret
!= Z_STREAM_END
) {
4341 OPS_ERROR(cbdata
->errors
, OPS_E_P_DECOMPRESSION_ERROR
,
4342 "Compressed data didn't end when region ended.");
4345 for (cc
= 0 ; cc
< length
; cc
+= len
) {
4346 if (&z
->out
[z
->offset
] == z
->zstream
.next_out
) {
4349 z
->zstream
.next_out
= z
->out
;
4350 z
->zstream
.avail_out
= sizeof(z
->out
);
4352 if (z
->zstream
.avail_in
== 0) {
4353 unsigned n
= z
->region
->length
;
4355 if (!z
->region
->indeterm
) {
4356 n
-= z
->region
->readc
;
4357 if (n
> sizeof(z
->in
)) {
4363 if (!__ops_stacked_limited_read(z
->in
, n
,
4365 errors
, readinfo
, cbdata
)) {
4369 z
->zstream
.next_in
= z
->in
;
4370 z
->zstream
.avail_in
= (z
->region
->indeterm
) ?
4371 z
->region
->lastread
: n
;
4373 ret
= inflate(&z
->zstream
, Z_SYNC_FLUSH
);
4374 if (ret
== Z_STREAM_END
) {
4375 if (!z
->region
->indeterm
&&
4376 z
->region
->readc
!= z
->region
->length
) {
4377 OPS_ERROR(cbdata
->errors
,
4378 OPS_E_P_DECOMPRESSION_ERROR
,
4379 "Compressed stream ended before packet end.");
4381 } else if (ret
!= Z_OK
) {
4382 loggit("ret=%d", ret
);
4383 OPS_ERROR(cbdata
->errors
,
4384 OPS_E_P_DECOMPRESSION_ERROR
, z
->zstream
.msg
);
4386 z
->inflate_ret
= ret
;
4388 if (z
->zstream
.next_out
<= &z
->out
[z
->offset
]) {
4389 loggit("Out of memory in buffer");
4392 len
= z
->zstream
.next_out
- &z
->out
[z
->offset
];
4396 (void) memcpy(&cdest
[cc
], &z
->out
[z
->offset
], len
);
4403 /* \todo remove code duplication between this and zlib_compressed_data_reader */
4405 bzip2_compressed_data_reader(void *dest
, size_t length
,
4406 __ops_error_t
**errors
,
4407 __ops_reader_t
*readinfo
,
4408 __ops_cbdata_t
*cbdata
)
4410 bz_decompress_t
*bz
= readinfo
->arg
;
4415 if (bz
->type
!= OPS_C_BZIP2
) {
4416 loggit("Weird type %d", bz
->type
);
4420 if (bz
->inflate_ret
== BZ_STREAM_END
&&
4421 bz
->bzstream
.next_out
== &bz
->out
[bz
->offset
]) {
4424 if (bz
->region
->readc
== bz
->region
->length
) {
4425 if (bz
->inflate_ret
!= BZ_STREAM_END
) {
4426 OPS_ERROR(cbdata
->errors
, OPS_E_P_DECOMPRESSION_ERROR
,
4427 "Compressed data didn't end when region ended.");
4430 for (cc
= 0 ; cc
< length
; cc
+= len
) {
4431 if (&bz
->out
[bz
->offset
] == bz
->bzstream
.next_out
) {
4434 bz
->bzstream
.next_out
= (char *) bz
->out
;
4435 bz
->bzstream
.avail_out
= sizeof(bz
->out
);
4437 if (bz
->bzstream
.avail_in
== 0) {
4438 unsigned n
= bz
->region
->length
;
4440 if (!bz
->region
->indeterm
) {
4441 n
-= bz
->region
->readc
;
4442 if (n
> sizeof(bz
->in
))
4447 if (!__ops_stacked_limited_read(
4450 errors
, readinfo
, cbdata
))
4453 bz
->bzstream
.next_in
= bz
->in
;
4454 bz
->bzstream
.avail_in
=
4455 (bz
->region
->indeterm
) ?
4456 bz
->region
->lastread
: n
;
4458 ret
= BZ2_bzDecompress(&bz
->bzstream
);
4459 if (ret
== BZ_STREAM_END
) {
4460 if (!bz
->region
->indeterm
&&
4461 bz
->region
->readc
!= bz
->region
->length
)
4462 OPS_ERROR(cbdata
->errors
,
4463 OPS_E_P_DECOMPRESSION_ERROR
,
4464 "Compressed stream ended before packet end.");
4465 } else if (ret
!= BZ_OK
) {
4466 OPS_ERROR_1(cbdata
->errors
,
4467 OPS_E_P_DECOMPRESSION_ERROR
,
4468 "Invalid return %d from BZ2_bzDecompress", ret
);
4470 bz
->inflate_ret
= ret
;
4472 if (bz
->bzstream
.next_out
<= &bz
->out
[bz
->offset
]) {
4473 loggit("Out of bz memroy");
4476 len
= bz
->bzstream
.next_out
- &bz
->out
[bz
->offset
];
4480 (void) memcpy(&cdest
[cc
], &bz
->out
[bz
->offset
], len
);
4488 * \ingroup Core_Compress
4490 * \param *region Pointer to a region
4491 * \param *stream How to parse
4492 * \param type Which compression type to expect
4496 __ops_decompress(__ops_region_t
*region
, __ops_stream_t
*stream
,
4497 __ops_ztype_t ztype
)
4501 const int printerrors
= 1;
4507 (void) memset(&z
, 0x0, sizeof(z
));
4513 z
.zstream
.next_in
= Z_NULL
;
4514 z
.zstream
.avail_in
= 0;
4515 z
.zstream
.next_out
= z
.out
;
4516 z
.zstream
.zalloc
= Z_NULL
;
4517 z
.zstream
.zfree
= Z_NULL
;
4518 z
.zstream
.opaque
= Z_NULL
;
4523 (void) memset(&bz
, 0x0, sizeof(bz
));
4529 bz
.bzstream
.next_in
= NULL
;
4530 bz
.bzstream
.avail_in
= 0;
4531 bz
.bzstream
.next_out
= bz
.out
;
4532 bz
.bzstream
.bzalloc
= NULL
;
4533 bz
.bzstream
.bzfree
= NULL
;
4534 bz
.bzstream
.opaque
= NULL
;
4539 OPS_ERROR_1(&stream
->errors
,
4540 OPS_E_ALG_UNSUPPORTED_COMPRESS_ALG
,
4541 "Compression algorithm %d is not yet supported", ztype
);
4547 ret
= inflateInit2(&z
.zstream
, -15);
4551 ret
= inflateInit(&z
.zstream
);
4555 ret
= BZ2_bzDecompressInit(&bz
.bzstream
, 1, 0);
4559 OPS_ERROR_1(&stream
->errors
,
4560 OPS_E_ALG_UNSUPPORTED_COMPRESS_ALG
,
4561 "Compression algorithm %d is not yet supported", ztype
);
4569 OPS_ERROR_1(&stream
->errors
,
4570 OPS_E_P_DECOMPRESSION_ERROR
,
4571 "Cannot initialise ZIP or ZLIB stream for decompression: error=%d", ret
);
4574 __ops_reader_push(stream
, zlib_compressed_data_reader
,
4580 OPS_ERROR_1(&stream
->errors
,
4581 OPS_E_P_DECOMPRESSION_ERROR
,
4582 "Cannot initialise BZIP2 stream for decompression: error=%d", ret
);
4585 __ops_reader_push(stream
, bzip2_compressed_data_reader
,
4590 OPS_ERROR_1(&stream
->errors
,
4591 OPS_E_ALG_UNSUPPORTED_COMPRESS_ALG
,
4592 "Compression algorithm %d is not yet supported", ztype
);
4596 ret
= __ops_parse(stream
, !printerrors
);
4598 __ops_reader_pop(stream
);
4603 /**************************************************************************/
4605 #define CALLBACK(t, cbdata, pkt) do { \
4607 if (__ops_callback(cbdata, pkt) == OPS_RELEASE_MEMORY) { \
4608 __ops_pkt_free(pkt); \
4610 } while(/* CONSTCOND */0)
4612 #define ERRP(cbdata, cont, err) do { \
4613 cont.u.error.error = err; \
4614 CALLBACK(OPS_PARSER_ERROR, cbdata, &cont); \
4617 } while(/*CONSTCOND*/0)
4619 static unsigned __ops_limited_read(uint8_t *,
4627 * limread_data reads the specified amount of the subregion's data
4628 * into a data_t structure
4630 * \param data Empty structure which will be filled with data
4631 * \param len Number of octets to read
4633 * \param stream How to parse
4635 * \return 1 on success, 0 on failure
4638 limread_data(__ops_data_t
*data
, unsigned int len
,
4639 __ops_region_t
*subregion
, __ops_stream_t
*stream
)
4643 if (subregion
->length
- subregion
->readc
< len
) {
4644 loggit("limread_data: bad length");
4648 data
->contents
= __ops_new(data
->len
);
4649 if (!data
->contents
) {
4653 return __ops_limited_read(data
->contents
, data
->len
, subregion
,
4654 &stream
->errors
, &stream
->readinfo
, &stream
->cbdata
);
4658 * read_data reads the remainder of the subregion's data
4659 * into a data_t structure
4665 * \return 1 on success, 0 on failure
4668 read_data(__ops_data_t
*data
, __ops_region_t
*region
, __ops_stream_t
*stream
)
4672 cc
= region
->length
- region
->readc
;
4673 return (cc
>= 0) ? limread_data(data
, (unsigned)cc
, region
, stream
) : 0;
4677 * Reads the remainder of the subregion as a string.
4678 * It is the user's responsibility to free the memory allocated here.
4682 read_unsig_str(uint8_t **str
, __ops_region_t
*subregion
,
4683 __ops_stream_t
*stream
)
4687 len
= subregion
->length
- subregion
->readc
;
4688 if ((*str
= __ops_new(len
+ 1)) == NULL
) {
4692 !__ops_limited_read(*str
, len
, subregion
, &stream
->errors
,
4693 &stream
->readinfo
, &stream
->cbdata
)) {
4696 /* ! ensure the string is NULL-terminated */
4702 read_string(char **str
, __ops_region_t
*subregion
, __ops_stream_t
*stream
)
4704 return read_unsig_str((uint8_t **) str
, subregion
, stream
);
4708 __ops_init_subregion(__ops_region_t
*subregion
, __ops_region_t
*region
)
4710 (void) memset(subregion
, 0x0, sizeof(*subregion
));
4711 subregion
->parent
= region
;
4715 * Read a full size_t's worth. If the return is < than length, then
4716 * *lastread tells you why - < 0 for an error, == 0 for EOF
4720 full_read(uint8_t *dest
,
4723 __ops_error_t
**errors
,
4724 __ops_reader_t
*readinfo
,
4725 __ops_cbdata_t
*cbdata
)
4728 int r
= 0; /* preset in case some loon calls with length
4731 for (t
= 0; t
< length
;) {
4732 r
= sub_base_read(dest
+ t
, length
- t
, errors
, readinfo
,
4748 /** Read a scalar value of selected length from reader.
4750 * Read an unsigned scalar value from reader in Big Endian representation.
4752 * This function does not know or care about packet boundaries. It
4753 * also assumes that an EOF is an error.
4755 * \param *result The scalar value is stored here
4756 * \param *reader Our reader
4757 * \param length How many bytes to read
4758 * \return 1 on success, 0 on failure
4761 read_scalar(unsigned *result
, unsigned length
,
4762 __ops_stream_t
*stream
)
4766 if (length
> sizeof(*result
)) {
4767 loggit("read_scalar: bad length");
4775 r
= sub_base_read(&c
, 1, &stream
->errors
, &stream
->readinfo
,
4787 * \ingroup Core_ReadPackets
4788 * \brief Read bytes from a region within the packet.
4790 * Read length bytes into the buffer pointed to by *dest.
4791 * Make sure we do not read over the packet boundary.
4792 * Updates the Packet Tag's __ops_ptag_t::readc.
4794 * If length would make us read over the packet boundary, or if
4795 * reading fails, we call the callback with an error.
4797 * Note that if the region is indeterminate, this can return a short
4798 * read - check region->lastread for the length. EOF is indicated by
4799 * a success return and region->lastread == 0 in this case (for a
4800 * region of known length, EOF is an error).
4802 * This function makes sure to respect packet boundaries.
4804 * \param dest The destination buffer
4805 * \param length How many bytes to read
4806 * \param region Pointer to packet region
4807 * \param errors Error stack
4808 * \param readinfo Reader info
4809 * \param cbdata Callback info
4810 * \return 1 on success, 0 on error
4813 __ops_limited_read(uint8_t *dest
,
4815 __ops_region_t
*region
,
4816 __ops_error_t
**errors
,
4817 __ops_reader_t
*readinfo
,
4818 __ops_cbdata_t
*cbdata
)
4823 if (!region
->indeterm
&&
4824 region
->readc
+ length
> region
->length
) {
4825 OPS_ERROR(errors
, OPS_E_P_NOT_ENOUGH_DATA
, "Not enough data");
4828 r
= full_read(dest
, length
, &lr
, errors
, readinfo
, cbdata
);
4830 OPS_ERROR(errors
, OPS_E_R_READ_FAILED
, "Read failed");
4833 if (!region
->indeterm
&& r
!= length
) {
4834 OPS_ERROR(errors
, OPS_E_R_READ_FAILED
, "Read failed");
4837 region
->lastread
= r
;
4840 if (region
->parent
&& region
->length
> region
->parent
->length
) {
4841 loggit("ops_limited_read: bad length");
4844 } while ((region
= region
->parent
) != NULL
);
4849 \ingroup Core_ReadPackets
4850 \brief Call __ops_limited_read on next in stack
4853 __ops_stacked_limited_read(uint8_t *dest
, unsigned length
,
4854 __ops_region_t
*region
,
4855 __ops_error_t
**errors
,
4856 __ops_reader_t
*readinfo
,
4857 __ops_cbdata_t
*cbdata
)
4859 return __ops_limited_read(dest
, length
, region
, errors
,
4860 readinfo
->next
, cbdata
);
4864 limread(uint8_t *dest
, unsigned length
,
4865 __ops_region_t
*region
, __ops_stream_t
*stream
)
4867 return __ops_limited_read(dest
, length
, region
, &stream
->errors
,
4868 &stream
->readinfo
, &stream
->cbdata
);
4872 exact_limread(uint8_t *dest
, unsigned len
,
4873 __ops_region_t
*region
,
4874 __ops_stream_t
*stream
)
4878 stream
->exact_read
= 1;
4879 ret
= limread(dest
, len
, region
, stream
);
4880 stream
->exact_read
= 0;
4884 /** Skip over length bytes of this packet.
4886 * Calls limread() to skip over some data.
4888 * This function makes sure to respect packet boundaries.
4890 * \param length How many bytes to skip
4891 * \param *region Pointer to packet region
4892 * \param *stream How to parse
4893 * \return 1 on success, 0 on error (calls the cb with OPS_PARSER_ERROR in limread()).
4896 limskip(unsigned length
, __ops_region_t
*region
, __ops_stream_t
*stream
)
4898 uint8_t buf
[NETPGP_BUFSIZ
];
4900 while (length
> 0) {
4901 unsigned n
= length
% NETPGP_BUFSIZ
;
4903 if (!limread(buf
, n
, region
, stream
)) {
4913 * Read a big-endian scalar of length bytes, respecting packet
4914 * boundaries (by calling limread() to read the raw data).
4916 * This function makes sure to respect packet boundaries.
4918 * \param *dest The scalar value is stored here
4919 * \param length How many bytes make up this scalar (at most 4)
4920 * \param *region Pointer to current packet region
4921 * \param *stream How to parse
4922 * \param *cb The callback
4923 * \return 1 on success, 0 on error (calls the cb with OPS_PARSER_ERROR in limread()).
4928 limread_scalar(unsigned *dest
,
4930 __ops_region_t
*region
,
4931 __ops_stream_t
*stream
)
4938 loggit("limread_scalar: bad length");
4942 if (/*CONSTCOND*/sizeof(*dest
) < 4) {
4943 loggit("limread_scalar: bad dest");
4946 if (!limread(c
, len
, region
, stream
)) {
4949 for (t
= 0, n
= 0; n
< len
; ++n
) {
4950 t
= (t
<< 8) + c
[n
];
4958 * Read a big-endian scalar of length bytes, respecting packet
4959 * boundaries (by calling limread() to read the raw data).
4961 * The value read is stored in a size_t, which is a different size
4962 * from an unsigned on some platforms.
4964 * This function makes sure to respect packet boundaries.
4966 * \param *dest The scalar value is stored here
4967 * \param length How many bytes make up this scalar (at most 4)
4968 * \param *region Pointer to current packet region
4969 * \param *stream How to parse
4970 * \param *cb The callback
4971 * \return 1 on success, 0 on error (calls the cb with OPS_PARSER_ERROR in limread()).
4976 limread_size_t(size_t *dest
,
4978 __ops_region_t
*region
,
4979 __ops_stream_t
*stream
)
4984 * Note that because the scalar is at most 4 bytes, we don't care if
4985 * size_t is bigger than usigned
4987 if (!limread_scalar(&tmp
, length
, region
, stream
)) {
4994 /** Read a timestamp.
4996 * Timestamps in OpenPGP are unix time, i.e. seconds since The Epoch
4997 * (1.1.1970). They are stored in an unsigned scalar of 4 bytes.
4999 * This function reads the timestamp using limread_scalar().
5001 * This function makes sure to respect packet boundaries.
5003 * \param *dest The timestamp is stored here
5004 * \param *ptag Pointer to current packet's Packet Tag.
5005 * \param *reader Our reader
5006 * \param *cb The callback
5007 * \return see limread_scalar()
5012 limited_read_time(time_t *dest
, __ops_region_t
*region
, __ops_stream_t
*stream
)
5019 * Cannot assume that time_t is 4 octets long -
5020 * SunOS 5.10 and NetBSD both have 64-bit time_ts.
5022 if (/* CONSTCOND */sizeof(time_t) == 4) {
5023 return limread_scalar((unsigned *)(void *)dest
, 4, region
,
5026 for (i
= 0; i
< 4; i
++) {
5027 if (!limread(&c
, 1, region
, stream
)) {
5030 mytime
= (mytime
<< 8) + c
;
5038 * Read a multiprecision integer.
5040 * Large numbers (multiprecision integers, MPI) are stored in OpenPGP in two parts. First there is a 2 byte scalar
5041 * indicating the length of the following MPI in Bits. Then follow the bits that make up the actual number, most
5042 * significant bits first (Big Endian). The most significant bit in the MPI is supposed to be 1 (unless the MPI is
5043 * encrypted - then it may be different as the bit count refers to the plain text but the bits are encrypted).
5045 * Unused bits (i.e. those filling up the most significant byte from the left to the first bits that counts) are
5046 * supposed to be cleared - I guess. XXX - does anything actually say so?
5048 * This function makes sure to respect packet boundaries.
5050 * \param **pgn return the integer there - the BIGNUM is created by BN_bin2bn() and probably needs to be freed
5051 * by the caller XXX right ben?
5052 * \param *ptag Pointer to current packet's Packet Tag.
5053 * \param *reader Our reader
5054 * \param *cb The callback
5055 * \return 1 on success, 0 on error (by limread_scalar() or limread() or if the MPI is not properly formed (XXX
5056 * see comment below - the callback is called with a OPS_PARSER_ERROR in case of an error)
5061 limread_mpi(BIGNUM
**pbn
, __ops_region_t
*region
, __ops_stream_t
*stream
)
5063 uint8_t buf
[NETPGP_BUFSIZ
] = "";
5064 /* an MPI has a 2 byte length part.
5065 * Length is given in bits, so the
5066 * largest we should ever need for
5067 * the buffer is NETPGP_BUFSIZ bytes. */
5072 stream
->reading_mpi_len
= 1;
5073 ret
= limread_scalar(&length
, 2, region
, stream
);
5075 stream
->reading_mpi_len
= 0;
5080 nonzero
= length
& 7; /* there should be this many zero bits in the
5085 length
= (length
+ 7) / 8;
5088 /* if we try to read a length of 0, then fail */
5091 if (length
> NETPGP_BUFSIZ
) {
5092 loggit("limread_mpi: bad length");
5095 if (!limread(buf
, length
, region
, stream
)) {
5098 if (((unsigned)buf
[0] >> nonzero
) != 0 ||
5099 !((unsigned)buf
[0] & (1U << (nonzero
- 1U)))) {
5100 OPS_ERROR(&stream
->errors
, OPS_E_P_MPI_FORMAT_ERROR
,
5101 "MPI Format error");
5102 /* XXX: Ben, one part of
5103 * this constraint does
5105 * encrypted MPIs the
5106 * draft says. -- peter */
5109 *pbn
= BN_bin2bn(buf
, (int)length
, NULL
);
5113 /** Read some data with a New-Format length from reader.
5115 * \sa Internet-Draft RFC4880.txt Section 4.2.2
5117 * \param *length Where the decoded length will be put
5118 * \param *stream How to parse
5119 * \return 1 if OK, else 0
5124 read_new_length(unsigned *length
, __ops_stream_t
*stream
)
5128 if (sub_base_read(&c
, 1, &stream
->errors
, &stream
->readinfo
,
5129 &stream
->cbdata
) != 1) {
5133 /* 1. One-octet packet */
5137 if (c
>= 192 && c
<= 223) {
5138 /* 2. Two-octet packet */
5139 unsigned t
= (c
- 192) << 8;
5141 if (sub_base_read(&c
, 1, &stream
->errors
, &stream
->readinfo
,
5142 &stream
->cbdata
) != 1) {
5145 *length
= t
+ c
+ 192;
5149 /* 3. Five-Octet packet */
5150 return read_scalar(length
, 4, stream
);
5152 if (c
>= 224 && c
< 255) {
5153 /* 4. Partial Body Length */
5154 /* XXX - agc - gpg multi-recipient encryption uses this */
5155 OPS_ERROR(&stream
->errors
, OPS_E_UNIMPLEMENTED
,
5156 "New format Partial Body Length fields not yet implemented");
5162 /** Read the length information for a new format Packet Tag.
5164 * New style Packet Tags encode the length in one to five octets. This function reads the right amount of bytes and
5165 * decodes it to the proper length information.
5167 * This function makes sure to respect packet boundaries.
5169 * \param *length return the length here
5170 * \param *ptag Pointer to current packet's Packet Tag.
5171 * \param *reader Our reader
5172 * \param *cb The callback
5173 * \return 1 on success, 0 on error (by limread_scalar() or limread() or if the MPI is not properly formed (XXX
5174 * see comment below)
5176 * \see RFC4880 4.2.2
5180 limited_read_new_length(unsigned *length
, __ops_region_t
*region
,
5181 __ops_stream_t
*stream
)
5185 if (!limread(&c
, 1, region
, stream
)) {
5193 unsigned t
= (c
- 192) << 8;
5195 if (!limread(&c
, 1, region
, stream
)) {
5198 *length
= t
+ c
+ 192;
5201 return limread_scalar(length
, 4, region
, stream
);
5205 \ingroup Core_Create
5206 \brief Free allocated memory
5209 data_free(__ops_data_t
*data
)
5211 (void) free(data
->contents
);
5212 data
->contents
= NULL
;
5217 \ingroup Core_Create
5218 \brief Free allocated memory
5221 string_free(char **str
)
5228 \ingroup Core_Create
5229 \brief Free allocated memory
5231 /* ! Free packet memory, set pointer to NULL */
5233 __ops_subpacket_free(__ops_subpacket_t
*packet
)
5235 (void) free(packet
->raw
);
5240 \ingroup Core_Create
5241 \brief Free allocated memory
5244 __ops_headers_free(__ops_headers_t
*headers
)
5248 for (n
= 0; n
< headers
->headerc
; ++n
) {
5249 (void) free(headers
->headers
[n
].key
);
5250 (void) free(headers
->headers
[n
].value
);
5252 (void) free(headers
->headers
);
5253 headers
->headers
= NULL
;
5257 \ingroup Core_Create
5258 \brief Free allocated memory
5261 cleartext_trailer_free(__ops_cleartext_trailer_t
*trailer
)
5263 (void) free(trailer
->hash
);
5264 trailer
->hash
= NULL
;
5268 \ingroup Core_Create
5269 \brief Free allocated memory
5272 __ops_cmd_get_passphrase_free(__ops_seckey_passphrase_t
*seckey
)
5276 if (seckey
->passphrase
&& *seckey
->passphrase
) {
5277 len
= strlen(*seckey
->passphrase
);
5278 __ops_forget(*seckey
->passphrase
, len
);
5279 (void) free(*seckey
->passphrase
);
5280 *seckey
->passphrase
= NULL
;
5285 \ingroup Core_Create
5286 \brief Free the memory used when parsing this signature sub-packet type
5289 ss_userdef_free(__ops_ss_userdef_t
*ss_userdef
)
5291 data_free(&ss_userdef
->data
);
5295 \ingroup Core_Create
5296 \brief Free the memory used when parsing this signature sub-packet type
5299 ss_reserved_free(__ops_ss_unknown_t
*ss_unknown
)
5301 data_free(&ss_unknown
->data
);
5305 \ingroup Core_Create
5306 \brief Free the memory used when parsing this packet type
5309 trust_free(__ops_trust_t
*trust
)
5311 data_free(&trust
->data
);
5315 * \ingroup Core_Create
5316 * \brief Free the memory used when parsing a private/experimental PKA signature
5317 * \param unknown_sig
5320 free_unknown_sig_pka(__ops_unknown_sig_t
*unknown_sig
)
5322 data_free(&unknown_sig
->data
);
5326 \ingroup Core_Create
5327 \brief Free allocated memory
5330 free_BN(BIGNUM
**pp
)
5337 * \ingroup Core_Create
5338 * \brief Free the memory used when parsing a signature
5342 sig_free(__ops_sig_t
*sig
)
5344 switch (sig
->info
.key_alg
) {
5346 case OPS_PKA_RSA_SIGN_ONLY
:
5347 free_BN(&sig
->info
.sig
.rsa
.sig
);
5351 free_BN(&sig
->info
.sig
.dsa
.r
);
5352 free_BN(&sig
->info
.sig
.dsa
.s
);
5355 case OPS_PKA_ELGAMAL_ENCRYPT_OR_SIGN
:
5356 free_BN(&sig
->info
.sig
.elgamal
.r
);
5357 free_BN(&sig
->info
.sig
.elgamal
.s
);
5360 case OPS_PKA_PRIVATE00
:
5361 case OPS_PKA_PRIVATE01
:
5362 case OPS_PKA_PRIVATE02
:
5363 case OPS_PKA_PRIVATE03
:
5364 case OPS_PKA_PRIVATE04
:
5365 case OPS_PKA_PRIVATE05
:
5366 case OPS_PKA_PRIVATE06
:
5367 case OPS_PKA_PRIVATE07
:
5368 case OPS_PKA_PRIVATE08
:
5369 case OPS_PKA_PRIVATE09
:
5370 case OPS_PKA_PRIVATE10
:
5371 free_unknown_sig_pka(&sig
->info
.sig
.unknown
);
5375 loggit("sig_free: bad sig type");
5380 \ingroup Core_Create
5381 \brief Free the memory used when parsing this signature sub-packet type
5385 ss_skapref_free(__ops_ss_skapref_t
*ss_skapref
)
5387 data_free(&ss_skapref
->data
);
5391 \ingroup Core_Create
5392 \brief Free the memory used when parsing this signature sub-packet type
5396 ss_hashpref_free(__ops_ss_hashpref_t
*ss_hashpref
)
5398 data_free(&ss_hashpref
->data
);
5402 \ingroup Core_Create
5403 \brief Free the memory used when parsing this signature sub-packet type
5406 ss_zpref_free(__ops_ss_zpref_t
*ss_zpref
)
5408 data_free(&ss_zpref
->data
);
5412 \ingroup Core_Create
5413 \brief Free the memory used when parsing this signature sub-packet type
5416 ss_key_flags_free(__ops_ss_key_flags_t
*ss_key_flags
)
5418 data_free(&ss_key_flags
->data
);
5422 \ingroup Core_Create
5423 \brief Free the memory used when parsing this signature sub-packet type
5426 ss_key_server_prefs_free(__ops_ss_key_server_prefs_t
*ss_key_server_prefs
)
5428 data_free(&ss_key_server_prefs
->data
);
5432 \ingroup Core_Create
5433 \brief Free the memory used when parsing this signature sub-packet type
5436 ss_features_free(__ops_ss_features_t
*ss_features
)
5438 data_free(&ss_features
->data
);
5442 \ingroup Core_Create
5443 \brief Free the memory used when parsing this signature sub-packet type
5446 ss_notation_free(__ops_ss_notation_t
*ss_notation
)
5448 data_free(&ss_notation
->name
);
5449 data_free(&ss_notation
->value
);
5453 \ingroup Core_Create
5454 \brief Free allocated memory
5456 /* ! Free the memory used when parsing this signature sub-packet type */
5458 ss_regexp_free(__ops_ss_regexp_t
*regexp
)
5460 string_free(®exp
->regexp
);
5464 \ingroup Core_Create
5465 \brief Free allocated memory
5467 /* ! Free the memory used when parsing this signature sub-packet type */
5469 ss_policy_free(__ops_ss_policy_t
*policy
)
5471 string_free(&policy
->url
);
5475 \ingroup Core_Create
5476 \brief Free allocated memory
5478 /* ! Free the memory used when parsing this signature sub-packet type */
5480 ss_keyserv_free(__ops_ss_keyserv_t
*preferred_key_server
)
5482 string_free(&preferred_key_server
->name
);
5486 \ingroup Core_Create
5487 \brief Free the memory used when parsing this signature sub-packet type
5490 ss_revocation_free(__ops_ss_revocation_t
*ss_revocation
)
5492 string_free(&ss_revocation
->reason
);
5496 ss_embedded_sig_free(__ops_ss_embedded_sig_t
*ss_embedded_sig
)
5498 data_free(&ss_embedded_sig
->sig
);
5502 \ingroup Core_Create
5503 \brief Free allocated memory
5506 __ops_pk_sesskey_free(__ops_pk_sesskey_t
*sk
)
5510 free_BN(&sk
->params
.rsa
.encrypted_m
);
5513 case OPS_PKA_ELGAMAL
:
5514 free_BN(&sk
->params
.elgamal
.g_to_k
);
5515 free_BN(&sk
->params
.elgamal
.encrypted_m
);
5519 loggit("__ops_pk_sesskey_free: bad alg");
5525 \ingroup Core_Create
5526 \brief Free allocated memory
5528 /* ! Free the memory used when parsing a public key */
5530 __ops_pubkey_free(__ops_pubkey_t
*p
)
5534 case OPS_PKA_RSA_ENCRYPT_ONLY
:
5535 case OPS_PKA_RSA_SIGN_ONLY
:
5536 free_BN(&p
->key
.rsa
.n
);
5537 free_BN(&p
->key
.rsa
.e
);
5541 free_BN(&p
->key
.dsa
.p
);
5542 free_BN(&p
->key
.dsa
.q
);
5543 free_BN(&p
->key
.dsa
.g
);
5544 free_BN(&p
->key
.dsa
.y
);
5547 case OPS_PKA_ELGAMAL
:
5548 case OPS_PKA_ELGAMAL_ENCRYPT_OR_SIGN
:
5549 free_BN(&p
->key
.elgamal
.p
);
5550 free_BN(&p
->key
.elgamal
.g
);
5551 free_BN(&p
->key
.elgamal
.y
);
5555 /* nothing to free */
5559 loggit("__ops_pubkey_free: bad alg");
5565 \ingroup Core_Create
5566 \brief Free allocated memory
5568 /* ! Free the memory used when parsing this packet type */
5570 __ops_userattr_free(__ops_userattr_t
*user_att
)
5572 data_free(&user_att
->data
);
5576 \ingroup Core_Create
5577 \brief Free allocated memory
5579 /* ! Free the memory used when parsing this packet type */
5581 __ops_userid_free(__ops_userid_t
*id
)
5583 (void) free(id
->userid
);
5588 * \ingroup Core_Create
5590 * __ops_seckey_free() frees the memory associated with "key". Note that
5591 * the key itself is not freed.
5597 __ops_seckey_free(__ops_seckey_t
*key
)
5599 switch (key
->pubkey
.alg
) {
5601 case OPS_PKA_RSA_ENCRYPT_ONLY
:
5602 case OPS_PKA_RSA_SIGN_ONLY
:
5603 free_BN(&key
->key
.rsa
.d
);
5604 free_BN(&key
->key
.rsa
.p
);
5605 free_BN(&key
->key
.rsa
.q
);
5606 free_BN(&key
->key
.rsa
.u
);
5610 free_BN(&key
->key
.dsa
.x
);
5614 loggit("__ops_seckey_free: Unknown algorithm: %d (%s)",
5616 findtype((int) key
->pubkey
.alg
, pubkeyalgs
));
5618 (void) free(key
->checkhash
);
5619 __ops_pubkey_free(&key
->pubkey
);
5623 \ingroup Core_Create
5624 \brief Free allocated memory
5626 /* ! Free any memory allocated when parsing the packet content */
5628 __ops_pkt_free(__ops_packet_t
*c
)
5631 case OPS_PARSER_PTAG
:
5632 case OPS_PTAG_CT_COMPRESSED
:
5633 case OPS_PTAG_SS_CREATION_TIME
:
5634 case OPS_PTAG_SS_EXPIRATION_TIME
:
5635 case OPS_PTAG_SS_KEY_EXPIRY
:
5636 case OPS_PTAG_SS_TRUST
:
5637 case OPS_PTAG_SS_ISSUER_KEY_ID
:
5638 case OPS_PTAG_CT_1_PASS_SIG
:
5639 case OPS_PTAG_SS_PRIMARY_USER_ID
:
5640 case OPS_PTAG_SS_REVOCABLE
:
5641 case OPS_PTAG_SS_REVOCATION_KEY
:
5642 case OPS_PTAG_CT_LITDATA_HEADER
:
5643 case OPS_PTAG_CT_LITDATA_BODY
:
5644 case OPS_PTAG_CT_SIGNED_CLEARTEXT_BODY
:
5645 case OPS_PTAG_CT_UNARMOURED_TEXT
:
5646 case OPS_PTAG_CT_ARMOUR_TRAILER
:
5647 case OPS_PTAG_CT_SIGNATURE_HEADER
:
5648 case OPS_PTAG_CT_SE_DATA_HEADER
:
5649 case OPS_PTAG_CT_SE_IP_DATA_HEADER
:
5650 case OPS_PTAG_CT_SE_IP_DATA_BODY
:
5651 case OPS_PTAG_CT_MDC
:
5652 case OPS_GET_SECKEY
:
5655 case OPS_PTAG_CT_SIGNED_CLEARTEXT_HEADER
:
5656 __ops_headers_free(&c
->u
.cleartext_head
.headers
);
5659 case OPS_PTAG_CT_ARMOUR_HEADER
:
5660 __ops_headers_free(&c
->u
.armour_header
.headers
);
5663 case OPS_PTAG_CT_SIGNED_CLEARTEXT_TRAILER
:
5664 cleartext_trailer_free(&c
->u
.cleartext_trailer
);
5667 case OPS_PTAG_CT_TRUST
:
5668 trust_free(&c
->u
.trust
);
5671 case OPS_PTAG_CT_SIGNATURE
:
5672 case OPS_PTAG_CT_SIGNATURE_FOOTER
:
5673 sig_free(&c
->u
.sig
);
5676 case OPS_PTAG_CT_PUBLIC_KEY
:
5677 case OPS_PTAG_CT_PUBLIC_SUBKEY
:
5678 __ops_pubkey_free(&c
->u
.pubkey
);
5681 case OPS_PTAG_CT_USER_ID
:
5682 __ops_userid_free(&c
->u
.userid
);
5685 case OPS_PTAG_SS_SIGNERS_USER_ID
:
5686 __ops_userid_free(&c
->u
.ss_signer
);
5689 case OPS_PTAG_CT_USER_ATTR
:
5690 __ops_userattr_free(&c
->u
.userattr
);
5693 case OPS_PTAG_SS_PREFERRED_SKA
:
5694 ss_skapref_free(&c
->u
.ss_skapref
);
5697 case OPS_PTAG_SS_PREFERRED_HASH
:
5698 ss_hashpref_free(&c
->u
.ss_hashpref
);
5701 case OPS_PTAG_SS_PREF_COMPRESS
:
5702 ss_zpref_free(&c
->u
.ss_zpref
);
5705 case OPS_PTAG_SS_KEY_FLAGS
:
5706 ss_key_flags_free(&c
->u
.ss_key_flags
);
5709 case OPS_PTAG_SS_KEYSERV_PREFS
:
5710 ss_key_server_prefs_free(&c
->u
.ss_key_server_prefs
);
5713 case OPS_PTAG_SS_FEATURES
:
5714 ss_features_free(&c
->u
.ss_features
);
5717 case OPS_PTAG_SS_NOTATION_DATA
:
5718 ss_notation_free(&c
->u
.ss_notation
);
5721 case OPS_PTAG_SS_REGEXP
:
5722 ss_regexp_free(&c
->u
.ss_regexp
);
5725 case OPS_PTAG_SS_POLICY_URI
:
5726 ss_policy_free(&c
->u
.ss_policy
);
5729 case OPS_PTAG_SS_PREF_KEYSERV
:
5730 ss_keyserv_free(&c
->u
.ss_keyserv
);
5733 case OPS_PTAG_SS_USERDEFINED00
:
5734 case OPS_PTAG_SS_USERDEFINED01
:
5735 case OPS_PTAG_SS_USERDEFINED02
:
5736 case OPS_PTAG_SS_USERDEFINED03
:
5737 case OPS_PTAG_SS_USERDEFINED04
:
5738 case OPS_PTAG_SS_USERDEFINED05
:
5739 case OPS_PTAG_SS_USERDEFINED06
:
5740 case OPS_PTAG_SS_USERDEFINED07
:
5741 case OPS_PTAG_SS_USERDEFINED08
:
5742 case OPS_PTAG_SS_USERDEFINED09
:
5743 case OPS_PTAG_SS_USERDEFINED10
:
5744 ss_userdef_free(&c
->u
.ss_userdef
);
5747 case OPS_PTAG_SS_RESERVED
:
5748 ss_reserved_free(&c
->u
.ss_unknown
);
5751 case OPS_PTAG_SS_REVOCATION_REASON
:
5752 ss_revocation_free(&c
->u
.ss_revocation
);
5755 case OPS_PTAG_SS_EMBEDDED_SIGNATURE
:
5756 ss_embedded_sig_free(&c
->u
.ss_embedded_sig
);
5759 case OPS_PARSER_PACKET_END
:
5760 __ops_subpacket_free(&c
->u
.packet
);
5763 case OPS_PARSER_ERROR
:
5764 case OPS_PARSER_ERRCODE
:
5767 case OPS_PTAG_CT_SECRET_KEY
:
5768 case OPS_PTAG_CT_ENCRYPTED_SECRET_KEY
:
5769 __ops_seckey_free(&c
->u
.seckey
);
5772 case OPS_PTAG_CT_PK_SESSION_KEY
:
5773 case OPS_PTAG_CT_ENCRYPTED_PK_SESSION_KEY
:
5774 __ops_pk_sesskey_free(&c
->u
.pk_sesskey
);
5777 case OPS_GET_PASSPHRASE
:
5778 __ops_cmd_get_passphrase_free(&c
->u
.skey_passphrase
);
5782 loggit("Can't free %d (0x%x)", c
->tag
, c
->tag
);
5787 \ingroup Core_ReadPackets
5790 parse_pubkey_data(__ops_pubkey_t
*key
, __ops_region_t
*region
,
5791 __ops_stream_t
*stream
)
5795 if (region
->readc
!= 0) {
5796 /* We should not have read anything so far */
5797 loggit("parse_pubkey_data: bad length");
5801 if (!limread(&c
, 1, region
, stream
)) {
5805 if (key
->version
< 2 || key
->version
> 4) {
5806 OPS_ERROR_1(&stream
->errors
, OPS_E_PROTO_BAD_PUBLIC_KEY_VRSN
,
5807 "Bad public key version (0x%02x)", key
->version
);
5810 if (!limited_read_time(&key
->birthtime
, region
, stream
)) {
5814 key
->days_valid
= 0;
5815 if ((key
->version
== 2 || key
->version
== 3) &&
5816 !limread_scalar(&key
->days_valid
, 2, region
, stream
)) {
5820 if (!limread(&c
, 1, region
, stream
)) {
5827 if (!limread_mpi(&key
->key
.dsa
.p
, region
, stream
) ||
5828 !limread_mpi(&key
->key
.dsa
.q
, region
, stream
) ||
5829 !limread_mpi(&key
->key
.dsa
.g
, region
, stream
) ||
5830 !limread_mpi(&key
->key
.dsa
.y
, region
, stream
)) {
5836 case OPS_PKA_RSA_ENCRYPT_ONLY
:
5837 case OPS_PKA_RSA_SIGN_ONLY
:
5838 if (!limread_mpi(&key
->key
.rsa
.n
, region
, stream
) ||
5839 !limread_mpi(&key
->key
.rsa
.e
, region
, stream
)) {
5844 case OPS_PKA_ELGAMAL
:
5845 case OPS_PKA_ELGAMAL_ENCRYPT_OR_SIGN
:
5846 if (!limread_mpi(&key
->key
.elgamal
.p
, region
, stream
) ||
5847 !limread_mpi(&key
->key
.elgamal
.g
, region
, stream
) ||
5848 !limread_mpi(&key
->key
.elgamal
.y
, region
, stream
)) {
5854 OPS_ERROR_1(&stream
->errors
,
5855 OPS_E_ALG_UNSUPPORTED_PUBLIC_KEY_ALG
,
5856 "Unsupported Public Key algorithm (%s)",
5857 findtype((int) key
->alg
, pubkeyalgs
));
5865 \ingroup Core_ReadPackets
5866 \brief Calls the parse_cb_info's callback if present
5867 \return Return value from callback, if present; else OPS_FINISHED
5869 static __ops_cb_ret_t
5870 __ops_callback(__ops_cbdata_t
*cbdata
, const __ops_packet_t
*pkt
)
5872 return (cbdata
->cbfunc
) ? (*cbdata
->cbfunc
)(cbdata
, pkt
) : OPS_FINISHED
;
5876 * \ingroup Core_ReadPackets
5877 * \brief Parse a public key packet.
5879 * This function parses an entire v3 (== v2) or v4 public key packet for RSA, ElGamal, and DSA keys.
5881 * Once the key has been parsed successfully, it is passed to the callback.
5883 * \param *ptag Pointer to the current Packet Tag. This function should consume the entire packet.
5884 * \param *reader Our reader
5885 * \param *cb The callback
5886 * \return 1 on success, 0 on error
5888 * \see RFC4880 5.5.2
5891 parse_pubkey(__ops_content_tag_t tag
, __ops_region_t
*region
,
5892 __ops_stream_t
*stream
)
5896 if (!parse_pubkey_data(&pkt
.u
.pubkey
, region
, stream
)) {
5899 /* XXX: this test should be done for all packets, surely? */
5900 if (region
->readc
!= region
->length
) {
5901 OPS_ERROR_1(&stream
->errors
, OPS_E_R_UNCONSUMED_DATA
,
5902 "Unconsumed data (%d)",
5903 region
->length
- region
->readc
);
5906 CALLBACK(tag
, &stream
->cbdata
, &pkt
);
5911 * \ingroup Core_ReadPackets
5912 * \brief Parse one user attribute packet.
5914 * User attribute packets contain one or more attribute subpackets.
5915 * For now, handle the whole packet as raw data.
5919 parse_userattr(__ops_region_t
*region
, __ops_stream_t
*stream
)
5925 * xxx- treat as raw data for now. Could break down further into
5926 * attribute sub-packets later - rachel
5928 if (region
->readc
!= 0) {
5929 /* We should not have read anything so far */
5930 loggit("parse_userattr: bad length");
5933 if (!read_data(&pkt
.u
.userattr
.data
, region
, stream
)) {
5936 CALLBACK(OPS_PTAG_CT_USER_ATTR
, &stream
->cbdata
, &pkt
);
5941 * \ingroup Core_ReadPackets
5942 * \brief Parse a user id.
5944 * This function parses an user id packet, which is basically just a char array the size of the packet.
5946 * The char array is to be treated as an UTF-8 string.
5948 * The userid gets null terminated by this function. Freeing it is the responsibility of the caller.
5950 * Once the userid has been parsed successfully, it is passed to the callback.
5952 * \param *ptag Pointer to the Packet Tag. This function should consume the entire packet.
5953 * \param *reader Our reader
5954 * \param *cb The callback
5955 * \return 1 on success, 0 on error
5960 parse_userid(__ops_region_t
*region
, __ops_stream_t
*stream
)
5964 if (region
->readc
!= 0) {
5965 /* We should not have read anything so far */
5966 loggit("parse_userid: bad length");
5969 pkt
.u
.userid
.userid
= __ops_new(region
->length
+ 1);
5970 if (region
->length
&&
5971 !limread(pkt
.u
.userid
.userid
, region
->length
, region
, stream
)) {
5974 pkt
.u
.userid
.userid
[region
->length
] = '\0';
5975 CALLBACK(OPS_PTAG_CT_USER_ID
, &stream
->cbdata
, &pkt
);
5979 static __ops_hash_t
*
5980 parse_hash_find(__ops_stream_t
*stream
, const uint8_t *keyid
)
5982 __ops_hashtype_t
*hp
;
5985 for (n
= 0, hp
= stream
->hashes
; n
< stream
->hashc
; n
++, hp
++) {
5986 if (memcmp(hp
->keyid
, keyid
, OPS_KEY_ID_SIZE
) == 0) {
5994 * \ingroup Core_Parse
5995 * \brief Parse a version 3 signature.
5997 * This function parses an version 3 signature packet, handling RSA and DSA signatures.
5999 * Once the signature has been parsed successfully, it is passed to the callback.
6001 * \param *ptag Pointer to the Packet Tag. This function should consume the entire packet.
6002 * \param *reader Our reader
6003 * \param *cb The callback
6004 * \return 1 on success, 0 on error
6006 * \see RFC4880 5.2.2
6009 parse_v3_sig(__ops_region_t
*region
,
6010 __ops_stream_t
*stream
)
6015 /* clear signature */
6016 (void) memset(&pkt
.u
.sig
, 0x0, sizeof(pkt
.u
.sig
));
6018 pkt
.u
.sig
.info
.version
= OPS_V3
;
6020 /* hash info length */
6021 if (!limread(&c
, 1, region
, stream
)) {
6025 ERRP(&stream
->cbdata
, pkt
, "bad hash info length");
6028 if (!limread(&c
, 1, region
, stream
)) {
6031 pkt
.u
.sig
.info
.type
= c
;
6032 /* XXX: check signature type */
6034 if (!limited_read_time(&pkt
.u
.sig
.info
.birthtime
, region
, stream
)) {
6037 pkt
.u
.sig
.info
.gotbirthtime
= 1;
6039 if (!limread(pkt
.u
.sig
.info
.signer
, OPS_KEY_ID_SIZE
, region
, stream
)) {
6042 pkt
.u
.sig
.info
.gotsigner
= 1;
6044 if (!limread(&c
, 1, region
, stream
)) {
6047 pkt
.u
.sig
.info
.key_alg
= c
;
6048 /* XXX: check algorithm */
6050 if (!limread(&c
, 1, region
, stream
)) {
6053 pkt
.u
.sig
.info
.hash_alg
= c
;
6054 /* XXX: check algorithm */
6056 if (!limread(pkt
.u
.sig
.hash2
, 2, region
, stream
)) {
6060 switch (pkt
.u
.sig
.info
.key_alg
) {
6062 case OPS_PKA_RSA_SIGN_ONLY
:
6063 if (!limread_mpi(&pkt
.u
.sig
.info
.sig
.rsa
.sig
, region
, stream
)) {
6069 if (!limread_mpi(&pkt
.u
.sig
.info
.sig
.dsa
.r
, region
, stream
) ||
6070 !limread_mpi(&pkt
.u
.sig
.info
.sig
.dsa
.s
, region
, stream
)) {
6075 case OPS_PKA_ELGAMAL_ENCRYPT_OR_SIGN
:
6076 if (!limread_mpi(&pkt
.u
.sig
.info
.sig
.elgamal
.r
, region
,
6078 !limread_mpi(&pkt
.u
.sig
.info
.sig
.elgamal
.s
, region
,
6085 OPS_ERROR_1(&stream
->errors
,
6086 OPS_E_ALG_UNSUPPORTED_SIGNATURE_ALG
,
6087 "Unsupported signature key algorithm (%s)",
6088 findtype((int) pkt
.u
.sig
.info
.key_alg
, pubkeyalgs
));
6092 if (region
->readc
!= region
->length
) {
6093 OPS_ERROR_1(&stream
->errors
, OPS_E_R_UNCONSUMED_DATA
,
6094 "Unconsumed data (%d)",
6095 region
->length
- region
->readc
);
6098 if (pkt
.u
.sig
.info
.gotsigner
) {
6099 pkt
.u
.sig
.hash
= parse_hash_find(stream
, pkt
.u
.sig
.info
.signer
);
6101 CALLBACK(OPS_PTAG_CT_SIGNATURE
, &stream
->cbdata
, &pkt
);
6106 * \ingroup Core_ReadPackets
6107 * \brief Parse one signature sub-packet.
6109 * Version 4 signatures can have an arbitrary amount of (hashed and unhashed) subpackets. Subpackets are used to hold
6110 * optional attributes of subpackets.
6112 * This function parses one such signature subpacket.
6114 * Once the subpacket has been parsed successfully, it is passed to the callback.
6116 * \param *ptag Pointer to the Packet Tag. This function should consume the entire subpacket.
6117 * \param *reader Our reader
6118 * \param *cb The callback
6119 * \return 1 on success, 0 on error
6121 * \see RFC4880 5.2.3
6124 parse_one_sig_subpacket(__ops_sig_t
*sig
,
6125 __ops_region_t
*region
,
6126 __ops_stream_t
*stream
)
6128 __ops_region_t subregion
;
6130 uint8_t bools
= 0x0;
6132 unsigned doread
= 1;
6136 __ops_init_subregion(&subregion
, region
);
6137 if (!limited_read_new_length(&subregion
.length
, region
, stream
)) {
6141 if (subregion
.length
> region
->length
) {
6142 ERRP(&stream
->cbdata
, pkt
, "Subpacket too long");
6145 if (!limread(&c
, 1, &subregion
, stream
)) {
6149 t8
= (c
& 0x7f) / 8;
6152 pkt
.critical
= (unsigned)c
>> 7;
6153 pkt
.tag
= OPS_PTAG_SIG_SUBPKT_BASE
+ (c
& 0x7f);
6155 /* Application wants it delivered raw */
6156 if (stream
->ss_raw
[t8
] & t7
) {
6157 pkt
.u
.ss_raw
.tag
= pkt
.tag
;
6158 pkt
.u
.ss_raw
.length
= subregion
.length
- 1;
6159 pkt
.u
.ss_raw
.raw
= __ops_new(pkt
.u
.ss_raw
.length
);
6160 if (!limread(pkt
.u
.ss_raw
.raw
, pkt
.u
.ss_raw
.length
,
6161 &subregion
, stream
)) {
6164 CALLBACK(OPS_PTAG_RAW_SS
, &stream
->cbdata
, &pkt
);
6168 case OPS_PTAG_SS_CREATION_TIME
:
6169 case OPS_PTAG_SS_EXPIRATION_TIME
:
6170 case OPS_PTAG_SS_KEY_EXPIRY
:
6171 if (!limited_read_time(&pkt
.u
.ss_time
.time
, &subregion
, stream
))
6173 if (pkt
.tag
== OPS_PTAG_SS_CREATION_TIME
) {
6174 sig
->info
.birthtime
= pkt
.u
.ss_time
.time
;
6175 sig
->info
.gotbirthtime
= 1;
6179 case OPS_PTAG_SS_TRUST
:
6180 if (!limread(&pkt
.u
.ss_trust
.level
, 1, &subregion
, stream
) ||
6181 !limread(&pkt
.u
.ss_trust
.amount
, 1, &subregion
, stream
)) {
6186 case OPS_PTAG_SS_REVOCABLE
:
6187 if (!limread(&bools
, 1, &subregion
, stream
)) {
6190 pkt
.u
.ss_revocable
.revocable
= !!bools
;
6193 case OPS_PTAG_SS_ISSUER_KEY_ID
:
6194 if (!limread(pkt
.u
.ss_issuer
.keyid
, OPS_KEY_ID_SIZE
,
6195 &subregion
, stream
)) {
6198 (void) memcpy(sig
->info
.signer
, pkt
.u
.ss_issuer
.keyid
,
6200 sig
->info
.gotsigner
= 1;
6203 case OPS_PTAG_SS_PREFERRED_SKA
:
6204 if (!read_data(&pkt
.u
.ss_skapref
.data
, &subregion
, stream
)) {
6209 case OPS_PTAG_SS_PREFERRED_HASH
:
6210 if (!read_data(&pkt
.u
.ss_hashpref
.data
, &subregion
, stream
)) {
6215 case OPS_PTAG_SS_PREF_COMPRESS
:
6216 if (!read_data(&pkt
.u
.ss_zpref
.data
,
6217 &subregion
, stream
)) {
6222 case OPS_PTAG_SS_PRIMARY_USER_ID
:
6223 if (!limread(&bools
, 1, &subregion
, stream
)) {
6226 pkt
.u
.ss_primary_userid
.primary_userid
= !!bools
;
6229 case OPS_PTAG_SS_KEY_FLAGS
:
6230 if (!read_data(&pkt
.u
.ss_key_flags
.data
, &subregion
, stream
)) {
6235 case OPS_PTAG_SS_KEYSERV_PREFS
:
6236 if (!read_data(&pkt
.u
.ss_key_server_prefs
.data
, &subregion
,
6242 case OPS_PTAG_SS_FEATURES
:
6243 if (!read_data(&pkt
.u
.ss_features
.data
, &subregion
, stream
)) {
6248 case OPS_PTAG_SS_SIGNERS_USER_ID
:
6249 if (!read_unsig_str(&pkt
.u
.ss_signer
.userid
, &subregion
,
6255 case OPS_PTAG_SS_EMBEDDED_SIGNATURE
:
6256 /* \todo should do something with this sig? */
6257 if (!read_data(&pkt
.u
.ss_embedded_sig
.sig
, &subregion
, stream
)) {
6262 case OPS_PTAG_SS_NOTATION_DATA
:
6263 if (!limread_data(&pkt
.u
.ss_notation
.flags
, 4,
6264 &subregion
, stream
)) {
6267 if (!limread_size_t(&pkt
.u
.ss_notation
.name
.len
, 2,
6268 &subregion
, stream
)) {
6271 if (!limread_size_t(&pkt
.u
.ss_notation
.value
.len
, 2,
6272 &subregion
, stream
)) {
6275 if (!limread_data(&pkt
.u
.ss_notation
.name
,
6276 pkt
.u
.ss_notation
.name
.len
,
6277 &subregion
, stream
)) {
6280 if (!limread_data(&pkt
.u
.ss_notation
.value
,
6281 pkt
.u
.ss_notation
.value
.len
,
6282 &subregion
, stream
)) {
6287 case OPS_PTAG_SS_POLICY_URI
:
6288 if (!read_string(&pkt
.u
.ss_policy
.url
, &subregion
, stream
)) {
6293 case OPS_PTAG_SS_REGEXP
:
6294 if (!read_string(&pkt
.u
.ss_regexp
.regexp
, &subregion
, stream
)) {
6299 case OPS_PTAG_SS_PREF_KEYSERV
:
6300 if (!read_string(&pkt
.u
.ss_keyserv
.name
, &subregion
, stream
)) {
6305 case OPS_PTAG_SS_USERDEFINED00
:
6306 case OPS_PTAG_SS_USERDEFINED01
:
6307 case OPS_PTAG_SS_USERDEFINED02
:
6308 case OPS_PTAG_SS_USERDEFINED03
:
6309 case OPS_PTAG_SS_USERDEFINED04
:
6310 case OPS_PTAG_SS_USERDEFINED05
:
6311 case OPS_PTAG_SS_USERDEFINED06
:
6312 case OPS_PTAG_SS_USERDEFINED07
:
6313 case OPS_PTAG_SS_USERDEFINED08
:
6314 case OPS_PTAG_SS_USERDEFINED09
:
6315 case OPS_PTAG_SS_USERDEFINED10
:
6316 if (!read_data(&pkt
.u
.ss_userdef
.data
, &subregion
, stream
)) {
6321 case OPS_PTAG_SS_RESERVED
:
6322 if (!read_data(&pkt
.u
.ss_unknown
.data
, &subregion
, stream
)) {
6327 case OPS_PTAG_SS_REVOCATION_REASON
:
6328 /* first byte is the machine-readable code */
6329 if (!limread(&pkt
.u
.ss_revocation
.code
, 1, &subregion
, stream
)) {
6332 /* the rest is a human-readable UTF-8 string */
6333 if (!read_string(&pkt
.u
.ss_revocation
.reason
, &subregion
,
6339 case OPS_PTAG_SS_REVOCATION_KEY
:
6340 /* octet 0 = class. Bit 0x80 must be set */
6341 if (!limread(&pkt
.u
.ss_revocation_key
.class, 1,
6342 &subregion
, stream
)) {
6345 if (!(pkt
.u
.ss_revocation_key
.class & 0x80)) {
6346 loggit("Warning: OPS_PTAG_SS_REVOCATION_KEY class: "
6347 "Bit 0x80 should be set");
6350 /* octet 1 = algid */
6351 if (!limread(&pkt
.u
.ss_revocation_key
.algid
, 1,
6352 &subregion
, stream
)) {
6355 /* octets 2-21 = fingerprint */
6356 if (!limread(&pkt
.u
.ss_revocation_key
.fingerprint
[0],
6357 OPS_FINGERPRINT_SIZE
, &subregion
, stream
)) {
6363 if (stream
->ss_parsed
[t8
] & t7
) {
6364 OPS_ERROR_1(&stream
->errors
, OPS_E_PROTO_UNKNOWN_SS
,
6365 "Unknown signature subpacket type (%d)",
6372 /* Application doesn't want it delivered parsed */
6373 if (!(stream
->ss_parsed
[t8
] & t7
)) {
6375 OPS_ERROR_1(&stream
->errors
,
6376 OPS_E_PROTO_CRITICAL_SS_IGNORED
,
6377 "Critical signature subpacket ignored (%d)",
6381 !limskip(subregion
.length
- 1, &subregion
, stream
)) {
6385 __ops_pkt_free(&pkt
);
6389 if (doread
&& subregion
.readc
!= subregion
.length
) {
6390 OPS_ERROR_1(&stream
->errors
, OPS_E_R_UNCONSUMED_DATA
,
6391 "Unconsumed data (%d)",
6392 subregion
.length
- subregion
.readc
);
6395 CALLBACK(pkt
.tag
, &stream
->cbdata
, &pkt
);
6400 * \ingroup Core_ReadPackets
6401 * \brief Parse several signature subpackets.
6403 * Hashed and unhashed subpacket sets are preceded by an octet count that specifies the length of the complete set.
6404 * This function parses this length and then calls parse_one_sig_subpacket() for each subpacket until the
6405 * entire set is consumed.
6407 * This function does not call the callback directly, parse_one_sig_subpacket() does for each subpacket.
6409 * \param *ptag Pointer to the Packet Tag.
6410 * \param *reader Our reader
6411 * \param *cb The callback
6412 * \return 1 on success, 0 on error
6414 * \see RFC4880 5.2.3
6417 parse_sig_subpkts(__ops_sig_t
*sig
,
6418 __ops_region_t
*region
,
6419 __ops_stream_t
*stream
)
6421 __ops_region_t subregion
;
6424 __ops_init_subregion(&subregion
, region
);
6425 if (!limread_scalar(&subregion
.length
, 2, region
, stream
)) {
6429 if (subregion
.length
> region
->length
) {
6430 ERRP(&stream
->cbdata
, pkt
, "Subpacket set too long");
6433 while (subregion
.readc
< subregion
.length
) {
6434 if (!parse_one_sig_subpacket(sig
, &subregion
, stream
)) {
6439 if (subregion
.readc
!= subregion
.length
) {
6440 if (!limskip(subregion
.length
- subregion
.readc
,
6441 &subregion
, stream
)) {
6442 ERRP(&stream
->cbdata
, pkt
,
6443 "parse_sig_subpkts: subpacket length read mismatch");
6445 ERRP(&stream
->cbdata
, pkt
, "Subpacket length mismatch");
6451 * \ingroup Core_ReadPackets
6452 * \brief Parse a version 4 signature.
6454 * This function parses a version 4 signature including all its hashed and unhashed subpackets.
6456 * Once the signature packet has been parsed successfully, it is passed to the callback.
6458 * \param *ptag Pointer to the Packet Tag.
6459 * \param *reader Our reader
6460 * \param *cb The callback
6461 * \return 1 on success, 0 on error
6463 * \see RFC4880 5.2.3
6466 parse_v4_sig(__ops_region_t
*region
, __ops_stream_t
*stream
)
6471 /* clear signature */
6472 (void) memset(&pkt
.u
.sig
, 0x0, sizeof(pkt
.u
.sig
));
6475 * We need to hash the packet data from version through the hashed
6479 pkt
.u
.sig
.v4_hashstart
= stream
->readinfo
.alength
- 1;
6481 /* Set version,type,algorithms */
6483 pkt
.u
.sig
.info
.version
= OPS_V4
;
6485 if (!limread(&c
, 1, region
, stream
)) {
6488 pkt
.u
.sig
.info
.type
= c
;
6489 /* XXX: check signature type */
6491 if (!limread(&c
, 1, region
, stream
)) {
6494 pkt
.u
.sig
.info
.key_alg
= c
;
6495 /* XXX: check algorithm */
6496 if (!limread(&c
, 1, region
, stream
)) {
6499 pkt
.u
.sig
.info
.hash_alg
= c
;
6500 /* XXX: check algorithm */
6501 CALLBACK(OPS_PTAG_CT_SIGNATURE_HEADER
, &stream
->cbdata
, &pkt
);
6503 if (!parse_sig_subpkts(&pkt
.u
.sig
, region
, stream
)) {
6507 pkt
.u
.sig
.info
.v4_hashlen
= stream
->readinfo
.alength
6508 - pkt
.u
.sig
.v4_hashstart
;
6510 /* copy hashed subpackets */
6511 if (pkt
.u
.sig
.info
.v4_hashed
) {
6512 (void) free(pkt
.u
.sig
.info
.v4_hashed
);
6514 pkt
.u
.sig
.info
.v4_hashed
= __ops_new(pkt
.u
.sig
.info
.v4_hashlen
);
6516 if (!stream
->readinfo
.accumulate
) {
6517 /* We must accumulate, else we can't check the signature */
6518 loggit("*** ERROR: must set accumulate to 1");
6521 (void) memcpy(pkt
.u
.sig
.info
.v4_hashed
,
6522 stream
->readinfo
.accumulated
+ pkt
.u
.sig
.v4_hashstart
,
6523 pkt
.u
.sig
.info
.v4_hashlen
);
6525 if (!parse_sig_subpkts(&pkt
.u
.sig
, region
, stream
)) {
6529 if (!limread(pkt
.u
.sig
.hash2
, 2, region
, stream
)) {
6533 switch (pkt
.u
.sig
.info
.key_alg
) {
6535 if (!limread_mpi(&pkt
.u
.sig
.info
.sig
.rsa
.sig
, region
, stream
)) {
6541 if (!limread_mpi(&pkt
.u
.sig
.info
.sig
.dsa
.r
, region
, stream
)) {
6543 * usually if this fails, it just means we've reached
6544 * the end of the keyring
6548 if (!limread_mpi(&pkt
.u
.sig
.info
.sig
.dsa
.s
, region
, stream
)) {
6549 ERRP(&stream
->cbdata
, pkt
,
6550 "Error reading DSA s field in signature");
6554 case OPS_PKA_ELGAMAL_ENCRYPT_OR_SIGN
:
6555 if (!limread_mpi(&pkt
.u
.sig
.info
.sig
.elgamal
.r
, region
,
6557 !limread_mpi(&pkt
.u
.sig
.info
.sig
.elgamal
.s
, region
,
6563 case OPS_PKA_PRIVATE00
:
6564 case OPS_PKA_PRIVATE01
:
6565 case OPS_PKA_PRIVATE02
:
6566 case OPS_PKA_PRIVATE03
:
6567 case OPS_PKA_PRIVATE04
:
6568 case OPS_PKA_PRIVATE05
:
6569 case OPS_PKA_PRIVATE06
:
6570 case OPS_PKA_PRIVATE07
:
6571 case OPS_PKA_PRIVATE08
:
6572 case OPS_PKA_PRIVATE09
:
6573 case OPS_PKA_PRIVATE10
:
6574 if (!read_data(&pkt
.u
.sig
.info
.sig
.unknown
.data
, region
,
6581 OPS_ERROR_1(&stream
->errors
,
6582 OPS_E_ALG_UNSUPPORTED_SIGNATURE_ALG
,
6583 "Bad v4 signature key algorithm (%s)",
6584 findtype((int) pkt
.u
.sig
.info
.key_alg
, pubkeyalgs
));
6587 if (region
->readc
!= region
->length
) {
6588 OPS_ERROR_1(&stream
->errors
, OPS_E_R_UNCONSUMED_DATA
,
6589 "Unconsumed data (%d)",
6590 region
->length
- region
->readc
);
6593 CALLBACK(OPS_PTAG_CT_SIGNATURE_FOOTER
, &stream
->cbdata
, &pkt
);
6598 * \ingroup Core_ReadPackets
6599 * \brief Parse a signature subpacket.
6601 * This function calls the appropriate function to handle v3 or v4 signatures.
6603 * Once the signature packet has been parsed successfully, it is passed to the callback.
6605 * \param *ptag Pointer to the Packet Tag.
6606 * \param *reader Our reader
6607 * \param *cb The callback
6608 * \return 1 on success, 0 on error
6611 parse_sig(__ops_region_t
*region
, __ops_stream_t
*stream
)
6616 if (region
->readc
!= 0) {
6617 /* We should not have read anything so far */
6618 loggit("parse_sig: bad length");
6622 (void) memset(&pkt
, 0x0, sizeof(pkt
));
6623 if (!limread(&c
, 1, region
, stream
)) {
6626 if (c
== 2 || c
== 3) {
6627 return parse_v3_sig(region
, stream
);
6630 return parse_v4_sig(region
, stream
);
6632 OPS_ERROR_1(&stream
->errors
, OPS_E_PROTO_BAD_SIGNATURE_VRSN
,
6633 "Bad signature version (%d)", c
);
6638 \ingroup Core_ReadPackets
6639 \brief Parse Compressed packet
6642 parse_compressed(__ops_region_t
*region
, __ops_stream_t
*stream
)
6647 if (!limread(&c
, 1, region
, stream
)) {
6651 pkt
.u
.compressed
.type
= c
;
6653 CALLBACK(OPS_PTAG_CT_COMPRESSED
, &stream
->cbdata
, &pkt
);
6656 * The content of a compressed data packet is more OpenPGP packets
6657 * once decompressed, so recursively handle them
6660 return __ops_decompress(region
, stream
, pkt
.u
.compressed
.type
);
6663 /* XXX: this could be improved by sharing all hashes that are the */
6664 /* same, then duping them just before checking the signature. */
6666 parse_hash_init(__ops_stream_t
*stream
, __ops_hash_alg_t type
,
6667 const uint8_t *keyid
)
6669 __ops_hashtype_t
*hash
;
6671 stream
->hashes
= realloc(stream
->hashes
,
6672 (stream
->hashc
+ 1) * sizeof(*stream
->hashes
));
6673 hash
= &stream
->hashes
[stream
->hashc
++];
6675 __ops_hash_any(&hash
->hash
, type
);
6676 hash
->hash
.init(&hash
->hash
);
6677 (void) memcpy(hash
->keyid
, keyid
, sizeof(hash
->keyid
));
6681 \ingroup Core_ReadPackets
6682 \brief Parse a One Pass Signature packet
6685 parse_one_pass(__ops_region_t
* region
, __ops_stream_t
* stream
)
6690 if (!limread(&pkt
.u
.one_pass_sig
.version
, 1, region
, stream
)) {
6693 if (pkt
.u
.one_pass_sig
.version
!= 3) {
6694 OPS_ERROR_1(&stream
->errors
, OPS_E_PROTO_BAD_ONE_PASS_SIG_VRSN
,
6695 "Bad one-pass signature version (%d)",
6696 pkt
.u
.one_pass_sig
.version
);
6699 if (!limread(&c
, 1, region
, stream
)) {
6702 pkt
.u
.one_pass_sig
.sig_type
= c
;
6704 if (!limread(&c
, 1, region
, stream
)) {
6707 pkt
.u
.one_pass_sig
.hash_alg
= c
;
6709 if (!limread(&c
, 1, region
, stream
)) {
6712 pkt
.u
.one_pass_sig
.key_alg
= c
;
6714 if (!limread(pkt
.u
.one_pass_sig
.keyid
,
6715 sizeof(pkt
.u
.one_pass_sig
.keyid
), region
, stream
)) {
6719 if (!limread(&c
, 1, region
, stream
)) {
6722 pkt
.u
.one_pass_sig
.nested
= !!c
;
6723 CALLBACK(OPS_PTAG_CT_1_PASS_SIG
, &stream
->cbdata
, &pkt
);
6724 /* XXX: we should, perhaps, let the app choose whether to hash or not */
6725 parse_hash_init(stream
, pkt
.u
.one_pass_sig
.hash_alg
,
6726 pkt
.u
.one_pass_sig
.keyid
);
6731 \ingroup Core_ReadPackets
6732 \brief Parse a Trust packet
6735 parse_trust(__ops_region_t
*region
, __ops_stream_t
*stream
)
6739 if (!read_data(&pkt
.u
.trust
.data
, region
, stream
)) {
6742 CALLBACK(OPS_PTAG_CT_TRUST
, &stream
->cbdata
, &pkt
);
6747 parse_hash_data(__ops_stream_t
*stream
, const void *data
, size_t len
)
6751 for (n
= 0; n
< stream
->hashc
; ++n
) {
6752 stream
->hashes
[n
].hash
.add(&stream
->hashes
[n
].hash
, data
, len
);
6757 \ingroup Core_ReadPackets
6758 \brief Parse a Literal Data packet
6761 parse_litdata(__ops_region_t
*region
, __ops_stream_t
*stream
)
6763 __ops_memory_t
*mem
;
6767 if (!limread(&c
, 1, region
, stream
)) {
6770 pkt
.u
.litdata_header
.format
= c
;
6771 if (!limread(&c
, 1, region
, stream
)) {
6774 if (!limread((uint8_t *)pkt
.u
.litdata_header
.filename
,
6775 (unsigned)c
, region
, stream
)) {
6778 pkt
.u
.litdata_header
.filename
[c
] = '\0';
6779 if (!limited_read_time(&pkt
.u
.litdata_header
.mtime
, region
, stream
)) {
6782 CALLBACK(OPS_PTAG_CT_LITDATA_HEADER
, &stream
->cbdata
, &pkt
);
6783 mem
= pkt
.u
.litdata_body
.mem
= __ops_new(sizeof(*mem
));
6784 __ops_memory_init(pkt
.u
.litdata_body
.mem
,
6785 (unsigned)(region
->length
* 1.01) + 12);
6786 pkt
.u
.litdata_body
.data
= mem
->buf
;
6788 while (region
->readc
< region
->length
) {
6789 unsigned readc
= region
->length
- region
->readc
;
6791 if (!limread(mem
->buf
, readc
, region
, stream
)) {
6794 pkt
.u
.litdata_body
.length
= readc
;
6795 parse_hash_data(stream
, pkt
.u
.litdata_body
.data
, region
->length
);
6796 CALLBACK(OPS_PTAG_CT_LITDATA_BODY
, &stream
->cbdata
, &pkt
);
6799 /* XXX - get rid of mem here? */
6805 consume_packet(__ops_region_t
*region
, __ops_stream_t
*stream
, unsigned warn
)
6808 __ops_data_t remainder
;
6810 if (region
->indeterm
) {
6811 ERRP(&stream
->cbdata
, pkt
,
6812 "Can't consume indeterminate packets");
6815 if (read_data(&remainder
, region
, stream
)) {
6816 /* now throw it away */
6817 data_free(&remainder
);
6819 OPS_ERROR(&stream
->errors
, OPS_E_P_PACKET_CONSUMED
,
6820 "Warning: packet consumer");
6824 OPS_ERROR(&stream
->errors
, OPS_E_P_PACKET_NOT_CONSUMED
,
6825 (warn
) ? "Warning: Packet was not consumed" :
6826 "Packet was not consumed");
6830 static void __ops_reader_push_decrypt(__ops_stream_t
*,
6833 static void __ops_reader_pop_decrypt(__ops_stream_t
*);
6836 hash_reader(void *dest
,
6838 __ops_error_t
**errors
,
6839 __ops_reader_t
*readinfo
,
6840 __ops_cbdata_t
*cbdata
)
6842 __ops_hash_t
*hash
= readinfo
->arg
;
6845 r
= __ops_stacked_read(dest
, length
, errors
, readinfo
, cbdata
);
6849 hash
->add(hash
, dest
, (unsigned)r
);
6854 \ingroup Internal_Readers_Hash
6855 \brief Push hashed data reader on stack
6858 __ops_reader_push_hash(__ops_stream_t
*stream
, __ops_hash_t
*hash
)
6861 __ops_reader_push(stream
, hash_reader
, NULL
, hash
);
6865 \ingroup Internal_Readers_Hash
6866 \brief Pop hashed data reader from stack
6869 __ops_reader_pop_hash(__ops_stream_t
*stream
)
6871 __ops_reader_pop(stream
);
6875 * \ingroup Core_ReadPackets
6876 * \brief Parse a secret key
6879 parse_seckey(__ops_region_t
*region
, __ops_stream_t
*stream
)
6882 __ops_region_t encregion
;
6883 __ops_region_t
*saved_region
= NULL
;
6885 __ops_crypt_t decrypt
;
6886 __ops_hash_t checkhash
;
6891 (void) memset(&pkt
, 0x0, sizeof(pkt
));
6892 if (!parse_pubkey_data(&pkt
.u
.seckey
.pubkey
, region
, stream
)) {
6895 stream
->reading_v3_secret
= pkt
.u
.seckey
.pubkey
.version
!= OPS_V4
;
6897 if (!limread(&c
, 1, region
, stream
)) {
6900 pkt
.u
.seckey
.s2k_usage
= c
;
6902 if (pkt
.u
.seckey
.s2k_usage
== OPS_S2KU_ENCRYPTED
||
6903 pkt
.u
.seckey
.s2k_usage
== OPS_S2KU_ENCRYPTED_AND_HASHED
) {
6904 if (!limread(&c
, 1, region
, stream
)) {
6907 pkt
.u
.seckey
.alg
= c
;
6908 if (!limread(&c
, 1, region
, stream
)) {
6911 pkt
.u
.seckey
.s2k_specifier
= c
;
6912 switch (pkt
.u
.seckey
.s2k_specifier
) {
6913 case OPS_S2KS_SIMPLE
:
6914 case OPS_S2KS_SALTED
:
6915 case OPS_S2KS_ITERATED_AND_SALTED
:
6918 loggit("parse_seckey: bad seckey");
6921 if (!limread(&c
, 1, region
, stream
)) {
6924 pkt
.u
.seckey
.hash_alg
= c
;
6925 if (pkt
.u
.seckey
.s2k_specifier
!= OPS_S2KS_SIMPLE
&&
6926 !limread(pkt
.u
.seckey
.salt
, 8, region
, stream
)) {
6929 if (pkt
.u
.seckey
.s2k_specifier
==
6930 OPS_S2KS_ITERATED_AND_SALTED
) {
6931 if (!limread(&c
, 1, region
, stream
)) {
6934 pkt
.u
.seckey
.octetc
=
6935 (16 + ((unsigned)c
& 15)) <<
6936 (((unsigned)c
>> 4) + 6);
6938 } else if (pkt
.u
.seckey
.s2k_usage
!= OPS_S2KU_NONE
) {
6939 /* this is V3 style, looks just like a V4 simple hash */
6940 pkt
.u
.seckey
.alg
= c
;
6941 pkt
.u
.seckey
.s2k_usage
= OPS_S2KU_ENCRYPTED
;
6942 pkt
.u
.seckey
.s2k_specifier
= OPS_S2KS_SIMPLE
;
6943 pkt
.u
.seckey
.hash_alg
= OPS_HASH_MD5
;
6945 crypted
= pkt
.u
.seckey
.s2k_usage
== OPS_S2KU_ENCRYPTED
||
6946 pkt
.u
.seckey
.s2k_usage
== OPS_S2KU_ENCRYPTED_AND_HASHED
;
6949 __ops_packet_t seckey
;
6950 uint8_t key
[OPS_MAX_KEY_SIZE
+ OPS_MAX_HASH_SIZE
];
6951 __ops_hash_t hashes
[(OPS_MAX_KEY_SIZE
+ OPS_MIN_HASH_SIZE
- 1) / OPS_MIN_HASH_SIZE
];
6958 blocksize
= __ops_block_size(pkt
.u
.seckey
.alg
);
6959 if (blocksize
== 0 || blocksize
> OPS_MAX_BLOCK_SIZE
) {
6960 loggit("parse_seckey: bad blocksize");
6964 if (!limread(pkt
.u
.seckey
.iv
, blocksize
, region
, stream
)) {
6967 (void) memset(&seckey
, 0x0, sizeof(seckey
));
6969 seckey
.u
.skey_passphrase
.passphrase
= &passphrase
;
6970 seckey
.u
.skey_passphrase
.seckey
= &pkt
.u
.seckey
;
6971 CALLBACK(OPS_GET_PASSPHRASE
, &stream
->cbdata
, &seckey
);
6973 if (!consume_packet(region
, stream
, 0)) {
6976 CALLBACK(OPS_PTAG_CT_ENCRYPTED_SECRET_KEY
,
6977 &stream
->cbdata
, &pkt
);
6980 keysize
= __ops_key_size(pkt
.u
.seckey
.alg
);
6981 if (keysize
== 0 || keysize
> OPS_MAX_KEY_SIZE
) {
6982 loggit("parse_seckey: bad keysize");
6986 hashsize
= __ops_hash_size(pkt
.u
.seckey
.hash_alg
);
6987 if (hashsize
== 0 || hashsize
> OPS_MAX_HASH_SIZE
) {
6988 loggit("parse_seckey: bad hashsize");
6992 for (n
= 0; n
* hashsize
< keysize
; ++n
) {
6995 __ops_hash_any(&hashes
[n
],
6996 pkt
.u
.seckey
.hash_alg
);
6997 hashes
[n
].init(&hashes
[n
]);
6998 /* preload hashes with zeroes... */
6999 for (i
= 0; i
< n
; ++i
) {
7000 hashes
[n
].add(&hashes
[n
],
7001 (const uint8_t *) "", 1);
7004 passlen
= strlen(passphrase
);
7005 for (n
= 0; n
* hashsize
< keysize
; ++n
) {
7008 switch (pkt
.u
.seckey
.s2k_specifier
) {
7009 case OPS_S2KS_SALTED
:
7010 hashes
[n
].add(&hashes
[n
],
7014 case OPS_S2KS_SIMPLE
:
7015 hashes
[n
].add(&hashes
[n
],
7016 (uint8_t *) passphrase
, passlen
);
7019 case OPS_S2KS_ITERATED_AND_SALTED
:
7020 for (i
= 0; i
< pkt
.u
.seckey
.octetc
;
7021 i
+= passlen
+ OPS_SALT_SIZE
) {
7024 j
= passlen
+ OPS_SALT_SIZE
;
7025 if (i
+ j
> pkt
.u
.seckey
.octetc
&& i
!= 0) {
7026 j
= pkt
.u
.seckey
.octetc
- i
;
7028 hashes
[n
].add(&hashes
[n
],
7030 (unsigned)(j
> OPS_SALT_SIZE
) ?
7032 if (j
> OPS_SALT_SIZE
) {
7033 hashes
[n
].add(&hashes
[n
],
7034 (uint8_t *) passphrase
,
7042 for (n
= 0; n
* hashsize
< keysize
; ++n
) {
7045 r
= hashes
[n
].finish(&hashes
[n
], key
+ n
* hashsize
);
7046 if (r
!= hashsize
) {
7047 loggit("parse_seckey: bad r");
7052 __ops_forget(passphrase
, passlen
);
7053 (void) free(passphrase
);
7055 __ops_crypt_any(&decrypt
, pkt
.u
.seckey
.alg
);
7056 decrypt
.set_iv(&decrypt
, pkt
.u
.seckey
.iv
);
7057 decrypt
.set_crypt_key(&decrypt
, key
);
7059 /* now read encrypted data */
7061 __ops_reader_push_decrypt(stream
, &decrypt
, region
);
7064 * Since all known encryption for PGP doesn't compress, we
7065 * can limit to the same length as the current region (for
7068 __ops_init_subregion(&encregion
, NULL
);
7069 encregion
.length
= region
->length
- region
->readc
;
7070 if (pkt
.u
.seckey
.pubkey
.version
!= OPS_V4
) {
7071 encregion
.length
-= 2;
7073 saved_region
= region
;
7074 region
= &encregion
;
7076 if (pkt
.u
.seckey
.s2k_usage
== OPS_S2KU_ENCRYPTED_AND_HASHED
) {
7077 pkt
.u
.seckey
.checkhash
= __ops_new(OPS_CHECKHASH_SIZE
);
7078 __ops_hash_sha1(&checkhash
);
7079 __ops_reader_push_hash(stream
, &checkhash
);
7081 __ops_reader_push_sum16(stream
);
7084 switch (pkt
.u
.seckey
.pubkey
.alg
) {
7086 case OPS_PKA_RSA_ENCRYPT_ONLY
:
7087 case OPS_PKA_RSA_SIGN_ONLY
:
7088 if (!limread_mpi(&pkt
.u
.seckey
.key
.rsa
.d
, region
, stream
) ||
7089 !limread_mpi(&pkt
.u
.seckey
.key
.rsa
.p
, region
, stream
) ||
7090 !limread_mpi(&pkt
.u
.seckey
.key
.rsa
.q
, region
, stream
) ||
7091 !limread_mpi(&pkt
.u
.seckey
.key
.rsa
.u
, region
, stream
)) {
7097 if (!limread_mpi(&pkt
.u
.seckey
.key
.dsa
.x
, region
, stream
)) {
7103 OPS_ERROR_2(&stream
->errors
,
7104 OPS_E_ALG_UNSUPPORTED_PUBLIC_KEY_ALG
,
7105 "Unsupported Public Key algorithm %d (%s)",
7106 pkt
.u
.seckey
.pubkey
.alg
,
7107 findtype((int) pkt
.u
.seckey
.pubkey
.alg
, pubkeyalgs
));
7111 stream
->reading_v3_secret
= 0;
7113 if (pkt
.u
.seckey
.s2k_usage
== OPS_S2KU_ENCRYPTED_AND_HASHED
) {
7114 uint8_t hash
[OPS_CHECKHASH_SIZE
];
7116 __ops_reader_pop_hash(stream
);
7117 checkhash
.finish(&checkhash
, hash
);
7120 pkt
.u
.seckey
.pubkey
.version
!= OPS_V4
) {
7121 __ops_reader_pop_decrypt(stream
);
7122 region
= saved_region
;
7125 if (!limread(pkt
.u
.seckey
.checkhash
,
7126 OPS_CHECKHASH_SIZE
, region
, stream
)) {
7130 if (memcmp(hash
, pkt
.u
.seckey
.checkhash
,
7131 OPS_CHECKHASH_SIZE
) != 0) {
7132 ERRP(&stream
->cbdata
, pkt
,
7133 "Hash mismatch in secret key");
7139 sum
= __ops_reader_pop_sum16(stream
);
7141 pkt
.u
.seckey
.pubkey
.version
!= OPS_V4
) {
7142 __ops_reader_pop_decrypt(stream
);
7143 region
= saved_region
;
7146 if (!limread_scalar(&pkt
.u
.seckey
.checksum
, 2,
7150 if (sum
!= pkt
.u
.seckey
.checksum
) {
7151 ERRP(&stream
->cbdata
, pkt
,
7152 "Checksum mismatch in secret key");
7157 if (crypted
&& pkt
.u
.seckey
.pubkey
.version
== OPS_V4
) {
7158 __ops_reader_pop_decrypt(stream
);
7160 if (ret
&& region
->readc
!= region
->length
) {
7161 loggit("parse_seckey: bad length");
7167 CALLBACK(OPS_PTAG_CT_SECRET_KEY
, &stream
->cbdata
, &pkt
);
7173 \brief Decrypt and unencode MPI
7174 \param buf Buffer in which to write decrypted unencoded MPI
7175 \param buflen Length of buffer
7178 \return length of MPI
7179 \note only RSA at present
7182 __ops_decrypt_decode_mpi(uint8_t *buf
,
7184 const BIGNUM
*encmpi
,
7185 const __ops_seckey_t
*seckey
)
7188 uint8_t encmpibuf
[NETPGP_BUFSIZ
];
7189 uint8_t mpibuf
[NETPGP_BUFSIZ
];
7193 mpisize
= BN_num_bytes(encmpi
);
7194 /* MPI can't be more than 65,536 */
7195 if (mpisize
> sizeof(encmpibuf
)) {
7196 loggit("mpisize too big %u", mpisize
);
7199 BN_bn2bin(encmpi
, encmpibuf
);
7201 if (seckey
->pubkey
.alg
!= OPS_PKA_RSA
) {
7202 loggit("pubkey algorithm wrong");
7206 n
= __ops_rsa_private_decrypt(mpibuf
, encmpibuf
,
7207 (unsigned)(BN_num_bits(encmpi
) + 7) / 8,
7208 &seckey
->key
.rsa
, &seckey
->pubkey
.key
.rsa
);
7210 loggit("ops_rsa_private_decrypt failure");
7218 /* Decode EME-PKCS1_V1_5 (RFC 2437). */
7220 if (mpibuf
[0] != 0 || mpibuf
[1] != 2) {
7224 /* Skip the random bytes. */
7225 for (i
= 2; i
< n
&& mpibuf
[i
]; ++i
) {
7228 if (i
== n
|| i
< 10) {
7235 /* this is the unencoded m buf */
7236 if ((unsigned) (n
- i
) <= buflen
) {
7237 (void) memcpy(buf
, mpibuf
+ i
, (unsigned)(n
- i
));
7244 \ingroup Core_ReadPackets
7245 \brief Parse a Public Key Session Key packet
7248 parse_pk_sesskey(__ops_region_t
*region
, __ops_stream_t
*stream
)
7250 const __ops_seckey_t
*secret
;
7251 __ops_packet_t sesskey
;
7260 /* Can't rely on it being CAST5 */
7261 /* \todo FIXME RW */
7262 /* const size_t sz_unencoded_m_buf=CAST_KEY_LENGTH+1+2; */
7263 uint8_t unencoded_m_buf
[1024];
7265 cs
[0] = cs
[1] = 0x0;
7266 if (!limread(&c
, 1, region
, stream
)) {
7269 pkt
.u
.pk_sesskey
.version
= c
;
7270 if (pkt
.u
.pk_sesskey
.version
!= OPS_PKSK_V3
) {
7271 OPS_ERROR_1(&stream
->errors
, OPS_E_PROTO_BAD_PKSK_VRSN
,
7272 "Bad public-key encrypted session key version (%d)",
7273 pkt
.u
.pk_sesskey
.version
);
7276 if (!limread(pkt
.u
.pk_sesskey
.keyid
,
7277 sizeof(pkt
.u
.pk_sesskey
.keyid
), region
, stream
)) {
7280 if (!limread(&c
, 1, region
, stream
)) {
7283 pkt
.u
.pk_sesskey
.alg
= c
;
7284 switch (pkt
.u
.pk_sesskey
.alg
) {
7286 if (!limread_mpi(&pkt
.u
.pk_sesskey
.params
.rsa
.encrypted_m
,
7290 enc_m
= pkt
.u
.pk_sesskey
.params
.rsa
.encrypted_m
;
7293 case OPS_PKA_ELGAMAL
:
7294 if (!limread_mpi(&pkt
.u
.pk_sesskey
.params
.elgamal
.g_to_k
,
7297 &pkt
.u
.pk_sesskey
.params
.elgamal
.encrypted_m
,
7301 enc_m
= pkt
.u
.pk_sesskey
.params
.elgamal
.encrypted_m
;
7305 OPS_ERROR_1(&stream
->errors
,
7306 OPS_E_ALG_UNSUPPORTED_PUBLIC_KEY_ALG
,
7307 "Unknown public key algorithm in session key (%s)",
7308 findtype((int) pkt
.u
.pk_sesskey
.alg
, pubkeyalgs
));
7312 (void) memset(&sesskey
, 0x0, sizeof(sesskey
));
7314 sesskey
.u
.get_seckey
.seckey
= &secret
;
7315 sesskey
.u
.get_seckey
.pk_sesskey
= &pkt
.u
.pk_sesskey
;
7317 CALLBACK(OPS_GET_SECKEY
, &stream
->cbdata
, &sesskey
);
7320 CALLBACK(OPS_PTAG_CT_ENCRYPTED_PK_SESSION_KEY
, &stream
->cbdata
,
7324 n
= __ops_decrypt_decode_mpi(unencoded_m_buf
, sizeof(unencoded_m_buf
),
7327 ERRP(&stream
->cbdata
, pkt
, "decrypted message too short");
7332 pkt
.u
.pk_sesskey
.symm_alg
= unencoded_m_buf
[0];
7334 if (!__ops_is_sa_supported(pkt
.u
.pk_sesskey
.symm_alg
)) {
7336 OPS_ERROR_1(&stream
->errors
,
7337 OPS_E_ALG_UNSUPPORTED_SYMMETRIC_ALG
,
7338 "Symmetric algorithm %s not supported",
7339 findtype((int)pkt
.u
.pk_sesskey
.symm_alg
, symm_alg_map
));
7342 k
= __ops_key_size(pkt
.u
.pk_sesskey
.symm_alg
);
7344 if ((unsigned) n
!= k
+ 3) {
7345 OPS_ERROR_2(&stream
->errors
,
7346 OPS_E_PROTO_DECRYPTED_MSG_WRONG_LEN
,
7347 "decrypted message wrong length (got %d expected %d)",
7351 if (k
> sizeof(pkt
.u
.pk_sesskey
.key
)) {
7352 loggit("parse_pk_sesskey: bad keylength");
7356 (void) memcpy(pkt
.u
.pk_sesskey
.key
, unencoded_m_buf
+ 1, k
);
7358 pkt
.u
.pk_sesskey
.checksum
= unencoded_m_buf
[k
+ 1] +
7359 (unencoded_m_buf
[k
+ 2] << 8);
7361 /* Check checksum */
7362 __ops_calc_sesskey_checksum(&pkt
.u
.pk_sesskey
, cs
);
7363 if (unencoded_m_buf
[k
+ 1] != cs
[0] ||
7364 unencoded_m_buf
[k
+ 2] != cs
[1]) {
7365 OPS_ERROR_4(&stream
->errors
, OPS_E_PROTO_BAD_SK_CHECKSUM
,
7366 "Session key checksum wrong: expected %2x %2x, got %2x %2x",
7367 cs
[0], cs
[1], unencoded_m_buf
[k
+ 1],
7368 unencoded_m_buf
[k
+ 2]);
7372 CALLBACK(OPS_PTAG_CT_PK_SESSION_KEY
, &stream
->cbdata
, &pkt
);
7374 __ops_crypt_any(&stream
->decrypt
, pkt
.u
.pk_sesskey
.symm_alg
);
7375 iv
= __ops_new(stream
->decrypt
.blocksize
);
7376 stream
->decrypt
.set_iv(&stream
->decrypt
, iv
);
7377 stream
->decrypt
.set_crypt_key(&stream
->decrypt
, pkt
.u
.pk_sesskey
.key
);
7378 __ops_encrypt_init(&stream
->decrypt
);
7384 __ops_decrypt_se_data(__ops_content_tag_t tag
, __ops_region_t
*region
,
7385 __ops_stream_t
*stream
)
7387 __ops_crypt_t
*decrypt
;
7388 const int printerrors
= 1;
7391 if (stream
->decrypt
.alg
) {
7392 __ops_region_t encregion
;
7393 uint8_t buf
[OPS_MAX_BLOCK_SIZE
+ 2] = "";
7396 decrypt
= &stream
->decrypt
;
7397 blksize
= decrypt
->blocksize
;
7398 __ops_reader_push_decrypt(stream
, decrypt
, region
);
7399 __ops_init_subregion(&encregion
, NULL
);
7400 encregion
.length
= blksize
+ 2;
7401 if (!exact_limread(buf
, blksize
+ 2, &encregion
, stream
)) {
7404 if (buf
[blksize
- 2] != buf
[blksize
] ||
7405 buf
[blksize
- 1] != buf
[blksize
+ 1]) {
7406 __ops_reader_pop_decrypt(stream
);
7407 OPS_ERROR_4(&stream
->errors
,
7408 OPS_E_PROTO_BAD_SYMMETRIC_DECRYPT
,
7409 "Bad symmetric decrypt (%02x%02x vs %02x%02x)",
7410 buf
[blksize
- 2], buf
[blksize
- 1],
7411 buf
[blksize
], buf
[blksize
+ 1]);
7414 if (tag
== OPS_PTAG_CT_SE_DATA_BODY
) {
7415 decrypt
->decrypt_resync(decrypt
);
7416 decrypt
->block_encrypt(decrypt
, decrypt
->civ
,
7419 r
= __ops_parse(stream
, !printerrors
);
7420 __ops_reader_pop_decrypt(stream
);
7424 while (region
->readc
< region
->length
) {
7427 len
= region
->length
- region
->readc
;
7428 if (len
> sizeof(pkt
.u
.se_data_body
.data
))
7429 len
= sizeof(pkt
.u
.se_data_body
.data
);
7431 if (!limread(pkt
.u
.se_data_body
.data
, len
,
7435 pkt
.u
.se_data_body
.length
= len
;
7436 CALLBACK(tag
, &stream
->cbdata
, &pkt
);
7442 static void __ops_reader_push_se_ip_data(__ops_stream_t
*,
7445 static void __ops_reader_pop_se_ip_data(__ops_stream_t
*);
7448 __ops_decrypt_se_ip_data(__ops_content_tag_t tag
, __ops_region_t
*region
,
7449 __ops_stream_t
*stream
)
7451 __ops_crypt_t
*decrypt
;
7452 const int printerrors
= 1;
7455 if (stream
->decrypt
.alg
) {
7456 decrypt
= &stream
->decrypt
;
7457 __ops_reader_push_decrypt(stream
, decrypt
, region
);
7458 __ops_reader_push_se_ip_data(stream
, decrypt
, region
);
7459 r
= __ops_parse(stream
, !printerrors
);
7460 __ops_reader_pop_se_ip_data(stream
);
7461 __ops_reader_pop_decrypt(stream
);
7465 while (region
->readc
< region
->length
) {
7468 len
= region
->length
- region
->readc
;
7469 if (len
> sizeof(pkt
.u
.se_data_body
.data
)) {
7470 len
= sizeof(pkt
.u
.se_data_body
.data
);
7472 if (!limread(pkt
.u
.se_data_body
.data
,
7473 len
, region
, stream
)) {
7476 pkt
.u
.se_data_body
.length
= len
;
7477 CALLBACK(tag
, &stream
->cbdata
, &pkt
);
7484 \ingroup Core_ReadPackets
7485 \brief Read a Symmetrically Encrypted packet
7488 parse_se_data(__ops_region_t
*region
, __ops_stream_t
*stream
)
7492 /* there's no info to go with this, so just announce it */
7493 CALLBACK(OPS_PTAG_CT_SE_DATA_HEADER
, &stream
->cbdata
, &pkt
);
7496 * The content of an encrypted data packet is more OpenPGP packets
7497 * once decrypted, so recursively handle them
7499 return __ops_decrypt_se_data(OPS_PTAG_CT_SE_DATA_BODY
, region
, stream
);
7503 \ingroup Core_ReadPackets
7504 \brief Read a Symmetrically Encrypted Integrity Protected packet
7507 parse_se_ip_data(__ops_region_t
*region
, __ops_stream_t
*stream
)
7512 if (!limread(&c
, 1, region
, stream
)) {
7515 pkt
.u
.se_ip_data_header
.version
= c
;
7517 if (pkt
.u
.se_ip_data_header
.version
!= OPS_SE_IP_V1
) {
7518 loggit("parse_se_ip_data: bad version");
7523 * The content of an encrypted data packet is more OpenPGP packets
7524 * once decrypted, so recursively handle them
7526 return __ops_decrypt_se_ip_data(OPS_PTAG_CT_SE_IP_DATA_BODY
, region
,
7531 \ingroup Core_ReadPackets
7532 \brief Read a MDC packet
7535 parse_mdc(__ops_region_t
*region
, __ops_stream_t
*stream
)
7539 pkt
.u
.mdc
.length
= OPS_SHA1_HASH_SIZE
;
7540 pkt
.u
.mdc
.data
= __ops_new(OPS_SHA1_HASH_SIZE
);
7541 if (!limread(pkt
.u
.mdc
.data
, OPS_SHA1_HASH_SIZE
, region
, stream
)) {
7544 CALLBACK(OPS_PTAG_CT_MDC
, &stream
->cbdata
, &pkt
);
7545 (void) free(pkt
.u
.mdc
.data
);
7550 * \ingroup Core_ReadPackets
7551 * \brief Parse one packet.
7553 * This function parses the packet tag. It computes the value of the
7554 * content tag and then calls the appropriate function to handle the
7557 * \param *stream How to parse
7558 * \param *pktlen On return, will contain number of bytes in packet
7559 * \return 1 on success, 0 on error, -1 on EOF */
7561 __ops_parse_packet(__ops_stream_t
*stream
, unsigned long *pktlen
)
7564 __ops_region_t region
;
7566 unsigned indeterm
= 0;
7569 pkt
.u
.ptag
.position
= stream
->readinfo
.position
;
7571 ret
= sub_base_read(&ptag
, 1, &stream
->errors
, &stream
->readinfo
,
7574 /* errors in the base read are effectively EOF. */
7581 if (!(ptag
& OPS_PTAG_ALWAYS_SET
)) {
7582 pkt
.u
.error
.error
= "Format error (ptag bit not set)";
7583 CALLBACK(OPS_PARSER_ERROR
, &stream
->cbdata
, &pkt
);
7586 pkt
.u
.ptag
.new_format
= !!(ptag
& OPS_PTAG_NEW_FORMAT
);
7587 if (pkt
.u
.ptag
.new_format
) {
7588 pkt
.u
.ptag
.type
= ptag
& OPS_PTAG_NF_CONTENT_TAG_MASK
;
7589 pkt
.u
.ptag
.lentype
= 0;
7590 if (!read_new_length(&pkt
.u
.ptag
.length
, stream
)) {
7597 pkt
.u
.ptag
.type
= ((unsigned)ptag
&
7598 OPS_PTAG_OF_CONTENT_TAG_MASK
)
7599 >> OPS_PTAG_OF_CONTENT_TAG_SHIFT
;
7600 pkt
.u
.ptag
.lentype
= ptag
& OPS_PTAG_OF_LENGTH_TYPE_MASK
;
7601 switch (pkt
.u
.ptag
.lentype
) {
7602 case OPS_PTAG_OLD_LEN_1
:
7603 rb
= read_scalar(&pkt
.u
.ptag
.length
, 1, stream
);
7606 case OPS_PTAG_OLD_LEN_2
:
7607 rb
= read_scalar(&pkt
.u
.ptag
.length
, 2, stream
);
7610 case OPS_PTAG_OLD_LEN_4
:
7611 rb
= read_scalar(&pkt
.u
.ptag
.length
, 4, stream
);
7614 case OPS_PTAG_OLD_LEN_INDETERMINATE
:
7615 pkt
.u
.ptag
.length
= 0;
7625 CALLBACK(OPS_PARSER_PTAG
, &stream
->cbdata
, &pkt
);
7627 __ops_init_subregion(®ion
, NULL
);
7628 region
.length
= pkt
.u
.ptag
.length
;
7629 region
.indeterm
= indeterm
;
7630 switch (pkt
.u
.ptag
.type
) {
7631 case OPS_PTAG_CT_SIGNATURE
:
7632 ret
= parse_sig(®ion
, stream
);
7635 case OPS_PTAG_CT_PUBLIC_KEY
:
7636 case OPS_PTAG_CT_PUBLIC_SUBKEY
:
7637 ret
= parse_pubkey(pkt
.u
.ptag
.type
, ®ion
, stream
);
7640 case OPS_PTAG_CT_TRUST
:
7641 ret
= parse_trust(®ion
, stream
);
7644 case OPS_PTAG_CT_USER_ID
:
7645 ret
= parse_userid(®ion
, stream
);
7648 case OPS_PTAG_CT_COMPRESSED
:
7649 ret
= parse_compressed(®ion
, stream
);
7652 case OPS_PTAG_CT_1_PASS_SIG
:
7653 ret
= parse_one_pass(®ion
, stream
);
7656 case OPS_PTAG_CT_LITDATA
:
7657 ret
= parse_litdata(®ion
, stream
);
7660 case OPS_PTAG_CT_USER_ATTR
:
7661 ret
= parse_userattr(®ion
, stream
);
7664 case OPS_PTAG_CT_SECRET_KEY
:
7665 ret
= parse_seckey(®ion
, stream
);
7668 case OPS_PTAG_CT_SECRET_SUBKEY
:
7669 ret
= parse_seckey(®ion
, stream
);
7672 case OPS_PTAG_CT_PK_SESSION_KEY
:
7673 ret
= parse_pk_sesskey(®ion
, stream
);
7676 case OPS_PTAG_CT_SE_DATA
:
7677 ret
= parse_se_data(®ion
, stream
);
7680 case OPS_PTAG_CT_SE_IP_DATA
:
7681 ret
= parse_se_ip_data(®ion
, stream
);
7684 case OPS_PTAG_CT_MDC
:
7685 ret
= parse_mdc(®ion
, stream
);
7689 OPS_ERROR_1(&stream
->errors
, OPS_E_P_UNKNOWN_TAG
,
7690 "Unknown content tag 0x%x",
7695 /* Ensure that the entire packet has been consumed */
7697 if (region
.length
!= region
.readc
&& !region
.indeterm
) {
7698 if (!consume_packet(®ion
, stream
, 0)) {
7703 /* also consume it if there's been an error? */
7704 /* \todo decide what to do about an error on an */
7705 /* indeterminate packet */
7707 if (!consume_packet(®ion
, stream
, 0)) {
7713 *pktlen
= stream
->readinfo
.alength
;
7715 /* do callback on entire packet, if desired and there was no error */
7717 if (ret
> 0 && stream
->readinfo
.accumulate
) {
7718 pkt
.u
.packet
.length
= stream
->readinfo
.alength
;
7719 pkt
.u
.packet
.raw
= stream
->readinfo
.accumulated
;
7720 stream
->readinfo
.accumulated
= NULL
;
7721 stream
->readinfo
.asize
= 0;
7722 CALLBACK(OPS_PARSER_PACKET_END
, &stream
->cbdata
, &pkt
);
7724 stream
->readinfo
.alength
= 0;
7726 return (ret
< 0) ? -1 : (ret
) ? 1 : 0;
7730 * \ingroup Core_ReadPackets
7732 * \brief Parse packets from an input stream until EOF or error.
7734 * \details Setup the necessary parsing configuration in "stream"
7735 * before calling __ops_parse().
7737 * That information includes :
7739 * - a "reader" function to be used to get the data to be parsed
7741 * - a "callback" function to be called when this library has identified
7742 * a parseable object within the data
7744 * - whether the calling function wants the signature subpackets
7745 * returned raw, parsed or not at all.
7747 * After returning, stream->errors holds any errors encountered while parsing.
7749 * \param stream Parsing configuration
7750 * \return 1 on success in all packets, 0 on error in any packet
7752 * \sa CoreAPI Overview
7754 * \sa __ops_print_errors()
7759 __ops_parse(__ops_stream_t
*stream
, int perrors
)
7761 unsigned long pktlen
;
7765 r
= __ops_parse_packet(stream
, &pktlen
);
7768 __ops_print_errors(stream
->errors
);
7770 return (stream
->errors
== NULL
);
7774 /**************************************************************************/
7776 #define CRC24_POLY 0x1864cfbL
7779 * \struct dearmour_t
7790 BEGIN_PGP_PUBLIC_KEY_BLOCK
,
7791 BEGIN_PGP_PRIVATE_KEY_BLOCK
,
7793 BEGIN_PGP_SIGNATURE
,
7796 END_PGP_PUBLIC_KEY_BLOCK
,
7797 END_PGP_PRIVATE_KEY_BLOCK
,
7801 BEGIN_PGP_SIGNED_MESSAGE
7803 __ops_stream_t
*stream
;
7806 unsigned can_runon_data
:1;
7807 /* !< allow headers in armoured data that are
7808 * not separated from the data by a blank line
7810 unsigned no_gap_needed
:1;
7811 /* !< allow no blank line at the start of
7813 unsigned can_trail_ws
:1;
7814 /* !< allow armoured stuff to have trailing
7815 * whitespace where we wouldn't strictly expect
7817 /* it is an error to get a cleartext message without a sig */
7818 unsigned expect_sig
:1;
7824 unsigned long checksum
;
7825 unsigned long read_checksum
;
7826 /* unarmoured text blocks */
7827 uint8_t unarmoured
[NETPGP_BUFSIZ
];
7829 /* pushed back data (stored backwards) */
7832 /* armoured block headers */
7833 __ops_headers_t headers
;
7837 push_back(dearmour_t
*dearmour
, const uint8_t *buf
,
7842 if (dearmour
->pushback
) {
7843 loggit("push_back: already pushed back");
7845 dearmour
->pushback
= __ops_new(length
);
7846 for (n
= 0; n
< length
; ++n
) {
7847 dearmour
->pushback
[n
] = buf
[length
- n
- 1];
7849 dearmour
->pushbackc
= length
;
7853 /* this struct holds a textual header line */
7854 typedef struct headerline_t
{
7855 const char *s
; /* the header line */
7856 size_t len
; /* its length */
7857 int type
; /* the defined type */
7860 static headerline_t headerlines
[] = {
7861 { "BEGIN PGP MESSAGE", 17, BEGIN_PGP_MESSAGE
},
7862 { "BEGIN PGP PUBLIC KEY BLOCK", 26, BEGIN_PGP_PUBLIC_KEY_BLOCK
},
7863 { "BEGIN PGP PRIVATE KEY BLOCK",27, BEGIN_PGP_PRIVATE_KEY_BLOCK
},
7864 { "BEGIN PGP MESSAGE, PART ", 25, BEGIN_PGP_MULTI
},
7865 { "BEGIN PGP SIGNATURE", 19, BEGIN_PGP_SIGNATURE
},
7867 { "END PGP MESSAGE", 15, END_PGP_MESSAGE
},
7868 { "END PGP PUBLIC KEY BLOCK", 24, END_PGP_PUBLIC_KEY_BLOCK
},
7869 { "END PGP PRIVATE KEY BLOCK", 25, END_PGP_PRIVATE_KEY_BLOCK
},
7870 { "END PGP MESSAGE, PART ", 22, END_PGP_MULTI
},
7871 { "END PGP SIGNATURE", 17, END_PGP_SIGNATURE
},
7873 { "BEGIN PGP SIGNED MESSAGE", 24, BEGIN_PGP_SIGNED_MESSAGE
},
7878 /* search through the table of header lines */
7880 findheaderline(char *headerline
)
7884 for (hp
= headerlines
; hp
->s
; hp
++) {
7885 if (strncmp(headerline
, hp
->s
, hp
->len
) == 0) {
7893 set_lastseen_headerline(dearmour_t
*dearmour
, char *hdr
, __ops_error_t
**errors
)
7898 prev
= dearmour
->lastseen
;
7899 if ((lastseen
= findheaderline(hdr
)) == -1) {
7900 OPS_ERROR_1(errors
, OPS_E_R_BAD_FORMAT
,
7901 "Unrecognised Header Line %s", hdr
);
7904 dearmour
->lastseen
= lastseen
;
7905 switch (dearmour
->lastseen
) {
7907 OPS_ERROR_1(errors
, OPS_E_R_BAD_FORMAT
,
7908 "Unrecognised last seen Header Line %s", hdr
);
7911 case END_PGP_MESSAGE
:
7912 if (prev
!= BEGIN_PGP_MESSAGE
) {
7913 OPS_ERROR(errors
, OPS_E_R_BAD_FORMAT
,
7914 "Got END PGP MESSAGE, but not after BEGIN");
7918 case END_PGP_PUBLIC_KEY_BLOCK
:
7919 if (prev
!= BEGIN_PGP_PUBLIC_KEY_BLOCK
) {
7920 OPS_ERROR(errors
, OPS_E_R_BAD_FORMAT
,
7921 "Got END PGP PUBLIC KEY BLOCK, but not after BEGIN");
7925 case END_PGP_PRIVATE_KEY_BLOCK
:
7926 if (prev
!= BEGIN_PGP_PRIVATE_KEY_BLOCK
) {
7927 OPS_ERROR(errors
, OPS_E_R_BAD_FORMAT
,
7928 "Got END PGP PRIVATE KEY BLOCK, but not after BEGIN");
7932 case BEGIN_PGP_MULTI
:
7934 OPS_ERROR(errors
, OPS_E_R_UNSUPPORTED
,
7935 "Multi-part messages are not yet supported");
7938 case END_PGP_SIGNATURE
:
7939 if (prev
!= BEGIN_PGP_SIGNATURE
) {
7940 OPS_ERROR(errors
, OPS_E_R_BAD_FORMAT
,
7941 "Got END PGP SIGNATURE, but not after BEGIN");
7945 case BEGIN_PGP_MESSAGE
:
7946 case BEGIN_PGP_PUBLIC_KEY_BLOCK
:
7947 case BEGIN_PGP_PRIVATE_KEY_BLOCK
:
7948 case BEGIN_PGP_SIGNATURE
:
7949 case BEGIN_PGP_SIGNED_MESSAGE
:
7956 read_char(dearmour_t
*dearmour
,
7957 __ops_error_t
**errors
,
7958 __ops_reader_t
*readinfo
,
7959 __ops_cbdata_t
*cbdata
,
7965 if (dearmour
->pushbackc
) {
7966 c
= dearmour
->pushback
[--dearmour
->pushbackc
];
7967 if (dearmour
->pushbackc
== 0) {
7968 (void) free(dearmour
->pushback
);
7969 dearmour
->pushback
= NULL
;
7971 } else if (__ops_stacked_read(&c
, 1, errors
, readinfo
,
7975 } while (skip
&& c
== '\r');
7976 dearmour
->prev_nl
= dearmour
->seen_nl
;
7977 dearmour
->seen_nl
= (c
== '\n');
7982 eat_whitespace(int first
,
7983 dearmour_t
*dearmour
,
7984 __ops_error_t
**errors
,
7985 __ops_reader_t
*readinfo
,
7986 __ops_cbdata_t
*cbdata
,
7991 while (c
== ' ' || c
== '\t') {
7992 c
= read_char(dearmour
, errors
, readinfo
, cbdata
, skip
);
7998 read_and_eat_whitespace(dearmour_t
*dearmour
,
7999 __ops_error_t
**errors
,
8000 __ops_reader_t
*readinfo
,
8001 __ops_cbdata_t
*cbdata
,
8007 c
= read_char(dearmour
, errors
, readinfo
, cbdata
, skip
);
8008 } while (c
== ' ' || c
== '\t');
8013 flush(dearmour_t
*dearmour
, __ops_cbdata_t
*cbdata
)
8015 __ops_packet_t content
;
8017 if (dearmour
->unarmoredc
> 0) {
8018 content
.u
.unarmoured_text
.data
= dearmour
->unarmoured
;
8019 content
.u
.unarmoured_text
.length
= dearmour
->unarmoredc
;
8020 CALLBACK(OPS_PTAG_CT_UNARMOURED_TEXT
, cbdata
, &content
);
8021 dearmour
->unarmoredc
= 0;
8026 unarmoured_read_char(dearmour_t
*dearmour
,
8027 __ops_error_t
**errors
,
8028 __ops_reader_t
*readinfo
,
8029 __ops_cbdata_t
*cbdata
,
8035 c
= read_char(dearmour
, errors
, readinfo
, cbdata
, 0);
8039 dearmour
->unarmoured
[dearmour
->unarmoredc
++] = c
;
8040 if (dearmour
->unarmoredc
== sizeof(dearmour
->unarmoured
)) {
8041 flush(dearmour
, cbdata
);
8043 } while (skip
&& c
== '\r');
8051 * \return header value if found, otherwise NULL
8054 __ops_find_header(__ops_headers_t
*headers
, const char *key
)
8058 for (n
= 0; n
< headers
->headerc
; ++n
) {
8059 if (strcmp(headers
->headers
[n
].key
, key
) == 0) {
8060 return headers
->headers
[n
].value
;
8071 __ops_dup_headers(__ops_headers_t
*dest
, const __ops_headers_t
*src
)
8075 dest
->headers
= __ops_new(src
->headerc
* sizeof(*dest
->headers
));
8076 dest
->headerc
= src
->headerc
;
8077 for (n
= 0; n
< src
->headerc
; ++n
) {
8078 dest
->headers
[n
].key
= strdup(src
->headers
[n
].key
);
8079 dest
->headers
[n
].value
= strdup(src
->headers
[n
].value
);
8084 * Note that this skips CRs so implementations always see just straight LFs
8085 * as line terminators
8088 process_dash_escaped(dearmour_t
*dearmour
,
8089 __ops_error_t
**errors
,
8090 __ops_reader_t
*readinfo
,
8091 __ops_cbdata_t
*cbdata
)
8093 __ops_packet_t content
;
8094 __ops_packet_t content2
;
8095 __ops_cleartext_body_t
*body
= &content
.u
.cleartext_body
;
8096 __ops_cleartext_trailer_t
*trailer
= &content2
.u
.cleartext_trailer
;
8097 const char *hashstr
;
8101 hash
= __ops_new(sizeof(*hash
));
8102 hashstr
= __ops_find_header(&dearmour
->headers
, "Hash");
8104 __ops_hash_alg_t alg
;
8106 alg
= __ops_str_to_hash_alg(hashstr
);
8107 if (!__ops_is_hash_alg_supported(&alg
)) {
8109 OPS_ERROR_1(errors
, OPS_E_R_BAD_FORMAT
,
8110 "Unsupported hash algorithm '%s'", hashstr
);
8113 if (alg
== OPS_HASH_UNKNOWN
) {
8115 OPS_ERROR_1(errors
, OPS_E_R_BAD_FORMAT
,
8116 "Unknown hash algorithm '%s'", hashstr
);
8119 __ops_hash_any(hash
, alg
);
8121 __ops_hash_md5(hash
);
8132 c
= read_char(dearmour
, errors
, readinfo
, cbdata
, 1);
8136 if (dearmour
->prev_nl
&& c
== '-') {
8137 if ((c
= read_char(dearmour
, errors
, readinfo
, cbdata
,
8142 /* then this had better be a trailer! */
8144 OPS_ERROR(errors
, OPS_E_R_BAD_FORMAT
,
8145 "Bad dash-escaping");
8147 for (count
= 2; count
< 5; ++count
) {
8148 if ((c
= read_char(dearmour
, errors
,
8149 readinfo
, cbdata
, 0)) < 0) {
8155 "Bad dash-escaping (2)");
8158 dearmour
->state
= AT_TRAILER_NAME
;
8161 /* otherwise we read the next character */
8162 if ((c
= read_char(dearmour
, errors
, readinfo
, cbdata
,
8167 if (c
== '\n' && body
->length
) {
8168 if (memchr(body
->data
+ 1, '\n', body
->length
- 1)
8170 loggit("process_dash_escaped: newline found");
8173 if (body
->data
[0] == '\n') {
8174 hash
->add(hash
, (const uint8_t *)"\r", 1);
8176 hash
->add(hash
, body
->data
, body
->length
);
8177 CALLBACK(OPS_PTAG_CT_SIGNED_CLEARTEXT_BODY
, cbdata
,
8181 body
->data
[body
->length
++] = c
;
8183 if (body
->length
== sizeof(body
->data
)) {
8184 CALLBACK(OPS_PTAG_CT_SIGNED_CLEARTEXT_BODY
, cbdata
,
8189 if (body
->data
[0] != '\n') {
8190 loggit("process_dash_escaped: no newline in body data");
8193 if (body
->length
!= 1) {
8194 loggit("process_dash_escaped: bad body length");
8198 /* don't send that one character, because it's part of the trailer */
8199 trailer
->hash
= hash
;
8200 CALLBACK(OPS_PTAG_CT_SIGNED_CLEARTEXT_TRAILER
, cbdata
, &content2
);
8205 add_header(dearmour_t
*dearmour
, const char *key
, const char *value
)
8210 * Check that the header is valid
8212 if (strcmp(key
, "Version") == 0 ||
8213 strcmp(key
, "Comment") == 0 ||
8214 strcmp(key
, "MessageID") == 0 ||
8215 strcmp(key
, "Hash") == 0 ||
8216 strcmp(key
, "Charset") == 0) {
8217 n
= dearmour
->headers
.headerc
;
8218 dearmour
->headers
.headers
= realloc(dearmour
->headers
.headers
,
8219 (n
+ 1) * sizeof(*dearmour
->headers
.headers
));
8220 dearmour
->headers
.headers
[n
].key
= strdup(key
);
8221 dearmour
->headers
.headers
[n
].value
= strdup(value
);
8222 dearmour
->headers
.headerc
= n
+ 1;
8228 /* \todo what does a return value of 0 indicate? 1 is good, -1 is bad */
8230 parse_headers(dearmour_t
*dearmour
, __ops_error_t
**errors
,
8231 __ops_reader_t
* readinfo
, __ops_cbdata_t
* cbdata
)
8245 c
= read_char(dearmour
, errors
, readinfo
, cbdata
, 1);
8247 OPS_ERROR(errors
, OPS_E_R_BAD_FORMAT
, "Unexpected EOF");
8258 loggit("parse_headers: bad size");
8262 if ((s
= strchr(buf
, ':')) == NULL
) {
8263 if (!first
&& !dearmour
->can_runon_data
) {
8265 * then we have seriously malformed
8268 OPS_ERROR(errors
, OPS_E_R_BAD_FORMAT
,
8269 "No colon in armour header");
8274 !(dearmour
->can_runon_data
||
8275 dearmour
->no_gap_needed
)) {
8278 "No colon in armour header (2)");
8280 * then we have a nasty
8281 * armoured block with no
8282 * headers, not even a blank
8296 OPS_ERROR(errors
, OPS_E_R_BAD_FORMAT
,
8297 "No space in armour header");
8301 if (!add_header(dearmour
, buf
, s
+ 2)) {
8302 OPS_ERROR_1(errors
, OPS_E_R_BAD_FORMAT
,
8303 "Invalid header %s", buf
);
8311 if (size
<= nbuf
+ 1) {
8313 buf
= realloc(buf
, size
);
8323 read4(dearmour_t
*dearmour
, __ops_error_t
**errors
,
8324 __ops_reader_t
*readinfo
, __ops_cbdata_t
*cbdata
,
8325 int *pc
, unsigned *pn
, unsigned long *pl
)
8328 unsigned long l
= 0;
8330 for (n
= 0; n
< 4; ++n
) {
8331 c
= read_char(dearmour
, errors
, readinfo
, cbdata
, 1);
8333 dearmour
->eof64
= 1;
8336 if (c
== '-' || c
== '=') {
8340 if (c
>= 'A' && c
<= 'Z') {
8342 } else if (c
>= 'a' && c
<= 'z') {
8344 } else if (c
>= '0' && c
<= '9') {
8346 } else if (c
== '+') {
8348 } else if (c
== '/') {
8364 __ops_crc24(unsigned checksum
, uint8_t c
)
8368 checksum
^= c
<< 16;
8369 for (i
= 0; i
< 8; i
++) {
8371 if (checksum
& 0x1000000)
8372 checksum
^= CRC24_POLY
;
8374 return checksum
& 0xffffffL
;
8378 decode64(dearmour_t
*dearmour
, __ops_error_t
**errors
,
8379 __ops_reader_t
*readinfo
, __ops_cbdata_t
*cbdata
)
8387 if (dearmour
->buffered
) {
8388 loggit("decode64: bad dearmour->buffered");
8392 ret
= read4(dearmour
, errors
, readinfo
, cbdata
, &c
, &n
, &l
);
8394 OPS_ERROR(errors
, OPS_E_R_BAD_FORMAT
, "Badly formed base64");
8399 OPS_ERROR(errors
, OPS_E_R_BAD_FORMAT
,
8400 "Badly terminated base64 (2)");
8403 dearmour
->buffered
= 2;
8404 dearmour
->eof64
= 1;
8406 } else if (n
== 2) {
8408 OPS_ERROR(errors
, OPS_E_R_BAD_FORMAT
,
8409 "Badly terminated base64 (3)");
8412 dearmour
->buffered
= 1;
8413 dearmour
->eof64
= 1;
8415 c
= read_char(dearmour
, errors
, readinfo
, cbdata
, 0);
8417 OPS_ERROR(errors
, OPS_E_R_BAD_FORMAT
,
8418 "Badly terminated base64");
8421 } else if (n
== 0) {
8422 if (!dearmour
->prev_nl
|| c
!= '=') {
8423 OPS_ERROR(errors
, OPS_E_R_BAD_FORMAT
,
8424 "Badly terminated base64 (4)");
8427 dearmour
->buffered
= 0;
8430 loggit("decode64: bad n (!= 4)");
8433 dearmour
->buffered
= 3;
8434 if (c
== '-' || c
== '=') {
8435 loggit("decode64: bad c");
8440 if (dearmour
->buffered
< 3 && dearmour
->buffered
> 0) {
8441 /* then we saw padding */
8443 loggit("decode64: bad c (=)");
8446 c
= read_and_eat_whitespace(dearmour
, errors
, readinfo
, cbdata
,
8449 OPS_ERROR(errors
, OPS_E_R_BAD_FORMAT
,
8450 "No newline at base64 end");
8453 c
= read_char(dearmour
, errors
, readinfo
, cbdata
, 0);
8455 OPS_ERROR(errors
, OPS_E_R_BAD_FORMAT
,
8456 "No checksum at base64 end");
8461 /* now we are at the checksum */
8462 ret
= read4(dearmour
, errors
, readinfo
, cbdata
, &c
, &n
,
8463 &dearmour
->read_checksum
);
8464 if (ret
< 0 || n
!= 4) {
8465 OPS_ERROR(errors
, OPS_E_R_BAD_FORMAT
,
8466 "Error in checksum");
8469 c
= read_char(dearmour
, errors
, readinfo
, cbdata
, 1);
8470 if (dearmour
->can_trail_ws
)
8471 c
= eat_whitespace(c
, dearmour
, errors
, readinfo
, cbdata
,
8474 OPS_ERROR(errors
, OPS_E_R_BAD_FORMAT
,
8475 "Badly terminated checksum");
8478 c
= read_char(dearmour
, errors
, readinfo
, cbdata
, 0);
8480 OPS_ERROR(errors
, OPS_E_R_BAD_FORMAT
,
8481 "Bad base64 trailer (2)");
8486 for (n
= 0; n
< 4; ++n
)
8487 if (read_char(dearmour
, errors
, readinfo
, cbdata
,
8489 OPS_ERROR(errors
, OPS_E_R_BAD_FORMAT
,
8490 "Bad base64 trailer");
8493 dearmour
->eof64
= 1;
8495 if (!dearmour
->buffered
) {
8496 loggit("decode64: not buffered");
8501 for (n
= 0; n
< dearmour
->buffered
; ++n
) {
8502 dearmour
->buffer
[n
] = (uint8_t)l
;
8506 for (n2
= dearmour
->buffered
- 1; n2
>= 0; --n2
)
8507 dearmour
->checksum
= __ops_crc24((unsigned)dearmour
->checksum
,
8508 dearmour
->buffer
[n2
]);
8510 if (dearmour
->eof64
&& dearmour
->read_checksum
!= dearmour
->checksum
) {
8511 OPS_ERROR(errors
, OPS_E_R_BAD_FORMAT
, "Checksum mismatch");
8518 base64(dearmour_t
*dearmour
)
8520 dearmour
->state
= BASE64
;
8521 dearmour
->checksum
= CRC24_INIT
;
8522 dearmour
->eof64
= 0;
8523 dearmour
->buffered
= 0;
8526 /* This reader is rather strange in that it can generate callbacks for */
8527 /* content - this is because plaintext is not encapsulated in PGP */
8528 /* packets... it also calls back for the text between the blocks. */
8531 armoured_data_reader(void *dest_
, size_t length
, __ops_error_t
**errors
,
8532 __ops_reader_t
*readinfo
,
8533 __ops_cbdata_t
*cbdata
)
8535 dearmour_t
*dearmour
= readinfo
->arg
;
8536 __ops_packet_t content
;
8539 uint8_t *dest
= dest_
;
8542 if (dearmour
->eof64
&& !dearmour
->buffered
) {
8543 if (dearmour
->state
!= OUTSIDE_BLOCK
&&
8544 dearmour
->state
!= AT_TRAILER_NAME
) {
8545 loggit("armoured_data_reader: bad dearmour state");
8550 while (length
> 0) {
8556 flush(dearmour
, cbdata
);
8557 switch (dearmour
->state
) {
8560 * This code returns EOF rather than EARLY_EOF
8561 * because if we don't see a header line at all, then
8562 * it is just an EOF (and not a BLOCK_END)
8564 while (!dearmour
->seen_nl
) {
8565 if ((c
= unarmoured_read_char(dearmour
, errors
,
8566 readinfo
, cbdata
, 1)) < 0) {
8572 * flush at this point so we definitely have room for
8573 * the header, and so we can easily erase it from the
8576 flush(dearmour
, cbdata
);
8577 /* Find and consume the 5 leading '-' */
8578 for (count
= 0; count
< 5; ++count
) {
8579 if ((c
= unarmoured_read_char(dearmour
, errors
,
8580 readinfo
, cbdata
, 0)) < 0) {
8588 /* Now find the block type */
8589 for (n
= 0; n
< sizeof(buf
) - 1;) {
8590 if ((c
= unarmoured_read_char(dearmour
, errors
,
8591 readinfo
, cbdata
, 0)) < 0) {
8599 /* then I guess this wasn't a proper header */
8605 /* Consume trailing '-' */
8606 for (count
= 1; count
< 5; ++count
) {
8607 if ((c
= unarmoured_read_char(dearmour
, errors
,
8608 readinfo
, cbdata
, 0)) < 0) {
8612 /* wasn't a header after all */
8617 /* Consume final NL */
8618 if ((c
= unarmoured_read_char(dearmour
, errors
, readinfo
,
8622 if (dearmour
->can_trail_ws
) {
8623 if ((c
= eat_whitespace(c
, dearmour
, errors
,
8624 readinfo
, cbdata
, 1)) < 0) {
8629 /* wasn't a header line after all */
8634 * Now we've seen the header, scrub it from the
8637 dearmour
->unarmoredc
= 0;
8640 * But now we've seen a header line, then errors are
8643 if ((ret
= parse_headers(dearmour
, errors
, readinfo
,
8648 if (!set_lastseen_headerline(dearmour
, buf
, errors
)) {
8652 if (strcmp(buf
, "BEGIN PGP SIGNED MESSAGE") == 0) {
8654 &content
.u
.cleartext_head
.headers
,
8655 &dearmour
->headers
);
8656 CALLBACK(OPS_PTAG_CT_SIGNED_CLEARTEXT_HEADER
,
8659 ret
= process_dash_escaped(dearmour
, errors
,
8665 content
.u
.armour_header
.type
= buf
;
8666 content
.u
.armour_header
.headers
=
8668 (void) memset(&dearmour
->headers
, 0x0,
8669 sizeof(dearmour
->headers
));
8670 CALLBACK(OPS_PTAG_CT_ARMOUR_HEADER
, cbdata
,
8678 while (length
> 0) {
8679 if (!dearmour
->buffered
) {
8680 if (!dearmour
->eof64
) {
8681 ret
= decode64(dearmour
,
8682 errors
, readinfo
, cbdata
);
8687 if (!dearmour
->buffered
) {
8688 if (!dearmour
->eof64
) {
8690 "armoured_data_reader: bad dearmour eof64");
8701 if (!dearmour
->buffered
) {
8703 "armoured_data_reader: bad dearmour buffered");
8706 *dest
= dearmour
->buffer
[--dearmour
->buffered
];
8711 if (dearmour
->eof64
&& !dearmour
->buffered
) {
8712 dearmour
->state
= AT_TRAILER_NAME
;
8716 case AT_TRAILER_NAME
:
8717 for (n
= 0; n
< sizeof(buf
) - 1;) {
8718 if ((c
= read_char(dearmour
, errors
, readinfo
,
8727 /* then I guess this wasn't a proper trailer */
8728 OPS_ERROR(errors
, OPS_E_R_BAD_FORMAT
,
8729 "Bad ASCII armour trailer");
8735 if (!set_lastseen_headerline(dearmour
, buf
, errors
)) {
8739 /* Consume trailing '-' */
8740 for (count
= 1; count
< 5; ++count
) {
8741 if ((c
= read_char(dearmour
, errors
, readinfo
,
8746 /* wasn't a trailer after all */
8747 OPS_ERROR(errors
, OPS_E_R_BAD_FORMAT
,
8748 "Bad ASCII armour trailer (2)");
8752 /* Consume final NL */
8753 if ((c
= read_char(dearmour
, errors
, readinfo
, cbdata
,
8757 if (dearmour
->can_trail_ws
) {
8758 if ((c
= eat_whitespace(c
, dearmour
, errors
,
8759 readinfo
, cbdata
, 1)) < 0) {
8764 /* wasn't a trailer line after all */
8765 OPS_ERROR(errors
, OPS_E_R_BAD_FORMAT
,
8766 "Bad ASCII armour trailer (3)");
8769 if (strncmp(buf
, "BEGIN ", 6) == 0) {
8770 if (!set_lastseen_headerline(dearmour
, buf
,
8774 if ((ret
= parse_headers(dearmour
, errors
,
8775 readinfo
, cbdata
)) <= 0) {
8778 content
.u
.armour_header
.type
= buf
;
8779 content
.u
.armour_header
.headers
=
8781 (void) memset(&dearmour
->headers
, 0x0,
8782 sizeof(dearmour
->headers
));
8783 CALLBACK(OPS_PTAG_CT_ARMOUR_HEADER
, cbdata
,
8787 content
.u
.armour_trailer
.type
= buf
;
8788 CALLBACK(OPS_PTAG_CT_ARMOUR_TRAILER
, cbdata
,
8790 dearmour
->state
= OUTSIDE_BLOCK
;
8802 armoured_data_destroyer(__ops_reader_t
*readinfo
)
8804 (void) free(readinfo
->arg
);
8808 * \ingroup Core_Readers_Armour
8809 * \brief Pushes dearmouring reader onto stack
8810 * \param stream Usual structure containing information about to how to do the parse
8811 * \sa __ops_reader_pop_dearmour()
8814 __ops_reader_push_dearmour(__ops_stream_t
*stream
)
8816 * This function originally had these params to cater for packets which
8817 * didn't strictly match the RFC. The initial 0.5 release is only going to
8818 * support strict checking. If it becomes desirable to support loose checking
8819 * of armoured packets and these params are reinstated, parse_headers() must
8820 * be fixed so that these flags work correctly.
8822 * // Allow headers in armoured data that are not separated from the data by a
8823 * blank line unsigned without_gap,
8825 * // Allow no blank line at the start of armoured data unsigned no_gap,
8827 * //Allow armoured data to have trailing whitespace where we strictly would not
8828 * expect it unsigned trailing_whitespace
8831 dearmour_t
*dearmour
;
8833 dearmour
= __ops_new(sizeof(*dearmour
));
8834 dearmour
->seen_nl
= 1;
8836 dearmour->can_runon_data=without_gap;
8837 dearmour->no_gap_needed=no_gap;
8838 dearmour->can_trail_ws=trailing_whitespace;
8840 dearmour
->expect_sig
= 0;
8841 dearmour
->got_sig
= 0;
8843 __ops_reader_push(stream
, armoured_data_reader
,
8844 armoured_data_destroyer
, dearmour
);
8848 * \ingroup Core_Readers_Armour
8849 * \brief Pops dearmour reader from stock
8851 * \sa __ops_reader_push_dearmour()
8854 __ops_reader_pop_dearmour(__ops_stream_t
*stream
)
8856 dearmour_t
*dearmour
;
8858 dearmour
= stream
->readinfo
.arg
;
8859 (void) free(dearmour
);
8860 __ops_reader_pop(stream
);
8863 /**************************************************************************/
8865 /* this is actually used for *decrypting* */
8867 uint8_t v
[1024 * 15];
8870 __ops_crypt_t
*decrypt
;
8871 __ops_region_t
*region
;
8872 unsigned prevplain
:1;
8876 encrypted_reader(void *dest
,
8878 __ops_error_t
**errors
,
8879 __ops_reader_t
*readinfo
,
8880 __ops_cbdata_t
*cbdata
)
8886 enc
= readinfo
->arg
;
8889 * V3 MPIs have the count plain and the cipher is reset after each
8892 if (enc
->prevplain
&& !readinfo
->parent
->reading_mpi_len
) {
8893 if (!readinfo
->parent
->reading_v3_secret
) {
8894 loggit("encrypted_reader: bad v3 secret");
8897 enc
->decrypt
->decrypt_resync(enc
->decrypt
);
8899 } else if (readinfo
->parent
->reading_v3_secret
&&
8900 readinfo
->parent
->reading_mpi_len
) {
8903 while (length
> 0) {
8908 * if we are reading v3 we should never read
8909 * more than we're asked for */
8910 if (length
< enc
->c
&&
8911 (readinfo
->parent
->reading_v3_secret
||
8912 readinfo
->parent
->exact_read
)) {
8913 loggit("encrypted_reader: bad v3 read");
8916 n
= MIN(length
, enc
->c
);
8917 (void) memcpy(dest
, enc
->v
+ enc
->off
, n
);
8925 unsigned n
= enc
->region
->length
;
8931 if (!enc
->region
->indeterm
) {
8932 n
-= enc
->region
->readc
;
8934 return saved
- length
;
8936 if (n
> sizeof(buf
)) {
8944 * we can only read as much as we're asked for
8945 * in v3 keys because they're partially
8947 if ((readinfo
->parent
->reading_v3_secret
||
8948 readinfo
->parent
->exact_read
) && n
> length
) {
8952 if (!__ops_stacked_limited_read(buf
, n
,
8953 enc
->region
, errors
, readinfo
, cbdata
)) {
8956 if (!readinfo
->parent
->reading_v3_secret
||
8957 !readinfo
->parent
->reading_mpi_len
) {
8958 enc
->c
= __ops_decrypt_se_ip(enc
->decrypt
,
8962 (void) memcpy(&enc
->v
[enc
->off
], buf
, n
);
8967 loggit("encrypted_reader: 0 decrypted count");
8979 nuke_encrypted(__ops_reader_t
*readinfo
)
8981 (void) free(readinfo
->arg
);
8985 * \ingroup Core_Readers_SE
8986 * \brief Pushes decryption reader onto stack
8987 * \sa __ops_reader_pop_decrypt()
8990 __ops_reader_push_decrypt(__ops_stream_t
*stream
, __ops_crypt_t
*decrypt
,
8991 __ops_region_t
*region
)
8995 enc
= __ops_new(sizeof(*enc
));
8996 enc
->decrypt
= decrypt
;
8997 enc
->region
= region
;
8998 __ops_decrypt_init(enc
->decrypt
);
8999 __ops_reader_push(stream
, encrypted_reader
, nuke_encrypted
, enc
);
9003 * \ingroup Core_Readers_Encrypted
9004 * \brief Pops decryption reader from stack
9005 * \sa __ops_reader_push_decrypt()
9008 __ops_reader_pop_decrypt(__ops_stream_t
*stream
)
9012 enc
= stream
->readinfo
.arg
;
9013 enc
->decrypt
->decrypt_finish(enc
->decrypt
);
9015 __ops_reader_pop(stream
);
9018 /**************************************************************************/
9021 /* boolean: 0 once we've done the preamble/MDC checks */
9022 /* and are reading from the plaintext */
9025 size_t plaintext_available
;
9026 size_t plaintext_offset
;
9027 __ops_region_t
*region
;
9028 __ops_crypt_t
*decrypt
;
9032 Gets entire SE_IP data packet.
9033 Verifies leading preamble
9034 Verifies trailing MDC packet
9035 Then passes up plaintext as requested
9038 se_ip_data_reader(void *dest_
,
9040 __ops_error_t
**errors
,
9041 __ops_reader_t
*readinfo
,
9042 __ops_cbdata_t
*cbdata
)
9044 decrypt_se_ip_t
*se_ip
;
9045 __ops_region_t decrypted_region
;
9048 se_ip
= readinfo
->arg
;
9049 if (!se_ip
->passed_checks
) {
9050 uint8_t *buf
= NULL
;
9052 uint8_t hashed
[OPS_SHA1_HASH_SIZE
];
9057 size_t sz_plaintext
;
9063 __ops_hash_any(&hash
, OPS_HASH_SHA1
);
9066 __ops_init_subregion(&decrypted_region
, NULL
);
9067 decrypted_region
.length
=
9068 se_ip
->region
->length
- se_ip
->region
->readc
;
9069 buf
= __ops_new(decrypted_region
.length
);
9071 /* read entire SE IP packet */
9072 if (!__ops_stacked_limited_read(buf
, decrypted_region
.length
,
9073 &decrypted_region
, errors
, readinfo
, cbdata
)) {
9077 /* verify leading preamble */
9079 b
= se_ip
->decrypt
->blocksize
;
9080 if (buf
[b
- 2] != buf
[b
] || buf
[b
- 1] != buf
[b
+ 1]) {
9082 "Bad symmetric decrypt (%02x%02x vs %02x%02x)",
9083 buf
[b
- 2], buf
[b
- 1], buf
[b
], buf
[b
+ 1]);
9084 OPS_ERROR(errors
, OPS_E_PROTO_BAD_SYMMETRIC_DECRYPT
,
9085 "Bad symmetric decrypt when parsing SE IP packet");
9089 /* Verify trailing MDC hash */
9091 sz_preamble
= se_ip
->decrypt
->blocksize
+ 2;
9092 sz_mdc_hash
= OPS_SHA1_HASH_SIZE
;
9093 sz_mdc
= 1 + 1 + sz_mdc_hash
;
9094 sz_plaintext
= decrypted_region
.length
- sz_preamble
- sz_mdc
;
9097 plaintext
= buf
+ sz_preamble
;
9098 mdc
= plaintext
+ sz_plaintext
;
9101 __ops_calc_mdc_hash(preamble
, sz_preamble
, plaintext
,
9102 sz_plaintext
, hashed
);
9104 if (memcmp(mdc_hash
, hashed
, OPS_SHA1_HASH_SIZE
) != 0) {
9105 OPS_ERROR(errors
, OPS_E_V_BAD_HASH
,
9106 "Bad hash in MDC packet");
9110 /* all done with the checks */
9111 /* now can start reading from the plaintext */
9112 if (se_ip
->plaintext
) {
9113 loggit("se_ip_data_reader: bad plaintext");
9116 se_ip
->plaintext
= __ops_new(sz_plaintext
);
9117 memcpy(se_ip
->plaintext
, plaintext
, sz_plaintext
);
9118 se_ip
->plaintext_available
= sz_plaintext
;
9120 se_ip
->passed_checks
= 1;
9125 if (n
> se_ip
->plaintext_available
) {
9126 n
= se_ip
->plaintext_available
;
9129 memcpy(dest_
, se_ip
->plaintext
+ se_ip
->plaintext_offset
, n
);
9130 se_ip
->plaintext_available
-= n
;
9131 se_ip
->plaintext_offset
+= n
;
9138 se_ip_data_destroyer(__ops_reader_t
*readinfo
)
9140 decrypt_se_ip_t
*se_ip
;
9142 se_ip
= readinfo
->arg
;
9143 (void) free(se_ip
->plaintext
);
9148 \ingroup Internal_Readers_SEIP
9151 __ops_reader_push_se_ip_data(__ops_stream_t
*stream
, __ops_crypt_t
*decrypt
,
9152 __ops_region_t
* region
)
9154 decrypt_se_ip_t
*se_ip
= __ops_new(sizeof(*se_ip
));
9156 se_ip
->region
= region
;
9157 se_ip
->decrypt
= decrypt
;
9158 __ops_reader_push(stream
, se_ip_data_reader
, se_ip_data_destroyer
,
9163 \ingroup Internal_Readers_SEIP
9166 __ops_reader_pop_se_ip_data(__ops_stream_t
*stream
)
9168 decrypt_se_ip_t
*se_ip
;
9170 se_ip
= stream
->readinfo
.arg
;
9172 __ops_reader_pop(stream
);
9175 /**************************************************************************/
9177 /** Arguments for reader_fd
9179 typedef struct mmap_reader_t
{
9180 void *mem
; /* memory mapped file */
9181 uint64_t size
; /* size of file */
9182 uint64_t offset
; /* current offset in file */
9183 int fd
; /* file descriptor */
9188 * \ingroup Core_Readers
9190 * __ops_reader_fd() attempts to read up to "plength" bytes from the file
9191 * descriptor in "stream" into the buffer starting at "dest" using the
9192 * rules contained in "flags"
9194 * \param dest Pointer to previously allocated buffer
9195 * \param plength Number of bytes to try to read
9196 * \param flags Rules about reading to use
9197 * \param readinfo Reader info
9198 * \param cbdata Callback info
9200 * \return n Number of bytes read
9202 * OPS_R_EARLY_EOF and OPS_R_ERROR push errors on the stack
9205 fd_reader(void *dest
, size_t length
, __ops_error_t
**errors
,
9206 __ops_reader_t
*readinfo
, __ops_cbdata_t
*cbdata
)
9208 mmap_reader_t
*reader
;
9212 reader
= readinfo
->arg
;
9213 if ((n
= read(reader
->fd
, dest
, length
)) == 0) {
9217 OPS_SYSTEM_ERROR_1(errors
, OPS_E_R_READ_FAILED
, "read",
9218 "file descriptor %d", reader
->fd
);
9225 reader_fd_destroyer(__ops_reader_t
*readinfo
)
9227 (void) free(readinfo
->arg
);
9230 /**************************************************************************/
9233 const uint8_t *buffer
;
9239 mem_reader(void *dest
, size_t length
, __ops_error_t
**errors
,
9240 __ops_reader_t
*readinfo
, __ops_cbdata_t
*cbdata
)
9242 reader_mem_t
*reader
= readinfo
->arg
;
9248 if (reader
->offset
+ length
> reader
->length
) {
9249 n
= reader
->length
- reader
->offset
;
9256 (void) memcpy(dest
, reader
->buffer
+ reader
->offset
, n
);
9257 reader
->offset
+= n
;
9262 mem_destroyer(__ops_reader_t
*readinfo
)
9264 (void) free(readinfo
->arg
);
9268 \ingroup Core_Readers_First
9269 \brief Starts stack with memory reader
9273 __ops_reader_set_memory(__ops_stream_t
*stream
, const void *buffer
,
9276 reader_mem_t
*mem
= __ops_new(sizeof(*mem
));
9278 mem
->buffer
= buffer
;
9279 mem
->length
= length
;
9281 __ops_reader_set(stream
, mem_reader
, mem_destroyer
, mem
);
9286 /* File manipulation here */
9288 /**************************************************************************/
9292 \ingroup Core_Readers
9293 \brief Create stream and sets to read from memory
9294 \param stream Address where new stream will be set
9295 \param mem Memory to read from
9296 \param arg Reader-specific arg
9297 \param callback Callback to use with reader
9298 \param accumulate Set if we need to accumulate as we read. (Usually 0 unless doing signature verification)
9299 \note It is the caller's responsiblity to free stream
9300 \sa __ops_teardown_memory_read()
9303 __ops_setup_memory_read(__ops_io_t
*io
,
9304 __ops_stream_t
**stream
,
9305 __ops_memory_t
*mem
,
9307 __ops_cb_ret_t
callback(__ops_cbdata_t
*,
9308 const __ops_packet_t
*),
9309 unsigned accumulate
)
9311 *stream
= __ops_new(sizeof(*stream
));
9312 (*stream
)->io
= (*stream
)->cbdata
.io
= io
;
9313 __ops_set_callback(*stream
, callback
, vp
);
9314 __ops_reader_set_memory(*stream
, mem
->buf
, mem
->length
);
9316 (*stream
)->readinfo
.accumulate
= 1;
9321 \ingroup Core_Readers
9322 \brief Frees stream and mem
9325 \sa __ops_setup_memory_read()
9328 __ops_teardown_memory_read(__ops_stream_t
*stream
, __ops_memory_t
*mem
)
9330 __ops_stream_delete(stream
);
9331 __ops_memory_free(mem
);
9334 /* read memory from the previously mmap-ed file */
9336 mmap_reader(void *dest
, size_t length
, __ops_error_t
**errors
,
9337 __ops_reader_t
*readinfo
, __ops_cbdata_t
*cbdata
)
9345 mem
= readinfo
->arg
;
9347 n
= MIN(length
, (unsigned)(mem
->size
- mem
->offset
));
9349 (void) memcpy(dest
, &cmem
[(int)mem
->offset
], (unsigned)n
);
9355 /* tear down the mmap, close the fd */
9357 mmap_destroyer(__ops_reader_t
*readinfo
)
9361 mem
= readinfo
->arg
;
9362 (void) munmap(mem
->mem
, (unsigned)mem
->size
);
9363 (void) close(mem
->fd
);
9367 /* set up the file to use mmap-ed memory if available, file IO otherwise */
9369 __ops_reader_set_mmap(__ops_stream_t
*stream
, int fd
)
9371 mmap_reader_t
*mem
= __ops_new(sizeof(*mem
));
9374 if (fstat(fd
, &st
) == 0) {
9375 mem
->size
= st
.st_size
;
9378 mem
->mem
= mmap(NULL
, (size_t)st
.st_size
, PROT_READ
,
9379 MAP_FILE
| MAP_PRIVATE
, fd
, 0);
9380 if (mem
->mem
== MAP_FAILED
) {
9381 __ops_reader_set(stream
, fd_reader
, reader_fd_destroyer
,
9384 __ops_reader_set(stream
, mmap_reader
, mmap_destroyer
,
9390 /* small function to pretty print an 8-character raw userid */
9392 userid_to_id(const uint8_t *userid
, char *id
)
9394 static const char *hexes
= "0123456789abcdef";
9397 for (i
= 0; i
< 8 ; i
++) {
9398 id
[i
* 2] = hexes
[(unsigned)(userid
[i
] & 0xf0) >> 4];
9399 id
[(i
* 2) + 1] = hexes
[userid
[i
] & 0xf];
9405 static void __ops_print_pubkeydata(__ops_io_t
*, const __ops_key_t
*);
9407 /* print out the successful signature information */
9409 resultp(__ops_io_t
*io
,
9411 __ops_validation_t
*res
,
9412 __ops_keyring_t
*ring
)
9414 const __ops_key_t
*pubkey
;
9416 char id
[MAX_ID_LENGTH
+ 1];
9418 for (i
= 0; i
< res
->validc
; i
++) {
9419 loggit("Good signature for %s made %susing %s key %s",
9421 ctime(&res
->valids
[i
].birthtime
),
9422 findtype((int) res
->valids
[i
].key_alg
, pubkeyalgs
),
9423 userid_to_id(res
->valids
[i
].signer
, id
));
9424 pubkey
= __ops_getkeybyid(ring
,
9425 (const uint8_t *) res
->valids
[i
].signer
);
9426 __ops_print_pubkeydata(io
, pubkey
);
9430 /* static functions */
9433 ptime(FILE *fp
, time_t t
)
9438 printf("%04d-%02d-%02d",
9444 /* return the number of bits in the public key */
9446 numkeybits(const __ops_pubkey_t
*pubkey
)
9448 switch(pubkey
->alg
) {
9450 case OPS_PKA_RSA_ENCRYPT_ONLY
:
9451 case OPS_PKA_RSA_SIGN_ONLY
:
9452 return BN_num_bytes(pubkey
->key
.rsa
.n
) * 8;
9454 switch(BN_num_bytes(pubkey
->key
.dsa
.q
)) {
9464 case OPS_PKA_ELGAMAL
:
9465 return BN_num_bytes(pubkey
->key
.elgamal
.y
) * 8;
9472 hexdump(FILE *fp
, const uint8_t *src
, size_t length
, const char *sep
)
9476 for (i
= 0 ; i
< length
; i
+= 2) {
9477 printf("%02x", *src
++);
9478 printf("%02x%s", *src
++, sep
);
9485 Prints a public key in succinct detail
9487 \param key Ptr to public key
9490 __ops_print_pubkeydata(__ops_io_t
*io
, const __ops_key_t
*key
)
9494 printf("pub %d/%s ",
9495 numkeybits(&key
->key
.pubkey
),
9496 findtype((int) key
->key
.pubkey
.alg
, pubkeyalgs
));
9497 hexdump(io
->errs
, key
->keyid
, OPS_KEY_ID_SIZE
, "");
9499 ptime(io
->errs
, key
->key
.pubkey
.birthtime
);
9500 printf("\nKey fingerprint: ");
9501 hexdump(io
->errs
, key
->fingerprint
.fingerprint
, OPS_FINGERPRINT_SIZE
,
9504 for (i
= 0; i
< key
->uidc
; i
++) {
9506 key
->uids
[i
].userid
);
9515 \ingroup Core_Readers
9516 \brief Creates stream, opens file, and sets to read from file
9517 \param stream Address where new stream will be set
9518 \param filename Name of file to read
9519 \param vp Reader-specific arg
9520 \param callback Callback to use when reading
9521 \param accumulate Set if we need to accumulate as we read. (Usually 0 unless doing signature verification)
9522 \note It is the caller's responsiblity to free stream and to close fd
9523 \sa __ops_teardown_file_read()
9526 __ops_setup_file_read(__ops_io_t
*io
,
9527 __ops_stream_t
**stream
,
9528 const char *filename
,
9530 __ops_cb_ret_t
callback(__ops_cbdata_t
*,
9531 const __ops_packet_t
*),
9532 unsigned accumulate
)
9537 fd
= open(filename
, O_RDONLY
| O_BINARY
);
9539 fd
= open(filename
, O_RDONLY
);
9542 loggit("can't open \"%s\"", filename
);
9545 *stream
= __ops_new(sizeof(*stream
));
9546 (*stream
)->io
= (*stream
)->cbdata
.io
= io
;
9547 __ops_set_callback(*stream
, callback
, vp
);
9548 __ops_reader_set_mmap(*stream
, fd
);
9550 (*stream
)->readinfo
.accumulate
= 1;
9556 \ingroup Core_Readers
9557 \brief Frees stream and closes fd
9560 \sa __ops_setup_file_read()
9563 __ops_teardown_file_read(__ops_stream_t
*stream
, int fd
)
9566 __ops_stream_delete(stream
);
9569 /**************************************************************************/
9571 /* \todo check where pkt pointers are copied */
9572 static __ops_cb_ret_t
9573 cb_keyring_read(__ops_cbdata_t
*cbdata
, const __ops_packet_t
*pkt
)
9578 case OPS_PARSER_PTAG
:
9579 case OPS_PTAG_CT_ENCRYPTED_SECRET_KEY
: /* we get these because we
9581 case OPS_PTAG_CT_SIGNATURE_HEADER
:
9582 case OPS_PTAG_CT_SIGNATURE_FOOTER
:
9583 case OPS_PTAG_CT_SIGNATURE
:
9584 case OPS_PTAG_CT_TRUST
:
9585 case OPS_PARSER_ERRCODE
:
9592 return OPS_RELEASE_MEMORY
;
9596 \ingroup HighLevel_KeyringRead
9598 \brief Reads a keyring from a file
9600 \param keyring Pointer to an existing __ops_keyring_t struct
9601 \param armour 1 if file is armoured; else 0
9602 \param filename Filename of keyring to be read
9604 \return __ops 1 if OK; 0 on error
9606 \note Keyring struct must already exist.
9608 \note Can be used with either a public or secret keyring.
9610 \note You must call __ops_keyring_free() after usage to free alloc-ed memory.
9612 \note If you call this twice on the same keyring struct, without calling
9613 __ops_keyring_free() between these calls, you will introduce a memory leak.
9615 \sa __ops_keyring_read_from_mem()
9616 \sa __ops_keyring_free()
9620 __ops_keyring_fileread(__ops_keyring_t
*keyring
,
9621 const unsigned armour
,
9622 const char *filename
)
9624 __ops_stream_t
*stream
;
9628 stream
= __ops_new(sizeof(*stream
));
9629 /* add this for the moment, */
9631 * \todo need to fix the problems with reading signature subpackets
9634 __ops_stream_options(stream
, OPS_PTAG_SS_ALL
, OPS_PARSE_PARSED
);
9636 fd
= open(filename
, O_RDONLY
| O_BINARY
);
9638 fd
= open(filename
, O_RDONLY
);
9641 __ops_stream_delete(stream
);
9645 __ops_reader_set_mmap(stream
, fd
);
9646 __ops_set_callback(stream
, cb_keyring_read
, NULL
);
9648 __ops_reader_push_dearmour(stream
);
9650 ret
= __ops_parse_and_accumulate(keyring
, stream
);
9651 __ops_print_errors(stream
->errors
);
9653 __ops_reader_pop_dearmour(stream
);
9656 __ops_stream_delete(stream
);
9661 \ingroup HighLevel_KeyringRead
9663 \brief Frees keyring's contents (but not keyring itself)
9665 \param keyring Keyring whose data is to be freed
9667 \note This does not free keyring itself, just the memory alloc-ed in it.
9670 __ops_keyring_free(__ops_keyring_t
*keyring
)
9672 (void)free(keyring
->keys
);
9673 keyring
->keys
= NULL
;
9675 keyring
->keysize
= 0;
9682 /* check there's enough space in the arrays */
9684 size_arrays(netpgp_t
*netpgp
, unsigned needed
)
9686 if (netpgp
->size
== 0) {
9687 /* only get here first time around */
9688 netpgp
->size
= needed
;
9689 netpgp
->name
= __ops_new(sizeof(char *) * needed
);
9690 netpgp
->value
= __ops_new(sizeof(char *) * needed
);
9691 } else if (netpgp
->c
== netpgp
->size
) {
9692 /* only uses 'needed' when filled array */
9693 netpgp
->size
+= needed
;
9694 netpgp
->name
= realloc(netpgp
->name
, sizeof(char *) * needed
);
9695 netpgp
->value
= realloc(netpgp
->value
, sizeof(char *) * needed
);
9699 /* find the name in the array */
9701 findvar(netpgp_t
*netpgp
, const char *name
)
9705 for (i
= 0 ; i
< netpgp
->c
&& strcmp(netpgp
->name
[i
], name
) != 0; i
++) {
9707 return (i
== netpgp
->c
) ? -1 : (int)i
;
9710 /* read a keyring and return it */
9712 readkeyring(netpgp_t
*netpgp
, const char *name
)
9714 __ops_keyring_t
*keyring
;
9715 const unsigned noarmor
= 0;
9720 homedir
= netpgp_getvar(netpgp
, "homedir");
9721 if ((filename
= netpgp_getvar(netpgp
, name
)) == NULL
) {
9722 (void) snprintf(f
, sizeof(f
), "%s/%s.gpg", homedir
, name
);
9725 keyring
= __ops_new(sizeof(*keyring
));
9726 if (!__ops_keyring_fileread(keyring
, noarmor
, filename
)) {
9727 loggit("Can't read %s %s", name
, filename
);
9730 netpgp_setvar(netpgp
, name
, filename
);
9734 /* read any gpg config file */
9736 conffile(netpgp_t
*netpgp
, char *homedir
, char *userid
, size_t length
)
9738 regmatch_t matchv
[10];
9744 (void) snprintf(buf
, sizeof(buf
), "%s/gpg.conf", homedir
);
9745 if ((fp
= fopen(buf
, "r")) == NULL
) {
9746 loggit("conffile: can't open '%s'", buf
);
9749 (void) memset(&keyre
, 0x0, sizeof(keyre
));
9750 (void) regcomp(&keyre
, "^[ \t]*default-key[ \t]+([0-9a-zA-F]+)",
9752 while (fgets(buf
, sizeof(buf
), fp
) != NULL
) {
9753 if (regexec(&keyre
, buf
, 10, matchv
, 0) == 0) {
9754 (void) memcpy(userid
, &buf
[(int)matchv
[1].rm_so
],
9755 MIN((unsigned)(matchv
[1].rm_eo
-
9756 matchv
[1].rm_so
), length
));
9757 loggit("netpgp: default key set to \"%.*s\"",
9758 (int)(matchv
[1].rm_eo
- matchv
[1].rm_so
),
9759 &buf
[(int)matchv
[1].rm_so
]);
9767 \ingroup HighLevel_Verify
9768 \brief Verifies the signatures in a signed file
9769 \param result Where to put the result
9770 \param filename Name of file to be validated
9771 \param armoured Treat file as armoured, if set
9772 \param keyring Keyring to use
9773 \return 1 if signatures validate successfully;
9774 0 if signatures fail or there are no signatures
9775 \note After verification, result holds the details of all keys which
9776 have passed, failed and not been recognised.
9777 \note It is the caller's responsiblity to call
9778 __ops_validate_result_free(result) after use.
9781 __ops_validate_file(__ops_io_t
*io
,
9782 __ops_validation_t
*result
,
9784 const char *outfile
,
9786 const __ops_keyring_t
*keyring
)
9788 validate_data_cb_t validation
;
9789 __ops_stream_t
*parse
= NULL
;
9791 const int printerrors
= 1;
9794 char origfile
[MAXPATHLEN
];
9800 #define SIG_OVERHEAD 284 /* XXX - depends on sig size? */
9802 if (stat(infile
, &st
) < 0) {
9803 loggit("can't validate \"%s\"", infile
);
9806 sigsize
= st
.st_size
;
9808 cc
= snprintf(origfile
, sizeof(origfile
), "%s", infile
);
9809 if (strcmp(&origfile
[cc
- 4], ".sig") == 0) {
9810 origfile
[cc
- 4] = 0x0;
9811 if (stat(origfile
, &st
) == 0 &&
9812 st
.st_size
> sigsize
- SIG_OVERHEAD
) {
9813 detachname
= strdup(origfile
);
9817 (void) memset(&validation
, 0x0, sizeof(validation
));
9819 infd
= __ops_setup_file_read(io
, &parse
, infile
, &validation
,
9820 validate_data_cb
, 1);
9825 validation
.detachname
= detachname
;
9827 /* Set verification reader and handling options */
9828 validation
.result
= result
;
9829 validation
.keyring
= keyring
;
9830 validation
.mem
= __ops_new(sizeof(*validation
.mem
));
9831 __ops_memory_init(validation
.mem
, 128);
9832 /* Note: Coverity incorrectly reports an error that validation.reader */
9833 /* is never used. */
9834 validation
.reader
= parse
->readinfo
.arg
;
9837 __ops_reader_push_dearmour(parse
);
9840 /* Do the verification */
9841 __ops_parse(parse
, !printerrors
);
9845 __ops_reader_pop_dearmour(parse
);
9847 __ops_teardown_file_read(parse
, infd
);
9849 ret
= validate_result_status(result
);
9851 /* this is triggered only for --cat output */
9853 /* need to send validated output somewhere */
9854 if (strcmp(outfile
, "-") == 0) {
9855 outfd
= STDOUT_FILENO
;
9857 outfd
= open(outfile
, O_WRONLY
| O_CREAT
, 0666);
9860 /* even if the signature was good, we can't
9861 * write the file, so send back a bad return
9864 } else if (validate_result_status(result
)) {
9869 len
= validation
.mem
->length
;
9870 cp
= validation
.mem
->buf
;
9871 for (i
= 0 ; i
< (int)len
; i
+= cc
) {
9872 cc
= write(outfd
, &cp
[i
], len
- i
);
9874 loggit("netpgp: short write");
9879 if (strcmp(outfile
, "-") != 0) {
9880 (void) close(outfd
);
9884 __ops_memory_free(validation
.mem
);
9889 \ingroup HighLevel_Verify
9890 \brief Verifies the signatures in a __ops_memory_t struct
9891 \param result Where to put the result
9892 \param mem Memory to be validated
9893 \param armoured Treat data as armoured, if set
9894 \param keyring Keyring to use
9895 \return 1 if signature validates successfully; 0 if not
9896 \note After verification, result holds the details of all keys which
9897 have passed, failed and not been recognised.
9898 \note It is the caller's responsiblity to call
9899 __ops_validate_result_free(result) after use.
9903 __ops_validate_mem(__ops_io_t
*io
,
9904 __ops_validation_t
*result
,
9905 __ops_memory_t
*mem
,
9907 const __ops_keyring_t
*keyring
)
9909 validate_data_cb_t validation
;
9910 __ops_stream_t
*stream
= NULL
;
9911 const unsigned accumulate
= 1;
9912 const int printerrors
= 1;
9914 __ops_setup_memory_read(io
, &stream
, mem
, &validation
,
9915 validate_data_cb
, accumulate
);
9916 /* Set verification reader and handling options */
9917 (void) memset(&validation
, 0x0, sizeof(validation
));
9918 validation
.result
= result
;
9919 validation
.keyring
= keyring
;
9920 validation
.mem
= __ops_new(sizeof(*validation
.mem
));
9921 __ops_memory_init(validation
.mem
, 128);
9922 /* Note: Coverity incorrectly reports an error that validation.reader */
9923 /* is never used. */
9924 validation
.reader
= stream
->readinfo
.arg
;
9926 __ops_reader_push_dearmour(stream
);
9928 /* Do the verification */
9929 __ops_parse(stream
, !printerrors
);
9932 __ops_reader_pop_dearmour(stream
);
9934 __ops_teardown_memory_read(stream
, mem
);
9935 __ops_memory_free(validation
.mem
);
9936 return validate_result_status(result
);
9939 /***************************************************************************/
9940 /* exported functions start here */
9941 /***************************************************************************/
9945 netpgp_verify_file(netpgp_t
*netpgp
, const char *in
, const char *out
, int armored
)
9947 __ops_validation_t result
;
9950 (void) memset(&result
, 0x0, sizeof(result
));
9952 if (__ops_validate_file(io
, &result
, in
, out
, armored
,
9954 resultp(io
, in
, &result
, netpgp
->pubring
);
9957 if (result
.validc
+ result
.invalidc
+ result
.unknownc
== 0) {
9958 loggit("\"%s\": No signatures found - is this a signed file?",
9962 "\"%s\": verification failure: %d invalid signatures, %d unknown signatures",
9963 in
, result
.invalidc
, result
.unknownc
);
9970 netpgp_verify_mem(netpgp_t
*netpgp
, const char *in
, size_t len
, int armored
)
9972 __ops_validation_t result
;
9973 __ops_memory_t
*mem
;
9976 (void) memset(&result
, 0x0, sizeof(result
));
9977 mem
= __ops_new(sizeof(*mem
));
9978 __ops_memory_init(mem
, len
);
9979 __ops_memory_add(mem
, (const uint8_t *)in
, len
);
9981 if (__ops_validate_mem(io
, &result
, mem
, armored
, netpgp
->pubring
)) {
9982 resultp(io
, "", &result
, netpgp
->pubring
);
9985 if (result
.validc
+ result
.invalidc
+ result
.unknownc
== 0) {
9986 loggit("No signatures found - is this memory signed?");
9989 "verification failure: %d invalid signatures, %d unknown signatures",
9990 result
.invalidc
, result
.unknownc
);
9992 __ops_memory_free(mem
);
9996 /* return the version for the library */
9998 netpgp_get_info(const char *type
)
10000 return __ops_get_info(type
);
10004 /* set a variable */
10006 netpgp_setvar(netpgp_t
*netpgp
, const char *name
, const char *value
)
10010 if ((i
= findvar(netpgp
, name
)) < 0) {
10011 /* add the element to the array */
10012 size_arrays(netpgp
, netpgp
->size
+ 15);
10013 netpgp
->name
[i
= netpgp
->c
++] = strdup(name
);
10015 /* replace the element in the array */
10016 if (netpgp
->value
[i
]) {
10017 (void) free(netpgp
->value
[i
]);
10018 netpgp
->value
[i
] = NULL
;
10021 /* sanity checks for range of values */
10022 if (strcmp(name
, "hash") == 0 || strcmp(name
, "algorithm") == 0) {
10023 if (__ops_str_to_hash_alg(value
) == OPS_HASH_UNKNOWN
) {
10027 netpgp
->value
[i
] = strdup(value
);
10031 /* get a variable's value (NULL if not set) */
10033 netpgp_getvar(netpgp_t
*netpgp
, const char *name
)
10037 return ((i
= findvar(netpgp
, name
)) < 0) ? NULL
: netpgp
->value
[i
];
10040 /* initialise a netpgp_t structure */
10042 netpgp_init(netpgp_t
*netpgp
)
10045 char id
[MAX_ID_LENGTH
];
10051 #ifdef HAVE_SYS_RESOURCE_H
10052 struct rlimit limit
;
10054 coredumps
= netpgp_getvar(netpgp
, "coredumps") != NULL
;
10056 (void) memset(&limit
, 0x0, sizeof(limit
));
10057 if (setrlimit(RLIMIT_CORE
, &limit
) != 0) {
10059 "netpgp_init: warning - can't turn off core dumps");
10066 io
= __ops_new(sizeof(*io
));
10068 if ((stream
= netpgp_getvar(netpgp
, "stdout")) != NULL
&&
10069 strcmp(stream
, "stderr") == 0) {
10073 if ((stream
= netpgp_getvar(netpgp
, "stderr")) != NULL
&&
10074 strcmp(stream
, "stdout") == 0) {
10080 loggit("netpgp: warning: core dumps enabled");
10082 if ((homedir
= netpgp_getvar(netpgp
, "homedir")) == NULL
) {
10083 loggit("netpgp: bad homedir");
10086 if ((userid
= netpgp_getvar(netpgp
, "userid")) == NULL
) {
10087 (void) memset(id
, 0x0, sizeof(id
));
10088 (void) conffile(netpgp
, homedir
, id
, sizeof(id
));
10089 if (id
[0] != 0x0) {
10090 netpgp_setvar(netpgp
, "userid", userid
= id
);
10093 if (userid
== NULL
) {
10094 if (netpgp_getvar(netpgp
, "userid checks") == NULL
) {
10095 loggit("Cannot find user id");
10098 loggit("Skipping user id check");
10100 (void) netpgp_setvar(netpgp
, "userid", id
);
10102 if ((netpgp
->pubring
= readkeyring(netpgp
, "pubring")) == NULL
) {
10103 loggit("Can't read pub keyring");
10106 if ((netpgp
->secring
= readkeyring(netpgp
, "secring")) == NULL
) {
10107 loggit("Can't read sec keyring");
10113 /* finish off with the netpgp_t struct */
10115 netpgp_end(netpgp_t
*netpgp
)
10119 for (i
= 0 ; i
< netpgp
->c
; i
++) {
10120 if (netpgp
->name
[i
] != NULL
) {
10121 (void) free(netpgp
->name
[i
]);
10123 if (netpgp
->value
[i
] != NULL
) {
10124 (void) free(netpgp
->value
[i
]);
10127 if (netpgp
->name
!= NULL
) {
10128 (void) free(netpgp
->name
);
10130 if (netpgp
->value
!= NULL
) {
10131 (void) free(netpgp
->value
);
10133 if (netpgp
->pubring
!= NULL
) {
10134 __ops_keyring_free(netpgp
->pubring
);
10136 if (netpgp
->secring
!= NULL
) {
10137 __ops_keyring_free(netpgp
->secring
);
10139 (void) free(netpgp
->io
);
10145 #include <getopt.h>
10148 * 2048 is the absolute minimum, really - we should really look at
10149 * bumping this to 4096 or even higher - agc, 20090522
10151 #define DEFAULT_NUMBITS 2048
10154 * Similraily, SHA1 is now looking as though it should not be used.
10155 * Let's pre-empt this by specifying SHA256 - gpg interoperates just
10156 * fine with SHA256 - agc, 20090522
10158 #define DEFAULT_HASH_ALG "SHA256"
10160 static const char *usage
=
10162 "\t--encrypt [--output=file] [options] files... OR\n"
10163 "\t--decrypt [--output=file] [options] files... OR\n\n"
10164 "\t--sign [--armor] [--detach] [--hash=alg] [--output=file]\n"
10165 "\t\t[options] files... OR\n"
10166 "\t--verify [options] files... OR\n"
10167 "\t--cat [--output=file] [options] files... OR\n"
10168 "\t--clearsign [--output=file] [options] files... OR\n\n"
10169 "\t--export-keys [options] OR\n"
10170 "\t--find-key [options] OR\n"
10171 "\t--generate-key [options] OR\n"
10172 "\t--import-key [options] OR\n"
10173 "\t--list-keys [options] OR\n\n"
10174 "\t--list-packets [options] OR\n"
10176 "where options are:\n"
10177 "\t[--coredumps] AND/OR\n"
10178 "\t[--homedir=<homedir>] AND/OR\n"
10179 "\t[--keyring=<keyring>] AND/OR\n"
10180 "\t[--userid=<userid>] AND/OR\n"
10216 #define EXIT_ERROR 2
10218 static struct option options
[] = {
10219 /* debugging commands */
10220 {"help", no_argument
, NULL
, HELP_CMD
},
10221 {"version", no_argument
, NULL
, VERSION_CMD
},
10222 {"debug", required_argument
, NULL
, OPS_DEBUG
},
10224 {"coredumps", no_argument
, NULL
, COREDUMPS
},
10225 {"keyring", required_argument
, NULL
, KEYRING
},
10226 {"userid", required_argument
, NULL
, USERID
},
10227 {"home", required_argument
, NULL
, HOMEDIR
},
10228 {"homedir", required_argument
, NULL
, HOMEDIR
},
10229 {"verbose", no_argument
, NULL
, VERBOSE
},
10230 {"output", required_argument
, NULL
, OUTPUT
},
10231 { NULL
, 0, NULL
, 0},
10234 /* gather up program variables into one struct */
10235 typedef struct prog_t
{
10236 char keyring
[MAXPATHLEN
+ 1]; /* name of keyring */
10237 char *progname
; /* program name */
10238 char *output
; /* output file name */
10239 int overwrite
; /* overwrite files? */
10240 int numbits
; /* # of bits */
10241 int armour
; /* ASCII armor */
10242 int detached
; /* use separate file */
10243 int cmd
; /* netpgp command */
10247 /* print a usage message */
10249 print_usage(const char *usagemsg
, char *progname
)
10251 loggit("%s\nAll bug reports, praise and chocolate, please, to:\n%s",
10252 netpgp_get_info("version"),
10253 netpgp_get_info("maintainer"));
10254 loggit("Usage: %s COMMAND OPTIONS:\n%s %s",
10255 progname
, progname
, usagemsg
);
10258 /* get even more lippy */
10260 give_it_large(netpgp_t
*netpgp
)
10267 if ((cp
= netpgp_getvar(netpgp
, "verbose")) != NULL
) {
10270 (void) snprintf(num
, sizeof(num
), "%d", val
+ 1);
10271 netpgp_setvar(netpgp
, "verbose", num
);
10274 /* set the home directory value to "home/subdir" */
10276 set_homedir(netpgp_t
*netpgp
, char *home
, const char *subdir
)
10279 char d
[MAXPATHLEN
];
10281 if (home
== NULL
) {
10282 loggit("NULL HOME directory");
10285 (void) snprintf(d
, sizeof(d
), "%s%s", home
, (subdir
) ? subdir
: "");
10286 if (stat(d
, &st
) == 0) {
10287 if ((st
.st_mode
& S_IFMT
) == S_IFDIR
) {
10288 netpgp_setvar(netpgp
, "homedir", d
);
10291 loggit("netpgp: homedir \"%s\" is not a dir", d
);
10294 loggit("netpgp: warning homedir \"%s\" not found", d
);
10299 main(int argc
, char **argv
)
10308 (void) memset(&p
, 0x0, sizeof(p
));
10309 (void) memset(&netpgp
, 0x0, sizeof(netpgp
));
10310 p
.progname
= argv
[0];
10311 p
.numbits
= DEFAULT_NUMBITS
;
10315 print_usage(usage
, p
.progname
);
10318 /* set some defaults */
10319 netpgp_setvar(&netpgp
, "hash", DEFAULT_HASH_ALG
);
10320 set_homedir(&netpgp
, getenv("HOME"), "/.gnupg");
10322 while ((ch
= getopt_long(argc
, argv
, "", options
, &optindex
)) != -1) {
10323 switch (options
[optindex
].val
) {
10325 netpgp_setvar(&netpgp
, "coredumps", "allowed");
10326 p
.cmd
= options
[optindex
].val
;
10330 "%s\nAll bug reports, praise and chocolate, please, to:\n%s",
10331 netpgp_get_info("version"),
10332 netpgp_get_info("maintainer"));
10333 exit(EXIT_SUCCESS
);
10336 if (optarg
== NULL
) {
10337 loggit("No keyring argument provided");
10340 snprintf(p
.keyring
, sizeof(p
.keyring
), "%s", optarg
);
10343 if (optarg
== NULL
) {
10344 loggit("No userid argument provided");
10347 netpgp_setvar(&netpgp
, "userid", optarg
);
10350 give_it_large(&netpgp
);
10353 if (optarg
== NULL
) {
10354 loggit("No home directory argument provided");
10357 set_homedir(&netpgp
, optarg
, NULL
);
10360 if (optarg
== NULL
) {
10361 loggit("No output filename argument provided");
10365 (void) free(p
.output
);
10367 p
.output
= strdup(optarg
);
10374 /* initialise, and read keys from file */
10375 if (!netpgp_init(&netpgp
)) {
10376 loggit("can't initialise");
10379 /* now do the required action for each of the command line args */
10380 ret
= EXIT_SUCCESS
;
10381 for (i
= optind
; i
< argc
; i
++) {
10382 if (!netpgp_verify_file(&netpgp
, argv
[i
], p
.output
, p
.armour
)) {
10383 ret
= EXIT_FAILURE
;
10386 netpgp_end(&netpgp
);