]> the.earth.li Git - onak.git/blob - sigcheck.c
Remove --with-systemd option to dh
[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         case KEYHASH(OPENPGP_PKALGO_ECDSA, OPENPGP_HASH_SHA256):
413                 ret = ecdsa_verify(&pubkey.ecc,
414                                 SHA256_DIGEST_SIZE, hash, &dsasig) ?
415                         ONAK_E_OK : ONAK_E_BAD_SIGNATURE;
416                 break;
417         case KEYHASH(OPENPGP_PKALGO_ECDSA, OPENPGP_HASH_SHA384):
418                 ret = ecdsa_verify(&pubkey.ecc,
419                                 SHA384_DIGEST_SIZE, hash, &dsasig) ?
420                         ONAK_E_OK : ONAK_E_BAD_SIGNATURE;
421                 break;
422         case KEYHASH(OPENPGP_PKALGO_ECDSA, OPENPGP_HASH_SHA512):
423                 ret = ecdsa_verify(&pubkey.ecc,
424                                 SHA512_DIGEST_SIZE, hash, &dsasig) ?
425                         ONAK_E_OK : ONAK_E_BAD_SIGNATURE;
426                 break;
427         case KEYHASH(OPENPGP_PKALGO_EDDSA, OPENPGP_HASH_RIPEMD160):
428                 ret = ed25519_sha512_verify(pubkey.ed25519,
429                                 RIPEMD160_DIGEST_SIZE, hash, edsig) ?
430                         ONAK_E_OK : ONAK_E_BAD_SIGNATURE;
431                 break;
432         case KEYHASH(OPENPGP_PKALGO_EDDSA, OPENPGP_HASH_SHA256):
433                 ret = ed25519_sha512_verify(pubkey.ed25519,
434                                 SHA256_DIGEST_SIZE, hash, edsig) ?
435                         ONAK_E_OK : ONAK_E_BAD_SIGNATURE;
436                 break;
437         case KEYHASH(OPENPGP_PKALGO_EDDSA, OPENPGP_HASH_SHA384):
438                 ret = ed25519_sha512_verify(pubkey.ed25519,
439                                 SHA384_DIGEST_SIZE, hash, edsig) ?
440                         ONAK_E_OK : ONAK_E_BAD_SIGNATURE;
441                 break;
442         case KEYHASH(OPENPGP_PKALGO_EDDSA, OPENPGP_HASH_SHA512):
443                 ret = ed25519_sha512_verify(pubkey.ed25519,
444                                 SHA512_DIGEST_SIZE, hash, edsig) ?
445                         ONAK_E_OK : ONAK_E_BAD_SIGNATURE;
446                 break;
447         case KEYHASH(OPENPGP_PKALGO_RSA, OPENPGP_HASH_MD5):
448                 ret = rsa_md5_verify_digest(&pubkey.rsa, hash, s) ?
449                         ONAK_E_WEAK_SIGNATURE : ONAK_E_BAD_SIGNATURE;
450                 break;
451         case KEYHASH(OPENPGP_PKALGO_RSA, OPENPGP_HASH_RIPEMD160):
452                 ret = rsa_ripemd160_verify_digest(&pubkey.rsa, hash, s) ?
453                         ONAK_E_OK : ONAK_E_BAD_SIGNATURE;
454                 break;
455         case KEYHASH(OPENPGP_PKALGO_RSA, OPENPGP_HASH_SHA1):
456                 ret = rsa_sha1_verify_digest(&pubkey.rsa, hash, s) ?
457                         ONAK_E_OK : ONAK_E_BAD_SIGNATURE;
458                 break;
459         case KEYHASH(OPENPGP_PKALGO_RSA, OPENPGP_HASH_SHA224):
460                 ret = rsa_sha224_verify_digest(&pubkey.rsa, hash, s) ?
461                         ONAK_E_OK : ONAK_E_BAD_SIGNATURE;
462                 break;
463         case KEYHASH(OPENPGP_PKALGO_RSA, OPENPGP_HASH_SHA256):
464                 ret = rsa_sha256_verify_digest(&pubkey.rsa, hash, s) ?
465                         ONAK_E_OK : ONAK_E_BAD_SIGNATURE;
466                 break;
467         case KEYHASH(OPENPGP_PKALGO_RSA, OPENPGP_HASH_SHA384):
468                 ret = rsa_sha384_verify_digest(&pubkey.rsa, hash, s) ?
469                         ONAK_E_OK : ONAK_E_BAD_SIGNATURE;
470                 break;
471         case KEYHASH(OPENPGP_PKALGO_RSA, OPENPGP_HASH_SHA512):
472                 ret = rsa_sha512_verify_digest(&pubkey.rsa, hash, s) ?
473                         ONAK_E_OK : ONAK_E_BAD_SIGNATURE;
474                 break;
475         default:
476                 ret = ONAK_E_UNSUPPORTED_FEATURE;
477         }
478
479 sigerr:
480         switch (sig->data[2]) {
481         case OPENPGP_PKALGO_ECDSA:
482         case OPENPGP_PKALGO_EDDSA:
483         case OPENPGP_PKALGO_DSA:
484                 mpz_clear(dsasig.r);
485                 mpz_clear(dsasig.s);
486                 break;
487         case OPENPGP_PKALGO_RSA:
488         case OPENPGP_PKALGO_RSA_SIGN:
489                 mpz_clear(s);
490                 break;
491         }
492
493 out:
494         onak_free_key_material(&pubkey);
495
496         return ret;
497 }
498
499 #endif /* HAVE_CRYPTO */
500
501 onak_status_t calculate_packet_sighash(struct openpgp_publickey *key,
502                         struct openpgp_packet *packet,
503                         struct openpgp_packet *sig,
504                         uint8_t *hashtype,
505                         uint8_t *hash,
506                         uint8_t **sighash)
507 {
508         size_t siglen, unhashedlen;
509         struct sha1_ctx sha1_context;
510         struct sha1x_ctx sha1x_context;
511         struct md5_ctx md5_context;
512 #ifdef HAVE_NETTLE
513         struct ripemd160_ctx ripemd160_context;
514         struct sha224_ctx sha224_context;
515         struct sha256_ctx sha256_context;
516         struct sha384_ctx sha384_context;
517         struct sha512_ctx sha512_context;
518 #endif
519         uint8_t keyheader[5];
520         uint8_t packetheader[5];
521         uint8_t trailer[10];
522         uint8_t *hashdata[8];
523         size_t hashlen[8];
524         int chunks, i;
525         uint64_t keyid;
526         onak_status_t res;
527
528         *hashtype = 0;
529         *sighash = NULL;
530
531         switch (sig->data[0]) {
532         case 2:
533         case 3:
534                 keyheader[0] = 0x99;
535                 keyheader[1] = key->publickey->length >> 8;
536                 keyheader[2] = key->publickey->length & 0xFF;
537                 hashdata[0] = keyheader;
538                 hashlen[0] = 3;
539                 hashdata[1] = key->publickey->data;
540                 hashlen[1] = key->publickey->length;
541                 chunks = 2;
542
543                 *hashtype = sig->data[16];
544
545                 if (packet != NULL) {
546                         if (packet->tag == OPENPGP_PACKET_PUBLICSUBKEY) {
547                                 packetheader[0] = 0x99;
548                                 packetheader[1] = packet->length >> 8;
549                                 packetheader[2] = packet->length & 0xFF;
550                                 hashdata[chunks] = packetheader;
551                                 hashlen[chunks] = 3;
552                                 chunks++;
553                         }
554
555                         // TODO: Things other than UIDS/subkeys?
556                         hashdata[chunks] = packet->data;
557                         hashlen[chunks] = packet->length;
558                         chunks++;
559                 }
560
561                 hashdata[chunks] = &sig->data[2];
562                 hashlen[chunks] = 5;
563                 chunks++;
564                 *sighash = &sig->data[17];
565                 break;
566         case 4:
567                 keyheader[0] = 0x99;
568                 keyheader[1] = key->publickey->length >> 8;
569                 keyheader[2] = key->publickey->length & 0xFF;
570                 hashdata[0] = keyheader;
571                 hashlen[0] = 3;
572                 hashdata[1] = key->publickey->data;
573                 hashlen[1] = key->publickey->length;
574                 chunks = 2;
575
576                 /* Check to see if this is an X509 based signature */
577                 if (sig->data[2] == 0 || sig->data[2] == 100) {
578                         size_t len;
579
580                         keyid = 0;
581                         res = parse_subpackets(&sig->data[4],
582                                                 sig->length - 4, &len,
583                                                 &keyid, NULL);
584                         if (res != ONAK_E_OK) {
585                                 return res;
586                         }
587                         if (keyid == 0 &&
588                                         /* No unhashed data */
589                                         sig->data[4 + len] == 0 &&
590                                         sig->data[5 + len] == 0 &&
591                                         /* Dummy 0 checksum */
592                                         sig->data[6 + len] == 0 &&
593                                         sig->data[7 + len] == 0 &&
594                                         /* Dummy MPI of 1 */
595                                         sig->data[8 + len] == 0 &&
596                                         sig->data[9 + len] == 1 &&
597                                         sig->data[10 + len] == 1) {
598                                 return ONAK_E_UNSUPPORTED_FEATURE;
599                         }
600                 }
601
602                 *hashtype = sig->data[3];
603
604                 if (packet != NULL) {
605                         if (packet->tag == OPENPGP_PACKET_PUBLICSUBKEY) {
606                                 packetheader[0] = 0x99;
607                                 packetheader[1] = packet->length >> 8;
608                                 packetheader[2] = packet->length & 0xFF;
609                                 hashdata[chunks] = packetheader;
610                                 hashlen[chunks] = 3;
611                                 chunks++;
612                         } else if (packet->tag == OPENPGP_PACKET_UID ||
613                                         packet->tag == OPENPGP_PACKET_UAT) {
614                                 packetheader[0] = (packet->tag ==
615                                         OPENPGP_PACKET_UID) ?  0xB4 : 0xD1;
616                                 packetheader[1] = packet->length >> 24;
617                                 packetheader[2] = (packet->length >> 16) & 0xFF;
618                                 packetheader[3] = (packet->length >> 8) & 0xFF;
619                                 packetheader[4] = packet->length & 0xFF;
620                                 hashdata[chunks] = packetheader;
621                                 hashlen[chunks] = 5;
622                                 chunks++;
623                         }
624                         hashdata[chunks] = packet->data;
625                         hashlen[chunks] = packet->length;
626                         chunks++;
627                 }
628
629                 hashdata[chunks] = sig->data;
630                 hashlen[chunks] = siglen = (sig->data[4] << 8) +
631                         sig->data[5] + 6;;
632                 if (siglen > sig->length) {
633                         /* Signature data exceed packet length, bogus */
634                         return ONAK_E_INVALID_PKT;
635                 }
636                 chunks++;
637
638                 trailer[0] = 4;
639                 trailer[1] = 0xFF;
640                 trailer[2] = siglen >> 24;
641                 trailer[3] = (siglen >> 16) & 0xFF;
642                 trailer[4] = (siglen >> 8) & 0xFF;
643                 trailer[5] = siglen & 0xFF;
644                 hashdata[chunks] = trailer;
645                 hashlen[chunks] = 6;
646                 chunks++;
647
648                 unhashedlen = (sig->data[siglen] << 8) +
649                         sig->data[siglen + 1];
650                 *sighash = &sig->data[siglen + unhashedlen + 2];
651                 break;
652         case 5:
653                 keyheader[0] = 0x9A;
654                 keyheader[1] = 0;
655                 keyheader[2] = 0;
656                 keyheader[3] = key->publickey->length >> 8;
657                 keyheader[4] = key->publickey->length & 0xFF;
658                 hashdata[0] = keyheader;
659                 hashlen[0] = 5;
660                 hashdata[1] = key->publickey->data;
661                 hashlen[1] = key->publickey->length;
662                 chunks = 2;
663
664                 *hashtype = sig->data[3];
665
666                 if (packet != NULL) {
667                         if (packet->tag == OPENPGP_PACKET_PUBLICSUBKEY) {
668                                 packetheader[0] = 0x9A;
669                                 packetheader[1] = 0;
670                                 packetheader[2] = 0;
671                                 packetheader[3] = packet->length >> 8;
672                                 packetheader[4] = packet->length & 0xFF;
673                                 hashdata[chunks] = packetheader;
674                                 hashlen[chunks] = 5;
675                                 chunks++;
676                         } else if (packet->tag == OPENPGP_PACKET_UID ||
677                                         packet->tag == OPENPGP_PACKET_UAT) {
678                                 packetheader[0] = (packet->tag ==
679                                         OPENPGP_PACKET_UID) ?  0xB4 : 0xD1;
680                                 packetheader[1] = packet->length >> 24;
681                                 packetheader[2] = (packet->length >> 16) & 0xFF;
682                                 packetheader[3] = (packet->length >> 8) & 0xFF;
683                                 packetheader[4] = packet->length & 0xFF;
684                                 hashdata[chunks] = packetheader;
685                                 hashlen[chunks] = 5;
686                                 chunks++;
687                         }
688                         hashdata[chunks] = packet->data;
689                         hashlen[chunks] = packet->length;
690                         chunks++;
691                 }
692
693                 hashdata[chunks] = sig->data;
694                 hashlen[chunks] = siglen = (sig->data[4] << 8) +
695                         sig->data[5] + 6;;
696                 if (siglen > sig->length) {
697                         /* Signature data exceed packet length, bogus */
698                         return ONAK_E_INVALID_PKT;
699                 }
700                 chunks++;
701
702                 trailer[0] = 5;
703                 trailer[1] = 0xFF;
704                 trailer[2] = 0;
705                 trailer[3] = 0;
706                 trailer[4] = 0;
707                 trailer[5] = 0;
708                 trailer[6] = siglen >> 24;
709                 trailer[7] = (siglen >> 16) & 0xFF;
710                 trailer[8] = (siglen >> 8) & 0xFF;
711                 trailer[9] = siglen & 0xFF;
712                 hashdata[chunks] = trailer;
713                 hashlen[chunks] = 10;
714                 chunks++;
715
716                 unhashedlen = (sig->data[siglen] << 8) +
717                         sig->data[siglen + 1];
718                 *sighash = &sig->data[siglen + unhashedlen + 2];
719                 break;
720         default:
721                 return ONAK_E_UNSUPPORTED_FEATURE;
722         }
723
724         switch (*hashtype) {
725         case OPENPGP_HASH_MD5:
726                 md5_init(&md5_context);
727                 for (i = 0; i < chunks; i++) {
728                         md5_update(&md5_context, hashlen[i], hashdata[i]);
729                 }
730                 md5_digest(&md5_context, MD5_DIGEST_SIZE, hash);
731                 break;
732         case OPENPGP_HASH_SHA1:
733                 sha1_init(&sha1_context);
734                 for (i = 0; i < chunks; i++) {
735                         sha1_update(&sha1_context, hashlen[i], hashdata[i]);
736                 }
737                 sha1_digest(&sha1_context, SHA1_DIGEST_SIZE, hash);
738                 break;
739         case OPENPGP_HASH_SHA1X:
740                 sha1x_init(&sha1x_context);
741                 for (i = 0; i < chunks; i++) {
742                         sha1x_update(&sha1x_context, hashlen[i], hashdata[i]);
743                 }
744                 sha1x_digest(&sha1x_context, SHA1X_DIGEST_SIZE, hash);
745                 break;
746 #ifdef HAVE_NETTLE
747         case OPENPGP_HASH_RIPEMD160:
748                 ripemd160_init(&ripemd160_context);
749                 for (i = 0; i < chunks; i++) {
750                         ripemd160_update(&ripemd160_context, hashlen[i],
751                                 hashdata[i]);
752                 }
753                 ripemd160_digest(&ripemd160_context, RIPEMD160_DIGEST_SIZE,
754                         hash);
755                 break;
756         case OPENPGP_HASH_SHA224:
757                 sha224_init(&sha224_context);
758                 for (i = 0; i < chunks; i++) {
759                         sha224_update(&sha224_context, hashlen[i],
760                                 hashdata[i]);
761                 }
762                 sha224_digest(&sha224_context, SHA224_DIGEST_SIZE, hash);
763                 break;
764         case OPENPGP_HASH_SHA256:
765                 sha256_init(&sha256_context);
766                 for (i = 0; i < chunks; i++) {
767                         sha256_update(&sha256_context, hashlen[i],
768                                 hashdata[i]);
769                 }
770                 sha256_digest(&sha256_context, SHA256_DIGEST_SIZE, hash);
771                 break;
772         case OPENPGP_HASH_SHA384:
773                 sha384_init(&sha384_context);
774                 for (i = 0; i < chunks; i++) {
775                         sha384_update(&sha384_context, hashlen[i],
776                                 hashdata[i]);
777                 }
778                 sha384_digest(&sha384_context, SHA384_DIGEST_SIZE, hash);
779                 break;
780         case OPENPGP_HASH_SHA512:
781                 sha512_init(&sha512_context);
782                 for (i = 0; i < chunks; i++) {
783                         sha512_update(&sha512_context, hashlen[i],
784                                 hashdata[i]);
785                 }
786                 sha512_digest(&sha512_context, SHA512_DIGEST_SIZE, hash);
787                 break;
788 #endif
789         default:
790                 return ONAK_E_UNSUPPORTED_FEATURE;
791         }
792
793         return ONAK_E_OK;
794 }