Annotation of embedaddon/strongswan/src/libstrongswan/plugins/botan/botan_rsa_private_key.c, revision 1.1.1.2

1.1       misho       1: /*
                      2:  * Copyright (C) 2018 Tobias Brunner
                      3:  * Copyright (C) 2018 Andreas Steffen
                      4:  * HSR Hochschule fuer Technik Rapperswil
                      5:  *
                      6:  * Copyright (C) 2018 René Korthaus
                      7:  * Rohde & Schwarz Cybersecurity GmbH
                      8:  *
                      9:  * Permission is hereby granted, free of charge, to any person obtaining a copy
                     10:  * of this software and associated documentation files (the "Software"), to deal
                     11:  * in the Software without restriction, including without limitation the rights
                     12:  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
                     13:  * copies of the Software, and to permit persons to whom the Software is
                     14:  * furnished to do so, subject to the following conditions:
                     15:  *
                     16:  * The above copyright notice and this permission notice shall be included in
                     17:  * all copies or substantial portions of the Software.
                     18:  *
                     19:  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
                     20:  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
                     21:  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
                     22:  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
                     23:  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
                     24:  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
                     25:  * THE SOFTWARE.
                     26:  */
                     27: 
                     28: #include "botan_rsa_private_key.h"
                     29: #include "botan_rsa_public_key.h"
                     30: 
                     31: #include <botan/build.h>
                     32: 
                     33: #ifdef BOTAN_HAS_RSA
                     34: 
                     35: #include "botan_util.h"
                     36: 
                     37: #include <botan/ffi.h>
                     38: 
                     39: #include <utils/debug.h>
                     40: 
                     41: typedef struct private_botan_rsa_private_key_t private_botan_rsa_private_key_t;
                     42: 
                     43: /**
                     44:  * Private data of a botan_rsa_private_key_t object.
                     45:  */
                     46: struct private_botan_rsa_private_key_t {
                     47: 
                     48:        /**
                     49:         * Public interface for this signer.
                     50:         */
                     51:        botan_rsa_private_key_t public;
                     52: 
                     53:        /**
                     54:         * Botan private key
                     55:         */
                     56:        botan_privkey_t key;
                     57: 
                     58:        /**
                     59:         * reference count
                     60:         */
                     61:        refcount_t ref;
                     62: };
                     63: 
                     64: /**
                     65:  * Get the Botan string identifier for an EMSA PSS signature
                     66:  */
                     67: bool botan_emsa_pss_identifier(rsa_pss_params_t *params, char *id, size_t len)
                     68: {
                     69:        const char *hash;
                     70: 
                     71:        if (!params)
                     72:        {
                     73:                return FALSE;
                     74:        }
                     75: 
                     76:        /* botan currently does not support passing the mgf1 hash */
                     77:        if (params->hash != params->mgf1_hash)
                     78:        {
                     79:                DBG1(DBG_LIB, "passing mgf1 hash not supported via botan");
                     80:                return FALSE;
                     81:        }
                     82: 
                     83:        hash = botan_get_hash(params->hash);
                     84:        if (!hash)
                     85:        {
                     86:                return FALSE;
                     87:        }
                     88:        return snprintf(id, len, "EMSA-PSS(%s,MGF1,%zd)", hash,
                     89:                                        params->salt_len) < len;
                     90: }
                     91: 
                     92: /**
                     93:  * Build an EMSA PSS signature described in PKCS#1
                     94:  */
                     95: static bool build_emsa_pss_signature(private_botan_rsa_private_key_t *this,
                     96:                                                                         rsa_pss_params_t *params, chunk_t data,
                     97:                                                                         chunk_t *sig)
                     98: {
                     99:        char hash_and_padding[BUF_LEN];
                    100: 
                    101:        if (!botan_emsa_pss_identifier(params, hash_and_padding,
                    102:                                                                   sizeof(hash_and_padding)))
                    103:        {
                    104:                return FALSE;
                    105:        }
                    106:        return botan_get_signature(this->key, hash_and_padding, data, sig);
                    107: }
                    108: 
                    109: METHOD(private_key_t, get_type, key_type_t,
                    110:        private_botan_rsa_private_key_t *this)
                    111: {
                    112:        return KEY_RSA;
                    113: }
                    114: 
                    115: METHOD(private_key_t, sign, bool,
                    116:        private_botan_rsa_private_key_t *this, signature_scheme_t scheme,
                    117:        void *params, chunk_t data, chunk_t *signature)
                    118: {
                    119:        switch (scheme)
                    120:        {
                    121:                case SIGN_RSA_EMSA_PKCS1_NULL:
                    122:                        return botan_get_signature(this->key, "EMSA_PKCS1(Raw)", data,
                    123:                                                                           signature);
                    124:                case SIGN_RSA_EMSA_PKCS1_SHA1:
                    125:                        return botan_get_signature(this->key, "EMSA_PKCS1(SHA-1)", data,
                    126:                                                                           signature);
                    127:                case SIGN_RSA_EMSA_PKCS1_SHA2_224:
                    128:                        return botan_get_signature(this->key, "EMSA_PKCS1(SHA-224)", data,
                    129:                                                                           signature);
                    130:                case SIGN_RSA_EMSA_PKCS1_SHA2_256:
                    131:                        return botan_get_signature(this->key, "EMSA_PKCS1(SHA-256)", data,
                    132:                                                                           signature);
                    133:                case SIGN_RSA_EMSA_PKCS1_SHA2_384:
                    134:                        return botan_get_signature(this->key, "EMSA_PKCS1(SHA-384)", data,
                    135:                                                                           signature);
                    136:                case SIGN_RSA_EMSA_PKCS1_SHA2_512:
                    137:                        return botan_get_signature(this->key, "EMSA_PKCS1(SHA-512)", data,
                    138:                                                                           signature);
                    139:                case SIGN_RSA_EMSA_PKCS1_SHA3_224:
                    140:                        return botan_get_signature(this->key, "EMSA_PKCS1(SHA-3(224))", data,
                    141:                                                                           signature);
                    142:                case SIGN_RSA_EMSA_PKCS1_SHA3_256:
                    143:                        return botan_get_signature(this->key, "EMSA_PKCS1(SHA-3(256))", data,
                    144:                                                                           signature);
                    145:                case SIGN_RSA_EMSA_PKCS1_SHA3_384:
                    146:                        return botan_get_signature(this->key, "EMSA_PKCS1(SHA-3(384))", data,
                    147:                                                                           signature);
                    148:                case SIGN_RSA_EMSA_PKCS1_SHA3_512:
                    149:                        return botan_get_signature(this->key, "EMSA_PKCS1(SHA-3(512))", data,
                    150:                                                                           signature);
                    151:                case SIGN_RSA_EMSA_PSS:
                    152:                        return build_emsa_pss_signature(this, params, data, signature);
                    153:                default:
                    154:                        DBG1(DBG_LIB, "signature scheme %N not supported via botan",
                    155:                                 signature_scheme_names, scheme);
                    156:                        return FALSE;
                    157:        }
                    158: }
                    159: 
                    160: METHOD(private_key_t, decrypt, bool,
                    161:        private_botan_rsa_private_key_t *this, encryption_scheme_t scheme,
                    162:        chunk_t crypto, chunk_t *plain)
                    163: {
                    164:        botan_pk_op_decrypt_t decrypt_op;
                    165:        const char *padding;
                    166: 
                    167:        switch (scheme)
                    168:        {
                    169:                case ENCRYPT_RSA_PKCS1:
                    170:                        padding = "PKCS1v15";
                    171:                        break;
                    172:                case ENCRYPT_RSA_OAEP_SHA1:
                    173:                        padding = "OAEP(SHA-1)";
                    174:                        break;
                    175:                case ENCRYPT_RSA_OAEP_SHA224:
                    176:                        padding = "OAEP(SHA-224)";
                    177:                        break;
                    178:                case ENCRYPT_RSA_OAEP_SHA256:
                    179:                        padding = "OAEP(SHA-256)";
                    180:                        break;
                    181:                case ENCRYPT_RSA_OAEP_SHA384:
                    182:                        padding = "OAEP(SHA-384)";
                    183:                        break;
                    184:                case ENCRYPT_RSA_OAEP_SHA512:
                    185:                        padding = "OAEP(SHA-512)";
                    186:                        break;
                    187:                default:
                    188:                        DBG1(DBG_LIB, "encryption scheme %N not supported via botan",
                    189:                                 encryption_scheme_names, scheme);
                    190:                        return FALSE;
                    191:        }
                    192: 
                    193:        if (botan_pk_op_decrypt_create(&decrypt_op, this->key, padding, 0))
                    194:        {
                    195:                return FALSE;
                    196:        }
                    197: 
                    198:        plain->len = 0;
                    199:        if (botan_pk_op_decrypt_output_length(decrypt_op, crypto.len, &plain->len))
                    200:        {
                    201:                botan_pk_op_decrypt_destroy(decrypt_op);
                    202:                return FALSE;
                    203:        }
                    204: 
                    205:        *plain = chunk_alloc(plain->len);
                    206:        if (botan_pk_op_decrypt(decrypt_op, plain->ptr, &plain->len, crypto.ptr,
                    207:                                                        crypto.len))
                    208:        {
                    209:                chunk_free(plain);
                    210:                botan_pk_op_decrypt_destroy(decrypt_op);
                    211:                return FALSE;
                    212:        }
                    213:        botan_pk_op_decrypt_destroy(decrypt_op);
                    214:        return TRUE;
                    215: }
                    216: 
                    217: METHOD(private_key_t, get_keysize, int,
                    218:        private_botan_rsa_private_key_t *this)
                    219: {
                    220:        botan_mp_t n;
                    221:        size_t bits = 0;
                    222: 
                    223:        if (botan_mp_init(&n))
                    224:        {
                    225:                return 0;
                    226:        }
                    227: 
                    228:        if (botan_privkey_get_field(n, this->key, "n") ||
                    229:                botan_mp_num_bits(n, &bits))
                    230:        {
                    231:                botan_mp_destroy(n);
                    232:                return 0;
                    233:        }
                    234: 
                    235:        botan_mp_destroy(n);
                    236:        return bits;
                    237: }
                    238: 
                    239: METHOD(private_key_t, get_public_key, public_key_t*,
                    240:        private_botan_rsa_private_key_t *this)
                    241: {
                    242:        botan_pubkey_t pubkey;
                    243: 
                    244:        if (botan_privkey_export_pubkey(&pubkey, this->key))
                    245:        {
                    246:                return NULL;
                    247:        }
                    248:        return (public_key_t*)botan_rsa_public_key_adopt(pubkey);
                    249: }
                    250: 
                    251: METHOD(private_key_t, get_fingerprint, bool,
                    252:        private_botan_rsa_private_key_t *this, cred_encoding_type_t type,
                    253:        chunk_t *fingerprint)
                    254: {
                    255:        botan_pubkey_t pubkey;
                    256:        bool success = FALSE;
                    257: 
                    258:        /* check the cache before doing the export */
                    259:        if (lib->encoding->get_cache(lib->encoding, type, this, fingerprint))
                    260:        {
                    261:                return TRUE;
                    262:        }
                    263: 
                    264:        if (botan_privkey_export_pubkey(&pubkey, this->key))
                    265:        {
                    266:                return FALSE;
                    267:        }
                    268:        success = botan_get_fingerprint(pubkey, this, type, fingerprint);
                    269:        botan_pubkey_destroy(pubkey);
                    270:        return success;
                    271: }
                    272: 
                    273: METHOD(private_key_t, get_encoding, bool,
                    274:        private_botan_rsa_private_key_t *this, cred_encoding_type_t type,
                    275:        chunk_t *encoding)
                    276: {
                    277:        return botan_get_privkey_encoding(this->key, type, encoding);
                    278: }
                    279: 
                    280: METHOD(private_key_t, get_ref, private_key_t*,
                    281:        private_botan_rsa_private_key_t *this)
                    282: {
                    283:        ref_get(&this->ref);
                    284:        return &this->public.key;
                    285: }
                    286: 
                    287: METHOD(private_key_t, destroy, void,
                    288:        private_botan_rsa_private_key_t *this)
                    289: {
                    290:        if (ref_put(&this->ref))
                    291:        {
                    292:                lib->encoding->clear_cache(lib->encoding, this);
                    293:                botan_privkey_destroy(this->key);
                    294:                free(this);
                    295:        }
                    296: }
                    297: 
                    298: /**
                    299:  * Internal generic constructor
                    300:  */
                    301: static private_botan_rsa_private_key_t *create_empty()
                    302: {
                    303:        private_botan_rsa_private_key_t *this;
                    304: 
                    305:        INIT(this,
                    306:                .public = {
                    307:                        .key = {
                    308:                                .get_type = _get_type,
                    309:                                .sign = _sign,
                    310:                                .decrypt = _decrypt,
                    311:                                .get_keysize = _get_keysize,
                    312:                                .get_public_key = _get_public_key,
                    313:                                .equals = private_key_equals,
                    314:                                .belongs_to = private_key_belongs_to,
                    315:                                .get_fingerprint = _get_fingerprint,
                    316:                                .has_fingerprint = private_key_has_fingerprint,
                    317:                                .get_encoding = _get_encoding,
                    318:                                .get_ref = _get_ref,
                    319:                                .destroy = _destroy,
                    320:                        },
                    321:                },
                    322:                .ref = 1,
                    323:        );
                    324: 
                    325:        return this;
                    326: }
                    327: 
                    328: /*
                    329:  * Described in header
                    330:  */
                    331: botan_rsa_private_key_t *botan_rsa_private_key_adopt(botan_privkey_t key)
                    332: {
                    333:        private_botan_rsa_private_key_t *this;
                    334: 
                    335:        this = create_empty();
                    336:        this->key = key;
                    337: 
                    338:        return &this->public;
                    339: }
                    340: 
                    341: /*
                    342:  * Described in header
                    343:  */
                    344: botan_rsa_private_key_t *botan_rsa_private_key_gen(key_type_t type,
                    345:                                                                                                   va_list args)
                    346: {
                    347:        private_botan_rsa_private_key_t *this;
                    348:        botan_rng_t rng;
                    349:        char buf[BUF_LEN];
                    350:        u_int key_size = 0;
                    351: 
                    352:        while (TRUE)
                    353:        {
                    354:                switch (va_arg(args, builder_part_t))
                    355:                {
                    356:                        case BUILD_KEY_SIZE:
                    357:                                key_size = va_arg(args, u_int);
                    358:                                continue;
                    359:                        case BUILD_END:
                    360:                                break;
                    361:                        default:
                    362:                                return NULL;
                    363:                }
                    364:                break;
                    365:        }
                    366: 
                    367:        if (!key_size)
                    368:        {
                    369:                return NULL;
                    370:        }
                    371: 
1.1.1.2 ! misho     372:        if (!botan_get_rng(&rng, RNG_TRUE))
1.1       misho     373:        {
                    374:                return NULL;
                    375:        }
                    376: 
                    377:        this = create_empty();
                    378: 
                    379:        snprintf(buf, sizeof(buf), "%u", key_size);
                    380: 
                    381:        if (botan_privkey_create(&this->key, "RSA", buf, rng))
                    382:        {
                    383:                botan_rng_destroy(rng);
                    384:                free(this);
                    385:                return NULL;
                    386:        }
                    387:        botan_rng_destroy(rng);
                    388:        return &this->public;
                    389: }
                    390: 
                    391: /**
                    392:  * Recover the primes from n, e and d using the algorithm described in
                    393:  * Appendix C of NIST SP 800-56B.
                    394:  */
                    395: static bool calculate_pq(botan_mp_t *n, botan_mp_t *e, botan_mp_t *d,
                    396:                                                 botan_mp_t *p, botan_mp_t *q)
                    397: {
                    398:        botan_mp_t k = NULL, one = NULL, r = NULL, zero = NULL, two = NULL;
                    399:        botan_mp_t n1 = NULL, x = NULL, y = NULL, g = NULL, rem = NULL;
                    400:        botan_rng_t rng = NULL;
                    401:        int i, t, j;
                    402:        bool success = FALSE;
                    403: 
                    404:        if (botan_mp_init(&k) ||
                    405:                botan_mp_init(&one) ||
                    406:                botan_mp_set_from_int(one, 1))
                    407:        {
                    408:                goto error;
                    409:        }
                    410: 
                    411:        /* 1. k = d * e - 1 */
                    412:        if (botan_mp_mul(k, *d, *e) || botan_mp_sub(k, k, one))
                    413:        {
                    414:                goto error;
                    415:        }
                    416: 
                    417:        /* k must be even */
                    418:        if (botan_mp_get_bit(k, 0) != 0)
                    419:        {
                    420:                goto error;
                    421:        }
                    422: 
                    423:        /* 2. k = 2^t * r, where r is the largest odd integer dividing k, and t >= 1 */
                    424:        if (botan_mp_init(&r) ||
                    425:                botan_mp_set_from_mp(r, k))
                    426:        {
                    427:                goto error;
                    428:        }
                    429: 
                    430:        for (t = 0; botan_mp_get_bit(r, 0) != 1; t++)
                    431:        {
                    432:                if (botan_mp_rshift(r, r, 1))
                    433:                {
                    434:                        goto error;
                    435:                }
                    436:        }
                    437: 
                    438:        /* need 0 and n-1 below */
                    439:        if (botan_mp_init(&zero) ||
                    440:                botan_mp_init(&n1) ||
                    441:                botan_mp_sub(n1, *n, one))
                    442:        {
                    443:                goto error;
                    444:        }
                    445: 
                    446:        if (botan_mp_init(&g))
                    447:        {
                    448:                goto error;
                    449:        }
                    450: 
1.1.1.2 ! misho     451:        if (!botan_get_rng(&rng, RNG_STRONG))
1.1       misho     452:        {
                    453:                goto error;
                    454:        }
                    455: 
                    456:        if (botan_mp_init(&two))
                    457:        {
                    458:                goto error;
                    459:        }
                    460: 
                    461:        if (botan_mp_set_from_int(two, 2))
                    462:        {
                    463:                goto error;
                    464:        }
                    465: 
                    466:        if (botan_mp_init(&y) ||
                    467:                botan_mp_init(&x))
                    468:        {
                    469:                goto error;
                    470:        }
                    471: 
                    472:        for (i = 0; i < 100; i++)
                    473:        {
                    474:                /* 3a. generate a random integer g in the range [0, n-1] */
                    475:                if (botan_mp_rand_range(g, rng, zero, n1))
                    476:                {
                    477:                        goto error;
                    478:                }
                    479:                /* 3b. y = g^r mod n */
                    480:                if (botan_mp_powmod(y, g, r, *n))
                    481:                {
                    482:                        goto error;
                    483:                }
                    484: 
                    485:                /* 3c. If y = 1 or y = n – 1, try again */
                    486:                if (botan_mp_equal(y, one) || botan_mp_equal(y, n1))
                    487:                {
                    488:                        continue;
                    489:                }
                    490: 
                    491:                for (j = 0; j < t; j++)
                    492:                {
                    493:                        /* x = y^2 mod n */
                    494:                        if (botan_mp_powmod(x, y, two, *n))
                    495:                        {
                    496:                                goto error;
                    497:                        }
                    498: 
                    499:                        /* stop if x == 1 */
                    500:                        if (botan_mp_equal(x, one))
                    501:                        {
                    502:                                goto done;
                    503:                        }
                    504: 
                    505:                        /* retry with new g if x = n-1 */
                    506:                        if (botan_mp_equal(x, n1))
                    507:                        {
                    508:                                break;
                    509:                        }
                    510: 
                    511:                        /* let y = x */
                    512:                        if (botan_mp_set_from_mp(y, x))
                    513:                        {
                    514:                                goto error;
                    515:                        }
                    516:                }
                    517:        }
                    518: 
                    519: done:
                    520:        /* 5. p = GCD(y – 1, n) and q = n/p */
                    521:        if (botan_mp_sub(y, y, one))
                    522:        {
                    523:                goto error;
                    524:        }
                    525: 
                    526:        if (botan_mp_init(p) ||
                    527:                botan_mp_gcd(*p, y, *n))
                    528:        {
                    529:                goto error;
                    530:        }
                    531: 
                    532:        if (botan_mp_init(q) ||
                    533:                botan_mp_init(&rem) ||
                    534:                botan_mp_div(*q, rem, *n, *p))
                    535:        {
                    536:                goto error;
                    537:        }
                    538: 
                    539:        if (!botan_mp_is_zero(rem))
                    540:        {
                    541:                goto error;
                    542:        }
                    543: 
                    544:        success = TRUE;
                    545: 
                    546: error:
                    547:        if (!success)
                    548:        {
                    549:                botan_mp_destroy(*p);
                    550:                botan_mp_destroy(*q);
                    551:        }
                    552:        botan_rng_destroy(rng);
                    553:        botan_mp_destroy(k);
                    554:        botan_mp_destroy(one);
                    555:        botan_mp_destroy(r);
                    556:        botan_mp_destroy(zero);
                    557:        botan_mp_destroy(two);
                    558:        botan_mp_destroy(n1);
                    559:        botan_mp_destroy(x);
                    560:        botan_mp_destroy(y);
                    561:        botan_mp_destroy(g);
                    562:        botan_mp_destroy(rem);
                    563:        return success;
                    564: }
                    565: 
                    566: /*
                    567:  * Described in header
                    568:  */
                    569: botan_rsa_private_key_t *botan_rsa_private_key_load(key_type_t type,
                    570:                                                                                                        va_list args)
                    571: {
                    572:        private_botan_rsa_private_key_t *this;
                    573:        chunk_t n, e, d, p, q, blob;
                    574: 
                    575:        n = e = d = p = q = blob = chunk_empty;
                    576:        while (TRUE)
                    577:        {
                    578:                switch (va_arg(args, builder_part_t))
                    579:                {
                    580:                        case BUILD_BLOB_ASN1_DER:
                    581:                                blob = va_arg(args, chunk_t);
                    582:                                continue;
                    583:                        case BUILD_RSA_MODULUS:
                    584:                                n = va_arg(args, chunk_t);
                    585:                                continue;
                    586:                        case BUILD_RSA_PUB_EXP:
                    587:                                e = va_arg(args, chunk_t);
                    588:                                continue;
                    589:                        case BUILD_RSA_PRIV_EXP:
                    590:                                d = va_arg(args, chunk_t);
                    591:                                continue;
                    592:                        case BUILD_RSA_PRIME1:
                    593:                                p = va_arg(args, chunk_t);
                    594:                                continue;
                    595:                        case BUILD_RSA_PRIME2:
                    596:                                q = va_arg(args, chunk_t);
                    597:                                continue;
                    598:                        case BUILD_RSA_EXP1:
                    599:                        case BUILD_RSA_EXP2:
                    600:                        case BUILD_RSA_COEFF:
                    601:                                /* not required for botan */
                    602:                                va_arg(args, chunk_t);
                    603:                                continue;
                    604:                        case BUILD_END:
                    605:                                break;
                    606:                        default:
                    607:                                return NULL;
                    608:                }
                    609:                break;
                    610:        }
                    611: 
                    612:        if (type == KEY_ANY && !blob.ptr)
                    613:        {
                    614:                return NULL;
                    615:        }
                    616: 
                    617:        if (blob.ptr)
                    618:        {
                    619:                this = create_empty();
                    620: 
                    621:                if (botan_privkey_load_rsa_pkcs1(&this->key, blob.ptr, blob.len))
                    622:                {
                    623:                        free(this);
                    624:                        return NULL;
                    625:                }
                    626:                return &this->public;
                    627:        }
                    628: 
                    629:        if (n.ptr && e.ptr && d.ptr)
                    630:        {
                    631:                botan_mp_t n_mp, e_mp, d_mp, p_mp = NULL, q_mp = NULL;
                    632: 
                    633:                if (!chunk_to_botan_mp(n, &n_mp))
                    634:                {
                    635:                        return NULL;
                    636:                }
                    637: 
                    638:                if (!chunk_to_botan_mp(e, &e_mp))
                    639:                {
                    640:                        botan_mp_destroy(n_mp);
                    641:                        return NULL;
                    642:                }
                    643: 
                    644:                if (!chunk_to_botan_mp(d, &d_mp))
                    645:                {
                    646:                        botan_mp_destroy(n_mp);
                    647:                        botan_mp_destroy(e_mp);
                    648:                        return NULL;
                    649:                }
                    650: 
                    651:                if (p.ptr && q.ptr)
                    652:                {
                    653:                        if (!chunk_to_botan_mp(p, &p_mp))
                    654:                        {
                    655:                                botan_mp_destroy(n_mp);
                    656:                                botan_mp_destroy(e_mp);
                    657:                                botan_mp_destroy(d_mp);
                    658:                                return NULL;
                    659:                        }
                    660: 
                    661:                        if (!chunk_to_botan_mp(q, &q_mp))
                    662:                        {
                    663:                                botan_mp_destroy(n_mp);
                    664:                                botan_mp_destroy(e_mp);
                    665:                                botan_mp_destroy(d_mp);
                    666:                                botan_mp_destroy(p_mp);
                    667:                                return NULL;
                    668:                        }
                    669:                }
                    670:                else
                    671:                {
                    672:                        /* calculate p,q from n, e, d */
                    673:                        if (!calculate_pq(&n_mp, &e_mp, &d_mp, &p_mp, &q_mp))
                    674:                        {
                    675:                                botan_mp_destroy(n_mp);
                    676:                                botan_mp_destroy(e_mp);
                    677:                                botan_mp_destroy(d_mp);
                    678:                                return NULL;
                    679:                        }
                    680:                }
                    681:                botan_mp_destroy(n_mp);
                    682:                botan_mp_destroy(d_mp);
                    683: 
                    684:                this = create_empty();
                    685: 
                    686:                if (botan_privkey_load_rsa(&this->key, p_mp, q_mp, e_mp))
                    687:                {
                    688:                        botan_mp_destroy(e_mp);
                    689:                        botan_mp_destroy(p_mp);
                    690:                        botan_mp_destroy(q_mp);
                    691:                        free(this);
                    692:                        return NULL;
                    693:                }
                    694: 
                    695:                botan_mp_destroy(e_mp);
                    696:                botan_mp_destroy(p_mp);
                    697:                botan_mp_destroy(q_mp);
                    698: 
                    699:                return &this->public;
                    700:        }
                    701: 
                    702:        return NULL;
                    703: }
                    704: 
                    705: #endif

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>