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