2 * Copyright (C) 2004 Internet Systems Consortium, Inc. ("ISC")
3 * Copyright (C) 2000-2003 Internet Software Consortium.
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.
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.1.4.1 2004/12/09 04:07:18 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>
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.
51 #if OPENSSL_VERSION_NUMBER < 0x0090601fL
52 #define SET_FLAGS(rsa) \
54 (rsa)->flags &= ~(RSA_FLAG_CACHE_PUBLIC | RSA_FLAG_CACHE_PRIVATE); \
55 (rsa)->flags |= RSA_FLAG_BLINDING; \
58 #define SET_FLAGS(rsa) \
60 (rsa)->flags |= RSA_FLAG_BLINDING; \
65 #if OPENSSL_VERSION_NUMBER < 0x0090601fL
66 #define SET_FLAGS(rsa) \
68 (rsa)->flags &= ~(RSA_FLAG_CACHE_PUBLIC | RSA_FLAG_CACHE_PRIVATE); \
69 (rsa)->flags &= ~RSA_FLAG_BLINDING; \
72 #define SET_FLAGS(rsa) \
74 (rsa)->flags &= ~RSA_FLAG_BLINDING; \
78 static isc_result_t opensslrsa_todns(const dst_key_t *key, isc_buffer_t *data);
81 opensslrsa_createctx(dst_key_t *key, dst_context_t *dctx) {
83 REQUIRE(dctx->key->key_alg == DST_ALG_RSAMD5 ||
84 dctx->key->key_alg == DST_ALG_RSASHA1);
86 if (dctx->key->key_alg == DST_ALG_RSAMD5) {
89 md5ctx = isc_mem_get(dctx->mctx, sizeof(isc_md5_t));
91 dctx->opaque = md5ctx;
95 sha1ctx = isc_mem_get(dctx->mctx, sizeof(isc_sha1_t));
96 isc_sha1_init(sha1ctx);
97 dctx->opaque = sha1ctx;
100 return (ISC_R_SUCCESS);
104 opensslrsa_destroyctx(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) {
109 isc_md5_t *md5ctx = dctx->opaque;
111 if (md5ctx != NULL) {
112 isc_md5_invalidate(md5ctx);
113 isc_mem_put(dctx->mctx, md5ctx, sizeof(isc_md5_t));
116 isc_sha1_t *sha1ctx = dctx->opaque;
118 if (sha1ctx != NULL) {
119 isc_sha1_invalidate(sha1ctx);
120 isc_mem_put(dctx->mctx, sha1ctx, sizeof(isc_sha1_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);
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);
135 isc_sha1_t *sha1ctx = dctx->opaque;
136 isc_sha1_update(sha1ctx, data->base, data->length);
138 return (ISC_R_SUCCESS);
142 opensslrsa_sign(dst_context_t *dctx, isc_buffer_t *sig) {
143 dst_key_t *key = dctx->key;
144 RSA *rsa = key->opaque;
146 /* note: ISC_SHA1_DIGESTLENGTH > ISC_MD5_DIGESTLENGTH */
147 unsigned char digest[ISC_SHA1_DIGESTLENGTH];
148 unsigned int siglen = 0;
151 unsigned int digestlen;
157 REQUIRE(dctx->key->key_alg == DST_ALG_RSAMD5 ||
158 dctx->key->key_alg == DST_ALG_RSASHA1);
160 isc_buffer_availableregion(sig, &r);
162 if (r.length < (unsigned int) RSA_size(rsa))
163 return (ISC_R_NOSPACE);
165 if (dctx->key->key_alg == DST_ALG_RSAMD5) {
166 isc_md5_t *md5ctx = dctx->opaque;
167 isc_md5_final(md5ctx, digest);
169 digestlen = ISC_MD5_DIGESTLENGTH;
171 isc_sha1_t *sha1ctx = dctx->opaque;
172 isc_sha1_final(sha1ctx, digest);
174 digestlen = ISC_SHA1_DIGESTLENGTH;
177 status = RSA_sign(type, digest, digestlen, r.base, &siglen, rsa);
179 err = ERR_peek_error_line(&file, &line);
181 message = ERR_error_string(err, NULL);
182 fprintf(stderr, "%s:%s:%d\n", message,
183 file ? file : "", line);
185 return (dst__openssl_toresult(DST_R_OPENSSLFAILURE));
188 isc_buffer_add(sig, siglen);
190 return (ISC_R_SUCCESS);
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];
201 unsigned int digestlen;
203 REQUIRE(dctx->key->key_alg == DST_ALG_RSAMD5 ||
204 dctx->key->key_alg == DST_ALG_RSASHA1);
206 if (dctx->key->key_alg == DST_ALG_RSAMD5) {
207 isc_md5_t *md5ctx = dctx->opaque;
208 isc_md5_final(md5ctx, digest);
210 digestlen = ISC_MD5_DIGESTLENGTH;
212 isc_sha1_t *sha1ctx = dctx->opaque;
213 isc_sha1_final(sha1ctx, digest);
215 digestlen = ISC_SHA1_DIGESTLENGTH;
218 if (sig->length < (unsigned int) RSA_size(rsa))
219 return (DST_R_VERIFYFAILURE);
221 status = RSA_verify(type, digest, digestlen, sig->base,
224 return (dst__openssl_toresult(DST_R_VERIFYFAILURE));
226 return (ISC_R_SUCCESS);
230 opensslrsa_compare(const dst_key_t *key1, const dst_key_t *key2) {
234 rsa1 = (RSA *) key1->opaque;
235 rsa2 = (RSA *) key2->opaque;
237 if (rsa1 == NULL && rsa2 == NULL)
239 else if (rsa1 == NULL || rsa2 == NULL)
242 status = BN_cmp(rsa1->n, rsa2->n) ||
243 BN_cmp(rsa1->e, rsa2->e);
248 if (rsa1->d != NULL || rsa2->d != NULL) {
249 if (rsa1->d == NULL || rsa2->d == NULL)
251 status = BN_cmp(rsa1->d, rsa2->d) ||
252 BN_cmp(rsa1->p, rsa2->p) ||
253 BN_cmp(rsa1->q, rsa2->q);
262 opensslrsa_generate(dst_key_t *key, int exp) {
270 rsa = RSA_generate_key(key->key_size, e, NULL, NULL);
272 return (dst__openssl_toresult(DST_R_OPENSSLFAILURE));
276 return (ISC_R_SUCCESS);
280 opensslrsa_isprivate(const dst_key_t *key) {
281 RSA *rsa = (RSA *) key->opaque;
282 return (ISC_TF(rsa != NULL && rsa->d != NULL));
286 opensslrsa_destroy(dst_key_t *key) {
287 RSA *rsa = key->opaque;
294 opensslrsa_todns(const dst_key_t *key, isc_buffer_t *data) {
297 unsigned int e_bytes;
298 unsigned int mod_bytes;
300 REQUIRE(key->opaque != NULL);
302 rsa = (RSA *) key->opaque;
304 isc_buffer_availableregion(data, &r);
306 e_bytes = BN_num_bytes(rsa->e);
307 mod_bytes = BN_num_bytes(rsa->n);
309 if (e_bytes < 256) { /* key exponent is <= 2040 bits */
311 return (ISC_R_NOSPACE);
312 isc_buffer_putuint8(data, (isc_uint8_t) e_bytes);
315 return (ISC_R_NOSPACE);
316 isc_buffer_putuint8(data, 0);
317 isc_buffer_putuint16(data, (isc_uint16_t) e_bytes);
320 if (r.length < e_bytes + mod_bytes)
321 return (ISC_R_NOSPACE);
322 isc_buffer_availableregion(data, &r);
324 BN_bn2bin(rsa->e, r.base);
326 BN_bn2bin(rsa->n, r.base);
328 isc_buffer_add(data, e_bytes + mod_bytes);
330 return (ISC_R_SUCCESS);
334 opensslrsa_fromdns(dst_key_t *key, isc_buffer_t *data) {
337 unsigned int e_bytes;
339 isc_buffer_remainingregion(data, &r);
341 return (ISC_R_SUCCESS);
345 return (ISC_R_NOMEMORY);
350 return (DST_R_INVALIDPUBLICKEY);
358 return (DST_R_INVALIDPUBLICKEY);
360 e_bytes = ((*r.base++) << 8);
361 e_bytes += *r.base++;
365 if (r.length < e_bytes) {
367 return (DST_R_INVALIDPUBLICKEY);
369 rsa->e = BN_bin2bn(r.base, e_bytes, NULL);
373 rsa->n = BN_bin2bn(r.base, r.length, NULL);
375 key->key_size = BN_num_bits(rsa->n);
377 isc_buffer_forward(data, r.length);
379 key->opaque = (void *) rsa;
381 return (ISC_R_SUCCESS);
386 opensslrsa_tofile(const dst_key_t *key, const char *directory) {
390 unsigned char *bufs[8];
393 if (key->opaque == NULL)
394 return (DST_R_NULLKEY);
396 rsa = (RSA *) key->opaque;
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;
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];
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];
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];
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];
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];
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];
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];
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];
457 result = dst__privstruct_writefile(key, &priv, directory);
459 for (i = 0; i < 8; i++) {
462 isc_mem_put(key->mctx, bufs[i], BN_num_bytes(rsa->n));
468 opensslrsa_parse(dst_key_t *key, isc_lex_t *lexer) {
473 isc_mem_t *mctx = key->mctx;
474 #define DST_RET(a) {ret = a; goto err;}
476 /* read private key file */
477 ret = dst__privstruct_parse(key, DST_ALG_RSA, lexer, mctx, &priv);
478 if (ret != ISC_R_SUCCESS)
483 DST_RET(ISC_R_NOMEMORY);
487 for (i = 0; i < priv.nelements; i++) {
489 bn = BN_bin2bn(priv.elements[i].data,
490 priv.elements[i].length, NULL);
492 DST_RET(ISC_R_NOMEMORY);
494 switch (priv.elements[i].tag) {
495 case TAG_RSA_MODULUS:
498 case TAG_RSA_PUBLICEXPONENT:
501 case TAG_RSA_PRIVATEEXPONENT:
510 case TAG_RSA_EXPONENT1:
513 case TAG_RSA_EXPONENT2:
516 case TAG_RSA_COEFFICIENT:
521 dst__privstruct_free(&priv, mctx);
523 key->key_size = BN_num_bits(rsa->n);
525 return (ISC_R_SUCCESS);
528 opensslrsa_destroy(key);
529 dst__privstruct_free(&priv, mctx);
530 memset(&priv, 0, sizeof(priv));
534 static dst_func_t opensslrsa_functions = {
535 opensslrsa_createctx,
536 opensslrsa_destroyctx,
540 NULL, /* computesecret */
542 NULL, /* paramcompare */
544 opensslrsa_isprivate,
554 dst__opensslrsa_init(dst_func_t **funcp) {
555 REQUIRE(funcp != NULL);
557 *funcp = &opensslrsa_functions;
558 return (ISC_R_SUCCESS);
563 #include <isc/util.h>
565 EMPTY_TRANSLATION_UNIT