]> the.earth.li Git - onak.git/blob - sigcheck.c
Fix issues found by llvm scan-build static analysis
[onak.git] / sigcheck.c
1 /*
2  * sigcheck.c - routines to check OpenPGP signatures
3  *
4  * Copyright 2012 Jonathan McDowell <noodles@earth.li>
5  *
6  * This program is free software: you can redistribute it and/or modify it
7  * under the terms of the GNU General Public License as published by the Free
8  * Software Foundation; version 2 of the License.
9  *
10  * This program is distributed in the hope that it will be useful, but WITHOUT
11  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12  * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
13  * more details.
14  *
15  * You should have received a copy of the GNU General Public License along with
16  * this program.  If not, see <https://www.gnu.org/licenses/>.
17  */
18
19 #include <stdint.h>
20 #include <string.h>
21
22 #include "build-config.h"
23 #include "decodekey.h"
24 #include "hash-helper.h"
25 #include "keyid.h"
26 #include "keystructs.h"
27 #include "log.h"
28 #include "onak.h"
29 #include "openpgp.h"
30 #include "sigcheck.h"
31
32 #ifdef HAVE_CRYPTO
33 #include <gmp.h>
34 #include <nettle/dsa.h>
35 #include <nettle/ecc.h>
36 #include <nettle/ecc-curve.h>
37 #include <nettle/ecdsa.h>
38 #include <nettle/eddsa.h>
39 #include <nettle/rsa.h>
40 #include "rsa.h"
41
42 #ifndef HAVE_NETTLE_GET_SECP_256R1
43 #define nettle_get_secp_256r1() &nettle_secp_256r1
44 #endif
45 #ifndef HAVE_NETTLE_GET_SECP_384R1
46 #define nettle_get_secp_384r1() &nettle_secp_384r1
47 #endif
48 #ifndef HAVE_NETTLE_GET_SECP_521R1
49 #define nettle_get_secp_521r1() &nettle_secp_521r1
50 #endif
51
52 #endif
53
54 /* Take an MPI from a buffer and import it into a GMP mpz_t */
55 #define MPI_TO_MPZ(pk, v) \
56 {                                                                             \
57         /* MPI length is stored in bits, convert it to bytes */               \
58         if (pk->length < (ofs + 2)) {                                         \
59                 ret = ONAK_E_INVALID_PKT;                                     \
60         } else {                                                              \
61                 len = pk->data[ofs] << 8 | pk->data[ofs + 1];                 \
62                 len += 7;                                                     \
63                 len = len >> 3;                                               \
64                 if (pk->length < (ofs + len + 2)) {                           \
65                         ret = ONAK_E_INVALID_PKT;                             \
66                 } else {                                                      \
67                         mpz_import(v, len, 1, 1, 0, 0, &pk->data[ofs + 2]);   \
68                         ofs += len + 2;                                       \
69                 }                                                             \
70         }                                                                     \
71 }
72
73 #if HAVE_CRYPTO
74
75 /*
76  * Hold the crypto material for a public key.
77  * May want to move to a header at some point.
78  */
79 struct onak_key_material {
80         uint8_t type;
81         union {
82                 struct dsa_params dsa;
83                 struct ecc_point ecc;
84                 struct rsa_public_key rsa;
85                 uint8_t ed25519[32];
86         };
87         mpz_t y;
88 };
89
90 static void onak_free_key_material(struct onak_key_material *key)
91 {
92         switch (key->type) {
93         case OPENPGP_PKALGO_ECDSA:
94                 ecc_point_clear(&key->ecc);
95                 break;
96         case OPENPGP_PKALGO_DSA:
97                 mpz_clear(key->dsa.p);
98                 mpz_clear(key->dsa.q);
99                 mpz_clear(key->dsa.g);
100                 mpz_clear(key->y);
101                 break;
102         case OPENPGP_PKALGO_RSA:
103         case OPENPGP_PKALGO_RSA_ENC:
104         case OPENPGP_PKALGO_RSA_SIGN:
105                 mpz_clear(key->rsa.n);
106                 mpz_clear(key->rsa.e);
107                 break;
108         }
109
110         /* Set the key type back to 0 to indicate we cleared it */
111         key->type = 0;
112
113         return;
114 }
115
116 static onak_status_t onak_parse_key_material(struct openpgp_packet *pk,
117                 struct onak_key_material *key)
118 {
119         int i, len, ofs;
120         enum onak_oid oid;
121         mpz_t x, y;
122         onak_status_t ret = ONAK_E_OK;
123
124         /* Clear the key type; only set it when fully parsed */
125         key->type = 0;
126
127         /*
128          * Shortest valid key is v4 Ed25519, which takes 51 bytes, so do a
129          * quick sanity check which will ensure we have enough data to check
130          * the packet header and OID info.
131          */
132         if (pk->length < 51)
133                 return ONAK_E_INVALID_PKT;
134
135         if (pk->data[0] != 4 && pk->data[0] != 5)
136                 return ONAK_E_UNSUPPORTED_FEATURE;
137
138         /*
139          * MPIs are after version byte, 4 byte creation time +
140          * type byte plus length for v5.
141          */
142         ofs = (pk->data[0] == 4) ? 6 : 10;
143         switch (pk->data[5]) {
144         case OPENPGP_PKALGO_ECDSA:
145                 oid = onak_parse_oid(&pk->data[ofs], pk->length - ofs);
146                 if (oid == ONAK_OID_INVALID)
147                         return ONAK_E_INVALID_PKT;
148                 if (oid == ONAK_OID_UNKNOWN)
149                         return ONAK_E_UNSUPPORTED_FEATURE;
150
151                 if (oid == ONAK_OID_NISTP256) {
152                         if (pk->length - ofs != 76)
153                                 return ONAK_E_INVALID_PKT;
154                         /* Move past the OID to the key data MPI */
155                         ofs += pk->data[ofs] + 1;
156                         len = pk->data[ofs] << 8 | pk->data[ofs + 1];
157                         if (len != 515)
158                                 return ONAK_E_INVALID_PKT;
159                         if (pk->data[ofs + 2] != 4)
160                                 return ONAK_E_INVALID_PKT;
161                         mpz_init(x);
162                         mpz_init(y);
163                         ecc_point_init(&key->ecc, nettle_get_secp_256r1());
164                         ofs += 3;
165                         mpz_import(x, 32, 1, 1, 0, 0, &pk->data[ofs]);
166                         ofs += 32;
167                         mpz_import(y, 32, 1, 1, 0, 0, &pk->data[ofs]);
168                         ofs += 32;
169                         ecc_point_set(&key->ecc, x, y);
170                 } else if (oid == ONAK_OID_NISTP384) {
171                         if (pk->length - ofs != 105)
172                                 return ONAK_E_INVALID_PKT;
173                         /* Move past the OID to the key data MPI */
174                         ofs += pk->data[ofs] + 1;
175                         len = pk->data[ofs] << 8 | pk->data[ofs + 1];
176                         if (len != 771)
177                                 return ONAK_E_INVALID_PKT;
178                         if (pk->data[ofs + 2] != 4)
179                                 return ONAK_E_INVALID_PKT;
180                         mpz_init(x);
181                         mpz_init(y);
182                         ecc_point_init(&key->ecc, nettle_get_secp_384r1());
183                         ofs += 3;
184                         mpz_import(x, 48, 1, 1, 0, 0, &pk->data[ofs]);
185                         ofs += 48;
186                         mpz_import(y, 48, 1, 1, 0, 0, &pk->data[ofs]);
187                         ofs += 48;
188                         ecc_point_set(&key->ecc, x, y);
189                 } else if (oid == ONAK_OID_NISTP521) {
190                         if (pk->length - ofs != 141)
191                                 return ONAK_E_INVALID_PKT;
192                         /* Move past the OID to the key data MPI */
193                         ofs += pk->data[ofs] + 1;
194                         len = pk->data[ofs] << 8 | pk->data[ofs + 1];
195                         if (len != 1059)
196                                 return ONAK_E_INVALID_PKT;
197                         if (pk->data[ofs + 2] != 4)
198                                 return ONAK_E_INVALID_PKT;
199                         mpz_init(x);
200                         mpz_init(y);
201                         ecc_point_init(&key->ecc, nettle_get_secp_521r1());
202                         ofs += 3;
203                         mpz_import(x, 66, 1, 1, 0, 0, &pk->data[ofs]);
204                         ofs += 66;
205                         mpz_import(y, 66, 1, 1, 0, 0, &pk->data[ofs]);
206                         ofs += 66;
207                         ecc_point_set(&key->ecc, x, y);
208                 } else {
209                         return ONAK_E_UNSUPPORTED_FEATURE;
210                 }
211                 mpz_clear(y);
212                 mpz_clear(x);
213                 break;
214         case OPENPGP_PKALGO_EDDSA:
215                 if (pk->length - ofs != 45)
216                         return ONAK_E_INVALID_PKT;
217                 oid = onak_parse_oid(&pk->data[ofs], pk->length - ofs);
218                 if (oid == ONAK_OID_INVALID)
219                         return ONAK_E_INVALID_PKT;
220                 if (oid == ONAK_OID_UNKNOWN)
221                         return ONAK_E_UNSUPPORTED_FEATURE;
222
223                 /* Move past the OID to the key data MPI */
224                 ofs += pk->data[ofs] + 1;
225
226                 if (oid == ONAK_OID_ED25519) {
227                         len = pk->data[ofs] << 8 | pk->data[ofs + 1];
228                         if (len != 263)
229                                 return ONAK_E_INVALID_PKT;
230                         if (pk->data[ofs + 2] != 0x40)
231                                 return ONAK_E_INVALID_PKT;
232                         ofs += 3;
233                         memcpy(key->ed25519, &pk->data[ofs], 32);
234                         ofs += 32;
235                 } else {
236                         return ONAK_E_UNSUPPORTED_FEATURE;
237                 }
238                 break;
239         case OPENPGP_PKALGO_DSA:
240                 mpz_init(key->dsa.p);
241                 mpz_init(key->dsa.q);
242                 mpz_init(key->dsa.g);
243                 mpz_init(key->y);
244                 MPI_TO_MPZ(pk, key->dsa.p);
245                 if (ret == ONAK_E_OK)
246                         MPI_TO_MPZ(pk, key->dsa.q);
247                 if (ret == ONAK_E_OK)
248                         MPI_TO_MPZ(pk, key->dsa.g);
249                 if (ret == ONAK_E_OK)
250                         MPI_TO_MPZ(pk, key->y);
251                 break;
252         case OPENPGP_PKALGO_RSA:
253         case OPENPGP_PKALGO_RSA_ENC:
254         case OPENPGP_PKALGO_RSA_SIGN:
255                 mpz_init(key->rsa.n);
256                 mpz_init(key->rsa.e);
257                 key->rsa.size = ((pk->data[6] << 8) + pk->data[7] + 7) >> 3;
258                 MPI_TO_MPZ(pk, key->rsa.n);
259                 if (ret == ONAK_E_OK)
260                         MPI_TO_MPZ(pk, key->rsa.e);
261                 break;
262         default:
263                 return ONAK_E_UNSUPPORTED_FEATURE;
264         }
265
266         /*
267          * Keep scan-build happy; we bump this in MPI_TO_MPZ and then don't use
268          * it again the last time we do so.
269          */
270         (void)ofs;
271
272         key->type = pk->data[5];
273
274         if (ret != ONAK_E_OK) {
275                 onak_free_key_material(key);
276         }
277
278         return ret;
279 }
280
281 onak_status_t onak_check_hash_sig(struct openpgp_publickey *sigkey,
282                 struct openpgp_packet *sig,
283                 uint8_t *hash,
284                 uint8_t hashtype)
285 {
286         onak_status_t ret;
287         struct onak_key_material pubkey;
288         struct dsa_signature dsasig;
289         uint8_t sigkeytype;
290         uint8_t edsig[64];
291         uint64_t keyid;
292         int len, ofs;
293         mpz_t s;
294
295         ret = onak_parse_key_material(sigkey->publickey, &pubkey);
296         if (ret != ONAK_E_OK) {
297                 return ret;
298         }
299
300         /* Sanity check the length of the signature packet */
301         if (sig->length < 8) {
302                 ret = ONAK_E_INVALID_PKT;
303                 goto out;
304         }
305
306         if (sig->data[0] == 3) {
307                 /* Must be 5 bytes hashed */
308                 if (sig->data[1] != 5) {
309                         ret = ONAK_E_INVALID_PARAM;
310                         goto out;
311                 }
312
313                 /* Need at least 19 bytes for the sig header */
314                 if (sig->length < 19) {
315                         ret = ONAK_E_INVALID_PKT;
316                         goto out;
317                 }
318
319                 /* Skip to the signature material */
320                 ofs = 19;
321                 sigkeytype = sig->data[15];
322         } else if (sig->data[0] >= 4) {
323                 /* Skip the hashed data */
324                 ofs = (sig->data[4] << 8) + sig->data[5] + 6;
325                 if (sig->length < ofs + 2) {
326                         ret = ONAK_E_INVALID_PKT;
327                         goto out;
328                 }
329                 /* Skip the unhashed data */
330                 ofs += (sig->data[ofs] << 8) + sig->data[ofs + 1] + 2;
331                 if (sig->length < ofs + 2) {
332                         ret = ONAK_E_INVALID_PKT;
333                         goto out;
334                 }
335                 /* Skip the sig hash bytes */
336                 ofs += 2;
337                 sigkeytype = sig->data[2];
338         } else {
339                 ret = ONAK_E_UNSUPPORTED_FEATURE;
340                 goto out;
341         }
342
343         /* Is the key the same type as the signature we're checking? */
344         if (pubkey.type != sigkeytype) {
345                 ret = ONAK_E_INVALID_PARAM;
346                 goto out;
347         }
348
349         /* Parse the actual signature values */
350         switch (sigkeytype) {
351         case OPENPGP_PKALGO_ECDSA:
352         case OPENPGP_PKALGO_DSA:
353                 mpz_init(dsasig.r);
354                 mpz_init(dsasig.s);
355                 MPI_TO_MPZ(sig, dsasig.r);
356                 if (ret == ONAK_E_OK)
357                         MPI_TO_MPZ(sig, dsasig.s);
358                 break;
359         case OPENPGP_PKALGO_EDDSA:
360                 mpz_init(dsasig.r);
361                 mpz_init(dsasig.s);
362                 MPI_TO_MPZ(sig, dsasig.r);
363                 if (ret == ONAK_E_OK)
364                         MPI_TO_MPZ(sig, dsasig.s);
365                 mpz_export(edsig, NULL, 1, 1, 0, 0, dsasig.r);
366                 mpz_export(&edsig[32], NULL, 1, 1, 0, 0, dsasig.s);
367                 break;
368         case OPENPGP_PKALGO_RSA:
369         case OPENPGP_PKALGO_RSA_SIGN:
370                 mpz_init(s);
371                 MPI_TO_MPZ(sig, s);
372                 break;
373         }
374
375         /* If we didn't parse the signature properly then do clean-up */
376         if (ret != ONAK_E_OK)
377                 goto sigerr;
378
379         /* Squash a signing only RSA key to a standard RSA key for below */
380         if (pubkey.type == OPENPGP_PKALGO_RSA_SIGN) {
381                 pubkey.type = OPENPGP_PKALGO_RSA;
382         }
383
384 #define KEYHASH(key, hash) ((key << 8) | hash)
385
386         switch KEYHASH(pubkey.type, hashtype) {
387         case KEYHASH(OPENPGP_PKALGO_DSA, OPENPGP_HASH_MD5):
388                 ret = dsa_verify(&pubkey.dsa, pubkey.y,
389                                 MD5_DIGEST_SIZE, hash, &dsasig) ?
390                         ONAK_E_WEAK_SIGNATURE : ONAK_E_BAD_SIGNATURE;
391                 break;
392         case KEYHASH(OPENPGP_PKALGO_DSA, OPENPGP_HASH_RIPEMD160):
393                 ret = dsa_verify(&pubkey.dsa, pubkey.y,
394                                 RIPEMD160_DIGEST_SIZE, hash, &dsasig) ?
395                         ONAK_E_OK : ONAK_E_BAD_SIGNATURE;
396                 break;
397         case KEYHASH(OPENPGP_PKALGO_DSA, OPENPGP_HASH_SHA1):
398                 ret = dsa_verify(&pubkey.dsa, pubkey.y,
399                                 SHA1_DIGEST_SIZE, hash, &dsasig) ?
400                         ONAK_E_OK : ONAK_E_BAD_SIGNATURE;
401                 break;
402         case KEYHASH(OPENPGP_PKALGO_DSA, OPENPGP_HASH_SHA1X):
403                 ret = dsa_verify(&pubkey.dsa, pubkey.y,
404                                 SHA1X_DIGEST_SIZE, hash, &dsasig) ?
405                         ONAK_E_OK : ONAK_E_BAD_SIGNATURE;
406                 break;
407         case KEYHASH(OPENPGP_PKALGO_DSA, OPENPGP_HASH_SHA224):
408                 ret = dsa_verify(&pubkey.dsa, pubkey.y,
409                                 SHA224_DIGEST_SIZE, hash, &dsasig) ?
410                         ONAK_E_OK : ONAK_E_BAD_SIGNATURE;
411                 break;
412         case KEYHASH(OPENPGP_PKALGO_DSA, OPENPGP_HASH_SHA256):
413                 ret = dsa_verify(&pubkey.dsa, pubkey.y,
414                                 SHA256_DIGEST_SIZE, hash, &dsasig) ?
415                         ONAK_E_OK : ONAK_E_BAD_SIGNATURE;
416                 break;
417         case KEYHASH(OPENPGP_PKALGO_DSA, OPENPGP_HASH_SHA384):
418                 ret = dsa_verify(&pubkey.dsa, pubkey.y,
419                                 SHA384_DIGEST_SIZE, hash, &dsasig) ?
420                         ONAK_E_OK : ONAK_E_BAD_SIGNATURE;
421                 break;
422         case KEYHASH(OPENPGP_PKALGO_DSA, OPENPGP_HASH_SHA512):
423                 ret = dsa_verify(&pubkey.dsa, pubkey.y,
424                                 SHA512_DIGEST_SIZE, hash, &dsasig) ?
425                         ONAK_E_OK : ONAK_E_BAD_SIGNATURE;
426                 break;
427         case KEYHASH(OPENPGP_PKALGO_ECDSA, OPENPGP_HASH_SHA1):
428                 ret = ecdsa_verify(&pubkey.ecc,
429                                 SHA1_DIGEST_SIZE, hash, &dsasig) ?
430                         ONAK_E_OK : ONAK_E_BAD_SIGNATURE;
431                 break;
432         case KEYHASH(OPENPGP_PKALGO_ECDSA, OPENPGP_HASH_SHA256):
433                 ret = ecdsa_verify(&pubkey.ecc,
434                                 SHA256_DIGEST_SIZE, hash, &dsasig) ?
435                         ONAK_E_OK : ONAK_E_BAD_SIGNATURE;
436                 break;
437         case KEYHASH(OPENPGP_PKALGO_ECDSA, OPENPGP_HASH_SHA384):
438                 ret = ecdsa_verify(&pubkey.ecc,
439                                 SHA384_DIGEST_SIZE, hash, &dsasig) ?
440                         ONAK_E_OK : ONAK_E_BAD_SIGNATURE;
441                 break;
442         case KEYHASH(OPENPGP_PKALGO_ECDSA, OPENPGP_HASH_SHA512):
443                 ret = ecdsa_verify(&pubkey.ecc,
444                                 SHA512_DIGEST_SIZE, hash, &dsasig) ?
445                         ONAK_E_OK : ONAK_E_BAD_SIGNATURE;
446                 break;
447         case KEYHASH(OPENPGP_PKALGO_EDDSA, OPENPGP_HASH_RIPEMD160):
448                 ret = ed25519_sha512_verify(pubkey.ed25519,
449                                 RIPEMD160_DIGEST_SIZE, hash, edsig) ?
450                         ONAK_E_OK : ONAK_E_BAD_SIGNATURE;
451                 break;
452         case KEYHASH(OPENPGP_PKALGO_EDDSA, OPENPGP_HASH_SHA256):
453                 ret = ed25519_sha512_verify(pubkey.ed25519,
454                                 SHA256_DIGEST_SIZE, hash, edsig) ?
455                         ONAK_E_OK : ONAK_E_BAD_SIGNATURE;
456                 break;
457         case KEYHASH(OPENPGP_PKALGO_EDDSA, OPENPGP_HASH_SHA384):
458                 ret = ed25519_sha512_verify(pubkey.ed25519,
459                                 SHA384_DIGEST_SIZE, hash, edsig) ?
460                         ONAK_E_OK : ONAK_E_BAD_SIGNATURE;
461                 break;
462         case KEYHASH(OPENPGP_PKALGO_EDDSA, OPENPGP_HASH_SHA512):
463                 ret = ed25519_sha512_verify(pubkey.ed25519,
464                                 SHA512_DIGEST_SIZE, hash, edsig) ?
465                         ONAK_E_OK : ONAK_E_BAD_SIGNATURE;
466                 break;
467         case KEYHASH(OPENPGP_PKALGO_RSA, OPENPGP_HASH_MD5):
468                 ret = rsa_md5_verify_digest(&pubkey.rsa, hash, s) ?
469                         ONAK_E_WEAK_SIGNATURE : ONAK_E_BAD_SIGNATURE;
470                 break;
471         case KEYHASH(OPENPGP_PKALGO_RSA, OPENPGP_HASH_RIPEMD160):
472                 ret = rsa_ripemd160_verify_digest(&pubkey.rsa, hash, s) ?
473                         ONAK_E_OK : ONAK_E_BAD_SIGNATURE;
474                 break;
475         case KEYHASH(OPENPGP_PKALGO_RSA, OPENPGP_HASH_SHA1):
476                 ret = rsa_sha1_verify_digest(&pubkey.rsa, hash, s) ?
477                         ONAK_E_OK : ONAK_E_BAD_SIGNATURE;
478                 break;
479         case KEYHASH(OPENPGP_PKALGO_RSA, OPENPGP_HASH_SHA224):
480                 ret = rsa_sha224_verify_digest(&pubkey.rsa, hash, s) ?
481                         ONAK_E_OK : ONAK_E_BAD_SIGNATURE;
482                 break;
483         case KEYHASH(OPENPGP_PKALGO_RSA, OPENPGP_HASH_SHA256):
484                 ret = rsa_sha256_verify_digest(&pubkey.rsa, hash, s) ?
485                         ONAK_E_OK : ONAK_E_BAD_SIGNATURE;
486                 break;
487         case KEYHASH(OPENPGP_PKALGO_RSA, OPENPGP_HASH_SHA384):
488                 ret = rsa_sha384_verify_digest(&pubkey.rsa, hash, s) ?
489                         ONAK_E_OK : ONAK_E_BAD_SIGNATURE;
490                 break;
491         case KEYHASH(OPENPGP_PKALGO_RSA, OPENPGP_HASH_SHA512):
492                 ret = rsa_sha512_verify_digest(&pubkey.rsa, hash, s) ?
493                         ONAK_E_OK : ONAK_E_BAD_SIGNATURE;
494                 break;
495         default:
496                 ret = ONAK_E_UNSUPPORTED_FEATURE;
497         }
498
499 sigerr:
500         switch (sigkeytype) {
501         case OPENPGP_PKALGO_ECDSA:
502         case OPENPGP_PKALGO_EDDSA:
503         case OPENPGP_PKALGO_DSA:
504                 mpz_clear(dsasig.r);
505                 mpz_clear(dsasig.s);
506                 break;
507         case OPENPGP_PKALGO_RSA:
508         case OPENPGP_PKALGO_RSA_SIGN:
509                 mpz_clear(s);
510                 break;
511         }
512
513 out:
514         onak_free_key_material(&pubkey);
515
516         return ret;
517 }
518
519 #endif /* HAVE_CRYPTO */
520
521 onak_status_t calculate_packet_sighash(struct openpgp_publickey *key,
522                         struct openpgp_packet *packet,
523                         struct openpgp_packet *sig,
524                         uint8_t *hashtype,
525                         uint8_t *hash,
526                         uint8_t **sighash)
527 {
528         size_t siglen, unhashedlen;
529         struct onak_hash_data hashdata;
530         uint8_t keyheader[5];
531         uint8_t packetheader[5];
532         uint8_t trailer[10];
533         int i;
534         uint64_t keyid;
535         onak_status_t res;
536
537         *hashtype = 0;
538         *sighash = NULL;
539         memset(&hashdata, 0, sizeof(hashdata));
540
541         switch (sig->data[0]) {
542         case 2:
543         case 3:
544                 keyheader[0] = 0x99;
545                 keyheader[1] = key->publickey->length >> 8;
546                 keyheader[2] = key->publickey->length & 0xFF;
547                 hashdata.data[0] = keyheader;
548                 hashdata.len[0] = 3;
549                 hashdata.data[1] = key->publickey->data;
550                 hashdata.len[1] = key->publickey->length;
551                 hashdata.chunks = 2;
552
553                 *hashtype = sig->data[16];
554
555                 if (packet != NULL) {
556                         if (packet->tag == OPENPGP_PACKET_PUBLICSUBKEY) {
557                                 packetheader[0] = 0x99;
558                                 packetheader[1] = packet->length >> 8;
559                                 packetheader[2] = packet->length & 0xFF;
560                                 hashdata.data[hashdata.chunks] = packetheader;
561                                 hashdata.len[hashdata.chunks] = 3;
562                                 hashdata.chunks++;
563                         }
564
565                         // TODO: Things other than UIDS/subkeys?
566                         hashdata.data[hashdata.chunks] = packet->data;
567                         hashdata.len[hashdata.chunks] = packet->length;
568                         hashdata.chunks++;
569                 }
570
571                 hashdata.data[hashdata.chunks] = &sig->data[2];
572                 hashdata.len[hashdata.chunks] = 5;
573                 hashdata.chunks++;
574                 *sighash = &sig->data[17];
575                 break;
576         case 4:
577                 keyheader[0] = 0x99;
578                 keyheader[1] = key->publickey->length >> 8;
579                 keyheader[2] = key->publickey->length & 0xFF;
580                 hashdata.data[0] = keyheader;
581                 hashdata.len[0] = 3;
582                 hashdata.data[1] = key->publickey->data;
583                 hashdata.len[1] = key->publickey->length;
584                 hashdata.chunks = 2;
585
586                 /* Check to see if this is an X509 based signature */
587                 if (sig->data[2] == 0 || sig->data[2] == 100) {
588                         size_t len;
589
590                         keyid = 0;
591                         res = parse_subpackets(&sig->data[4],
592                                                 sig->length - 4, &len,
593                                                 &keyid, NULL);
594                         if (res != ONAK_E_OK) {
595                                 return res;
596                         }
597                         if (keyid == 0 &&
598                                         /* No unhashed data */
599                                         sig->data[4 + len] == 0 &&
600                                         sig->data[5 + len] == 0 &&
601                                         /* Dummy 0 checksum */
602                                         sig->data[6 + len] == 0 &&
603                                         sig->data[7 + len] == 0 &&
604                                         /* Dummy MPI of 1 */
605                                         sig->data[8 + len] == 0 &&
606                                         sig->data[9 + len] == 1 &&
607                                         sig->data[10 + len] == 1) {
608                                 return ONAK_E_UNSUPPORTED_FEATURE;
609                         }
610                 }
611
612                 *hashtype = sig->data[3];
613
614                 if (packet != NULL) {
615                         if (packet->tag == OPENPGP_PACKET_PUBLICSUBKEY) {
616                                 packetheader[0] = 0x99;
617                                 packetheader[1] = packet->length >> 8;
618                                 packetheader[2] = packet->length & 0xFF;
619                                 hashdata.data[hashdata.chunks] = packetheader;
620                                 hashdata.len[hashdata.chunks] = 3;
621                                 hashdata.chunks++;
622                         } else if (packet->tag == OPENPGP_PACKET_UID ||
623                                         packet->tag == OPENPGP_PACKET_UAT) {
624                                 packetheader[0] = (packet->tag ==
625                                         OPENPGP_PACKET_UID) ?  0xB4 : 0xD1;
626                                 packetheader[1] = packet->length >> 24;
627                                 packetheader[2] = (packet->length >> 16) & 0xFF;
628                                 packetheader[3] = (packet->length >> 8) & 0xFF;
629                                 packetheader[4] = packet->length & 0xFF;
630                                 hashdata.data[hashdata.chunks] = packetheader;
631                                 hashdata.len[hashdata.chunks] = 5;
632                                 hashdata.chunks++;
633                         }
634                         hashdata.data[hashdata.chunks] = packet->data;
635                         hashdata.len[hashdata.chunks] = packet->length;
636                         hashdata.chunks++;
637                 }
638
639                 hashdata.data[hashdata.chunks] = sig->data;
640                 hashdata.len[hashdata.chunks] = siglen = (sig->data[4] << 8) +
641                         sig->data[5] + 6;;
642                 if (siglen > sig->length) {
643                         /* Signature data exceed packet length, bogus */
644                         return ONAK_E_INVALID_PKT;
645                 }
646                 hashdata.chunks++;
647
648                 trailer[0] = 4;
649                 trailer[1] = 0xFF;
650                 trailer[2] = siglen >> 24;
651                 trailer[3] = (siglen >> 16) & 0xFF;
652                 trailer[4] = (siglen >> 8) & 0xFF;
653                 trailer[5] = siglen & 0xFF;
654                 hashdata.data[hashdata.chunks] = trailer;
655                 hashdata.len[hashdata.chunks] = 6;
656                 hashdata.chunks++;
657
658                 unhashedlen = (sig->data[siglen] << 8) +
659                         sig->data[siglen + 1];
660                 *sighash = &sig->data[siglen + unhashedlen + 2];
661                 break;
662         case 5:
663                 keyheader[0] = 0x9A;
664                 keyheader[1] = 0;
665                 keyheader[2] = 0;
666                 keyheader[3] = key->publickey->length >> 8;
667                 keyheader[4] = key->publickey->length & 0xFF;
668                 hashdata.data[0] = keyheader;
669                 hashdata.len[0] = 5;
670                 hashdata.data[1] = key->publickey->data;
671                 hashdata.len[1] = key->publickey->length;
672                 hashdata.chunks = 2;
673
674                 *hashtype = sig->data[3];
675
676                 if (packet != NULL) {
677                         if (packet->tag == OPENPGP_PACKET_PUBLICSUBKEY) {
678                                 packetheader[0] = 0x9A;
679                                 packetheader[1] = 0;
680                                 packetheader[2] = 0;
681                                 packetheader[3] = packet->length >> 8;
682                                 packetheader[4] = packet->length & 0xFF;
683                                 hashdata.data[hashdata.chunks] = packetheader;
684                                 hashdata.len[hashdata.chunks] = 5;
685                                 hashdata.chunks++;
686                         } else if (packet->tag == OPENPGP_PACKET_UID ||
687                                         packet->tag == OPENPGP_PACKET_UAT) {
688                                 packetheader[0] = (packet->tag ==
689                                         OPENPGP_PACKET_UID) ?  0xB4 : 0xD1;
690                                 packetheader[1] = packet->length >> 24;
691                                 packetheader[2] = (packet->length >> 16) & 0xFF;
692                                 packetheader[3] = (packet->length >> 8) & 0xFF;
693                                 packetheader[4] = packet->length & 0xFF;
694                                 hashdata.data[hashdata.chunks] = packetheader;
695                                 hashdata.len[hashdata.chunks] = 5;
696                                 hashdata.chunks++;
697                         }
698                         hashdata.data[hashdata.chunks] = packet->data;
699                         hashdata.len[hashdata.chunks] = packet->length;
700                         hashdata.chunks++;
701                 }
702
703                 hashdata.data[hashdata.chunks] = sig->data;
704                 hashdata.len[hashdata.chunks] = siglen = (sig->data[4] << 8) +
705                         sig->data[5] + 6;;
706                 if (siglen > sig->length) {
707                         /* Signature data exceed packet length, bogus */
708                         return ONAK_E_INVALID_PKT;
709                 }
710                 hashdata.chunks++;
711
712                 trailer[0] = 5;
713                 trailer[1] = 0xFF;
714                 trailer[2] = 0;
715                 trailer[3] = 0;
716                 trailer[4] = 0;
717                 trailer[5] = 0;
718                 trailer[6] = siglen >> 24;
719                 trailer[7] = (siglen >> 16) & 0xFF;
720                 trailer[8] = (siglen >> 8) & 0xFF;
721                 trailer[9] = siglen & 0xFF;
722                 hashdata.data[hashdata.chunks] = trailer;
723                 hashdata.len[hashdata.chunks] = 10;
724                 hashdata.chunks++;
725
726                 unhashedlen = (sig->data[siglen] << 8) +
727                         sig->data[siglen + 1];
728                 *sighash = &sig->data[siglen + unhashedlen + 2];
729                 break;
730         default:
731                 return ONAK_E_UNSUPPORTED_FEATURE;
732         }
733
734         hashdata.hashtype = *hashtype;
735
736         res = onak_hash(&hashdata, hash);
737
738         return res;
739 }