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