1 /*-
2  * Copyright (c) 2012 Alistair Crooks <agc@NetBSD.org>
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  * 1. Redistributions of source code must retain the above copyright
9  *    notice, this list of conditions and the following disclaimer.
10  * 2. Redistributions in binary form must reproduce the above copyright
11  *    notice, this list of conditions and the following disclaimer in the
12  *    documentation and/or other materials provided with the distribution.
13  *
14  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
15  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
16  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
17  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
18  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
19  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
20  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
21  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
23  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24  */
25 #ifndef NETPGP_VERIFY_H_
26 #define NETPGP_VERIFY_H_	20120928
27 
28 #include <sys/types.h>
29 
30 #include <inttypes.h>
31 
32 #ifndef PGPV_ARRAY
33 /* creates 2 unsigned vars called "name"c and "name"size in current scope */
34 /* also creates an array called "name"s in current scope */
35 #define PGPV_ARRAY(type, name)						\
36 	unsigned name##c; unsigned name##vsize; type *name##s
37 #endif
38 
39 /* 64bit key ids */
40 #define PGPV_KEYID_LEN		8
41 #define PGPV_STR_KEYID_LEN	(PGPV_KEYID_LEN + PGPV_KEYID_LEN + 1)
42 
43 /* bignum structure */
44 typedef struct pgpv_bignum_t {
45 	void			*bn;	/* hide the implementation details */
46 	uint16_t		 bits;	/* cached number of bits */
47 } pgpv_bignum_t;
48 
49 /* right now, our max binary digest length is 20 bytes */
50 #define PGPV_MAX_HASH_LEN	20
51 
52 /* fingerprint */
53 typedef struct pgpv_fingerprint_t {
54 	uint8_t			hashalg;	/* algorithm for digest */
55 	uint8_t			v[PGPV_MAX_HASH_LEN];	/* the digest */
56 	uint32_t		len;		/* its length */
57 } pgpv_fingerprint_t;
58 
59 /* specify size for array of bignums */
60 #define PGPV_MAX_PUBKEY_BN	4
61 
62 /* public key */
63 typedef struct pgpv_pubkey_t {
64 	pgpv_fingerprint_t	 fingerprint;	/* key fingerprint i.e. digest */
65 	uint8_t			 keyid[PGPV_KEYID_LEN];	/* last 8 bytes of v4 keys */
66 	int64_t		 	 birth;		/* creation time */
67 	int64_t			 expiry;	/* expiry time */
68 	pgpv_bignum_t		 bn[PGPV_MAX_PUBKEY_BN];	/* bignums */
69 	uint8_t			 keyalg;	/* key algorithm */
70 	uint8_t			 hashalg;	/* hash algorithm */
71 	uint8_t			 version;	/* key version */
72 } pgpv_pubkey_t;
73 
74 #define PGPV_MAX_SESSKEY_BN	2
75 
76 /* a (size, byte array) string */
77 typedef struct pgpv_string_t {
78 	size_t			 size;
79 	uint8_t			*data;
80 } pgpv_string_t;
81 
82 typedef struct pgpv_ref_t {
83 	void			*vp;
84 	size_t			 offset;
85 	unsigned		 mem;
86 } pgpv_ref_t;
87 
88 #define PGPV_MAX_SECKEY_BN	4
89 
90 typedef struct pgpv_compress_t {
91 	pgpv_string_t		 s;
92 	uint8_t			 compalg;
93 } pgpv_compress_t;
94 
95 /* a packet dealing with trust */
96 typedef struct pgpv_trust_t {
97 	uint8_t			level;
98 	uint8_t			amount;
99 } pgpv_trust_t;
100 
101 /* a signature sub packet */
102 typedef struct pgpv_sigsubpkt_t {
103 	pgpv_string_t		 s;
104 	uint8_t			 tag;
105 	uint8_t			 critical;
106 } pgpv_sigsubpkt_t;
107 
108 #define PGPV_MAX_SIG_BN		2
109 
110 typedef struct pgpv_signature_t {
111 	uint8_t			*signer;		/* key id of signer */
112 	pgpv_ref_t		 hashstart;
113 	uint8_t			*hash2;
114 	uint8_t			*mpi;
115 	int64_t			 birth;
116 	int64_t			 keyexpiry;
117 	int64_t			 expiry;
118 	uint32_t		 hashlen;
119 	uint8_t			 version;
120 	uint8_t			 type;
121 	uint8_t			 keyalg;
122 	uint8_t			 hashalg;
123 	uint8_t			 trustlevel;
124 	uint8_t			 trustamount;
125 	pgpv_bignum_t		 bn[PGPV_MAX_SIG_BN];
126 	char			*regexp;
127 	char			*pref_key_server;
128 	char			*policy;
129 	char			*features;
130 	char			*why_revoked;
131 	uint8_t			*revoke_fingerprint;
132 	uint8_t			 revoke_alg;
133 	uint8_t			 revoke_sensitive;
134 	uint8_t			 trustsig;
135 	uint8_t			 revocable;
136 	uint8_t			 pref_symm_alg;
137 	uint8_t			 pref_hash_alg;
138 	uint8_t			 pref_compress_alg;
139 	uint8_t			 key_server_modify;
140 	uint8_t			 notation;
141 	uint8_t			 type_key;
142 	uint8_t			 primary_userid;
143 	uint8_t			 revoked;	/* subtract 1 to get real reason, 0 == not revoked */
144 } pgpv_signature_t;
145 
146 /* a signature packet */
147 typedef struct pgpv_sigpkt_t {
148 	pgpv_signature_t	 sig;
149 	uint16_t		 subslen;
150 	uint16_t		 unhashlen;
151 	PGPV_ARRAY(pgpv_sigsubpkt_t, subpkts);
152 } pgpv_sigpkt_t;
153 
154 /* a one-pass signature packet */
155 typedef struct pgpv_onepass_t {
156 	uint8_t			 keyid[PGPV_KEYID_LEN];
157 	uint8_t			 version;
158 	uint8_t			 type;
159 	uint8_t			 hashalg;
160 	uint8_t			 keyalg;
161 	uint8_t			 nested;
162 } pgpv_onepass_t;
163 
164 /* a literal data packet */
165 typedef struct pgpv_litdata_t {
166 	uint8_t			*filename;
167 	pgpv_string_t		 s;
168 	uint32_t		 secs;
169 	uint8_t			 namelen;
170 	char			 format;
171 	unsigned		 mem;
172 	size_t			 offset;
173 	size_t			 len;
174 } pgpv_litdata_t;
175 
176 /* user attributes - images */
177 typedef struct pgpv_userattr_t {
178 	size_t 			 len;
179 	PGPV_ARRAY(pgpv_string_t, subattrs);
180 } pgpv_userattr_t;
181 
182 /* a general PGP packet */
183 typedef struct pgpv_pkt_t {
184 	uint8_t			 tag;
185 	uint8_t			 newfmt;
186 	uint8_t			 allocated;
187 	uint8_t			 mement;
188 	size_t			 offset;
189 	pgpv_string_t		 s;
190 	union {
191 		pgpv_sigpkt_t	sigpkt;
192 		pgpv_onepass_t	onepass;
193 		pgpv_litdata_t	litdata;
194 		pgpv_compress_t	compressed;
195 		pgpv_trust_t	trust;
196 		pgpv_pubkey_t	pubkey;
197 		pgpv_string_t	userid;
198 		pgpv_userattr_t	userattr;
199 	} u;
200 } pgpv_pkt_t;
201 
202 /* a memory structure */
203 typedef struct pgpv_mem_t {
204 	size_t			 size;
205 	size_t			 cc;
206 	uint8_t			*mem;
207 	FILE			*fp;
208 	uint8_t			 dealloc;
209 	const char		*allowed;	/* the types of packet that are allowed */
210 } pgpv_mem_t;
211 
212 /* packet parser */
213 
214 typedef struct pgpv_signed_userid_t {
215 	pgpv_string_t	 	 userid;
216 	PGPV_ARRAY(pgpv_signature_t, sigs);
217 	uint8_t			 primary_userid;
218 	uint8_t			 revoked;
219 } pgpv_signed_userid_t;
220 
221 typedef struct pgpv_signed_userattr_t {
222 	pgpv_userattr_t	 	 userattr;
223 	PGPV_ARRAY(pgpv_signature_t, sigs);
224 	uint8_t			 revoked;
225 } pgpv_signed_userattr_t;
226 
227 typedef struct pgpv_signed_subkey_t {
228 	pgpv_pubkey_t	 	 subkey;
229 	pgpv_signature_t 	 revoc_self_sig;
230 	PGPV_ARRAY(pgpv_signature_t, sigs);
231 } pgpv_signed_subkey_t;
232 
233 typedef struct pgpv_primarykey_t {
234 	pgpv_pubkey_t 		 primary;
235 	pgpv_signature_t 	 revoc_self_sig;
236 	PGPV_ARRAY(pgpv_signature_t, direct_sigs);
237 	PGPV_ARRAY(pgpv_signed_userid_t, signed_userids);
238 	PGPV_ARRAY(pgpv_signed_userattr_t, signed_userattrs);
239 	PGPV_ARRAY(pgpv_signed_subkey_t, signed_subkeys);
240 	size_t			 fmtsize;
241 	uint8_t			 primary_userid;
242 } pgpv_primarykey_t;
243 
244 /* everything stems from this structure */
245 typedef struct pgpv_t {
246 	PGPV_ARRAY(pgpv_pkt_t, 	 pkts);		/* packet array */
247 	PGPV_ARRAY(pgpv_primarykey_t,	 primaries);	/* array of primary keys */
248 	PGPV_ARRAY(pgpv_mem_t,	 areas);	/* areas we read packets from */
249 	PGPV_ARRAY(size_t,	 datastarts);	/* starts of data packets */
250 	size_t		 	 pkt;		/* when parsing, current pkt number */
251 	const char		*op;		/* the operation we're doing */
252 } pgpv_t;
253 
254 #define PGPV_REASON_LEN		128
255 
256 /* when searching, we define a cursor, and fill in an array of subscripts */
257 typedef struct pgpv_cursor_t {
258 	pgpv_t			*pgp;			/* pointer to pgp tree */
259 	char			*field;			/* field we're searching on */
260 	char			*op;			/* operation we're doing */
261 	char			*value;			/* value we're searching for */
262 	void			*ptr;			/* for regexps etc */
263 	PGPV_ARRAY(uint32_t,	 found);		/* array of matched subscripts */
264 	PGPV_ARRAY(size_t,	 datacookies);		/* cookies to retrieve matched data */
265 	int64_t			 sigtime;		/* time of signature */
266 	char			 why[PGPV_REASON_LEN];	/* reason for bad signature */
267 } pgpv_cursor_t;
268 
269 #ifndef __BEGIN_DECLS
270 #  if defined(__cplusplus)
271 #  define __BEGIN_DECLS           extern "C" {
272 #  define __END_DECLS             }
273 #  else
274 #  define __BEGIN_DECLS
275 #  define __END_DECLS
276 #  endif
277 #endif
278 
279 __BEGIN_DECLS
280 
281 int pgpv_read_pubring(pgpv_t */*pgp*/, const void */*keyringfile/mem*/, ssize_t /*size*/);
282 
283 size_t pgpv_verify(pgpv_cursor_t */*cursor*/, pgpv_t */*pgp*/, const void */*mem/file*/, ssize_t /*size*/);
284 size_t pgpv_get_verified(pgpv_cursor_t */*cursor*/, size_t /*cookie*/, char **/*ret*/);
285 
286 size_t pgpv_get_entry(pgpv_t */*pgp*/, unsigned /*ent*/, char **/*ret*/);
287 
288 int pgpv_close(pgpv_t */*pgp*/);
289 
290 __END_DECLS
291 
292 #endif
293