Added SILC Thread Queue API
[silc.git] / lib / silccrypt / silcpkcs1.c
1 /*
2
3   silcpkcs1.c
4
5   Author: Pekka Riikonen <priikone@silcnet.org>
6
7   Copyright (C) 2003 - 2007 Pekka Riikonen
8
9   This program is free software; you can redistribute it and/or modify
10   it under the terms of the GNU General Public License as published by
11   the Free Software Foundation; version 2 of the License.
12
13   This program is distributed in the hope that it will be useful,
14   but WITHOUT ANY WARRANTY; without even the implied warranty of
15   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16   GNU General Public License for more details.
17
18 */
19 /* $Id$ */
20
21 #include "silc.h"
22 #include "rsa.h"
23 #include "silcpkcs1_i.h"
24
25 /************************** PKCS #1 message format ***************************/
26
27 /* Minimum padding in block */
28 #define SILC_PKCS1_MIN_PADDING 8
29
30 /* Encodes PKCS#1 data block from the `data' according to the block type
31    indicated by `bt'.  When encoding signatures the `bt' must be
32    SILC_PKCS1_BT_PRV1 and when encoding encryption blocks the `bt' must
33    be SILC_PKCS1_BT_PUB.  The encoded data is copied into the `dest_data'
34    buffer which is size of `dest_data_size'.  If the `dest_data' is not
35    able to hold the encoded block this returns FALSE.  The `rng' must be
36    set when `bt' is SILC_PKCS1_BT_PUB.  This function returns TRUE on
37    success. */
38
39 SilcBool silc_pkcs1_encode(SilcPkcs1BlockType bt,
40                            const unsigned char *data,
41                            SilcUInt32 data_len,
42                            unsigned char *dest_data,
43                            SilcUInt32 dest_data_size,
44                            SilcRng rng)
45 {
46   SilcInt32 padlen;
47   int i;
48
49   SILC_LOG_DEBUG(("PKCS#1 encoding, bt %d", bt));
50
51   if (!data || !dest_data ||
52       dest_data_size < SILC_PKCS1_MIN_PADDING + 3 ||
53       dest_data_size < data_len) {
54     SILC_LOG_DEBUG(("Data to be encoded is too long"));
55     return FALSE;
56   }
57
58   /* Start of block */
59   dest_data[0] = 0x00;
60   dest_data[1] = (unsigned char)bt;
61
62   padlen = (SilcInt32)dest_data_size - (SilcInt32)data_len - 3;
63   if (padlen < SILC_PKCS1_MIN_PADDING) {
64     SILC_LOG_DEBUG(("Data to be encoded is too long"));
65     return FALSE;
66   }
67
68   /* Encode according to block type */
69   switch (bt) {
70   case SILC_PKCS1_BT_PRV0:
71   case SILC_PKCS1_BT_PRV1:
72     /* Signature */
73     memset(dest_data + 2, bt == SILC_PKCS1_BT_PRV1 ? 0xff : 0x00, padlen);
74     break;
75
76   case SILC_PKCS1_BT_PUB:
77     /* Encryption */
78     if (!rng) {
79       SILC_LOG_ERROR(("Cannot encrypt: random number generator not provided"));
80       return FALSE;
81     }
82
83     /* It is guaranteed this routine does not return zero byte. */
84     for (i = 2; i < padlen; i++)
85       dest_data[i] = silc_rng_get_byte_fast(rng);
86
87     break;
88   }
89
90   /* Copy the data */
91   dest_data[padlen + 2] = 0x00;
92   memcpy(dest_data + padlen + 3, data, data_len);
93
94   return TRUE;
95 }
96
97 /* Decodes the PKCS#1 encoded block according to the block type `bt'.
98    When verifying signatures the `bt' must be SILC_PKCS1_BT_PRV1 and
99    when decrypting it must be SILC_PKCS1_BT_PUB.  This copies the
100    decoded data into `dest_data' which is size of `dest_data_size'.  If
101    the deocded block does not fit to `dest_data' this returns FALSE.
102    Returns TRUE on success. */
103
104 SilcBool silc_pkcs1_decode(SilcPkcs1BlockType bt,
105                            const unsigned char *data,
106                            SilcUInt32 data_len,
107                            unsigned char *dest_data,
108                            SilcUInt32 dest_data_size,
109                            SilcUInt32 *dest_len)
110 {
111   int i = 0;
112
113   SILC_LOG_DEBUG(("PKCS#1 decoding, bt %d", bt));
114
115   /* Sanity checks */
116   if (!data || !dest_data || dest_data_size < 3 ||
117       data[0] != 0x00 || data[1] != (unsigned char)bt) {
118     SILC_LOG_DEBUG(("Malformed block"));
119     return FALSE;
120   }
121
122   /* Decode according to block type */
123   switch (bt) {
124   case SILC_PKCS1_BT_PRV0:
125     /* Do nothing */
126     break;
127
128   case SILC_PKCS1_BT_PRV1:
129     /* Verification */
130     for (i = 2; i < data_len; i++)
131       if (data[i] != 0xff)
132         break;
133     break;
134
135   case SILC_PKCS1_BT_PUB:
136     /* Decryption */
137     for (i = 2; i < data_len; i++)
138       if (data[i] == 0x00)
139         break;
140     break;
141   }
142
143   /* Sanity checks */
144   if (data[i++] != 0x00) {
145     SILC_LOG_DEBUG(("Malformed block"));
146     return FALSE;
147   }
148   if (i - 1 < SILC_PKCS1_MIN_PADDING) {
149     SILC_LOG_DEBUG(("Malformed block"));
150     return FALSE;
151   }
152   if (dest_data_size < data_len - i) {
153     SILC_LOG_DEBUG(("Destination buffer too small"));
154     return FALSE;
155   }
156
157   /* Copy the data */
158   memcpy(dest_data, data + i, data_len - i);
159
160   /* Return data length */
161   if (dest_len)
162     *dest_len = data_len - i;
163
164   return TRUE;
165 }
166
167
168 /***************************** PKCS #1 PKCS API ******************************/
169
170 /* Generates RSA key pair. */
171
172 SILC_PKCS_ALG_GENERATE_KEY(silc_pkcs1_generate_key)
173 {
174   SilcUInt32 prime_bits = keylen / 2;
175   SilcMPInt p, q;
176   SilcBool found = FALSE;
177
178   if (keylen < 768 || keylen > 16384)
179     return FALSE;
180
181   silc_mp_init(&p);
182   silc_mp_init(&q);
183
184   /* Find p and q */
185   while (!found) {
186     silc_math_gen_prime(&p, prime_bits, FALSE, rng);
187     silc_math_gen_prime(&q, prime_bits, FALSE, rng);
188     if ((silc_mp_cmp(&p, &q)) != 0)
189       found = TRUE;
190   }
191
192   /* If p is smaller than q, switch them */
193   if ((silc_mp_cmp(&p, &q)) > 0) {
194     SilcMPInt hlp;
195     silc_mp_init(&hlp);
196
197     silc_mp_set(&hlp, &p);
198     silc_mp_set(&p, &q);
199     silc_mp_set(&q, &hlp);
200
201     silc_mp_uninit(&hlp);
202   }
203
204   /* Generate the actual keys */
205   if (!silc_rsa_generate_keys(keylen, &p, &q, ret_public_key, ret_private_key))
206     return FALSE;
207
208   silc_mp_uninit(&p);
209   silc_mp_uninit(&q);
210
211   return TRUE;
212 }
213
214 /* Import PKCS #1 compliant public key */
215
216 SILC_PKCS_ALG_IMPORT_PUBLIC_KEY(silc_pkcs1_import_public_key)
217 {
218   SilcAsn1 asn1 = NULL;
219   SilcBufferStruct alg_key;
220   RsaPublicKey *pubkey;
221
222   if (!ret_public_key)
223     return 0;
224
225   asn1 = silc_asn1_alloc(NULL);
226   if (!asn1)
227     return 0;
228
229   /* Allocate RSA public key */
230   *ret_public_key = pubkey = silc_calloc(1, sizeof(*pubkey));
231   if (!pubkey)
232     goto err;
233
234   /* Parse the PKCS #1 public key */
235   silc_buffer_set(&alg_key, key, key_len);
236   if (!silc_asn1_decode(asn1, &alg_key,
237                         SILC_ASN1_OPTS(SILC_ASN1_ALLOC),
238                         SILC_ASN1_SEQUENCE,
239                           SILC_ASN1_INT(&pubkey->n),
240                           SILC_ASN1_INT(&pubkey->e),
241                         SILC_ASN1_END, SILC_ASN1_END))
242     goto err;
243
244   /* Set key length */
245   pubkey->bits = ((silc_mp_sizeinbase(&pubkey->n, 2) + 7) / 8) * 8;
246
247   silc_asn1_free(asn1);
248
249   return key_len;
250
251  err:
252   silc_free(pubkey);
253   silc_asn1_free(asn1);
254   return 0;
255 }
256
257 /* Export PKCS #1 compliant public key */
258
259 SILC_PKCS_ALG_EXPORT_PUBLIC_KEY(silc_pkcs1_export_public_key)
260 {
261   RsaPublicKey *key = public_key;
262   SilcAsn1 asn1 = NULL;
263   SilcBufferStruct alg_key;
264   unsigned char *ret;
265
266   asn1 = silc_asn1_alloc(stack);
267   if (!asn1)
268     goto err;
269
270   /* Encode to PKCS #1 public key */
271   memset(&alg_key, 0, sizeof(alg_key));
272   if (!silc_asn1_encode(asn1, &alg_key,
273                         SILC_ASN1_OPTS(SILC_ASN1_ALLOC),
274                         SILC_ASN1_SEQUENCE,
275                           SILC_ASN1_INT(&key->n),
276                           SILC_ASN1_INT(&key->e),
277                         SILC_ASN1_END, SILC_ASN1_END))
278     goto err;
279
280   ret = silc_buffer_steal(&alg_key, ret_len);
281   silc_asn1_free(asn1);
282
283   return ret;
284
285  err:
286   if (asn1)
287     silc_asn1_free(asn1);
288   return NULL;
289 }
290
291 /* Returns key length */
292
293 SILC_PKCS_ALG_PUBLIC_KEY_BITLEN(silc_pkcs1_public_key_bitlen)
294 {
295   RsaPublicKey *key = public_key;
296   return key->bits;
297 }
298
299 /* Copy public key */
300
301 SILC_PKCS_ALG_PUBLIC_KEY_COPY(silc_pkcs1_public_key_copy)
302 {
303   RsaPublicKey *key = public_key, *new_key;
304
305   new_key = silc_calloc(1, sizeof(*new_key));
306   if (!new_key)
307     return NULL;
308
309   silc_mp_init(&new_key->n);
310   silc_mp_init(&new_key->e);
311   silc_mp_set(&new_key->n, &key->n);
312   silc_mp_set(&new_key->e, &key->e);
313   new_key->bits = key->bits;
314
315   return new_key;
316 }
317
318 /* Compare public keys */
319
320 SILC_PKCS_ALG_PUBLIC_KEY_COMPARE(silc_pkcs1_public_key_compare)
321 {
322   RsaPublicKey *k1 = key1, *k2 = key2;
323
324   if (k1->bits != k2->bits)
325     return FALSE;
326   if (silc_mp_cmp(&k1->e, &k2->e) != 0)
327     return FALSE;
328   if (silc_mp_cmp(&k1->n, &k2->n) != 0)
329     return FALSE;
330
331   return TRUE;
332 }
333
334 /* Frees public key */
335
336 SILC_PKCS_ALG_PUBLIC_KEY_FREE(silc_pkcs1_public_key_free)
337 {
338   RsaPublicKey *key = public_key;
339
340   silc_mp_uninit(&key->n);
341   silc_mp_uninit(&key->e);
342   silc_free(key);
343 }
344
345 /* Import PKCS #1 compliant private key */
346
347 SILC_PKCS_ALG_IMPORT_PRIVATE_KEY(silc_pkcs1_import_private_key)
348 {
349   SilcAsn1 asn1;
350   SilcBufferStruct alg_key;
351   RsaPrivateKey *privkey;
352   SilcUInt32 ver;
353
354   if (!ret_private_key)
355     return 0;
356
357   asn1 = silc_asn1_alloc(NULL);
358   if (!asn1)
359     return 0;
360
361   /* Allocate RSA private key */
362   *ret_private_key = privkey = silc_calloc(1, sizeof(*privkey));
363   if (!privkey)
364     goto err;
365
366   /* Parse the PKCS #1 private key */
367   silc_buffer_set(&alg_key, key, key_len);
368   if (!silc_asn1_decode(asn1, &alg_key,
369                         SILC_ASN1_OPTS(SILC_ASN1_ALLOC),
370                         SILC_ASN1_SEQUENCE,
371                           SILC_ASN1_SHORT_INT(&ver),
372                           SILC_ASN1_INT(&privkey->n),
373                           SILC_ASN1_INT(&privkey->e),
374                           SILC_ASN1_INT(&privkey->d),
375                           SILC_ASN1_INT(&privkey->p),
376                           SILC_ASN1_INT(&privkey->q),
377                           SILC_ASN1_INT(&privkey->dP),
378                           SILC_ASN1_INT(&privkey->dQ),
379                           SILC_ASN1_INT(&privkey->qP),
380                         SILC_ASN1_END, SILC_ASN1_END))
381     goto err;
382
383   if (ver != 0)
384     goto err;
385
386   /* Set key length */
387   privkey->bits = ((silc_mp_sizeinbase(&privkey->n, 2) + 7) / 8) * 8;
388
389   silc_asn1_free(asn1);
390
391   return key_len;
392
393  err:
394   silc_free(privkey);
395   silc_asn1_free(asn1);
396   return 0;
397 }
398
399 /* Export PKCS #1 compliant private key */
400
401 SILC_PKCS_ALG_EXPORT_PRIVATE_KEY(silc_pkcs1_export_private_key)
402 {
403   RsaPrivateKey *key = private_key;
404   SilcAsn1 asn1;
405   SilcBufferStruct alg_key;
406   unsigned char *ret;
407
408   asn1 = silc_asn1_alloc(stack);
409   if (!asn1)
410     return FALSE;
411
412   /* Encode to PKCS #1 private key */
413   memset(&alg_key, 0, sizeof(alg_key));
414   if (!silc_asn1_encode(asn1, &alg_key,
415                         SILC_ASN1_OPTS(SILC_ASN1_ALLOC),
416                         SILC_ASN1_SEQUENCE,
417                           SILC_ASN1_SHORT_INT(0),
418                           SILC_ASN1_INT(&key->n),
419                           SILC_ASN1_INT(&key->e),
420                           SILC_ASN1_INT(&key->d),
421                           SILC_ASN1_INT(&key->p),
422                           SILC_ASN1_INT(&key->q),
423                           SILC_ASN1_INT(&key->dP),
424                           SILC_ASN1_INT(&key->dQ),
425                           SILC_ASN1_INT(&key->qP),
426                         SILC_ASN1_END, SILC_ASN1_END))
427     goto err;
428
429   ret = silc_buffer_steal(&alg_key, ret_len);
430   silc_asn1_free(asn1);
431
432   return ret;
433
434  err:
435   silc_asn1_free(asn1);
436   return NULL;
437 }
438
439 /* Returns key length */
440
441 SILC_PKCS_ALG_PRIVATE_KEY_BITLEN(silc_pkcs1_private_key_bitlen)
442 {
443   RsaPrivateKey *key = private_key;
444   return key->bits;
445 }
446
447 /* Frees private key */
448
449 SILC_PKCS_ALG_PRIVATE_KEY_FREE(silc_pkcs1_private_key_free)
450 {
451   RsaPrivateKey *key = private_key;
452
453   silc_mp_uninit(&key->n);
454   silc_mp_uninit(&key->e);
455   silc_mp_uninit(&key->d);
456   silc_mp_uninit(&key->dP);
457   silc_mp_uninit(&key->dQ);
458   silc_mp_uninit(&key->qP);
459   silc_mp_uninit(&key->p);
460   silc_mp_uninit(&key->q);
461   silc_free(key);
462 }
463
464 /* PKCS #1 RSA routines */
465
466 SILC_PKCS_ALG_ENCRYPT(silc_pkcs1_encrypt)
467 {
468   RsaPublicKey *key = public_key;
469   SilcMPInt mp_tmp;
470   SilcMPInt mp_dst;
471   unsigned char padded[2048 + 1];
472   SilcUInt32 len = (key->bits + 7) / 8;
473   SilcStack stack;
474
475   if (sizeof(padded) < len) {
476     encrypt_cb(FALSE, NULL, 0, context);
477     return NULL;
478   }
479
480   /* Pad data */
481   if (!silc_pkcs1_encode(SILC_PKCS1_BT_PUB, src, src_len,
482                          padded, len, rng)) {
483     encrypt_cb(FALSE, NULL, 0, context);
484     return NULL;
485   }
486
487   stack = silc_stack_alloc(2048, silc_crypto_stack());
488
489   silc_mp_sinit(stack, &mp_tmp);
490   silc_mp_sinit(stack, &mp_dst);
491
492   /* Data to MP */
493   silc_mp_bin2mp(padded, len, &mp_tmp);
494
495   /* Encrypt */
496   silc_rsa_public_operation(key, &mp_tmp, &mp_dst);
497
498   /* MP to data */
499   silc_mp_mp2bin_noalloc(&mp_dst, padded, len);
500
501   /* Deliver result */
502   encrypt_cb(TRUE, padded, len, context);
503
504   memset(padded, 0, sizeof(padded));
505   silc_mp_suninit(stack, &mp_tmp);
506   silc_mp_suninit(stack, &mp_dst);
507   silc_stack_free(stack);
508
509   return NULL;
510 }
511
512 SILC_PKCS_ALG_DECRYPT(silc_pkcs1_decrypt)
513 {
514   RsaPrivateKey *key = private_key;
515   SilcMPInt mp_tmp;
516   SilcMPInt mp_dst;
517   unsigned char *padded, unpadded[2048 + 1];
518   SilcUInt32 padded_len, dst_len;
519   SilcStack stack;
520
521   if (sizeof(unpadded) < (key->bits + 7) / 8) {
522     decrypt_cb(FALSE, NULL, 0, context);
523     return NULL;
524   }
525
526   stack = silc_stack_alloc(2048, silc_crypto_stack());
527
528   silc_mp_sinit(stack, &mp_tmp);
529   silc_mp_sinit(stack, &mp_dst);
530
531   /* Data to MP */
532   silc_mp_bin2mp(src, src_len, &mp_tmp);
533
534   /* Decrypt */
535   silc_rsa_private_operation(key, &mp_tmp, &mp_dst);
536
537   /* MP to data */
538   padded = silc_mp_mp2bin(&mp_dst, (key->bits + 7) / 8, &padded_len);
539
540   /* Unpad data */
541   if (!silc_pkcs1_decode(SILC_PKCS1_BT_PUB, padded, padded_len,
542                          unpadded, sizeof(unpadded), &dst_len)) {
543     memset(padded, 0, padded_len);
544     silc_free(padded);
545     silc_mp_suninit(stack, &mp_tmp);
546     silc_mp_suninit(stack, &mp_dst);
547     decrypt_cb(FALSE, NULL, 0, context);
548     return NULL;
549   }
550
551   /* Deliver result */
552   decrypt_cb(TRUE, unpadded, dst_len, context);
553
554   memset(padded, 0, padded_len);
555   memset(unpadded, 0, sizeof(unpadded));
556   silc_free(padded);
557   silc_mp_suninit(stack, &mp_tmp);
558   silc_mp_suninit(stack, &mp_dst);
559   silc_stack_free(stack);
560
561   return NULL;
562 }
563
564 /* PKCS #1 sign with appendix, hash OID included in the signature */
565
566 SILC_PKCS_ALG_SIGN(silc_pkcs1_sign)
567 {
568   RsaPrivateKey *key = private_key;
569   unsigned char padded[2048 + 1], hashr[SILC_HASH_MAXLEN];
570   SilcMPInt mp_tmp;
571   SilcMPInt mp_dst;
572   SilcBufferStruct di;
573   SilcUInt32 len = (key->bits + 7) / 8;
574   const char *oid;
575   SilcStack stack;
576   SilcAsn1 asn1;
577
578   SILC_LOG_DEBUG(("Sign"));
579
580   if (sizeof(padded) < len) {
581     sign_cb(FALSE, NULL, 0, context);
582     return NULL;
583   }
584
585   oid = silc_hash_get_oid(hash);
586   if (!oid) {
587     sign_cb(FALSE, NULL, 0, context);
588     return NULL;
589   }
590
591   stack = silc_stack_alloc(2048, silc_crypto_stack());
592
593   asn1 = silc_asn1_alloc(stack);
594   if (!asn1) {
595     silc_stack_free(stack);
596     sign_cb(FALSE, NULL, 0, context);
597     return NULL;
598   }
599
600   /* Compute hash */
601   if (compute_hash) {
602     silc_hash_make(hash, src, src_len, hashr);
603     src = hashr;
604     src_len = silc_hash_len(hash);
605   }
606
607   /* Encode digest info */
608   memset(&di, 0, sizeof(di));
609   if (!silc_asn1_encode(asn1, &di,
610                         SILC_ASN1_SEQUENCE,
611                           SILC_ASN1_SEQUENCE,
612                             SILC_ASN1_OID(oid),
613                             SILC_ASN1_NULL(TRUE),
614                           SILC_ASN1_END,
615                           SILC_ASN1_OCTET_STRING(src, src_len),
616                         SILC_ASN1_END, SILC_ASN1_END)) {
617     silc_asn1_free(asn1);
618     silc_stack_free(stack);
619     sign_cb(FALSE, NULL, 0, context);
620     return NULL;
621   }
622   SILC_LOG_HEXDUMP(("DigestInfo"), silc_buffer_data(&di),
623                    silc_buffer_len(&di));
624
625   /* Pad data */
626   if (!silc_pkcs1_encode(SILC_PKCS1_BT_PRV1, silc_buffer_data(&di),
627                          silc_buffer_len(&di), padded, len, NULL)) {
628     silc_asn1_free(asn1);
629     silc_stack_free(stack);
630     sign_cb(FALSE, NULL, 0, context);
631     return NULL;
632   }
633
634   silc_mp_sinit(stack, &mp_tmp);
635   silc_mp_sinit(stack, &mp_dst);
636
637   /* Data to MP */
638   silc_mp_bin2mp(padded, len, &mp_tmp);
639
640   /* Sign */
641   silc_rsa_private_operation(key, &mp_tmp, &mp_dst);
642
643   /* MP to data */
644   silc_mp_mp2bin_noalloc(&mp_dst, padded, len);
645
646   /* Deliver result */
647   sign_cb(TRUE, padded, len, context);
648
649   memset(padded, 0, sizeof(padded));
650   if (compute_hash)
651     memset(hashr, 0, sizeof(hashr));
652   silc_mp_suninit(stack, &mp_tmp);
653   silc_mp_suninit(stack, &mp_dst);
654   silc_asn1_free(asn1);
655   silc_stack_free(stack);
656
657   return NULL;
658 }
659
660 /* PKCS #1 verification with appendix. */
661
662 SILC_PKCS_ALG_VERIFY(silc_pkcs1_verify)
663 {
664   RsaPublicKey *key = public_key;
665   SilcBool ret = FALSE;
666   SilcMPInt mp_tmp2;
667   SilcMPInt mp_dst;
668   unsigned char *verify, unpadded[2048 + 1], hashr[SILC_HASH_MAXLEN];
669   SilcUInt32 verify_len, len = (key->bits + 7) / 8;
670   SilcBufferStruct di, ldi;
671   SilcBool has_null = TRUE;
672   SilcHash ihash = NULL;
673   SilcStack stack;
674   SilcAsn1 asn1;
675   char *oid;
676
677   SILC_LOG_DEBUG(("Verify signature"));
678
679   stack = silc_stack_alloc(2048, silc_crypto_stack());
680
681   asn1 = silc_asn1_alloc(stack);
682   if (!asn1) {
683     verify_cb(FALSE, context);
684     return NULL;
685   }
686
687   silc_mp_sinit(stack, &mp_tmp2);
688   silc_mp_sinit(stack, &mp_dst);
689
690   /* Format the signature into MP int */
691   silc_mp_bin2mp(signature, signature_len, &mp_tmp2);
692
693   /* Verify */
694   silc_rsa_public_operation(key, &mp_tmp2, &mp_dst);
695
696   /* MP to data */
697   verify = silc_mp_mp2bin(&mp_dst, len, &verify_len);
698
699   /* Unpad data */
700   if (!silc_pkcs1_decode(SILC_PKCS1_BT_PRV1, verify, verify_len,
701                          unpadded, sizeof(unpadded), &len))
702     goto err;
703   silc_buffer_set(&di, unpadded, len);
704
705   /* If hash isn't given, allocate the one given in digest info */
706   if (!hash) {
707     has_null = FALSE;
708
709     /* Decode digest info */
710     if (!silc_asn1_decode(asn1, &di,
711                           SILC_ASN1_OPTS(SILC_ASN1_ACCUMUL),
712                           SILC_ASN1_SEQUENCE,
713                             SILC_ASN1_SEQUENCE,
714                               SILC_ASN1_OID(&oid),
715                               SILC_ASN1_NULL_T(SILC_ASN1_OPTIONAL,
716                                                SILC_ASN1_TAG_NULL, &has_null),
717                             SILC_ASN1_END,
718                           SILC_ASN1_END, SILC_ASN1_END))
719       goto err;
720
721     if (!silc_hash_alloc_by_oid(oid, &ihash)) {
722       SILC_LOG_DEBUG(("Unknown OID %s", oid));
723       goto err;
724     }
725     hash = ihash;
726   }
727
728   /* Hash the data */
729   silc_hash_make(hash, data, data_len, hashr);
730   data = hashr;
731   data_len = silc_hash_len(hash);
732   oid = (char *)silc_hash_get_oid(hash);
733
734   /* Encode digest info for comparison */
735   memset(&ldi, 0, sizeof(ldi));
736   if (!silc_asn1_encode(asn1, &ldi,
737                         SILC_ASN1_OPTS(SILC_ASN1_ACCUMUL),
738                         SILC_ASN1_SEQUENCE,
739                           SILC_ASN1_SEQUENCE,
740                             SILC_ASN1_OID(oid),
741                             SILC_ASN1_NULL(has_null),
742                           SILC_ASN1_END,
743                           SILC_ASN1_OCTET_STRING(data, data_len),
744                         SILC_ASN1_END, SILC_ASN1_END))
745     goto err;
746
747   SILC_LOG_HEXDUMP(("DigestInfo remote"), silc_buffer_data(&di),
748                    silc_buffer_len(&di));
749   SILC_LOG_HEXDUMP(("DigestInfo local"), silc_buffer_data(&ldi),
750                    silc_buffer_len(&ldi));
751
752   /* Compare */
753   if (silc_buffer_len(&di) == silc_buffer_len(&ldi) &&
754       !memcmp(silc_buffer_data(&di), silc_buffer_data(&ldi),
755               silc_buffer_len(&ldi)))
756     ret = TRUE;
757
758   /* Deliver result */
759   verify_cb(ret, context);
760
761   memset(verify, 0, verify_len);
762   memset(unpadded, 0, sizeof(unpadded));
763   silc_free(verify);
764   silc_mp_suninit(stack, &mp_tmp2);
765   silc_mp_suninit(stack, &mp_dst);
766   if (hash)
767     memset(hashr, 0, sizeof(hashr));
768   if (ihash)
769     silc_hash_free(ihash);
770   silc_asn1_free(asn1);
771   silc_stack_free(stack);
772
773   return NULL;
774
775  err:
776   memset(verify, 0, verify_len);
777   silc_free(verify);
778   silc_mp_suninit(stack, &mp_tmp2);
779   silc_mp_suninit(stack, &mp_dst);
780   if (ihash)
781     silc_hash_free(ihash);
782   silc_asn1_free(asn1);
783   silc_stack_free(stack);
784
785   verify_cb(FALSE, context);
786   return NULL;
787 }
788
789 /* PKCS #1 sign without hash oid */
790
791 SILC_PKCS_ALG_SIGN(silc_pkcs1_sign_no_oid)
792 {
793   RsaPrivateKey *key = private_key;
794   SilcMPInt mp_tmp;
795   SilcMPInt mp_dst;
796   unsigned char padded[2048 + 1], hashr[SILC_HASH_MAXLEN];
797   SilcUInt32 len = (key->bits + 7) / 8;
798   SilcStack stack;
799
800   SILC_LOG_DEBUG(("Sign"));
801
802   if (sizeof(padded) < len) {
803     sign_cb(FALSE, NULL, 0, context);
804     return NULL;
805   }
806
807   /* Compute hash if requested */
808   if (compute_hash) {
809     silc_hash_make(hash, src, src_len, hashr);
810     src = hashr;
811     src_len = silc_hash_len(hash);
812   }
813
814   /* Pad data */
815   if (!silc_pkcs1_encode(SILC_PKCS1_BT_PRV1, src, src_len,
816                          padded, len, NULL)) {
817     sign_cb(FALSE, NULL, 0, context);
818     return NULL;
819   }
820
821   stack = silc_stack_alloc(2048, silc_crypto_stack());
822
823   silc_mp_sinit(stack, &mp_tmp);
824   silc_mp_sinit(stack, &mp_dst);
825
826   /* Data to MP */
827   silc_mp_bin2mp(padded, len, &mp_tmp);
828
829   /* Sign */
830   silc_rsa_private_operation(key, &mp_tmp, &mp_dst);
831
832   /* MP to data */
833   silc_mp_mp2bin_noalloc(&mp_dst, padded, len);
834
835   /* Deliver result */
836   sign_cb(TRUE, padded, len, context);
837
838   memset(padded, 0, sizeof(padded));
839   if (compute_hash)
840     memset(hashr, 0, sizeof(hashr));
841   silc_mp_suninit(stack, &mp_tmp);
842   silc_mp_suninit(stack, &mp_dst);
843   silc_stack_free(stack);
844
845   return NULL;
846 }
847
848 /* PKCS #1 verify without hash oid */
849
850 SILC_PKCS_ALG_VERIFY(silc_pkcs1_verify_no_oid)
851 {
852   RsaPublicKey *key = public_key;
853   SilcBool ret = FALSE;
854   SilcMPInt mp_tmp2;
855   SilcMPInt mp_dst;
856   unsigned char *verify, unpadded[2048 + 1], hashr[SILC_HASH_MAXLEN];
857   SilcUInt32 verify_len, len = (key->bits + 7) / 8;
858   SilcStack stack;
859
860   SILC_LOG_DEBUG(("Verify signature"));
861
862   stack = silc_stack_alloc(2048, silc_crypto_stack());
863
864   silc_mp_sinit(stack, &mp_tmp2);
865   silc_mp_sinit(stack, &mp_dst);
866
867   /* Format the signature into MP int */
868   silc_mp_bin2mp(signature, signature_len, &mp_tmp2);
869
870   /* Verify */
871   silc_rsa_public_operation(key, &mp_tmp2, &mp_dst);
872
873   /* MP to data */
874   verify = silc_mp_mp2bin(&mp_dst, len, &verify_len);
875
876   /* Unpad data */
877   if (!silc_pkcs1_decode(SILC_PKCS1_BT_PRV1, verify, verify_len,
878                          unpadded, sizeof(unpadded), &len)) {
879     memset(verify, 0, verify_len);
880     silc_free(verify);
881     silc_mp_suninit(stack, &mp_tmp2);
882     silc_mp_suninit(stack, &mp_dst);
883     silc_stack_free(stack);
884     verify_cb(FALSE, context);
885     return NULL;
886   }
887
888   /* Hash data if requested */
889   if (hash) {
890     silc_hash_make(hash, data, data_len, hashr);
891     data = hashr;
892     data_len = silc_hash_len(hash);
893   }
894
895   /* Compare */
896   if (len == data_len && !memcmp(data, unpadded, len))
897     ret = TRUE;
898
899   /* Deliver result */
900   verify_cb(ret, context);
901
902   memset(verify, 0, verify_len);
903   memset(unpadded, 0, sizeof(unpadded));
904   if (hash)
905     memset(hashr, 0, sizeof(hashr));
906   silc_free(verify);
907   silc_mp_suninit(stack, &mp_tmp2);
908   silc_mp_suninit(stack, &mp_dst);
909   silc_stack_free(stack);
910
911   return NULL;
912 }