]> CyberLeo.Net >> Repos - FreeBSD/releng/8.0.git/blob - contrib/bind9/lib/dns/opensslrsa_link.c
Adjust to reflect 8.0-RELEASE.
[FreeBSD/releng/8.0.git] / contrib / bind9 / lib / dns / opensslrsa_link.c
1 /*
2  * Copyright (C) 2004-2009  Internet Systems Consortium, Inc. ("ISC")
3  * Copyright (C) 2000-2003  Internet Software Consortium.
4  *
5  * Permission to use, copy, modify, and/or 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.20.50.3 2009/01/18 23:25:16 marka Exp $
21  */
22 #ifdef OPENSSL
23 #ifndef USE_EVP
24 #define USE_EVP 1
25 #endif
26 #if USE_EVP
27 #define USE_EVP_RSA 1
28 #endif
29
30 #include <config.h>
31
32 #include <isc/entropy.h>
33 #include <isc/md5.h>
34 #include <isc/sha1.h>
35 #include <isc/mem.h>
36 #include <isc/string.h>
37 #include <isc/util.h>
38
39 #include <dst/result.h>
40
41 #include "dst_internal.h"
42 #include "dst_openssl.h"
43 #include "dst_parse.h"
44
45 #include <openssl/err.h>
46 #include <openssl/objects.h>
47 #include <openssl/rsa.h>
48 #if OPENSSL_VERSION_NUMBER > 0x00908000L
49 #include <openssl/bn.h>
50 #endif
51 #include <openssl/engine.h>
52
53 /*
54  * We don't use configure for windows so enforce the OpenSSL version
55  * here.  Unlike with configure we don't support overriding this test.
56  */
57 #ifdef WIN32
58 #if !((OPENSSL_VERSION_NUMBER >= 0x009070cfL && \
59        OPENSSL_VERSION_NUMBER < 0x00908000L) || \
60       OPENSSL_VERSION_NUMBER >= 0x0090804fL)
61 #error Please upgrade OpenSSL to 0.9.8d/0.9.7l or greater.
62 #endif
63 #endif
64
65
66         /*
67          * XXXMPA  Temporarily disable RSA_BLINDING as it requires
68          * good quality random data that cannot currently be guaranteed.
69          * XXXMPA  Find which versions of openssl use pseudo random data
70          * and set RSA_FLAG_BLINDING for those.
71          */
72
73 #if 0
74 #if OPENSSL_VERSION_NUMBER < 0x0090601fL
75 #define SET_FLAGS(rsa) \
76         do { \
77         (rsa)->flags &= ~(RSA_FLAG_CACHE_PUBLIC | RSA_FLAG_CACHE_PRIVATE); \
78         (rsa)->flags |= RSA_FLAG_BLINDING; \
79         } while (0)
80 #else
81 #define SET_FLAGS(rsa) \
82         do { \
83                 (rsa)->flags |= RSA_FLAG_BLINDING; \
84         } while (0)
85 #endif
86 #endif
87
88 #if OPENSSL_VERSION_NUMBER < 0x0090601fL
89 #define SET_FLAGS(rsa) \
90         do { \
91         (rsa)->flags &= ~(RSA_FLAG_CACHE_PUBLIC | RSA_FLAG_CACHE_PRIVATE); \
92         (rsa)->flags &= ~RSA_FLAG_BLINDING; \
93         } while (0)
94 #elif defined(RSA_FLAG_NO_BLINDING)
95 #define SET_FLAGS(rsa) \
96         do { \
97                 (rsa)->flags &= ~RSA_FLAG_BLINDING; \
98                 (rsa)->flags |= RSA_FLAG_NO_BLINDING; \
99         } while (0)
100 #else
101 #define SET_FLAGS(rsa) \
102         do { \
103                 (rsa)->flags &= ~RSA_FLAG_BLINDING; \
104         } while (0)
105 #endif
106
107 #define DST_RET(a) {ret = a; goto err;}
108
109 static isc_result_t opensslrsa_todns(const dst_key_t *key, isc_buffer_t *data);
110
111 static isc_result_t
112 opensslrsa_createctx(dst_key_t *key, dst_context_t *dctx) {
113 #if USE_EVP
114         EVP_MD_CTX *evp_md_ctx;
115         const EVP_MD *type;
116 #endif
117
118         UNUSED(key);
119         REQUIRE(dctx->key->key_alg == DST_ALG_RSAMD5 ||
120                 dctx->key->key_alg == DST_ALG_RSASHA1 ||
121                 dctx->key->key_alg == DST_ALG_NSEC3RSASHA1);
122
123 #if USE_EVP
124         evp_md_ctx = EVP_MD_CTX_create();
125         if (evp_md_ctx == NULL)
126                 return (ISC_R_NOMEMORY);
127
128         if (dctx->key->key_alg == DST_ALG_RSAMD5)
129                 type = EVP_md5();       /* MD5 + RSA */
130         else
131                 type = EVP_sha1();      /* SHA1 + RSA */
132
133         if (!EVP_DigestInit_ex(evp_md_ctx, type, NULL)) {
134                 EVP_MD_CTX_destroy(evp_md_ctx);
135                 return (ISC_R_FAILURE);
136         }
137         dctx->ctxdata.evp_md_ctx = evp_md_ctx;
138 #else
139         if (dctx->key->key_alg == DST_ALG_RSAMD5) {
140                 isc_md5_t *md5ctx;
141
142                 md5ctx = isc_mem_get(dctx->mctx, sizeof(isc_md5_t));
143                 if (md5ctx == NULL)
144                         return (ISC_R_NOMEMORY);
145                 isc_md5_init(md5ctx);
146                 dctx->ctxdata.md5ctx = md5ctx;
147         } else {
148                 isc_sha1_t *sha1ctx;
149
150                 sha1ctx = isc_mem_get(dctx->mctx, sizeof(isc_sha1_t));
151                 if (sha1ctx == NULL)
152                         return (ISC_R_NOMEMORY);
153                 isc_sha1_init(sha1ctx);
154                 dctx->ctxdata.sha1ctx = sha1ctx;
155         }
156 #endif
157
158         return (ISC_R_SUCCESS);
159 }
160
161 static void
162 opensslrsa_destroyctx(dst_context_t *dctx) {
163 #if USE_EVP
164         EVP_MD_CTX *evp_md_ctx = dctx->ctxdata.evp_md_ctx;
165 #endif
166
167         REQUIRE(dctx->key->key_alg == DST_ALG_RSAMD5 ||
168                 dctx->key->key_alg == DST_ALG_RSASHA1 ||
169                 dctx->key->key_alg == DST_ALG_NSEC3RSASHA1);
170
171 #if USE_EVP
172         if (evp_md_ctx != NULL) {
173                 EVP_MD_CTX_destroy(evp_md_ctx);
174                 dctx->ctxdata.evp_md_ctx = NULL;
175         }
176 #else
177         if (dctx->key->key_alg == DST_ALG_RSAMD5) {
178                 isc_md5_t *md5ctx = dctx->ctxdata.md5ctx;
179
180                 if (md5ctx != NULL) {
181                         isc_md5_invalidate(md5ctx);
182                         isc_mem_put(dctx->mctx, md5ctx, sizeof(isc_md5_t));
183                         dctx->ctxdata.md5ctx = NULL;
184                 }
185         } else {
186                 isc_sha1_t *sha1ctx = dctx->ctxdata.sha1ctx;
187
188                 if (sha1ctx != NULL) {
189                         isc_sha1_invalidate(sha1ctx);
190                         isc_mem_put(dctx->mctx, sha1ctx, sizeof(isc_sha1_t));
191                         dctx->ctxdata.sha1ctx = NULL;
192                 }
193         }
194 #endif
195 }
196
197 static isc_result_t
198 opensslrsa_adddata(dst_context_t *dctx, const isc_region_t *data) {
199 #if USE_EVP
200         EVP_MD_CTX *evp_md_ctx = dctx->ctxdata.evp_md_ctx;
201 #endif
202
203         REQUIRE(dctx->key->key_alg == DST_ALG_RSAMD5 ||
204                 dctx->key->key_alg == DST_ALG_RSASHA1 ||
205                 dctx->key->key_alg == DST_ALG_NSEC3RSASHA1);
206
207 #if USE_EVP
208         if (!EVP_DigestUpdate(evp_md_ctx, data->base, data->length)) {
209                 return (ISC_R_FAILURE);
210         }
211 #else
212         if (dctx->key->key_alg == DST_ALG_RSAMD5) {
213                 isc_md5_t *md5ctx = dctx->ctxdata.md5ctx;
214                 isc_md5_update(md5ctx, data->base, data->length);
215         } else {
216                 isc_sha1_t *sha1ctx = dctx->ctxdata.sha1ctx;
217                 isc_sha1_update(sha1ctx, data->base, data->length);
218         }
219 #endif
220         return (ISC_R_SUCCESS);
221 }
222
223 static isc_result_t
224 opensslrsa_sign(dst_context_t *dctx, isc_buffer_t *sig) {
225         dst_key_t *key = dctx->key;
226         isc_region_t r;
227         unsigned int siglen = 0;
228 #if USE_EVP
229         EVP_MD_CTX *evp_md_ctx = dctx->ctxdata.evp_md_ctx;
230         EVP_PKEY *pkey = key->keydata.pkey;
231 #else
232         RSA *rsa = key->keydata.rsa;
233         /* note: ISC_SHA1_DIGESTLENGTH > ISC_MD5_DIGESTLENGTH */
234         unsigned char digest[ISC_SHA1_DIGESTLENGTH];
235         int status;
236         int type;
237         unsigned int digestlen;
238         char *message;
239         unsigned long err;
240         const char* file;
241         int line;
242 #endif
243
244         REQUIRE(dctx->key->key_alg == DST_ALG_RSAMD5 ||
245                 dctx->key->key_alg == DST_ALG_RSASHA1 ||
246                 dctx->key->key_alg == DST_ALG_NSEC3RSASHA1);
247
248         isc_buffer_availableregion(sig, &r);
249
250 #if USE_EVP
251         if (r.length < (unsigned int) EVP_PKEY_size(pkey))
252                 return (ISC_R_NOSPACE);
253
254         if (!EVP_SignFinal(evp_md_ctx, r.base, &siglen, pkey)) {
255                 return (ISC_R_FAILURE);
256         }
257 #else
258         if (r.length < (unsigned int) RSA_size(rsa))
259                 return (ISC_R_NOSPACE);
260
261         if (dctx->key->key_alg == DST_ALG_RSAMD5) {
262                 isc_md5_t *md5ctx = dctx->ctxdata.md5ctx;
263                 isc_md5_final(md5ctx, digest);
264                 type = NID_md5;
265                 digestlen = ISC_MD5_DIGESTLENGTH;
266         } else {
267                 isc_sha1_t *sha1ctx = dctx->ctxdata.sha1ctx;
268                 isc_sha1_final(sha1ctx, digest);
269                 type = NID_sha1;
270                 digestlen = ISC_SHA1_DIGESTLENGTH;
271         }
272
273         status = RSA_sign(type, digest, digestlen, r.base, &siglen, rsa);
274         if (status == 0) {
275                 err = ERR_peek_error_line(&file, &line);
276                 if (err != 0U) {
277                         message = ERR_error_string(err, NULL);
278                 }
279                 return (dst__openssl_toresult(DST_R_OPENSSLFAILURE));
280         }
281 #endif
282
283         isc_buffer_add(sig, siglen);
284
285         return (ISC_R_SUCCESS);
286 }
287
288 static isc_result_t
289 opensslrsa_verify(dst_context_t *dctx, const isc_region_t *sig) {
290         dst_key_t *key = dctx->key;
291         int status = 0;
292 #if USE_EVP
293         EVP_MD_CTX *evp_md_ctx = dctx->ctxdata.evp_md_ctx;
294         EVP_PKEY *pkey = key->keydata.pkey;
295 #else
296         /* note: ISC_SHA1_DIGESTLENGTH > ISC_MD5_DIGESTLENGTH */
297         unsigned char digest[ISC_SHA1_DIGESTLENGTH];
298         int type;
299         unsigned int digestlen;
300         RSA *rsa = key->keydata.rsa;
301 #endif
302
303         REQUIRE(dctx->key->key_alg == DST_ALG_RSAMD5 ||
304                 dctx->key->key_alg == DST_ALG_RSASHA1 ||
305                 dctx->key->key_alg == DST_ALG_NSEC3RSASHA1);
306
307 #if USE_EVP
308         status = EVP_VerifyFinal(evp_md_ctx, sig->base, sig->length, pkey);
309 #else
310         if (dctx->key->key_alg == DST_ALG_RSAMD5) {
311                 isc_md5_t *md5ctx = dctx->ctxdata.md5ctx;
312                 isc_md5_final(md5ctx, digest);
313                 type = NID_md5;
314                 digestlen = ISC_MD5_DIGESTLENGTH;
315         } else {
316                 isc_sha1_t *sha1ctx = dctx->ctxdata.sha1ctx;
317                 isc_sha1_final(sha1ctx, digest);
318                 type = NID_sha1;
319                 digestlen = ISC_SHA1_DIGESTLENGTH;
320         }
321
322         if (sig->length < (unsigned int) RSA_size(rsa))
323                 return (DST_R_VERIFYFAILURE);
324
325         status = RSA_verify(type, digest, digestlen, sig->base,
326                             RSA_size(rsa), rsa);
327 #endif
328         if (status != 1)
329                 return (dst__openssl_toresult(DST_R_VERIFYFAILURE));
330
331         return (ISC_R_SUCCESS);
332 }
333
334 static isc_boolean_t
335 opensslrsa_compare(const dst_key_t *key1, const dst_key_t *key2) {
336         int status;
337         RSA *rsa1 = NULL, *rsa2 = NULL;
338 #if USE_EVP
339         EVP_PKEY *pkey1, *pkey2;
340 #endif
341
342 #if USE_EVP
343         pkey1 = key1->keydata.pkey;
344         pkey2 = key2->keydata.pkey;
345         /*
346          * The pkey reference will keep these around after
347          * the RSA_free() call.
348          */
349         if (pkey1 != NULL) {
350                 rsa1 = EVP_PKEY_get1_RSA(pkey1);
351                 RSA_free(rsa1);
352         }
353         if (pkey2 != NULL) {
354                 rsa2 = EVP_PKEY_get1_RSA(pkey2);
355                 RSA_free(rsa2);
356         }
357 #else
358         rsa1 = key1->keydata.rsa;
359         rsa2 = key2->keydata.rsa;
360 #endif
361
362         if (rsa1 == NULL && rsa2 == NULL)
363                 return (ISC_TRUE);
364         else if (rsa1 == NULL || rsa2 == NULL)
365                 return (ISC_FALSE);
366
367         status = BN_cmp(rsa1->n, rsa2->n) ||
368                  BN_cmp(rsa1->e, rsa2->e);
369
370         if (status != 0)
371                 return (ISC_FALSE);
372
373 #if USE_EVP
374         if ((rsa1->flags & RSA_FLAG_EXT_PKEY) != 0 ||
375             (rsa2->flags & RSA_FLAG_EXT_PKEY) != 0) {
376                 if ((rsa1->flags & RSA_FLAG_EXT_PKEY) == 0 ||
377                     (rsa2->flags & RSA_FLAG_EXT_PKEY) == 0)
378                         return (ISC_FALSE);
379                 /*
380                  * Can't compare private parameters, BTW does it make sense?
381                  */
382                 return (ISC_TRUE);
383         }
384 #endif
385
386         if (rsa1->d != NULL || rsa2->d != NULL) {
387                 if (rsa1->d == NULL || rsa2->d == NULL)
388                         return (ISC_FALSE);
389                 status = BN_cmp(rsa1->d, rsa2->d) ||
390                          BN_cmp(rsa1->p, rsa2->p) ||
391                          BN_cmp(rsa1->q, rsa2->q);
392
393                 if (status != 0)
394                         return (ISC_FALSE);
395         }
396         return (ISC_TRUE);
397 }
398
399 static isc_result_t
400 opensslrsa_generate(dst_key_t *key, int exp) {
401 #if OPENSSL_VERSION_NUMBER > 0x00908000L
402         BN_GENCB cb;
403         RSA *rsa = RSA_new();
404         BIGNUM *e = BN_new();
405 #if USE_EVP
406         EVP_PKEY *pkey = EVP_PKEY_new();
407 #endif
408
409         if (rsa == NULL || e == NULL)
410                 goto err;
411 #if USE_EVP
412         if (pkey == NULL)
413                 goto err;
414         if (!EVP_PKEY_set1_RSA(pkey, rsa))
415                 goto err;
416 #endif
417
418         if (exp == 0) {
419                 /* RSA_F4 0x10001 */
420                 BN_set_bit(e, 0);
421                 BN_set_bit(e, 16);
422         } else {
423                 /* F5 0x100000001 */
424                 BN_set_bit(e, 0);
425                 BN_set_bit(e, 32);
426         }
427
428         BN_GENCB_set_old(&cb, NULL, NULL);
429
430         if (RSA_generate_key_ex(rsa, key->key_size, e, &cb)) {
431                 BN_free(e);
432                 SET_FLAGS(rsa);
433 #if USE_EVP
434                 key->keydata.pkey = pkey;
435
436                 RSA_free(rsa);
437 #else
438                 key->keydata.rsa = rsa;
439 #endif
440                 return (ISC_R_SUCCESS);
441         }
442
443 err:
444 #if USE_EVP
445         if (pkey != NULL)
446                 EVP_PKEY_free(pkey);
447 #endif
448         if (e != NULL)
449                 BN_free(e);
450         if (rsa != NULL)
451                 RSA_free(rsa);
452         return (dst__openssl_toresult(DST_R_OPENSSLFAILURE));
453 #else
454         RSA *rsa;
455         unsigned long e;
456 #if USE_EVP
457         EVP_PKEY *pkey = EVP_PKEY_new();
458
459         if (pkey == NULL)
460                 return (ISC_R_NOMEMORY);
461 #endif
462
463         if (exp == 0)
464                e = RSA_F4;
465         else
466                e = 0x40000003;
467         rsa = RSA_generate_key(key->key_size, e, NULL, NULL);
468         if (rsa == NULL) {
469 #if USE_EVP
470                 EVP_PKEY_free(pkey);
471 #endif
472                 return (dst__openssl_toresult(DST_R_OPENSSLFAILURE));
473         }
474         SET_FLAGS(rsa);
475 #if USE_EVP
476         if (!EVP_PKEY_set1_RSA(pkey, rsa)) {
477                 EVP_PKEY_free(pkey);
478                 RSA_free(rsa);
479                 return (dst__openssl_toresult(DST_R_OPENSSLFAILURE));
480         }
481         key->keydata.pkey = pkey;
482         RSA_free(rsa);
483 #else
484         key->keydata.rsa = rsa;
485 #endif
486
487         return (ISC_R_SUCCESS);
488 #endif
489 }
490
491 static isc_boolean_t
492 opensslrsa_isprivate(const dst_key_t *key) {
493 #if USE_EVP
494         RSA *rsa = EVP_PKEY_get1_RSA(key->keydata.pkey);
495         INSIST(rsa != NULL);
496         RSA_free(rsa);
497         /* key->keydata.pkey still has a reference so rsa is still valid. */
498 #else
499         RSA *rsa = key->keydata.rsa;
500 #endif
501         if (rsa != NULL && (rsa->flags & RSA_FLAG_EXT_PKEY) != 0)
502                 return (ISC_TRUE);
503         return (ISC_TF(rsa != NULL && rsa->d != NULL));
504 }
505
506 static void
507 opensslrsa_destroy(dst_key_t *key) {
508 #if USE_EVP
509         EVP_PKEY *pkey = key->keydata.pkey;
510         EVP_PKEY_free(pkey);
511         key->keydata.pkey = NULL;
512 #else
513         RSA *rsa = key->keydata.rsa;
514         RSA_free(rsa);
515         key->keydata.rsa = NULL;
516 #endif
517 }
518
519
520 static isc_result_t
521 opensslrsa_todns(const dst_key_t *key, isc_buffer_t *data) {
522         isc_region_t r;
523         unsigned int e_bytes;
524         unsigned int mod_bytes;
525         isc_result_t ret;
526         RSA *rsa;
527 #if USE_EVP
528         EVP_PKEY *pkey;
529 #endif
530
531 #if USE_EVP
532         REQUIRE(key->keydata.pkey != NULL);
533 #else
534         REQUIRE(key->keydata.rsa != NULL);
535 #endif
536
537 #if USE_EVP
538         pkey = key->keydata.pkey;
539         rsa = EVP_PKEY_get1_RSA(pkey);
540         if (rsa == NULL)
541                 return (dst__openssl_toresult(DST_R_OPENSSLFAILURE));
542 #else
543         rsa = key->keydata.rsa;
544 #endif
545
546         isc_buffer_availableregion(data, &r);
547
548         e_bytes = BN_num_bytes(rsa->e);
549         mod_bytes = BN_num_bytes(rsa->n);
550
551         if (e_bytes < 256) {    /*%< key exponent is <= 2040 bits */
552                 if (r.length < 1)
553                         DST_RET(ISC_R_NOSPACE);
554                 isc_buffer_putuint8(data, (isc_uint8_t) e_bytes);
555         } else {
556                 if (r.length < 3)
557                         DST_RET(ISC_R_NOSPACE);
558                 isc_buffer_putuint8(data, 0);
559                 isc_buffer_putuint16(data, (isc_uint16_t) e_bytes);
560         }
561
562         if (r.length < e_bytes + mod_bytes)
563                 return (ISC_R_NOSPACE);
564         isc_buffer_availableregion(data, &r);
565
566         BN_bn2bin(rsa->e, r.base);
567         r.base += e_bytes;
568         BN_bn2bin(rsa->n, r.base);
569
570         isc_buffer_add(data, e_bytes + mod_bytes);
571
572         ret = ISC_R_SUCCESS;
573  err:
574 #if USE_EVP
575         if (rsa != NULL)
576                 RSA_free(rsa);
577 #endif
578         return (ret);
579 }
580
581 static isc_result_t
582 opensslrsa_fromdns(dst_key_t *key, isc_buffer_t *data) {
583         RSA *rsa;
584         isc_region_t r;
585         unsigned int e_bytes;
586 #if USE_EVP
587         EVP_PKEY *pkey;
588 #endif
589
590         isc_buffer_remainingregion(data, &r);
591         if (r.length == 0)
592                 return (ISC_R_SUCCESS);
593
594         rsa = RSA_new();
595         if (rsa == NULL)
596                 return (dst__openssl_toresult(ISC_R_NOMEMORY));
597         SET_FLAGS(rsa);
598
599         if (r.length < 1) {
600                 RSA_free(rsa);
601                 return (DST_R_INVALIDPUBLICKEY);
602         }
603         e_bytes = *r.base++;
604         r.length--;
605
606         if (e_bytes == 0) {
607                 if (r.length < 2) {
608                         RSA_free(rsa);
609                         return (DST_R_INVALIDPUBLICKEY);
610                 }
611                 e_bytes = ((*r.base++) << 8);
612                 e_bytes += *r.base++;
613                 r.length -= 2;
614         }
615
616         if (r.length < e_bytes) {
617                 RSA_free(rsa);
618                 return (DST_R_INVALIDPUBLICKEY);
619         }
620         rsa->e = BN_bin2bn(r.base, e_bytes, NULL);
621         r.base += e_bytes;
622         r.length -= e_bytes;
623
624         rsa->n = BN_bin2bn(r.base, r.length, NULL);
625
626         key->key_size = BN_num_bits(rsa->n);
627
628         isc_buffer_forward(data, r.length);
629
630 #if USE_EVP
631         pkey = EVP_PKEY_new();
632         if (pkey == NULL) {
633                 RSA_free(rsa);
634                 return (ISC_R_NOMEMORY);
635         }
636         if (!EVP_PKEY_set1_RSA(pkey, rsa)) {
637                 EVP_PKEY_free(pkey);
638                 RSA_free(rsa);
639                 return (dst__openssl_toresult(DST_R_OPENSSLFAILURE));
640         }
641         key->keydata.pkey = pkey;
642         RSA_free(rsa);
643 #else
644         key->keydata.rsa = rsa;
645 #endif
646
647         return (ISC_R_SUCCESS);
648 }
649
650 static isc_result_t
651 opensslrsa_tofile(const dst_key_t *key, const char *directory) {
652         int i;
653         RSA *rsa;
654         dst_private_t priv;
655         unsigned char *bufs[8];
656         isc_result_t result;
657
658 #if USE_EVP
659         if (key->keydata.pkey == NULL)
660                 return (DST_R_NULLKEY);
661         rsa = EVP_PKEY_get1_RSA(key->keydata.pkey);
662         if (rsa == NULL)
663                 return (dst__openssl_toresult(DST_R_OPENSSLFAILURE));
664 #else
665         if (key->keydata.rsa == NULL)
666                 return (DST_R_NULLKEY);
667         rsa = key->keydata.rsa;
668 #endif
669
670         for (i = 0; i < 8; i++) {
671                 bufs[i] = isc_mem_get(key->mctx, BN_num_bytes(rsa->n));
672                 if (bufs[i] == NULL) {
673                         result = ISC_R_NOMEMORY;
674                         goto fail;
675                 }
676         }
677
678         i = 0;
679
680         priv.elements[i].tag = TAG_RSA_MODULUS;
681         priv.elements[i].length = BN_num_bytes(rsa->n);
682         BN_bn2bin(rsa->n, bufs[i]);
683         priv.elements[i].data = bufs[i];
684         i++;
685
686         priv.elements[i].tag = TAG_RSA_PUBLICEXPONENT;
687         priv.elements[i].length = BN_num_bytes(rsa->e);
688         BN_bn2bin(rsa->e, bufs[i]);
689         priv.elements[i].data = bufs[i];
690         i++;
691
692         if (rsa->d != NULL) {
693                 priv.elements[i].tag = TAG_RSA_PRIVATEEXPONENT;
694                 priv.elements[i].length = BN_num_bytes(rsa->d);
695                 BN_bn2bin(rsa->d, bufs[i]);
696                 priv.elements[i].data = bufs[i];
697                 i++;
698         }
699
700         if (rsa->p != NULL) {
701                 priv.elements[i].tag = TAG_RSA_PRIME1;
702                 priv.elements[i].length = BN_num_bytes(rsa->p);
703                 BN_bn2bin(rsa->p, bufs[i]);
704                 priv.elements[i].data = bufs[i];
705                 i++;
706         }
707
708         if (rsa->q != NULL) {
709                 priv.elements[i].tag = TAG_RSA_PRIME2;
710                 priv.elements[i].length = BN_num_bytes(rsa->q);
711                 BN_bn2bin(rsa->q, bufs[i]);
712                 priv.elements[i].data = bufs[i];
713                 i++;
714         }
715
716         if (rsa->dmp1 != NULL) {
717                 priv.elements[i].tag = TAG_RSA_EXPONENT1;
718                 priv.elements[i].length = BN_num_bytes(rsa->dmp1);
719                 BN_bn2bin(rsa->dmp1, bufs[i]);
720                 priv.elements[i].data = bufs[i];
721                 i++;
722         }
723
724         if (rsa->dmq1 != NULL) {
725                 priv.elements[i].tag = TAG_RSA_EXPONENT2;
726                 priv.elements[i].length = BN_num_bytes(rsa->dmq1);
727                 BN_bn2bin(rsa->dmq1, bufs[i]);
728                 priv.elements[i].data = bufs[i];
729                 i++;
730         }
731
732         if (rsa->iqmp != NULL) {
733                 priv.elements[i].tag = TAG_RSA_COEFFICIENT;
734                 priv.elements[i].length = BN_num_bytes(rsa->iqmp);
735                 BN_bn2bin(rsa->iqmp, bufs[i]);
736                 priv.elements[i].data = bufs[i];
737                 i++;
738         }
739
740         if (key->engine != NULL) {
741                 priv.elements[i].tag = TAG_RSA_ENGINE;
742                 priv.elements[i].length = strlen(key->engine) + 1;
743                 priv.elements[i].data = (unsigned char *)key->engine;
744                 i++;
745         }
746
747         if (key->label != NULL) {
748                 priv.elements[i].tag = TAG_RSA_LABEL;
749                 priv.elements[i].length = strlen(key->label) + 1;
750                 priv.elements[i].data = (unsigned char *)key->label;
751                 i++;
752         }
753
754         priv.nelements = i;
755         result =  dst__privstruct_writefile(key, &priv, directory);
756  fail:
757 #if USE_EVP
758         RSA_free(rsa);
759 #endif
760         for (i = 0; i < 8; i++) {
761                 if (bufs[i] == NULL)
762                         break;
763                 isc_mem_put(key->mctx, bufs[i], BN_num_bytes(rsa->n));
764         }
765         return (result);
766 }
767
768 static isc_result_t
769 opensslrsa_parse(dst_key_t *key, isc_lex_t *lexer) {
770         dst_private_t priv;
771         isc_result_t ret;
772         int i;
773         RSA *rsa = NULL;
774         ENGINE *e = NULL;
775         isc_mem_t *mctx = key->mctx;
776         const char *name = NULL, *label = NULL;
777         EVP_PKEY *pkey = NULL;
778
779         /* read private key file */
780         ret = dst__privstruct_parse(key, DST_ALG_RSA, lexer, mctx, &priv);
781         if (ret != ISC_R_SUCCESS)
782                 return (ret);
783
784         for (i = 0; i < priv.nelements; i++) {
785                 switch (priv.elements[i].tag) {
786                 case TAG_RSA_ENGINE:
787                         name = (char *)priv.elements[i].data;
788                         break;
789                 case TAG_RSA_LABEL:
790                         label = (char *)priv.elements[i].data;
791                         break;
792                 default:
793                         break;
794                 }
795         }
796         /*
797          * Is this key is stored in a HSM?
798          * See if we can fetch it.
799          */
800         if (name != NULL || label != NULL) {
801                 INSIST(name != NULL);
802                 INSIST(label != NULL);
803                 e = dst__openssl_getengine(name);
804                 if (e == NULL)
805                         DST_RET(DST_R_NOENGINE);
806                 pkey = ENGINE_load_private_key(e, label, NULL, NULL);
807                 if (pkey == NULL) {
808                         ERR_print_errors_fp(stderr);
809                         DST_RET(ISC_R_FAILURE);
810                 }
811                 key->engine = isc_mem_strdup(key->mctx, name);
812                 if (key->engine == NULL)
813                         DST_RET(ISC_R_NOMEMORY);
814                 key->label = isc_mem_strdup(key->mctx, label);
815                 if (key->label == NULL)
816                         DST_RET(ISC_R_NOMEMORY);
817                 key->key_size = EVP_PKEY_bits(pkey);
818 #if USE_EVP
819                 key->keydata.pkey = pkey;
820 #else
821                 key->keydata.rsa = EVP_PKEY_get1_RSA(pkey);
822                 if (rsa == NULL)
823                         DST_RET(dst__openssl_toresult(DST_R_OPENSSLFAILURE));
824                 EVP_PKEY_free(pkey);
825 #endif
826                 dst__privstruct_free(&priv, mctx);
827                 return (ISC_R_SUCCESS);
828         }
829
830         rsa = RSA_new();
831         if (rsa == NULL)
832                 DST_RET(ISC_R_NOMEMORY);
833         SET_FLAGS(rsa);
834
835 #if USE_EVP
836         pkey = EVP_PKEY_new();
837         if (pkey == NULL)
838                 DST_RET(ISC_R_NOMEMORY);
839         if (!EVP_PKEY_set1_RSA(pkey, rsa)) {
840                 DST_RET(ISC_R_FAILURE);
841         }
842         key->keydata.pkey = pkey;
843 #else
844         key->keydata.rsa = rsa;
845 #endif
846
847         for (i = 0; i < priv.nelements; i++) {
848                 BIGNUM *bn;
849                 switch (priv.elements[i].tag) {
850                 case TAG_RSA_ENGINE:
851                         continue;
852                 case TAG_RSA_LABEL:
853                         continue;
854                 case TAG_RSA_PIN:
855                         continue;
856                 default:
857                         bn = BN_bin2bn(priv.elements[i].data,
858                                        priv.elements[i].length, NULL);
859                         if (bn == NULL)
860                                 DST_RET(ISC_R_NOMEMORY);
861                 }
862
863                 switch (priv.elements[i].tag) {
864                         case TAG_RSA_MODULUS:
865                                 rsa->n = bn;
866                                 break;
867                         case TAG_RSA_PUBLICEXPONENT:
868                                 rsa->e = bn;
869                                 break;
870                         case TAG_RSA_PRIVATEEXPONENT:
871                                 rsa->d = bn;
872                                 break;
873                         case TAG_RSA_PRIME1:
874                                 rsa->p = bn;
875                                 break;
876                         case TAG_RSA_PRIME2:
877                                 rsa->q = bn;
878                                 break;
879                         case TAG_RSA_EXPONENT1:
880                                 rsa->dmp1 = bn;
881                                 break;
882                         case TAG_RSA_EXPONENT2:
883                                 rsa->dmq1 = bn;
884                                 break;
885                         case TAG_RSA_COEFFICIENT:
886                                 rsa->iqmp = bn;
887                                 break;
888                 }
889         }
890         dst__privstruct_free(&priv, mctx);
891
892         key->key_size = BN_num_bits(rsa->n);
893 #if USE_EVP
894         RSA_free(rsa);
895 #endif
896
897         return (ISC_R_SUCCESS);
898
899  err:
900 #if USE_EVP
901         if (pkey != NULL)
902                 EVP_PKEY_free(pkey);
903 #endif
904         if (rsa != NULL)
905                 RSA_free(rsa);
906         opensslrsa_destroy(key);
907         dst__privstruct_free(&priv, mctx);
908         memset(&priv, 0, sizeof(priv));
909         return (ret);
910 }
911
912 static isc_result_t
913 opensslrsa_fromlabel(dst_key_t *key, const char *engine, const char *label,
914                      const char *pin)
915 {
916         ENGINE *e = NULL;
917         isc_result_t ret;
918         EVP_PKEY *pkey = NULL;
919
920         UNUSED(pin);
921
922         e = dst__openssl_getengine(engine);
923         if (e == NULL)
924                 DST_RET(DST_R_NOENGINE);
925         pkey = ENGINE_load_private_key(e, label, NULL, NULL);
926         if (pkey == NULL)
927                 DST_RET(ISC_R_NOMEMORY);
928         key->engine = isc_mem_strdup(key->mctx, label);
929         if (key->engine == NULL)
930                 DST_RET(ISC_R_NOMEMORY);
931         key->label = isc_mem_strdup(key->mctx, label);
932         if (key->label == NULL)
933                 DST_RET(ISC_R_NOMEMORY);
934         key->key_size = EVP_PKEY_bits(pkey);
935 #if USE_EVP
936         key->keydata.pkey = pkey;
937 #else
938         key->keydata.rsa = EVP_PKEY_get1_RSA(pkey);
939         EVP_PKEY_free(pkey);
940         if (key->keydata.rsa == NULL)
941                 return (dst__openssl_toresult(DST_R_OPENSSLFAILURE));
942 #endif
943         return (ISC_R_SUCCESS);
944
945  err:
946         if (pkey != NULL)
947                 EVP_PKEY_free(pkey);
948         return (ret);
949 }
950
951 static dst_func_t opensslrsa_functions = {
952         opensslrsa_createctx,
953         opensslrsa_destroyctx,
954         opensslrsa_adddata,
955         opensslrsa_sign,
956         opensslrsa_verify,
957         NULL, /*%< computesecret */
958         opensslrsa_compare,
959         NULL, /*%< paramcompare */
960         opensslrsa_generate,
961         opensslrsa_isprivate,
962         opensslrsa_destroy,
963         opensslrsa_todns,
964         opensslrsa_fromdns,
965         opensslrsa_tofile,
966         opensslrsa_parse,
967         NULL, /*%< cleanup */
968         opensslrsa_fromlabel,
969 };
970
971 isc_result_t
972 dst__opensslrsa_init(dst_func_t **funcp) {
973         REQUIRE(funcp != NULL);
974         if (*funcp == NULL)
975                 *funcp = &opensslrsa_functions;
976         return (ISC_R_SUCCESS);
977 }
978
979 #else /* OPENSSL */
980
981 #include <isc/util.h>
982
983 EMPTY_TRANSLATION_UNIT
984
985 #endif /* OPENSSL */
986 /*! \file */