[BACK]Return to opensslecdsa_link.c CVS log [TXT][DIR] Up to [cvs.NetBSD.org] / src / external / mpl / bind / dist / lib / dns

Annotation of src/external/mpl/bind/dist/lib/dns/opensslecdsa_link.c, Revision 1.3

1.2       christos    1: /*     $NetBSD: opensslecdsa_link.c,v 1.1.1.12 2018/04/07 21:44:07 christos Exp $      */
1.1       christos    2:
                      3: /*
                      4:  * Copyright (C) Internet Systems Consortium, Inc. ("ISC")
                      5:  *
                      6:  * This Source Code Form is subject to the terms of the Mozilla Public
                      7:  * License, v. 2.0. If a copy of the MPL was not distributed with this
                      8:  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
                      9:  *
                     10:  * See the COPYRIGHT file distributed with this work for additional
                     11:  * information regarding copyright ownership.
                     12:  */
                     13:
1.3     ! christos   14: /*! \file */
        !            15:
1.1       christos   16: #include <config.h>
                     17:
1.3     ! christos   18: #if !USE_PKCS11
1.1       christos   19:
1.3     ! christos   20: #include <stdbool.h>
1.1       christos   21:
                     22: #include <isc/mem.h>
                     23: #include <isc/safe.h>
                     24: #include <isc/string.h>
                     25: #include <isc/util.h>
                     26:
                     27: #include <dns/keyvalues.h>
                     28: #include <dst/result.h>
                     29:
                     30: #include "dst_internal.h"
                     31: #include "dst_openssl.h"
                     32: #include "dst_parse.h"
                     33:
                     34: #include <openssl/err.h>
                     35: #include <openssl/objects.h>
                     36: #include <openssl/ecdsa.h>
                     37: #include <openssl/bn.h>
                     38:
                     39: #ifndef NID_X9_62_prime256v1
                     40: #error "P-256 group is not known (NID_X9_62_prime256v1)"
                     41: #endif
                     42: #ifndef NID_secp384r1
                     43: #error "P-384 group is not known (NID_secp384r1)"
                     44: #endif
                     45:
                     46: #define DST_RET(a) {ret = a; goto err;}
                     47:
1.3     ! christos   48: #if !HAVE_ECDSA_SIG_GET0
1.1       christos   49: /* From OpenSSL 1.1 */
                     50: static void
                     51: ECDSA_SIG_get0(const ECDSA_SIG *sig, const BIGNUM **pr, const BIGNUM **ps) {
                     52:        if (pr != NULL) {
                     53:                *pr = sig->r;
                     54:        }
                     55:        if (ps != NULL) {
                     56:                *ps = sig->s;
                     57:        }
                     58: }
                     59:
                     60: static int
                     61: ECDSA_SIG_set0(ECDSA_SIG *sig, BIGNUM *r, BIGNUM *s) {
                     62:        if (r == NULL || s == NULL) {
                     63:                return 0;
                     64:        }
                     65:
                     66:        BN_clear_free(sig->r);
                     67:        BN_clear_free(sig->s);
                     68:        sig->r = r;
                     69:        sig->s = s;
                     70:
                     71:        return 1;
                     72: }
1.3     ! christos   73: #endif /* !HAVE_ECDSA_SIG_GET0 */
1.1       christos   74:
                     75: static isc_result_t opensslecdsa_todns(const dst_key_t *key,
                     76:                                       isc_buffer_t *data);
                     77:
                     78: static isc_result_t
                     79: opensslecdsa_createctx(dst_key_t *key, dst_context_t *dctx) {
                     80:        EVP_MD_CTX *evp_md_ctx;
                     81:        const EVP_MD *type = NULL;
                     82:
                     83:        UNUSED(key);
                     84:        REQUIRE(dctx->key->key_alg == DST_ALG_ECDSA256 ||
                     85:                dctx->key->key_alg == DST_ALG_ECDSA384);
                     86:
                     87:        evp_md_ctx = EVP_MD_CTX_create();
                     88:        if (evp_md_ctx == NULL)
                     89:                return (ISC_R_NOMEMORY);
                     90:        if (dctx->key->key_alg == DST_ALG_ECDSA256)
                     91:                type = EVP_sha256();
                     92:        else
                     93:                type = EVP_sha384();
                     94:
                     95:        if (!EVP_DigestInit_ex(evp_md_ctx, type, NULL)) {
                     96:                EVP_MD_CTX_destroy(evp_md_ctx);
                     97:                return (dst__openssl_toresult3(dctx->category,
                     98:                                               "EVP_DigestInit_ex",
                     99:                                               ISC_R_FAILURE));
                    100:        }
                    101:
                    102:        dctx->ctxdata.evp_md_ctx = evp_md_ctx;
                    103:
                    104:        return (ISC_R_SUCCESS);
                    105: }
                    106:
                    107: static void
                    108: opensslecdsa_destroyctx(dst_context_t *dctx) {
                    109:        EVP_MD_CTX *evp_md_ctx = dctx->ctxdata.evp_md_ctx;
                    110:
                    111:        REQUIRE(dctx->key->key_alg == DST_ALG_ECDSA256 ||
                    112:                dctx->key->key_alg == DST_ALG_ECDSA384);
                    113:
                    114:        if (evp_md_ctx != NULL) {
                    115:                EVP_MD_CTX_destroy(evp_md_ctx);
                    116:                dctx->ctxdata.evp_md_ctx = NULL;
                    117:        }
                    118: }
                    119:
                    120: static isc_result_t
                    121: opensslecdsa_adddata(dst_context_t *dctx, const isc_region_t *data) {
                    122:        EVP_MD_CTX *evp_md_ctx = dctx->ctxdata.evp_md_ctx;
                    123:
                    124:        REQUIRE(dctx->key->key_alg == DST_ALG_ECDSA256 ||
                    125:                dctx->key->key_alg == DST_ALG_ECDSA384);
                    126:
                    127:        if (!EVP_DigestUpdate(evp_md_ctx, data->base, data->length))
                    128:                return (dst__openssl_toresult3(dctx->category,
                    129:                                               "EVP_DigestUpdate",
                    130:                                               ISC_R_FAILURE));
                    131:
                    132:        return (ISC_R_SUCCESS);
                    133: }
                    134:
                    135: static int
                    136: BN_bn2bin_fixed(const BIGNUM *bn, unsigned char *buf, int size) {
                    137:        int bytes = size - BN_num_bytes(bn);
                    138:
                    139:        while (bytes-- > 0)
                    140:                *buf++ = 0;
                    141:        BN_bn2bin(bn, buf);
                    142:        return (size);
                    143: }
                    144:
                    145: static isc_result_t
                    146: opensslecdsa_sign(dst_context_t *dctx, isc_buffer_t *sig) {
                    147:        isc_result_t ret;
                    148:        dst_key_t *key = dctx->key;
                    149:        isc_region_t region;
                    150:        ECDSA_SIG *ecdsasig;
                    151:        EVP_MD_CTX *evp_md_ctx = dctx->ctxdata.evp_md_ctx;
                    152:        EVP_PKEY *pkey = key->keydata.pkey;
                    153:        EC_KEY *eckey = EVP_PKEY_get1_EC_KEY(pkey);
                    154:        unsigned int dgstlen, siglen;
                    155:        unsigned char digest[EVP_MAX_MD_SIZE];
                    156:        const BIGNUM *r, *s;
                    157:
                    158:        REQUIRE(key->key_alg == DST_ALG_ECDSA256 ||
                    159:                key->key_alg == DST_ALG_ECDSA384);
                    160:
                    161:        if (eckey == NULL)
                    162:                return (ISC_R_FAILURE);
                    163:
                    164:        if (key->key_alg == DST_ALG_ECDSA256)
                    165:                siglen = DNS_SIG_ECDSA256SIZE;
                    166:        else
                    167:                siglen = DNS_SIG_ECDSA384SIZE;
                    168:
                    169:        isc_buffer_availableregion(sig, &region);
                    170:        if (region.length < siglen)
                    171:                DST_RET(ISC_R_NOSPACE);
                    172:
                    173:        if (!EVP_DigestFinal(evp_md_ctx, digest, &dgstlen))
                    174:                DST_RET(dst__openssl_toresult3(dctx->category,
                    175:                                               "EVP_DigestFinal",
                    176:                                               ISC_R_FAILURE));
                    177:
                    178:        ecdsasig = ECDSA_do_sign(digest, dgstlen, eckey);
                    179:        if (ecdsasig == NULL)
                    180:                DST_RET(dst__openssl_toresult3(dctx->category,
                    181:                                               "ECDSA_do_sign",
                    182:                                               DST_R_SIGNFAILURE));
                    183:        ECDSA_SIG_get0(ecdsasig, &r, &s);
                    184:        BN_bn2bin_fixed(r, region.base, siglen / 2);
                    185:        isc_region_consume(&region, siglen / 2);
                    186:        BN_bn2bin_fixed(s, region.base, siglen / 2);
                    187:        isc_region_consume(&region, siglen / 2);
                    188:        ECDSA_SIG_free(ecdsasig);
                    189:        isc_buffer_add(sig, siglen);
                    190:        ret = ISC_R_SUCCESS;
                    191:
                    192:  err:
                    193:        if (eckey != NULL)
                    194:                EC_KEY_free(eckey);
                    195:        return (ret);
                    196: }
                    197:
                    198: static isc_result_t
                    199: opensslecdsa_verify(dst_context_t *dctx, const isc_region_t *sig) {
                    200:        isc_result_t ret;
                    201:        dst_key_t *key = dctx->key;
                    202:        int status;
                    203:        unsigned char *cp = sig->base;
                    204:        ECDSA_SIG *ecdsasig = NULL;
                    205:        EVP_MD_CTX *evp_md_ctx = dctx->ctxdata.evp_md_ctx;
                    206:        EVP_PKEY *pkey = key->keydata.pkey;
                    207:        EC_KEY *eckey = EVP_PKEY_get1_EC_KEY(pkey);
                    208:        unsigned int dgstlen, siglen;
                    209:        unsigned char digest[EVP_MAX_MD_SIZE];
                    210:        BIGNUM *r = NULL, *s = NULL ;
                    211:
                    212:        REQUIRE(key->key_alg == DST_ALG_ECDSA256 ||
                    213:                key->key_alg == DST_ALG_ECDSA384);
                    214:
                    215:        if (eckey == NULL)
                    216:                return (ISC_R_FAILURE);
                    217:
                    218:        if (key->key_alg == DST_ALG_ECDSA256)
                    219:                siglen = DNS_SIG_ECDSA256SIZE;
                    220:        else
                    221:                siglen = DNS_SIG_ECDSA384SIZE;
                    222:
                    223:        if (sig->length != siglen)
                    224:                return (DST_R_VERIFYFAILURE);
                    225:
                    226:        if (!EVP_DigestFinal_ex(evp_md_ctx, digest, &dgstlen))
                    227:                DST_RET (dst__openssl_toresult3(dctx->category,
                    228:                                                "EVP_DigestFinal_ex",
                    229:                                                ISC_R_FAILURE));
                    230:
                    231:        ecdsasig = ECDSA_SIG_new();
                    232:        if (ecdsasig == NULL)
                    233:                DST_RET (ISC_R_NOMEMORY);
                    234:        r = BN_bin2bn(cp, siglen / 2, NULL);
                    235:        cp += siglen / 2;
                    236:        s = BN_bin2bn(cp, siglen / 2, NULL);
                    237:        ECDSA_SIG_set0(ecdsasig, r, s);
                    238:        /* cp += siglen / 2; */
                    239:
                    240:        status = ECDSA_do_verify(digest, dgstlen, ecdsasig, eckey);
                    241:        switch (status) {
                    242:        case 1:
                    243:                ret = ISC_R_SUCCESS;
                    244:                break;
                    245:        case 0:
                    246:                ret = dst__openssl_toresult(DST_R_VERIFYFAILURE);
                    247:                break;
                    248:        default:
                    249:                ret = dst__openssl_toresult3(dctx->category,
                    250:                                             "ECDSA_do_verify",
                    251:                                             DST_R_VERIFYFAILURE);
                    252:                break;
                    253:        }
                    254:
                    255:  err:
                    256:        if (ecdsasig != NULL)
                    257:                ECDSA_SIG_free(ecdsasig);
                    258:        if (eckey != NULL)
                    259:                EC_KEY_free(eckey);
                    260:        return (ret);
                    261: }
                    262:
1.3     ! christos  263: static bool
1.1       christos  264: opensslecdsa_compare(const dst_key_t *key1, const dst_key_t *key2) {
1.3     ! christos  265:        bool ret;
1.1       christos  266:        int status;
                    267:        EVP_PKEY *pkey1 = key1->keydata.pkey;
                    268:        EVP_PKEY *pkey2 = key2->keydata.pkey;
                    269:        EC_KEY *eckey1 = NULL;
                    270:        EC_KEY *eckey2 = NULL;
                    271:        const BIGNUM *priv1, *priv2;
                    272:
                    273:        if (pkey1 == NULL && pkey2 == NULL)
1.3     ! christos  274:                return (true);
1.1       christos  275:        else if (pkey1 == NULL || pkey2 == NULL)
1.3     ! christos  276:                return (false);
1.1       christos  277:
                    278:        eckey1 = EVP_PKEY_get1_EC_KEY(pkey1);
                    279:        eckey2 = EVP_PKEY_get1_EC_KEY(pkey2);
                    280:        if (eckey1 == NULL && eckey2 == NULL) {
1.3     ! christos  281:                DST_RET (true);
1.1       christos  282:        } else if (eckey1 == NULL || eckey2 == NULL)
1.3     ! christos  283:                DST_RET (false);
1.1       christos  284:
                    285:        status = EVP_PKEY_cmp(pkey1, pkey2);
                    286:        if (status != 1)
1.3     ! christos  287:                DST_RET (false);
1.1       christos  288:
                    289:        priv1 = EC_KEY_get0_private_key(eckey1);
                    290:        priv2 = EC_KEY_get0_private_key(eckey2);
                    291:        if (priv1 != NULL || priv2 != NULL) {
                    292:                if (priv1 == NULL || priv2 == NULL)
1.3     ! christos  293:                        DST_RET (false);
1.1       christos  294:                if (BN_cmp(priv1, priv2) != 0)
1.3     ! christos  295:                        DST_RET (false);
1.1       christos  296:        }
1.3     ! christos  297:        ret = true;
1.1       christos  298:
                    299:  err:
                    300:        if (eckey1 != NULL)
                    301:                EC_KEY_free(eckey1);
                    302:        if (eckey2 != NULL)
                    303:                EC_KEY_free(eckey2);
                    304:        return (ret);
                    305: }
                    306:
                    307: static isc_result_t
                    308: opensslecdsa_generate(dst_key_t *key, int unused, void (*callback)(int)) {
                    309:        isc_result_t ret;
                    310:        EVP_PKEY *pkey;
                    311:        EC_KEY *eckey = NULL;
                    312:        int group_nid;
                    313:
                    314:        REQUIRE(key->key_alg == DST_ALG_ECDSA256 ||
                    315:                key->key_alg == DST_ALG_ECDSA384);
                    316:        UNUSED(unused);
                    317:        UNUSED(callback);
                    318:
                    319:        if (key->key_alg == DST_ALG_ECDSA256) {
                    320:                group_nid = NID_X9_62_prime256v1;
                    321:                key->key_size = DNS_KEY_ECDSA256SIZE * 4;
                    322:        } else {
                    323:                group_nid = NID_secp384r1;
                    324:                key->key_size = DNS_KEY_ECDSA384SIZE * 4;
                    325:        }
                    326:
                    327:        eckey = EC_KEY_new_by_curve_name(group_nid);
                    328:        if (eckey == NULL)
                    329:                return (dst__openssl_toresult2("EC_KEY_new_by_curve_name",
                    330:                                               DST_R_OPENSSLFAILURE));
                    331:
                    332:        if (EC_KEY_generate_key(eckey) != 1)
                    333:                DST_RET (dst__openssl_toresult2("EC_KEY_generate_key",
                    334:                                                DST_R_OPENSSLFAILURE));
                    335:
                    336:        pkey = EVP_PKEY_new();
                    337:        if (pkey == NULL)
                    338:                DST_RET (ISC_R_NOMEMORY);
                    339:        if (!EVP_PKEY_set1_EC_KEY(pkey, eckey)) {
                    340:                EVP_PKEY_free(pkey);
                    341:                DST_RET (ISC_R_FAILURE);
                    342:        }
                    343:        key->keydata.pkey = pkey;
                    344:        ret = ISC_R_SUCCESS;
                    345:
                    346:  err:
                    347:        if (eckey != NULL)
                    348:                EC_KEY_free(eckey);
                    349:        return (ret);
                    350: }
                    351:
1.3     ! christos  352: static bool
1.1       christos  353: opensslecdsa_isprivate(const dst_key_t *key) {
1.3     ! christos  354:        bool ret;
1.1       christos  355:        EVP_PKEY *pkey = key->keydata.pkey;
                    356:        EC_KEY *eckey = EVP_PKEY_get1_EC_KEY(pkey);
                    357:
1.3     ! christos  358:        ret = (eckey != NULL && EC_KEY_get0_private_key(eckey) != NULL);
1.1       christos  359:        if (eckey != NULL)
                    360:                EC_KEY_free(eckey);
                    361:        return (ret);
                    362: }
                    363:
                    364: static void
                    365: opensslecdsa_destroy(dst_key_t *key) {
                    366:        EVP_PKEY *pkey = key->keydata.pkey;
                    367:
                    368:        EVP_PKEY_free(pkey);
                    369:        key->keydata.pkey = NULL;
                    370: }
                    371:
                    372: static isc_result_t
                    373: opensslecdsa_todns(const dst_key_t *key, isc_buffer_t *data) {
                    374:        isc_result_t ret;
                    375:        EVP_PKEY *pkey;
                    376:        EC_KEY *eckey = NULL;
                    377:        isc_region_t r;
                    378:        int len;
                    379:        unsigned char *cp;
                    380:        unsigned char buf[DNS_KEY_ECDSA384SIZE + 1];
                    381:
                    382:        REQUIRE(key->keydata.pkey != NULL);
                    383:
                    384:        pkey = key->keydata.pkey;
                    385:        eckey = EVP_PKEY_get1_EC_KEY(pkey);
                    386:        if (eckey == NULL)
                    387:                return (dst__openssl_toresult(ISC_R_FAILURE));
                    388:        len = i2o_ECPublicKey(eckey, NULL);
                    389:        /* skip form */
                    390:        len--;
                    391:
                    392:        isc_buffer_availableregion(data, &r);
                    393:        if (r.length < (unsigned int) len)
                    394:                DST_RET (ISC_R_NOSPACE);
                    395:        cp = buf;
                    396:        if (!i2o_ECPublicKey(eckey, &cp))
                    397:                DST_RET (dst__openssl_toresult(ISC_R_FAILURE));
                    398:        memmove(r.base, buf + 1, len);
                    399:        isc_buffer_add(data, len);
                    400:        ret = ISC_R_SUCCESS;
                    401:
                    402:  err:
                    403:        if (eckey != NULL)
                    404:                EC_KEY_free(eckey);
                    405:        return (ret);
                    406: }
                    407:
                    408: static isc_result_t
                    409: opensslecdsa_fromdns(dst_key_t *key, isc_buffer_t *data) {
                    410:        isc_result_t ret;
                    411:        EVP_PKEY *pkey;
                    412:        EC_KEY *eckey = NULL;
                    413:        isc_region_t r;
                    414:        int group_nid;
                    415:        unsigned int len;
                    416:        const unsigned char *cp;
                    417:        unsigned char buf[DNS_KEY_ECDSA384SIZE + 1];
                    418:
                    419:        REQUIRE(key->key_alg == DST_ALG_ECDSA256 ||
                    420:                key->key_alg == DST_ALG_ECDSA384);
                    421:
                    422:        if (key->key_alg == DST_ALG_ECDSA256) {
                    423:                len = DNS_KEY_ECDSA256SIZE;
                    424:                group_nid = NID_X9_62_prime256v1;
                    425:        } else {
                    426:                len = DNS_KEY_ECDSA384SIZE;
                    427:                group_nid = NID_secp384r1;
                    428:        }
                    429:
                    430:        isc_buffer_remainingregion(data, &r);
                    431:        if (r.length == 0)
                    432:                return (ISC_R_SUCCESS);
                    433:        if (r.length < len)
                    434:                return (DST_R_INVALIDPUBLICKEY);
                    435:
                    436:        eckey = EC_KEY_new_by_curve_name(group_nid);
                    437:        if (eckey == NULL)
                    438:                return (dst__openssl_toresult(DST_R_OPENSSLFAILURE));
                    439:
                    440:        buf[0] = POINT_CONVERSION_UNCOMPRESSED;
                    441:        memmove(buf + 1, r.base, len);
                    442:        cp = buf;
                    443:        if (o2i_ECPublicKey(&eckey,
                    444:                            (const unsigned char **) &cp,
                    445:                            (long) len + 1) == NULL)
                    446:                DST_RET (dst__openssl_toresult(DST_R_INVALIDPUBLICKEY));
                    447:        if (EC_KEY_check_key(eckey) != 1)
                    448:                DST_RET (dst__openssl_toresult(DST_R_INVALIDPUBLICKEY));
                    449:
                    450:        pkey = EVP_PKEY_new();
                    451:        if (pkey == NULL)
                    452:                DST_RET (ISC_R_NOMEMORY);
                    453:        if (!EVP_PKEY_set1_EC_KEY(pkey, eckey)) {
                    454:                EVP_PKEY_free(pkey);
                    455:                DST_RET (dst__openssl_toresult(ISC_R_FAILURE));
                    456:        }
                    457:
                    458:        isc_buffer_forward(data, len);
                    459:        key->keydata.pkey = pkey;
                    460:        key->key_size = len * 4;
                    461:        ret = ISC_R_SUCCESS;
                    462:
                    463:  err:
                    464:        if (eckey != NULL)
                    465:                EC_KEY_free(eckey);
                    466:        return (ret);
                    467: }
                    468:
                    469: static isc_result_t
                    470: opensslecdsa_tofile(const dst_key_t *key, const char *directory) {
                    471:        isc_result_t ret;
                    472:        EVP_PKEY *pkey;
                    473:        EC_KEY *eckey = NULL;
                    474:        const BIGNUM *privkey;
                    475:        dst_private_t priv;
                    476:        unsigned char *buf = NULL;
                    477:
                    478:        if (key->keydata.pkey == NULL)
                    479:                return (DST_R_NULLKEY);
                    480:
                    481:        if (key->external) {
                    482:                priv.nelements = 0;
                    483:                return (dst__privstruct_writefile(key, &priv, directory));
                    484:        }
                    485:
                    486:        pkey = key->keydata.pkey;
                    487:        eckey = EVP_PKEY_get1_EC_KEY(pkey);
                    488:        if (eckey == NULL)
                    489:                return (dst__openssl_toresult(DST_R_OPENSSLFAILURE));
                    490:        privkey = EC_KEY_get0_private_key(eckey);
                    491:        if (privkey == NULL)
                    492:                DST_RET (ISC_R_FAILURE);
                    493:
                    494:        buf = isc_mem_get(key->mctx, BN_num_bytes(privkey));
                    495:        if (buf == NULL)
                    496:                DST_RET (ISC_R_NOMEMORY);
                    497:
                    498:        priv.elements[0].tag = TAG_ECDSA_PRIVATEKEY;
                    499:        priv.elements[0].length = BN_num_bytes(privkey);
                    500:        BN_bn2bin(privkey, buf);
                    501:        priv.elements[0].data = buf;
                    502:        priv.nelements = 1;
                    503:        ret = dst__privstruct_writefile(key, &priv, directory);
                    504:
                    505:  err:
                    506:        if (eckey != NULL)
                    507:                EC_KEY_free(eckey);
                    508:        if (buf != NULL)
                    509:                isc_mem_put(key->mctx, buf, BN_num_bytes(privkey));
                    510:        return (ret);
                    511: }
                    512:
                    513: static isc_result_t
                    514: ecdsa_check(EC_KEY *eckey, dst_key_t *pub)
                    515: {
                    516:        isc_result_t ret = ISC_R_FAILURE;
                    517:        EVP_PKEY *pkey;
                    518:        EC_KEY *pubeckey = NULL;
                    519:        const EC_POINT *pubkey;
                    520:
                    521:        if (pub == NULL)
                    522:                return (ISC_R_SUCCESS);
                    523:        pkey = pub->keydata.pkey;
                    524:        if (pkey == NULL)
                    525:                return (ISC_R_SUCCESS);
                    526:        pubeckey = EVP_PKEY_get1_EC_KEY(pkey);
                    527:        if (pubeckey == NULL)
                    528:                return (ISC_R_SUCCESS);
                    529:        pubkey = EC_KEY_get0_public_key(pubeckey);
                    530:        if (pubkey == NULL)
                    531:                DST_RET (ISC_R_SUCCESS);
                    532:        if (EC_KEY_set_public_key(eckey, pubkey) != 1)
                    533:                DST_RET (ISC_R_SUCCESS);
                    534:        if (EC_KEY_check_key(eckey) == 1)
                    535:                DST_RET (ISC_R_SUCCESS);
                    536:
                    537:  err:
                    538:        if (pubeckey != NULL)
                    539:                EC_KEY_free(pubeckey);
                    540:        return (ret);
                    541: }
                    542:
                    543: static isc_result_t
                    544: opensslecdsa_parse(dst_key_t *key, isc_lex_t *lexer, dst_key_t *pub) {
                    545:        dst_private_t priv;
                    546:        isc_result_t ret;
                    547:        EVP_PKEY *pkey;
                    548:        EC_KEY *eckey = NULL;
                    549:        BIGNUM *privkey = NULL;
                    550:        int group_nid;
                    551:        isc_mem_t *mctx = key->mctx;
                    552:
                    553:        REQUIRE(key->key_alg == DST_ALG_ECDSA256 ||
                    554:                key->key_alg == DST_ALG_ECDSA384);
                    555:
                    556:        /* read private key file */
                    557:        ret = dst__privstruct_parse(key, DST_ALG_ECDSA256, lexer, mctx, &priv);
                    558:        if (ret != ISC_R_SUCCESS)
                    559:                goto err;
                    560:
                    561:        if (key->external) {
                    562:                if (priv.nelements != 0)
                    563:                        DST_RET(DST_R_INVALIDPRIVATEKEY);
                    564:                if (pub == NULL)
                    565:                        DST_RET(DST_R_INVALIDPRIVATEKEY);
                    566:                key->keydata.pkey = pub->keydata.pkey;
                    567:                pub->keydata.pkey = NULL;
                    568:                dst__privstruct_free(&priv, mctx);
                    569:                isc_safe_memwipe(&priv, sizeof(priv));
                    570:                return (ISC_R_SUCCESS);
                    571:        }
                    572:
                    573:        if (key->key_alg == DST_ALG_ECDSA256)
                    574:                group_nid = NID_X9_62_prime256v1;
                    575:        else
                    576:                group_nid = NID_secp384r1;
                    577:
                    578:        eckey = EC_KEY_new_by_curve_name(group_nid);
                    579:        if (eckey == NULL)
                    580:                return (dst__openssl_toresult(DST_R_OPENSSLFAILURE));
                    581:
                    582:        privkey = BN_bin2bn(priv.elements[0].data,
                    583:                            priv.elements[0].length, NULL);
                    584:        if (privkey == NULL)
                    585:                DST_RET(ISC_R_NOMEMORY);
                    586:        if (!EC_KEY_set_private_key(eckey, privkey))
                    587:                DST_RET(ISC_R_NOMEMORY);
                    588:        if (ecdsa_check(eckey, pub) != ISC_R_SUCCESS)
                    589:                DST_RET(DST_R_INVALIDPRIVATEKEY);
                    590:
                    591:        pkey = EVP_PKEY_new();
                    592:        if (pkey == NULL)
                    593:                DST_RET (ISC_R_NOMEMORY);
                    594:        if (!EVP_PKEY_set1_EC_KEY(pkey, eckey)) {
                    595:                EVP_PKEY_free(pkey);
                    596:                DST_RET (dst__openssl_toresult(DST_R_OPENSSLFAILURE));
                    597:        }
                    598:        key->keydata.pkey = pkey;
                    599:        if (key->key_alg == DST_ALG_ECDSA256)
                    600:                key->key_size = DNS_KEY_ECDSA256SIZE * 4;
                    601:        else
                    602:                key->key_size = DNS_KEY_ECDSA384SIZE * 4;
                    603:        ret = ISC_R_SUCCESS;
                    604:
                    605:  err:
                    606:        if (privkey != NULL)
                    607:                BN_clear_free(privkey);
                    608:        if (eckey != NULL)
                    609:                EC_KEY_free(eckey);
                    610:        dst__privstruct_free(&priv, mctx);
                    611:        isc_safe_memwipe(&priv, sizeof(priv));
                    612:        return (ret);
                    613: }
                    614:
                    615: static dst_func_t opensslecdsa_functions = {
                    616:        opensslecdsa_createctx,
                    617:        NULL, /*%< createctx2 */
                    618:        opensslecdsa_destroyctx,
                    619:        opensslecdsa_adddata,
                    620:        opensslecdsa_sign,
                    621:        opensslecdsa_verify,
                    622:        NULL, /*%< verify2 */
                    623:        NULL, /*%< computesecret */
                    624:        opensslecdsa_compare,
                    625:        NULL, /*%< paramcompare */
                    626:        opensslecdsa_generate,
                    627:        opensslecdsa_isprivate,
                    628:        opensslecdsa_destroy,
                    629:        opensslecdsa_todns,
                    630:        opensslecdsa_fromdns,
                    631:        opensslecdsa_tofile,
                    632:        opensslecdsa_parse,
                    633:        NULL, /*%< cleanup */
                    634:        NULL, /*%< fromlabel */
                    635:        NULL, /*%< dump */
                    636:        NULL, /*%< restore */
                    637: };
                    638:
                    639: isc_result_t
                    640: dst__opensslecdsa_init(dst_func_t **funcp) {
                    641:        REQUIRE(funcp != NULL);
                    642:        if (*funcp == NULL)
                    643:                *funcp = &opensslecdsa_functions;
                    644:        return (ISC_R_SUCCESS);
                    645: }
                    646:
1.3     ! christos  647: #endif /* !USE_PKCS11 */

CVSweb <webmaster@jp.NetBSD.org>