]> the.earth.li Git - onak.git/blob - sigcheck.c
0.6.3 release
[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 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_packet *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         int len, ofs;
292         size_t count;
293         mpz_t s;
294
295         ret = onak_parse_key_material(sigkey, &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, &count, 1, 1, 0, 0, dsasig.r);
366                 if (count < 32) {
367                         memmove(&edsig[32 - count], edsig, count);
368                         while (count < 32) {
369                                 count++;
370                                 edsig[32 - count] = 0;
371                         }
372                 }
373                 mpz_export(&edsig[32], &count, 1, 1, 0, 0, dsasig.s);
374                 if (count < 32) {
375                         memmove(&edsig[32 - count], edsig, count);
376                         while (count < 32) {
377                                 count++;
378                                 edsig[32 - count] = 0;
379                         }
380                 }
381                 break;
382         case OPENPGP_PKALGO_RSA:
383         case OPENPGP_PKALGO_RSA_SIGN:
384                 mpz_init(s);
385                 MPI_TO_MPZ(sig, s);
386                 break;
387         }
388
389         /* If we didn't parse the signature properly then do clean-up */
390         if (ret != ONAK_E_OK)
391                 goto sigerr;
392
393         /* Squash a signing only RSA key to a standard RSA key for below */
394         if (pubkey.type == OPENPGP_PKALGO_RSA_SIGN) {
395                 pubkey.type = OPENPGP_PKALGO_RSA;
396         }
397
398 #define KEYHASH(key, hash) ((key << 8) | hash)
399
400         switch KEYHASH(pubkey.type, hashtype) {
401         case KEYHASH(OPENPGP_PKALGO_DSA, OPENPGP_HASH_MD5):
402                 ret = dsa_verify(&pubkey.dsa, pubkey.y,
403                                 MD5_DIGEST_SIZE, hash, &dsasig) ?
404                         ONAK_E_WEAK_SIGNATURE : ONAK_E_BAD_SIGNATURE;
405                 break;
406         case KEYHASH(OPENPGP_PKALGO_DSA, OPENPGP_HASH_RIPEMD160):
407                 ret = dsa_verify(&pubkey.dsa, pubkey.y,
408                                 RIPEMD160_DIGEST_SIZE, hash, &dsasig) ?
409                         ONAK_E_OK : ONAK_E_BAD_SIGNATURE;
410                 break;
411         case KEYHASH(OPENPGP_PKALGO_DSA, OPENPGP_HASH_SHA1):
412                 ret = dsa_verify(&pubkey.dsa, pubkey.y,
413                                 SHA1_DIGEST_SIZE, hash, &dsasig) ?
414                         ONAK_E_OK : ONAK_E_BAD_SIGNATURE;
415                 break;
416         case KEYHASH(OPENPGP_PKALGO_DSA, OPENPGP_HASH_SHA1X):
417                 ret = dsa_verify(&pubkey.dsa, pubkey.y,
418                                 SHA1X_DIGEST_SIZE, hash, &dsasig) ?
419                         ONAK_E_OK : ONAK_E_BAD_SIGNATURE;
420                 break;
421         case KEYHASH(OPENPGP_PKALGO_DSA, OPENPGP_HASH_SHA224):
422                 ret = dsa_verify(&pubkey.dsa, pubkey.y,
423                                 SHA224_DIGEST_SIZE, hash, &dsasig) ?
424                         ONAK_E_OK : ONAK_E_BAD_SIGNATURE;
425                 break;
426         case KEYHASH(OPENPGP_PKALGO_DSA, OPENPGP_HASH_SHA256):
427                 ret = dsa_verify(&pubkey.dsa, pubkey.y,
428                                 SHA256_DIGEST_SIZE, hash, &dsasig) ?
429                         ONAK_E_OK : ONAK_E_BAD_SIGNATURE;
430                 break;
431         case KEYHASH(OPENPGP_PKALGO_DSA, OPENPGP_HASH_SHA384):
432                 ret = dsa_verify(&pubkey.dsa, pubkey.y,
433                                 SHA384_DIGEST_SIZE, hash, &dsasig) ?
434                         ONAK_E_OK : ONAK_E_BAD_SIGNATURE;
435                 break;
436         case KEYHASH(OPENPGP_PKALGO_DSA, OPENPGP_HASH_SHA512):
437                 ret = dsa_verify(&pubkey.dsa, pubkey.y,
438                                 SHA512_DIGEST_SIZE, hash, &dsasig) ?
439                         ONAK_E_OK : ONAK_E_BAD_SIGNATURE;
440                 break;
441         case KEYHASH(OPENPGP_PKALGO_ECDSA, OPENPGP_HASH_SHA1):
442                 ret = ecdsa_verify(&pubkey.ecc,
443                                 SHA1_DIGEST_SIZE, hash, &dsasig) ?
444                         ONAK_E_OK : ONAK_E_BAD_SIGNATURE;
445                 break;
446         case KEYHASH(OPENPGP_PKALGO_ECDSA, OPENPGP_HASH_SHA256):
447                 ret = ecdsa_verify(&pubkey.ecc,
448                                 SHA256_DIGEST_SIZE, hash, &dsasig) ?
449                         ONAK_E_OK : ONAK_E_BAD_SIGNATURE;
450                 break;
451         case KEYHASH(OPENPGP_PKALGO_ECDSA, OPENPGP_HASH_SHA384):
452                 ret = ecdsa_verify(&pubkey.ecc,
453                                 SHA384_DIGEST_SIZE, hash, &dsasig) ?
454                         ONAK_E_OK : ONAK_E_BAD_SIGNATURE;
455                 break;
456         case KEYHASH(OPENPGP_PKALGO_ECDSA, OPENPGP_HASH_SHA512):
457                 ret = ecdsa_verify(&pubkey.ecc,
458                                 SHA512_DIGEST_SIZE, hash, &dsasig) ?
459                         ONAK_E_OK : ONAK_E_BAD_SIGNATURE;
460                 break;
461         case KEYHASH(OPENPGP_PKALGO_EDDSA, OPENPGP_HASH_RIPEMD160):
462                 ret = ed25519_sha512_verify(pubkey.ed25519,
463                                 RIPEMD160_DIGEST_SIZE, hash, edsig) ?
464                         ONAK_E_OK : ONAK_E_BAD_SIGNATURE;
465                 break;
466         case KEYHASH(OPENPGP_PKALGO_EDDSA, OPENPGP_HASH_SHA256):
467                 ret = ed25519_sha512_verify(pubkey.ed25519,
468                                 SHA256_DIGEST_SIZE, hash, edsig) ?
469                         ONAK_E_OK : ONAK_E_BAD_SIGNATURE;
470                 break;
471         case KEYHASH(OPENPGP_PKALGO_EDDSA, OPENPGP_HASH_SHA384):
472                 ret = ed25519_sha512_verify(pubkey.ed25519,
473                                 SHA384_DIGEST_SIZE, hash, edsig) ?
474                         ONAK_E_OK : ONAK_E_BAD_SIGNATURE;
475                 break;
476         case KEYHASH(OPENPGP_PKALGO_EDDSA, OPENPGP_HASH_SHA512):
477                 ret = ed25519_sha512_verify(pubkey.ed25519,
478                                 SHA512_DIGEST_SIZE, hash, edsig) ?
479                         ONAK_E_OK : ONAK_E_BAD_SIGNATURE;
480                 break;
481         case KEYHASH(OPENPGP_PKALGO_RSA, OPENPGP_HASH_MD5):
482                 ret = rsa_md5_verify_digest(&pubkey.rsa, hash, s) ?
483                         ONAK_E_WEAK_SIGNATURE : ONAK_E_BAD_SIGNATURE;
484                 break;
485         case KEYHASH(OPENPGP_PKALGO_RSA, OPENPGP_HASH_RIPEMD160):
486                 ret = rsa_ripemd160_verify_digest(&pubkey.rsa, hash, s) ?
487                         ONAK_E_OK : ONAK_E_BAD_SIGNATURE;
488                 break;
489         case KEYHASH(OPENPGP_PKALGO_RSA, OPENPGP_HASH_SHA1):
490                 ret = rsa_sha1_verify_digest(&pubkey.rsa, hash, s) ?
491                         ONAK_E_OK : ONAK_E_BAD_SIGNATURE;
492                 break;
493         case KEYHASH(OPENPGP_PKALGO_RSA, OPENPGP_HASH_SHA224):
494                 ret = rsa_sha224_verify_digest(&pubkey.rsa, hash, s) ?
495                         ONAK_E_OK : ONAK_E_BAD_SIGNATURE;
496                 break;
497         case KEYHASH(OPENPGP_PKALGO_RSA, OPENPGP_HASH_SHA256):
498                 ret = rsa_sha256_verify_digest(&pubkey.rsa, hash, s) ?
499                         ONAK_E_OK : ONAK_E_BAD_SIGNATURE;
500                 break;
501         case KEYHASH(OPENPGP_PKALGO_RSA, OPENPGP_HASH_SHA384):
502                 ret = rsa_sha384_verify_digest(&pubkey.rsa, hash, s) ?
503                         ONAK_E_OK : ONAK_E_BAD_SIGNATURE;
504                 break;
505         case KEYHASH(OPENPGP_PKALGO_RSA, OPENPGP_HASH_SHA512):
506                 ret = rsa_sha512_verify_digest(&pubkey.rsa, hash, s) ?
507                         ONAK_E_OK : ONAK_E_BAD_SIGNATURE;
508                 break;
509         default:
510                 ret = ONAK_E_UNSUPPORTED_FEATURE;
511         }
512
513 sigerr:
514         switch (sigkeytype) {
515         case OPENPGP_PKALGO_ECDSA:
516         case OPENPGP_PKALGO_EDDSA:
517         case OPENPGP_PKALGO_DSA:
518                 mpz_clear(dsasig.r);
519                 mpz_clear(dsasig.s);
520                 break;
521         case OPENPGP_PKALGO_RSA:
522         case OPENPGP_PKALGO_RSA_SIGN:
523                 mpz_clear(s);
524                 break;
525         }
526
527 out:
528         onak_free_key_material(&pubkey);
529
530         return ret;
531 }
532
533 #endif /* HAVE_CRYPTO */
534
535 onak_status_t calculate_packet_sighash(struct openpgp_publickey *key,
536                         struct openpgp_packet *packet,
537                         struct openpgp_packet *sig,
538                         uint8_t *hashtype,
539                         uint8_t *hash,
540                         uint8_t **sighash)
541 {
542         size_t siglen, unhashedlen;
543         struct onak_hash_data hashdata;
544         uint8_t keyheader[5];
545         uint8_t packetheader[5];
546         uint8_t trailer[10];
547         uint64_t keyid;
548         onak_status_t res;
549
550         *hashtype = 0;
551         *sighash = NULL;
552         memset(&hashdata, 0, sizeof(hashdata));
553
554         switch (sig->data[0]) {
555         case 2:
556         case 3:
557                 keyheader[0] = 0x99;
558                 keyheader[1] = key->publickey->length >> 8;
559                 keyheader[2] = key->publickey->length & 0xFF;
560                 hashdata.data[0] = keyheader;
561                 hashdata.len[0] = 3;
562                 hashdata.data[1] = key->publickey->data;
563                 hashdata.len[1] = key->publickey->length;
564                 hashdata.chunks = 2;
565
566                 *hashtype = sig->data[16];
567
568                 if (packet != NULL) {
569                         if (packet->tag == OPENPGP_PACKET_PUBLICSUBKEY) {
570                                 packetheader[0] = 0x99;
571                                 packetheader[1] = packet->length >> 8;
572                                 packetheader[2] = packet->length & 0xFF;
573                                 hashdata.data[hashdata.chunks] = packetheader;
574                                 hashdata.len[hashdata.chunks] = 3;
575                                 hashdata.chunks++;
576                         }
577
578                         // TODO: Things other than UIDS/subkeys?
579                         hashdata.data[hashdata.chunks] = packet->data;
580                         hashdata.len[hashdata.chunks] = packet->length;
581                         hashdata.chunks++;
582                 }
583
584                 hashdata.data[hashdata.chunks] = &sig->data[2];
585                 hashdata.len[hashdata.chunks] = 5;
586                 hashdata.chunks++;
587                 *sighash = &sig->data[17];
588                 break;
589         case 4:
590                 keyheader[0] = 0x99;
591                 keyheader[1] = key->publickey->length >> 8;
592                 keyheader[2] = key->publickey->length & 0xFF;
593                 hashdata.data[0] = keyheader;
594                 hashdata.len[0] = 3;
595                 hashdata.data[1] = key->publickey->data;
596                 hashdata.len[1] = key->publickey->length;
597                 hashdata.chunks = 2;
598
599                 /* Check to see if this is an X509 based signature */
600                 if (sig->data[2] == 0 || sig->data[2] == 100) {
601                         size_t len;
602
603                         keyid = 0;
604                         res = parse_subpackets(&sig->data[4],
605                                                 sig->length - 4, &len,
606                                                 &keyid, NULL);
607                         if (res != ONAK_E_OK) {
608                                 return res;
609                         }
610                         if (keyid == 0 &&
611                                         /* No unhashed data */
612                                         sig->data[4 + len] == 0 &&
613                                         sig->data[5 + len] == 0 &&
614                                         /* Dummy 0 checksum */
615                                         sig->data[6 + len] == 0 &&
616                                         sig->data[7 + len] == 0 &&
617                                         /* Dummy MPI of 1 */
618                                         sig->data[8 + len] == 0 &&
619                                         sig->data[9 + len] == 1 &&
620                                         sig->data[10 + len] == 1) {
621                                 return ONAK_E_UNSUPPORTED_FEATURE;
622                         }
623                 }
624
625                 *hashtype = sig->data[3];
626
627                 if (packet != NULL) {
628                         if (packet->tag == OPENPGP_PACKET_PUBLICSUBKEY) {
629                                 packetheader[0] = 0x99;
630                                 packetheader[1] = packet->length >> 8;
631                                 packetheader[2] = packet->length & 0xFF;
632                                 hashdata.data[hashdata.chunks] = packetheader;
633                                 hashdata.len[hashdata.chunks] = 3;
634                                 hashdata.chunks++;
635                         } else if (packet->tag == OPENPGP_PACKET_UID ||
636                                         packet->tag == OPENPGP_PACKET_UAT) {
637                                 packetheader[0] = (packet->tag ==
638                                         OPENPGP_PACKET_UID) ?  0xB4 : 0xD1;
639                                 packetheader[1] = packet->length >> 24;
640                                 packetheader[2] = (packet->length >> 16) & 0xFF;
641                                 packetheader[3] = (packet->length >> 8) & 0xFF;
642                                 packetheader[4] = packet->length & 0xFF;
643                                 hashdata.data[hashdata.chunks] = packetheader;
644                                 hashdata.len[hashdata.chunks] = 5;
645                                 hashdata.chunks++;
646                         }
647                         hashdata.data[hashdata.chunks] = packet->data;
648                         hashdata.len[hashdata.chunks] = packet->length;
649                         hashdata.chunks++;
650                 }
651
652                 hashdata.data[hashdata.chunks] = sig->data;
653                 hashdata.len[hashdata.chunks] = siglen = (sig->data[4] << 8) +
654                         sig->data[5] + 6;;
655                 if (siglen > sig->length) {
656                         /* Signature data exceed packet length, bogus */
657                         return ONAK_E_INVALID_PKT;
658                 }
659                 hashdata.chunks++;
660
661                 trailer[0] = 4;
662                 trailer[1] = 0xFF;
663                 trailer[2] = siglen >> 24;
664                 trailer[3] = (siglen >> 16) & 0xFF;
665                 trailer[4] = (siglen >> 8) & 0xFF;
666                 trailer[5] = siglen & 0xFF;
667                 hashdata.data[hashdata.chunks] = trailer;
668                 hashdata.len[hashdata.chunks] = 6;
669                 hashdata.chunks++;
670
671                 unhashedlen = (sig->data[siglen] << 8) +
672                         sig->data[siglen + 1];
673                 *sighash = &sig->data[siglen + unhashedlen + 2];
674                 break;
675         case 5:
676                 keyheader[0] = 0x9A;
677                 keyheader[1] = 0;
678                 keyheader[2] = 0;
679                 keyheader[3] = key->publickey->length >> 8;
680                 keyheader[4] = key->publickey->length & 0xFF;
681                 hashdata.data[0] = keyheader;
682                 hashdata.len[0] = 5;
683                 hashdata.data[1] = key->publickey->data;
684                 hashdata.len[1] = key->publickey->length;
685                 hashdata.chunks = 2;
686
687                 *hashtype = sig->data[3];
688
689                 if (packet != NULL) {
690                         if (packet->tag == OPENPGP_PACKET_PUBLICSUBKEY) {
691                                 packetheader[0] = 0x9A;
692                                 packetheader[1] = 0;
693                                 packetheader[2] = 0;
694                                 packetheader[3] = packet->length >> 8;
695                                 packetheader[4] = packet->length & 0xFF;
696                                 hashdata.data[hashdata.chunks] = packetheader;
697                                 hashdata.len[hashdata.chunks] = 5;
698                                 hashdata.chunks++;
699                         } else if (packet->tag == OPENPGP_PACKET_UID ||
700                                         packet->tag == OPENPGP_PACKET_UAT) {
701                                 packetheader[0] = (packet->tag ==
702                                         OPENPGP_PACKET_UID) ?  0xB4 : 0xD1;
703                                 packetheader[1] = packet->length >> 24;
704                                 packetheader[2] = (packet->length >> 16) & 0xFF;
705                                 packetheader[3] = (packet->length >> 8) & 0xFF;
706                                 packetheader[4] = packet->length & 0xFF;
707                                 hashdata.data[hashdata.chunks] = packetheader;
708                                 hashdata.len[hashdata.chunks] = 5;
709                                 hashdata.chunks++;
710                         }
711                         hashdata.data[hashdata.chunks] = packet->data;
712                         hashdata.len[hashdata.chunks] = packet->length;
713                         hashdata.chunks++;
714                 }
715
716                 hashdata.data[hashdata.chunks] = sig->data;
717                 hashdata.len[hashdata.chunks] = siglen = (sig->data[4] << 8) +
718                         sig->data[5] + 6;;
719                 if (siglen > sig->length) {
720                         /* Signature data exceed packet length, bogus */
721                         return ONAK_E_INVALID_PKT;
722                 }
723                 hashdata.chunks++;
724
725                 trailer[0] = 5;
726                 trailer[1] = 0xFF;
727                 trailer[2] = 0;
728                 trailer[3] = 0;
729                 trailer[4] = 0;
730                 trailer[5] = 0;
731                 trailer[6] = siglen >> 24;
732                 trailer[7] = (siglen >> 16) & 0xFF;
733                 trailer[8] = (siglen >> 8) & 0xFF;
734                 trailer[9] = siglen & 0xFF;
735                 hashdata.data[hashdata.chunks] = trailer;
736                 hashdata.len[hashdata.chunks] = 10;
737                 hashdata.chunks++;
738
739                 unhashedlen = (sig->data[siglen] << 8) +
740                         sig->data[siglen + 1];
741                 *sighash = &sig->data[siglen + unhashedlen + 2];
742                 break;
743         default:
744                 return ONAK_E_UNSUPPORTED_FEATURE;
745         }
746
747         hashdata.hashtype = *hashtype;
748
749         res = onak_hash(&hashdata, hash);
750
751         return res;
752 }