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