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