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