Patrick Welche <prlw1@cam.ac.uk>
[netbsd-mini2440.git] / crypto / external / bsd / netpgp / dist / src / netpgpverify / verify.c
blob3b8328cb531ddafb1570420058c509647c9a6516
1 /*-
2 * Copyright (c) 2009 The NetBSD Foundation, Inc.
3 * All rights reserved.
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
10 * are met:
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.
50 #include "config.h"
52 #ifdef HAVE_SYS_CDEFS_H
53 #include <sys/cdefs.h>
54 #endif
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 $");
59 #endif
61 #include <sys/types.h>
62 #include <sys/stat.h>
63 #include <sys/param.h>
65 #ifdef HAVE_SYS_RESOURCE_H
66 #include <sys/resource.h>
67 #endif
69 #include <sys/mman.h>
71 #ifdef HAVE_OPENSSL_AES_H
72 #include <openssl/aes.h>
73 #endif
75 #ifdef HAVE_OPENSSL_CAST_H
76 #include <openssl/cast.h>
77 #endif
79 #ifdef HAVE_OPENSSL_DES_H
80 #include <openssl/des.h>
81 #endif
83 #ifdef HAVE_OPENSSL_DSA_H
84 #include <openssl/dsa.h>
85 #endif
87 #ifdef HAVE_OPENSSL_ERR_H
88 #include <openssl/err.h>
89 #endif
91 #ifdef HAVE_OPENSSL_IDEA_H
92 #include <openssl/idea.h>
93 #endif
95 #ifdef HAVE_OPENSSL_MD5_H
96 #include <openssl/md5.h>
97 #endif
99 #ifdef HAVE_OPENSSL_SHA_H
100 #include <openssl/sha.h>
101 #endif
103 /* Apple */
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>
109 #endif
111 #ifdef HAVE_OPENSSL_RAND_H
112 #include <openssl/rand.h>
113 #endif
115 #ifdef HAVE_OPENSSL_RSA_H
116 #include <openssl/rsa.h>
117 #endif
119 #ifdef HAVE_BZLIB_H
120 #include <bzlib.h>
121 #endif
123 #include <errno.h>
125 #ifdef HAVE_INTTYPES_H
126 #include <inttypes.h>
127 #endif
129 #ifdef HAVE_LIMITS_H
130 #include <limits.h>
131 #endif
133 #include <stdarg.h>
134 #include <stdio.h>
135 #include <stdlib.h>
136 #include <string.h>
138 #include <time.h>
140 #ifdef HAVE_UNISTD_H
141 #include <unistd.h>
142 #endif
144 #ifdef HAVE_ZLIB_H
145 #include <zlib.h>
146 #endif
148 /* external interface */
149 #include <netpgp.h>
151 #ifndef NETPGP_AUTOCONF_VERSION
152 #define NETPGP_AUTOCONF_VERSION PACKAGE_VERSION
153 #endif
155 #ifndef NETPGP_MAINTAINER
156 #define NETPGP_MAINTAINER PACKAGE_BUGREPORT
157 #endif
159 /* don't use some digest algorithms */
160 #undef USE_SHA224
161 #undef USE_SHA384
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)
171 /* SHA1 Hash Size */
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
176 enum {
177 MAX_ID_LENGTH = 128,
178 MAX_PASSPHRASE_LENGTH = 256
181 #define PRItime "ll"
183 #ifdef WIN32
184 #define PRIsize "I"
185 #else
186 #define PRIsize "z"
187 #endif
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)
195 #ifndef __UNCONST
196 #define __UNCONST(a) ((void *)(unsigned long)(const void *)(a))
197 #endif
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 */
208 } __ops_memory_t;
210 /* Remember to add names to map in errors.c */
211 typedef enum {
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
215 * details */
216 OPS_E_UNIMPLEMENTED = 0x0003, /* feature not yet implemented */
218 /* reader errors */
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
223 * armour */
224 OPS_E_R_UNSUPPORTED = OPS_E_R + 4,
225 OPS_E_R_UNCONSUMED_DATA = OPS_E_R + 5,
227 /* writer errors */
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,
232 /* parser errors */
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,
242 /* creator errors */
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
271 } __ops_errcode_t;
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 */
277 char *comment;
278 const char *file;
279 int line;
280 struct __ops_error_t *next;
281 } __ops_error_t;
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
291 * handling */
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 {
312 size_t len;
313 uint8_t *contents;
314 uint8_t mmapped; /* contents need an munmap(2) */
315 } __ops_data_t;
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.
325 * \see RFC4880 4.2
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.
334 * \see RFC4880 4.2
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.
345 * \see RFC4880 4.2
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.
353 * \see RFC4880 4.2
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.
362 * \see RFC4880 4.2
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
369 * old packet format.
371 * \see RFC4880 4.2.1
373 typedef enum {
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
380 * long. */
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.
392 * \see RFC4880 4.2
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.
400 * \see RFC4880 4.2
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.
411 * \see RFC4880 4.3
412 * \see RFC4880 5.2.3.1
414 typedef enum {
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
418 * Key Packet */
419 OPS_PTAG_CT_SIGNATURE = 2, /* Signature Packet */
420 OPS_PTAG_CT_SK_SESSION_KEY = 3, /* Symmetric-Key Encrypted Session
421 * Key Packet */
422 OPS_PTAG_CT_1_PASS_SIG = 4, /* One-Pass Signature
423 * Packet */
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
443 * back the PTag. */
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
454 * value. */
455 OPS_PTAG_SS_CREATION_TIME = 0x200 + 2, /* signature creation time */
456 OPS_PTAG_SS_EXPIRATION_TIME = 0x200 + 3, /* signature
457 * expiration time */
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
464 * time */
465 OPS_PTAG_SS_RESERVED = 0x200 + 10, /* reserved */
466 OPS_PTAG_SS_PREFERRED_SKA = 0x200 + 11, /* preferred symmetric
467 * algs */
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
472 * algs */
473 OPS_PTAG_SS_PREF_COMPRESS = 0x200 + 22, /* preferred
474 * compression
475 * algorithms */
476 OPS_PTAG_SS_KEYSERV_PREFS = 0x200 + 23, /* key server
477 * preferences */
478 OPS_PTAG_SS_PREF_KEYSERV = 0x200 + 24, /* Preferred Key
479 * Server */
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
485 * revocation */
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
491 * user-defined */
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
515 * algorithm specific
516 * fields will not be
517 * initialised */
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,
528 /* Errors */
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.
545 * \see RFC4880 4.2
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 */
563 } __ops_ptag_t;
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.
570 * \see RFC4880 9.1
572 typedef enum {
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
581 * Curve */
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
586 * IETF-S/MIME) */
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.
602 * \see RFC4880 5.5.2
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.
614 * \see RFC4880 5.5.2
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.
623 * \see RFC4880 5.5.2
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 */
633 typedef union {
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;
639 /** Version.
640 * OpenPGP has two different protocol versions: version 3 and version 4.
642 * \see RFC4880 5.2
644 typedef enum {
645 OPS_V2 = 2, /* Version 2 (essentially the same as v3) */
646 OPS_V3 = 3, /* Version 3 */
647 OPS_V4 = 4 /* Version 4 */
648 } __ops_version_t;
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...) */
653 time_t birthtime;
654 /* when the key was created. Note that
655 * interpretation varies with key version. */
656 unsigned days_valid;
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
660 * v3 keys. */
661 __ops_pubkey_alg_t alg; /* Public Key Algorithm type */
662 __ops_pubkey_union_t key; /* Public Key Parameters */
663 } __ops_pubkey_t;
665 /** Structure to hold data for one RSA secret key
667 typedef struct __ops_rsa_seckey_t {
668 BIGNUM *d;
669 BIGNUM *p;
670 BIGNUM *q;
671 BIGNUM *u;
672 } __ops_rsa_seckey_t;
674 /** __ops_dsa_seckey_t */
675 typedef struct __ops_dsa_seckey_t {
676 BIGNUM *x;
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;
685 /** s2k_usage_t
687 typedef enum {
688 OPS_S2KU_NONE = 0,
689 OPS_S2KU_ENCRYPTED_AND_HASHED = 254,
690 OPS_S2KU_ENCRYPTED = 255
691 } __ops_s2k_usage_t;
693 /** s2k_specifier_t
695 typedef enum {
696 OPS_S2KS_SIMPLE = 0,
697 OPS_S2KS_SALTED = 1,
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
703 * part of OpenPGP.
705 * This lists algorithm numbers for symmetric key algorithms.
707 * \see RFC4880 9.2
709 typedef enum {
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) */
719 } __ops_symm_alg_t;
721 /** Hashing Algorithm Numbers.
722 * OpenPGP assigns a unique Algorithm Number to each algorithm that is
723 * part of OpenPGP.
725 * This lists algorithm numbers for hash algorithms.
727 * \see RFC4880 9.4
729 typedef enum {
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 */
736 #ifdef USE_SHA384
737 OPS_HASH_SHA384 = 9, /* SHA384 */
738 #endif
739 OPS_HASH_SHA512 = 10, /* SHA512 */
740 #ifdef USE_SHA224
741 OPS_HASH_SHA224 = 11 /* SHA224 */
742 #endif
743 } __ops_hash_alg_t;
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
755 /* Max hash size */
756 #define OPS_MAX_HASH_SIZE 64
758 /** __ops_seckey_t
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];
767 unsigned octetc;
768 uint8_t iv[OPS_MAX_BLOCK_SIZE];
769 __ops_seckey_union_t key;
770 unsigned checksum;
771 uint8_t *checkhash;
772 } __ops_seckey_t;
774 /** Structure to hold one trust packet's data */
776 typedef struct __ops_trust_t {
777 __ops_data_t data; /* Trust Packet */
778 } __ops_trust_t;
780 /** Structure to hold one user id */
781 typedef struct __ops_userid_t {
782 uint8_t *userid;/* User ID - UTF-8 string */
783 } __ops_userid_t;
785 /** Structure to hold one user attribute */
786 typedef struct __ops_userattr_t {
787 __ops_data_t data; /* User Attribute */
788 } __ops_userattr_t;
790 /** Signature Type.
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,
795 * etc.
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).
801 * \see RFC4880 5.2.1
803 typedef enum {
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 */
828 } __ops_signtype_t;
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) */
833 } __ops_rsa_sig_t;
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 */
839 } __ops_dsa_sig_t;
841 /** __ops_elgamal_signature_t */
842 typedef struct __ops_elgamal_sig_t {
843 BIGNUM *r;
844 BIGNUM *s;
845 } __ops_elgamal_sig_t;
847 /** Struct to hold data for a private/experimental signature */
848 typedef struct __ops_unknown_sig_t {
849 __ops_data_t data;
850 } __ops_unknown_sig_t;
852 /** Union to hold signature params of any algorithm */
853 typedef union {
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 */
858 } __ops_sig_union_t;
860 #define OPS_KEY_ID_SIZE 8
861 #define OPS_FINGERPRINT_SIZE 20
863 /** Struct to hold a signature packet.
865 * \see RFC4880 5.2.2
866 * \see RFC4880 5.2.3
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 */
877 size_t v4_hashlen;
878 uint8_t *v4_hashed;
879 unsigned gotbirthtime:1;
880 unsigned gotsigner:1;
881 } __ops_signinfo_t;
883 #define OPS_MIN_HASH_SIZE 16
885 /** __ops_hash_t */
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);
892 /* add text func */
893 unsigned (*finish)(struct __ops_hash_t *, uint8_t *);
894 /* finalise func */
895 void *data; /* blob for data */
896 } __ops_hash_t;
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 -
903 * for quick test */
904 size_t v4_hashstart; /* only valid if accumulate
905 * is set */
906 __ops_hash_t *hash; /* if set, the hash filled in for the data
907 * so far */
908 } __ops_sig_t;
910 /** The raw bytes of a signature subpacket */
911 typedef struct __ops_ss_raw_t {
912 __ops_content_tag_t tag;
913 size_t length;
914 uint8_t *raw;
915 } __ops_ss_raw_t;
917 /** Signature Subpacket : Trust Level */
918 typedef struct __ops_ss_trust_t {
919 uint8_t level; /* Trust Level */
920 uint8_t amount; /* Amount */
921 } __ops_ss_trust_t;
923 /** Signature Subpacket : Revocable */
924 typedef struct __ops_ss_revocable_t {
925 unsigned revocable;
926 } __ops_ss_revocable_t;
928 /** Signature Subpacket : Time */
929 typedef struct __ops_ss_time_t {
930 time_t time;
931 } __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];
936 } __ops_ss_key_id_t;
938 /** Signature Subpacket : Notation Data */
939 typedef struct __ops_ss_notation_t {
940 __ops_data_t flags;
941 __ops_data_t name;
942 __ops_data_t value;
943 } __ops_ss_notation_t;
945 /** Signature Subpacket : User Defined */
946 typedef struct __ops_ss_userdef_t {
947 __ops_data_t data;
948 } __ops_ss_userdef_t;
950 /** Signature Subpacket : Unknown */
951 typedef struct __ops_ss_unknown_t {
952 __ops_data_t data;
953 } __ops_ss_unknown_t;
955 /** Signature Subpacket : Preferred Symmetric Key Algorithm */
956 typedef struct __ops_ss_skapref_t {
957 __ops_data_t data;
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 {
966 __ops_data_t data;
967 } __ops_ss_hashpref_t;
969 /** Signature Subpacket : Preferred Compression */
970 typedef struct __ops_ss_zpref_t {
971 __ops_data_t data;
972 } __ops_ss_zpref_t;
974 /** Signature Subpacket : Key Flags */
975 typedef struct __ops_ss_key_flags_t {
976 __ops_data_t data;
977 } __ops_ss_key_flags_t;
979 /** Signature Subpacket : Key Server Preferences */
980 typedef struct __ops_ss_key_server_prefs_t {
981 __ops_data_t data;
982 } __ops_ss_key_server_prefs_t;
984 /** Signature Subpacket : Features */
985 typedef struct __ops_ss_features_t {
986 __ops_data_t data;
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;
993 __ops_data_t hash;
994 } __ops_ss_sig_target_t;
996 /** Signature Subpacket : Embedded Signature */
997 typedef struct __ops_ss_embedded_sig_t {
998 __ops_data_t sig;
999 } __ops_ss_embedded_sig_t;
1001 /** __ops_subpacket_t */
1002 typedef struct __ops_subpacket_t {
1003 size_t length;
1004 uint8_t *raw;
1005 } __ops_subpacket_t;
1007 /** Types of Compression */
1008 typedef enum {
1009 OPS_C_NONE = 0,
1010 OPS_C_ZIP = 1,
1011 OPS_C_ZLIB = 2,
1012 OPS_C_BZIP2 = 3
1013 } __ops_ztype_t;
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 {
1021 __ops_ztype_t type;
1022 } __ops_compressed_t;
1024 /** __ops_one_pass_sig_t */
1025 typedef struct __ops_one_pass_sig_t {
1026 uint8_t version;
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];
1031 unsigned nested;
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 {
1041 char *regexp;
1042 } __ops_ss_regexp_t;
1044 /** Signature Subpacket : Policy URL */
1045 typedef struct __ops_ss_policy_t {
1046 char *url;
1047 } __ops_ss_policy_t;
1049 /** Signature Subpacket : Preferred Key Server */
1050 typedef struct __ops_ss_keyserv_t {
1051 char *name;
1052 } __ops_ss_keyserv_t;
1054 /** Signature Subpacket : Revocation Key */
1055 typedef struct __ops_ss_revocation_key_t {
1056 uint8_t class;
1057 uint8_t algid;
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 {
1063 uint8_t code;
1064 char *reason;
1065 } __ops_ss_revocation_t;
1067 /** litdata_type_t */
1068 typedef enum {
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;
1079 char filename[256];
1080 time_t mtime;
1081 } __ops_litdata_header_t;
1083 /** __ops_litdata_body_t */
1084 typedef struct __ops_litdata_body_t {
1085 unsigned length;
1086 uint8_t *data;
1087 __ops_memory_t *mem;
1088 } __ops_litdata_body_t;
1090 /** __ops_mdc_t */
1091 typedef struct __ops_mdc_t {
1092 unsigned length;
1093 uint8_t *data;
1094 } __ops_mdc_t;
1096 /** __ops_header_var_t */
1097 typedef struct __ops_header_var_t {
1098 char *key;
1099 char *value;
1100 } __ops_header_var_t;
1102 /** __ops_headers_t */
1103 typedef struct __ops_headers_t {
1104 __ops_header_var_t *headers;
1105 unsigned headerc;
1106 } __ops_headers_t;
1108 /** __ops_armour_header_t */
1109 typedef struct __ops_armour_header_t {
1110 const char *type;
1111 __ops_headers_t headers;
1112 } __ops_armour_header_t;
1114 /** __ops_armour_trailer_t */
1115 typedef struct __ops_armour_trailer_t {
1116 const char *type;
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 {
1126 unsigned length;
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
1135 * form */
1136 } __ops_cleartext_trailer_t;
1138 /** __ops_unarmoured_text_t */
1139 typedef struct __ops_unarmoured_text_t {
1140 unsigned length;
1141 uint8_t *data;
1142 } __ops_unarmoured_text_t;
1144 typedef enum {
1145 SE_IP_DATA_VERSION = 1
1146 } __ops_se_ip_data_version_t;
1148 typedef enum {
1149 OPS_PKSK_V3 = 3
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;
1155 BIGNUM *m;
1156 } __ops_pk_sesskey_params_rsa_t;
1158 /** __ops_pk_sesskey_params_elgamal_t */
1159 typedef struct __ops_pk_sesskey_params_elgamal_t {
1160 BIGNUM *g_to_k;
1161 BIGNUM *encrypted_m;
1162 } __ops_pk_sesskey_params_elgamal_t;
1164 /** __ops_pk_sesskey_params_t */
1165 typedef union {
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];
1178 uint16_t checksum;
1179 } __ops_pk_sesskey_t;
1181 /** __ops_seckey_passphrase_t */
1182 typedef struct __ops_seckey_passphrase_t {
1183 const __ops_seckey_t *seckey;
1184 char **passphrase;
1185 /* point somewhere that gets filled in to work around
1186 * constness of content */
1187 } __ops_seckey_passphrase_t;
1189 typedef enum {
1190 OPS_SE_IP_V1 = 1
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 {
1200 unsigned length;
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 {
1206 unsigned length;
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 */
1217 typedef union {
1218 __ops_parser_error_t error;
1219 __ops_parser_errcode_t errcode;
1220 __ops_ptag_t ptag;
1221 __ops_pubkey_t pubkey;
1222 __ops_trust_t trust;
1223 __ops_userid_t userid;
1224 __ops_userattr_t userattr;
1225 __ops_sig_t sig;
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;
1249 __ops_mdc_t mdc;
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;
1268 } __ops_contents_t;
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 */
1275 } __ops_packet_t;
1277 /** __ops_fingerprint_t */
1278 typedef struct __ops_fingerprint_t {
1279 uint8_t fingerprint[OPS_FINGERPRINT_SIZE];
1280 unsigned length;
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
1296 typedef union {
1297 __ops_pubkey_t pubkey;
1298 __ops_seckey_t seckey;
1299 } __ops_keypair_union_t;
1301 /** sigpacket_t */
1302 typedef struct sigpacket_t {
1303 __ops_userid_t *userid;
1304 __ops_subpacket_t *packet;
1305 } sigpacket_t;
1307 /**
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;
1318 } __ops_key_t;
1320 /* this struct defines a number of keys (a keyring) */
1321 typedef struct __ops_keyring_t {
1322 DYNARRAY(__ops_key_t, key);
1323 } __ops_keyring_t;
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 */
1330 } __ops_io_t;
1332 /** Writer settings */
1333 typedef struct __ops_writer_t {
1334 unsigned (*writer)(struct __ops_writer_t *,
1335 const uint8_t *,
1336 unsigned,
1337 __ops_error_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 */
1347 } __ops_writer_t;
1349 typedef struct __ops_output_t {
1350 __ops_writer_t writer;
1351 __ops_error_t *errors; /* error stack */
1352 } __ops_output_t;
1354 /** _ops_crypt_t */
1355 typedef struct __ops_crypt_t {
1356 __ops_symm_alg_t alg;
1357 size_t blocksize;
1358 size_t keysize;
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 *,
1368 size_t);
1369 void (*cfb_decrypt)(struct __ops_crypt_t *, void *, const void *,
1370 size_t);
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];
1377 int num;
1378 /* num is offset - see openssl _encrypt doco */
1379 void *encrypt_key;
1380 void *decrypt_key;
1381 } __ops_crypt_t;
1383 /** __ops_region_t */
1384 typedef struct __ops_region_t {
1385 struct __ops_region_t *parent;
1386 unsigned length;
1387 unsigned readc; /* length read */
1388 unsigned lastread;
1389 /* length of last read, only valid in deepest child */
1390 unsigned indeterm:1;
1391 } __ops_region_t;
1393 /** __ops_cb_ret_t */
1394 typedef enum {
1395 OPS_RELEASE_MEMORY,
1396 OPS_KEEP_MEMORY,
1397 OPS_FINISHED
1398 } __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
1420 * or ignored. */
1421 typedef enum {
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 */
1437 } __ops_cbdata_t;
1439 /** __ops_reader_t */
1440 typedef struct __ops_reader_t {
1441 int (*reader)(void *, size_t, __ops_error_t **,
1442 struct __ops_reader_t *,
1443 __ops_cbdata_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 */
1453 } __ops_reader_t;
1455 /** __ops_hashtype_t */
1456 typedef struct __ops_hashtype_t {
1457 __ops_hash_t hash;
1458 uint8_t keyid[OPS_KEY_ID_SIZE];
1459 } __ops_hashtype_t;
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;
1494 size_t hashc;
1495 __ops_hashtype_t *hashes;
1496 unsigned reading_v3_secret:1;
1497 unsigned reading_mpi_len:1;
1498 unsigned exact_read:1;
1499 } __ops_stream_t;
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;
1512 unsigned packet;
1513 unsigned offset;
1514 } validate_reader_t;
1516 /** Struct use with the validate_data_cb callback */
1517 typedef struct {
1518 enum {
1519 LITDATA,
1520 SIGNED_CLEARTEXT
1521 } type;
1522 union {
1523 __ops_litdata_body_t litdata_body;
1524 __ops_cleartext_body_t cleartext_body;
1525 } data;
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;
1531 char *detachname;
1532 } validate_data_cb_t;
1534 typedef enum {
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,
1540 OPS_PGP_SIGNATURE
1541 } __ops_armor_type_t;
1543 #define CRC24_INIT 0xb704ceL
1545 /*************************************************************************/
1546 /* code starts here */
1547 /*************************************************************************/
1549 #ifdef WIN32
1550 #define vsnprintf _vsnprintf
1551 #endif
1553 static void
1554 loggit(const char *fmt, ...)
1556 va_list args;
1557 char buf[1024];
1559 va_start(args, fmt);
1560 vsnprintf(buf, sizeof(buf), fmt, args);
1561 va_end(args);
1562 printf("netpgpverify: %s\n", buf);
1565 /* generic grab new storage function */
1566 static void *
1567 __ops_new(size_t size)
1569 void *vp;
1571 if ((vp = calloc(1, size)) == NULL) {
1572 loggit("allocation failure for %" PRIsize "u bytes", size);
1574 return vp;
1577 /* \todo check where userid pointers are copied */
1579 \ingroup Core_Keys
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)
1588 size_t len;
1590 len = strlen((char *) src->userid);
1591 if (dst->userid) {
1592 (void) free(dst->userid);
1594 dst->userid = __ops_new(len + 1);
1595 (void) memcpy(dst->userid, src->userid, len);
1596 return dst;
1600 \ingroup Core_Keys
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;
1611 EXPAND(key, uid);
1612 uidp = &key->uids[key->uidc++];
1613 uidp->userid = NULL;
1614 return __ops_copy_userid(uidp, userid);
1618 \ingroup Core_Keys
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)
1627 if (dst->raw) {
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);
1633 return dst;
1637 \ingroup Core_Keys
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++];
1650 pktp->length = 0;
1651 pktp->raw = NULL;
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 *,
1658 const size_t,
1659 const __ops_pubkey_t *);
1660 static void __ops_fingerprint(__ops_fingerprint_t *, const __ops_pubkey_t *);
1663 typedef struct {
1664 __ops_keyring_t *keyring;
1665 } accumulate_t;
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
1681 static void
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 */
1686 __ops_error_t *err;
1687 unsigned maxbuf = 128;
1688 va_list args;
1689 char *comment;
1691 if ((comment = __ops_new(maxbuf + 1)) == NULL) {
1692 loggit("alloc comment failure");
1693 return;
1695 va_start(args, fmt);
1696 vsnprintf(comment, maxbuf + 1, fmt, args);
1697 va_end(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");
1701 return;
1703 err->next = *errstack;
1704 *errstack = err;
1706 /* fill in the details */
1707 err->errcode = errcode;
1708 err->sys_errno = sys_errno;
1709 err->file = file;
1710 err->line = line;
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;
1724 __ops_key_t *key;
1725 accumulate_t *accumulate;
1727 content = &pkt->u;
1728 accumulate = cbdata->arg;
1729 keyring = accumulate->keyring;
1730 key = (keyring->keyc > 0) ? &keyring->keys[keyring->keyc] : NULL;
1731 switch (pkt->tag) {
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) ?
1737 &content->pubkey :
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;
1746 } else {
1747 key->key.seckey = content->seckey;
1749 return OPS_KEEP_MEMORY;
1751 case OPS_PTAG_CT_USER_ID:
1752 if (key) {
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:
1760 if (key) {
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));
1773 break;
1775 default:
1776 break;
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()
1790 static void
1791 __ops_set_callback(__ops_stream_t *stream,
1792 __ops_cb_ret_t (*cb)(__ops_cbdata_t *, const __ops_packet_t *),
1793 void *arg)
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()
1805 static void
1806 __ops_callback_push(__ops_stream_t *stream,
1807 __ops_cb_ret_t (*cb)(__ops_cbdata_t *, const __ops_packet_t *),
1808 void *arg)
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
1832 static int
1833 __ops_parse_and_accumulate(__ops_keyring_t *keyring, __ops_stream_t *parse)
1835 accumulate_t accumulate;
1836 const int printerrors = 1;
1837 int ret;
1839 if (parse->readinfo.accumulate) {
1840 loggit("__ops_parse_and_accumulate: already init");
1841 return 0;
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);
1848 return ret;
1852 /** \file
1853 * \brief Error Handling
1855 #define ERRNAME(code) { code, #code }
1857 typedef struct {
1858 int type;
1859 const char *string;
1860 } __ops_map_t;
1862 static __ops_map_t errcode_name_map[] = {
1863 ERRNAME(OPS_E_OK),
1864 ERRNAME(OPS_E_FAIL),
1865 ERRNAME(OPS_E_SYSTEM_ERROR),
1866 ERRNAME(OPS_E_UNIMPLEMENTED),
1868 ERRNAME(OPS_E_R),
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),
1874 ERRNAME(OPS_E_W),
1875 ERRNAME(OPS_E_W_WRITE_FAILED),
1876 ERRNAME(OPS_E_W_WRITE_TOO_SHORT),
1878 ERRNAME(OPS_E_P),
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),
1884 ERRNAME(OPS_E_C),
1886 ERRNAME(OPS_E_V),
1887 ERRNAME(OPS_E_V_BAD_SIGNATURE),
1888 ERRNAME(OPS_E_V_NO_SIGNATURE),
1889 ERRNAME(OPS_E_V_UNKNOWN_SIGNER),
1891 ERRNAME(OPS_E_ALG),
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),
1908 {0x00, NULL}
1912 * \ingroup Core_Print
1914 * Searches the given map for the given type.
1915 * Returns a readable string if found, "Unknown" if not.
1917 static const char *
1918 findtype(int type, __ops_map_t *map)
1920 __ops_map_t *row;
1922 for (row = map; row->string != NULL; row++) {
1923 if (row->type == type) {
1924 return row->string;
1927 return "Unknown";
1931 * \ingroup Core_Errors
1932 * \brief returns error code name
1933 * \param errcode
1934 * \return error code name or "Unknown"
1936 static const char *
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
1947 static void
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,
1953 err->comment);
1954 } else {
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
1964 static void
1965 __ops_print_errors(__ops_error_t *errstack)
1967 __ops_error_t *err;
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
1979 static void
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);
1988 errstack = next;
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()
2000 static void
2001 __ops_memory_release(__ops_memory_t *mem)
2003 if (mem->mmapped) {
2004 (void) munmap(mem->buf, mem->length);
2005 } else {
2006 (void) free(mem->buf);
2008 mem->buf = NULL;
2009 mem->length = 0;
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()
2019 static void
2020 __ops_memory_free(__ops_memory_t *mem)
2022 __ops_memory_release(mem);
2023 (void) free(mem);
2026 /* various message digest functions */
2028 static void
2029 md5_init(__ops_hash_t *hash)
2031 if (hash->data) {
2032 loggit("md5_init: hash data non-null");
2034 hash->data = __ops_new(sizeof(MD5_CTX));
2035 MD5_Init(hash->data);
2038 static void
2039 md5_add(__ops_hash_t *hash, const uint8_t *data, unsigned length)
2041 MD5_Update(hash->data, data, length);
2044 static unsigned
2045 md5_finish(__ops_hash_t *hash, uint8_t *out)
2047 MD5_Final(out, hash->data);
2048 free(hash->data);
2049 hash->data = NULL;
2050 return 16;
2053 static __ops_hash_t __md5 = {
2054 OPS_HASH_MD5,
2055 MD5_DIGEST_LENGTH,
2056 "MD5",
2057 md5_init,
2058 md5_add,
2059 md5_finish,
2060 NULL
2064 \ingroup Core_Crypto
2065 \brief Initialise to MD5
2066 \param hash Hash to initialise
2068 static void
2069 __ops_hash_md5(__ops_hash_t *hash)
2071 *hash = __md5;
2074 static void
2075 sha1_init(__ops_hash_t *hash)
2077 if (hash->data) {
2078 loggit("sha1_init: hash data non-null");
2080 hash->data = __ops_new(sizeof(SHA_CTX));
2081 SHA1_Init(hash->data);
2084 static void
2085 sha1_add(__ops_hash_t *hash, const uint8_t *data, unsigned length)
2087 SHA1_Update(hash->data, data, length);
2090 static unsigned
2091 sha1_finish(__ops_hash_t *hash, uint8_t *out)
2093 SHA1_Final(out, hash->data);
2094 (void) free(hash->data);
2095 hash->data = NULL;
2096 return OPS_SHA1_HASH_SIZE;
2099 static __ops_hash_t __sha1 = {
2100 OPS_HASH_SHA1,
2101 OPS_SHA1_HASH_SIZE,
2102 "SHA1",
2103 sha1_init,
2104 sha1_add,
2105 sha1_finish,
2106 NULL
2110 \ingroup Core_Crypto
2111 \brief Initialise to SHA1
2112 \param hash Hash to initialise
2114 static void
2115 __ops_hash_sha1(__ops_hash_t *hash)
2117 *hash = __sha1;
2120 static void
2121 sha256_init(__ops_hash_t *hash)
2123 if (hash->data) {
2124 loggit("sha256_init: hash data non-null");
2126 hash->data = __ops_new(sizeof(SHA256_CTX));
2127 SHA256_Init(hash->data);
2130 static void
2131 sha256_add(__ops_hash_t *hash, const uint8_t *data, unsigned length)
2133 SHA256_Update(hash->data, data, length);
2136 static unsigned
2137 sha256_finish(__ops_hash_t *hash, uint8_t *out)
2139 SHA256_Final(out, hash->data);
2140 (void) free(hash->data);
2141 hash->data = NULL;
2142 return SHA256_DIGEST_LENGTH;
2145 static __ops_hash_t __sha256 = {
2146 OPS_HASH_SHA256,
2147 SHA256_DIGEST_LENGTH,
2148 "SHA256",
2149 sha256_init,
2150 sha256_add,
2151 sha256_finish,
2152 NULL
2155 static void
2156 __ops_hash_sha256(__ops_hash_t *hash)
2158 *hash = __sha256;
2161 #ifdef USE_SHA384
2163 * SHA384
2165 static void
2166 sha384_init(__ops_hash_t *hash)
2168 if (hash->data) {
2169 loggit("sha384_init: hash data non-null");
2171 hash->data = __ops_new(sizeof(SHA512_CTX));
2172 SHA384_Init(hash->data);
2175 static void
2176 sha384_add(__ops_hash_t *hash, const uint8_t *data, unsigned length)
2178 SHA384_Update(hash->data, data, length);
2181 static unsigned
2182 sha384_finish(__ops_hash_t *hash, uint8_t *out)
2184 SHA384_Final(out, hash->data);
2185 (void) free(hash->data);
2186 hash->data = NULL;
2187 return SHA384_DIGEST_LENGTH;
2190 static __ops_hash_t __sha384 = {
2191 OPS_HASH_SHA384,
2192 SHA384_DIGEST_LENGTH,
2193 "SHA384",
2194 sha384_init,
2195 sha384_add,
2196 sha384_finish,
2197 NULL
2200 static void
2201 __ops_hash_sha384(__ops_hash_t *hash)
2203 *hash = __sha384;
2205 #endif
2208 * SHA512
2210 static void
2211 sha512_init(__ops_hash_t *hash)
2213 if (hash->data) {
2214 loggit("sha512_init: hash data non-null");
2216 hash->data = __ops_new(sizeof(SHA512_CTX));
2217 SHA512_Init(hash->data);
2220 static void
2221 sha512_add(__ops_hash_t *hash, const uint8_t *data, unsigned length)
2223 SHA512_Update(hash->data, data, length);
2226 static unsigned
2227 sha512_finish(__ops_hash_t *hash, uint8_t *out)
2229 SHA512_Final(out, hash->data);
2230 (void) free(hash->data);
2231 hash->data = NULL;
2232 return SHA512_DIGEST_LENGTH;
2235 static __ops_hash_t __sha512 = {
2236 OPS_HASH_SHA512,
2237 SHA512_DIGEST_LENGTH,
2238 "SHA512",
2239 sha512_init,
2240 sha512_add,
2241 sha512_finish,
2242 NULL
2245 static void
2246 __ops_hash_sha512(__ops_hash_t *hash)
2248 *hash = __sha512;
2251 #ifdef USE_SHA224
2253 * SHA224
2256 static void
2257 sha224_init(__ops_hash_t *hash)
2259 if (hash->data) {
2260 loggit("sha224_init: hash data non-null");
2262 hash->data = __ops_new(sizeof(SHA256_CTX));
2263 SHA224_Init(hash->data);
2266 static void
2267 sha224_add(__ops_hash_t *hash, const uint8_t *data, unsigned length)
2269 SHA224_Update(hash->data, data, length);
2272 static unsigned
2273 sha224_finish(__ops_hash_t *hash, uint8_t *out)
2275 SHA224_Final(out, hash->data);
2276 (void) free(hash->data);
2277 hash->data = NULL;
2278 return SHA224_DIGEST_LENGTH;
2281 static __ops_hash_t __sha224 = {
2282 OPS_HASH_SHA224,
2283 SHA224_DIGEST_LENGTH,
2284 "SHA224",
2285 sha224_init,
2286 sha224_add,
2287 sha224_finish,
2288 NULL
2291 static void
2292 __ops_hash_sha224(__ops_hash_t *hash)
2294 *hash = __sha224;
2296 #endif
2299 \ingroup Core_Hashes
2300 \brief Add to the hash
2301 \param hash Hash to add to
2302 \param n Int to add
2303 \param length Length of int in bytes
2305 static void
2306 __ops_hash_add_int(__ops_hash_t *hash, unsigned n, unsigned length)
2308 while (length--) {
2309 uint8_t c;
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
2325 static void
2326 __ops_fingerprint(__ops_fingerprint_t *fp, const __ops_pubkey_t *key)
2328 if (key->version == 2 || key->version == 3) {
2329 uint8_t *bn;
2330 __ops_hash_t md5;
2331 size_t n;
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");
2337 return;
2339 /* start the md5 digest */
2340 __ops_hash_md5(&md5);
2341 md5.init(&md5);
2342 n = BN_num_bytes(key->key.rsa.n);
2343 /* add the digests of the RSA numbers */
2344 bn = __ops_new(n);
2345 BN_bn2bin(key->key.rsa.n, bn);
2346 md5.add(&md5, bn, n);
2347 (void) free(bn);
2348 n = BN_num_bytes(key->key.rsa.e);
2349 bn = __ops_new(n);
2350 BN_bn2bin(key->key.rsa.e, bn);
2351 md5.add(&md5, bn, n);
2352 (void) free(bn);
2353 fp->length = md5.finish(&md5, fp->fingerprint);
2354 } else {
2355 __ops_memory_t *mem;
2356 __ops_hash_t sha1;
2357 size_t len;
2359 mem = __ops_new(sizeof(*mem));
2360 __ops_build_pubkey(key, mem);
2362 __ops_hash_sha1(&sha1);
2363 sha1.init(&sha1);
2365 len = mem->length;
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
2385 static void
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");
2394 return;
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");
2400 return;
2402 BN_bn2bin(key->key.rsa.n, bn);
2403 (void) memcpy(keyid, bn + n - idlen, idlen);
2404 } else {
2405 __ops_fingerprint_t finger;
2407 __ops_fingerprint(&finger, key);
2408 (void) memcpy(keyid,
2409 finger.fingerprint + finger.length - idlen,
2410 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
2420 static void
2421 __ops_hash_any(__ops_hash_t *hash, __ops_hash_alg_t alg)
2423 switch (alg) {
2424 case OPS_HASH_MD5:
2425 __ops_hash_md5(hash);
2426 break;
2428 case OPS_HASH_SHA1:
2429 __ops_hash_sha1(hash);
2430 break;
2432 case OPS_HASH_SHA256:
2433 __ops_hash_sha256(hash);
2434 break;
2436 #ifdef USE_SHA384
2437 case OPS_HASH_SHA384:
2438 __ops_hash_sha384(hash);
2439 break;
2440 #endif
2442 case OPS_HASH_SHA512:
2443 __ops_hash_sha512(hash);
2444 break;
2446 #ifdef USE_SHA224
2447 case OPS_HASH_SHA224:
2448 __ops_hash_sha224(hash);
2449 break;
2450 #endif
2452 default:
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
2463 static unsigned
2464 __ops_hash_size(__ops_hash_alg_t alg)
2466 switch (alg) {
2467 case OPS_HASH_MD5:
2468 return 16;
2470 case OPS_HASH_SHA1:
2471 return 20;
2473 case OPS_HASH_SHA256:
2474 return 32;
2476 #ifdef USE_SHA224
2477 case OPS_HASH_SHA224:
2478 return 28;
2479 #endif
2481 #ifdef USE_SHA384
2482 case OPS_HASH_SHA384:
2483 return 48;
2484 #endif
2486 case OPS_HASH_SHA512:
2487 return 64;
2489 default:
2490 loggit("__ops_hash_size: bad algorithm");
2493 return 0;
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;
2514 #ifdef USE_SHA224
2516 if (strcmp(hash,"SHA224") == 0) {
2517 return OPS_HASH_SHA224;
2520 #endif
2521 #ifdef USE_SHA384
2522 if (strcmp(hash, "SHA384") == 0) {
2523 return OPS_HASH_SHA384;
2525 #endif
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
2542 static void
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,
2547 uint8_t *hashed)
2549 uint8_t c;
2550 __ops_hash_t hash;
2552 /* init */
2553 __ops_hash_any(&hash, OPS_HASH_SHA1);
2554 hash.init(&hash);
2556 /* preamble */
2557 hash.add(&hash, preamble, sz_preamble);
2558 /* plaintext */
2559 hash.add(&hash, plaintext, sz_plaintext);
2560 /* MDC packet tag */
2561 c = MDC_PKT_TAG;
2562 hash.add(&hash, &c, 1);
2563 /* MDC packet len */
2564 c = OPS_SHA1_HASH_SIZE;
2565 hash.add(&hash, &c, 1);
2567 /* finish */
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
2577 static unsigned
2578 __ops_is_hash_alg_supported(const __ops_hash_alg_t *hash_alg)
2580 switch (*hash_alg) {
2581 case OPS_HASH_MD5:
2582 case OPS_HASH_SHA1:
2583 case OPS_HASH_SHA256:
2584 return 1;
2586 default:
2587 return 0;
2593 \ingroup HighLevel_Memory
2594 \brief Memory to initialise
2595 \param mem memory to initialise
2596 \param needed Size to initialise to
2598 static void
2599 __ops_memory_init(__ops_memory_t *mem, size_t needed)
2601 mem->length = 0;
2602 if (mem->buf) {
2603 if (mem->allocated < needed) {
2604 mem->buf = realloc(mem->buf, needed);
2605 mem->allocated = needed;
2607 return;
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
2619 static void
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");
2624 return;
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
2642 static void
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 */
2651 static int
2652 __ops_mem_readfile(__ops_memory_t *mem, const char *f)
2654 struct stat st;
2655 FILE *fp;
2656 int cc;
2658 if ((fp = fopen(f, "rb")) == NULL) {
2659 loggit( "__ops_mem_readfile: can't open \"%s\"", f);
2660 return 0;
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");
2670 (void) fclose(fp);
2671 return 0;
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) {
2679 } else {
2680 mem->length = mem->allocated;
2681 mem->mmapped = 1;
2683 (void) fclose(fp);
2684 return (mem->allocated == mem->length);
2687 typedef struct {
2688 uint16_t sum;
2689 } sum16_t;
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
2704 * parsed data.
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.
2711 * \param *dest
2712 * \param *plength
2713 * \param flags
2714 * \param *stream
2716 * \return OPS_R_OK
2717 * \return OPS_R_PARTIAL_READ
2718 * \return OPS_R_EOF
2719 * \return OPS_R_EARLY_EOF
2721 * \sa #__ops_reader_ret_t for details of return codes
2724 static int
2725 sub_base_read(void *dest, size_t length, __ops_error_t **errors,
2726 __ops_reader_t *readinfo, __ops_cbdata_t *cbdata)
2728 size_t n;
2730 /* reading more than this would look like an error */
2731 if (length > INT_MAX) {
2732 length = INT_MAX;
2735 for (n = 0; n < length;) {
2736 int r;
2738 r = readinfo->reader((char *) dest + n, length - n, errors,
2739 readinfo, cbdata);
2740 if (r > (int)(length - n)) {
2741 loggit("sub_base_read: bad read");
2742 return 0;
2744 if (r < 0) {
2745 return r;
2747 if (r == 0) {
2748 break;
2750 n += r;
2753 if (n == 0) {
2754 return 0;
2756 if (readinfo->accumulate) {
2757 if (readinfo->asize < readinfo->alength) {
2758 loggit("sub_base_read: bad size");
2759 return 0;
2761 if (readinfo->alength + n > readinfo->asize) {
2762 readinfo->asize = readinfo->asize * 2 + n;
2763 readinfo->accumulated = realloc(readinfo->accumulated,
2764 readinfo->asize);
2766 if (readinfo->asize < readinfo->alength + n) {
2767 loggit("sub_base_read: bad realloc");
2768 return 0;
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;
2778 return n;
2781 static int
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);
2788 static int
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;
2793 sum16_t *arg;
2794 int r;
2795 int n;
2797 arg = readinfo->arg;
2798 r = __ops_stacked_read(destarg, length, errors, readinfo, cbdata);
2799 if (r < 0) {
2800 return r;
2802 for (n = 0; n < r; ++n) {
2803 arg->sum = (arg->sum + dest[n]) & 0xffff;
2805 return r;
2808 static void
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
2822 static void
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 *),
2827 void *vp)
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
2842 static void
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 *),
2847 void *vp)
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
2867 static void
2868 __ops_reader_push_sum16(__ops_stream_t *stream)
2870 sum16_t *arg;
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
2881 static void
2882 __ops_reader_pop(__ops_stream_t *stream)
2884 __ops_reader_t *next = stream->readinfo.next;
2886 stream->readinfo = *next;
2887 (void) free(next);
2891 \ingroup Internal_Readers_Sum16
2892 \param stream Parse settings
2893 \return sum
2895 static uint16_t
2896 __ops_reader_pop_sum16(__ops_stream_t *stream)
2898 uint16_t sum;
2899 sum16_t *arg;
2901 arg = stream->readinfo.arg;
2902 sum = arg->sum;
2903 __ops_reader_pop(stream);
2904 free(arg);
2905 return sum;
2908 /* return the version for the library */
2909 static const char *
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;
2918 return "[unknown]";
2922 static unsigned
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)
2927 unsigned qlen;
2928 DSA_SIG *osig;
2929 DSA *odsa;
2930 int ret;
2932 osig = DSA_SIG_new();
2933 osig->r = sig->r;
2934 osig->s = sig->s;
2936 odsa = DSA_new();
2937 odsa->p = dsa->p;
2938 odsa->q = dsa->q;
2939 odsa->g = dsa->g;
2940 odsa->pub_key = dsa->y;
2942 if ((qlen = BN_num_bytes(odsa->q)) < hash_length) {
2943 hash_length = qlen;
2945 ret = DSA_do_verify(hash, (int)hash_length, osig, odsa);
2946 if (ret < 0) {
2947 loggit("__ops_dsa_verify: DSA verification");
2948 return 0;
2951 odsa->p = odsa->q = odsa->g = odsa->pub_key = NULL;
2952 DSA_free(odsa);
2954 osig->r = osig->s = NULL;
2955 DSA_SIG_free(osig);
2957 return ret;
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
2969 static int
2970 __ops_rsa_public_decrypt(uint8_t *out,
2971 const uint8_t *in,
2972 size_t length,
2973 const __ops_rsa_pubkey_t *pubkey)
2975 RSA *orsa;
2976 int n;
2978 orsa = RSA_new();
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;
2985 RSA_free(orsa);
2987 return n;
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
3000 static int
3001 __ops_rsa_private_decrypt(uint8_t *out,
3002 const uint8_t *in,
3003 size_t length,
3004 const __ops_rsa_seckey_t *seckey,
3005 const __ops_rsa_pubkey_t *pubkey)
3007 RSA *keypair;
3008 int n;
3009 char errbuf[1024];
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;
3017 /* debug */
3018 keypair->e = pubkey->e;
3019 if (RSA_check_key(keypair) != 1) {
3020 loggit("RSA_check_key is not set");
3021 return 0;
3023 /* end debug */
3025 n = RSA_private_decrypt((int)length, in, out, keypair, RSA_NO_PADDING);
3027 errbuf[0] = '\0';
3028 if (n == -1) {
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;
3035 RSA_free(keypair);
3037 return n;
3040 static void
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);
3048 static void
3049 add_sig_to_list(const __ops_signinfo_t *sig, __ops_signinfo_t **sigs,
3050 unsigned *count)
3052 if (*count == 0) {
3053 *sigs = __ops_new((*count + 1) * sizeof(__ops_signinfo_t));
3054 } else {
3055 *sigs = realloc(*sigs,
3056 (*count + 1) * sizeof(__ops_signinfo_t));
3058 copy_sig_info(&(*sigs)[*count], sig);
3059 *count += 1;
3063 \ingroup HighLevel_KeyGeneral
3065 \brief Returns the public key in the given key.
3066 \param 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) ?
3077 &key->key.pubkey :
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])
3099 unsigned n;
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];
3111 return NULL;
3114 static unsigned
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? */
3120 static unsigned
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];
3127 uint8_t trailer[6];
3128 unsigned int hashedlen;
3129 __ops_hash_t hash;
3130 unsigned n = 0;
3132 __OPS_USED(signer);
3133 __ops_hash_any(&hash, sig->info.hash_alg);
3134 hash.init(&hash);
3135 hash.add(&hash, data, len);
3136 switch (sig->info.version) {
3137 case OPS_V3:
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);
3144 break;
3146 case OPS_V4:
3147 hash.add(&hash, sig->info.v4_hashed, sig->info.v4_hashlen);
3148 trailer[0] = 0x04; /* version */
3149 trailer[1] = 0xFF;
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);
3156 break;
3158 default:
3159 loggit("Invalid signature version %d",
3160 sig->info.version);
3161 return 0;
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;
3174 __ops_io_t *io;
3175 unsigned valid = 0;
3177 io = cbdata->io;
3178 data = cbdata->arg;
3179 errors = cbdata->errors;
3180 switch (pkt->tag) {
3181 case OPS_PTAG_CT_SIGNED_CLEARTEXT_HEADER:
3183 * ignore - this gives us the "Armor Header" line "Hash:
3184 * SHA1" or similar
3186 break;
3188 case OPS_PTAG_CT_LITDATA_HEADER:
3189 /* ignore */
3190 break;
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 */
3208 break;
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);
3214 if (!signer) {
3215 OPS_ERROR(errors, OPS_E_V_UNKNOWN_SIGNER,
3216 "Unknown Signer");
3217 add_sig_to_list(&content->sig.info,
3218 &data->result->unknowns,
3219 &data->result->unknownc);
3220 break;
3222 switch (content->sig.info.type) {
3223 case OPS_SIG_BINARY:
3224 case OPS_SIG_TEXT:
3225 if (data->mem->length == 0 &&
3226 data->detachname) {
3227 /* check we have seen some data */
3228 /* if not, need to read from detached name */
3229 loggit(
3230 "netpgp: assuming signed data in \"%s\"",
3231 data->detachname);
3232 data->mem = __ops_new(sizeof(*data->mem));
3233 __ops_mem_readfile(data->mem, data->detachname);
3235 valid = check_binary_sig(data->mem->length,
3236 data->mem->buf,
3237 &content->sig,
3238 __ops_get_pubkey(signer));
3239 break;
3241 default:
3242 OPS_ERROR_1(errors, OPS_E_UNIMPLEMENTED,
3243 "No Sig Verification type 0x%02x yet\n",
3244 content->sig.info.type);
3245 break;
3249 if (valid) {
3250 add_sig_to_list(&content->sig.info,
3251 &data->result->valids,
3252 &data->result->validc);
3253 } else {
3254 OPS_ERROR(errors, OPS_E_V_BAD_SIGNATURE,
3255 "Bad Signature");
3256 add_sig_to_list(&content->sig.info,
3257 &data->result->invalids,
3258 &data->result->invalidc);
3260 break;
3262 /* ignore these */
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:
3268 break;
3270 case OPS_PARSER_PACKET_END:
3271 break;
3273 default:
3274 OPS_ERROR(errors, OPS_E_V_NO_SIGNATURE, "No signature");
3275 break;
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
3289 static unsigned
3290 validate_result_status(__ops_validation_t *val)
3292 return val->validc && !val->invalidc && !val->unknownc;
3295 /* utility function to zero out memory */
3296 static void
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 */
3312 static void
3313 __ops_stream_options(__ops_stream_t *stream,
3314 __ops_content_tag_t tag,
3315 __ops_parse_type_t type)
3317 int t8, t7;
3319 if (tag == OPS_PTAG_SS_ALL) {
3320 int n;
3322 for (n = 0; n < 256; ++n) {
3323 __ops_stream_options(stream,
3324 OPS_PTAG_SIG_SUBPKT_BASE + n,
3325 type);
3327 return;
3329 if (tag < OPS_PTAG_SIG_SUBPKT_BASE ||
3330 tag > OPS_PTAG_SIG_SUBPKT_BASE + NTAGS - 1) {
3331 loggit("__ops_stream_options: bad tag");
3332 return;
3334 t8 = (tag - OPS_PTAG_SIG_SUBPKT_BASE) / 8;
3335 t7 = 1 << ((tag - OPS_PTAG_SIG_SUBPKT_BASE) & 7);
3336 switch (type) {
3337 case OPS_PARSE_RAW:
3338 stream->ss_raw[t8] |= t7;
3339 stream->ss_parsed[t8] &= ~t7;
3340 break;
3342 case OPS_PARSE_PARSED:
3343 stream->ss_raw[t8] &= ~t7;
3344 stream->ss_parsed[t8] |= t7;
3345 break;
3347 case OPS_PARSE_IGNORE:
3348 stream->ss_raw[t8] &= ~t7;
3349 stream->ss_parsed[t8] &= ~t7;
3350 break;
3355 \ingroup Core_ReadPackets
3356 \brief Free __ops_stream_t struct and its contents
3358 static void
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
3393 static unsigned
3394 rsa_verify(__ops_hash_alg_t type,
3395 const uint8_t *hash,
3396 size_t hash_length,
3397 const __ops_rsa_sig_t *sig,
3398 const __ops_rsa_pubkey_t *pubrsa)
3400 const uint8_t *prefix;
3401 unsigned n;
3402 unsigned keysize;
3403 unsigned plen;
3404 uint8_t sigbuf[NETPGP_BUFSIZ];
3405 uint8_t hashbuf_from_sig[NETPGP_BUFSIZ];
3407 plen = 0;
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");
3413 return 0;
3415 if ((unsigned) BN_num_bits(sig->sig) > 8 * sizeof(sigbuf)) {
3416 loggit("rsa_verify: BN_numbits too big");
3417 return 0;
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);
3424 if (n != keysize) {
3425 /* obviously, this includes error returns */
3426 return 0;
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) {
3432 return 0;
3435 switch (type) {
3436 case OPS_HASH_MD5:
3437 prefix = prefix_md5;
3438 plen = sizeof(prefix_md5);
3439 break;
3440 case OPS_HASH_SHA1:
3441 prefix = prefix_sha1;
3442 plen = sizeof(prefix_sha1);
3443 break;
3444 case OPS_HASH_SHA256:
3445 prefix = prefix_sha256;
3446 plen = sizeof(prefix_sha256);
3447 break;
3448 default:
3449 loggit("Unknown hash algorithm: %d", type);
3450 return 0;
3453 if (keysize - plen - hash_length < 10) {
3454 return 0;
3457 for (n = 2; n < keysize - plen - hash_length - 1; ++n) {
3458 if (hashbuf_from_sig[n] != 0xff) {
3459 return 0;
3463 if (hashbuf_from_sig[n++] != 0) {
3464 return 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
3480 static unsigned
3481 __ops_check_sig(const uint8_t *hash, unsigned length,
3482 const __ops_sig_t * sig,
3483 const __ops_pubkey_t * signer)
3485 unsigned ret;
3487 ret = 0;
3488 switch (sig->info.key_alg) {
3489 case OPS_PKA_DSA:
3490 ret = __ops_dsa_verify(hash, length, &sig->info.sig.dsa,
3491 &signer->key.dsa);
3492 break;
3493 case OPS_PKA_RSA:
3494 ret = rsa_verify(sig->info.hash_alg, hash, length,
3495 &sig->info.sig.rsa,
3496 &signer->key.rsa);
3497 break;
3498 default:
3499 loggit("__ops_check_sig: unusual alg");
3500 ret = 0;
3502 return ret;
3507 * return 1 if OK, otherwise 0
3509 static unsigned
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
3518 * \param src
3519 * \param len
3520 * \param output
3521 * \return 1 if OK, otherwise 0
3524 static unsigned
3525 __ops_write(__ops_output_t *output, const void *src, unsigned len)
3527 return base_write(src, len, output);
3531 * \ingroup Core_WritePackets
3532 * \param n
3533 * \param len
3534 * \param output
3535 * \return 1 if OK, otherwise 0
3537 static unsigned
3538 __ops_write_scalar(__ops_output_t *output, unsigned n, unsigned len)
3540 uint8_t c;
3542 while (len-- > 0) {
3543 c = n >> (len * 8);
3544 if (!base_write(&c, 1, output)) {
3545 return 0;
3548 return 1;
3552 * \ingroup Core_WritePackets
3553 * \param bn
3554 * \param output
3555 * \return 1 if OK, otherwise 0
3558 static unsigned
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);
3564 if (bits > 65535) {
3565 loggit("__ops_write_mpi: too large %u", bits);
3566 return 0;
3568 BN_bn2bin(bn, buf);
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
3577 static unsigned
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))) {
3582 return 0;
3584 if (key->version != 4 &&
3585 !__ops_write_scalar(output, key->days_valid, 2)) {
3586 return 0;
3588 if (!__ops_write_scalar(output, (unsigned)key->alg, 1)) {
3589 return 0;
3591 switch (key->alg) {
3592 case OPS_PKA_DSA:
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);
3598 case OPS_PKA_RSA:
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);
3608 default:
3609 loggit("write_pubkey_body: bad algorithm");
3610 break;
3612 return 0;
3615 static unsigned
3616 memory_writer(__ops_writer_t *writer,
3617 const uint8_t *src,
3618 unsigned len,
3619 __ops_error_t **errors)
3621 __ops_memory_t *mem;
3623 __OPS_USED(errors);
3624 mem = writer->arg;
3625 __ops_memory_add(mem, src, len);
3626 return 1;
3630 * \ingroup Core_Writers
3632 * Set a writer in output. There should not be another writer set.
3634 * \param output The output structure
3635 * \param writer
3636 * \param finaliser
3637 * \param destroyer
3638 * \param arg The argument for the writer and destroyer
3640 static void
3641 __ops_writer_set(__ops_output_t *output,
3642 unsigned (*writer)(__ops_writer_t *, const uint8_t *, unsigned,
3643 __ops_error_t **),
3644 unsigned (*finaliser)(__ops_error_t **, __ops_writer_t *),
3645 void (*destroyer)(__ops_writer_t *),
3646 void *arg)
3648 if (output->writer.writer) {
3649 loggit("__ops_writer_set: already set");
3650 } else {
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()
3670 static void
3671 __ops_writer_set_memory(__ops_output_t *output, __ops_memory_t *mem)
3673 __ops_writer_set(output, memory_writer, NULL, NULL, mem);
3676 static void
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");
3682 return;
3684 if (writer->next) {
3685 writer_info_delete(writer->next);
3686 free(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.
3705 static void
3706 __ops_output_delete(__ops_output_t *output)
3708 writer_info_delete(&output->writer);
3709 (void) free(output);
3714 * \ingroup Core_Create
3715 * \param out
3716 * \param key
3717 * \param make_packet
3719 static void
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"},
3756 {0x00, NULL}
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)"},
3769 {0x00, NULL}
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
3778 static unsigned
3779 __ops_is_sa_supported(__ops_symm_alg_t alg)
3781 switch (alg) {
3782 case OPS_SA_AES_128:
3783 case OPS_SA_AES_256:
3784 case OPS_SA_CAST5:
3785 case OPS_SA_TRIPLEDES:
3786 #ifndef OPENSSL_NO_IDEA
3787 case OPS_SA_IDEA:
3788 #endif
3789 return 1;
3791 default:
3792 loggit("\nWarning: %s not supported",
3793 findtype((int) alg, symm_alg_map));
3794 return 0;
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
3805 static unsigned
3806 __ops_calc_sesskey_checksum(__ops_pk_sesskey_t *sesskey, uint8_t *cs)
3808 unsigned int i = 0;
3809 unsigned long checksum = 0;
3811 if (!__ops_is_sa_supported(sesskey->symm_alg)) {
3812 return 0;
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);
3823 return 1;
3826 static void
3827 std_set_iv(__ops_crypt_t *cryp, const uint8_t *iv)
3829 (void) memcpy(cryp->iv, iv, cryp->blocksize);
3830 cryp->num = 0;
3833 static void
3834 std_set_key(__ops_crypt_t *cryp, const uint8_t *key)
3836 (void) memcpy(cryp->key, key, cryp->keysize);
3839 static void
3840 std_resync(__ops_crypt_t *decrypt)
3842 if ((size_t) decrypt->num == decrypt->blocksize) {
3843 return;
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);
3849 decrypt->num = 0;
3852 static void
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;
3865 static void
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);
3877 static void
3878 cast5_block_encrypt(__ops_crypt_t *cryp, void *out, const void *in)
3880 CAST_ecb_encrypt(in, out, cryp->encrypt_key, CAST_ENCRYPT);
3883 static void
3884 cast5_block_decrypt(__ops_crypt_t *cryp, void *out, const void *in)
3886 CAST_ecb_encrypt(in, out, cryp->encrypt_key, CAST_DECRYPT);
3889 static void
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,
3894 CAST_ENCRYPT);
3897 static void
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,
3902 CAST_DECRYPT);
3905 #define TRAILER "","","","",0,NULL,NULL
3907 static __ops_crypt_t cast5 =
3909 OPS_SA_CAST5,
3910 CAST_BLOCK,
3911 CAST_KEY_LENGTH,
3912 std_set_iv,
3913 std_set_key,
3914 cast5_init,
3915 std_resync,
3916 cast5_block_encrypt,
3917 cast5_block_decrypt,
3918 cast5_cfb_encrypt,
3919 cast5_cfb_decrypt,
3920 std_finish,
3921 TRAILER
3924 #ifndef OPENSSL_NO_IDEA
3925 static void
3926 idea_init(__ops_crypt_t *cryp)
3928 if (cryp->keysize != IDEA_KEY_LENGTH) {
3929 loggit("idea_init: keysize wrong");
3930 return;
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);
3949 static void
3950 idea_block_encrypt(__ops_crypt_t *cryp, void *out, const void *in)
3952 idea_ecb_encrypt(in, out, cryp->encrypt_key);
3955 static void
3956 idea_block_decrypt(__ops_crypt_t *cryp, void *out, const void *in)
3958 idea_ecb_encrypt(in, out, cryp->decrypt_key);
3961 static void
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,
3966 CAST_ENCRYPT);
3969 static void
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,
3974 CAST_DECRYPT);
3977 static const __ops_crypt_t idea =
3979 OPS_SA_IDEA,
3980 IDEA_BLOCK,
3981 IDEA_KEY_LENGTH,
3982 std_set_iv,
3983 std_set_key,
3984 idea_init,
3985 std_resync,
3986 idea_block_encrypt,
3987 idea_block_decrypt,
3988 idea_cfb_encrypt,
3989 idea_cfb_decrypt,
3990 std_finish,
3991 TRAILER
3993 #endif /* OPENSSL_NO_IDEA */
3995 /* AES with 128-bit key (AES) */
3997 #define KEYBITS_AES128 128
3999 static void
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");
4021 static void
4022 aes_block_encrypt(__ops_crypt_t *cryp, void *out, const void *in)
4024 AES_encrypt(in, out, cryp->encrypt_key);
4027 static void
4028 aes_block_decrypt(__ops_crypt_t *cryp, void *out, const void *in)
4030 AES_decrypt(in, out, cryp->decrypt_key);
4033 static void
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,
4038 AES_ENCRYPT);
4041 static void
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,
4046 AES_DECRYPT);
4049 static const __ops_crypt_t aes128 =
4051 OPS_SA_AES_128,
4052 AES_BLOCK_SIZE,
4053 KEYBITS_AES128 / 8,
4054 std_set_iv,
4055 std_set_key,
4056 aes128_init,
4057 std_resync,
4058 aes_block_encrypt,
4059 aes_block_decrypt,
4060 aes_cfb_encrypt,
4061 aes_cfb_decrypt,
4062 std_finish,
4063 TRAILER
4066 /* AES with 256-bit key */
4068 #define KEYBITS_AES256 256
4070 static void
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 =
4093 OPS_SA_AES_256,
4094 AES_BLOCK_SIZE,
4095 KEYBITS_AES256 / 8,
4096 std_set_iv,
4097 std_set_key,
4098 aes256_init,
4099 std_resync,
4100 aes_block_encrypt,
4101 aes_block_decrypt,
4102 aes_cfb_encrypt,
4103 aes_cfb_decrypt,
4104 std_finish,
4105 TRAILER
4108 /* Triple DES */
4110 static void
4111 tripledes_init(__ops_crypt_t *cryp)
4113 DES_key_schedule *keys;
4114 int n;
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),
4123 &keys[n]);
4127 static void
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],
4133 DES_ENCRYPT);
4136 static void
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],
4142 DES_DECRYPT);
4145 static void
4146 tripledes_cfb_encrypt(__ops_crypt_t *cryp, void *out, const void *in,
4147 size_t count)
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);
4156 static void
4157 tripledes_cfb_decrypt(__ops_crypt_t *cryp, void *out, const void *in,
4158 size_t count)
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 =
4169 OPS_SA_TRIPLEDES,
4172 std_set_iv,
4173 std_set_key,
4174 tripledes_init,
4175 std_resync,
4176 tripledes_block_encrypt,
4177 tripledes_block_decrypt,
4178 tripledes_cfb_encrypt,
4179 tripledes_cfb_decrypt,
4180 std_finish,
4181 TRAILER
4184 static const __ops_crypt_t *
4185 get_proto(__ops_symm_alg_t alg)
4187 switch (alg) {
4188 case OPS_SA_CAST5:
4189 return &cast5;
4191 #ifndef OPENSSL_NO_IDEA
4192 case OPS_SA_IDEA:
4193 return &idea;
4194 #endif /* OPENSSL_NO_IDEA */
4196 case OPS_SA_AES_128:
4197 return &aes128;
4199 case OPS_SA_AES_256:
4200 return &aes256;
4202 case OPS_SA_TRIPLEDES:
4203 return &tripledes;
4205 default:
4206 loggit("Unknown algorithm: %d (%s)",
4207 alg,
4208 findtype((int) alg, symm_alg_map));
4211 return NULL;
4214 static unsigned
4215 __ops_key_size(__ops_symm_alg_t alg)
4217 const __ops_crypt_t *p;
4219 p = get_proto(alg);
4220 return (p == NULL) ? 0 : p->keysize;
4223 static int
4224 __ops_crypt_any(__ops_crypt_t *cryp, __ops_symm_alg_t alg)
4226 const __ops_crypt_t *ptr = get_proto(alg);
4228 if (ptr) {
4229 *cryp = *ptr;
4230 return 1;
4231 } else {
4232 (void) memset(cryp, 0x0, sizeof(*cryp));
4233 return 0;
4237 static unsigned
4238 __ops_block_size(__ops_symm_alg_t alg)
4240 const __ops_crypt_t *p;
4242 p = get_proto(alg);
4243 return (p == NULL) ? 0 : p->blocksize;
4246 static void
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);
4252 decrypt->num = 0;
4255 static void
4256 __ops_encrypt_init(__ops_crypt_t *encryp)
4258 /* \todo should there be a separate __ops_encrypt_init? */
4259 __ops_decrypt_init(encryp);
4263 static size_t
4264 __ops_decrypt_se_ip(__ops_crypt_t *cryp, void *out, const void *in,
4265 size_t count)
4267 if (!__ops_is_sa_supported(cryp->alg)) {
4268 return 0;
4270 cryp->cfb_decrypt(cryp, out, in, count);
4271 /* \todo check this number was in fact decrypted */
4272 return count;
4276 /**************************************************************************/
4279 #define DECOMPRESS_BUFFER 1024
4281 typedef struct {
4282 __ops_ztype_t type;
4283 __ops_region_t *region;
4284 uint8_t in[DECOMPRESS_BUFFER];
4285 uint8_t out[DECOMPRESS_BUFFER];
4286 z_stream zstream;/* ZIP and ZLIB */
4287 size_t offset;
4288 int inflate_ret;
4289 } z_decompress_t;
4291 typedef struct {
4292 __ops_ztype_t type;
4293 __ops_region_t *region;
4294 char in[DECOMPRESS_BUFFER];
4295 char out[DECOMPRESS_BUFFER];
4296 bz_stream bzstream; /* BZIP2 */
4297 size_t offset;
4298 int inflate_ret;
4299 } bz_decompress_t;
4301 typedef struct {
4302 z_stream stream;
4303 uint8_t *src;
4304 uint8_t *dst;
4305 } compress_t;
4307 static unsigned __ops_stacked_limited_read(uint8_t *, unsigned,
4308 __ops_region_t *,
4309 __ops_error_t **,
4310 __ops_reader_t *,
4311 __ops_cbdata_t *);
4314 * \todo remove code duplication between this and
4315 * bzip2_compressed_data_reader
4317 static int
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;
4324 size_t len;
4325 size_t cc;
4326 char *cdest = dest;
4328 if (z->type != OPS_C_ZIP && z->type != OPS_C_ZLIB) {
4329 loggit("zlib_compressed_data_reader: weird type %d",
4330 z->type);
4331 return 0;
4334 if (z->inflate_ret == Z_STREAM_END &&
4335 z->zstream.next_out == &z->out[z->offset]) {
4336 return 0;
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) {
4347 int ret;
4349 z->zstream.next_out = z->out;
4350 z->zstream.avail_out = sizeof(z->out);
4351 z->offset = 0;
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)) {
4358 n = sizeof(z->in);
4360 } else {
4361 n = sizeof(z->in);
4363 if (!__ops_stacked_limited_read(z->in, n,
4364 z->region,
4365 errors, readinfo, cbdata)) {
4366 return -1;
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");
4390 return 0;
4392 len = z->zstream.next_out - &z->out[z->offset];
4393 if (len > length) {
4394 len = length;
4396 (void) memcpy(&cdest[cc], &z->out[z->offset], len);
4397 z->offset += len;
4400 return length;
4403 /* \todo remove code duplication between this and zlib_compressed_data_reader */
4404 static int
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;
4411 size_t len;
4412 size_t cc;
4413 char *cdest = dest;
4415 if (bz->type != OPS_C_BZIP2) {
4416 loggit("Weird type %d", bz->type);
4417 return 0;
4420 if (bz->inflate_ret == BZ_STREAM_END &&
4421 bz->bzstream.next_out == &bz->out[bz->offset]) {
4422 return 0;
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) {
4432 int ret;
4434 bz->bzstream.next_out = (char *) bz->out;
4435 bz->bzstream.avail_out = sizeof(bz->out);
4436 bz->offset = 0;
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))
4443 n = sizeof(bz->in);
4444 } else
4445 n = sizeof(bz->in);
4447 if (!__ops_stacked_limited_read(
4448 (uint8_t *) bz->in,
4449 n, bz->region,
4450 errors, readinfo, cbdata))
4451 return -1;
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");
4474 return 0;
4476 len = bz->bzstream.next_out - &bz->out[bz->offset];
4477 if (len > length) {
4478 len = length;
4480 (void) memcpy(&cdest[cc], &bz->out[bz->offset], len);
4481 bz->offset += len;
4484 return length;
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
4495 static int
4496 __ops_decompress(__ops_region_t *region, __ops_stream_t *stream,
4497 __ops_ztype_t ztype)
4499 z_decompress_t z;
4500 bz_decompress_t bz;
4501 const int printerrors = 1;
4502 int ret;
4504 switch (ztype) {
4505 case OPS_C_ZIP:
4506 case OPS_C_ZLIB:
4507 (void) memset(&z, 0x0, sizeof(z));
4509 z.region = region;
4510 z.offset = 0;
4511 z.type = ztype;
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;
4520 break;
4522 case OPS_C_BZIP2:
4523 (void) memset(&bz, 0x0, sizeof(bz));
4525 bz.region = region;
4526 bz.offset = 0;
4527 bz.type = ztype;
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;
4536 break;
4538 default:
4539 OPS_ERROR_1(&stream->errors,
4540 OPS_E_ALG_UNSUPPORTED_COMPRESS_ALG,
4541 "Compression algorithm %d is not yet supported", ztype);
4542 return 0;
4545 switch (ztype) {
4546 case OPS_C_ZIP:
4547 ret = inflateInit2(&z.zstream, -15);
4548 break;
4550 case OPS_C_ZLIB:
4551 ret = inflateInit(&z.zstream);
4552 break;
4554 case OPS_C_BZIP2:
4555 ret = BZ2_bzDecompressInit(&bz.bzstream, 1, 0);
4556 break;
4558 default:
4559 OPS_ERROR_1(&stream->errors,
4560 OPS_E_ALG_UNSUPPORTED_COMPRESS_ALG,
4561 "Compression algorithm %d is not yet supported", ztype);
4562 return 0;
4565 switch (ztype) {
4566 case OPS_C_ZIP:
4567 case OPS_C_ZLIB:
4568 if (ret != Z_OK) {
4569 OPS_ERROR_1(&stream->errors,
4570 OPS_E_P_DECOMPRESSION_ERROR,
4571 "Cannot initialise ZIP or ZLIB stream for decompression: error=%d", ret);
4572 return 0;
4574 __ops_reader_push(stream, zlib_compressed_data_reader,
4575 NULL, &z);
4576 break;
4578 case OPS_C_BZIP2:
4579 if (ret != BZ_OK) {
4580 OPS_ERROR_1(&stream->errors,
4581 OPS_E_P_DECOMPRESSION_ERROR,
4582 "Cannot initialise BZIP2 stream for decompression: error=%d", ret);
4583 return 0;
4585 __ops_reader_push(stream, bzip2_compressed_data_reader,
4586 NULL, &bz);
4587 break;
4589 default:
4590 OPS_ERROR_1(&stream->errors,
4591 OPS_E_ALG_UNSUPPORTED_COMPRESS_ALG,
4592 "Compression algorithm %d is not yet supported", ztype);
4593 return 0;
4596 ret = __ops_parse(stream, !printerrors);
4598 __ops_reader_pop(stream);
4600 return ret;
4603 /**************************************************************************/
4605 #define CALLBACK(t, cbdata, pkt) do { \
4606 (pkt)->tag = (t); \
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); \
4615 return 0; \
4616 /*NOTREACHED*/ \
4617 } while(/*CONSTCOND*/0)
4619 static unsigned __ops_limited_read(uint8_t *,
4620 size_t,
4621 __ops_region_t *,
4622 __ops_error_t **,
4623 __ops_reader_t *,
4624 __ops_cbdata_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
4632 * \param subregion
4633 * \param stream How to parse
4635 * \return 1 on success, 0 on failure
4637 static int
4638 limread_data(__ops_data_t *data, unsigned int len,
4639 __ops_region_t *subregion, __ops_stream_t *stream)
4641 data->len = len;
4643 if (subregion->length - subregion->readc < len) {
4644 loggit("limread_data: bad length");
4645 return 0;
4648 data->contents = __ops_new(data->len);
4649 if (!data->contents) {
4650 return 0;
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
4661 * \param data
4662 * \param subregion
4663 * \param stream
4665 * \return 1 on success, 0 on failure
4667 static int
4668 read_data(__ops_data_t *data, __ops_region_t *region, __ops_stream_t *stream)
4670 int cc;
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.
4681 static int
4682 read_unsig_str(uint8_t **str, __ops_region_t *subregion,
4683 __ops_stream_t *stream)
4685 size_t len = 0;
4687 len = subregion->length - subregion->readc;
4688 if ((*str = __ops_new(len + 1)) == NULL) {
4689 return 0;
4691 if (len &&
4692 !__ops_limited_read(*str, len, subregion, &stream->errors,
4693 &stream->readinfo, &stream->cbdata)) {
4694 return 0;
4696 /* ! ensure the string is NULL-terminated */
4697 (*str)[len] = '\0';
4698 return 1;
4701 static int
4702 read_string(char **str, __ops_region_t *subregion, __ops_stream_t *stream)
4704 return read_unsig_str((uint8_t **) str, subregion, stream);
4707 static void
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
4719 static size_t
4720 full_read(uint8_t *dest,
4721 size_t length,
4722 int *lastread,
4723 __ops_error_t **errors,
4724 __ops_reader_t *readinfo,
4725 __ops_cbdata_t *cbdata)
4727 size_t t;
4728 int r = 0; /* preset in case some loon calls with length
4729 * == 0 */
4731 for (t = 0; t < length;) {
4732 r = sub_base_read(dest + t, length - t, errors, readinfo,
4733 cbdata);
4734 if (r <= 0) {
4735 *lastread = r;
4736 return t;
4738 t += r;
4741 *lastread = r;
4743 return t;
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
4760 static unsigned
4761 read_scalar(unsigned *result, unsigned length,
4762 __ops_stream_t *stream)
4764 unsigned t = 0;
4766 if (length > sizeof(*result)) {
4767 loggit("read_scalar: bad length");
4768 return 0;
4771 while (length--) {
4772 uint8_t c;
4773 int r;
4775 r = sub_base_read(&c, 1, &stream->errors, &stream->readinfo,
4776 &stream->cbdata);
4777 if (r != 1)
4778 return 0;
4779 t = (t << 8) + c;
4782 *result = t;
4783 return 1;
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
4812 static unsigned
4813 __ops_limited_read(uint8_t *dest,
4814 size_t length,
4815 __ops_region_t *region,
4816 __ops_error_t **errors,
4817 __ops_reader_t *readinfo,
4818 __ops_cbdata_t *cbdata)
4820 size_t r;
4821 int lr;
4823 if (!region->indeterm &&
4824 region->readc + length > region->length) {
4825 OPS_ERROR(errors, OPS_E_P_NOT_ENOUGH_DATA, "Not enough data");
4826 return 0;
4828 r = full_read(dest, length, &lr, errors, readinfo, cbdata);
4829 if (lr < 0) {
4830 OPS_ERROR(errors, OPS_E_R_READ_FAILED, "Read failed");
4831 return 0;
4833 if (!region->indeterm && r != length) {
4834 OPS_ERROR(errors, OPS_E_R_READ_FAILED, "Read failed");
4835 return 0;
4837 region->lastread = r;
4838 do {
4839 region->readc += r;
4840 if (region->parent && region->length > region->parent->length) {
4841 loggit("ops_limited_read: bad length");
4842 return 0;
4844 } while ((region = region->parent) != NULL);
4845 return 1;
4849 \ingroup Core_ReadPackets
4850 \brief Call __ops_limited_read on next in stack
4852 static unsigned
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);
4863 static unsigned
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);
4871 static unsigned
4872 exact_limread(uint8_t *dest, unsigned len,
4873 __ops_region_t *region,
4874 __ops_stream_t *stream)
4876 unsigned ret;
4878 stream->exact_read = 1;
4879 ret = limread(dest, len, region, stream);
4880 stream->exact_read = 0;
4881 return ret;
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()).
4895 static int
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)) {
4904 return 0;
4906 length -= n;
4908 return 1;
4911 /** Read a scalar.
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()).
4925 * \see RFC4880 3.1
4927 static int
4928 limread_scalar(unsigned *dest,
4929 unsigned len,
4930 __ops_region_t *region,
4931 __ops_stream_t *stream)
4933 uint8_t c[4] = "";
4934 unsigned t;
4935 unsigned n;
4937 if (len > 4) {
4938 loggit("limread_scalar: bad length");
4939 return 0;
4941 /*LINTED*/
4942 if (/*CONSTCOND*/sizeof(*dest) < 4) {
4943 loggit("limread_scalar: bad dest");
4944 return 0;
4946 if (!limread(c, len, region, stream)) {
4947 return 0;
4949 for (t = 0, n = 0; n < len; ++n) {
4950 t = (t << 8) + c[n];
4952 *dest = t;
4953 return 1;
4956 /** Read a scalar.
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()).
4973 * \see RFC4880 3.1
4975 static int
4976 limread_size_t(size_t *dest,
4977 unsigned length,
4978 __ops_region_t *region,
4979 __ops_stream_t *stream)
4981 unsigned tmp;
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)) {
4988 return 0;
4990 *dest = tmp;
4991 return 1;
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()
5009 * \see RFC4880 3.5
5011 static int
5012 limited_read_time(time_t *dest, __ops_region_t *region, __ops_stream_t *stream)
5014 uint8_t c;
5015 time_t mytime = 0;
5016 int i = 0;
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,
5024 stream);
5026 for (i = 0; i < 4; i++) {
5027 if (!limread(&c, 1, region, stream)) {
5028 return 0;
5030 mytime = (mytime << 8) + c;
5032 *dest = mytime;
5033 return 1;
5037 * \ingroup Core_MPI
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)
5058 * \see RFC4880 3.2
5060 static int
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. */
5068 unsigned length;
5069 unsigned nonzero;
5070 unsigned ret;
5072 stream->reading_mpi_len = 1;
5073 ret = limread_scalar(&length, 2, region, stream);
5075 stream->reading_mpi_len = 0;
5076 if (!ret) {
5077 return 0;
5080 nonzero = length & 7; /* there should be this many zero bits in the
5081 * MS byte */
5082 if (!nonzero) {
5083 nonzero = 8;
5085 length = (length + 7) / 8;
5087 if (length == 0) {
5088 /* if we try to read a length of 0, then fail */
5089 return 0;
5091 if (length > NETPGP_BUFSIZ) {
5092 loggit("limread_mpi: bad length");
5093 return 0;
5095 if (!limread(buf, length, region, stream)) {
5096 return 0;
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
5104 * not apply to
5105 * encrypted MPIs the
5106 * draft says. -- peter */
5107 return 0;
5109 *pbn = BN_bin2bn(buf, (int)length, NULL);
5110 return 1;
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
5123 static unsigned
5124 read_new_length(unsigned *length, __ops_stream_t *stream)
5126 uint8_t c;
5128 if (sub_base_read(&c, 1, &stream->errors, &stream->readinfo,
5129 &stream->cbdata) != 1) {
5130 return 0;
5132 if (c < 192) {
5133 /* 1. One-octet packet */
5134 *length = c;
5135 return 1;
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) {
5143 return 0;
5145 *length = t + c + 192;
5146 return 1;
5148 if (c == 255) {
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");
5157 return 0;
5159 return 0;
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
5177 * \see __ops_ptag_t
5179 static int
5180 limited_read_new_length(unsigned *length, __ops_region_t *region,
5181 __ops_stream_t *stream)
5183 uint8_t c = 0x0;
5185 if (!limread(&c, 1, region, stream)) {
5186 return 0;
5188 if (c < 192) {
5189 *length = c;
5190 return 1;
5192 if (c < 255) {
5193 unsigned t = (c - 192) << 8;
5195 if (!limread(&c, 1, region, stream)) {
5196 return 0;
5198 *length = t + c + 192;
5199 return 1;
5201 return limread_scalar(length, 4, region, stream);
5205 \ingroup Core_Create
5206 \brief Free allocated memory
5208 static void
5209 data_free(__ops_data_t *data)
5211 (void) free(data->contents);
5212 data->contents = NULL;
5213 data->len = 0;
5217 \ingroup Core_Create
5218 \brief Free allocated memory
5220 static void
5221 string_free(char **str)
5223 (void) free(*str);
5224 *str = NULL;
5228 \ingroup Core_Create
5229 \brief Free allocated memory
5231 /* ! Free packet memory, set pointer to NULL */
5232 static void
5233 __ops_subpacket_free(__ops_subpacket_t *packet)
5235 (void) free(packet->raw);
5236 packet->raw = NULL;
5240 \ingroup Core_Create
5241 \brief Free allocated memory
5243 static void
5244 __ops_headers_free(__ops_headers_t *headers)
5246 unsigned n;
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
5260 static void
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
5271 static void
5272 __ops_cmd_get_passphrase_free(__ops_seckey_passphrase_t *seckey)
5274 unsigned len;
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
5288 static void
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
5298 static void
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
5308 static void
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
5319 static void
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
5329 static void
5330 free_BN(BIGNUM **pp)
5332 BN_free(*pp);
5333 *pp = NULL;
5337 * \ingroup Core_Create
5338 * \brief Free the memory used when parsing a signature
5339 * \param sig
5341 static void
5342 sig_free(__ops_sig_t *sig)
5344 switch (sig->info.key_alg) {
5345 case OPS_PKA_RSA:
5346 case OPS_PKA_RSA_SIGN_ONLY:
5347 free_BN(&sig->info.sig.rsa.sig);
5348 break;
5350 case OPS_PKA_DSA:
5351 free_BN(&sig->info.sig.dsa.r);
5352 free_BN(&sig->info.sig.dsa.s);
5353 break;
5355 case OPS_PKA_ELGAMAL_ENCRYPT_OR_SIGN:
5356 free_BN(&sig->info.sig.elgamal.r);
5357 free_BN(&sig->info.sig.elgamal.s);
5358 break;
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);
5372 break;
5374 default:
5375 loggit("sig_free: bad sig type");
5380 \ingroup Core_Create
5381 \brief Free the memory used when parsing this signature sub-packet type
5382 \param ss_skapref
5384 static void
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
5393 \param ss_hashpref
5395 static void
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
5405 static void
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
5415 static void
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
5425 static void
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
5435 static void
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
5445 static void
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 */
5457 static void
5458 ss_regexp_free(__ops_ss_regexp_t *regexp)
5460 string_free(&regexp->regexp);
5464 \ingroup Core_Create
5465 \brief Free allocated memory
5467 /* ! Free the memory used when parsing this signature sub-packet type */
5468 static void
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 */
5479 static void
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
5489 static void
5490 ss_revocation_free(__ops_ss_revocation_t *ss_revocation)
5492 string_free(&ss_revocation->reason);
5495 static void
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
5505 static void
5506 __ops_pk_sesskey_free(__ops_pk_sesskey_t *sk)
5508 switch (sk->alg) {
5509 case OPS_PKA_RSA:
5510 free_BN(&sk->params.rsa.encrypted_m);
5511 break;
5513 case OPS_PKA_ELGAMAL:
5514 free_BN(&sk->params.elgamal.g_to_k);
5515 free_BN(&sk->params.elgamal.encrypted_m);
5516 break;
5518 default:
5519 loggit("__ops_pk_sesskey_free: bad alg");
5520 break;
5525 \ingroup Core_Create
5526 \brief Free allocated memory
5528 /* ! Free the memory used when parsing a public key */
5529 static void
5530 __ops_pubkey_free(__ops_pubkey_t *p)
5532 switch (p->alg) {
5533 case OPS_PKA_RSA:
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);
5538 break;
5540 case OPS_PKA_DSA:
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);
5545 break;
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);
5552 break;
5554 case 0:
5555 /* nothing to free */
5556 break;
5558 default:
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 */
5569 static void
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 */
5580 static void
5581 __ops_userid_free(__ops_userid_t *id)
5583 (void) free(id->userid);
5584 id->userid = NULL;
5588 * \ingroup Core_Create
5590 * __ops_seckey_free() frees the memory associated with "key". Note that
5591 * the key itself is not freed.
5593 * \param key
5596 static void
5597 __ops_seckey_free(__ops_seckey_t *key)
5599 switch (key->pubkey.alg) {
5600 case OPS_PKA_RSA:
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);
5607 break;
5609 case OPS_PKA_DSA:
5610 free_BN(&key->key.dsa.x);
5611 break;
5613 default:
5614 loggit("__ops_seckey_free: Unknown algorithm: %d (%s)",
5615 key->pubkey.alg,
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 */
5627 static void
5628 __ops_pkt_free(__ops_packet_t *c)
5630 switch (c->tag) {
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:
5653 break;
5655 case OPS_PTAG_CT_SIGNED_CLEARTEXT_HEADER:
5656 __ops_headers_free(&c->u.cleartext_head.headers);
5657 break;
5659 case OPS_PTAG_CT_ARMOUR_HEADER:
5660 __ops_headers_free(&c->u.armour_header.headers);
5661 break;
5663 case OPS_PTAG_CT_SIGNED_CLEARTEXT_TRAILER:
5664 cleartext_trailer_free(&c->u.cleartext_trailer);
5665 break;
5667 case OPS_PTAG_CT_TRUST:
5668 trust_free(&c->u.trust);
5669 break;
5671 case OPS_PTAG_CT_SIGNATURE:
5672 case OPS_PTAG_CT_SIGNATURE_FOOTER:
5673 sig_free(&c->u.sig);
5674 break;
5676 case OPS_PTAG_CT_PUBLIC_KEY:
5677 case OPS_PTAG_CT_PUBLIC_SUBKEY:
5678 __ops_pubkey_free(&c->u.pubkey);
5679 break;
5681 case OPS_PTAG_CT_USER_ID:
5682 __ops_userid_free(&c->u.userid);
5683 break;
5685 case OPS_PTAG_SS_SIGNERS_USER_ID:
5686 __ops_userid_free(&c->u.ss_signer);
5687 break;
5689 case OPS_PTAG_CT_USER_ATTR:
5690 __ops_userattr_free(&c->u.userattr);
5691 break;
5693 case OPS_PTAG_SS_PREFERRED_SKA:
5694 ss_skapref_free(&c->u.ss_skapref);
5695 break;
5697 case OPS_PTAG_SS_PREFERRED_HASH:
5698 ss_hashpref_free(&c->u.ss_hashpref);
5699 break;
5701 case OPS_PTAG_SS_PREF_COMPRESS:
5702 ss_zpref_free(&c->u.ss_zpref);
5703 break;
5705 case OPS_PTAG_SS_KEY_FLAGS:
5706 ss_key_flags_free(&c->u.ss_key_flags);
5707 break;
5709 case OPS_PTAG_SS_KEYSERV_PREFS:
5710 ss_key_server_prefs_free(&c->u.ss_key_server_prefs);
5711 break;
5713 case OPS_PTAG_SS_FEATURES:
5714 ss_features_free(&c->u.ss_features);
5715 break;
5717 case OPS_PTAG_SS_NOTATION_DATA:
5718 ss_notation_free(&c->u.ss_notation);
5719 break;
5721 case OPS_PTAG_SS_REGEXP:
5722 ss_regexp_free(&c->u.ss_regexp);
5723 break;
5725 case OPS_PTAG_SS_POLICY_URI:
5726 ss_policy_free(&c->u.ss_policy);
5727 break;
5729 case OPS_PTAG_SS_PREF_KEYSERV:
5730 ss_keyserv_free(&c->u.ss_keyserv);
5731 break;
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);
5745 break;
5747 case OPS_PTAG_SS_RESERVED:
5748 ss_reserved_free(&c->u.ss_unknown);
5749 break;
5751 case OPS_PTAG_SS_REVOCATION_REASON:
5752 ss_revocation_free(&c->u.ss_revocation);
5753 break;
5755 case OPS_PTAG_SS_EMBEDDED_SIGNATURE:
5756 ss_embedded_sig_free(&c->u.ss_embedded_sig);
5757 break;
5759 case OPS_PARSER_PACKET_END:
5760 __ops_subpacket_free(&c->u.packet);
5761 break;
5763 case OPS_PARSER_ERROR:
5764 case OPS_PARSER_ERRCODE:
5765 break;
5767 case OPS_PTAG_CT_SECRET_KEY:
5768 case OPS_PTAG_CT_ENCRYPTED_SECRET_KEY:
5769 __ops_seckey_free(&c->u.seckey);
5770 break;
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);
5775 break;
5777 case OPS_GET_PASSPHRASE:
5778 __ops_cmd_get_passphrase_free(&c->u.skey_passphrase);
5779 break;
5781 default:
5782 loggit("Can't free %d (0x%x)", c->tag, c->tag);
5787 \ingroup Core_ReadPackets
5789 static int
5790 parse_pubkey_data(__ops_pubkey_t *key, __ops_region_t *region,
5791 __ops_stream_t *stream)
5793 uint8_t c = 0x0;
5795 if (region->readc != 0) {
5796 /* We should not have read anything so far */
5797 loggit("parse_pubkey_data: bad length");
5798 return 0;
5801 if (!limread(&c, 1, region, stream)) {
5802 return 0;
5804 key->version = c;
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);
5808 return 0;
5810 if (!limited_read_time(&key->birthtime, region, stream)) {
5811 return 0;
5814 key->days_valid = 0;
5815 if ((key->version == 2 || key->version == 3) &&
5816 !limread_scalar(&key->days_valid, 2, region, stream)) {
5817 return 0;
5820 if (!limread(&c, 1, region, stream)) {
5821 return 0;
5823 key->alg = c;
5825 switch (key->alg) {
5826 case OPS_PKA_DSA:
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)) {
5831 return 0;
5833 break;
5835 case OPS_PKA_RSA:
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)) {
5840 return 0;
5842 break;
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)) {
5849 return 0;
5851 break;
5853 default:
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));
5858 return 0;
5861 return 1;
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
5890 static int
5891 parse_pubkey(__ops_content_tag_t tag, __ops_region_t *region,
5892 __ops_stream_t *stream)
5894 __ops_packet_t pkt;
5896 if (!parse_pubkey_data(&pkt.u.pubkey, region, stream)) {
5897 return 0;
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);
5904 return 0;
5906 CALLBACK(tag, &stream->cbdata, &pkt);
5907 return 1;
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.
5918 static int
5919 parse_userattr(__ops_region_t *region, __ops_stream_t *stream)
5922 __ops_packet_t pkt;
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");
5931 return 0;
5933 if (!read_data(&pkt.u.userattr.data, region, stream)) {
5934 return 0;
5936 CALLBACK(OPS_PTAG_CT_USER_ATTR, &stream->cbdata, &pkt);
5937 return 1;
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
5957 * \see RFC4880 5.11
5959 static int
5960 parse_userid(__ops_region_t *region, __ops_stream_t *stream)
5962 __ops_packet_t pkt;
5964 if (region->readc != 0) {
5965 /* We should not have read anything so far */
5966 loggit("parse_userid: bad length");
5967 return 0;
5969 pkt.u.userid.userid = __ops_new(region->length + 1);
5970 if (region->length &&
5971 !limread(pkt.u.userid.userid, region->length, region, stream)) {
5972 return 0;
5974 pkt.u.userid.userid[region->length] = '\0';
5975 CALLBACK(OPS_PTAG_CT_USER_ID, &stream->cbdata, &pkt);
5976 return 1;
5979 static __ops_hash_t *
5980 parse_hash_find(__ops_stream_t *stream, const uint8_t *keyid)
5982 __ops_hashtype_t *hp;
5983 size_t n;
5985 for (n = 0, hp = stream->hashes; n < stream->hashc; n++, hp++) {
5986 if (memcmp(hp->keyid, keyid, OPS_KEY_ID_SIZE) == 0) {
5987 return &hp->hash;
5990 return NULL;
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
6008 static int
6009 parse_v3_sig(__ops_region_t *region,
6010 __ops_stream_t *stream)
6012 __ops_packet_t pkt;
6013 uint8_t c = 0x0;
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)) {
6022 return 0;
6024 if (c != 5) {
6025 ERRP(&stream->cbdata, pkt, "bad hash info length");
6028 if (!limread(&c, 1, region, stream)) {
6029 return 0;
6031 pkt.u.sig.info.type = c;
6032 /* XXX: check signature type */
6034 if (!limited_read_time(&pkt.u.sig.info.birthtime, region, stream)) {
6035 return 0;
6037 pkt.u.sig.info.gotbirthtime = 1;
6039 if (!limread(pkt.u.sig.info.signer, OPS_KEY_ID_SIZE, region, stream)) {
6040 return 0;
6042 pkt.u.sig.info.gotsigner = 1;
6044 if (!limread(&c, 1, region, stream)) {
6045 return 0;
6047 pkt.u.sig.info.key_alg = c;
6048 /* XXX: check algorithm */
6050 if (!limread(&c, 1, region, stream)) {
6051 return 0;
6053 pkt.u.sig.info.hash_alg = c;
6054 /* XXX: check algorithm */
6056 if (!limread(pkt.u.sig.hash2, 2, region, stream)) {
6057 return 0;
6060 switch (pkt.u.sig.info.key_alg) {
6061 case OPS_PKA_RSA:
6062 case OPS_PKA_RSA_SIGN_ONLY:
6063 if (!limread_mpi(&pkt.u.sig.info.sig.rsa.sig, region, stream)) {
6064 return 0;
6066 break;
6068 case OPS_PKA_DSA:
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)) {
6071 return 0;
6073 break;
6075 case OPS_PKA_ELGAMAL_ENCRYPT_OR_SIGN:
6076 if (!limread_mpi(&pkt.u.sig.info.sig.elgamal.r, region,
6077 stream) ||
6078 !limread_mpi(&pkt.u.sig.info.sig.elgamal.s, region,
6079 stream)) {
6080 return 0;
6082 break;
6084 default:
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));
6089 return 0;
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);
6096 return 0;
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);
6102 return 1;
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
6123 static int
6124 parse_one_sig_subpacket(__ops_sig_t *sig,
6125 __ops_region_t *region,
6126 __ops_stream_t *stream)
6128 __ops_region_t subregion;
6129 __ops_packet_t pkt;
6130 uint8_t bools = 0x0;
6131 uint8_t c = 0x0;
6132 unsigned doread = 1;
6133 unsigned t8;
6134 unsigned t7;
6136 __ops_init_subregion(&subregion, region);
6137 if (!limited_read_new_length(&subregion.length, region, stream)) {
6138 return 0;
6141 if (subregion.length > region->length) {
6142 ERRP(&stream->cbdata, pkt, "Subpacket too long");
6145 if (!limread(&c, 1, &subregion, stream)) {
6146 return 0;
6149 t8 = (c & 0x7f) / 8;
6150 t7 = 1 << (c & 7);
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)) {
6162 return 0;
6164 CALLBACK(OPS_PTAG_RAW_SS, &stream->cbdata, &pkt);
6165 return 1;
6167 switch (pkt.tag) {
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))
6172 return 0;
6173 if (pkt.tag == OPS_PTAG_SS_CREATION_TIME) {
6174 sig->info.birthtime = pkt.u.ss_time.time;
6175 sig->info.gotbirthtime = 1;
6177 break;
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)) {
6182 return 0;
6184 break;
6186 case OPS_PTAG_SS_REVOCABLE:
6187 if (!limread(&bools, 1, &subregion, stream)) {
6188 return 0;
6190 pkt.u.ss_revocable.revocable = !!bools;
6191 break;
6193 case OPS_PTAG_SS_ISSUER_KEY_ID:
6194 if (!limread(pkt.u.ss_issuer.keyid, OPS_KEY_ID_SIZE,
6195 &subregion, stream)) {
6196 return 0;
6198 (void) memcpy(sig->info.signer, pkt.u.ss_issuer.keyid,
6199 OPS_KEY_ID_SIZE);
6200 sig->info.gotsigner = 1;
6201 break;
6203 case OPS_PTAG_SS_PREFERRED_SKA:
6204 if (!read_data(&pkt.u.ss_skapref.data, &subregion, stream)) {
6205 return 0;
6207 break;
6209 case OPS_PTAG_SS_PREFERRED_HASH:
6210 if (!read_data(&pkt.u.ss_hashpref.data, &subregion, stream)) {
6211 return 0;
6213 break;
6215 case OPS_PTAG_SS_PREF_COMPRESS:
6216 if (!read_data(&pkt.u.ss_zpref.data,
6217 &subregion, stream)) {
6218 return 0;
6220 break;
6222 case OPS_PTAG_SS_PRIMARY_USER_ID:
6223 if (!limread(&bools, 1, &subregion, stream)) {
6224 return 0;
6226 pkt.u.ss_primary_userid.primary_userid = !!bools;
6227 break;
6229 case OPS_PTAG_SS_KEY_FLAGS:
6230 if (!read_data(&pkt.u.ss_key_flags.data, &subregion, stream)) {
6231 return 0;
6233 break;
6235 case OPS_PTAG_SS_KEYSERV_PREFS:
6236 if (!read_data(&pkt.u.ss_key_server_prefs.data, &subregion,
6237 stream)) {
6238 return 0;
6240 break;
6242 case OPS_PTAG_SS_FEATURES:
6243 if (!read_data(&pkt.u.ss_features.data, &subregion, stream)) {
6244 return 0;
6246 break;
6248 case OPS_PTAG_SS_SIGNERS_USER_ID:
6249 if (!read_unsig_str(&pkt.u.ss_signer.userid, &subregion,
6250 stream)) {
6251 return 0;
6253 break;
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)) {
6258 return 0;
6260 break;
6262 case OPS_PTAG_SS_NOTATION_DATA:
6263 if (!limread_data(&pkt.u.ss_notation.flags, 4,
6264 &subregion, stream)) {
6265 return 0;
6267 if (!limread_size_t(&pkt.u.ss_notation.name.len, 2,
6268 &subregion, stream)) {
6269 return 0;
6271 if (!limread_size_t(&pkt.u.ss_notation.value.len, 2,
6272 &subregion, stream)) {
6273 return 0;
6275 if (!limread_data(&pkt.u.ss_notation.name,
6276 pkt.u.ss_notation.name.len,
6277 &subregion, stream)) {
6278 return 0;
6280 if (!limread_data(&pkt.u.ss_notation.value,
6281 pkt.u.ss_notation.value.len,
6282 &subregion, stream)) {
6283 return 0;
6285 break;
6287 case OPS_PTAG_SS_POLICY_URI:
6288 if (!read_string(&pkt.u.ss_policy.url, &subregion, stream)) {
6289 return 0;
6291 break;
6293 case OPS_PTAG_SS_REGEXP:
6294 if (!read_string(&pkt.u.ss_regexp.regexp, &subregion, stream)) {
6295 return 0;
6297 break;
6299 case OPS_PTAG_SS_PREF_KEYSERV:
6300 if (!read_string(&pkt.u.ss_keyserv.name, &subregion, stream)) {
6301 return 0;
6303 break;
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)) {
6317 return 0;
6319 break;
6321 case OPS_PTAG_SS_RESERVED:
6322 if (!read_data(&pkt.u.ss_unknown.data, &subregion, stream)) {
6323 return 0;
6325 break;
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)) {
6330 return 0;
6332 /* the rest is a human-readable UTF-8 string */
6333 if (!read_string(&pkt.u.ss_revocation.reason, &subregion,
6334 stream)) {
6335 return 0;
6337 break;
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)) {
6343 return 0;
6345 if (!(pkt.u.ss_revocation_key.class & 0x80)) {
6346 loggit("Warning: OPS_PTAG_SS_REVOCATION_KEY class: "
6347 "Bit 0x80 should be set");
6348 return 0;
6350 /* octet 1 = algid */
6351 if (!limread(&pkt.u.ss_revocation_key.algid, 1,
6352 &subregion, stream)) {
6353 return 0;
6355 /* octets 2-21 = fingerprint */
6356 if (!limread(&pkt.u.ss_revocation_key.fingerprint[0],
6357 OPS_FINGERPRINT_SIZE, &subregion, stream)) {
6358 return 0;
6360 break;
6362 default:
6363 if (stream->ss_parsed[t8] & t7) {
6364 OPS_ERROR_1(&stream->errors, OPS_E_PROTO_UNKNOWN_SS,
6365 "Unknown signature subpacket type (%d)",
6366 c & 0x7f);
6368 doread = 0;
6369 break;
6372 /* Application doesn't want it delivered parsed */
6373 if (!(stream->ss_parsed[t8] & t7)) {
6374 if (pkt.critical) {
6375 OPS_ERROR_1(&stream->errors,
6376 OPS_E_PROTO_CRITICAL_SS_IGNORED,
6377 "Critical signature subpacket ignored (%d)",
6378 c & 0x7f);
6380 if (!doread &&
6381 !limskip(subregion.length - 1, &subregion, stream)) {
6382 return 0;
6384 if (doread) {
6385 __ops_pkt_free(&pkt);
6387 return 1;
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);
6393 return 0;
6395 CALLBACK(pkt.tag, &stream->cbdata, &pkt);
6396 return 1;
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
6416 static int
6417 parse_sig_subpkts(__ops_sig_t *sig,
6418 __ops_region_t *region,
6419 __ops_stream_t *stream)
6421 __ops_region_t subregion;
6422 __ops_packet_t pkt;
6424 __ops_init_subregion(&subregion, region);
6425 if (!limread_scalar(&subregion.length, 2, region, stream)) {
6426 return 0;
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)) {
6435 return 0;
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");
6447 return 1;
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
6465 static int
6466 parse_v4_sig(__ops_region_t *region, __ops_stream_t *stream)
6468 uint8_t c = 0x0;
6469 __ops_packet_t pkt;
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
6476 * subpacket data
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)) {
6486 return 0;
6488 pkt.u.sig.info.type = c;
6489 /* XXX: check signature type */
6491 if (!limread(&c, 1, region, stream)) {
6492 return 0;
6494 pkt.u.sig.info.key_alg = c;
6495 /* XXX: check algorithm */
6496 if (!limread(&c, 1, region, stream)) {
6497 return 0;
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)) {
6504 return 0;
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");
6519 return 0;
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)) {
6526 return 0;
6529 if (!limread(pkt.u.sig.hash2, 2, region, stream)) {
6530 return 0;
6533 switch (pkt.u.sig.info.key_alg) {
6534 case OPS_PKA_RSA:
6535 if (!limread_mpi(&pkt.u.sig.info.sig.rsa.sig, region, stream)) {
6536 return 0;
6538 break;
6540 case OPS_PKA_DSA:
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
6546 return 0;
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");
6552 break;
6554 case OPS_PKA_ELGAMAL_ENCRYPT_OR_SIGN:
6555 if (!limread_mpi(&pkt.u.sig.info.sig.elgamal.r, region,
6556 stream) ||
6557 !limread_mpi(&pkt.u.sig.info.sig.elgamal.s, region,
6558 stream)) {
6559 return 0;
6561 break;
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,
6575 stream)) {
6576 return 0;
6578 break;
6580 default:
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));
6585 return 0;
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);
6591 return 0;
6593 CALLBACK(OPS_PTAG_CT_SIGNATURE_FOOTER, &stream->cbdata, &pkt);
6594 return 1;
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
6610 static int
6611 parse_sig(__ops_region_t *region, __ops_stream_t *stream)
6613 uint8_t c = 0x0;
6614 __ops_packet_t pkt;
6616 if (region->readc != 0) {
6617 /* We should not have read anything so far */
6618 loggit("parse_sig: bad length");
6619 return 0;
6622 (void) memset(&pkt, 0x0, sizeof(pkt));
6623 if (!limread(&c, 1, region, stream)) {
6624 return 0;
6626 if (c == 2 || c == 3) {
6627 return parse_v3_sig(region, stream);
6629 if (c == 4) {
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);
6634 return 0;
6638 \ingroup Core_ReadPackets
6639 \brief Parse Compressed packet
6641 static int
6642 parse_compressed(__ops_region_t *region, __ops_stream_t *stream)
6644 __ops_packet_t pkt;
6645 uint8_t c = 0x0;
6647 if (!limread(&c, 1, region, stream)) {
6648 return 0;
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. */
6665 static void
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
6684 static int
6685 parse_one_pass(__ops_region_t * region, __ops_stream_t * stream)
6687 uint8_t c = 0x0;
6688 __ops_packet_t pkt;
6690 if (!limread(&pkt.u.one_pass_sig.version, 1, region, stream)) {
6691 return 0;
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);
6697 return 0;
6699 if (!limread(&c, 1, region, stream)) {
6700 return 0;
6702 pkt.u.one_pass_sig.sig_type = c;
6704 if (!limread(&c, 1, region, stream)) {
6705 return 0;
6707 pkt.u.one_pass_sig.hash_alg = c;
6709 if (!limread(&c, 1, region, stream)) {
6710 return 0;
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)) {
6716 return 0;
6719 if (!limread(&c, 1, region, stream)) {
6720 return 0;
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);
6727 return 1;
6731 \ingroup Core_ReadPackets
6732 \brief Parse a Trust packet
6734 static int
6735 parse_trust(__ops_region_t *region, __ops_stream_t *stream)
6737 __ops_packet_t pkt;
6739 if (!read_data(&pkt.u.trust.data, region, stream)) {
6740 return 0;
6742 CALLBACK(OPS_PTAG_CT_TRUST, &stream->cbdata, &pkt);
6743 return 1;
6746 static void
6747 parse_hash_data(__ops_stream_t *stream, const void *data, size_t len)
6749 size_t n;
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
6760 static int
6761 parse_litdata(__ops_region_t *region, __ops_stream_t *stream)
6763 __ops_memory_t *mem;
6764 __ops_packet_t pkt;
6765 uint8_t c = 0x0;
6767 if (!limread(&c, 1, region, stream)) {
6768 return 0;
6770 pkt.u.litdata_header.format = c;
6771 if (!limread(&c, 1, region, stream)) {
6772 return 0;
6774 if (!limread((uint8_t *)pkt.u.litdata_header.filename,
6775 (unsigned)c, region, stream)) {
6776 return 0;
6778 pkt.u.litdata_header.filename[c] = '\0';
6779 if (!limited_read_time(&pkt.u.litdata_header.mtime, region, stream)) {
6780 return 0;
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)) {
6792 return 0;
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? */
6801 return 1;
6804 static int
6805 consume_packet(__ops_region_t *region, __ops_stream_t *stream, unsigned warn)
6807 __ops_packet_t pkt;
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);
6818 if (warn) {
6819 OPS_ERROR(&stream->errors, OPS_E_P_PACKET_CONSUMED,
6820 "Warning: packet consumer");
6822 return 1;
6824 OPS_ERROR(&stream->errors, OPS_E_P_PACKET_NOT_CONSUMED,
6825 (warn) ? "Warning: Packet was not consumed" :
6826 "Packet was not consumed");
6827 return warn;
6830 static void __ops_reader_push_decrypt(__ops_stream_t *,
6831 __ops_crypt_t *,
6832 __ops_region_t *);
6833 static void __ops_reader_pop_decrypt(__ops_stream_t *);
6835 static int
6836 hash_reader(void *dest,
6837 size_t length,
6838 __ops_error_t **errors,
6839 __ops_reader_t *readinfo,
6840 __ops_cbdata_t *cbdata)
6842 __ops_hash_t *hash = readinfo->arg;
6843 int r;
6845 r = __ops_stacked_read(dest, length, errors, readinfo, cbdata);
6846 if (r <= 0) {
6847 return r;
6849 hash->add(hash, dest, (unsigned)r);
6850 return r;
6854 \ingroup Internal_Readers_Hash
6855 \brief Push hashed data reader on stack
6857 static void
6858 __ops_reader_push_hash(__ops_stream_t *stream, __ops_hash_t *hash)
6860 hash->init(hash);
6861 __ops_reader_push(stream, hash_reader, NULL, hash);
6865 \ingroup Internal_Readers_Hash
6866 \brief Pop hashed data reader from stack
6868 static void
6869 __ops_reader_pop_hash(__ops_stream_t *stream)
6871 __ops_reader_pop(stream);
6875 * \ingroup Core_ReadPackets
6876 * \brief Parse a secret key
6878 static int
6879 parse_seckey(__ops_region_t *region, __ops_stream_t *stream)
6881 __ops_packet_t pkt;
6882 __ops_region_t encregion;
6883 __ops_region_t *saved_region = NULL;
6884 uint8_t c = 0x0;
6885 __ops_crypt_t decrypt;
6886 __ops_hash_t checkhash;
6887 unsigned blocksize;
6888 unsigned crypted;
6889 int ret = 1;
6891 (void) memset(&pkt, 0x0, sizeof(pkt));
6892 if (!parse_pubkey_data(&pkt.u.seckey.pubkey, region, stream)) {
6893 return 0;
6895 stream->reading_v3_secret = pkt.u.seckey.pubkey.version != OPS_V4;
6897 if (!limread(&c, 1, region, stream)) {
6898 return 0;
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)) {
6905 return 0;
6907 pkt.u.seckey.alg = c;
6908 if (!limread(&c, 1, region, stream)) {
6909 return 0;
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:
6916 break;
6917 default:
6918 loggit("parse_seckey: bad seckey");
6919 return 0;
6921 if (!limread(&c, 1, region, stream)) {
6922 return 0;
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)) {
6927 return 0;
6929 if (pkt.u.seckey.s2k_specifier ==
6930 OPS_S2KS_ITERATED_AND_SALTED) {
6931 if (!limread(&c, 1, region, stream)) {
6932 return 0;
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;
6948 if (crypted) {
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];
6952 size_t passlen;
6953 char *passphrase;
6954 int hashsize;
6955 int keysize;
6956 int n;
6958 blocksize = __ops_block_size(pkt.u.seckey.alg);
6959 if (blocksize == 0 || blocksize > OPS_MAX_BLOCK_SIZE) {
6960 loggit("parse_seckey: bad blocksize");
6961 return 0;
6964 if (!limread(pkt.u.seckey.iv, blocksize, region, stream)) {
6965 return 0;
6967 (void) memset(&seckey, 0x0, sizeof(seckey));
6968 passphrase = NULL;
6969 seckey.u.skey_passphrase.passphrase = &passphrase;
6970 seckey.u.skey_passphrase.seckey = &pkt.u.seckey;
6971 CALLBACK(OPS_GET_PASSPHRASE, &stream->cbdata, &seckey);
6972 if (!passphrase) {
6973 if (!consume_packet(region, stream, 0)) {
6974 return 0;
6976 CALLBACK(OPS_PTAG_CT_ENCRYPTED_SECRET_KEY,
6977 &stream->cbdata, &pkt);
6978 return 1;
6980 keysize = __ops_key_size(pkt.u.seckey.alg);
6981 if (keysize == 0 || keysize > OPS_MAX_KEY_SIZE) {
6982 loggit("parse_seckey: bad keysize");
6983 return 0;
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");
6989 return 0;
6992 for (n = 0; n * hashsize < keysize; ++n) {
6993 int i;
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) {
7006 unsigned i;
7008 switch (pkt.u.seckey.s2k_specifier) {
7009 case OPS_S2KS_SALTED:
7010 hashes[n].add(&hashes[n],
7011 pkt.u.seckey.salt,
7012 OPS_SALT_SIZE);
7013 /* FALLTHROUGH */
7014 case OPS_S2KS_SIMPLE:
7015 hashes[n].add(&hashes[n],
7016 (uint8_t *) passphrase, passlen);
7017 break;
7019 case OPS_S2KS_ITERATED_AND_SALTED:
7020 for (i = 0; i < pkt.u.seckey.octetc;
7021 i += passlen + OPS_SALT_SIZE) {
7022 unsigned j;
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],
7029 pkt.u.seckey.salt,
7030 (unsigned)(j > OPS_SALT_SIZE) ?
7031 OPS_SALT_SIZE : j);
7032 if (j > OPS_SALT_SIZE) {
7033 hashes[n].add(&hashes[n],
7034 (uint8_t *) passphrase,
7035 j - OPS_SALT_SIZE);
7042 for (n = 0; n * hashsize < keysize; ++n) {
7043 int r;
7045 r = hashes[n].finish(&hashes[n], key + n * hashsize);
7046 if (r != hashsize) {
7047 loggit("parse_seckey: bad r");
7048 return 0;
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
7066 * now).
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);
7080 } else {
7081 __ops_reader_push_sum16(stream);
7084 switch (pkt.u.seckey.pubkey.alg) {
7085 case OPS_PKA_RSA:
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)) {
7092 ret = 0;
7094 break;
7096 case OPS_PKA_DSA:
7097 if (!limread_mpi(&pkt.u.seckey.key.dsa.x, region, stream)) {
7098 ret = 0;
7100 break;
7102 default:
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));
7108 ret = 0;
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);
7119 if (crypted &&
7120 pkt.u.seckey.pubkey.version != OPS_V4) {
7121 __ops_reader_pop_decrypt(stream);
7122 region = saved_region;
7124 if (ret) {
7125 if (!limread(pkt.u.seckey.checkhash,
7126 OPS_CHECKHASH_SIZE, region, stream)) {
7127 return 0;
7130 if (memcmp(hash, pkt.u.seckey.checkhash,
7131 OPS_CHECKHASH_SIZE) != 0) {
7132 ERRP(&stream->cbdata, pkt,
7133 "Hash mismatch in secret key");
7136 } else {
7137 uint16_t sum;
7139 sum = __ops_reader_pop_sum16(stream);
7140 if (crypted &&
7141 pkt.u.seckey.pubkey.version != OPS_V4) {
7142 __ops_reader_pop_decrypt(stream);
7143 region = saved_region;
7145 if (ret) {
7146 if (!limread_scalar(&pkt.u.seckey.checksum, 2,
7147 region, stream))
7148 return 0;
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");
7162 return 0;
7164 if (!ret) {
7165 return 0;
7167 CALLBACK(OPS_PTAG_CT_SECRET_KEY, &stream->cbdata, &pkt);
7168 return 1;
7172 \ingroup Core_MPI
7173 \brief Decrypt and unencode MPI
7174 \param buf Buffer in which to write decrypted unencoded MPI
7175 \param buflen Length of buffer
7176 \param encmpi
7177 \param seckey
7178 \return length of MPI
7179 \note only RSA at present
7181 static int
7182 __ops_decrypt_decode_mpi(uint8_t *buf,
7183 unsigned buflen,
7184 const BIGNUM *encmpi,
7185 const __ops_seckey_t *seckey)
7187 unsigned mpisize;
7188 uint8_t encmpibuf[NETPGP_BUFSIZ];
7189 uint8_t mpibuf[NETPGP_BUFSIZ];
7190 int n;
7191 int i;
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);
7197 return -1;
7199 BN_bn2bin(encmpi, encmpibuf);
7201 if (seckey->pubkey.alg != OPS_PKA_RSA) {
7202 loggit("pubkey algorithm wrong");
7203 return -1;
7206 n = __ops_rsa_private_decrypt(mpibuf, encmpibuf,
7207 (unsigned)(BN_num_bits(encmpi) + 7) / 8,
7208 &seckey->key.rsa, &seckey->pubkey.key.rsa);
7209 if (n == -1) {
7210 loggit("ops_rsa_private_decrypt failure");
7211 return -1;
7214 if (n <= 0) {
7215 return -1;
7218 /* Decode EME-PKCS1_V1_5 (RFC 2437). */
7220 if (mpibuf[0] != 0 || mpibuf[1] != 2) {
7221 return -1;
7224 /* Skip the random bytes. */
7225 for (i = 2; i < n && mpibuf[i]; ++i) {
7228 if (i == n || i < 10) {
7229 return -1;
7232 /* Skip the zero */
7233 i += 1;
7235 /* this is the unencoded m buf */
7236 if ((unsigned) (n - i) <= buflen) {
7237 (void) memcpy(buf, mpibuf + i, (unsigned)(n - i));
7240 return n - i;
7244 \ingroup Core_ReadPackets
7245 \brief Parse a Public Key Session Key packet
7247 static int
7248 parse_pk_sesskey(__ops_region_t *region, __ops_stream_t *stream)
7250 const __ops_seckey_t *secret;
7251 __ops_packet_t sesskey;
7252 __ops_packet_t pkt;
7253 uint8_t *iv;
7254 uint8_t c = 0x0;
7255 uint8_t cs[2];
7256 unsigned k;
7257 BIGNUM *enc_m;
7258 int n;
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)) {
7267 return 0;
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);
7274 return 0;
7276 if (!limread(pkt.u.pk_sesskey.keyid,
7277 sizeof(pkt.u.pk_sesskey.keyid), region, stream)) {
7278 return 0;
7280 if (!limread(&c, 1, region, stream)) {
7281 return 0;
7283 pkt.u.pk_sesskey.alg = c;
7284 switch (pkt.u.pk_sesskey.alg) {
7285 case OPS_PKA_RSA:
7286 if (!limread_mpi(&pkt.u.pk_sesskey.params.rsa.encrypted_m,
7287 region, stream)) {
7288 return 0;
7290 enc_m = pkt.u.pk_sesskey.params.rsa.encrypted_m;
7291 break;
7293 case OPS_PKA_ELGAMAL:
7294 if (!limread_mpi(&pkt.u.pk_sesskey.params.elgamal.g_to_k,
7295 region, stream) ||
7296 !limread_mpi(
7297 &pkt.u.pk_sesskey.params.elgamal.encrypted_m,
7298 region, stream)) {
7299 return 0;
7301 enc_m = pkt.u.pk_sesskey.params.elgamal.encrypted_m;
7302 break;
7304 default:
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));
7309 return 0;
7312 (void) memset(&sesskey, 0x0, sizeof(sesskey));
7313 secret = NULL;
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);
7319 if (!secret) {
7320 CALLBACK(OPS_PTAG_CT_ENCRYPTED_PK_SESSION_KEY, &stream->cbdata,
7321 &pkt);
7322 return 1;
7324 n = __ops_decrypt_decode_mpi(unencoded_m_buf, sizeof(unencoded_m_buf),
7325 enc_m, secret);
7326 if (n < 1) {
7327 ERRP(&stream->cbdata, pkt, "decrypted message too short");
7328 return 0;
7331 /* PKA */
7332 pkt.u.pk_sesskey.symm_alg = unencoded_m_buf[0];
7334 if (!__ops_is_sa_supported(pkt.u.pk_sesskey.symm_alg)) {
7335 /* ERR1P */
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));
7340 return 0;
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)",
7348 n, k + 3);
7349 return 0;
7351 if (k > sizeof(pkt.u.pk_sesskey.key)) {
7352 loggit("parse_pk_sesskey: bad keylength");
7353 return 0;
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]);
7369 return 0;
7371 /* all is well */
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);
7379 (void) free(iv);
7380 return 1;
7383 static int
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;
7389 int r = 1;
7391 if (stream->decrypt.alg) {
7392 __ops_region_t encregion;
7393 uint8_t buf[OPS_MAX_BLOCK_SIZE + 2] = "";
7394 size_t blksize;
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)) {
7402 return 0;
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]);
7412 return 0;
7414 if (tag == OPS_PTAG_CT_SE_DATA_BODY) {
7415 decrypt->decrypt_resync(decrypt);
7416 decrypt->block_encrypt(decrypt, decrypt->civ,
7417 decrypt->civ);
7419 r = __ops_parse(stream, !printerrors);
7420 __ops_reader_pop_decrypt(stream);
7421 } else {
7422 __ops_packet_t pkt;
7424 while (region->readc < region->length) {
7425 unsigned len;
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,
7432 region, stream)) {
7433 return 0;
7435 pkt.u.se_data_body.length = len;
7436 CALLBACK(tag, &stream->cbdata, &pkt);
7439 return r;
7442 static void __ops_reader_push_se_ip_data(__ops_stream_t *,
7443 __ops_crypt_t *,
7444 __ops_region_t *);
7445 static void __ops_reader_pop_se_ip_data(__ops_stream_t *);
7447 static int
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;
7453 int r = 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);
7462 } else {
7463 __ops_packet_t pkt;
7465 while (region->readc < region->length) {
7466 unsigned len;
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)) {
7474 return 0;
7476 pkt.u.se_data_body.length = len;
7477 CALLBACK(tag, &stream->cbdata, &pkt);
7480 return r;
7484 \ingroup Core_ReadPackets
7485 \brief Read a Symmetrically Encrypted packet
7487 static int
7488 parse_se_data(__ops_region_t *region, __ops_stream_t *stream)
7490 __ops_packet_t pkt;
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
7506 static int
7507 parse_se_ip_data(__ops_region_t *region, __ops_stream_t *stream)
7509 __ops_packet_t pkt;
7510 uint8_t c = 0x0;
7512 if (!limread(&c, 1, region, stream)) {
7513 return 0;
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");
7519 return 0;
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,
7527 stream);
7531 \ingroup Core_ReadPackets
7532 \brief Read a MDC packet
7534 static int
7535 parse_mdc(__ops_region_t *region, __ops_stream_t *stream)
7537 __ops_packet_t pkt;
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)) {
7542 return 0;
7544 CALLBACK(OPS_PTAG_CT_MDC, &stream->cbdata, &pkt);
7545 (void) free(pkt.u.mdc.data);
7546 return 1;
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
7555 * content.
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 */
7560 static int
7561 __ops_parse_packet(__ops_stream_t *stream, unsigned long *pktlen)
7563 __ops_packet_t pkt;
7564 __ops_region_t region;
7565 uint8_t ptag;
7566 unsigned indeterm = 0;
7567 int ret;
7569 pkt.u.ptag.position = stream->readinfo.position;
7571 ret = sub_base_read(&ptag, 1, &stream->errors, &stream->readinfo,
7572 &stream->cbdata);
7574 /* errors in the base read are effectively EOF. */
7575 if (ret <= 0) {
7576 return -1;
7579 *pktlen = 0;
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);
7584 return 0;
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)) {
7591 return 0;
7593 } else {
7594 unsigned rb;
7596 rb = 0;
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);
7604 break;
7606 case OPS_PTAG_OLD_LEN_2:
7607 rb = read_scalar(&pkt.u.ptag.length, 2, stream);
7608 break;
7610 case OPS_PTAG_OLD_LEN_4:
7611 rb = read_scalar(&pkt.u.ptag.length, 4, stream);
7612 break;
7614 case OPS_PTAG_OLD_LEN_INDETERMINATE:
7615 pkt.u.ptag.length = 0;
7616 indeterm = 1;
7617 rb = 1;
7618 break;
7620 if (!rb) {
7621 return 0;
7625 CALLBACK(OPS_PARSER_PTAG, &stream->cbdata, &pkt);
7627 __ops_init_subregion(&region, 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(&region, stream);
7633 break;
7635 case OPS_PTAG_CT_PUBLIC_KEY:
7636 case OPS_PTAG_CT_PUBLIC_SUBKEY:
7637 ret = parse_pubkey(pkt.u.ptag.type, &region, stream);
7638 break;
7640 case OPS_PTAG_CT_TRUST:
7641 ret = parse_trust(&region, stream);
7642 break;
7644 case OPS_PTAG_CT_USER_ID:
7645 ret = parse_userid(&region, stream);
7646 break;
7648 case OPS_PTAG_CT_COMPRESSED:
7649 ret = parse_compressed(&region, stream);
7650 break;
7652 case OPS_PTAG_CT_1_PASS_SIG:
7653 ret = parse_one_pass(&region, stream);
7654 break;
7656 case OPS_PTAG_CT_LITDATA:
7657 ret = parse_litdata(&region, stream);
7658 break;
7660 case OPS_PTAG_CT_USER_ATTR:
7661 ret = parse_userattr(&region, stream);
7662 break;
7664 case OPS_PTAG_CT_SECRET_KEY:
7665 ret = parse_seckey(&region, stream);
7666 break;
7668 case OPS_PTAG_CT_SECRET_SUBKEY:
7669 ret = parse_seckey(&region, stream);
7670 break;
7672 case OPS_PTAG_CT_PK_SESSION_KEY:
7673 ret = parse_pk_sesskey(&region, stream);
7674 break;
7676 case OPS_PTAG_CT_SE_DATA:
7677 ret = parse_se_data(&region, stream);
7678 break;
7680 case OPS_PTAG_CT_SE_IP_DATA:
7681 ret = parse_se_ip_data(&region, stream);
7682 break;
7684 case OPS_PTAG_CT_MDC:
7685 ret = parse_mdc(&region, stream);
7686 break;
7688 default:
7689 OPS_ERROR_1(&stream->errors, OPS_E_P_UNKNOWN_TAG,
7690 "Unknown content tag 0x%x",
7691 pkt.u.ptag.type);
7692 ret = 0;
7695 /* Ensure that the entire packet has been consumed */
7697 if (region.length != region.readc && !region.indeterm) {
7698 if (!consume_packet(&region, stream, 0)) {
7699 ret = -1;
7703 /* also consume it if there's been an error? */
7704 /* \todo decide what to do about an error on an */
7705 /* indeterminate packet */
7706 if (ret == 0) {
7707 if (!consume_packet(&region, stream, 0)) {
7708 ret = -1;
7711 /* set pktlen */
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()
7758 static int
7759 __ops_parse(__ops_stream_t *stream, int perrors)
7761 unsigned long pktlen;
7762 int r;
7764 do {
7765 r = __ops_parse_packet(stream, &pktlen);
7766 } while (r != -1);
7767 if (perrors) {
7768 __ops_print_errors(stream->errors);
7770 return (stream->errors == NULL);
7774 /**************************************************************************/
7776 #define CRC24_POLY 0x1864cfbL
7779 * \struct dearmour_t
7781 typedef struct {
7782 enum {
7783 OUTSIDE_BLOCK = 0,
7784 BASE64,
7785 AT_TRAILER_NAME
7786 } state;
7787 enum {
7788 NONE = 0,
7789 BEGIN_PGP_MESSAGE,
7790 BEGIN_PGP_PUBLIC_KEY_BLOCK,
7791 BEGIN_PGP_PRIVATE_KEY_BLOCK,
7792 BEGIN_PGP_MULTI,
7793 BEGIN_PGP_SIGNATURE,
7795 END_PGP_MESSAGE,
7796 END_PGP_PUBLIC_KEY_BLOCK,
7797 END_PGP_PRIVATE_KEY_BLOCK,
7798 END_PGP_MULTI,
7799 END_PGP_SIGNATURE,
7801 BEGIN_PGP_SIGNED_MESSAGE
7802 } lastseen;
7803 __ops_stream_t *stream;
7804 unsigned seen_nl:1;
7805 unsigned prev_nl:1;
7806 unsigned can_runon_data:1;
7807 /* !< allow headers in armoured data that are
7808 * not separated from the data by a blank line
7809 * */
7810 unsigned no_gap_needed:1;
7811 /* !< allow no blank line at the start of
7812 * armoured data */
7813 unsigned can_trail_ws:1;
7814 /* !< allow armoured stuff to have trailing
7815 * whitespace where we wouldn't strictly expect
7816 * it */
7817 /* it is an error to get a cleartext message without a sig */
7818 unsigned expect_sig:1;
7819 unsigned got_sig:1;
7820 /* base64 stuff */
7821 unsigned buffered;
7822 uint8_t buffer[3];
7823 unsigned eof64;
7824 unsigned long checksum;
7825 unsigned long read_checksum;
7826 /* unarmoured text blocks */
7827 uint8_t unarmoured[NETPGP_BUFSIZ];
7828 size_t unarmoredc;
7829 /* pushed back data (stored backwards) */
7830 uint8_t *pushback;
7831 unsigned pushbackc;
7832 /* armoured block headers */
7833 __ops_headers_t headers;
7834 } dearmour_t;
7836 static void
7837 push_back(dearmour_t *dearmour, const uint8_t *buf,
7838 unsigned length)
7840 unsigned n;
7842 if (dearmour->pushback) {
7843 loggit("push_back: already pushed back");
7844 } else {
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 */
7858 } headerline_t;
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 },
7875 { NULL, 0, -1 }
7878 /* search through the table of header lines */
7879 static int
7880 findheaderline(char *headerline)
7882 headerline_t *hp;
7884 for (hp = headerlines ; hp->s ; hp++) {
7885 if (strncmp(headerline, hp->s, hp->len) == 0) {
7886 break;
7889 return hp->type;
7892 static int
7893 set_lastseen_headerline(dearmour_t *dearmour, char *hdr, __ops_error_t **errors)
7895 int lastseen;
7896 int prev;
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);
7902 return 0;
7904 dearmour->lastseen = lastseen;
7905 switch (dearmour->lastseen) {
7906 case NONE:
7907 OPS_ERROR_1(errors, OPS_E_R_BAD_FORMAT,
7908 "Unrecognised last seen Header Line %s", hdr);
7909 break;
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");
7916 break;
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");
7923 break;
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");
7930 break;
7932 case BEGIN_PGP_MULTI:
7933 case END_PGP_MULTI:
7934 OPS_ERROR(errors, OPS_E_R_UNSUPPORTED,
7935 "Multi-part messages are not yet supported");
7936 break;
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");
7943 break;
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:
7950 break;
7952 return 1;
7955 static int
7956 read_char(dearmour_t *dearmour,
7957 __ops_error_t **errors,
7958 __ops_reader_t *readinfo,
7959 __ops_cbdata_t *cbdata,
7960 unsigned skip)
7962 uint8_t c;
7964 do {
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,
7972 cbdata) != 1) {
7973 return -1;
7975 } while (skip && c == '\r');
7976 dearmour->prev_nl = dearmour->seen_nl;
7977 dearmour->seen_nl = (c == '\n');
7978 return c;
7981 static int
7982 eat_whitespace(int first,
7983 dearmour_t *dearmour,
7984 __ops_error_t **errors,
7985 __ops_reader_t *readinfo,
7986 __ops_cbdata_t *cbdata,
7987 unsigned skip)
7989 int c = first;
7991 while (c == ' ' || c == '\t') {
7992 c = read_char(dearmour, errors, readinfo, cbdata, skip);
7994 return c;
7997 static int
7998 read_and_eat_whitespace(dearmour_t *dearmour,
7999 __ops_error_t **errors,
8000 __ops_reader_t *readinfo,
8001 __ops_cbdata_t *cbdata,
8002 unsigned skip)
8004 int c;
8006 do {
8007 c = read_char(dearmour, errors, readinfo, cbdata, skip);
8008 } while (c == ' ' || c == '\t');
8009 return c;
8012 static void
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;
8025 static int
8026 unarmoured_read_char(dearmour_t *dearmour,
8027 __ops_error_t **errors,
8028 __ops_reader_t *readinfo,
8029 __ops_cbdata_t *cbdata,
8030 unsigned skip)
8032 int c;
8034 do {
8035 c = read_char(dearmour, errors, readinfo, cbdata, 0);
8036 if (c < 0) {
8037 return c;
8039 dearmour->unarmoured[dearmour->unarmoredc++] = c;
8040 if (dearmour->unarmoredc == sizeof(dearmour->unarmoured)) {
8041 flush(dearmour, cbdata);
8043 } while (skip && c == '\r');
8044 return c;
8048 * \param headers
8049 * \param key
8051 * \return header value if found, otherwise NULL
8053 static const char *
8054 __ops_find_header(__ops_headers_t *headers, const char *key)
8056 unsigned n;
8058 for (n = 0; n < headers->headerc; ++n) {
8059 if (strcmp(headers->headers[n].key, key) == 0) {
8060 return headers->headers[n].value;
8063 return NULL;
8067 * \param dest
8068 * \param src
8070 static void
8071 __ops_dup_headers(__ops_headers_t *dest, const __ops_headers_t *src)
8073 unsigned n;
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
8087 static int
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;
8098 __ops_hash_t *hash;
8099 int total;
8101 hash = __ops_new(sizeof(*hash));
8102 hashstr = __ops_find_header(&dearmour->headers, "Hash");
8103 if (hashstr) {
8104 __ops_hash_alg_t alg;
8106 alg = __ops_str_to_hash_alg(hashstr);
8107 if (!__ops_is_hash_alg_supported(&alg)) {
8108 (void) free(hash);
8109 OPS_ERROR_1(errors, OPS_E_R_BAD_FORMAT,
8110 "Unsupported hash algorithm '%s'", hashstr);
8111 return -1;
8113 if (alg == OPS_HASH_UNKNOWN) {
8114 (void) free(hash);
8115 OPS_ERROR_1(errors, OPS_E_R_BAD_FORMAT,
8116 "Unknown hash algorithm '%s'", hashstr);
8117 return -1;
8119 __ops_hash_any(hash, alg);
8120 } else {
8121 __ops_hash_md5(hash);
8124 hash->init(hash);
8126 body->length = 0;
8127 total = 0;
8128 for (;;) {
8129 int c;
8130 unsigned count;
8132 c = read_char(dearmour, errors, readinfo, cbdata, 1);
8133 if (c < 0) {
8134 return -1;
8136 if (dearmour->prev_nl && c == '-') {
8137 if ((c = read_char(dearmour, errors, readinfo, cbdata,
8138 0)) < 0) {
8139 return -1;
8141 if (c != ' ') {
8142 /* then this had better be a trailer! */
8143 if (c != '-') {
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) {
8150 return -1;
8152 if (c != '-') {
8153 OPS_ERROR(errors,
8154 OPS_E_R_BAD_FORMAT,
8155 "Bad dash-escaping (2)");
8158 dearmour->state = AT_TRAILER_NAME;
8159 break;
8161 /* otherwise we read the next character */
8162 if ((c = read_char(dearmour, errors, readinfo, cbdata,
8163 0)) < 0) {
8164 return -1;
8167 if (c == '\n' && body->length) {
8168 if (memchr(body->data + 1, '\n', body->length - 1)
8169 != NULL) {
8170 loggit("process_dash_escaped: newline found");
8171 return -1;
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,
8178 &content);
8179 body->length = 0;
8181 body->data[body->length++] = c;
8182 total += 1;
8183 if (body->length == sizeof(body->data)) {
8184 CALLBACK(OPS_PTAG_CT_SIGNED_CLEARTEXT_BODY, cbdata,
8185 &content);
8186 body->length = 0;
8189 if (body->data[0] != '\n') {
8190 loggit("process_dash_escaped: no newline in body data");
8191 return -1;
8193 if (body->length != 1) {
8194 loggit("process_dash_escaped: bad body length");
8195 return -1;
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);
8201 return total;
8204 static int
8205 add_header(dearmour_t *dearmour, const char *key, const char *value)
8207 int n;
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;
8223 return 1;
8225 return 0;
8228 /* \todo what does a return value of 0 indicate? 1 is good, -1 is bad */
8229 static int
8230 parse_headers(dearmour_t *dearmour, __ops_error_t **errors,
8231 __ops_reader_t * readinfo, __ops_cbdata_t * cbdata)
8233 unsigned nbuf;
8234 unsigned size;
8235 unsigned first = 1;
8236 char *buf;
8237 int ret = 1;
8239 buf = NULL;
8240 nbuf = size = 0;
8242 for (;;) {
8243 int c;
8245 c = read_char(dearmour, errors, readinfo, cbdata, 1);
8246 if (c < 0) {
8247 OPS_ERROR(errors, OPS_E_R_BAD_FORMAT, "Unexpected EOF");
8248 ret = -1;
8249 break;
8251 if (c == '\n') {
8252 char *s;
8254 if (nbuf == 0) {
8255 break;
8257 if (nbuf >= size) {
8258 loggit("parse_headers: bad size");
8259 return -1;
8261 buf[nbuf] = '\0';
8262 if ((s = strchr(buf, ':')) == NULL) {
8263 if (!first && !dearmour->can_runon_data) {
8265 * then we have seriously malformed
8266 * armour
8268 OPS_ERROR(errors, OPS_E_R_BAD_FORMAT,
8269 "No colon in armour header");
8270 ret = -1;
8271 break;
8272 } else {
8273 if (first &&
8274 !(dearmour->can_runon_data ||
8275 dearmour->no_gap_needed)) {
8276 OPS_ERROR(errors,
8277 OPS_E_R_BAD_FORMAT,
8278 "No colon in armour header (2)");
8280 * then we have a nasty
8281 * armoured block with no
8282 * headers, not even a blank
8283 * line.
8285 buf[nbuf] = '\n';
8286 push_back(dearmour,
8287 (uint8_t *) buf,
8288 nbuf + 1);
8289 ret = -1;
8290 break;
8293 } else {
8294 *s = '\0';
8295 if (s[1] != ' ') {
8296 OPS_ERROR(errors, OPS_E_R_BAD_FORMAT,
8297 "No space in armour header");
8298 (void) free(buf);
8299 return -1;
8301 if (!add_header(dearmour, buf, s + 2)) {
8302 OPS_ERROR_1(errors, OPS_E_R_BAD_FORMAT,
8303 "Invalid header %s", buf);
8304 (void) free(buf);
8305 return -1;
8307 nbuf = 0;
8309 first = 0;
8310 } else {
8311 if (size <= nbuf + 1) {
8312 size += size + 80;
8313 buf = realloc(buf, size);
8315 buf[nbuf++] = c;
8318 (void) free(buf);
8319 return ret;
8322 static int
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)
8327 int n, c;
8328 unsigned long l = 0;
8330 for (n = 0; n < 4; ++n) {
8331 c = read_char(dearmour, errors, readinfo, cbdata, 1);
8332 if (c < 0) {
8333 dearmour->eof64 = 1;
8334 return -1;
8336 if (c == '-' || c == '=') {
8337 break;
8339 l <<= 6;
8340 if (c >= 'A' && c <= 'Z') {
8341 l += c - 'A';
8342 } else if (c >= 'a' && c <= 'z') {
8343 l += c - 'a' + 26;
8344 } else if (c >= '0' && c <= '9') {
8345 l += c - '0' + 52;
8346 } else if (c == '+') {
8347 l += 62;
8348 } else if (c == '/') {
8349 l += 63;
8350 } else {
8351 --n;
8352 l >>= 6;
8356 *pc = c;
8357 *pn = n;
8358 *pl = l;
8360 return 4;
8363 static unsigned
8364 __ops_crc24(unsigned checksum, uint8_t c)
8366 unsigned i;
8368 checksum ^= c << 16;
8369 for (i = 0; i < 8; i++) {
8370 checksum <<= 1;
8371 if (checksum & 0x1000000)
8372 checksum ^= CRC24_POLY;
8374 return checksum & 0xffffffL;
8377 static int
8378 decode64(dearmour_t *dearmour, __ops_error_t **errors,
8379 __ops_reader_t *readinfo, __ops_cbdata_t *cbdata)
8381 unsigned long l;
8382 unsigned n;
8383 int n2;
8384 int c;
8385 int ret;
8387 if (dearmour->buffered) {
8388 loggit("decode64: bad dearmour->buffered");
8389 return 0;
8392 ret = read4(dearmour, errors, readinfo, cbdata, &c, &n, &l);
8393 if (ret < 0) {
8394 OPS_ERROR(errors, OPS_E_R_BAD_FORMAT, "Badly formed base64");
8395 return 0;
8397 if (n == 3) {
8398 if (c != '=') {
8399 OPS_ERROR(errors, OPS_E_R_BAD_FORMAT,
8400 "Badly terminated base64 (2)");
8401 return 0;
8403 dearmour->buffered = 2;
8404 dearmour->eof64 = 1;
8405 l >>= 2;
8406 } else if (n == 2) {
8407 if (c != '=') {
8408 OPS_ERROR(errors, OPS_E_R_BAD_FORMAT,
8409 "Badly terminated base64 (3)");
8410 return 0;
8412 dearmour->buffered = 1;
8413 dearmour->eof64 = 1;
8414 l >>= 4;
8415 c = read_char(dearmour, errors, readinfo, cbdata, 0);
8416 if (c != '=') {
8417 OPS_ERROR(errors, OPS_E_R_BAD_FORMAT,
8418 "Badly terminated base64");
8419 return 0;
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)");
8425 return 0;
8427 dearmour->buffered = 0;
8428 } else {
8429 if (n != 4) {
8430 loggit("decode64: bad n (!= 4)");
8431 return 0;
8433 dearmour->buffered = 3;
8434 if (c == '-' || c == '=') {
8435 loggit("decode64: bad c");
8436 return 0;
8440 if (dearmour->buffered < 3 && dearmour->buffered > 0) {
8441 /* then we saw padding */
8442 if (c != '=') {
8443 loggit("decode64: bad c (=)");
8444 return 0;
8446 c = read_and_eat_whitespace(dearmour, errors, readinfo, cbdata,
8448 if (c != '\n') {
8449 OPS_ERROR(errors, OPS_E_R_BAD_FORMAT,
8450 "No newline at base64 end");
8451 return 0;
8453 c = read_char(dearmour, errors, readinfo, cbdata, 0);
8454 if (c != '=') {
8455 OPS_ERROR(errors, OPS_E_R_BAD_FORMAT,
8456 "No checksum at base64 end");
8457 return 0;
8460 if (c == '=') {
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");
8467 return 0;
8469 c = read_char(dearmour, errors, readinfo, cbdata, 1);
8470 if (dearmour->can_trail_ws)
8471 c = eat_whitespace(c, dearmour, errors, readinfo, cbdata,
8473 if (c != '\n') {
8474 OPS_ERROR(errors, OPS_E_R_BAD_FORMAT,
8475 "Badly terminated checksum");
8476 return 0;
8478 c = read_char(dearmour, errors, readinfo, cbdata, 0);
8479 if (c != '-') {
8480 OPS_ERROR(errors, OPS_E_R_BAD_FORMAT,
8481 "Bad base64 trailer (2)");
8482 return 0;
8485 if (c == '-') {
8486 for (n = 0; n < 4; ++n)
8487 if (read_char(dearmour, errors, readinfo, cbdata,
8488 0) != '-') {
8489 OPS_ERROR(errors, OPS_E_R_BAD_FORMAT,
8490 "Bad base64 trailer");
8491 return 0;
8493 dearmour->eof64 = 1;
8494 } else {
8495 if (!dearmour->buffered) {
8496 loggit("decode64: not buffered");
8497 return 0;
8501 for (n = 0; n < dearmour->buffered; ++n) {
8502 dearmour->buffer[n] = (uint8_t)l;
8503 l >>= 8;
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");
8512 return 0;
8514 return 1;
8517 static void
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. */
8530 static int
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;
8537 int ret;
8538 unsigned first;
8539 uint8_t *dest = dest_;
8540 int saved = length;
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");
8546 return 0;
8550 while (length > 0) {
8551 unsigned count;
8552 unsigned n;
8553 char buf[1024];
8554 int c;
8556 flush(dearmour, cbdata);
8557 switch (dearmour->state) {
8558 case OUTSIDE_BLOCK:
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) {
8567 return 0;
8572 * flush at this point so we definitely have room for
8573 * the header, and so we can easily erase it from the
8574 * buffer
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) {
8581 return 0;
8583 if (c != '-') {
8584 goto reloop;
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) {
8592 return 0;
8594 if (c == '-') {
8595 goto got_minus;
8597 buf[n++] = c;
8599 /* then I guess this wasn't a proper header */
8600 break;
8602 got_minus:
8603 buf[n] = '\0';
8605 /* Consume trailing '-' */
8606 for (count = 1; count < 5; ++count) {
8607 if ((c = unarmoured_read_char(dearmour, errors,
8608 readinfo, cbdata, 0)) < 0) {
8609 return 0;
8611 if (c != '-') {
8612 /* wasn't a header after all */
8613 goto reloop;
8617 /* Consume final NL */
8618 if ((c = unarmoured_read_char(dearmour, errors, readinfo,
8619 cbdata, 1)) < 0) {
8620 return 0;
8622 if (dearmour->can_trail_ws) {
8623 if ((c = eat_whitespace(c, dearmour, errors,
8624 readinfo, cbdata, 1)) < 0) {
8625 return 0;
8628 if (c != '\n') {
8629 /* wasn't a header line after all */
8630 break;
8634 * Now we've seen the header, scrub it from the
8635 * buffer
8637 dearmour->unarmoredc = 0;
8640 * But now we've seen a header line, then errors are
8641 * EARLY_EOF
8643 if ((ret = parse_headers(dearmour, errors, readinfo,
8644 cbdata)) <= 0) {
8645 return -1;
8648 if (!set_lastseen_headerline(dearmour, buf, errors)) {
8649 return -1;
8652 if (strcmp(buf, "BEGIN PGP SIGNED MESSAGE") == 0) {
8653 __ops_dup_headers(
8654 &content.u.cleartext_head.headers,
8655 &dearmour->headers);
8656 CALLBACK(OPS_PTAG_CT_SIGNED_CLEARTEXT_HEADER,
8657 cbdata,
8658 &content);
8659 ret = process_dash_escaped(dearmour, errors,
8660 readinfo, cbdata);
8661 if (ret <= 0) {
8662 return ret;
8664 } else {
8665 content.u.armour_header.type = buf;
8666 content.u.armour_header.headers =
8667 dearmour->headers;
8668 (void) memset(&dearmour->headers, 0x0,
8669 sizeof(dearmour->headers));
8670 CALLBACK(OPS_PTAG_CT_ARMOUR_HEADER, cbdata,
8671 &content);
8672 base64(dearmour);
8674 break;
8676 case BASE64:
8677 first = 1;
8678 while (length > 0) {
8679 if (!dearmour->buffered) {
8680 if (!dearmour->eof64) {
8681 ret = decode64(dearmour,
8682 errors, readinfo, cbdata);
8683 if (ret <= 0) {
8684 return ret;
8687 if (!dearmour->buffered) {
8688 if (!dearmour->eof64) {
8689 loggit(
8690 "armoured_data_reader: bad dearmour eof64");
8691 return 0;
8693 if (first) {
8694 dearmour->state =
8695 AT_TRAILER_NAME;
8696 goto reloop;
8698 return -1;
8701 if (!dearmour->buffered) {
8702 loggit(
8703 "armoured_data_reader: bad dearmour buffered");
8704 return 0;
8706 *dest = dearmour->buffer[--dearmour->buffered];
8707 ++dest;
8708 --length;
8709 first = 0;
8711 if (dearmour->eof64 && !dearmour->buffered) {
8712 dearmour->state = AT_TRAILER_NAME;
8714 break;
8716 case AT_TRAILER_NAME:
8717 for (n = 0; n < sizeof(buf) - 1;) {
8718 if ((c = read_char(dearmour, errors, readinfo,
8719 cbdata, 0)) < 0) {
8720 return -1;
8722 if (c == '-') {
8723 goto got_minus2;
8725 buf[n++] = c;
8727 /* then I guess this wasn't a proper trailer */
8728 OPS_ERROR(errors, OPS_E_R_BAD_FORMAT,
8729 "Bad ASCII armour trailer");
8730 break;
8732 got_minus2:
8733 buf[n] = '\0';
8735 if (!set_lastseen_headerline(dearmour, buf, errors)) {
8736 return -1;
8739 /* Consume trailing '-' */
8740 for (count = 1; count < 5; ++count) {
8741 if ((c = read_char(dearmour, errors, readinfo,
8742 cbdata, 0)) < 0) {
8743 return -1;
8745 if (c != '-') {
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,
8754 1)) < 0) {
8755 return -1;
8757 if (dearmour->can_trail_ws) {
8758 if ((c = eat_whitespace(c, dearmour, errors,
8759 readinfo, cbdata, 1)) < 0) {
8760 return 0;
8763 if (c != '\n') {
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,
8771 errors)) {
8772 return -1;
8774 if ((ret = parse_headers(dearmour, errors,
8775 readinfo, cbdata)) <= 0) {
8776 return ret;
8778 content.u.armour_header.type = buf;
8779 content.u.armour_header.headers =
8780 dearmour->headers;
8781 (void) memset(&dearmour->headers, 0x0,
8782 sizeof(dearmour->headers));
8783 CALLBACK(OPS_PTAG_CT_ARMOUR_HEADER, cbdata,
8784 &content);
8785 base64(dearmour);
8786 } else {
8787 content.u.armour_trailer.type = buf;
8788 CALLBACK(OPS_PTAG_CT_ARMOUR_TRAILER, cbdata,
8789 &content);
8790 dearmour->state = OUTSIDE_BLOCK;
8792 break;
8794 reloop:
8795 continue;
8798 return saved;
8801 static void
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()
8813 static void
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
8850 * \param stream
8851 * \sa __ops_reader_push_dearmour()
8853 static void
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* */
8866 typedef struct {
8867 uint8_t v[1024 * 15];
8868 size_t c;
8869 size_t off;
8870 __ops_crypt_t *decrypt;
8871 __ops_region_t *region;
8872 unsigned prevplain:1;
8873 } encrypted_t;
8875 static int
8876 encrypted_reader(void *dest,
8877 size_t length,
8878 __ops_error_t **errors,
8879 __ops_reader_t *readinfo,
8880 __ops_cbdata_t *cbdata)
8882 encrypted_t *enc;
8883 char *cdest;
8884 int saved;
8886 enc = readinfo->arg;
8887 saved = length;
8889 * V3 MPIs have the count plain and the cipher is reset after each
8890 * count
8892 if (enc->prevplain && !readinfo->parent->reading_mpi_len) {
8893 if (!readinfo->parent->reading_v3_secret) {
8894 loggit("encrypted_reader: bad v3 secret");
8895 return -1;
8897 enc->decrypt->decrypt_resync(enc->decrypt);
8898 enc->prevplain = 0;
8899 } else if (readinfo->parent->reading_v3_secret &&
8900 readinfo->parent->reading_mpi_len) {
8901 enc->prevplain = 1;
8903 while (length > 0) {
8904 if (enc->c) {
8905 unsigned n;
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");
8914 return 0;
8916 n = MIN(length, enc->c);
8917 (void) memcpy(dest, enc->v + enc->off, n);
8918 enc->c -= n;
8919 enc->off += n;
8920 length -= n;
8921 cdest = dest;
8922 cdest += n;
8923 dest = cdest;
8924 } else {
8925 unsigned n = enc->region->length;
8926 uint8_t buf[1024];
8928 if (!n) {
8929 return -1;
8931 if (!enc->region->indeterm) {
8932 n -= enc->region->readc;
8933 if (n == 0) {
8934 return saved - length;
8936 if (n > sizeof(buf)) {
8937 n = sizeof(buf);
8939 } else {
8940 n = sizeof(buf);
8944 * we can only read as much as we're asked for
8945 * in v3 keys because they're partially
8946 * unencrypted! */
8947 if ((readinfo->parent->reading_v3_secret ||
8948 readinfo->parent->exact_read) && n > length) {
8949 n = length;
8952 if (!__ops_stacked_limited_read(buf, n,
8953 enc->region, errors, readinfo, cbdata)) {
8954 return -1;
8956 if (!readinfo->parent->reading_v3_secret ||
8957 !readinfo->parent->reading_mpi_len) {
8958 enc->c = __ops_decrypt_se_ip(enc->decrypt,
8959 enc->v, buf, n);
8961 } else {
8962 (void) memcpy(&enc->v[enc->off], buf, n);
8963 enc->c = n;
8966 if (enc->c == 0) {
8967 loggit("encrypted_reader: 0 decrypted count");
8968 return 0;
8971 enc->off = 0;
8975 return saved;
8978 static void
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()
8989 static void
8990 __ops_reader_push_decrypt(__ops_stream_t *stream, __ops_crypt_t *decrypt,
8991 __ops_region_t *region)
8993 encrypted_t *enc;
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()
9007 static void
9008 __ops_reader_pop_decrypt(__ops_stream_t *stream)
9010 encrypted_t *enc;
9012 enc = stream->readinfo.arg;
9013 enc->decrypt->decrypt_finish(enc->decrypt);
9014 (void) free(enc);
9015 __ops_reader_pop(stream);
9018 /**************************************************************************/
9020 typedef struct {
9021 /* boolean: 0 once we've done the preamble/MDC checks */
9022 /* and are reading from the plaintext */
9023 int passed_checks;
9024 uint8_t *plaintext;
9025 size_t plaintext_available;
9026 size_t plaintext_offset;
9027 __ops_region_t *region;
9028 __ops_crypt_t *decrypt;
9029 } decrypt_se_ip_t;
9032 Gets entire SE_IP data packet.
9033 Verifies leading preamble
9034 Verifies trailing MDC packet
9035 Then passes up plaintext as requested
9037 static int
9038 se_ip_data_reader(void *dest_,
9039 size_t len,
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;
9046 unsigned int n = 0;
9048 se_ip = readinfo->arg;
9049 if (!se_ip->passed_checks) {
9050 uint8_t *buf = NULL;
9051 __ops_hash_t hash;
9052 uint8_t hashed[OPS_SHA1_HASH_SIZE];
9053 size_t b;
9054 size_t sz_preamble;
9055 size_t sz_mdc_hash;
9056 size_t sz_mdc;
9057 size_t sz_plaintext;
9058 uint8_t *preamble;
9059 uint8_t *plaintext;
9060 uint8_t *mdc;
9061 uint8_t *mdc_hash;
9063 __ops_hash_any(&hash, OPS_HASH_SHA1);
9064 hash.init(&hash);
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)) {
9074 (void) free(buf);
9075 return -1;
9077 /* verify leading preamble */
9079 b = se_ip->decrypt->blocksize;
9080 if (buf[b - 2] != buf[b] || buf[b - 1] != buf[b + 1]) {
9081 loggit(
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");
9086 (void) free(buf);
9087 return -1;
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;
9096 preamble = buf;
9097 plaintext = buf + sz_preamble;
9098 mdc = plaintext + sz_plaintext;
9099 mdc_hash = mdc + 2;
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");
9107 (void) free(buf);
9108 return 0;
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");
9114 return 0;
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;
9122 (void) free(buf);
9124 n = len;
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;
9132 len -= n;
9134 return n;
9137 static void
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);
9144 (void) free(se_ip);
9148 \ingroup Internal_Readers_SEIP
9150 static void
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,
9159 se_ip);
9163 \ingroup Internal_Readers_SEIP
9165 static void
9166 __ops_reader_pop_se_ip_data(__ops_stream_t *stream)
9168 decrypt_se_ip_t *se_ip;
9170 se_ip = stream->readinfo.arg;
9171 (void) free(se_ip);
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 */
9184 } mmap_reader_t;
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
9204 static int
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;
9209 int n;
9211 __OPS_USED(cbdata);
9212 reader = readinfo->arg;
9213 if ((n = read(reader->fd, dest, length)) == 0) {
9214 return 0;
9216 if (n < 0) {
9217 OPS_SYSTEM_ERROR_1(errors, OPS_E_R_READ_FAILED, "read",
9218 "file descriptor %d", reader->fd);
9219 return -1;
9221 return n;
9224 static void
9225 reader_fd_destroyer(__ops_reader_t *readinfo)
9227 (void) free(readinfo->arg);
9230 /**************************************************************************/
9232 typedef struct {
9233 const uint8_t *buffer;
9234 size_t length;
9235 size_t offset;
9236 } reader_mem_t;
9238 static int
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;
9243 unsigned n;
9245 __OPS_USED(cbdata);
9246 __OPS_USED(errors);
9248 if (reader->offset + length > reader->length) {
9249 n = reader->length - reader->offset;
9250 } else {
9251 n = length;
9253 if (n == 0) {
9254 return 0;
9256 (void) memcpy(dest, reader->buffer + reader->offset, n);
9257 reader->offset += n;
9258 return n;
9261 static void
9262 mem_destroyer(__ops_reader_t *readinfo)
9264 (void) free(readinfo->arg);
9268 \ingroup Core_Readers_First
9269 \brief Starts stack with memory reader
9272 static void
9273 __ops_reader_set_memory(__ops_stream_t *stream, const void *buffer,
9274 size_t length)
9276 reader_mem_t *mem = __ops_new(sizeof(*mem));
9278 mem->buffer = buffer;
9279 mem->length = length;
9280 mem->offset = 0;
9281 __ops_reader_set(stream, mem_reader, mem_destroyer, mem);
9284 /* --- */
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()
9302 static void
9303 __ops_setup_memory_read(__ops_io_t *io,
9304 __ops_stream_t **stream,
9305 __ops_memory_t *mem,
9306 void *vp,
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);
9315 if (accumulate) {
9316 (*stream)->readinfo.accumulate = 1;
9321 \ingroup Core_Readers
9322 \brief Frees stream and mem
9323 \param stream
9324 \param mem
9325 \sa __ops_setup_memory_read()
9327 static void
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 */
9335 static int
9336 mmap_reader(void *dest, size_t length, __ops_error_t **errors,
9337 __ops_reader_t *readinfo, __ops_cbdata_t *cbdata)
9339 mmap_reader_t *mem;
9340 unsigned n;
9341 char *cmem;
9343 __OPS_USED(errors);
9344 __OPS_USED(cbdata);
9345 mem = readinfo->arg;
9346 cmem = mem->mem;
9347 n = MIN(length, (unsigned)(mem->size - mem->offset));
9348 if (n > 0) {
9349 (void) memcpy(dest, &cmem[(int)mem->offset], (unsigned)n);
9350 mem->offset += n;
9352 return n;
9355 /* tear down the mmap, close the fd */
9356 static void
9357 mmap_destroyer(__ops_reader_t *readinfo)
9359 mmap_reader_t *mem;
9361 mem = readinfo->arg;
9362 (void) munmap(mem->mem, (unsigned)mem->size);
9363 (void) close(mem->fd);
9364 (void) free(mem);
9367 /* set up the file to use mmap-ed memory if available, file IO otherwise */
9368 static void
9369 __ops_reader_set_mmap(__ops_stream_t *stream, int fd)
9371 mmap_reader_t *mem = __ops_new(sizeof(*mem));
9372 struct stat st;
9374 if (fstat(fd, &st) == 0) {
9375 mem->size = st.st_size;
9376 mem->offset = 0;
9377 mem->fd = fd;
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,
9382 mem);
9383 } else {
9384 __ops_reader_set(stream, mmap_reader, mmap_destroyer,
9385 mem);
9390 /* small function to pretty print an 8-character raw userid */
9391 static char *
9392 userid_to_id(const uint8_t *userid, char *id)
9394 static const char *hexes = "0123456789abcdef";
9395 int i;
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];
9401 id[8 * 2] = 0x0;
9402 return id;
9405 static void __ops_print_pubkeydata(__ops_io_t *, const __ops_key_t *);
9407 /* print out the successful signature information */
9408 static void
9409 resultp(__ops_io_t *io,
9410 const char *f,
9411 __ops_validation_t *res,
9412 __ops_keyring_t *ring)
9414 const __ops_key_t *pubkey;
9415 unsigned i;
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 */
9432 static void
9433 ptime(FILE *fp, time_t t)
9435 struct tm *tm;
9437 tm = gmtime(&t);
9438 printf("%04d-%02d-%02d",
9439 tm->tm_year + 1900,
9440 tm->tm_mon + 1,
9441 tm->tm_mday);
9444 /* return the number of bits in the public key */
9445 static int
9446 numkeybits(const __ops_pubkey_t *pubkey)
9448 switch(pubkey->alg) {
9449 case OPS_PKA_RSA:
9450 case OPS_PKA_RSA_ENCRYPT_ONLY:
9451 case OPS_PKA_RSA_SIGN_ONLY:
9452 return BN_num_bytes(pubkey->key.rsa.n) * 8;
9453 case OPS_PKA_DSA:
9454 switch(BN_num_bytes(pubkey->key.dsa.q)) {
9455 case 20:
9456 return 1024;
9457 case 28:
9458 return 2048;
9459 case 32:
9460 return 3072;
9461 default:
9462 return 0;
9464 case OPS_PKA_ELGAMAL:
9465 return BN_num_bytes(pubkey->key.elgamal.y) * 8;
9466 default:
9467 return -1;
9471 static void
9472 hexdump(FILE *fp, const uint8_t *src, size_t length, const char *sep)
9474 unsigned i;
9476 for (i = 0 ; i < length ; i += 2) {
9477 printf("%02x", *src++);
9478 printf("%02x%s", *src++, sep);
9483 \ingroup Core_Print
9485 Prints a public key in succinct detail
9487 \param key Ptr to public key
9489 static void
9490 __ops_print_pubkeydata(__ops_io_t *io, const __ops_key_t *key)
9492 unsigned int i;
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, "");
9498 printf(" ");
9499 ptime(io->errs, key->key.pubkey.birthtime);
9500 printf("\nKey fingerprint: ");
9501 hexdump(io->errs, key->fingerprint.fingerprint, OPS_FINGERPRINT_SIZE,
9502 " ");
9503 printf("\n");
9504 for (i = 0; i < key->uidc; i++) {
9505 printf("uid %s\n",
9506 key->uids[i].userid);
9510 #ifdef HAVE_FCNTL_H
9511 #include <fcntl.h>
9512 #endif
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()
9525 static int
9526 __ops_setup_file_read(__ops_io_t *io,
9527 __ops_stream_t **stream,
9528 const char *filename,
9529 void *vp,
9530 __ops_cb_ret_t callback(__ops_cbdata_t *,
9531 const __ops_packet_t *),
9532 unsigned accumulate)
9534 int fd;
9536 #ifdef O_BINARY
9537 fd = open(filename, O_RDONLY | O_BINARY);
9538 #else
9539 fd = open(filename, O_RDONLY);
9540 #endif
9541 if (fd < 0) {
9542 loggit("can't open \"%s\"", filename);
9543 return fd;
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);
9549 if (accumulate) {
9550 (*stream)->readinfo.accumulate = 1;
9552 return fd;
9556 \ingroup Core_Readers
9557 \brief Frees stream and closes fd
9558 \param stream
9559 \param fd
9560 \sa __ops_setup_file_read()
9562 static void
9563 __ops_teardown_file_read(__ops_stream_t *stream, int fd)
9565 (void) close(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)
9575 __OPS_USED(cbdata);
9577 switch (pkt->tag) {
9578 case OPS_PARSER_PTAG:
9579 case OPS_PTAG_CT_ENCRYPTED_SECRET_KEY: /* we get these because we
9580 * didn't prompt */
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:
9586 break;
9588 default:
9589 break;
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()
9619 static unsigned
9620 __ops_keyring_fileread(__ops_keyring_t *keyring,
9621 const unsigned armour,
9622 const char *filename)
9624 __ops_stream_t *stream;
9625 unsigned ret = 1;
9626 int fd;
9628 stream = __ops_new(sizeof(*stream));
9629 /* add this for the moment, */
9631 * \todo need to fix the problems with reading signature subpackets
9632 * later
9634 __ops_stream_options(stream, OPS_PTAG_SS_ALL, OPS_PARSE_PARSED);
9635 #ifdef O_BINARY
9636 fd = open(filename, O_RDONLY | O_BINARY);
9637 #else
9638 fd = open(filename, O_RDONLY);
9639 #endif
9640 if (fd < 0) {
9641 __ops_stream_delete(stream);
9642 perror(filename);
9643 return 0;
9645 __ops_reader_set_mmap(stream, fd);
9646 __ops_set_callback(stream, cb_keyring_read, NULL);
9647 if (armour) {
9648 __ops_reader_push_dearmour(stream);
9650 ret = __ops_parse_and_accumulate(keyring, stream);
9651 __ops_print_errors(stream->errors);
9652 if (armour) {
9653 __ops_reader_pop_dearmour(stream);
9655 (void) close(fd);
9656 __ops_stream_delete(stream);
9657 return ret;
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.
9669 static void
9670 __ops_keyring_free(__ops_keyring_t *keyring)
9672 (void)free(keyring->keys);
9673 keyring->keys = NULL;
9674 keyring->keyc = 0;
9675 keyring->keysize = 0;
9678 /* -- */
9680 #include <regex.h>
9682 /* check there's enough space in the arrays */
9683 static void
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 */
9700 static int
9701 findvar(netpgp_t *netpgp, const char *name)
9703 unsigned i;
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 */
9711 static void *
9712 readkeyring(netpgp_t *netpgp, const char *name)
9714 __ops_keyring_t *keyring;
9715 const unsigned noarmor = 0;
9716 char f[MAXPATHLEN];
9717 char *filename;
9718 char *homedir;
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);
9723 filename = f;
9725 keyring = __ops_new(sizeof(*keyring));
9726 if (!__ops_keyring_fileread(keyring, noarmor, filename)) {
9727 loggit("Can't read %s %s", name, filename);
9728 return NULL;
9730 netpgp_setvar(netpgp, name, filename);
9731 return keyring;
9734 /* read any gpg config file */
9735 static int
9736 conffile(netpgp_t *netpgp, char *homedir, char *userid, size_t length)
9738 regmatch_t matchv[10];
9739 regex_t keyre;
9740 char buf[BUFSIZ];
9741 FILE *fp;
9743 __OPS_USED(netpgp);
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);
9747 return 0;
9749 (void) memset(&keyre, 0x0, sizeof(keyre));
9750 (void) regcomp(&keyre, "^[ \t]*default-key[ \t]+([0-9a-zA-F]+)",
9751 REG_EXTENDED);
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]);
9762 (void) fclose(fp);
9763 return 1;
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.
9780 static unsigned
9781 __ops_validate_file(__ops_io_t *io,
9782 __ops_validation_t *result,
9783 const char *infile,
9784 const char *outfile,
9785 const int armoured,
9786 const __ops_keyring_t *keyring)
9788 validate_data_cb_t validation;
9789 __ops_stream_t *parse = NULL;
9790 struct stat st;
9791 const int printerrors = 1;
9792 unsigned ret;
9793 int64_t sigsize;
9794 char origfile[MAXPATHLEN];
9795 char *detachname;
9796 int outfd = 0;
9797 int infd;
9798 int cc;
9800 #define SIG_OVERHEAD 284 /* XXX - depends on sig size? */
9802 if (stat(infile, &st) < 0) {
9803 loggit("can't validate \"%s\"", infile);
9804 return 0;
9806 sigsize = st.st_size;
9807 detachname = NULL;
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);
9821 if (infd < 0) {
9822 return 0;
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;
9836 if (armoured) {
9837 __ops_reader_push_dearmour(parse);
9840 /* Do the verification */
9841 __ops_parse(parse, !printerrors);
9843 /* Tidy up */
9844 if (armoured) {
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 */
9852 if (outfile) {
9853 /* need to send validated output somewhere */
9854 if (strcmp(outfile, "-") == 0) {
9855 outfd = STDOUT_FILENO;
9856 } else {
9857 outfd = open(outfile, O_WRONLY | O_CREAT, 0666);
9859 if (outfd < 0) {
9860 /* even if the signature was good, we can't
9861 * write the file, so send back a bad return
9862 * code */
9863 ret = 0;
9864 } else if (validate_result_status(result)) {
9865 uint8_t *cp;
9866 unsigned len;
9867 int i;
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);
9873 if (cc < 0) {
9874 loggit("netpgp: short write");
9875 ret = 0;
9876 break;
9879 if (strcmp(outfile, "-") != 0) {
9880 (void) close(outfd);
9884 __ops_memory_free(validation.mem);
9885 return ret;
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.
9902 static unsigned
9903 __ops_validate_mem(__ops_io_t *io,
9904 __ops_validation_t *result,
9905 __ops_memory_t *mem,
9906 const int armoured,
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;
9925 if (armoured) {
9926 __ops_reader_push_dearmour(stream);
9928 /* Do the verification */
9929 __ops_parse(stream, !printerrors);
9930 /* Tidy up */
9931 if (armoured) {
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 /***************************************************************************/
9943 /* verify a file */
9945 netpgp_verify_file(netpgp_t *netpgp, const char *in, const char *out, int armored)
9947 __ops_validation_t result;
9948 __ops_io_t *io;
9950 (void) memset(&result, 0x0, sizeof(result));
9951 io = netpgp->io;
9952 if (__ops_validate_file(io, &result, in, out, armored,
9953 netpgp->pubring)) {
9954 resultp(io, in, &result, netpgp->pubring);
9955 return 1;
9957 if (result.validc + result.invalidc + result.unknownc == 0) {
9958 loggit("\"%s\": No signatures found - is this a signed file?",
9959 in);
9960 } else {
9961 loggit(
9962 "\"%s\": verification failure: %d invalid signatures, %d unknown signatures",
9963 in, result.invalidc, result.unknownc);
9965 return 0;
9968 /* verify memory */
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;
9974 __ops_io_t *io;
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);
9980 io = netpgp->io;
9981 if (__ops_validate_mem(io, &result, mem, armored, netpgp->pubring)) {
9982 resultp(io, "", &result, netpgp->pubring);
9983 return 1;
9985 if (result.validc + result.invalidc + result.unknownc == 0) {
9986 loggit("No signatures found - is this memory signed?");
9987 } else {
9988 loggit(
9989 "verification failure: %d invalid signatures, %d unknown signatures",
9990 result.invalidc, result.unknownc);
9992 __ops_memory_free(mem);
9993 return 0;
9996 /* return the version for the library */
9997 const char *
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)
10008 int i;
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);
10014 } else {
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) {
10024 return 0;
10027 netpgp->value[i] = strdup(value);
10028 return 1;
10031 /* get a variable's value (NULL if not set) */
10032 char *
10033 netpgp_getvar(netpgp_t *netpgp, const char *name)
10035 int i;
10037 return ((i = findvar(netpgp, name)) < 0) ? NULL : netpgp->value[i];
10040 /* initialise a netpgp_t structure */
10042 netpgp_init(netpgp_t *netpgp)
10044 __ops_io_t *io;
10045 char id[MAX_ID_LENGTH];
10046 char *homedir;
10047 char *userid;
10048 char *stream;
10049 int coredumps;
10051 #ifdef HAVE_SYS_RESOURCE_H
10052 struct rlimit limit;
10054 coredumps = netpgp_getvar(netpgp, "coredumps") != NULL;
10055 if (!coredumps) {
10056 (void) memset(&limit, 0x0, sizeof(limit));
10057 if (setrlimit(RLIMIT_CORE, &limit) != 0) {
10058 loggit(
10059 "netpgp_init: warning - can't turn off core dumps");
10060 coredumps = 1;
10063 #else
10064 coredumps = 1;
10065 #endif
10066 io = __ops_new(sizeof(*io));
10067 io->outs = stdout;
10068 if ((stream = netpgp_getvar(netpgp, "stdout")) != NULL &&
10069 strcmp(stream, "stderr") == 0) {
10070 io->outs = stderr;
10072 io->errs = stderr;
10073 if ((stream = netpgp_getvar(netpgp, "stderr")) != NULL &&
10074 strcmp(stream, "stdout") == 0) {
10075 io->errs = stdout;
10077 io->errs = stderr;
10078 netpgp->io = io;
10079 if (coredumps) {
10080 loggit("netpgp: warning: core dumps enabled");
10082 if ((homedir = netpgp_getvar(netpgp, "homedir")) == NULL) {
10083 loggit("netpgp: bad homedir");
10084 return 0;
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");
10096 return 0;
10098 loggit("Skipping user id check");
10099 } else {
10100 (void) netpgp_setvar(netpgp, "userid", id);
10102 if ((netpgp->pubring = readkeyring(netpgp, "pubring")) == NULL) {
10103 loggit("Can't read pub keyring");
10104 return 0;
10106 if ((netpgp->secring = readkeyring(netpgp, "secring")) == NULL) {
10107 loggit("Can't read sec keyring");
10108 return 0;
10110 return 1;
10113 /* finish off with the netpgp_t struct */
10115 netpgp_end(netpgp_t *netpgp)
10117 unsigned i;
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);
10140 return 1;
10143 /* ----- */
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 =
10161 " --help OR\n"
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"
10175 "\t--version\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"
10181 "\t[--verbose]\n";
10183 enum optdefs {
10184 /* commands */
10185 LIST_KEYS = 1,
10186 FIND_KEY,
10187 EXPORT_KEY,
10188 IMPORT_KEY,
10189 GENERATE_KEY,
10190 ENCRYPT,
10191 DECRYPT,
10192 SIGN,
10193 CLEARSIGN,
10194 VERIFY,
10195 VERIFY_CAT,
10196 LIST_PACKETS,
10197 VERSION_CMD,
10198 HELP_CMD,
10200 /* options */
10201 KEYRING,
10202 USERID,
10203 HOMEDIR,
10204 NUMBITS,
10205 DETACHED,
10206 HASH_ALG,
10207 OUTPUT,
10208 VERBOSE,
10209 COREDUMPS,
10211 /* debug */
10212 OPS_DEBUG
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},
10223 /* options */
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 */
10244 } prog_t;
10247 /* print a usage message */
10248 static void
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 */
10259 static void
10260 give_it_large(netpgp_t *netpgp)
10262 char *cp;
10263 char num[16];
10264 int val;
10266 val = 0;
10267 if ((cp = netpgp_getvar(netpgp, "verbose")) != NULL) {
10268 val = atoi(cp);
10270 (void) snprintf(num, sizeof(num), "%d", val + 1);
10271 netpgp_setvar(netpgp, "verbose", num);
10274 /* set the home directory value to "home/subdir" */
10275 static int
10276 set_homedir(netpgp_t *netpgp, char *home, const char *subdir)
10278 struct stat st;
10279 char d[MAXPATHLEN];
10281 if (home == NULL) {
10282 loggit("NULL HOME directory");
10283 return 0;
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);
10289 return 1;
10291 loggit("netpgp: homedir \"%s\" is not a dir", d);
10292 return 0;
10294 loggit("netpgp: warning homedir \"%s\" not found", d);
10295 return 1;
10299 main(int argc, char **argv)
10301 netpgp_t netpgp;
10302 prog_t p;
10303 int optindex;
10304 int ret;
10305 int ch;
10306 int i;
10308 (void) memset(&p, 0x0, sizeof(p));
10309 (void) memset(&netpgp, 0x0, sizeof(netpgp));
10310 p.progname = argv[0];
10311 p.numbits = DEFAULT_NUMBITS;
10312 p.overwrite = 1;
10313 p.output = NULL;
10314 if (argc < 2) {
10315 print_usage(usage, p.progname);
10316 exit(EXIT_ERROR);
10318 /* set some defaults */
10319 netpgp_setvar(&netpgp, "hash", DEFAULT_HASH_ALG);
10320 set_homedir(&netpgp, getenv("HOME"), "/.gnupg");
10321 optindex = 0;
10322 while ((ch = getopt_long(argc, argv, "", options, &optindex)) != -1) {
10323 switch (options[optindex].val) {
10324 case COREDUMPS:
10325 netpgp_setvar(&netpgp, "coredumps", "allowed");
10326 p.cmd = options[optindex].val;
10327 break;
10328 case VERSION_CMD:
10329 loggit(
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);
10334 /* options */
10335 case KEYRING:
10336 if (optarg == NULL) {
10337 loggit("No keyring argument provided");
10338 exit(EXIT_ERROR);
10340 snprintf(p.keyring, sizeof(p.keyring), "%s", optarg);
10341 break;
10342 case USERID:
10343 if (optarg == NULL) {
10344 loggit("No userid argument provided");
10345 exit(EXIT_ERROR);
10347 netpgp_setvar(&netpgp, "userid", optarg);
10348 break;
10349 case VERBOSE:
10350 give_it_large(&netpgp);
10351 break;
10352 case HOMEDIR:
10353 if (optarg == NULL) {
10354 loggit("No home directory argument provided");
10355 exit(EXIT_ERROR);
10357 set_homedir(&netpgp, optarg, NULL);
10358 break;
10359 case OUTPUT:
10360 if (optarg == NULL) {
10361 loggit("No output filename argument provided");
10362 exit(EXIT_ERROR);
10364 if (p.output) {
10365 (void) free(p.output);
10367 p.output = strdup(optarg);
10368 break;
10369 default:
10370 p.cmd = HELP_CMD;
10371 break;
10374 /* initialise, and read keys from file */
10375 if (!netpgp_init(&netpgp)) {
10376 loggit("can't initialise");
10377 exit(EXIT_ERROR);
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);
10387 exit(ret);