xref: /netbsd-src/crypto/external/bsd/netpgp/dist/src/lib/packet.h (revision bbde328be4e75ea9ad02e9715ea13ca54b797ada)
1 /*-
2  * Copyright (c) 2009 The NetBSD Foundation, Inc.
3  * All rights reserved.
4  *
5  * This code is derived from software contributed to The NetBSD Foundation
6  * by Alistair Crooks (agc@NetBSD.org)
7  *
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.
16  *
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.
28  */
29 /*
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.
35  *
36  * Licensed under the Apache License, Version 2.0 (the "License"); you may not
37  * use this file except in compliance with the License.
38  *
39  * You may obtain a copy of the License at
40  *     http://www.apache.org/licenses/LICENSE-2.0
41  *
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.
45  *
46  * See the License for the specific language governing permissions and
47  * limitations under the License.
48  */
49 
50 /** \file
51  * packet related headers.
52  */
53 
54 #ifndef PACKET_H_
55 #define PACKET_H_
56 
57 #include <time.h>
58 
59 #ifdef HAVE_OPENSSL_BN_H
60 #include <openssl/bn.h>
61 #endif
62 
63 #include "types.h"
64 #include "errors.h"
65 
66 /* structure to keep track of printing state variables */
67 typedef struct __ops_printstate_t {
68 	unsigned	unarmoured;
69 	unsigned	skipping;
70 	int		indent;
71 } __ops_printstate_t;
72 
73 /** General-use structure for variable-length data
74  */
75 
76 typedef struct {
77 	size_t          len;
78 	uint8_t		*contents;
79 	uint8_t		mmapped;	/* contents need an munmap(2) */
80 } __ops_data_t;
81 
82 /************************************/
83 /* Packet Tags - RFC4880, 4.2 */
84 /************************************/
85 
86 /** Packet Tag - Bit 7 Mask (this bit is always set).
87  * The first byte of a packet is the "Packet Tag".  It always
88  * has bit 7 set.  This is the mask for it.
89  *
90  * \see RFC4880 4.2
91  */
92 #define OPS_PTAG_ALWAYS_SET		0x80
93 
94 /** Packet Tag - New Format Flag.
95  * Bit 6 of the Packet Tag is the packet format indicator.
96  * If it is set, the new format is used, if cleared the
97  * old format is used.
98  *
99  * \see RFC4880 4.2
100  */
101 #define OPS_PTAG_NEW_FORMAT		0x40
102 
103 
104 /** Old Packet Format: Mask for content tag.
105  * In the old packet format bits 5 to 2 (including)
106  * are the content tag.  This is the mask to apply
107  * to the packet tag.  Note that you need to
108  * shift by #OPS_PTAG_OF_CONTENT_TAG_SHIFT bits.
109  *
110  * \see RFC4880 4.2
111  */
112 #define OPS_PTAG_OF_CONTENT_TAG_MASK	0x3c
113 /** Old Packet Format: Offset for the content tag.
114  * As described at #OPS_PTAG_OF_CONTENT_TAG_MASK the
115  * content tag needs to be shifted after being masked
116  * out from the Packet Tag.
117  *
118  * \see RFC4880 4.2
119  */
120 #define OPS_PTAG_OF_CONTENT_TAG_SHIFT	2
121 /** Old Packet Format: Mask for length type.
122  * Bits 1 and 0 of the packet tag are the length type
123  * in the old packet format.
124  *
125  * See #__ops_ptag_of_lt_t for the meaning of the values.
126  *
127  * \see RFC4880 4.2
128  */
129 #define OPS_PTAG_OF_LENGTH_TYPE_MASK	0x03
130 
131 
132 /** Old Packet Format Lengths.
133  * Defines the meanings of the 2 bits for length type in the
134  * old packet format.
135  *
136  * \see RFC4880 4.2.1
137  */
138 typedef enum {
139 	OPS_PTAG_OLD_LEN_1 = 0x00,	/* Packet has a 1 byte length -
140 					 * header is 2 bytes long. */
141 	OPS_PTAG_OLD_LEN_2 = 0x01,	/* Packet has a 2 byte length -
142 					 * header is 3 bytes long. */
143 	OPS_PTAG_OLD_LEN_4 = 0x02,	/* Packet has a 4 byte
144 						 * length - header is 5 bytes
145 						 * long. */
146 	OPS_PTAG_OLD_LEN_INDETERMINATE = 0x03	/* Packet has a
147 						 * indeterminate length. */
148 } __ops_ptag_of_lt_t;
149 
150 
151 /** New Packet Format: Mask for content tag.
152  * In the new packet format the 6 rightmost bits
153  * are the content tag.  This is the mask to apply
154  * to the packet tag.  Note that you need to
155  * shift by #OPS_PTAG_NF_CONTENT_TAG_SHIFT bits.
156  *
157  * \see RFC4880 4.2
158  */
159 #define OPS_PTAG_NF_CONTENT_TAG_MASK	0x3f
160 /** New Packet Format: Offset for the content tag.
161  * As described at #OPS_PTAG_NF_CONTENT_TAG_MASK the
162  * content tag needs to be shifted after being masked
163  * out from the Packet Tag.
164  *
165  * \see RFC4880 4.2
166  */
167 #define OPS_PTAG_NF_CONTENT_TAG_SHIFT	0
168 
169 /* PTag Content Tags */
170 /***************************/
171 
172 /** Package Tags (aka Content Tags) and signature subpacket types.
173  * This enumerates all rfc-defined packet tag values and the
174  * signature subpacket type values that we understand.
175  *
176  * \see RFC4880 4.3
177  * \see RFC4880 5.2.3.1
178  */
179 typedef enum {
180 	OPS_PTAG_CT_RESERVED = 0,	/* Reserved - a packet tag must
181 					 * not have this value */
182 	OPS_PTAG_CT_PK_SESSION_KEY = 1,	/* Public-Key Encrypted Session
183 					 * Key Packet */
184 	OPS_PTAG_CT_SIGNATURE = 2,	/* Signature Packet */
185 	OPS_PTAG_CT_SK_SESSION_KEY = 3,	/* Symmetric-Key Encrypted Session
186 					 * Key Packet */
187 	OPS_PTAG_CT_1_PASS_SIG = 4,	/* One-Pass Signature
188 						 * Packet */
189 	OPS_PTAG_CT_SECRET_KEY = 5,	/* Secret Key Packet */
190 	OPS_PTAG_CT_PUBLIC_KEY = 6,	/* Public Key Packet */
191 	OPS_PTAG_CT_SECRET_SUBKEY = 7,	/* Secret Subkey Packet */
192 	OPS_PTAG_CT_COMPRESSED = 8,	/* Compressed Data Packet */
193 	OPS_PTAG_CT_SE_DATA = 9,/* Symmetrically Encrypted Data Packet */
194 	OPS_PTAG_CT_MARKER = 10,/* Marker Packet */
195 	OPS_PTAG_CT_LITDATA = 11,	/* Literal Data Packet */
196 	OPS_PTAG_CT_TRUST = 12,	/* Trust Packet */
197 	OPS_PTAG_CT_USER_ID = 13,	/* User ID Packet */
198 	OPS_PTAG_CT_PUBLIC_SUBKEY = 14,	/* Public Subkey Packet */
199 	OPS_PTAG_CT_RESERVED2 = 15,	/* reserved */
200 	OPS_PTAG_CT_RESERVED3 = 16,	/* reserved */
201 	OPS_PTAG_CT_USER_ATTR = 17,	/* User Attribute Packet */
202 	OPS_PTAG_CT_SE_IP_DATA = 18,	/* Sym. Encrypted and Integrity
203 					 * Protected Data Packet */
204 	OPS_PTAG_CT_MDC = 19,	/* Modification Detection Code Packet */
205 
206 	OPS_PARSER_PTAG = 0x100,/* Internal Use: The packet is the "Packet
207 				 * Tag" itself - used when callback sends
208 				 * back the PTag. */
209 	OPS_PTAG_RAW_SS = 0x101,/* Internal Use: content is raw sig subtag */
210 	OPS_PTAG_SS_ALL = 0x102,/* Internal Use: select all subtags */
211 	OPS_PARSER_PACKET_END = 0x103,
212 
213 	/* signature subpackets (0x200-2ff) (type+0x200) */
214 	/* only those we can parse are listed here */
215 	OPS_PTAG_SIG_SUBPKT_BASE = 0x200,	/* Base for signature
216 							 * subpacket types - All
217 							 * signature type values
218 							 * are relative to this
219 							 * value. */
220 	OPS_PTAG_SS_CREATION_TIME = 0x200 + 2,	/* signature creation time */
221 	OPS_PTAG_SS_EXPIRATION_TIME = 0x200 + 3,	/* signature
222 							 * expiration time */
223 
224 	OPS_PTAG_SS_EXPORT_CERT = 0x200 + 4,	/* exportable certification */
225 	OPS_PTAG_SS_TRUST = 0x200 + 5,	/* trust signature */
226 	OPS_PTAG_SS_REGEXP = 0x200 + 6,	/* regular expression */
227 	OPS_PTAG_SS_REVOCABLE = 0x200 + 7,	/* revocable */
228 	OPS_PTAG_SS_KEY_EXPIRY = 0x200 + 9,	/* key expiration
229 							 * time */
230 	OPS_PTAG_SS_RESERVED = 0x200 + 10,	/* reserved */
231 	OPS_PTAG_SS_PREFERRED_SKA = 0x200 + 11,	/* preferred symmetric
232 						 * algs */
233 	OPS_PTAG_SS_REVOCATION_KEY = 0x200 + 12,	/* revocation key */
234 	OPS_PTAG_SS_ISSUER_KEY_ID = 0x200 + 16,	/* issuer key ID */
235 	OPS_PTAG_SS_NOTATION_DATA = 0x200 + 20,	/* notation data */
236 	OPS_PTAG_SS_PREFERRED_HASH = 0x200 + 21,	/* preferred hash
237 							 * algs */
238 	OPS_PTAG_SS_PREF_COMPRESS = 0x200 + 22,	/* preferred
239 							 * compression
240 							 * algorithms */
241 	OPS_PTAG_SS_KEYSERV_PREFS = 0x200 + 23,	/* key server
242 							 * preferences */
243 	OPS_PTAG_SS_PREF_KEYSERV = 0x200 + 24,	/* Preferred Key
244 							 * Server */
245 	OPS_PTAG_SS_PRIMARY_USER_ID = 0x200 + 25,	/* primary User ID */
246 	OPS_PTAG_SS_POLICY_URI = 0x200 + 26,	/* Policy URI */
247 	OPS_PTAG_SS_KEY_FLAGS = 0x200 + 27,	/* key flags */
248 	OPS_PTAG_SS_SIGNERS_USER_ID = 0x200 + 28,	/* Signer's User ID */
249 	OPS_PTAG_SS_REVOCATION_REASON = 0x200 + 29,	/* reason for
250 							 * revocation */
251 	OPS_PTAG_SS_FEATURES = 0x200 + 30,	/* features */
252 	OPS_PTAG_SS_SIGNATURE_TARGET = 0x200 + 31,	/* signature target */
253 	OPS_PTAG_SS_EMBEDDED_SIGNATURE = 0x200 + 32,	/* embedded signature */
254 
255 	OPS_PTAG_SS_USERDEFINED00 = 0x200 + 100,	/* internal or
256 							 * user-defined */
257 	OPS_PTAG_SS_USERDEFINED01 = 0x200 + 101,
258 	OPS_PTAG_SS_USERDEFINED02 = 0x200 + 102,
259 	OPS_PTAG_SS_USERDEFINED03 = 0x200 + 103,
260 	OPS_PTAG_SS_USERDEFINED04 = 0x200 + 104,
261 	OPS_PTAG_SS_USERDEFINED05 = 0x200 + 105,
262 	OPS_PTAG_SS_USERDEFINED06 = 0x200 + 106,
263 	OPS_PTAG_SS_USERDEFINED07 = 0x200 + 107,
264 	OPS_PTAG_SS_USERDEFINED08 = 0x200 + 108,
265 	OPS_PTAG_SS_USERDEFINED09 = 0x200 + 109,
266 	OPS_PTAG_SS_USERDEFINED10 = 0x200 + 110,
267 
268 	/* pseudo content types */
269 	OPS_PTAG_CT_LITDATA_HEADER = 0x300,
270 	OPS_PTAG_CT_LITDATA_BODY = 0x300 + 1,
271 	OPS_PTAG_CT_SIGNATURE_HEADER = 0x300 + 2,
272 	OPS_PTAG_CT_SIGNATURE_FOOTER = 0x300 + 3,
273 	OPS_PTAG_CT_ARMOUR_HEADER = 0x300 + 4,
274 	OPS_PTAG_CT_ARMOUR_TRAILER = 0x300 + 5,
275 	OPS_PTAG_CT_SIGNED_CLEARTEXT_HEADER = 0x300 + 6,
276 	OPS_PTAG_CT_SIGNED_CLEARTEXT_BODY = 0x300 + 7,
277 	OPS_PTAG_CT_SIGNED_CLEARTEXT_TRAILER = 0x300 + 8,
278 	OPS_PTAG_CT_UNARMOURED_TEXT = 0x300 + 9,
279 	OPS_PTAG_CT_ENCRYPTED_SECRET_KEY = 0x300 + 10,	/* In this case the
280 							 * algorithm specific
281 							 * fields will not be
282 							 * initialised */
283 	OPS_PTAG_CT_SE_DATA_HEADER = 0x300 + 11,
284 	OPS_PTAG_CT_SE_DATA_BODY = 0x300 + 12,
285 	OPS_PTAG_CT_SE_IP_DATA_HEADER = 0x300 + 13,
286 	OPS_PTAG_CT_SE_IP_DATA_BODY = 0x300 + 14,
287 	OPS_PTAG_CT_ENCRYPTED_PK_SESSION_KEY = 0x300 + 15,
288 
289 	/* commands to the callback */
290 	OPS_GET_PASSPHRASE = 0x400,
291 	OPS_GET_SECKEY = 0x400 + 1,
292 
293 	/* Errors */
294 	OPS_PARSER_ERROR = 0x500,	/* Internal Use: Parser Error */
295 	OPS_PARSER_ERRCODE = 0x500 + 1	/* Internal Use: Parser Error
296 					 * with errcode returned */
297 } __ops_content_tag_t;
298 
299 enum {
300 	OPS_REVOCATION_NO_REASON	= 0,
301 	OPS_REVOCATION_SUPERSEDED	= 1,
302 	OPS_REVOCATION_COMPROMISED	= 2,
303 	OPS_REVOCATION_RETIRED		= 3,
304 	OPS_REVOCATION_NO_LONGER_VALID	= 0x20
305 };
306 
307 typedef __ops_content_tag_t __ops_packet_tag_t;
308 typedef __ops_content_tag_t __ops_ss_type_t;
309 
310 /** Structure to hold one parse error string. */
311 typedef struct {
312 	const char     *error;	/* error message. */
313 } __ops_parser_error_t;
314 
315 /** Structure to hold one error code */
316 typedef struct {
317 	__ops_errcode_t   errcode;
318 } __ops_parser_errcode_t;
319 
320 /** Structure to hold one packet tag.
321  * \see RFC4880 4.2
322  */
323 typedef struct {
324 	unsigned        new_format;	/* Whether this packet tag is new
325 					 * (1) or old format (0) */
326 	unsigned        type;	/* content_tag value - See
327 					 * #__ops_content_tag_t for meanings */
328 	__ops_ptag_of_lt_t length_type;	/* Length type (#__ops_ptag_of_lt_t)
329 					 * - only if this packet tag is old
330 					 * format.  Set to 0 if new format. */
331 	unsigned        length;	/* The length of the packet.  This value
332 				 * is set when we read and compute the length
333 				 * information, not at the same moment we
334 				 * create the packet tag structure. Only
335 	 * defined if #readc is set. *//* XXX: Ben, is this correct? */
336 	unsigned        position;	/* The position (within the
337 					 * current reader) of the packet */
338 	unsigned	size;	/* number of bits */
339 } __ops_ptag_t;
340 
341 /** Public Key Algorithm Numbers.
342  * OpenPGP assigns a unique Algorithm Number to each algorithm that is part of OpenPGP.
343  *
344  * This lists algorithm numbers for public key algorithms.
345  *
346  * \see RFC4880 9.1
347  */
348 typedef enum {
349 	OPS_PKA_NOTHING	= 0,	/* No PKA */
350 	OPS_PKA_RSA = 1,	/* RSA (Encrypt or Sign) */
351 	OPS_PKA_RSA_ENCRYPT_ONLY = 2,	/* RSA Encrypt-Only (deprecated -
352 					 * \see RFC4880 13.5) */
353 	OPS_PKA_RSA_SIGN_ONLY = 3,	/* RSA Sign-Only (deprecated -
354 					 * \see RFC4880 13.5) */
355 	OPS_PKA_ELGAMAL = 16,	/* Elgamal (Encrypt-Only) */
356 	OPS_PKA_DSA = 17,	/* DSA (Digital Signature Algorithm) */
357 	OPS_PKA_RESERVED_ELLIPTIC_CURVE = 18,	/* Reserved for Elliptic
358 						 * Curve */
359 	OPS_PKA_RESERVED_ECDSA = 19,	/* Reserved for ECDSA */
360 	OPS_PKA_ELGAMAL_ENCRYPT_OR_SIGN = 20,	/* Deprecated. */
361 	OPS_PKA_RESERVED_DH = 21,	/* Reserved for Diffie-Hellman
362 					 * (X9.42, as defined for
363 					 * IETF-S/MIME) */
364 	OPS_PKA_PRIVATE00 = 100,/* Private/Experimental Algorithm */
365 	OPS_PKA_PRIVATE01 = 101,/* Private/Experimental Algorithm */
366 	OPS_PKA_PRIVATE02 = 102,/* Private/Experimental Algorithm */
367 	OPS_PKA_PRIVATE03 = 103,/* Private/Experimental Algorithm */
368 	OPS_PKA_PRIVATE04 = 104,/* Private/Experimental Algorithm */
369 	OPS_PKA_PRIVATE05 = 105,/* Private/Experimental Algorithm */
370 	OPS_PKA_PRIVATE06 = 106,/* Private/Experimental Algorithm */
371 	OPS_PKA_PRIVATE07 = 107,/* Private/Experimental Algorithm */
372 	OPS_PKA_PRIVATE08 = 108,/* Private/Experimental Algorithm */
373 	OPS_PKA_PRIVATE09 = 109,/* Private/Experimental Algorithm */
374 	OPS_PKA_PRIVATE10 = 110	/* Private/Experimental Algorithm */
375 } __ops_pubkey_alg_t;
376 
377 /** Structure to hold one DSA public key params.
378  *
379  * \see RFC4880 5.5.2
380  */
381 typedef struct {
382 	BIGNUM         *p;	/* DSA prime p */
383 	BIGNUM         *q;	/* DSA group order q */
384 	BIGNUM         *g;	/* DSA group generator g */
385 	BIGNUM         *y;	/* DSA public key value y (= g^x mod p
386 				 * with x being the secret) */
387 } __ops_dsa_pubkey_t;
388 
389 /** Structure to hold an RSA public key.
390  *
391  * \see RFC4880 5.5.2
392  */
393 typedef struct {
394 	BIGNUM         *n;	/* RSA public modulus n */
395 	BIGNUM         *e;	/* RSA public encryption exponent e */
396 } __ops_rsa_pubkey_t;
397 
398 /** Structure to hold an ElGamal public key params.
399  *
400  * \see RFC4880 5.5.2
401  */
402 typedef struct {
403 	BIGNUM         *p;	/* ElGamal prime p */
404 	BIGNUM         *g;	/* ElGamal group generator g */
405 	BIGNUM         *y;	/* ElGamal public key value y (= g^x mod p
406 				 * with x being the secret) */
407 } __ops_elgamal_pubkey_t;
408 
409 /** Union to hold public key params of any algorithm */
410 typedef union {
411 	__ops_dsa_pubkey_t dsa;	/* A DSA public key */
412 	__ops_rsa_pubkey_t rsa;	/* An RSA public key */
413 	__ops_elgamal_pubkey_t elgamal;	/* An ElGamal public key */
414 } __ops_pubkey_union_t;
415 
416 /** Version.
417  * OpenPGP has two different protocol versions: version 3 and version 4.
418  *
419  * \see RFC4880 5.2
420  */
421 typedef enum {
422 	OPS_V2 = 2,		/* Version 2 (essentially the same as v3) */
423 	OPS_V3 = 3,		/* Version 3 */
424 	OPS_V4 = 4		/* Version 4 */
425 } __ops_version_t;
426 
427 /** Structure to hold a pgp public key */
428 typedef struct {
429 	__ops_version_t		version;/* version of the key (v3, v4...) */
430 	time_t			birthtime;
431 	time_t			duration;
432 		/* validity period of the key in days since
433 		* creation.  A value of 0 has a special meaning
434 		* indicating this key does not expire.  Only used with
435 		* v3 keys.  */
436 	unsigned		days_valid;	/* v4 duration */
437 	__ops_pubkey_alg_t	alg;	/* Public Key Algorithm type */
438 	__ops_pubkey_union_t	key;	/* Public Key Parameters */
439 } __ops_pubkey_t;
440 
441 /** Structure to hold data for one RSA secret key
442  */
443 typedef struct {
444 	BIGNUM         *d;
445 	BIGNUM         *p;
446 	BIGNUM         *q;
447 	BIGNUM         *u;
448 } __ops_rsa_seckey_t;
449 
450 /** __ops_dsa_seckey_t */
451 typedef struct {
452 	BIGNUM         *x;
453 } __ops_dsa_seckey_t;
454 
455 /** __ops_seckey_union_t */
456 typedef union {
457 	__ops_rsa_seckey_t rsa;
458 	__ops_dsa_seckey_t dsa;
459 } __ops_seckey_union_t;
460 
461 /** s2k_usage_t
462  */
463 typedef enum {
464 	OPS_S2KU_NONE = 0,
465 	OPS_S2KU_ENCRYPTED_AND_HASHED = 254,
466 	OPS_S2KU_ENCRYPTED = 255
467 } __ops_s2k_usage_t;
468 
469 /** s2k_specifier_t
470  */
471 typedef enum {
472 	OPS_S2KS_SIMPLE = 0,
473 	OPS_S2KS_SALTED = 1,
474 	OPS_S2KS_ITERATED_AND_SALTED = 3
475 } __ops_s2k_specifier_t;
476 
477 /** Symmetric Key Algorithm Numbers.
478  * OpenPGP assigns a unique Algorithm Number to each algorithm that is
479  * part of OpenPGP.
480  *
481  * This lists algorithm numbers for symmetric key algorithms.
482  *
483  * \see RFC4880 9.2
484  */
485 typedef enum {
486 	OPS_SA_PLAINTEXT = 0,	/* Plaintext or unencrypted data */
487 	OPS_SA_IDEA = 1,	/* IDEA */
488 	OPS_SA_TRIPLEDES = 2,	/* TripleDES */
489 	OPS_SA_CAST5 = 3,	/* CAST5 */
490 	OPS_SA_BLOWFISH = 4,	/* Blowfish */
491 	OPS_SA_AES_128 = 7,	/* AES with 128-bit key (AES) */
492 	OPS_SA_AES_192 = 8,	/* AES with 192-bit key */
493 	OPS_SA_AES_256 = 9,	/* AES with 256-bit key */
494 	OPS_SA_TWOFISH = 10	/* Twofish with 256-bit key (TWOFISH) */
495 } __ops_symm_alg_t;
496 
497 /** Hashing Algorithm Numbers.
498  * OpenPGP assigns a unique Algorithm Number to each algorithm that is
499  * part of OpenPGP.
500  *
501  * This lists algorithm numbers for hash algorithms.
502  *
503  * \see RFC4880 9.4
504  */
505 typedef enum {
506 	OPS_HASH_UNKNOWN = -1,	/* used to indicate errors */
507 	OPS_HASH_MD5 = 1,	/* MD5 */
508 	OPS_HASH_SHA1 = 2,	/* SHA-1 */
509 	OPS_HASH_RIPEMD = 3,	/* RIPEMD160 */
510 
511 	OPS_HASH_SHA256 = 8,	/* SHA256 */
512 	OPS_HASH_SHA384 = 9,	/* SHA384 */
513 	OPS_HASH_SHA512 = 10,	/* SHA512 */
514 	OPS_HASH_SHA224 = 11	/* SHA224 */
515 } __ops_hash_alg_t;
516 
517 #define	OPS_DEFAULT_HASH_ALGORITHM	OPS_HASH_SHA256
518 
519 void   __ops_calc_mdc_hash(const uint8_t *,
520 			const size_t,
521 			const uint8_t *,
522 			const unsigned,
523 			uint8_t *);
524 unsigned   __ops_is_hash_alg_supported(const __ops_hash_alg_t *);
525 
526 /* Maximum block size for symmetric crypto */
527 #define OPS_MAX_BLOCK_SIZE	16
528 
529 /* Maximum key size for symmetric crypto */
530 #define OPS_MAX_KEY_SIZE	32
531 
532 /* Salt size for hashing */
533 #define OPS_SALT_SIZE		8
534 
535 /* Max hash size */
536 #define OPS_MAX_HASH_SIZE	64
537 
538 /** __ops_seckey_t
539  */
540 typedef struct {
541 	__ops_pubkey_t			pubkey;
542 	__ops_s2k_usage_t		s2k_usage;
543 	__ops_s2k_specifier_t		s2k_specifier;
544 	__ops_symm_alg_t		alg;
545 	__ops_hash_alg_t		hash_alg;
546 	uint8_t				salt[OPS_SALT_SIZE];
547 	unsigned			octetc;
548 	uint8_t				iv[OPS_MAX_BLOCK_SIZE];
549 	__ops_seckey_union_t		key;
550 	unsigned			checksum;
551 	uint8_t			       *checkhash;
552 } __ops_seckey_t;
553 
554 /** Structure to hold one trust packet's data */
555 
556 typedef struct {
557 	__ops_data_t      data;	/* Trust Packet */
558 } __ops_trust_t;
559 
560 /** Structure to hold one user id */
561 typedef struct {
562 	uint8_t		*userid;/* User ID - UTF-8 string */
563 } __ops_userid_t;
564 
565 /** Structure to hold one user attribute */
566 typedef struct {
567 	__ops_data_t      data;	/* User Attribute */
568 } __ops_userattr_t;
569 
570 /** Signature Type.
571  * OpenPGP defines different signature types that allow giving
572  * different meanings to signatures.  Signature types include 0x10 for
573  * generitc User ID certifications (used when Ben signs Weasel's key),
574  * Subkey binding signatures, document signatures, key revocations,
575  * etc.
576  *
577  * Different types are used in different places, and most make only
578  * sense in their intended location (for instance a subkey binding has
579  * no place on a UserID).
580  *
581  * \see RFC4880 5.2.1
582  */
583 typedef enum {
584 	OPS_SIG_BINARY = 0x00,	/* Signature of a binary document */
585 	OPS_SIG_TEXT = 0x01,	/* Signature of a canonical text document */
586 	OPS_SIG_STANDALONE = 0x02,	/* Standalone signature */
587 
588 	OPS_CERT_GENERIC = 0x10,/* Generic certification of a User ID and
589 				 * Public Key packet */
590 	OPS_CERT_PERSONA = 0x11,/* Persona certification of a User ID and
591 				 * Public Key packet */
592 	OPS_CERT_CASUAL = 0x12,	/* Casual certification of a User ID and
593 				 * Public Key packet */
594 	OPS_CERT_POSITIVE = 0x13,	/* Positive certification of a
595 					 * User ID and Public Key packet */
596 
597 	OPS_SIG_SUBKEY = 0x18,	/* Subkey Binding Signature */
598 	OPS_SIG_PRIMARY = 0x19,	/* Primary Key Binding Signature */
599 	OPS_SIG_DIRECT = 0x1f,	/* Signature directly on a key */
600 
601 	OPS_SIG_REV_KEY = 0x20,	/* Key revocation signature */
602 	OPS_SIG_REV_SUBKEY = 0x28,	/* Subkey revocation signature */
603 	OPS_SIG_REV_CERT = 0x30,/* Certification revocation signature */
604 
605 	OPS_SIG_TIMESTAMP = 0x40,	/* Timestamp signature */
606 
607 	OPS_SIG_3RD_PARTY = 0x50/* Third-Party Confirmation signature */
608 } __ops_sig_type_t;
609 
610 /** Struct to hold params of an RSA signature */
611 typedef struct {
612 	BIGNUM         *sig;	/* the signature value (m^d % n) */
613 } __ops_rsa_sig_t;
614 
615 /** Struct to hold params of a DSA signature */
616 typedef struct {
617 	BIGNUM         *r;	/* DSA value r */
618 	BIGNUM         *s;	/* DSA value s */
619 } __ops_dsa_sig_t;
620 
621 /** __ops_elgamal_signature_t */
622 typedef struct {
623 	BIGNUM         *r;
624 	BIGNUM         *s;
625 } __ops_elgamal_sig_t;
626 
627 /** Struct to hold data for a private/experimental signature */
628 typedef struct {
629 	__ops_data_t      data;
630 } __ops_unknown_sig_t;
631 
632 /** Union to hold signature params of any algorithm */
633 typedef union {
634 	__ops_rsa_sig_t rsa;/* An RSA Signature */
635 	__ops_dsa_sig_t dsa;/* A DSA Signature */
636 	__ops_elgamal_sig_t elgamal;	/* deprecated */
637 	__ops_unknown_sig_t unknown;	/* private or experimental */
638 } __ops_sig_union_t;
639 
640 #define OPS_KEY_ID_SIZE		8
641 #define OPS_FINGERPRINT_SIZE	20
642 
643 /** Struct to hold a signature packet.
644  *
645  * \see RFC4880 5.2.2
646  * \see RFC4880 5.2.3
647  */
648 typedef struct {
649 	__ops_version_t   version;/* signature version number */
650 	__ops_sig_type_t  type;	/* signature type value */
651 	time_t          birthtime;	/* creation time of the signature */
652 	time_t          duration;	/* number of seconds it's valid for */
653 	uint8_t		signer_id[OPS_KEY_ID_SIZE];	/* Eight-octet key ID
654 							 * of signer */
655 	__ops_pubkey_alg_t key_alg;	/* public key algorithm number */
656 	__ops_hash_alg_t hash_alg;	/* hashing algorithm number */
657 	__ops_sig_union_t sig;	/* signature params */
658 	size_t          v4_hashlen;
659 	uint8_t		*v4_hashed;
660 	unsigned	 birthtime_set:1;
661 	unsigned	 signer_id_set:1;
662 	unsigned	 duration_set:1;
663 } __ops_sig_info_t;
664 
665 /** Struct used when parsing a signature */
666 typedef struct __ops_sig_t {
667 	__ops_sig_info_t info;	/* The signature information */
668 	/* The following fields are only used while parsing the signature */
669 	uint8_t		 hash2[2];	/* high 2 bytes of hashed value */
670 	size_t		 v4_hashstart;	/* only valid if accumulate is set */
671 	__ops_hash_t     *hash;	/* the hash filled in for the data so far */
672 } __ops_sig_t;
673 
674 /** The raw bytes of a signature subpacket */
675 
676 typedef struct {
677 	__ops_content_tag_t	 tag;
678 	size_t          	 length;
679 	uint8_t			*raw;
680 } __ops_ss_raw_t;
681 
682 /** Signature Subpacket : Trust Level */
683 
684 typedef struct {
685 	uint8_t		level;	/* Trust Level */
686 	uint8_t		amount;	/* Amount */
687 } __ops_ss_trust_t;
688 
689 /** Signature Subpacket : Revocable */
690 typedef struct {
691 	unsigned		revocable;
692 } __ops_ss_revocable_t;
693 
694 /** Signature Subpacket : Time */
695 typedef struct {
696 	time_t			time;
697 } __ops_ss_time_t;
698 
699 /** Signature Subpacket : Key ID */
700 typedef struct {
701 	uint8_t		key_id[OPS_KEY_ID_SIZE];
702 } __ops_ss_key_id_t;
703 
704 /** Signature Subpacket : Notation Data */
705 typedef struct {
706 	__ops_data_t		flags;
707 	__ops_data_t		name;
708 	__ops_data_t		value;
709 } __ops_ss_notation_t;
710 
711 /** Signature Subpacket : User Defined */
712 typedef struct {
713 	__ops_data_t		data;
714 } __ops_ss_userdef_t;
715 
716 /** Signature Subpacket : Unknown */
717 typedef struct {
718 	__ops_data_t		data;
719 } __ops_ss_unknown_t;
720 
721 /** Signature Subpacket : Preferred Symmetric Key Algorithm */
722 typedef struct {
723 	__ops_data_t		data;
724 	/*
725 	 * Note that value 0 may represent the plaintext algorithm so we
726 	 * cannot expect data->contents to be a null-terminated list
727 	 */
728 } __ops_ss_skapref_t;
729 
730 /** Signature Subpacket : Preferrred Hash Algorithm */
731 typedef struct {
732 	__ops_data_t      data;
733 } __ops_ss_hashpref_t;
734 
735 /** Signature Subpacket : Preferred Compression */
736 typedef struct {
737 	__ops_data_t      data;
738 } __ops_ss_zpref_t;
739 
740 /** Signature Subpacket : Key Flags */
741 typedef struct {
742 	__ops_data_t      data;
743 } __ops_ss_key_flags_t;
744 
745 /** Signature Subpacket : Key Server Preferences */
746 typedef struct {
747 	__ops_data_t      data;
748 } __ops_ss_key_server_prefs_t;
749 
750 /** Signature Subpacket : Features */
751 typedef struct {
752 	__ops_data_t      data;
753 } __ops_ss_features_t;
754 
755 /** Signature Subpacket : Signature Target */
756 typedef struct {
757 	__ops_pubkey_alg_t	pka_alg;
758 	__ops_hash_alg_t	hash_alg;
759 	__ops_data_t		hash;
760 } __ops_ss_sig_target_t;
761 
762 /** Signature Subpacket : Embedded Signature */
763 typedef struct {
764 	__ops_data_t      sig;
765 } __ops_ss_embedded_sig_t;
766 
767 /** __ops_subpacket_t */
768 typedef struct __ops_subpacket_t {
769 	size_t          length;
770 	uint8_t		*raw;
771 } __ops_subpacket_t;
772 
773 /** Types of Compression */
774 typedef enum {
775 	OPS_C_NONE = 0,
776 	OPS_C_ZIP = 1,
777 	OPS_C_ZLIB = 2,
778 	OPS_C_BZIP2 = 3
779 } __ops_compression_type_t;
780 
781 /*
782  * unlike most structures, this will feed its data as a stream to the
783  * application instead of directly including it
784  */
785 /** __ops_compressed_t */
786 typedef struct {
787 	__ops_compression_type_t type;
788 } __ops_compressed_t;
789 
790 /** __ops_one_pass_sig_t */
791 typedef struct {
792 	uint8_t			version;
793 	__ops_sig_type_t	sig_type;
794 	__ops_hash_alg_t	hash_alg;
795 	__ops_pubkey_alg_t	key_alg;
796 	uint8_t			keyid[OPS_KEY_ID_SIZE];
797 	unsigned		nested;
798 } __ops_one_pass_sig_t;
799 
800 /** Signature Subpacket : Primary User ID */
801 typedef struct {
802 	unsigned   primary_userid;
803 } __ops_ss_primary_userid_t;
804 
805 /** Signature Subpacket : Regexp */
806 typedef struct {
807 	char           *regexp;
808 } __ops_ss_regexp_t;
809 
810 /** Signature Subpacket : Policy URL */
811 typedef struct {
812 	char           *url;
813 } __ops_ss_policy_t;
814 
815 /** Signature Subpacket : Preferred Key Server */
816 typedef struct {
817 	char           *name;
818 } __ops_ss_keyserv_t;
819 
820 /** Signature Subpacket : Revocation Key */
821 typedef struct {
822 	uint8_t   class;
823 	uint8_t   algid;
824 	uint8_t   fingerprint[OPS_FINGERPRINT_SIZE];
825 } __ops_ss_revocation_key_t;
826 
827 /** Signature Subpacket : Revocation Reason */
828 typedef struct {
829 	uint8_t   code;
830 	char           *reason;
831 } __ops_ss_revocation_t;
832 
833 /** litdata_type_t */
834 typedef enum {
835 	OPS_LDT_BINARY = 'b',
836 	OPS_LDT_TEXT = 't',
837 	OPS_LDT_UTF8 = 'u',
838 	OPS_LDT_LOCAL = 'l',
839 	OPS_LDT_LOCAL2 = '1'
840 } __ops_litdata_type_t;
841 
842 /** __ops_litdata_header_t */
843 typedef struct {
844 	__ops_litdata_type_t	format;
845 	char			filename[256];
846 	time_t			mtime;
847 } __ops_litdata_header_t;
848 
849 /** __ops_litdata_body_t */
850 typedef struct {
851 	unsigned         length;
852 	uint8_t		*data;
853 	void		*mem;		/* __ops_memory_t pointer */
854 } __ops_litdata_body_t;
855 
856 /** __ops_mdc_t */
857 typedef struct {
858 	unsigned	 length;
859 	uint8_t		*data;
860 } __ops_mdc_t;
861 
862 /** __ops_header_var_t */
863 typedef struct {
864 	char           *key;
865 	char           *value;
866 } __ops_header_var_t;
867 
868 /** __ops_headers_t */
869 typedef struct {
870 	__ops_header_var_t	*headers;
871 	unsigned	         headerc;
872 } __ops_headers_t;
873 
874 /** __ops_armour_header_t */
875 typedef struct {
876 	const char	*type;
877 	__ops_headers_t	 headers;
878 } __ops_armour_header_t;
879 
880 /** __ops_armour_trailer_t */
881 typedef struct {
882 	const char     *type;
883 } __ops_armour_trailer_t;
884 
885 /** __ops_cleartext_head_t */
886 typedef struct {
887 	__ops_headers_t   headers;
888 } __ops_cleartext_head_t;
889 
890 /** __ops_cleartext_body_t */
891 typedef struct {
892 	unsigned        length;
893 	uint8_t		data[8192];	/* \todo fix hard-coded value? */
894 } __ops_cleartext_body_t;
895 
896 /** __ops_cleartext_trailer_t */
897 typedef struct {
898 	struct _ops_hash_t *hash;	/* This will not have been
899 					 * finalised, but will have seen all
900 					 * the cleartext data in canonical
901 					 * form */
902 } __ops_cleartext_trailer_t;
903 
904 /** __ops_unarmoured_text_t */
905 typedef struct {
906 	unsigned        length;
907 	uint8_t		*data;
908 } __ops_unarmoured_text_t;
909 
910 typedef enum {
911 	SE_IP_DATA_VERSION = 1
912 } __ops_se_ip_data_version_t;
913 
914 typedef enum {
915 	OPS_PKSK_V3 = 3
916 } __ops_pk_sesskey_version_t;
917 
918 /** __ops_pk_sesskey_params_rsa_t */
919 typedef struct {
920 	BIGNUM         *encrypted_m;
921 	BIGNUM         *m;
922 } __ops_pk_sesskey_params_rsa_t;
923 
924 /** __ops_pk_sesskey_params_elgamal_t */
925 typedef struct {
926 	BIGNUM         *g_to_k;
927 	BIGNUM         *encrypted_m;
928 } __ops_pk_sesskey_params_elgamal_t;
929 
930 /** __ops_pk_sesskey_params_t */
931 typedef union {
932 	__ops_pk_sesskey_params_rsa_t rsa;
933 	__ops_pk_sesskey_params_elgamal_t elgamal;
934 } __ops_pk_sesskey_params_t;
935 
936 /** __ops_pk_sesskey_t */
937 typedef struct {
938 	__ops_pk_sesskey_version_t	version;
939 	uint8_t				key_id[OPS_KEY_ID_SIZE];
940 	__ops_pubkey_alg_t		alg;
941 	__ops_pk_sesskey_params_t	params;
942 	__ops_symm_alg_t		symm_alg;
943 	uint8_t				key[OPS_MAX_KEY_SIZE];
944 	uint16_t			checksum;
945 } __ops_pk_sesskey_t;
946 
947 /** __ops_seckey_passphrase_t */
948 typedef struct {
949 	const __ops_seckey_t *seckey;
950 	char          **passphrase;	/* point somewhere that gets filled
951 					 * in to work around constness of
952 					 * content */
953 } __ops_seckey_passphrase_t;
954 
955 typedef enum {
956 	OPS_SE_IP_V1 = 1
957 } __ops_se_ip_version_t;
958 
959 /** __ops_se_ip_data_header_t */
960 typedef struct {
961 	__ops_se_ip_version_t version;
962 } __ops_se_ip_data_header_t;
963 
964 /** __ops_se_ip_data_body_t */
965 typedef struct {
966 	unsigned         length;
967 	uint8_t		*data;	/* \todo remember to free this */
968 } __ops_se_ip_data_body_t;
969 
970 /** __ops_se_data_body_t */
971 typedef struct {
972 	unsigned	length;
973 	uint8_t		data[8192];	/* \todo parameterise this! */
974 } __ops_se_data_body_t;
975 
976 /** __ops_get_seckey_t */
977 typedef struct {
978 	const __ops_seckey_t **seckey;
979 	const __ops_pk_sesskey_t *pk_sesskey;
980 } __ops_get_seckey_t;
981 
982 /** __ops_parser_union_content_t */
983 typedef union {
984 	__ops_parser_error_t		error;
985 	__ops_parser_errcode_t		errcode;
986 	__ops_ptag_t			ptag;
987 	__ops_pubkey_t			pubkey;
988 	__ops_trust_t			trust;
989 	__ops_userid_t			userid;
990 	__ops_userattr_t		userattr;
991 	__ops_sig_t			sig;
992 	__ops_ss_raw_t			ss_raw;
993 	__ops_ss_trust_t		ss_trust;
994 	__ops_ss_revocable_t		ss_revocable;
995 	__ops_ss_time_t			ss_time;
996 	__ops_ss_key_id_t		ss_issuer;
997 	__ops_ss_notation_t		ss_notation;
998 	__ops_subpacket_t		packet;
999 	__ops_compressed_t		compressed;
1000 	__ops_one_pass_sig_t		one_pass_sig;
1001 	__ops_ss_skapref_t		ss_skapref;
1002 	__ops_ss_hashpref_t		ss_hashpref;
1003 	__ops_ss_zpref_t		ss_zpref;
1004 	__ops_ss_key_flags_t		ss_key_flags;
1005 	__ops_ss_key_server_prefs_t	ss_key_server_prefs;
1006 	__ops_ss_primary_userid_t	ss_primary_userid;
1007 	__ops_ss_regexp_t		ss_regexp;
1008 	__ops_ss_policy_t		ss_policy;
1009 	__ops_ss_keyserv_t		ss_keyserv;
1010 	__ops_ss_revocation_key_t	ss_revocation_key;
1011 	__ops_ss_userdef_t		ss_userdef;
1012 	__ops_ss_unknown_t		ss_unknown;
1013 	__ops_litdata_header_t		litdata_header;
1014 	__ops_litdata_body_t		litdata_body;
1015 	__ops_mdc_t			mdc;
1016 	__ops_ss_features_t		ss_features;
1017 	__ops_ss_sig_target_t		ss_sig_target;
1018 	__ops_ss_embedded_sig_t		ss_embedded_sig;
1019 	__ops_ss_revocation_t		ss_revocation;
1020 	__ops_seckey_t			seckey;
1021 	__ops_userid_t			ss_signer;
1022 	__ops_armour_header_t		armour_header;
1023 	__ops_armour_trailer_t		armour_trailer;
1024 	__ops_cleartext_head_t		cleartext_head;
1025 	__ops_cleartext_body_t		cleartext_body;
1026 	__ops_cleartext_trailer_t	cleartext_trailer;
1027 	__ops_unarmoured_text_t		unarmoured_text;
1028 	__ops_pk_sesskey_t		pk_sesskey;
1029 	__ops_seckey_passphrase_t	skey_passphrase;
1030 	__ops_se_ip_data_header_t	se_ip_data_header;
1031 	__ops_se_ip_data_body_t		se_ip_data_body;
1032 	__ops_se_data_body_t		se_data_body;
1033 	__ops_get_seckey_t		get_seckey;
1034 } __ops_contents_t;
1035 
1036 /** __ops_packet_t */
1037 struct __ops_packet_t {
1038 	__ops_content_tag_t	tag;		/* type of contents */
1039 	uint8_t			critical;	/* for sig subpackets */
1040 	__ops_contents_t	u;		/* union for contents */
1041 };
1042 
1043 /** __ops_fingerprint_t */
1044 typedef struct {
1045 	uint8_t		fingerprint[OPS_FINGERPRINT_SIZE];
1046 	unsigned        length;
1047 } __ops_fingerprint_t;
1048 
1049 void __ops_init(void);
1050 void __ops_finish(void);
1051 void __ops_keyid(uint8_t *, const size_t, const __ops_pubkey_t *);
1052 void __ops_fingerprint(__ops_fingerprint_t *, const __ops_pubkey_t *);
1053 void __ops_pubkey_free(__ops_pubkey_t *);
1054 void __ops_userid_free(__ops_userid_t *);
1055 void __ops_userattr_free(__ops_userattr_t *);
1056 void __ops_sig_free(__ops_sig_t *);
1057 void __ops_trust_free(__ops_trust_t *);
1058 void __ops_ss_skapref_free(__ops_ss_skapref_t *);
1059 void __ops_ss_hashpref_free(__ops_ss_hashpref_t *);
1060 void __ops_ss_zpref_free(__ops_ss_zpref_t *);
1061 void __ops_ss_key_flags_free(__ops_ss_key_flags_t *);
1062 void __ops_ss_key_server_prefs_free(__ops_ss_key_server_prefs_t *);
1063 void __ops_ss_features_free(__ops_ss_features_t *);
1064 void __ops_ss_notation_free(__ops_ss_notation_t *);
1065 void __ops_ss_policy_free(__ops_ss_policy_t *);
1066 void __ops_ss_keyserv_free(__ops_ss_keyserv_t *);
1067 void __ops_ss_regexp_free(__ops_ss_regexp_t *);
1068 void __ops_ss_userdef_free(__ops_ss_userdef_t *);
1069 void __ops_ss_reserved_free(__ops_ss_unknown_t *);
1070 void __ops_ss_revocation_free(__ops_ss_revocation_t *);
1071 void __ops_ss_sig_target_free(__ops_ss_sig_target_t *);
1072 void __ops_ss_embedded_sig_free(__ops_ss_embedded_sig_t *);
1073 
1074 void __ops_subpacket_free(__ops_subpacket_t *);
1075 void __ops_parser_content_free(__ops_packet_t *);
1076 void __ops_seckey_free(__ops_seckey_t *);
1077 void __ops_pk_sesskey_free(__ops_pk_sesskey_t *);
1078 
1079 int __ops_print_packet(__ops_printstate_t *, const __ops_packet_t *);
1080 
1081 #define DYNARRAY(type, arr)	\
1082 	unsigned arr##c; unsigned arr##vsize; type *arr##s
1083 
1084 #define EXPAND_ARRAY(str, arr) do {					\
1085 	if (str->arr##c == str->arr##vsize) {				\
1086 		void	*__newarr;					\
1087 		char	*__newarrc;					\
1088 		unsigned	__newsize;				\
1089 		__newsize = (str->arr##vsize * 2) + 10; 		\
1090 		if ((__newarrc = __newarr = realloc(str->arr##s,	\
1091 			__newsize * sizeof(*str->arr##s))) == NULL) {	\
1092 			(void) fprintf(stderr, "EXPAND_ARRAY - bad realloc\n"); \
1093 		} else {						\
1094 			(void) memset(&__newarrc[str->arr##vsize * sizeof(*str->arr##s)], \
1095 				0x0, (__newsize - str->arr##vsize) * sizeof(*str->arr##s)); \
1096 			str->arr##s = __newarr;				\
1097 			str->arr##vsize = __newsize;			\
1098 		}							\
1099 	}								\
1100 } while(/*CONSTCOND*/0)
1101 
1102 /** __ops_keydata_key_t
1103  */
1104 typedef union {
1105 	__ops_pubkey_t pubkey;
1106 	__ops_seckey_t seckey;
1107 } __ops_keydata_key_t;
1108 
1109 
1110 /* sigpacket_t */
1111 typedef struct {
1112 	__ops_userid_t		*userid;
1113 	__ops_subpacket_t	*packet;
1114 } sigpacket_t;
1115 
1116 /* user revocation info */
1117 typedef struct __ops_revoke_t {
1118 	uint32_t		 uid;		/* index in uid array */
1119 	uint8_t			 code;		/* revocation code */
1120 	char			*reason;	/* c'mon, spill the beans */
1121 } __ops_revoke_t;
1122 
1123 /** signature subpackets */
1124 typedef struct __ops_subsig_t {
1125 	uint32_t		uid;		/* index in userid array in key */
1126 	__ops_sig_t		sig;		/* trust signature */
1127 	uint8_t			trustlevel;	/* level of trust */
1128 	uint8_t			trustamount;	/* amount of trust */
1129 } __ops_subsig_t;
1130 
1131 /* describes a user's key */
1132 struct __ops_key_t {
1133 	DYNARRAY(__ops_userid_t, uid);		/* array of user ids */
1134 	DYNARRAY(__ops_subpacket_t, packet);	/* array of raw subpackets */
1135 	DYNARRAY(__ops_subsig_t, subsig);	/* array of signature subkeys */
1136 	DYNARRAY(__ops_revoke_t, revoke);	/* array of signature revocations */
1137 	uint8_t			key_id[OPS_KEY_ID_SIZE];
1138 	__ops_fingerprint_t	fingerprint;	/* pgp fingerprint */
1139 	__ops_content_tag_t	type;		/* type of key */
1140 	__ops_keydata_key_t	key;		/* pubkey/seckey data */
1141 	uint32_t		uid0;		/* primary uid index in uids array */
1142 	uint8_t			revoked;
1143 	__ops_revoke_t		revocation;
1144 };
1145 
1146 #define MDC_PKT_TAG	0xd3
1147 
1148 #endif /* PACKET_H_ */
1149