Fri Jul 8 15:56:47 2016 UTC ()
Update netpgpverify and libnetpgpverify to 20160705

External API changes
====================
+ add a pgpv_cursor_close() function to free resources associated with
a cursor

Better memory management
========================
+ restructure the way dynamic arrays are used, to avoid memory
corruption issues and memory leaks - keep all dynamic arrays in the global
data structure, and use indices in the other data structures to index them.
Means lack of data localisation, but avoids stale pointers, and leaks.

+ make signer field of signature a uint8_t array, rather than a pointer

+ use our own version of strdup(3) - don't depend on it being
available in standard library

+ keep track of whether litdata filenames and userid were allocated or not,
and free memory in pgpv_close() if it was allocated

+ free up allocated resources which were allocated in pgpv_close()


(agc)
diff -r1.20 -r1.21 pkgsrc/security/netpgpverify/files/libverify.c
diff -r1.30 -r1.31 pkgsrc/security/netpgpverify/files/verify.h

cvs diff -r1.20 -r1.21 pkgsrc/security/netpgpverify/files/libverify.c (expand / switch to unified diff)

--- pkgsrc/security/netpgpverify/files/libverify.c 2016/07/05 23:56:07 1.20
+++ pkgsrc/security/netpgpverify/files/libverify.c 2016/07/08 15:56:46 1.21
@@ -72,38 +72,39 @@ typedef struct pgpv_fingerprint_t { @@ -72,38 +72,39 @@ typedef struct pgpv_fingerprint_t {
72 uint8_t v[PGPV_MAX_HASH_LEN]; /* the digest */ 72 uint8_t v[PGPV_MAX_HASH_LEN]; /* the digest */
73 uint32_t len; /* its length */ 73 uint32_t len; /* its length */
74} pgpv_fingerprint_t; 74} pgpv_fingerprint_t;
75 75
76/* specify size for array of bignums */ 76/* specify size for array of bignums */
77#define PGPV_MAX_PUBKEY_BN 4 77#define PGPV_MAX_PUBKEY_BN 4
78 78
79/* public key */ 79/* public key */
80typedef struct pgpv_pubkey_t { 80typedef struct pgpv_pubkey_t {
81 pgpv_fingerprint_t fingerprint; /* key fingerprint i.e. digest */ 81 pgpv_fingerprint_t fingerprint; /* key fingerprint i.e. digest */
82 uint8_t keyid[PGPV_KEYID_LEN]; /* last 8 bytes of v4 keys */ 82 uint8_t keyid[PGPV_KEYID_LEN]; /* last 8 bytes of v4 keys */
83 int64_t birth; /* creation time */ 83 int64_t birth; /* creation time */
84 int64_t expiry; /* expiry time */ 84 int64_t expiry; /* expiry time */
85 pgpv_bignum_t bn[PGPV_MAX_PUBKEY_BN]; /* bignums */ 85 pgpv_bignum_t bn[PGPV_MAX_PUBKEY_BN]; /* bignums */
86 uint8_t keyalg; /* key algorithm */ 86 uint8_t keyalg; /* key algorithm */
87 uint8_t hashalg; /* hash algorithm */ 87 uint8_t hashalg; /* hash algorithm */
88 uint8_t version; /* key version */ 88 uint8_t version; /* key version */
89} pgpv_pubkey_t; 89} pgpv_pubkey_t;
90 90
91#define PGPV_MAX_SESSKEY_BN 2 91#define PGPV_MAX_SESSKEY_BN 2
92 92
93/* a (size, byte array) string */ 93/* a (size, byte array) string */
94typedef struct pgpv_string_t { 94typedef struct pgpv_string_t {
95 size_t size; 95 size_t size;
96 uint8_t *data; 96 uint8_t *data;
 97 uint8_t allocated;
97} pgpv_string_t; 98} pgpv_string_t;
98 99
99typedef struct pgpv_ref_t { 100typedef struct pgpv_ref_t {
100 void *vp; 101 void *vp;
101 size_t offset; 102 size_t offset;
102 unsigned mem; 103 unsigned mem;
103} pgpv_ref_t; 104} pgpv_ref_t;
104 105
105#define PGPV_MAX_SECKEY_BN 4 106#define PGPV_MAX_SECKEY_BN 4
106 107
107typedef struct pgpv_compress_t { 108typedef struct pgpv_compress_t {
108 pgpv_string_t s; 109 pgpv_string_t s;
109 uint8_t compalg; 110 uint8_t compalg;
@@ -115,27 +116,27 @@ typedef struct pgpv_trust_t { @@ -115,27 +116,27 @@ typedef struct pgpv_trust_t {
115 uint8_t amount; 116 uint8_t amount;
116} pgpv_trust_t; 117} pgpv_trust_t;
117 118
118/* a signature sub packet */ 119/* a signature sub packet */
119typedef struct pgpv_sigsubpkt_t { 120typedef struct pgpv_sigsubpkt_t {
120 pgpv_string_t s; 121 pgpv_string_t s;
121 uint8_t tag; 122 uint8_t tag;
122 uint8_t critical; 123 uint8_t critical;
123} pgpv_sigsubpkt_t; 124} pgpv_sigsubpkt_t;
124 125
125#define PGPV_MAX_SIG_BN 2 126#define PGPV_MAX_SIG_BN 2
126 127
127typedef struct pgpv_signature_t { 128typedef struct pgpv_signature_t {
128 uint8_t *signer; /* key id of signer */ 129 uint8_t signer[PGPV_KEYID_LEN]; /* key id of signer */
129 pgpv_ref_t hashstart; 130 pgpv_ref_t hashstart;
130 uint8_t *hash2; 131 uint8_t *hash2;
131 uint8_t *mpi; 132 uint8_t *mpi;
132 int64_t birth; 133 int64_t birth;
133 int64_t keyexpiry; 134 int64_t keyexpiry;
134 int64_t expiry; 135 int64_t expiry;
135 uint32_t hashlen; 136 uint32_t hashlen;
136 uint8_t version; 137 uint8_t version;
137 uint8_t type; 138 uint8_t type;
138 uint8_t keyalg; 139 uint8_t keyalg;
139 uint8_t hashalg; 140 uint8_t hashalg;
140 uint8_t trustlevel; 141 uint8_t trustlevel;
141 uint8_t trustamount; 142 uint8_t trustamount;
@@ -155,42 +156,42 @@ typedef struct pgpv_signature_t { @@ -155,42 +156,42 @@ typedef struct pgpv_signature_t {
155 uint8_t pref_compress_alg; 156 uint8_t pref_compress_alg;
156 uint8_t key_server_modify; 157 uint8_t key_server_modify;
157 uint8_t notation; 158 uint8_t notation;
158 uint8_t type_key; 159 uint8_t type_key;
159 uint8_t primary_userid; 160 uint8_t primary_userid;
160 uint8_t revoked; /* subtract 1 to get real reason, 0 == not revoked */ 161 uint8_t revoked; /* subtract 1 to get real reason, 0 == not revoked */
161} pgpv_signature_t; 162} pgpv_signature_t;
162 163
163/* a signature packet */ 164/* a signature packet */
164typedef struct pgpv_sigpkt_t { 165typedef struct pgpv_sigpkt_t {
165 pgpv_signature_t sig; 166 pgpv_signature_t sig;
166 uint16_t subslen; 167 uint16_t subslen;
167 uint16_t unhashlen; 168 uint16_t unhashlen;
168 PGPV_ARRAY(pgpv_sigsubpkt_t, subpkts); 169 PGPV_ARRAY(uint64_t, subpackets);
169} pgpv_sigpkt_t; 170} pgpv_sigpkt_t;
170 171
171/* a one-pass signature packet */ 172/* a one-pass signature packet */
172typedef struct pgpv_onepass_t { 173typedef struct pgpv_onepass_t {
173 uint8_t keyid[PGPV_KEYID_LEN]; 174 uint8_t keyid[PGPV_KEYID_LEN];
174 uint8_t version; 175 uint8_t version;
175 uint8_t type; 176 uint8_t type;
176 uint8_t hashalg; 177 uint8_t hashalg;
177 uint8_t keyalg; 178 uint8_t keyalg;
178 uint8_t nested; 179 uint8_t nested;
179} pgpv_onepass_t; 180} pgpv_onepass_t;
180 181
181/* a literal data packet */ 182/* a literal data packet */
182typedef struct pgpv_litdata_t { 183typedef struct pgpv_litdata_t {
183 uint8_t *filename; 184 pgpv_string_t filename;
184 pgpv_string_t s; 185 pgpv_string_t s;
185 uint32_t secs; 186 uint32_t secs;
186 uint8_t namelen; 187 uint8_t namelen;
187 char format; 188 char format;
188 unsigned mem; 189 unsigned mem;
189 size_t offset; 190 size_t offset;
190 size_t len; 191 size_t len;
191} pgpv_litdata_t; 192} pgpv_litdata_t;
192 193
193/* user attributes - images */ 194/* user attributes - images */
194typedef struct pgpv_userattr_t { 195typedef struct pgpv_userattr_t {
195 size_t len; 196 size_t len;
196 PGPV_ARRAY(pgpv_string_t, subattrs); 197 PGPV_ARRAY(pgpv_string_t, subattrs);
@@ -220,79 +221,85 @@ typedef struct pgpv_pkt_t { @@ -220,79 +221,85 @@ typedef struct pgpv_pkt_t {
220typedef struct pgpv_mem_t { 221typedef struct pgpv_mem_t {
221 size_t size; 222 size_t size;
222 size_t cc; 223 size_t cc;
223 uint8_t *mem; 224 uint8_t *mem;
224 FILE *fp; 225 FILE *fp;
225 uint8_t dealloc; 226 uint8_t dealloc;
226 const char *allowed; /* the types of packet that are allowed */ 227 const char *allowed; /* the types of packet that are allowed */
227} pgpv_mem_t; 228} pgpv_mem_t;
228 229
229/* packet parser */ 230/* packet parser */
230 231
231typedef struct pgpv_signed_userid_t { 232typedef struct pgpv_signed_userid_t {
232 pgpv_string_t userid; 233 pgpv_string_t userid;
233 PGPV_ARRAY(pgpv_signature_t, sigs); 234 PGPV_ARRAY(uint64_t, signatures);
234 uint8_t primary_userid; 235 uint8_t primary_userid;
235 uint8_t revoked; 236 uint8_t revoked;
236} pgpv_signed_userid_t; 237} pgpv_signed_userid_t;
237 238
238typedef struct pgpv_signed_userattr_t { 239typedef struct pgpv_signed_userattr_t {
239 pgpv_userattr_t userattr; 240 pgpv_userattr_t userattr;
240 PGPV_ARRAY(pgpv_signature_t, sigs); 241 PGPV_ARRAY(uint64_t, signatures);
241 uint8_t revoked; 242 uint8_t revoked;
242} pgpv_signed_userattr_t; 243} pgpv_signed_userattr_t;
243 244
244typedef struct pgpv_signed_subkey_t { 245typedef struct pgpv_signed_subkey_t {
245 pgpv_pubkey_t subkey; 246 pgpv_pubkey_t subkey;
246 pgpv_signature_t revoc_self_sig; 247 pgpv_signature_t revoc_self_sig;
247 PGPV_ARRAY(pgpv_signature_t, sigs); 248 PGPV_ARRAY(uint64_t, signatures);
248} pgpv_signed_subkey_t; 249} pgpv_signed_subkey_t;
249 250
250typedef struct pgpv_primarykey_t { 251typedef struct pgpv_primarykey_t {
251 pgpv_pubkey_t primary; 252 pgpv_pubkey_t primary;
252 pgpv_signature_t revoc_self_sig; 253 pgpv_signature_t revoc_self_sig;
253 PGPV_ARRAY(pgpv_signature_t, direct_sigs); 254 PGPV_ARRAY(uint64_t, signatures);
254 PGPV_ARRAY(pgpv_signed_userid_t, signed_userids); 255 PGPV_ARRAY(uint64_t, signed_userids);
255 PGPV_ARRAY(pgpv_signed_userattr_t, signed_userattrs); 256 PGPV_ARRAY(uint64_t, signed_userattrs);
256 PGPV_ARRAY(pgpv_signed_subkey_t, signed_subkeys); 257 PGPV_ARRAY(uint64_t, signed_subkeys);
257 size_t fmtsize; 258 size_t fmtsize;
258 uint8_t primary_userid; 259 uint8_t primary_userid;
259} pgpv_primarykey_t; 260} pgpv_primarykey_t;
260 261
261/* everything stems from this structure */ 262/* everything stems from this structure */
262typedef struct pgpv_t { 263typedef struct pgpv_t {
263 PGPV_ARRAY(pgpv_pkt_t, pkts); /* packet array */ 264 PGPV_ARRAY(pgpv_pkt_t, pkts); /* packet array */
264 PGPV_ARRAY(pgpv_primarykey_t, primaries); /* array of primary keys */ 265 PGPV_ARRAY(pgpv_primarykey_t, primaries); /* array of primary keys */
265 PGPV_ARRAY(pgpv_mem_t, areas); /* areas we read packets from */ 266 PGPV_ARRAY(pgpv_mem_t, areas); /* areas we read packets from */
266 PGPV_ARRAY(size_t, datastarts); /* starts of data packets */ 267 PGPV_ARRAY(size_t, datastarts); /* starts of data packets */
 268 PGPV_ARRAY(pgpv_signature_t, signatures); /* all signatures */
 269 PGPV_ARRAY(pgpv_signed_userid_t, signed_userids); /* all signed userids */
 270 PGPV_ARRAY(pgpv_signed_userattr_t, signed_userattrs); /* all signed user attrs */
 271 PGPV_ARRAY(pgpv_signed_subkey_t, signed_subkeys); /* all signed subkeys */
 272 PGPV_ARRAY(pgpv_sigsubpkt_t, subpkts); /* all sub packets */
267 size_t pkt; /* when parsing, current pkt number */ 273 size_t pkt; /* when parsing, current pkt number */
268 const char *op; /* the operation we're doing */ 274 const char *op; /* the operation we're doing */
269 unsigned ssh; /* using ssh keys */ 275 unsigned ssh; /* using ssh keys */
270} pgpv_t; 276} pgpv_t;
271 277
272#define PGPV_REASON_LEN 128 278#define PGPV_REASON_LEN 128
273 279
274/* when searching, we define a cursor, and fill in an array of subscripts */ 280/* when searching, we define a cursor, and fill in an array of subscripts */
275typedef struct pgpv_cursor_t { 281typedef struct pgpv_cursor_t {
276 pgpv_t *pgp; /* pointer to pgp tree */ 282 pgpv_t *pgp; /* pointer to pgp tree */
277 char *field; /* field we're searching on */ 283 char *field; /* field we're searching on */
278 char *op; /* operation we're doing */ 284 char *op; /* operation we're doing */
279 char *value; /* value we're searching for */ 285 char *value; /* value we're searching for */
280 void *ptr; /* for regexps etc */ 286 void *ptr; /* for regexps etc */
281 PGPV_ARRAY(uint32_t, found); /* array of matched pimary key subscripts */ 287 PGPV_ARRAY(uint32_t, found); /* array of matched pimary key subscripts */
282 PGPV_ARRAY(size_t, datacookies); /* cookies to retrieve matched data */ 288 PGPV_ARRAY(size_t, datacookies); /* cookies to retrieve matched data */
283 int64_t sigtime; /* time of signature */ 289 int64_t sigtime; /* time of signature */
284 char why[PGPV_REASON_LEN]; /* reason for bad signature */ 290 char why[PGPV_REASON_LEN]; /* reason for bad signature */
285} pgpv_cursor_t; 291} pgpv_cursor_t;
 292
286#ifndef USE_ARG 293#ifndef USE_ARG
287#define USE_ARG(x) /*LINTED*/(void)&(x) 294#define USE_ARG(x) /*LINTED*/(void)&(x)
288#endif 295#endif
289 296
290#ifndef __dead 297#ifndef __dead
291#define __dead __attribute__((__noreturn__)) 298#define __dead __attribute__((__noreturn__))
292#endif 299#endif
293 300
294#ifndef __printflike 301#ifndef __printflike
295#define __printflike(n, m) __attribute__((format(printf,n,m))) 302#define __printflike(n, m) __attribute__((format(printf,n,m)))
296#endif 303#endif
297 304
298#ifndef MIN 305#ifndef MIN
@@ -1054,42 +1061,43 @@ read_signature_mpis(pgpv_sigpkt_t *sigpk @@ -1054,42 +1061,43 @@ read_signature_mpis(pgpv_sigpkt_t *sigpk
1054 printf("sigpkt->version %d, dsa/elgamal sig weird\n", sigpkt->sig.version); 1061 printf("sigpkt->version %d, dsa/elgamal sig weird\n", sigpkt->sig.version);
1055 return 0; 1062 return 0;
1056 } 1063 }
1057 break; 1064 break;
1058 default: 1065 default:
1059 printf("weird type of sig! %d\n", sigpkt->sig.keyalg); 1066 printf("weird type of sig! %d\n", sigpkt->sig.keyalg);
1060 return 0; 1067 return 0;
1061 } 1068 }
1062 return 1; 1069 return 1;
1063} 1070}
1064 1071
1065/* add the signature sub packet to the signature packet */ 1072/* add the signature sub packet to the signature packet */
1066static int 1073static int
1067add_subpacket(pgpv_sigpkt_t *sigpkt, uint8_t tag, uint8_t *p, uint16_t len) 1074add_subpacket(pgpv_t *pgp, pgpv_sigpkt_t *sigpkt, uint8_t tag, uint8_t *p, uint16_t len)
1068{ 1075{
1069 pgpv_sigsubpkt_t subpkt; 1076 pgpv_sigsubpkt_t subpkt;
1070 1077
1071 memset(&subpkt, 0x0, sizeof(subpkt)); 1078 memset(&subpkt, 0x0, sizeof(subpkt));
1072 subpkt.s.size = len; 1079 subpkt.s.size = len;
1073 subpkt.critical = 0; 1080 subpkt.critical = 0;
1074 subpkt.tag = tag; 1081 subpkt.tag = tag;
1075 subpkt.s.data = p; 1082 subpkt.s.data = p;
1076 ARRAY_APPEND(sigpkt->subpkts, subpkt); 1083 ARRAY_APPEND(sigpkt->subpackets, ARRAY_COUNT(pgp->subpkts));
 1084 ARRAY_APPEND(pgp->subpkts, subpkt);
1077 return 1; 1085 return 1;
1078} 1086}
1079 1087
1080/* read the subpackets in the signature */ 1088/* read the subpackets in the signature */
1081static int 1089static int
1082read_sig_subpackets(pgpv_sigpkt_t *sigpkt, uint8_t *p, size_t pktlen) 1090read_sig_subpackets(pgpv_t *pgp, pgpv_sigpkt_t *sigpkt, uint8_t *p, size_t pktlen)
1083{ 1091{
1084 pgpv_sigsubpkt_t subpkt; 1092 pgpv_sigsubpkt_t subpkt;
1085 const int is_subpkt = 0; 1093 const int is_subpkt = 0;
1086 unsigned lenlen; 1094 unsigned lenlen;
1087 unsigned i; 1095 unsigned i;
1088 uint8_t *start; 1096 uint8_t *start;
1089 1097
1090 start = p; 1098 start = p;
1091 for (i = 0 ; (unsigned)(p - start) < sigpkt->subslen ; i++) { 1099 for (i = 0 ; (unsigned)(p - start) < sigpkt->subslen ; i++) {
1092 memset(&subpkt, 0x0, sizeof(subpkt)); 1100 memset(&subpkt, 0x0, sizeof(subpkt));
1093 subpkt.s.size = get_pkt_len(1, p, 0, is_subpkt); 1101 subpkt.s.size = get_pkt_len(1, p, 0, is_subpkt);
1094 lenlen = get_pkt_len_len(1, p, is_subpkt); 1102 lenlen = get_pkt_len_len(1, p, is_subpkt);
1095 if (lenlen > pktlen) { 1103 if (lenlen > pktlen) {
@@ -1101,30 +1109,30 @@ read_sig_subpackets(pgpv_sigpkt_t *sigpk @@ -1101,30 +1109,30 @@ read_sig_subpackets(pgpv_sigpkt_t *sigpk
1101 subpkt.tag = (*p & SUBPKT_TAG_MASK); 1109 subpkt.tag = (*p & SUBPKT_TAG_MASK);
1102 p += 1; 1110 p += 1;
1103 switch(subpkt.tag) { 1111 switch(subpkt.tag) {
1104 case SUBPKT_SIG_BIRTH: 1112 case SUBPKT_SIG_BIRTH:
1105 sigpkt->sig.birth = (int64_t)get_32(p); 1113 sigpkt->sig.birth = (int64_t)get_32(p);
1106 break; 1114 break;
1107 case SUBPKT_SIG_EXPIRY: 1115 case SUBPKT_SIG_EXPIRY:
1108 sigpkt->sig.expiry = (int64_t)get_32(p); 1116 sigpkt->sig.expiry = (int64_t)get_32(p);
1109 break; 1117 break;
1110 case SUBPKT_KEY_EXPIRY: 1118 case SUBPKT_KEY_EXPIRY:
1111 sigpkt->sig.keyexpiry = (int64_t)get_32(p); 1119 sigpkt->sig.keyexpiry = (int64_t)get_32(p);
1112 break; 1120 break;
1113 case SUBPKT_ISSUER: 1121 case SUBPKT_ISSUER:
1114 sigpkt->sig.signer = p; 1122 memcpy(sigpkt->sig.signer, p, sizeof(sigpkt->sig.signer));
1115 break; 1123 break;
1116 case SUBPKT_SIGNER_ID: 1124 case SUBPKT_SIGNER_ID:
1117 sigpkt->sig.signer = p; 1125 memcpy(sigpkt->sig.signer, p, sizeof(sigpkt->sig.signer));
1118 break; 1126 break;
1119 case SUBPKT_TRUST_SIG: 1127 case SUBPKT_TRUST_SIG:
1120 sigpkt->sig.trustsig = *p; 1128 sigpkt->sig.trustsig = *p;
1121 break; 1129 break;
1122 case SUBPKT_REGEXP: 1130 case SUBPKT_REGEXP:
1123 sigpkt->sig.regexp = (char *)(void *)p; 1131 sigpkt->sig.regexp = (char *)(void *)p;
1124 break; 1132 break;
1125 case SUBPKT_REVOCABLE: 1133 case SUBPKT_REVOCABLE:
1126 sigpkt->sig.revocable = *p; 1134 sigpkt->sig.revocable = *p;
1127 break; 1135 break;
1128 case SUBPKT_PREF_SYMMETRIC_ALG: 1136 case SUBPKT_PREF_SYMMETRIC_ALG:
1129 sigpkt->sig.pref_symm_alg = *p; 1137 sigpkt->sig.pref_symm_alg = *p;
1130 break; 1138 break;
@@ -1160,76 +1168,79 @@ read_sig_subpackets(pgpv_sigpkt_t *sigpk @@ -1160,76 +1168,79 @@ read_sig_subpackets(pgpv_sigpkt_t *sigpk
1160 case SUBPKT_FEATURES: 1168 case SUBPKT_FEATURES:
1161 sigpkt->sig.features = (char *)(void *)p; 1169 sigpkt->sig.features = (char *)(void *)p;
1162 break; 1170 break;
1163 case SUBPKT_REVOCATION_REASON: 1171 case SUBPKT_REVOCATION_REASON:
1164 sigpkt->sig.revoked = *p++ + 1; 1172 sigpkt->sig.revoked = *p++ + 1;
1165 sigpkt->sig.why_revoked = (char *)(void *)p; 1173 sigpkt->sig.why_revoked = (char *)(void *)p;
1166 break; 1174 break;
1167 default: 1175 default:
1168 printf("Ignoring unusual/reserved signature subpacket %d\n", subpkt.tag); 1176 printf("Ignoring unusual/reserved signature subpacket %d\n", subpkt.tag);
1169 break; 1177 break;
1170 } 1178 }
1171 subpkt.s.data = p; 1179 subpkt.s.data = p;
1172 p += subpkt.s.size - 1; 1180 p += subpkt.s.size - 1;
1173 ARRAY_APPEND(sigpkt->subpkts, subpkt); 1181 ARRAY_APPEND(sigpkt->subpackets, ARRAY_COUNT(pgp->subpkts));
 1182 ARRAY_APPEND(pgp->subpkts, subpkt);
1174 } 1183 }
1175 return 1; 1184 return 1;
1176} 1185}
1177 1186
1178/* parse signature packet */ 1187/* parse signature packet */
1179static int 1188static int
1180read_sigpkt(pgpv_t *pgp, uint8_t mement, pgpv_sigpkt_t *sigpkt, uint8_t *p, size_t pktlen) 1189read_sigpkt(pgpv_t *pgp, uint8_t mement, pgpv_sigpkt_t *sigpkt, uint8_t *p, size_t pktlen)
1181{ 1190{
1182 unsigned lenlen; 1191 unsigned lenlen;
1183 uint8_t *base; 1192 uint8_t *base;
1184 1193
1185 make_ref(pgp, mement, &sigpkt->sig.hashstart); 1194 make_ref(pgp, mement, &sigpkt->sig.hashstart);
1186 base = p; 1195 base = p;
1187 switch(sigpkt->sig.version = *p++) { 1196 switch(sigpkt->sig.version = *p++) {
1188 case 2: 1197 case 2:
1189 case 3: 1198 case 3:
1190 if ((lenlen = *p++) != 5) { 1199 if ((lenlen = *p++) != 5) {
1191 printf("read_sigpkt: hashed length not 5\n"); 1200 printf("read_sigpkt: hashed length not 5\n");
1192 return 0; 1201 return 0;
1193 } 1202 }
1194 sigpkt->sig.hashlen = lenlen; 1203 sigpkt->sig.hashlen = lenlen;
1195 /* put birthtime into a subpacket */ 1204 /* put birthtime into a subpacket */
1196 sigpkt->sig.type = *p++; 1205 sigpkt->sig.type = *p++;
1197 add_subpacket(sigpkt, SUBPKT_SIG_BIRTH, p, sizeof(uint32_t)); 1206 add_subpacket(pgp, sigpkt, SUBPKT_SIG_BIRTH, p, sizeof(uint32_t));
1198 sigpkt->sig.birth = (int64_t)get_32(p); 1207 sigpkt->sig.birth = (int64_t)get_32(p);
1199 p += sizeof(uint32_t); 1208 p += sizeof(uint32_t);
1200 sigpkt->sig.signer = p; 1209 memcpy(sigpkt->sig.signer, p, sizeof(sigpkt->sig.signer));
1201 add_subpacket(sigpkt, SUBPKT_SIGNER_ID, p, PGPV_KEYID_LEN); 1210 add_subpacket(pgp, sigpkt, SUBPKT_SIGNER_ID, p, PGPV_KEYID_LEN);
1202 p += PGPV_KEYID_LEN; 1211 p += PGPV_KEYID_LEN;
1203 sigpkt->sig.keyalg = *p++; 1212 sigpkt->sig.keyalg = *p++;
1204 sigpkt->sig.hashalg = *p++; 1213 sigpkt->sig.hashalg = *p++;
1205 sigpkt->sig.hash2 = p; 1214 sigpkt->sig.hash2 = p;
1206 if (!read_signature_mpis(sigpkt, sigpkt->sig.mpi = p + 2, pktlen)) { 1215 if (!read_signature_mpis(sigpkt, sigpkt->sig.mpi = p + 2, pktlen)) {
1207 printf("read_sigpkt: can't read sigs v3\n"); 1216 printf("read_sigpkt: can't read sigs v3\n");
1208 return 0; 1217 return 0;
1209 } 1218 }
1210 break; 1219 break;
1211 case 4: 1220 case 4:
1212 sigpkt->sig.type = *p++; 1221 sigpkt->sig.type = *p++;
1213 sigpkt->sig.keyalg = *p++; 1222 sigpkt->sig.keyalg = *p++;
1214 sigpkt->sig.hashalg = *p++; 1223 sigpkt->sig.hashalg = *p++;
1215 sigpkt->subslen = get_16(p); 1224 sigpkt->subslen = get_16(p);
1216 p += sizeof(sigpkt->subslen); 1225 p += sizeof(sigpkt->subslen);
1217 if (!read_sig_subpackets(sigpkt, p, pktlen)) { 1226 if (!read_sig_subpackets(pgp, sigpkt, p, pktlen)) {
1218 printf("read_sigpkt: can't read sig subpackets, v4\n"); 1227 printf("read_sigpkt: can't read sig subpackets, v4\n");
1219 return 0; 1228 return 0;
1220 } 1229 }
1221 if (!sigpkt->sig.signer) { 1230 if (sigpkt->sig.signer[0] == 0x0) {
1222 sigpkt->sig.signer = get_ref(&sigpkt->sig.hashstart) + 16; 1231 memcpy(sigpkt->sig.signer,
 1232 get_ref(&sigpkt->sig.hashstart) + 16,
 1233 sizeof(sigpkt->sig.signer));
1223 } 1234 }
1224 p += sigpkt->subslen; 1235 p += sigpkt->subslen;
1225 sigpkt->sig.hashlen = (unsigned)(p - base); 1236 sigpkt->sig.hashlen = (unsigned)(p - base);
1226 sigpkt->unhashlen = get_16(p); 1237 sigpkt->unhashlen = get_16(p);
1227 p += sizeof(sigpkt->unhashlen) + sigpkt->unhashlen; 1238 p += sizeof(sigpkt->unhashlen) + sigpkt->unhashlen;
1228 sigpkt->sig.hash2 = p; 1239 sigpkt->sig.hash2 = p;
1229 if (!read_signature_mpis(sigpkt, sigpkt->sig.mpi = p + 2, pktlen)) { 1240 if (!read_signature_mpis(sigpkt, sigpkt->sig.mpi = p + 2, pktlen)) {
1230 printf("read_sigpkt: can't read sigs, v4\n"); 1241 printf("read_sigpkt: can't read sigs, v4\n");
1231 return 0; 1242 return 0;
1232 } 1243 }
1233 break; 1244 break;
1234 default: 1245 default:
1235 printf("read_sigpkt: unusual signature version (%u)\n", sigpkt->sig.version); 1246 printf("read_sigpkt: unusual signature version (%u)\n", sigpkt->sig.version);
@@ -1433,28 +1444,29 @@ read_litdata(pgpv_t *pgp, pgpv_litdata_t @@ -1433,28 +1444,29 @@ read_litdata(pgpv_t *pgp, pgpv_litdata_t
1433 size_t cc; 1444 size_t cc;
1434 1445
1435 cc = 0; 1446 cc = 0;
1436 switch(litdata->format = p[cc++]) { 1447 switch(litdata->format = p[cc++]) {
1437 case LITDATA_BINARY: 1448 case LITDATA_BINARY:
1438 case LITDATA_TEXT: 1449 case LITDATA_TEXT:
1439 case LITDATA_UTF8: 1450 case LITDATA_UTF8:
1440 litdata->namelen = 0; 1451 litdata->namelen = 0;
1441 break; 1452 break;
1442 default: 1453 default:
1443 printf("weird litdata format %u\n", litdata->format); 1454 printf("weird litdata format %u\n", litdata->format);
1444 break; 1455 break;
1445 } 1456 }
1446 litdata->namelen = p[cc++]; 1457 litdata->filename.size = litdata->namelen = p[cc++];
1447 litdata->filename = &p[cc]; 1458 litdata->filename.data = &p[cc];
 1459 litdata->filename.allocated = 0;
1448 cc += litdata->namelen; 1460 cc += litdata->namelen;
1449 litdata->secs = get_32(&p[cc]); 1461 litdata->secs = get_32(&p[cc]);
1450 cc += 4; 1462 cc += 4;
1451 litdata->s.data = &p[cc]; 1463 litdata->s.data = &p[cc];
1452 litdata->len = litdata->s.size = size - cc; 1464 litdata->len = litdata->s.size = size - cc;
1453 litdata->mem = ARRAY_COUNT(pgp->areas) - 1; 1465 litdata->mem = ARRAY_COUNT(pgp->areas) - 1;
1454 litdata->offset = cc; 1466 litdata->offset = cc;
1455 return 1; 1467 return 1;
1456} 1468}
1457 1469
1458/* parse a single packet */ 1470/* parse a single packet */
1459static int 1471static int
1460read_pkt(pgpv_t *pgp, pgpv_mem_t *mem) 1472read_pkt(pgpv_t *pgp, pgpv_mem_t *mem)
@@ -1506,26 +1518,27 @@ read_pkt(pgpv_t *pgp, pgpv_mem_t *mem) @@ -1506,26 +1518,27 @@ read_pkt(pgpv_t *pgp, pgpv_mem_t *mem)
1506 case PUBKEY_PKT: 1518 case PUBKEY_PKT:
1507 case PUB_SUBKEY_PKT: 1519 case PUB_SUBKEY_PKT:
1508 break; 1520 break;
1509 case LITDATA_PKT: 1521 case LITDATA_PKT:
1510 read_litdata(pgp, &pkt.u.litdata, pkt.s.data, pkt.s.size); 1522 read_litdata(pgp, &pkt.u.litdata, pkt.s.data, pkt.s.size);
1511 break; 1523 break;
1512 case TRUST_PKT: 1524 case TRUST_PKT:
1513 pkt.u.trust.level = pkt.s.data[0]; 1525 pkt.u.trust.level = pkt.s.data[0];
1514 pkt.u.trust.amount = pkt.s.data[1]; 1526 pkt.u.trust.amount = pkt.s.data[1];
1515 break; 1527 break;
1516 case USERID_PKT: 1528 case USERID_PKT:
1517 pkt.u.userid.size = pkt.s.size; 1529 pkt.u.userid.size = pkt.s.size;
1518 pkt.u.userid.data = pkt.s.data; 1530 pkt.u.userid.data = pkt.s.data;
 1531 pkt.u.userid.allocated = 0;
1519 break; 1532 break;
1520 case COMPRESSED_DATA_PKT: 1533 case COMPRESSED_DATA_PKT:
1521 read_compressed(pgp, &pkt.u.compressed, pkt.s.data, pkt.s.size); 1534 read_compressed(pgp, &pkt.u.compressed, pkt.s.data, pkt.s.size);
1522 ARRAY_APPEND(pgp->pkts, pkt); 1535 ARRAY_APPEND(pgp->pkts, pkt);
1523 read_all_packets(pgp, &ARRAY_LAST(pgp->areas), pgp->op); 1536 read_all_packets(pgp, &ARRAY_LAST(pgp->areas), pgp->op);
1524 break; 1537 break;
1525 case USER_ATTRIBUTE_PKT: 1538 case USER_ATTRIBUTE_PKT:
1526 read_userattr(&pkt.u.userattr, pkt.s.data, pkt.s.size); 1539 read_userattr(&pkt.u.userattr, pkt.s.data, pkt.s.size);
1527 break; 1540 break;
1528 default: 1541 default:
1529 printf("hi, need to implement %d, offset %zu\n", pkt.tag, mem->cc); 1542 printf("hi, need to implement %d, offset %zu\n", pkt.tag, mem->cc);
1530 break; 1543 break;
1531 } 1544 }
@@ -1589,33 +1602,35 @@ static int @@ -1589,33 +1602,35 @@ static int
1589recog_userid(pgpv_t *pgp, pgpv_signed_userid_t *userid) 1602recog_userid(pgpv_t *pgp, pgpv_signed_userid_t *userid)
1590{ 1603{
1591 pgpv_signature_t signature; 1604 pgpv_signature_t signature;
1592 pgpv_pkt_t *pkt; 1605 pgpv_pkt_t *pkt;
1593 1606
1594 memset(userid, 0x0, sizeof(*userid)); 1607 memset(userid, 0x0, sizeof(*userid));
1595 if (!pkt_is(pgp, USERID_PKT)) { 1608 if (!pkt_is(pgp, USERID_PKT)) {
1596 printf("recog_userid: not %d\n", USERID_PKT); 1609 printf("recog_userid: not %d\n", USERID_PKT);
1597 return 0; 1610 return 0;
1598 } 1611 }
1599 pkt = &ARRAY_ELEMENT(pgp->pkts, pgp->pkt); 1612 pkt = &ARRAY_ELEMENT(pgp->pkts, pgp->pkt);
1600 userid->userid.size = pkt->s.size; 1613 userid->userid.size = pkt->s.size;
1601 userid->userid.data = pkt->s.data; 1614 userid->userid.data = pkt->s.data;
 1615 userid->userid.allocated = 0;
1602 pgp->pkt += 1; 1616 pgp->pkt += 1;
1603 while (pkt_is(pgp, SIGNATURE_PKT)) { 1617 while (pkt_is(pgp, SIGNATURE_PKT)) {
1604 if (!recog_signature(pgp, &signature)) { 1618 if (!recog_signature(pgp, &signature)) {
1605 printf("recog_userid: can't recognise signature/trust\n"); 1619 printf("recog_userid: can't recognise signature/trust\n");
1606 return 0; 1620 return 0;
1607 } 1621 }
1608 ARRAY_APPEND(userid->sigs, signature); 1622 ARRAY_APPEND(userid->signatures, ARRAY_COUNT(pgp->signatures));
 1623 ARRAY_APPEND(pgp->signatures, signature);
1609 if (signature.primary_userid) { 1624 if (signature.primary_userid) {
1610 userid->primary_userid = signature.primary_userid; 1625 userid->primary_userid = signature.primary_userid;
1611 } 1626 }
1612 if (signature.revoked) { 1627 if (signature.revoked) {
1613 userid->revoked = signature.revoked; 1628 userid->revoked = signature.revoked;
1614 } 1629 }
1615 } 1630 }
1616 return 1; 1631 return 1;
1617} 1632}
1618 1633
1619/* recognise user attributes packet */ 1634/* recognise user attributes packet */
1620static int 1635static int
1621recog_userattr(pgpv_t *pgp, pgpv_signed_userattr_t *userattr) 1636recog_userattr(pgpv_t *pgp, pgpv_signed_userattr_t *userattr)
@@ -1624,27 +1639,28 @@ recog_userattr(pgpv_t *pgp, pgpv_signed_ @@ -1624,27 +1639,28 @@ recog_userattr(pgpv_t *pgp, pgpv_signed_
1624 1639
1625 memset(userattr, 0x0, sizeof(*userattr)); 1640 memset(userattr, 0x0, sizeof(*userattr));
1626 if (!pkt_is(pgp, USER_ATTRIBUTE_PKT)) { 1641 if (!pkt_is(pgp, USER_ATTRIBUTE_PKT)) {
1627 printf("recog_userattr: not %d\n", USER_ATTRIBUTE_PKT); 1642 printf("recog_userattr: not %d\n", USER_ATTRIBUTE_PKT);
1628 return 0; 1643 return 0;
1629 } 1644 }
1630 userattr->userattr = ARRAY_ELEMENT(pgp->pkts, pgp->pkt).u.userattr; 1645 userattr->userattr = ARRAY_ELEMENT(pgp->pkts, pgp->pkt).u.userattr;
1631 pgp->pkt += 1; 1646 pgp->pkt += 1;
1632 while (pkt_is(pgp, SIGNATURE_PKT)) { 1647 while (pkt_is(pgp, SIGNATURE_PKT)) {
1633 if (!recog_signature(pgp, &signature)) { 1648 if (!recog_signature(pgp, &signature)) {
1634 printf("recog_userattr: can't recognise signature/trust\n"); 1649 printf("recog_userattr: can't recognise signature/trust\n");
1635 return 0; 1650 return 0;
1636 } 1651 }
1637 ARRAY_APPEND(userattr->sigs, signature); 1652 ARRAY_APPEND(userattr->signatures, ARRAY_COUNT(pgp->signatures));
 1653 ARRAY_APPEND(pgp->signatures, signature);
1638 if (signature.revoked) { 1654 if (signature.revoked) {
1639 userattr->revoked = signature.revoked; 1655 userattr->revoked = signature.revoked;
1640 } 1656 }
1641 } 1657 }
1642 return 1; 1658 return 1;
1643} 1659}
1644 1660
1645/* recognise a sub key */ 1661/* recognise a sub key */
1646static int 1662static int
1647recog_subkey(pgpv_t *pgp, pgpv_signed_subkey_t *subkey) 1663recog_subkey(pgpv_t *pgp, pgpv_signed_subkey_t *subkey)
1648{ 1664{
1649 pgpv_signature_t signature; 1665 pgpv_signature_t signature;
1650 pgpv_pkt_t *pkt; 1666 pgpv_pkt_t *pkt;
@@ -1658,27 +1674,28 @@ recog_subkey(pgpv_t *pgp, pgpv_signed_su @@ -1658,27 +1674,28 @@ recog_subkey(pgpv_t *pgp, pgpv_signed_su
1658 pkt_sigtype_is(pgp, SIGTYPE_CERT_REVOCATION)) { 1674 pkt_sigtype_is(pgp, SIGTYPE_CERT_REVOCATION)) {
1659 recog_signature(pgp, &signature); 1675 recog_signature(pgp, &signature);
1660 subkey->revoc_self_sig = signature; 1676 subkey->revoc_self_sig = signature;
1661 } 1677 }
1662 do { 1678 do {
1663 if (!pkt_is(pgp, SIGNATURE_PKT)) { 1679 if (!pkt_is(pgp, SIGNATURE_PKT)) {
1664 printf("recog_subkey: not signature packet at %zu\n", pgp->pkt); 1680 printf("recog_subkey: not signature packet at %zu\n", pgp->pkt);
1665 return 0; 1681 return 0;
1666 } 1682 }
1667 if (!recog_signature(pgp, &signature)) { 1683 if (!recog_signature(pgp, &signature)) {
1668 printf("recog_subkey: bad signature/trust at %zu\n", pgp->pkt); 1684 printf("recog_subkey: bad signature/trust at %zu\n", pgp->pkt);
1669 return 0; 1685 return 0;
1670 } 1686 }
1671 ARRAY_APPEND(subkey->sigs, signature); 1687 ARRAY_APPEND(subkey->signatures, ARRAY_COUNT(pgp->signatures));
 1688 ARRAY_APPEND(pgp->signatures, signature);
1672 if (signature.keyexpiry) { 1689 if (signature.keyexpiry) {
1673 /* XXX - check it's a good key expiry */ 1690 /* XXX - check it's a good key expiry */
1674 subkey->subkey.expiry = signature.keyexpiry; 1691 subkey->subkey.expiry = signature.keyexpiry;
1675 } 1692 }
1676 } while (pkt_is(pgp, SIGNATURE_PKT)); 1693 } while (pkt_is(pgp, SIGNATURE_PKT));
1677 return 1; 1694 return 1;
1678} 1695}
1679 1696
1680/* use a sparse map for the text strings here to save space */ 1697/* use a sparse map for the text strings here to save space */
1681static const char *keyalgs[] = { 1698static const char *keyalgs[] = {
1682 "[Unknown]", 1699 "[Unknown]",
1683 "RSA (Encrypt or Sign)", 1700 "RSA (Encrypt or Sign)",
1684 "RSA (Encrypt Only)", 1701 "RSA (Encrypt Only)",
@@ -1747,87 +1764,97 @@ fmt_pubkey(obuf_t *obuf, pgpv_pubkey_t * @@ -1747,87 +1764,97 @@ fmt_pubkey(obuf_t *obuf, pgpv_pubkey_t *
1747 } 1764 }
1748 } 1765 }
1749 if (!obuf_add_mem(obuf, "\n", 1)) { 1766 if (!obuf_add_mem(obuf, "\n", 1)) {
1750 return 0; 1767 return 0;
1751 } 1768 }
1752 return fmt_fingerprint(obuf, &pubkey->fingerprint, "fingerprint "); 1769 return fmt_fingerprint(obuf, &pubkey->fingerprint, "fingerprint ");
1753} 1770}
1754 1771
1755/* we add 1 to revocation value to denote compromised */ 1772/* we add 1 to revocation value to denote compromised */
1756#define COMPROMISED (0x02 + 1) 1773#define COMPROMISED (0x02 + 1)
1757 1774
1758/* format a userid - used to order the userids when formatting */ 1775/* format a userid - used to order the userids when formatting */
1759static int 1776static int
1760fmt_userid(obuf_t *obuf, pgpv_primarykey_t *primary, uint8_t u) 1777fmt_userid(obuf_t *obuf, pgpv_t *pgp, pgpv_primarykey_t *primary, uint8_t u)
1761{ 1778{
1762 pgpv_signed_userid_t *userid; 1779 pgpv_signed_userid_t *userid;
1763 const char *s; 1780 const char *s;
 1781 uint64_t id;
1764 1782
1765 userid = &ARRAY_ELEMENT(primary->signed_userids, u); 1783 id = ARRAY_ELEMENT(primary->signed_userids, u);
 1784 userid = &ARRAY_ELEMENT(pgp->signed_userids, id);
1766 s = (userid->revoked == COMPROMISED) ? " [COMPROMISED AND REVOKED]\n" : 1785 s = (userid->revoked == COMPROMISED) ? " [COMPROMISED AND REVOKED]\n" :
1767 (userid->revoked) ? " [REVOKED]\n" : "\n"; 1786 (userid->revoked) ? " [REVOKED]\n" : "\n";
1768 return obuf_add_mem(obuf, "uid ", 14) && 1787 return obuf_add_mem(obuf, "uid ", 14) &&
1769 obuf_add_mem(obuf, userid->userid.data, userid->userid.size) && 1788 obuf_add_mem(obuf, userid->userid.data, userid->userid.size) &&
1770 obuf_add_mem(obuf, s, strlen(s)); 1789 obuf_add_mem(obuf, s, strlen(s));
1771} 1790}
1772 1791
1773/* format a trust sig - used to order the userids when formatting */ 1792/* format a trust sig - used to order the userids when formatting */
1774static int 1793static int
1775fmt_trust(obuf_t *obuf, pgpv_signed_userid_t *userid, uint32_t u) 1794fmt_trust(obuf_t *obuf, pgpv_signature_t *sig)
1776{ 1795{
1777 pgpv_signature_t *sig; 
1778 
1779 sig = &ARRAY_ELEMENT(userid->sigs, u); 
1780 if (!obuf_add_mem(obuf, "trust ", 15) || 1796 if (!obuf_add_mem(obuf, "trust ", 15) ||
1781 !fmt_binary(obuf, sig->signer, 8)) { 1797 !fmt_binary(obuf, sig->signer, PGPV_KEYID_LEN)) {
1782 return 0; 1798 return 0;
1783 } 1799 }
1784 return obuf_add_mem(obuf, "\n", 1); 1800 return obuf_add_mem(obuf, "\n", 1);
1785} 1801}
1786 1802
1787/* print a primary key, per RFC 4880 */ 1803/* print a primary key, per RFC 4880 */
1788static int 1804static int
1789fmt_primary(obuf_t *obuf, pgpv_primarykey_t *primary, unsigned subkey, const char *modifiers) 1805fmt_primary(obuf_t *obuf, pgpv_t *pgp, pgpv_primarykey_t *primary, unsigned subkey, const char *modifiers)
1790{ 1806{
1791 pgpv_signed_userid_t *userid; 1807 pgpv_signed_userid_t *userid;
 1808 pgpv_signed_subkey_t *signed_subkey;
1792 pgpv_pubkey_t *pubkey; 1809 pgpv_pubkey_t *pubkey;
1793 unsigned i; 1810 unsigned i;
1794 unsigned j; 1811 unsigned j;
 1812 uint64_t id;
1795 1813
1796 pubkey = (subkey == 0) ? &primary->primary : &ARRAY_ELEMENT(primary->signed_subkeys, subkey - 1).subkey; 1814 if (subkey == 0) {
 1815 pubkey = &primary->primary;
 1816 } else {
 1817 id = ARRAY_ELEMENT(primary->signed_subkeys, subkey);
 1818 pubkey = &ARRAY_ELEMENT(pgp->signed_subkeys, id - 1).subkey;
 1819 }
1797 if (!fmt_pubkey(obuf, pubkey, "signature ")) { 1820 if (!fmt_pubkey(obuf, pubkey, "signature ")) {
1798 return 0; 1821 return 0;
1799 } 1822 }
1800 if (!fmt_userid(obuf, primary, primary->primary_userid)) { 1823 if (!fmt_userid(obuf, pgp, primary, primary->primary_userid)) {
1801 return 0; 1824 return 0;
1802 } 1825 }
1803 for (i = 0 ; i < ARRAY_COUNT(primary->signed_userids) ; i++) { 1826 for (i = 0 ; i < ARRAY_COUNT(primary->signed_userids) ; i++) {
1804 if (i != primary->primary_userid) { 1827 if (i != primary->primary_userid) {
1805 if (!fmt_userid(obuf, primary, i)) { 1828 if (!fmt_userid(obuf, pgp, primary, i)) {
1806 return 0; 1829 return 0;
1807 } 1830 }
1808 if (strcasecmp(modifiers, "trust") == 0) { 1831 if (strcasecmp(modifiers, "trust") == 0) {
1809 userid = &ARRAY_ELEMENT(primary->signed_userids, i); 1832 id = ARRAY_ELEMENT(primary->signed_userids, i);
1810 for (j = 0 ; j < ARRAY_COUNT(userid->sigs) ; j++) { 1833 userid = &ARRAY_ELEMENT(pgp->signed_userids, id);
1811 if (!fmt_trust(obuf, userid, j)) { 1834 for (j = 0 ; j < ARRAY_COUNT(userid->signatures) ; j++) {
 1835 if (!fmt_trust(obuf, &ARRAY_ELEMENT(pgp->signatures,
 1836 ARRAY_ELEMENT(userid->signatures, j)))) {
1812 return 0; 1837 return 0;
1813 } 1838 }
1814 } 1839 }
1815 } 1840 }
1816 } 1841 }
1817 } 1842 }
1818 if (strcasecmp(modifiers, "subkeys") == 0) { 1843 if (strcasecmp(modifiers, "subkeys") == 0) {
1819 for (i = 0 ; i < ARRAY_COUNT(primary->signed_subkeys) ; i++) { 1844 for (i = 0 ; i < ARRAY_COUNT(primary->signed_subkeys) ; i++) {
1820 if (!fmt_pubkey(obuf, &ARRAY_ELEMENT(primary->signed_subkeys, i).subkey, "encryption")) { 1845 id = ARRAY_ELEMENT(primary->signed_subkeys, i);
 1846 signed_subkey = &ARRAY_ELEMENT(pgp->signed_subkeys, id);
 1847 if (!fmt_pubkey(obuf, &signed_subkey->subkey, "encryption")) {
1821 return 0; 1848 return 0;
1822 } 1849 }
1823 } 1850 }
1824 } 1851 }
1825 return obuf_add_mem(obuf, "\n", 1); 1852 return obuf_add_mem(obuf, "\n", 1);
1826} 1853}
1827 1854
1828 1855
1829/* check the padding on the signature */ 1856/* check the padding on the signature */
1830static int 1857static int
1831rsa_padding_check_none(uint8_t *to, int tlen, const uint8_t *from, int flen, int num) 1858rsa_padding_check_none(uint8_t *to, int tlen, const uint8_t *from, int flen, int num)
1832{ 1859{
1833 USE_ARG(num); 1860 USE_ARG(num);
@@ -2199,26 +2226,40 @@ find_bin_string(const void *blockarg, si @@ -2199,26 +2226,40 @@ find_bin_string(const void *blockarg, si
2199 return __UNCONST(blockarg); 2226 return __UNCONST(blockarg);
2200 } 2227 }
2201 if (blen < plen) { 2228 if (blen < plen) {
2202 return NULL; 2229 return NULL;
2203 } 2230 }
2204 for (bp = block = blockarg ; (size_t)(bp - block) < blen - plen + 1 ; bp++) { 2231 for (bp = block = blockarg ; (size_t)(bp - block) < blen - plen + 1 ; bp++) {
2205 if (memcmp(bp, pat, plen) == 0) { 2232 if (memcmp(bp, pat, plen) == 0) {
2206 return __UNCONST(bp); 2233 return __UNCONST(bp);
2207 } 2234 }
2208 } 2235 }
2209 return NULL; 2236 return NULL;
2210} 2237}
2211 2238
 2239/* store string in allocated memory */
 2240static uint8_t *
 2241pgpv_strdup(const char *s)
 2242{
 2243 uint8_t *cp;
 2244 size_t len;
 2245
 2246 len = strlen(s);
 2247 if ((cp = calloc(len + 1, 1)) != NULL) {
 2248 memcpy(cp, s, len);
 2249 }
 2250 return cp;
 2251}
 2252
2212#define SIGSTART "-----BEGIN PGP SIGNATURE-----\n" 2253#define SIGSTART "-----BEGIN PGP SIGNATURE-----\n"
2213#define SIGEND "-----END PGP SIGNATURE-----\n" 2254#define SIGEND "-----END PGP SIGNATURE-----\n"
2214 2255
2215/* for ascii armor, we don't get a onepass packet - make one */ 2256/* for ascii armor, we don't get a onepass packet - make one */
2216static const char *cons_onepass = "\304\015\003\0\0\0\0\377\377\377\377\377\377\377\377\1"; 2257static const char *cons_onepass = "\304\015\003\0\0\0\0\377\377\377\377\377\377\377\377\1";
2217 2258
2218/* read ascii armor */ 2259/* read ascii armor */
2219static int 2260static int
2220read_ascii_armor(pgpv_cursor_t *cursor, pgpv_mem_t *mem, const char *filename) 2261read_ascii_armor(pgpv_cursor_t *cursor, pgpv_mem_t *mem, const char *filename)
2221{ 2262{
2222 pgpv_onepass_t *onepass; 2263 pgpv_onepass_t *onepass;
2223 pgpv_sigpkt_t *sigpkt; 2264 pgpv_sigpkt_t *sigpkt;
2224 pgpv_pkt_t litdata; 2265 pgpv_pkt_t litdata;
@@ -2231,27 +2272,28 @@ read_ascii_armor(pgpv_cursor_t *cursor,  @@ -2231,27 +2272,28 @@ read_ascii_armor(pgpv_cursor_t *cursor,
2231 /* cons up litdata pkt */ 2272 /* cons up litdata pkt */
2232 memset(&litdata, 0x0, sizeof(litdata)); 2273 memset(&litdata, 0x0, sizeof(litdata));
2233 litdata.u.litdata.mem = ARRAY_COUNT(cursor->pgp->areas) - 1; 2274 litdata.u.litdata.mem = ARRAY_COUNT(cursor->pgp->areas) - 1;
2234 p = mem->mem; 2275 p = mem->mem;
2235 /* jump over signed message line */ 2276 /* jump over signed message line */
2236 if ((p = find_bin_string(mem->mem, mem->size, "\n\n", 2)) == NULL) { 2277 if ((p = find_bin_string(mem->mem, mem->size, "\n\n", 2)) == NULL) {
2237 snprintf(cursor->why, sizeof(cursor->why), "malformed armor at offset 0"); 2278 snprintf(cursor->why, sizeof(cursor->why), "malformed armor at offset 0");
2238 return 0; 2279 return 0;
2239 } 2280 }
2240 p += 2; 2281 p += 2;
2241 litdata.tag = LITDATA_PKT; 2282 litdata.tag = LITDATA_PKT;
2242 litdata.s.data = p; 2283 litdata.s.data = p;
2243 litdata.u.litdata.offset = (size_t)(p - mem->mem); 2284 litdata.u.litdata.offset = (size_t)(p - mem->mem);
2244 litdata.u.litdata.filename = (uint8_t *)strdup(filename); 2285 litdata.u.litdata.filename.data = pgpv_strdup(filename);
 2286 litdata.u.litdata.filename.allocated = 1;
2245 if ((p = find_bin_string(datastart = p, mem->size - litdata.offset, SIGSTART, strlen(SIGSTART))) == NULL) { 2287 if ((p = find_bin_string(datastart = p, mem->size - litdata.offset, SIGSTART, strlen(SIGSTART))) == NULL) {
2246 snprintf(cursor->why, sizeof(cursor->why), 2288 snprintf(cursor->why, sizeof(cursor->why),
2247 "malformed armor - no sig - at %zu", (size_t)(p - mem->mem)); 2289 "malformed armor - no sig - at %zu", (size_t)(p - mem->mem));
2248 return 0; 2290 return 0;
2249 } 2291 }
2250 litdata.u.litdata.len = litdata.s.size = (size_t)(p - datastart); 2292 litdata.u.litdata.len = litdata.s.size = (size_t)(p - datastart);
2251 /* this puts p at the newline character, so it will find \n\n if no version */ 2293 /* this puts p at the newline character, so it will find \n\n if no version */
2252 p += strlen(SIGSTART) - 1; 2294 p += strlen(SIGSTART) - 1;
2253 if ((p = find_bin_string(p, mem->size, "\n\n", 2)) == NULL) { 2295 if ((p = find_bin_string(p, mem->size, "\n\n", 2)) == NULL) {
2254 snprintf(cursor->why, sizeof(cursor->why), 2296 snprintf(cursor->why, sizeof(cursor->why),
2255 "malformed armed signature at %zu", (size_t)(p - mem->mem)); 2297 "malformed armed signature at %zu", (size_t)(p - mem->mem));
2256 return 0; 2298 return 0;
2257 } 2299 }
@@ -2404,62 +2446,67 @@ recog_primary_key(pgpv_t *pgp, pgpv_prim @@ -2404,62 +2446,67 @@ recog_primary_key(pgpv_t *pgp, pgpv_prim
2404 printf("recog_primary_key: no signature/trust at PGPV_SIGTYPE_KEY_REVOCATION\n"); 2446 printf("recog_primary_key: no signature/trust at PGPV_SIGTYPE_KEY_REVOCATION\n");
2405 return 0; 2447 return 0;
2406 } 2448 }
2407 } 2449 }
2408 while (pkt_sigtype_is(pgp, SIGTYPE_DIRECT_KEY)) { 2450 while (pkt_sigtype_is(pgp, SIGTYPE_DIRECT_KEY)) {
2409 if (!recog_signature(pgp, &signature)) { 2451 if (!recog_signature(pgp, &signature)) {
2410 printf("recog_primary_key: no signature/trust at PGPV_SIGTYPE_DIRECT_KEY\n"); 2452 printf("recog_primary_key: no signature/trust at PGPV_SIGTYPE_DIRECT_KEY\n");
2411 return 0; 2453 return 0;
2412 } 2454 }
2413 if (signature.keyexpiry) { 2455 if (signature.keyexpiry) {
2414 /* XXX - check it's a good key expiry */ 2456 /* XXX - check it's a good key expiry */
2415 primary->primary.expiry = signature.keyexpiry; 2457 primary->primary.expiry = signature.keyexpiry;
2416 } 2458 }
2417 ARRAY_APPEND(primary->direct_sigs, signature); 2459 ARRAY_APPEND(primary->signatures, ARRAY_COUNT(pgp->signatures));
 2460 ARRAY_APPEND(pgp->signatures, signature);
2418 } 2461 }
2419 /* some keys out there have user ids where they shouldn't */ 2462 /* some keys out there have user ids where they shouldn't */
2420 do { 2463 do {
2421 if (!recog_userid(pgp, &userid)) { 2464 if (!recog_userid(pgp, &userid)) {
2422 printf("recog_primary_key: not userid\n"); 2465 printf("recog_primary_key: not userid\n");
2423 return 0; 2466 return 0;
2424 } 2467 }
2425 ARRAY_APPEND(primary->signed_userids, userid); 2468 ARRAY_APPEND(primary->signed_userids, ARRAY_COUNT(pgp->signed_userids));
 2469 ARRAY_APPEND(pgp->signed_userids, userid);
2426 if (userid.primary_userid) { 2470 if (userid.primary_userid) {
2427 primary->primary_userid = ARRAY_COUNT(primary->signed_userids) - 1; 2471 primary->primary_userid = ARRAY_COUNT(primary->signed_userids) - 1;
2428 } 2472 }
2429 while (pkt_is(pgp, USERID_PKT)) { 2473 while (pkt_is(pgp, USERID_PKT)) {
2430 if (!recog_userid(pgp, &userid)) { 2474 if (!recog_userid(pgp, &userid)) {
2431 printf("recog_primary_key: not signed secondary userid\n"); 2475 printf("recog_primary_key: not signed secondary userid\n");
2432 return 0; 2476 return 0;
2433 } 2477 }
2434 ARRAY_APPEND(primary->signed_userids, userid); 2478 ARRAY_APPEND(primary->signed_userids, ARRAY_COUNT(pgp->signed_userids));
 2479 ARRAY_APPEND(pgp->signed_userids, userid);
2435 if (userid.primary_userid) { 2480 if (userid.primary_userid) {
2436 primary->primary_userid = ARRAY_COUNT(primary->signed_userids) - 1; 2481 primary->primary_userid = ARRAY_COUNT(primary->signed_userids) - 1;
2437 } 2482 }
2438 } 2483 }
2439 while (pkt_is(pgp, USER_ATTRIBUTE_PKT)) { 2484 while (pkt_is(pgp, USER_ATTRIBUTE_PKT)) {
2440 if (!recog_userattr(pgp, &userattr)) { 2485 if (!recog_userattr(pgp, &userattr)) {
2441 printf("recog_primary_key: not signed user attribute\n"); 2486 printf("recog_primary_key: not signed user attribute\n");
2442 return 0; 2487 return 0;
2443 } 2488 }
2444 ARRAY_APPEND(primary->signed_userattrs, userattr); 2489 ARRAY_APPEND(primary->signed_userattrs, ARRAY_COUNT(pgp->signed_userattrs));
 2490 ARRAY_APPEND(pgp->signed_userattrs, userattr);
2445 } 2491 }
2446 while (pkt_is(pgp, PUB_SUBKEY_PKT)) { 2492 while (pkt_is(pgp, PUB_SUBKEY_PKT)) {
2447 if (!recog_subkey(pgp, &subkey)) { 2493 if (!recog_subkey(pgp, &subkey)) {
2448 printf("recog_primary_key: not signed public subkey\n"); 2494 printf("recog_primary_key: not signed public subkey\n");
2449 return 0; 2495 return 0;
2450 } 2496 }
2451 calc_keyid(&subkey.subkey, "sha1"); 2497 calc_keyid(&subkey.subkey, "sha1");
2452 ARRAY_APPEND(primary->signed_subkeys, subkey); 2498 ARRAY_APPEND(primary->signed_subkeys, ARRAY_COUNT(pgp->signed_subkeys));
 2499 ARRAY_APPEND(pgp->signed_subkeys, subkey);
2453 } 2500 }
2454 } while (pgp->pkt < ARRAY_COUNT(pgp->pkts) && pkt_is(pgp, USERID_PKT)); 2501 } while (pgp->pkt < ARRAY_COUNT(pgp->pkts) && pkt_is(pgp, USERID_PKT));
2455 primary->fmtsize = estimate_primarykey_size(primary); 2502 primary->fmtsize = estimate_primarykey_size(primary);
2456 return 1; 2503 return 1;
2457} 2504}
2458 2505
2459/* parse all of the packets for a given operation */ 2506/* parse all of the packets for a given operation */
2460static int 2507static int
2461read_all_packets(pgpv_t *pgp, pgpv_mem_t *mem, const char *op) 2508read_all_packets(pgpv_t *pgp, pgpv_mem_t *mem, const char *op)
2462{ 2509{
2463 pgpv_primarykey_t primary; 2510 pgpv_primarykey_t primary;
2464 2511
2465 if (op == NULL) { 2512 if (op == NULL) {
@@ -2678,31 +2725,33 @@ read_ssh_file(pgpv_t *pgp, pgpv_primaryk @@ -2678,31 +2725,33 @@ read_ssh_file(pgpv_t *pgp, pgpv_primaryk
2678 (void) gethostname(hostname, sizeof(hostname)); 2725 (void) gethostname(hostname, sizeof(hostname));
2679 if (strlen(space + 1) - 1 == 0) { 2726 if (strlen(space + 1) - 1 == 0) {
2680 (void) snprintf(owner, sizeof(owner), "<root@%s>", 2727 (void) snprintf(owner, sizeof(owner), "<root@%s>",
2681 hostname); 2728 hostname);
2682 } else { 2729 } else {
2683 (void) snprintf(owner, sizeof(owner), "<%.*s>", 2730 (void) snprintf(owner, sizeof(owner), "<%.*s>",
2684 (int)strlen(space + 1) - 1, 2731 (int)strlen(space + 1) - 1,
2685 space + 1); 2732 space + 1);
2686 } 2733 }
2687 calc_keyid(pubkey, "sha1"); 2734 calc_keyid(pubkey, "sha1");
2688 cc = snprintf(newbuf, sizeof(newbuf), "%s (%s) %s", 2735 cc = snprintf(newbuf, sizeof(newbuf), "%s (%s) %s",
2689 hostname, f, owner); 2736 hostname, f, owner);
2690 userid.userid.size = cc; 2737 userid.userid.size = cc;
 2738 userid.userid.allocated = 1;
2691 if ((userid.userid.data = calloc(1, cc + 1)) == NULL) { 2739 if ((userid.userid.data = calloc(1, cc + 1)) == NULL) {
2692 ok = 0; 2740 ok = 0;
2693 } else { 2741 } else {
2694 memcpy(userid.userid.data, newbuf, cc); 2742 memcpy(userid.userid.data, newbuf, cc);
2695 ARRAY_APPEND(primary->signed_userids, userid); 2743 ARRAY_APPEND(primary->signed_userids, ARRAY_COUNT(pgp->signed_userids));
 2744 ARRAY_APPEND(pgp->signed_userids, userid);
2696 primary->fmtsize = estimate_primarykey_size(primary) + 1024; 2745 primary->fmtsize = estimate_primarykey_size(primary) + 1024;
2697 } 2746 }
2698 } 2747 }
2699 (void) free(bin); 2748 (void) free(bin);
2700 (void) free(buf); 2749 (void) free(buf);
2701 bufgap_close(&bg); 2750 bufgap_close(&bg);
2702 return ok; 2751 return ok;
2703} 2752}
2704 2753
2705/* parse memory according to "op" */ 2754/* parse memory according to "op" */
2706static int 2755static int
2707read_binary_memory(pgpv_t *pgp, const char *op, const void *memory, size_t size) 2756read_binary_memory(pgpv_t *pgp, const char *op, const void *memory, size_t size)
2708{ 2757{
@@ -2745,27 +2794,28 @@ fixup_detached(pgpv_cursor_t *cursor, co @@ -2745,27 +2794,28 @@ fixup_detached(pgpv_cursor_t *cursor, co
2745 onepass = &ARRAY_ELEMENT(cursor->pgp->pkts, el).u.onepass; 2794 onepass = &ARRAY_ELEMENT(cursor->pgp->pkts, el).u.onepass;
2746 /* read the original file into litdata */ 2795 /* read the original file into litdata */
2747 snprintf(original, sizeof(original), "%.*s", (int)(dot - f), f); 2796 snprintf(original, sizeof(original), "%.*s", (int)(dot - f), f);
2748 if (!read_file(cursor->pgp, original)) { 2797 if (!read_file(cursor->pgp, original)) {
2749 printf("can't read file '%s'\n", original); 2798 printf("can't read file '%s'\n", original);
2750 return 0; 2799 return 0;
2751 } 2800 }
2752 memset(&litdata, 0x0, sizeof(litdata)); 2801 memset(&litdata, 0x0, sizeof(litdata));
2753 mem = &ARRAY_LAST(cursor->pgp->areas); 2802 mem = &ARRAY_LAST(cursor->pgp->areas);
2754 litdata.tag = LITDATA_PKT; 2803 litdata.tag = LITDATA_PKT;
2755 litdata.s.data = mem->mem; 2804 litdata.s.data = mem->mem;
2756 litdata.u.litdata.format = LITDATA_BINARY; 2805 litdata.u.litdata.format = LITDATA_BINARY;
2757 litdata.u.litdata.offset = 0; 2806 litdata.u.litdata.offset = 0;
2758 litdata.u.litdata.filename = (uint8_t *)strdup(original); 2807 litdata.u.litdata.filename.data = pgpv_strdup(original);
 2808 litdata.u.litdata.filename.allocated = 1;
2759 litdata.u.litdata.mem = ARRAY_COUNT(cursor->pgp->areas) - 1; 2809 litdata.u.litdata.mem = ARRAY_COUNT(cursor->pgp->areas) - 1;
2760 litdata.u.litdata.len = litdata.s.size = mem->size; 2810 litdata.u.litdata.len = litdata.s.size = mem->size;
2761 ARRAY_APPEND(cursor->pgp->pkts, litdata); 2811 ARRAY_APPEND(cursor->pgp->pkts, litdata);
2762 ARRAY_APPEND(cursor->pgp->pkts, sigpkt); 2812 ARRAY_APPEND(cursor->pgp->pkts, sigpkt);
2763 memcpy(onepass->keyid, sigpkt.u.sigpkt.sig.signer, sizeof(onepass->keyid)); 2813 memcpy(onepass->keyid, sigpkt.u.sigpkt.sig.signer, sizeof(onepass->keyid));
2764 onepass->hashalg = sigpkt.u.sigpkt.sig.hashalg; 2814 onepass->hashalg = sigpkt.u.sigpkt.sig.hashalg;
2765 onepass->keyalg = sigpkt.u.sigpkt.sig.keyalg; 2815 onepass->keyalg = sigpkt.u.sigpkt.sig.keyalg;
2766 return 1; 2816 return 1;
2767} 2817}
2768 2818
2769/* match the calculated signature against the one in the signature packet */ 2819/* match the calculated signature against the one in the signature packet */
2770static int 2820static int
2771match_sig(pgpv_cursor_t *cursor, pgpv_signature_t *signature, pgpv_pubkey_t *pubkey, uint8_t *data, size_t size) 2821match_sig(pgpv_cursor_t *cursor, pgpv_signature_t *signature, pgpv_pubkey_t *pubkey, uint8_t *data, size_t size)
@@ -2804,155 +2854,104 @@ match_sig(pgpv_cursor_t *cursor, pgpv_si @@ -2804,155 +2854,104 @@ match_sig(pgpv_cursor_t *cursor, pgpv_si
2804 if (valid_dates(signature, pubkey, cursor->why, sizeof(cursor->why)) > 0) { 2854 if (valid_dates(signature, pubkey, cursor->why, sizeof(cursor->why)) > 0) {
2805 return 0; 2855 return 0;
2806 } 2856 }
2807 if (key_expired(pubkey, cursor->why, sizeof(cursor->why))) { 2857 if (key_expired(pubkey, cursor->why, sizeof(cursor->why))) {
2808 return 0; 2858 return 0;
2809 } 2859 }
2810 if (signature->revoked) { 2860 if (signature->revoked) {
2811 snprintf(cursor->why, sizeof(cursor->why), "Signature was revoked"); 2861 snprintf(cursor->why, sizeof(cursor->why), "Signature was revoked");
2812 return 0; 2862 return 0;
2813 } 2863 }
2814 return 1; 2864 return 1;
2815} 2865}
2816 2866
2817/* check return value from getenv */ 
2818static const char * 
2819nonnull_getenv(const char *key) 
2820{ 
2821 char *value; 
2822 
2823 return ((value = getenv(key)) == NULL) ? "" : value; 
2824} 
2825 
2826/************************************************************************/ 
2827/* start of exported functions */ 
2828/************************************************************************/ 
2829 
2830/* close all stuff */ 
2831int 
2832pgpv_close(pgpv_t *pgp) 
2833{ 
2834 unsigned i; 
2835 
2836 if (pgp == NULL) { 
2837 return 0; 
2838 } 
2839 for (i = 0 ; i < ARRAY_COUNT(pgp->areas) ; i++) { 
2840 if (ARRAY_ELEMENT(pgp->areas, i).size > 0) { 
2841 closemem(&ARRAY_ELEMENT(pgp->areas, i)); 
2842 } 
2843 } 
2844 return 1; 
2845} 
2846 
2847/* return the formatted entry for the primary key desired */ 
2848size_t 
2849pgpv_get_entry(pgpv_t *pgp, unsigned ent, char **s, const char *modifiers) 
2850{ 
2851 unsigned subkey; 
2852 unsigned prim; 
2853 obuf_t obuf; 
2854 
2855 prim = ((ent >> 8) & 0xffffff); 
2856 subkey = (ent & 0xff); 
2857 if (s == NULL || pgp == NULL || prim >= ARRAY_COUNT(pgp->primaries)) { 
2858 return 0; 
2859 } 
2860 *s = NULL; 
2861 if (modifiers == NULL || (strcasecmp(modifiers, "trust") != 0 && strcasecmp(modifiers, "subkeys") != 0)) { 
2862 modifiers = "no-subkeys"; 
2863 } 
2864 memset(&obuf, 0x0, sizeof(obuf)); 
2865 if (!fmt_primary(&obuf, &ARRAY_ELEMENT(pgp->primaries, prim), subkey, modifiers)) { 
2866 return 0; 
2867 } 
2868 *s = (char *)obuf.v; 
2869 return obuf.c; 
2870} 
2871 
2872/* fixup key id, with birth, keyalg and hashalg value from signature */ 2867/* fixup key id, with birth, keyalg and hashalg value from signature */
2873static int 2868static int
2874fixup_ssh_keyid(pgpv_t *pgp, pgpv_signature_t *signature, const char *hashtype) 2869fixup_ssh_keyid(pgpv_t *pgp, pgpv_signature_t *signature, const char *hashtype)
2875{ 2870{
2876 pgpv_pubkey_t *pubkey; 2871 pgpv_pubkey_t *pubkey;
2877 unsigned i; 2872 unsigned i;
2878 2873
2879 for (i = 0 ; i < ARRAY_COUNT(pgp->primaries) ; i++) { 2874 for (i = 0 ; i < ARRAY_COUNT(pgp->primaries) ; i++) {
2880 pubkey = &ARRAY_ELEMENT(pgp->primaries, i).primary; 2875 pubkey = &ARRAY_ELEMENT(pgp->primaries, i).primary;
2881 pubkey->keyalg = signature->keyalg; 2876 pubkey->keyalg = signature->keyalg;
2882 calc_keyid(pubkey, hashtype); 2877 calc_keyid(pubkey, hashtype);
2883 } 2878 }
2884 return 1; 2879 return 1;
2885} 2880}
2886 2881
2887/* find key id */ 2882/* find key id */
2888static int 2883static int
2889find_keyid(pgpv_t *pgp, const char *strkeyid, uint8_t *keyid, unsigned *sub) 2884find_keyid(pgpv_t *pgp, const char *strkeyid, uint8_t *keyid, unsigned *sub)
2890{ 2885{
2891 pgpv_signed_subkey_t *subkey; 2886 pgpv_signed_subkey_t *subkey;
2892 pgpv_primarykey_t *prim; 2887 pgpv_primarykey_t *prim;
2893 unsigned i; 2888 unsigned i;
2894 unsigned j; 2889 unsigned j;
 2890 uint64_t n;
2895 uint8_t binkeyid[PGPV_KEYID_LEN]; 2891 uint8_t binkeyid[PGPV_KEYID_LEN];
2896 size_t off; 2892 size_t off;
2897 size_t cmp; 2893 size_t cmp;
2898 2894
2899 if (strkeyid == NULL && keyid == NULL) { 2895 if (strkeyid == NULL && keyid == NULL) {
2900 return 0; 2896 return 0;
2901 } 2897 }
2902 if (strkeyid) { 2898 if (strkeyid) {
2903 str_to_keyid(strkeyid, binkeyid); 2899 str_to_keyid(strkeyid, binkeyid);
2904 cmp = strlen(strkeyid) / 2; 2900 cmp = strlen(strkeyid) / 2;
2905 } else { 2901 } else {
2906 memcpy(binkeyid, keyid, sizeof(binkeyid)); 2902 memcpy(binkeyid, keyid, sizeof(binkeyid));
2907 cmp = PGPV_KEYID_LEN; 2903 cmp = PGPV_KEYID_LEN;
2908 } 2904 }
2909 *sub = 0; 2905 *sub = 0;
2910 off = PGPV_KEYID_LEN - cmp; 2906 off = PGPV_KEYID_LEN - cmp;
2911 for (i = 0 ; i < ARRAY_COUNT(pgp->primaries) ; i++) { 2907 for (i = 0 ; i < ARRAY_COUNT(pgp->primaries) ; i++) {
2912 prim = &ARRAY_ELEMENT(pgp->primaries, i); 2908 prim = &ARRAY_ELEMENT(pgp->primaries, i);
2913 if (memcmp(&prim->primary.keyid[off], &binkeyid[off], cmp) == 0) { 2909 if (memcmp(&prim->primary.keyid[off], &binkeyid[off], cmp) == 0) {
2914 return i; 2910 return i;
2915 } 2911 }
2916 for (j = 0 ; j < ARRAY_COUNT(prim->signed_subkeys) ; j++) { 2912 for (j = 0 ; j < ARRAY_COUNT(prim->signed_subkeys) ; j++) {
2917 subkey = &ARRAY_ELEMENT(prim->signed_subkeys, j); 2913 n = ARRAY_ELEMENT(prim->signed_subkeys, j);
 2914 subkey = &ARRAY_ELEMENT(pgp->signed_subkeys, n);
2918 if (memcmp(&subkey->subkey.keyid[off], &binkeyid[off], cmp) == 0) { 2915 if (memcmp(&subkey->subkey.keyid[off], &binkeyid[off], cmp) == 0) {
2919 *sub = j + 1; 2916 *sub = j + 1;
2920 return i; 2917 return i;
2921 } 2918 }
2922 } 2919 }
2923 2920
2924 } 2921 }
2925 return -1; 2922 return -1;
2926} 2923}
2927 2924
2928/* match the signature with the id indexed by 'primary' */ 2925/* match the signature with the id indexed by 'primary' */
2929static int 2926static int
2930match_sig_id(pgpv_cursor_t *cursor, pgpv_signature_t *signature, pgpv_litdata_t *litdata, unsigned primary, unsigned sub) 2927match_sig_id(pgpv_cursor_t *cursor, pgpv_t *pgp, pgpv_signature_t *signature, pgpv_litdata_t *litdata, unsigned primary, unsigned sub)
2931{ 2928{
2932 pgpv_primarykey_t *prim; 2929 pgpv_primarykey_t *prim;
2933 pgpv_pubkey_t *pubkey; 2930 pgpv_pubkey_t *pubkey;
 2931 uint64_t n;
2934 uint8_t *data; 2932 uint8_t *data;
2935 size_t insize; 2933 size_t insize;
2936 2934
2937 cursor->sigtime = signature->birth; 2935 cursor->sigtime = signature->birth;
2938 /* calc hash on data packet */ 2936 /* calc hash on data packet */
2939 data = get_literal_data(cursor, litdata, &insize); 2937 data = get_literal_data(cursor, litdata, &insize);
2940 if (sub == 0) { 2938 if (sub == 0) {
2941 pubkey = &ARRAY_ELEMENT(cursor->pgp->primaries, primary).primary; 2939 pubkey = &ARRAY_ELEMENT(cursor->pgp->primaries, primary).primary;
2942 return match_sig(cursor, signature, pubkey, data, insize); 2940 return match_sig(cursor, signature, pubkey, data, insize);
2943 } 2941 }
2944 prim = &ARRAY_ELEMENT(cursor->pgp->primaries, primary); 2942 prim = &ARRAY_ELEMENT(cursor->pgp->primaries, primary);
2945 pubkey = &ARRAY_ELEMENT(prim->signed_subkeys, sub - 1).subkey; 2943 n = ARRAY_ELEMENT(prim->signed_subkeys, sub - 1);
 2944 pubkey = &ARRAY_ELEMENT(pgp->signed_subkeys, n).subkey;
2946 return match_sig(cursor, signature, pubkey, data, insize); 2945 return match_sig(cursor, signature, pubkey, data, insize);
2947} 2946}
2948 2947
2949/* return the packet type */ 2948/* return the packet type */
2950static const char * 2949static const char *
2951get_packet_type(uint8_t tag) 2950get_packet_type(uint8_t tag)
2952{ 2951{
2953 switch(tag) { 2952 switch(tag) {
2954 case SIGNATURE_PKT: 2953 case SIGNATURE_PKT:
2955 return "signature packet"; 2954 return "signature packet";
2956 case ONEPASS_SIGNATURE_PKT: 2955 case ONEPASS_SIGNATURE_PKT:
2957 return "onepass signature packet"; 2956 return "onepass signature packet";
2958 case PUBKEY_PKT: 2957 case PUBKEY_PKT:
@@ -2966,27 +2965,149 @@ get_packet_type(uint8_t tag) @@ -2966,27 +2965,149 @@ get_packet_type(uint8_t tag)
2966 case TRUST_PKT: 2965 case TRUST_PKT:
2967 return "trust packet"; 2966 return "trust packet";
2968 case USERID_PKT: 2967 case USERID_PKT:
2969 return "userid packet"; 2968 return "userid packet";
2970 case PUB_SUBKEY_PKT: 2969 case PUB_SUBKEY_PKT:
2971 return "public subkey packet"; 2970 return "public subkey packet";
2972 case USER_ATTRIBUTE_PKT: 2971 case USER_ATTRIBUTE_PKT:
2973 return "user attribute packet"; 2972 return "user attribute packet";
2974 default: 2973 default:
2975 return "[UNKNOWN]"; 2974 return "[UNKNOWN]";
2976 } 2975 }
2977} 2976}
2978 2977
2979/**************************************************************************/ 2978/* check return value from getenv */
 2979static const char *
 2980nonnull_getenv(const char *key)
 2981{
 2982 char *value;
 2983
 2984 return ((value = getenv(key)) == NULL) ? "" : value;
 2985}
 2986
 2987/* free an array of bignums */
 2988static void
 2989free_bn_array(pgpv_bignum_t *v, unsigned n)
 2990{
 2991 unsigned i;
 2992
 2993 for (i = 0 ; i < n ; i++) {
 2994 PGPV_BN_free(v[i].bn);
 2995 }
 2996}
 2997
 2998/************************************************************************/
 2999/* start of exported functions */
 3000/************************************************************************/
 3001
 3002/* close all stuff */
 3003int
 3004pgpv_close(pgpv_t *pgp)
 3005{
 3006 pgpv_primarykey_t *primary;
 3007 pgpv_pkt_t *pkt;
 3008 unsigned i;
 3009
 3010 if (pgp == NULL) {
 3011 return 0;
 3012 }
 3013 for (i = 0 ; i < ARRAY_COUNT(pgp->areas) ; i++) {
 3014 if (ARRAY_ELEMENT(pgp->areas, i).size > 0) {
 3015 closemem(&ARRAY_ELEMENT(pgp->areas, i));
 3016 }
 3017 }
 3018 ARRAY_FREE(pgp->areas);
 3019 for (i = 0 ; i < ARRAY_COUNT(pgp->pkts) ; i++) {
 3020 pkt = &ARRAY_ELEMENT(pgp->pkts, i);
 3021 switch(pkt->tag) {
 3022 case SIGNATURE_PKT:
 3023 free_bn_array(pkt->u.sigpkt.sig.bn, PGPV_MAX_SIG_BN);
 3024 ARRAY_FREE(pkt->u.sigpkt.subpackets);
 3025 break;
 3026 case LITDATA_PKT:
 3027 if (pkt->u.litdata.filename.allocated) {
 3028 free(pkt->u.litdata.filename.data);
 3029 }
 3030 break;
 3031 case PUBKEY_PKT:
 3032 free_bn_array(pkt->u.pubkey.bn, PGPV_MAX_PUBKEY_BN);
 3033 break;
 3034 case USERID_PKT:
 3035 if (pkt->u.userid.allocated) {
 3036 free(pkt->u.userid.data);
 3037 }
 3038 break;
 3039 case USER_ATTRIBUTE_PKT:
 3040 ARRAY_FREE(pkt->u.userattr.subattrs);
 3041 break;
 3042 }
 3043 }
 3044 ARRAY_FREE(pgp->pkts);
 3045 for (i = 0 ; i < ARRAY_COUNT(pgp->primaries) ; i++) {
 3046 primary = &ARRAY_ELEMENT(pgp->primaries, i);
 3047 free_bn_array(primary->primary.bn, PGPV_MAX_PUBKEY_BN);
 3048 ARRAY_FREE(primary->signatures);
 3049 ARRAY_FREE(primary->signed_userids);
 3050 ARRAY_FREE(primary->signed_userattrs);
 3051 ARRAY_FREE(primary->signed_subkeys);
 3052 }
 3053 for (i = 0 ; i < ARRAY_COUNT(pgp->signatures) ; i++) {
 3054 free_bn_array(ARRAY_ELEMENT(pgp->signatures, i).bn, PGPV_MAX_SIG_BN);
 3055 }
 3056 ARRAY_FREE(pgp->primaries);
 3057 ARRAY_FREE(pgp->datastarts);
 3058 ARRAY_FREE(pgp->signatures);
 3059 ARRAY_FREE(pgp->signed_userids);
 3060 ARRAY_FREE(pgp->signed_userattrs);
 3061 ARRAY_FREE(pgp->signed_subkeys);
 3062 ARRAY_FREE(pgp->subpkts);
 3063 return 1;
 3064}
 3065
 3066/* free resources attached to cursor */
 3067int
 3068pgpv_cursor_close(pgpv_cursor_t *cursor)
 3069{
 3070 if (cursor) {
 3071 ARRAY_FREE(cursor->datacookies);
 3072 ARRAY_FREE(cursor->found);
 3073 }
 3074 return 0;
 3075}
 3076
 3077/* return the formatted entry for the primary key desired */
 3078size_t
 3079pgpv_get_entry(pgpv_t *pgp, unsigned ent, char **s, const char *modifiers)
 3080{
 3081 unsigned subkey;
 3082 unsigned prim;
 3083 obuf_t obuf;
 3084
 3085 prim = ((ent >> 8) & 0xffffff);
 3086 subkey = (ent & 0xff);
 3087 if (s == NULL || pgp == NULL || prim >= ARRAY_COUNT(pgp->primaries)) {
 3088 return 0;
 3089 }
 3090 *s = NULL;
 3091 if (modifiers == NULL || (strcasecmp(modifiers, "trust") != 0 && strcasecmp(modifiers, "subkeys") != 0)) {
 3092 modifiers = "no-subkeys";
 3093 }
 3094 memset(&obuf, 0x0, sizeof(obuf));
 3095 if (!fmt_primary(&obuf, pgp, &ARRAY_ELEMENT(pgp->primaries, prim), subkey, modifiers)) {
 3096 return 0;
 3097 }
 3098 *s = (char *)obuf.v;
 3099 return obuf.c;
 3100}
2980 3101
2981/* make a new pgpv struct */ 3102/* make a new pgpv struct */
2982pgpv_t * 3103pgpv_t *
2983pgpv_new(void) 3104pgpv_new(void)
2984{ 3105{
2985 return calloc(1, sizeof(pgpv_t)); 3106 return calloc(1, sizeof(pgpv_t));
2986} 3107}
2987 3108
2988/* make a new pgpv_cursor struct */ 3109/* make a new pgpv_cursor struct */
2989pgpv_cursor_t * 3110pgpv_cursor_t *
2990pgpv_new_cursor(void) 3111pgpv_new_cursor(void)
2991{ 3112{
2992 return calloc(1, sizeof(pgpv_cursor_t)); 3113 return calloc(1, sizeof(pgpv_cursor_t));
@@ -3071,27 +3192,27 @@ pgpv_verify(pgpv_cursor_t *cursor, pgpv_ @@ -3071,27 +3192,27 @@ pgpv_verify(pgpv_cursor_t *cursor, pgpv_
3071 fixup_ssh_keyid(cursor->pgp, signature, "sha1"); 3192 fixup_ssh_keyid(cursor->pgp, signature, "sha1");
3072 } 3193 }
3073 sub = 0; 3194 sub = 0;
3074 if ((j = find_keyid(cursor->pgp, NULL, onepass->keyid, &sub)) < 0) { 3195 if ((j = find_keyid(cursor->pgp, NULL, onepass->keyid, &sub)) < 0) {
3075 if (!fmt_binary(&obuf, onepass->keyid, (unsigned)sizeof(onepass->keyid))) { 3196 if (!fmt_binary(&obuf, onepass->keyid, (unsigned)sizeof(onepass->keyid))) {
3076 snprintf(cursor->why, sizeof(cursor->why), "Memory allocation failure"); 3197 snprintf(cursor->why, sizeof(cursor->why), "Memory allocation failure");
3077 return 0; 3198 return 0;
3078 } 3199 }
3079 snprintf(cursor->why, sizeof(cursor->why), 3200 snprintf(cursor->why, sizeof(cursor->why),
3080 "Signature key id %.*s not found ", 3201 "Signature key id %.*s not found ",
3081 (int)obuf.c, (char *)obuf.v); 3202 (int)obuf.c, (char *)obuf.v);
3082 return 0; 3203 return 0;
3083 } 3204 }
3084 if (!match_sig_id(cursor, signature, litdata, (unsigned)j, sub)) { 3205 if (!match_sig_id(cursor, pgp, signature, litdata, (unsigned)j, sub)) {
3085 snprintf(cursor->why, sizeof(cursor->why), 3206 snprintf(cursor->why, sizeof(cursor->why),
3086 "Signature does not match %.*s", 3207 "Signature does not match %.*s",
3087 (int)obuf.c, (char *)obuf.v); 3208 (int)obuf.c, (char *)obuf.v);
3088 return 0; 3209 return 0;
3089 } 3210 }
3090 ARRAY_APPEND(cursor->datacookies, pkt); 3211 ARRAY_APPEND(cursor->datacookies, pkt);
3091 j = ((j & 0xffffff) << 8) | (sub & 0xff); 3212 j = ((j & 0xffffff) << 8) | (sub & 0xff);
3092 ARRAY_APPEND(cursor->found, j); 3213 ARRAY_APPEND(cursor->found, j);
3093 return pkt + 1; 3214 return pkt + 1;
3094} 3215}
3095 3216
3096/* set up the pubkey keyring */ 3217/* set up the pubkey keyring */
3097int 3218int

cvs diff -r1.30 -r1.31 pkgsrc/security/netpgpverify/files/verify.h (expand / switch to unified diff)

--- pkgsrc/security/netpgpverify/files/verify.h 2016/07/05 23:56:07 1.30
+++ pkgsrc/security/netpgpverify/files/verify.h 2016/07/08 15:56:46 1.31
@@ -13,29 +13,29 @@ @@ -13,29 +13,29 @@
13 * 13 *
14 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 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 15 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
16 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 16 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
17 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 17 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
18 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 18 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
19 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 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 20 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
21 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 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 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. 23 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24 */ 24 */
25#ifndef NETPGP_VERIFY_H_ 25#ifndef NETPGP_VERIFY_H_
26#define NETPGP_VERIFY_H_ 20160704 26#define NETPGP_VERIFY_H_ 20160705
27 27
28#define NETPGPVERIFY_VERSION "netpgpverify portable 20160704" 28#define NETPGPVERIFY_VERSION "netpgpverify portable 20160705"
29 29
30#include <sys/types.h> 30#include <sys/types.h>
31 31
32#include <inttypes.h> 32#include <inttypes.h>
33 33
34struct pgpv_t; 34struct pgpv_t;
35typedef struct pgpv_t pgpv_t; 35typedef struct pgpv_t pgpv_t;
36 36
37struct pgpv_cursor_t; 37struct pgpv_cursor_t;
38typedef struct pgpv_cursor_t pgpv_cursor_t; 38typedef struct pgpv_cursor_t pgpv_cursor_t;
39 39
40#ifndef __BEGIN_DECLS 40#ifndef __BEGIN_DECLS
41# if defined(__cplusplus) 41# if defined(__cplusplus)
@@ -56,17 +56,18 @@ int pgpv_read_pubring(pgpv_t */*pgp*/, c @@ -56,17 +56,18 @@ int pgpv_read_pubring(pgpv_t */*pgp*/, c
56int pgpv_read_ssh_pubkeys(pgpv_t */*pgp*/, const void */*keyring*/, ssize_t /*size*/); 56int pgpv_read_ssh_pubkeys(pgpv_t */*pgp*/, const void */*keyring*/, ssize_t /*size*/);
57 57
58size_t pgpv_verify(pgpv_cursor_t */*cursor*/, pgpv_t */*pgp*/, const void */*mem/file*/, ssize_t /*size*/); 58size_t pgpv_verify(pgpv_cursor_t */*cursor*/, pgpv_t */*pgp*/, const void */*mem/file*/, ssize_t /*size*/);
59size_t pgpv_get_verified(pgpv_cursor_t */*cursor*/, size_t /*cookie*/, char **/*ret*/); 59size_t pgpv_get_verified(pgpv_cursor_t */*cursor*/, size_t /*cookie*/, char **/*ret*/);
60size_t pgpv_dump(pgpv_t */*pgp*/, char **/*data*/); 60size_t pgpv_dump(pgpv_t */*pgp*/, char **/*data*/);
61 61
62size_t pgpv_get_entry(pgpv_t */*pgp*/, unsigned /*ent*/, char **/*ret*/, const char */*modifiers*/); 62size_t pgpv_get_entry(pgpv_t */*pgp*/, unsigned /*ent*/, char **/*ret*/, const char */*modifiers*/);
63 63
64int64_t pgpv_get_cursor_num(pgpv_cursor_t */*cursor*/, const char */*field*/); 64int64_t pgpv_get_cursor_num(pgpv_cursor_t */*cursor*/, const char */*field*/);
65char *pgpv_get_cursor_str(pgpv_cursor_t */*cursor*/, const char */*field*/); 65char *pgpv_get_cursor_str(pgpv_cursor_t */*cursor*/, const char */*field*/);
66int pgpv_get_cursor_element(pgpv_cursor_t */*cursor*/, size_t /*element*/); 66int pgpv_get_cursor_element(pgpv_cursor_t */*cursor*/, size_t /*element*/);
67 67
68int pgpv_close(pgpv_t */*pgp*/); 68int pgpv_close(pgpv_t */*pgp*/);
 69int pgpv_cursor_close(pgpv_cursor_t */*cursor*/);
69 70
70__END_DECLS 71__END_DECLS
71 72
72#endif 73#endif