Merge from vendor branch LESS:
[dragonfly.git] / contrib / bind-9.3 / lib / dns / opensslrsa_link.c
1 /*
2  * Copyright (C) 2004  Internet Systems Consortium, Inc. ("ISC")
3  * Copyright (C) 2000-2003  Internet Software Consortium.
4  *
5  * Permission to use, copy, modify, and distribute this software for any
6  * purpose with or without fee is hereby granted, provided that the above
7  * copyright notice and this permission notice appear in all copies.
8  *
9  * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
10  * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
11  * AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
12  * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
13  * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
14  * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
15  * PERFORMANCE OF THIS SOFTWARE.
16  */
17
18 /*
19  * Principal Author: Brian Wellington
20  * $Id: opensslrsa_link.c,v 1.1.4.1 2004/12/09 04:07:18 marka Exp $
21  */
22 #ifdef OPENSSL
23
24 #include <config.h>
25
26 #include <isc/entropy.h>
27 #include <isc/md5.h>
28 #include <isc/sha1.h>
29 #include <isc/mem.h>
30 #include <isc/string.h>
31 #include <isc/util.h>
32
33 #include <dst/result.h>
34
35 #include "dst_internal.h"
36 #include "dst_openssl.h"
37 #include "dst_parse.h"
38
39 #include <openssl/err.h>
40 #include <openssl/objects.h>
41 #include <openssl/rsa.h>
42
43         /*
44          * XXXMPA  Temporarially disable RSA_BLINDING as it requires
45          * good quality random data that cannot currently be guarenteed.
46          * XXXMPA  Find which versions of openssl use pseudo random data
47          * and set RSA_FLAG_BLINDING for those.
48          */
49
50 #if 0
51 #if OPENSSL_VERSION_NUMBER < 0x0090601fL
52 #define SET_FLAGS(rsa) \
53         do { \
54         (rsa)->flags &= ~(RSA_FLAG_CACHE_PUBLIC | RSA_FLAG_CACHE_PRIVATE); \
55         (rsa)->flags |= RSA_FLAG_BLINDING; \
56         } while (0)
57 #else
58 #define SET_FLAGS(rsa) \
59         do { \
60                 (rsa)->flags |= RSA_FLAG_BLINDING; \
61         } while (0)
62 #endif
63 #endif
64
65 #if OPENSSL_VERSION_NUMBER < 0x0090601fL
66 #define SET_FLAGS(rsa) \
67         do { \
68         (rsa)->flags &= ~(RSA_FLAG_CACHE_PUBLIC | RSA_FLAG_CACHE_PRIVATE); \
69         (rsa)->flags &= ~RSA_FLAG_BLINDING; \
70         } while (0)
71 #else
72 #define SET_FLAGS(rsa) \
73         do { \
74                 (rsa)->flags &= ~RSA_FLAG_BLINDING; \
75         } while (0)
76 #endif
77
78 static isc_result_t opensslrsa_todns(const dst_key_t *key, isc_buffer_t *data);
79
80 static isc_result_t
81 opensslrsa_createctx(dst_key_t *key, dst_context_t *dctx) {
82         UNUSED(key);
83         REQUIRE(dctx->key->key_alg == DST_ALG_RSAMD5 ||
84                 dctx->key->key_alg == DST_ALG_RSASHA1);
85
86         if (dctx->key->key_alg == DST_ALG_RSAMD5) {
87                 isc_md5_t *md5ctx;
88
89                 md5ctx = isc_mem_get(dctx->mctx, sizeof(isc_md5_t));
90                 isc_md5_init(md5ctx);
91                 dctx->opaque = md5ctx;
92         } else {
93                 isc_sha1_t *sha1ctx;
94
95                 sha1ctx = isc_mem_get(dctx->mctx, sizeof(isc_sha1_t));
96                 isc_sha1_init(sha1ctx);
97                 dctx->opaque = sha1ctx;
98         }
99
100         return (ISC_R_SUCCESS);
101 }
102
103 static void
104 opensslrsa_destroyctx(dst_context_t *dctx) {
105         REQUIRE(dctx->key->key_alg == DST_ALG_RSAMD5 ||
106                 dctx->key->key_alg == DST_ALG_RSASHA1);
107
108         if (dctx->key->key_alg == DST_ALG_RSAMD5) {
109                 isc_md5_t *md5ctx = dctx->opaque;
110
111                 if (md5ctx != NULL) {
112                         isc_md5_invalidate(md5ctx);
113                         isc_mem_put(dctx->mctx, md5ctx, sizeof(isc_md5_t));
114                 }
115         } else {
116                 isc_sha1_t *sha1ctx = dctx->opaque;
117
118                 if (sha1ctx != NULL) {
119                         isc_sha1_invalidate(sha1ctx);
120                         isc_mem_put(dctx->mctx, sha1ctx, sizeof(isc_sha1_t));
121                 }
122         }
123         dctx->opaque = NULL;
124 }
125
126 static isc_result_t
127 opensslrsa_adddata(dst_context_t *dctx, const isc_region_t *data) {
128         REQUIRE(dctx->key->key_alg == DST_ALG_RSAMD5 ||
129                 dctx->key->key_alg == DST_ALG_RSASHA1);
130
131         if (dctx->key->key_alg == DST_ALG_RSAMD5) {
132                 isc_md5_t *md5ctx = dctx->opaque;
133                 isc_md5_update(md5ctx, data->base, data->length);
134         } else {
135                 isc_sha1_t *sha1ctx = dctx->opaque;
136                 isc_sha1_update(sha1ctx, data->base, data->length);
137         }
138         return (ISC_R_SUCCESS);
139 }
140
141 static isc_result_t
142 opensslrsa_sign(dst_context_t *dctx, isc_buffer_t *sig) {
143         dst_key_t *key = dctx->key;
144         RSA *rsa = key->opaque;
145         isc_region_t r;
146         /* note: ISC_SHA1_DIGESTLENGTH > ISC_MD5_DIGESTLENGTH */
147         unsigned char digest[ISC_SHA1_DIGESTLENGTH];
148         unsigned int siglen = 0;
149         int status;
150         int type;
151         unsigned int digestlen;
152         char *message;
153         unsigned long err;
154         const char* file;
155         int line;
156
157         REQUIRE(dctx->key->key_alg == DST_ALG_RSAMD5 ||
158                 dctx->key->key_alg == DST_ALG_RSASHA1);
159
160         isc_buffer_availableregion(sig, &r);
161
162         if (r.length < (unsigned int) RSA_size(rsa))
163                 return (ISC_R_NOSPACE);
164
165         if (dctx->key->key_alg == DST_ALG_RSAMD5) {
166                 isc_md5_t *md5ctx = dctx->opaque;
167                 isc_md5_final(md5ctx, digest);
168                 type = NID_md5;
169                 digestlen = ISC_MD5_DIGESTLENGTH;
170         } else {
171                 isc_sha1_t *sha1ctx = dctx->opaque;
172                 isc_sha1_final(sha1ctx, digest);
173                 type = NID_sha1;
174                 digestlen = ISC_SHA1_DIGESTLENGTH;
175         }
176
177         status = RSA_sign(type, digest, digestlen, r.base, &siglen, rsa);
178         if (status == 0) {
179                 err = ERR_peek_error_line(&file, &line);
180                 if (err != 0U) {
181                         message = ERR_error_string(err, NULL);
182                         fprintf(stderr, "%s:%s:%d\n", message,
183                                 file ? file : "", line);
184                 }
185                 return (dst__openssl_toresult(DST_R_OPENSSLFAILURE));
186         }
187
188         isc_buffer_add(sig, siglen);
189
190         return (ISC_R_SUCCESS);
191 }
192
193 static isc_result_t
194 opensslrsa_verify(dst_context_t *dctx, const isc_region_t *sig) {
195         dst_key_t *key = dctx->key;
196         RSA *rsa = key->opaque;
197         /* note: ISC_SHA1_DIGESTLENGTH > ISC_MD5_DIGESTLENGTH */
198         unsigned char digest[ISC_SHA1_DIGESTLENGTH];
199         int status = 0;
200         int type;
201         unsigned int digestlen;
202
203         REQUIRE(dctx->key->key_alg == DST_ALG_RSAMD5 ||
204                 dctx->key->key_alg == DST_ALG_RSASHA1);
205
206         if (dctx->key->key_alg == DST_ALG_RSAMD5) {
207                 isc_md5_t *md5ctx = dctx->opaque;
208                 isc_md5_final(md5ctx, digest);
209                 type = NID_md5;
210                 digestlen = ISC_MD5_DIGESTLENGTH;
211         } else {
212                 isc_sha1_t *sha1ctx = dctx->opaque;
213                 isc_sha1_final(sha1ctx, digest);
214                 type = NID_sha1;
215                 digestlen = ISC_SHA1_DIGESTLENGTH;
216         }
217
218         if (sig->length < (unsigned int) RSA_size(rsa))
219                 return (DST_R_VERIFYFAILURE);
220
221         status = RSA_verify(type, digest, digestlen, sig->base,
222                             RSA_size(rsa), rsa);
223         if (status == 0)
224                 return (dst__openssl_toresult(DST_R_VERIFYFAILURE));
225
226         return (ISC_R_SUCCESS);
227 }
228
229 static isc_boolean_t
230 opensslrsa_compare(const dst_key_t *key1, const dst_key_t *key2) {
231         int status;
232         RSA *rsa1, *rsa2;
233
234         rsa1 = (RSA *) key1->opaque;
235         rsa2 = (RSA *) key2->opaque;
236
237         if (rsa1 == NULL && rsa2 == NULL)
238                 return (ISC_TRUE);
239         else if (rsa1 == NULL || rsa2 == NULL)
240                 return (ISC_FALSE);
241
242         status = BN_cmp(rsa1->n, rsa2->n) ||
243                  BN_cmp(rsa1->e, rsa2->e);
244
245         if (status != 0)
246                 return (ISC_FALSE);
247
248         if (rsa1->d != NULL || rsa2->d != NULL) {
249                 if (rsa1->d == NULL || rsa2->d == NULL)
250                         return (ISC_FALSE);
251                 status = BN_cmp(rsa1->d, rsa2->d) ||
252                          BN_cmp(rsa1->p, rsa2->p) ||
253                          BN_cmp(rsa1->q, rsa2->q);
254
255                 if (status != 0)
256                         return (ISC_FALSE);
257         }
258         return (ISC_TRUE);
259 }
260
261 static isc_result_t
262 opensslrsa_generate(dst_key_t *key, int exp) {
263         RSA *rsa;
264         unsigned long e;
265
266         if (exp == 0)
267                 e = RSA_3;
268         else
269                 e = RSA_F4;
270         rsa = RSA_generate_key(key->key_size, e, NULL, NULL);
271         if (rsa == NULL)
272                 return (dst__openssl_toresult(DST_R_OPENSSLFAILURE));
273         SET_FLAGS(rsa);
274         key->opaque = rsa;
275
276         return (ISC_R_SUCCESS);
277 }
278
279 static isc_boolean_t
280 opensslrsa_isprivate(const dst_key_t *key) {
281         RSA *rsa = (RSA *) key->opaque;
282         return (ISC_TF(rsa != NULL && rsa->d != NULL));
283 }
284
285 static void
286 opensslrsa_destroy(dst_key_t *key) {
287         RSA *rsa = key->opaque;
288         RSA_free(rsa);
289         key->opaque = NULL;
290 }
291
292
293 static isc_result_t
294 opensslrsa_todns(const dst_key_t *key, isc_buffer_t *data) {
295         RSA *rsa;
296         isc_region_t r;
297         unsigned int e_bytes;
298         unsigned int mod_bytes;
299
300         REQUIRE(key->opaque != NULL);
301
302         rsa = (RSA *) key->opaque;
303
304         isc_buffer_availableregion(data, &r);
305
306         e_bytes = BN_num_bytes(rsa->e);
307         mod_bytes = BN_num_bytes(rsa->n);
308
309         if (e_bytes < 256) {    /* key exponent is <= 2040 bits */
310                 if (r.length < 1)
311                         return (ISC_R_NOSPACE);
312                 isc_buffer_putuint8(data, (isc_uint8_t) e_bytes);
313         } else {
314                 if (r.length < 3)
315                         return (ISC_R_NOSPACE);
316                 isc_buffer_putuint8(data, 0);
317                 isc_buffer_putuint16(data, (isc_uint16_t) e_bytes);
318         }
319
320         if (r.length < e_bytes + mod_bytes)
321                 return (ISC_R_NOSPACE);
322         isc_buffer_availableregion(data, &r);
323
324         BN_bn2bin(rsa->e, r.base);
325         r.base += e_bytes;
326         BN_bn2bin(rsa->n, r.base);
327
328         isc_buffer_add(data, e_bytes + mod_bytes);
329
330         return (ISC_R_SUCCESS);
331 }
332
333 static isc_result_t
334 opensslrsa_fromdns(dst_key_t *key, isc_buffer_t *data) {
335         RSA *rsa;
336         isc_region_t r;
337         unsigned int e_bytes;
338
339         isc_buffer_remainingregion(data, &r);
340         if (r.length == 0)
341                 return (ISC_R_SUCCESS);
342
343         rsa = RSA_new();
344         if (rsa == NULL)
345                 return (ISC_R_NOMEMORY);
346         SET_FLAGS(rsa);
347
348         if (r.length < 1) {
349                 RSA_free(rsa);
350                 return (DST_R_INVALIDPUBLICKEY);
351         }
352         e_bytes = *r.base++;
353         r.length--;
354
355         if (e_bytes == 0) {
356                 if (r.length < 2) {
357                         RSA_free(rsa);
358                         return (DST_R_INVALIDPUBLICKEY);
359                 }
360                 e_bytes = ((*r.base++) << 8);
361                 e_bytes += *r.base++;
362                 r.length -= 2;
363         }
364
365         if (r.length < e_bytes) {
366                 RSA_free(rsa);
367                 return (DST_R_INVALIDPUBLICKEY);
368         }
369         rsa->e = BN_bin2bn(r.base, e_bytes, NULL);
370         r.base += e_bytes;
371         r.length -= e_bytes;
372
373         rsa->n = BN_bin2bn(r.base, r.length, NULL);
374
375         key->key_size = BN_num_bits(rsa->n);
376
377         isc_buffer_forward(data, r.length);
378
379         key->opaque = (void *) rsa;
380
381         return (ISC_R_SUCCESS);
382 }
383
384
385 static isc_result_t
386 opensslrsa_tofile(const dst_key_t *key, const char *directory) {
387         int i;
388         RSA *rsa;
389         dst_private_t priv;
390         unsigned char *bufs[8];
391         isc_result_t result;
392
393         if (key->opaque == NULL)
394                 return (DST_R_NULLKEY);
395
396         rsa = (RSA *) key->opaque;
397
398         for (i = 0; i < 8; i++) {
399                 bufs[i] = isc_mem_get(key->mctx, BN_num_bytes(rsa->n));
400                 if (bufs[i] == NULL) {
401                         result = ISC_R_NOMEMORY;
402                         goto fail;
403                 }
404         }
405
406         i = 0;
407
408         priv.elements[i].tag = TAG_RSA_MODULUS;
409         priv.elements[i].length = BN_num_bytes(rsa->n);
410         BN_bn2bin(rsa->n, bufs[i]);
411         priv.elements[i].data = bufs[i];
412         i++;
413
414         priv.elements[i].tag = TAG_RSA_PUBLICEXPONENT;
415         priv.elements[i].length = BN_num_bytes(rsa->e);
416         BN_bn2bin(rsa->e, bufs[i]);
417         priv.elements[i].data = bufs[i];
418         i++;
419
420         priv.elements[i].tag = TAG_RSA_PRIVATEEXPONENT;
421         priv.elements[i].length = BN_num_bytes(rsa->d);
422         BN_bn2bin(rsa->d, bufs[i]);
423         priv.elements[i].data = bufs[i];
424         i++;
425
426         priv.elements[i].tag = TAG_RSA_PRIME1;
427         priv.elements[i].length = BN_num_bytes(rsa->p);
428         BN_bn2bin(rsa->p, bufs[i]);
429         priv.elements[i].data = bufs[i];
430         i++;
431
432         priv.elements[i].tag = TAG_RSA_PRIME2;
433         priv.elements[i].length = BN_num_bytes(rsa->q);
434         BN_bn2bin(rsa->q, bufs[i]);
435         priv.elements[i].data = bufs[i];
436         i++;
437
438         priv.elements[i].tag = TAG_RSA_EXPONENT1;
439         priv.elements[i].length = BN_num_bytes(rsa->dmp1);
440         BN_bn2bin(rsa->dmp1, bufs[i]);
441         priv.elements[i].data = bufs[i];
442         i++;
443
444         priv.elements[i].tag = TAG_RSA_EXPONENT2;
445         priv.elements[i].length = BN_num_bytes(rsa->dmq1);
446         BN_bn2bin(rsa->dmq1, bufs[i]);
447         priv.elements[i].data = bufs[i];
448         i++;
449
450         priv.elements[i].tag = TAG_RSA_COEFFICIENT;
451         priv.elements[i].length = BN_num_bytes(rsa->iqmp);
452         BN_bn2bin(rsa->iqmp, bufs[i]);
453         priv.elements[i].data = bufs[i];
454         i++;
455
456         priv.nelements = i;
457         result =  dst__privstruct_writefile(key, &priv, directory);
458  fail:
459         for (i = 0; i < 8; i++) {
460                 if (bufs[i] == NULL)
461                         break;
462                 isc_mem_put(key->mctx, bufs[i], BN_num_bytes(rsa->n));
463         }
464         return (result);
465 }
466
467 static isc_result_t
468 opensslrsa_parse(dst_key_t *key, isc_lex_t *lexer) {
469         dst_private_t priv;
470         isc_result_t ret;
471         int i;
472         RSA *rsa = NULL;
473         isc_mem_t *mctx = key->mctx;
474 #define DST_RET(a) {ret = a; goto err;}
475
476         /* read private key file */
477         ret = dst__privstruct_parse(key, DST_ALG_RSA, lexer, mctx, &priv);
478         if (ret != ISC_R_SUCCESS)
479                 return (ret);
480
481         rsa = RSA_new();
482         if (rsa == NULL)
483                 DST_RET(ISC_R_NOMEMORY);
484         SET_FLAGS(rsa);
485         key->opaque = rsa;
486
487         for (i = 0; i < priv.nelements; i++) {
488                 BIGNUM *bn;
489                 bn = BN_bin2bn(priv.elements[i].data,
490                                priv.elements[i].length, NULL);
491                 if (bn == NULL)
492                         DST_RET(ISC_R_NOMEMORY);
493
494                 switch (priv.elements[i].tag) {
495                         case TAG_RSA_MODULUS:
496                                 rsa->n = bn;
497                                 break;
498                         case TAG_RSA_PUBLICEXPONENT:
499                                 rsa->e = bn;
500                                 break;
501                         case TAG_RSA_PRIVATEEXPONENT:
502                                 rsa->d = bn;
503                                 break;
504                         case TAG_RSA_PRIME1:
505                                 rsa->p = bn;
506                                 break;
507                         case TAG_RSA_PRIME2:
508                                 rsa->q = bn;
509                                 break;
510                         case TAG_RSA_EXPONENT1:
511                                 rsa->dmp1 = bn;
512                                 break;
513                         case TAG_RSA_EXPONENT2:
514                                 rsa->dmq1 = bn;
515                                 break;
516                         case TAG_RSA_COEFFICIENT:
517                                 rsa->iqmp = bn;
518                                 break;
519                 }
520         }
521         dst__privstruct_free(&priv, mctx);
522
523         key->key_size = BN_num_bits(rsa->n);
524
525         return (ISC_R_SUCCESS);
526
527  err:
528         opensslrsa_destroy(key);
529         dst__privstruct_free(&priv, mctx);
530         memset(&priv, 0, sizeof(priv));
531         return (ret);
532 }
533
534 static dst_func_t opensslrsa_functions = {
535         opensslrsa_createctx,
536         opensslrsa_destroyctx,
537         opensslrsa_adddata,
538         opensslrsa_sign,
539         opensslrsa_verify,
540         NULL, /* computesecret */
541         opensslrsa_compare,
542         NULL, /* paramcompare */
543         opensslrsa_generate,
544         opensslrsa_isprivate,
545         opensslrsa_destroy,
546         opensslrsa_todns,
547         opensslrsa_fromdns,
548         opensslrsa_tofile,
549         opensslrsa_parse,
550         NULL, /* cleanup */
551 };
552
553 isc_result_t
554 dst__opensslrsa_init(dst_func_t **funcp) {
555         REQUIRE(funcp != NULL);
556         if (*funcp == NULL)
557                 *funcp = &opensslrsa_functions;
558         return (ISC_R_SUCCESS);
559 }
560
561 #else /* OPENSSL */
562
563 #include <isc/util.h>
564
565 EMPTY_TRANSLATION_UNIT
566
567 #endif /* OPENSSL */