2 * Copyright (C) 2004-2007, 2009 Internet Systems Consortium, Inc. ("ISC")
3 * Copyright (C) 2000-2003 Internet Software Consortium.
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.
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.
19 * Principal Author: Brian Wellington
20 * $Id: opensslrsa_link.c,v 1.16.128.3 2009/01/19 00:01:10 marka Exp $
26 #include <isc/entropy.h>
30 #include <isc/string.h>
33 #include <dst/result.h>
35 #include "dst_internal.h"
36 #include "dst_openssl.h"
37 #include "dst_parse.h"
39 #include <openssl/err.h>
40 #include <openssl/objects.h>
41 #include <openssl/rsa.h>
42 #if OPENSSL_VERSION_NUMBER > 0x00908000L
43 #include <openssl/bn.h>
47 * We don't use configure for windows so enforce the OpenSSL version
48 * here. Unlike with configure we don't support overriding this test.
51 #if !((OPENSSL_VERSION_NUMBER >= 0x009070cfL && \
52 OPENSSL_VERSION_NUMBER < 0x00908000L) || \
53 OPENSSL_VERSION_NUMBER >= 0x0090804fL)
54 #error Please upgrade OpenSSL to 0.9.8d/0.9.7l or greater.
60 * XXXMPA Temporarily disable RSA_BLINDING as it requires
61 * good quality random data that cannot currently be guaranteed.
62 * XXXMPA Find which versions of openssl use pseudo random data
63 * and set RSA_FLAG_BLINDING for those.
67 #if OPENSSL_VERSION_NUMBER < 0x0090601fL
68 #define SET_FLAGS(rsa) \
70 (rsa)->flags &= ~(RSA_FLAG_CACHE_PUBLIC | RSA_FLAG_CACHE_PRIVATE); \
71 (rsa)->flags |= RSA_FLAG_BLINDING; \
74 #define SET_FLAGS(rsa) \
76 (rsa)->flags |= RSA_FLAG_BLINDING; \
81 #if OPENSSL_VERSION_NUMBER < 0x0090601fL
82 #define SET_FLAGS(rsa) \
84 (rsa)->flags &= ~(RSA_FLAG_CACHE_PUBLIC | RSA_FLAG_CACHE_PRIVATE); \
85 (rsa)->flags &= ~RSA_FLAG_BLINDING; \
87 #elif defined(RSA_FLAG_NO_BLINDING)
88 #define SET_FLAGS(rsa) \
90 (rsa)->flags &= ~RSA_FLAG_BLINDING; \
91 (rsa)->flags |= RSA_FLAG_NO_BLINDING; \
94 #define SET_FLAGS(rsa) \
96 (rsa)->flags &= ~RSA_FLAG_BLINDING; \
100 static isc_result_t
opensslrsa_todns(const dst_key_t
*key
, isc_buffer_t
*data
);
103 opensslrsa_createctx(dst_key_t
*key
, dst_context_t
*dctx
) {
105 REQUIRE(dctx
->key
->key_alg
== DST_ALG_RSAMD5
||
106 dctx
->key
->key_alg
== DST_ALG_RSASHA1
);
108 if (dctx
->key
->key_alg
== DST_ALG_RSAMD5
) {
111 md5ctx
= isc_mem_get(dctx
->mctx
, sizeof(isc_md5_t
));
113 return (ISC_R_NOMEMORY
);
114 isc_md5_init(md5ctx
);
115 dctx
->ctxdata
.md5ctx
= md5ctx
;
119 sha1ctx
= isc_mem_get(dctx
->mctx
, sizeof(isc_sha1_t
));
121 return (ISC_R_NOMEMORY
);
122 isc_sha1_init(sha1ctx
);
123 dctx
->ctxdata
.sha1ctx
= sha1ctx
;
126 return (ISC_R_SUCCESS
);
130 opensslrsa_destroyctx(dst_context_t
*dctx
) {
131 REQUIRE(dctx
->key
->key_alg
== DST_ALG_RSAMD5
||
132 dctx
->key
->key_alg
== DST_ALG_RSASHA1
);
134 if (dctx
->key
->key_alg
== DST_ALG_RSAMD5
) {
135 isc_md5_t
*md5ctx
= dctx
->ctxdata
.md5ctx
;
137 if (md5ctx
!= NULL
) {
138 isc_md5_invalidate(md5ctx
);
139 isc_mem_put(dctx
->mctx
, md5ctx
, sizeof(isc_md5_t
));
140 dctx
->ctxdata
.md5ctx
= NULL
;
143 isc_sha1_t
*sha1ctx
= dctx
->ctxdata
.sha1ctx
;
145 if (sha1ctx
!= NULL
) {
146 isc_sha1_invalidate(sha1ctx
);
147 isc_mem_put(dctx
->mctx
, sha1ctx
, sizeof(isc_sha1_t
));
148 dctx
->ctxdata
.sha1ctx
= NULL
;
154 opensslrsa_adddata(dst_context_t
*dctx
, const isc_region_t
*data
) {
155 REQUIRE(dctx
->key
->key_alg
== DST_ALG_RSAMD5
||
156 dctx
->key
->key_alg
== DST_ALG_RSASHA1
);
158 if (dctx
->key
->key_alg
== DST_ALG_RSAMD5
) {
159 isc_md5_t
*md5ctx
= dctx
->ctxdata
.md5ctx
;
160 isc_md5_update(md5ctx
, data
->base
, data
->length
);
162 isc_sha1_t
*sha1ctx
= dctx
->ctxdata
.sha1ctx
;
163 isc_sha1_update(sha1ctx
, data
->base
, data
->length
);
165 return (ISC_R_SUCCESS
);
169 opensslrsa_sign(dst_context_t
*dctx
, isc_buffer_t
*sig
) {
170 dst_key_t
*key
= dctx
->key
;
171 RSA
*rsa
= key
->keydata
.rsa
;
173 /* note: ISC_SHA1_DIGESTLENGTH > ISC_MD5_DIGESTLENGTH */
174 unsigned char digest
[ISC_SHA1_DIGESTLENGTH
];
175 unsigned int siglen
= 0;
178 unsigned int digestlen
;
184 REQUIRE(dctx
->key
->key_alg
== DST_ALG_RSAMD5
||
185 dctx
->key
->key_alg
== DST_ALG_RSASHA1
);
187 isc_buffer_availableregion(sig
, &r
);
189 if (r
.length
< (unsigned int) RSA_size(rsa
))
190 return (ISC_R_NOSPACE
);
192 if (dctx
->key
->key_alg
== DST_ALG_RSAMD5
) {
193 isc_md5_t
*md5ctx
= dctx
->ctxdata
.md5ctx
;
194 isc_md5_final(md5ctx
, digest
);
196 digestlen
= ISC_MD5_DIGESTLENGTH
;
198 isc_sha1_t
*sha1ctx
= dctx
->ctxdata
.sha1ctx
;
199 isc_sha1_final(sha1ctx
, digest
);
201 digestlen
= ISC_SHA1_DIGESTLENGTH
;
204 status
= RSA_sign(type
, digest
, digestlen
, r
.base
, &siglen
, rsa
);
206 err
= ERR_peek_error_line(&file
, &line
);
208 message
= ERR_error_string(err
, NULL
);
209 fprintf(stderr
, "%s:%s:%d\n", message
,
210 file
? file
: "", line
);
212 return (dst__openssl_toresult(DST_R_OPENSSLFAILURE
));
215 isc_buffer_add(sig
, siglen
);
217 return (ISC_R_SUCCESS
);
221 opensslrsa_verify(dst_context_t
*dctx
, const isc_region_t
*sig
) {
222 dst_key_t
*key
= dctx
->key
;
223 RSA
*rsa
= key
->keydata
.rsa
;
224 /* note: ISC_SHA1_DIGESTLENGTH > ISC_MD5_DIGESTLENGTH */
225 unsigned char digest
[ISC_SHA1_DIGESTLENGTH
];
228 unsigned int digestlen
;
230 REQUIRE(dctx
->key
->key_alg
== DST_ALG_RSAMD5
||
231 dctx
->key
->key_alg
== DST_ALG_RSASHA1
);
233 if (dctx
->key
->key_alg
== DST_ALG_RSAMD5
) {
234 isc_md5_t
*md5ctx
= dctx
->ctxdata
.md5ctx
;
235 isc_md5_final(md5ctx
, digest
);
237 digestlen
= ISC_MD5_DIGESTLENGTH
;
239 isc_sha1_t
*sha1ctx
= dctx
->ctxdata
.sha1ctx
;
240 isc_sha1_final(sha1ctx
, digest
);
242 digestlen
= ISC_SHA1_DIGESTLENGTH
;
245 if (sig
->length
< (unsigned int) RSA_size(rsa
))
246 return (DST_R_VERIFYFAILURE
);
248 status
= RSA_verify(type
, digest
, digestlen
, sig
->base
,
251 return (dst__openssl_toresult(DST_R_VERIFYFAILURE
));
253 return (ISC_R_SUCCESS
);
257 opensslrsa_compare(const dst_key_t
*key1
, const dst_key_t
*key2
) {
261 rsa1
= key1
->keydata
.rsa
;
262 rsa2
= key2
->keydata
.rsa
;
264 if (rsa1
== NULL
&& rsa2
== NULL
)
266 else if (rsa1
== NULL
|| rsa2
== NULL
)
269 status
= BN_cmp(rsa1
->n
, rsa2
->n
) ||
270 BN_cmp(rsa1
->e
, rsa2
->e
);
275 if (rsa1
->d
!= NULL
|| rsa2
->d
!= NULL
) {
276 if (rsa1
->d
== NULL
|| rsa2
->d
== NULL
)
278 status
= BN_cmp(rsa1
->d
, rsa2
->d
) ||
279 BN_cmp(rsa1
->p
, rsa2
->p
) ||
280 BN_cmp(rsa1
->q
, rsa2
->q
);
289 opensslrsa_generate(dst_key_t
*key
, int exp
) {
290 #if OPENSSL_VERSION_NUMBER > 0x00908000L
292 RSA
*rsa
= RSA_new();
293 BIGNUM
*e
= BN_new();
295 if (rsa
== NULL
|| e
== NULL
)
308 BN_GENCB_set_old(&cb
, NULL
, NULL
);
310 if (RSA_generate_key_ex(rsa
, key
->key_size
, e
, &cb
)) {
313 key
->keydata
.rsa
= rsa
;
314 return (ISC_R_SUCCESS
);
322 return (dst__openssl_toresult(DST_R_OPENSSLFAILURE
));
331 rsa
= RSA_generate_key(key
->key_size
, e
, NULL
, NULL
);
333 return (dst__openssl_toresult(DST_R_OPENSSLFAILURE
));
335 key
->keydata
.rsa
= rsa
;
337 return (ISC_R_SUCCESS
);
342 opensslrsa_isprivate(const dst_key_t
*key
) {
343 RSA
*rsa
= (RSA
*) key
->keydata
.rsa
;
344 return (ISC_TF(rsa
!= NULL
&& rsa
->d
!= NULL
));
348 opensslrsa_destroy(dst_key_t
*key
) {
349 RSA
*rsa
= key
->keydata
.rsa
;
351 key
->keydata
.rsa
= NULL
;
356 opensslrsa_todns(const dst_key_t
*key
, isc_buffer_t
*data
) {
359 unsigned int e_bytes
;
360 unsigned int mod_bytes
;
362 REQUIRE(key
->keydata
.rsa
!= NULL
);
364 rsa
= key
->keydata
.rsa
;
366 isc_buffer_availableregion(data
, &r
);
368 e_bytes
= BN_num_bytes(rsa
->e
);
369 mod_bytes
= BN_num_bytes(rsa
->n
);
371 if (e_bytes
< 256) { /*%< key exponent is <= 2040 bits */
373 return (ISC_R_NOSPACE
);
374 isc_buffer_putuint8(data
, (isc_uint8_t
) e_bytes
);
377 return (ISC_R_NOSPACE
);
378 isc_buffer_putuint8(data
, 0);
379 isc_buffer_putuint16(data
, (isc_uint16_t
) e_bytes
);
382 if (r
.length
< e_bytes
+ mod_bytes
)
383 return (ISC_R_NOSPACE
);
384 isc_buffer_availableregion(data
, &r
);
386 BN_bn2bin(rsa
->e
, r
.base
);
388 BN_bn2bin(rsa
->n
, r
.base
);
390 isc_buffer_add(data
, e_bytes
+ mod_bytes
);
392 return (ISC_R_SUCCESS
);
396 opensslrsa_fromdns(dst_key_t
*key
, isc_buffer_t
*data
) {
399 unsigned int e_bytes
;
401 isc_buffer_remainingregion(data
, &r
);
403 return (ISC_R_SUCCESS
);
407 return (dst__openssl_toresult(ISC_R_NOMEMORY
));
412 return (DST_R_INVALIDPUBLICKEY
);
420 return (DST_R_INVALIDPUBLICKEY
);
422 e_bytes
= ((*r
.base
++) << 8);
423 e_bytes
+= *r
.base
++;
427 if (r
.length
< e_bytes
) {
429 return (DST_R_INVALIDPUBLICKEY
);
431 rsa
->e
= BN_bin2bn(r
.base
, e_bytes
, NULL
);
435 rsa
->n
= BN_bin2bn(r
.base
, r
.length
, NULL
);
437 key
->key_size
= BN_num_bits(rsa
->n
);
439 isc_buffer_forward(data
, r
.length
);
441 key
->keydata
.rsa
= rsa
;
443 return (ISC_R_SUCCESS
);
448 opensslrsa_tofile(const dst_key_t
*key
, const char *directory
) {
452 unsigned char *bufs
[8];
455 if (key
->keydata
.rsa
== NULL
)
456 return (DST_R_NULLKEY
);
458 rsa
= key
->keydata
.rsa
;
460 for (i
= 0; i
< 8; i
++) {
461 bufs
[i
] = isc_mem_get(key
->mctx
, BN_num_bytes(rsa
->n
));
462 if (bufs
[i
] == NULL
) {
463 result
= ISC_R_NOMEMORY
;
470 priv
.elements
[i
].tag
= TAG_RSA_MODULUS
;
471 priv
.elements
[i
].length
= BN_num_bytes(rsa
->n
);
472 BN_bn2bin(rsa
->n
, bufs
[i
]);
473 priv
.elements
[i
].data
= bufs
[i
];
476 priv
.elements
[i
].tag
= TAG_RSA_PUBLICEXPONENT
;
477 priv
.elements
[i
].length
= BN_num_bytes(rsa
->e
);
478 BN_bn2bin(rsa
->e
, bufs
[i
]);
479 priv
.elements
[i
].data
= bufs
[i
];
482 priv
.elements
[i
].tag
= TAG_RSA_PRIVATEEXPONENT
;
483 priv
.elements
[i
].length
= BN_num_bytes(rsa
->d
);
484 BN_bn2bin(rsa
->d
, bufs
[i
]);
485 priv
.elements
[i
].data
= bufs
[i
];
488 priv
.elements
[i
].tag
= TAG_RSA_PRIME1
;
489 priv
.elements
[i
].length
= BN_num_bytes(rsa
->p
);
490 BN_bn2bin(rsa
->p
, bufs
[i
]);
491 priv
.elements
[i
].data
= bufs
[i
];
494 priv
.elements
[i
].tag
= TAG_RSA_PRIME2
;
495 priv
.elements
[i
].length
= BN_num_bytes(rsa
->q
);
496 BN_bn2bin(rsa
->q
, bufs
[i
]);
497 priv
.elements
[i
].data
= bufs
[i
];
500 priv
.elements
[i
].tag
= TAG_RSA_EXPONENT1
;
501 priv
.elements
[i
].length
= BN_num_bytes(rsa
->dmp1
);
502 BN_bn2bin(rsa
->dmp1
, bufs
[i
]);
503 priv
.elements
[i
].data
= bufs
[i
];
506 priv
.elements
[i
].tag
= TAG_RSA_EXPONENT2
;
507 priv
.elements
[i
].length
= BN_num_bytes(rsa
->dmq1
);
508 BN_bn2bin(rsa
->dmq1
, bufs
[i
]);
509 priv
.elements
[i
].data
= bufs
[i
];
512 priv
.elements
[i
].tag
= TAG_RSA_COEFFICIENT
;
513 priv
.elements
[i
].length
= BN_num_bytes(rsa
->iqmp
);
514 BN_bn2bin(rsa
->iqmp
, bufs
[i
]);
515 priv
.elements
[i
].data
= bufs
[i
];
519 result
= dst__privstruct_writefile(key
, &priv
, directory
);
521 for (i
= 0; i
< 8; i
++) {
524 isc_mem_put(key
->mctx
, bufs
[i
], BN_num_bytes(rsa
->n
));
530 opensslrsa_parse(dst_key_t
*key
, isc_lex_t
*lexer
) {
535 isc_mem_t
*mctx
= key
->mctx
;
536 #define DST_RET(a) {ret = a; goto err;}
538 /* read private key file */
539 ret
= dst__privstruct_parse(key
, DST_ALG_RSA
, lexer
, mctx
, &priv
);
540 if (ret
!= ISC_R_SUCCESS
)
545 DST_RET(ISC_R_NOMEMORY
);
547 key
->keydata
.rsa
= rsa
;
549 for (i
= 0; i
< priv
.nelements
; i
++) {
551 bn
= BN_bin2bn(priv
.elements
[i
].data
,
552 priv
.elements
[i
].length
, NULL
);
554 DST_RET(ISC_R_NOMEMORY
);
556 switch (priv
.elements
[i
].tag
) {
557 case TAG_RSA_MODULUS
:
560 case TAG_RSA_PUBLICEXPONENT
:
563 case TAG_RSA_PRIVATEEXPONENT
:
572 case TAG_RSA_EXPONENT1
:
575 case TAG_RSA_EXPONENT2
:
578 case TAG_RSA_COEFFICIENT
:
583 dst__privstruct_free(&priv
, mctx
);
585 key
->key_size
= BN_num_bits(rsa
->n
);
587 return (ISC_R_SUCCESS
);
590 opensslrsa_destroy(key
);
591 dst__privstruct_free(&priv
, mctx
);
592 memset(&priv
, 0, sizeof(priv
));
596 static dst_func_t opensslrsa_functions
= {
597 opensslrsa_createctx
,
598 opensslrsa_destroyctx
,
602 NULL
, /*%< computesecret */
604 NULL
, /*%< paramcompare */
606 opensslrsa_isprivate
,
612 NULL
, /*%< cleanup */
616 dst__opensslrsa_init(dst_func_t
**funcp
) {
617 REQUIRE(funcp
!= NULL
);
619 *funcp
= &opensslrsa_functions
;
620 return (ISC_R_SUCCESS
);
625 #include <isc/util.h>
627 EMPTY_TRANSLATION_UNIT