Annotation of embedaddon/strongswan/src/libstrongswan/plugins/botan/botan_rsa_public_key.c, revision 1.1.1.1

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_public_key.h"
                     29: 
                     30: #include <botan/build.h>
                     31: 
                     32: #ifdef BOTAN_HAS_RSA
                     33: 
                     34: #include "botan_util.h"
                     35: 
                     36: #include <asn1/oid.h>
                     37: #include <asn1/asn1.h>
                     38: #include <asn1/asn1_parser.h>
                     39: 
                     40: #include <utils/debug.h>
                     41: 
                     42: #include <botan/ffi.h>
                     43: 
                     44: typedef struct private_botan_rsa_public_key_t private_botan_rsa_public_key_t;
                     45: 
                     46: /**
                     47:  * Private data structure with signing context.
                     48:  */
                     49: struct private_botan_rsa_public_key_t {
                     50: 
                     51:        /**
                     52:         * Public interface for this signer
                     53:         */
                     54:        botan_rsa_public_key_t public;
                     55: 
                     56:        /**
                     57:         * Botan public key
                     58:         */
                     59:        botan_pubkey_t key;
                     60: 
                     61:        /**
                     62:         * Reference counter
                     63:         */
                     64:        refcount_t ref;
                     65: };
                     66: 
                     67: /**
                     68:  * Defined in botan_rsa_private_key.c
                     69:  */
                     70: bool botan_emsa_pss_identifier(rsa_pss_params_t *params, char *id, size_t len);
                     71: 
                     72: /**
                     73:  * Verification of an EMSA PSS signature described in PKCS#1
                     74:  */
                     75: static bool verify_emsa_pss_signature(private_botan_rsa_public_key_t *this,
                     76:                                                                          rsa_pss_params_t *params, chunk_t data,
                     77:                                                                          chunk_t signature)
                     78: {
                     79:        char hash_and_padding[BUF_LEN];
                     80: 
                     81:        if (!botan_emsa_pss_identifier(params, hash_and_padding,
                     82:                                                                   sizeof(hash_and_padding)))
                     83:        {
                     84:                return FALSE;
                     85:        }
                     86:        return botan_verify_signature(this->key, hash_and_padding, data, signature);
                     87: }
                     88: 
                     89: METHOD(public_key_t, get_type, key_type_t,
                     90:        private_botan_rsa_public_key_t *this)
                     91: {
                     92:        return KEY_RSA;
                     93: }
                     94: 
                     95: METHOD(public_key_t, verify, bool,
                     96:        private_botan_rsa_public_key_t *this, signature_scheme_t scheme,
                     97:        void *params, chunk_t data, chunk_t signature)
                     98: {
                     99:        switch (scheme)
                    100:        {
                    101:                case SIGN_RSA_EMSA_PKCS1_NULL:
                    102:                        return botan_verify_signature(this->key, "EMSA_PKCS1(Raw)", data,
                    103:                                                                                  signature);
                    104:                case SIGN_RSA_EMSA_PKCS1_SHA1:
                    105:                        return botan_verify_signature(this->key, "EMSA_PKCS1(SHA-1)", data,
                    106:                                                                                  signature);
                    107:                case SIGN_RSA_EMSA_PKCS1_SHA2_224:
                    108:                        return botan_verify_signature(this->key, "EMSA_PKCS1(SHA-224)",
                    109:                                                                                  data, signature);
                    110:                case SIGN_RSA_EMSA_PKCS1_SHA2_256:
                    111:                        return botan_verify_signature(this->key, "EMSA_PKCS1(SHA-256)",
                    112:                                                                                  data, signature);
                    113:                case SIGN_RSA_EMSA_PKCS1_SHA2_384:
                    114:                        return botan_verify_signature(this->key, "EMSA_PKCS1(SHA-384)",
                    115:                                                                                  data, signature);
                    116:                case SIGN_RSA_EMSA_PKCS1_SHA2_512:
                    117:                        return botan_verify_signature(this->key, "EMSA_PKCS1(SHA-512)",
                    118:                                                                                  data, signature);
                    119:                case SIGN_RSA_EMSA_PKCS1_SHA3_224:
                    120:                        return botan_verify_signature(this->key, "EMSA_PKCS1(SHA-3(224)",
                    121:                                                                                  data, signature);
                    122:                case SIGN_RSA_EMSA_PKCS1_SHA3_256:
                    123:                        return botan_verify_signature(this->key, "EMSA_PKCS1(SHA-3(256))",
                    124:                                                                                  data, signature);
                    125:                case SIGN_RSA_EMSA_PKCS1_SHA3_384:
                    126:                        return botan_verify_signature(this->key, "EMSA_PKCS1(SHA-3(384))",
                    127:                                                                                  data, signature);
                    128:                case SIGN_RSA_EMSA_PKCS1_SHA3_512:
                    129:                        return botan_verify_signature(this->key, "EMSA_PKCS1(SHA-3(512))",
                    130:                                                                                  data, signature);
                    131:                case SIGN_RSA_EMSA_PSS:
                    132:                        return verify_emsa_pss_signature(this, params, data, signature);
                    133:                default:
                    134:                        DBG1(DBG_LIB, "signature scheme %N not supported via botan",
                    135:                                 signature_scheme_names, scheme);
                    136:                        return FALSE;
                    137:        }
                    138: }
                    139: 
                    140: METHOD(public_key_t, encrypt, bool,
                    141:        private_botan_rsa_public_key_t *this, encryption_scheme_t scheme,
                    142:        chunk_t plain, chunk_t *crypto)
                    143: {
                    144:        botan_pk_op_encrypt_t encrypt_op;
                    145:        botan_rng_t rng;
                    146:        const char* padding;
                    147: 
                    148:        switch (scheme)
                    149:        {
                    150:                case ENCRYPT_RSA_PKCS1:
                    151:                        padding = "PKCS1v15";
                    152:                        break;
                    153:                case ENCRYPT_RSA_OAEP_SHA1:
                    154:                        padding = "OAEP(SHA-1)";
                    155:                        break;
                    156:                case ENCRYPT_RSA_OAEP_SHA224:
                    157:                        padding = "OAEP(SHA-224)";
                    158:                        break;
                    159:                case ENCRYPT_RSA_OAEP_SHA256:
                    160:                        padding = "OAEP(SHA-256)";
                    161:                        break;
                    162:                case ENCRYPT_RSA_OAEP_SHA384:
                    163:                        padding = "OAEP(SHA-384)";
                    164:                        break;
                    165:                case ENCRYPT_RSA_OAEP_SHA512:
                    166:                        padding = "OAEP(SHA-512)";
                    167:                        break;
                    168:                default:
                    169:                        DBG1(DBG_LIB, "encryption scheme %N not supported via botan",
                    170:                                 encryption_scheme_names, scheme);
                    171:                        return FALSE;
                    172:        }
                    173: 
                    174:        if (botan_rng_init(&rng, "user"))
                    175:        {
                    176:                return FALSE;
                    177:        }
                    178: 
                    179:        if (botan_pk_op_encrypt_create(&encrypt_op, this->key, padding, 0))
                    180:        {
                    181:                botan_rng_destroy(rng);
                    182:                return FALSE;
                    183:        }
                    184: 
                    185:        crypto->len = 0;
                    186:        if (botan_pk_op_encrypt_output_length(encrypt_op, plain.len, &crypto->len))
                    187:        {
                    188:                botan_rng_destroy(rng);
                    189:                botan_pk_op_encrypt_destroy(encrypt_op);
                    190:                return FALSE;
                    191:        }
                    192: 
                    193:        *crypto = chunk_alloc(crypto->len);
                    194:        if (botan_pk_op_encrypt(encrypt_op, rng, crypto->ptr, &crypto->len,
                    195:                                                        plain.ptr, plain.len))
                    196:        {
                    197:                chunk_free(crypto);
                    198:                botan_rng_destroy(rng);
                    199:                botan_pk_op_encrypt_destroy(encrypt_op);
                    200:                return FALSE;
                    201:        }
                    202:        botan_rng_destroy(rng);
                    203:        botan_pk_op_encrypt_destroy(encrypt_op);
                    204:        return TRUE;
                    205: }
                    206: 
                    207: METHOD(public_key_t, get_keysize, int,
                    208:        private_botan_rsa_public_key_t *this)
                    209: {
                    210:        botan_mp_t n;
                    211:        size_t bits = 0;
                    212: 
                    213:        if (botan_mp_init(&n))
                    214:        {
                    215:                return 0;
                    216:        }
                    217: 
                    218:        if (botan_pubkey_get_field(n, this->key, "n") ||
                    219:                botan_mp_num_bits(n, &bits))
                    220:        {
                    221:                botan_mp_destroy(n);
                    222:                return 0;
                    223:        }
                    224: 
                    225:        botan_mp_destroy(n);
                    226:        return bits;
                    227: }
                    228: 
                    229: METHOD(public_key_t, get_fingerprint, bool,
                    230:        private_botan_rsa_public_key_t *this, cred_encoding_type_t type,
                    231:        chunk_t *fp)
                    232: {
                    233:        return botan_get_fingerprint(this->key, this, type, fp);
                    234: }
                    235: 
                    236: METHOD(public_key_t, get_encoding, bool,
                    237:        private_botan_rsa_public_key_t *this, cred_encoding_type_t type,
                    238:        chunk_t *encoding)
                    239: {
                    240:        return botan_get_encoding(this->key, type, encoding);
                    241: }
                    242: 
                    243: METHOD(public_key_t, get_ref, public_key_t*,
                    244:        private_botan_rsa_public_key_t *this)
                    245: {
                    246:        ref_get(&this->ref);
                    247:        return &this->public.key;
                    248: }
                    249: 
                    250: METHOD(public_key_t, destroy, void,
                    251:        private_botan_rsa_public_key_t *this)
                    252: {
                    253:        if (ref_put(&this->ref))
                    254:        {
                    255:                lib->encoding->clear_cache(lib->encoding, this);
                    256:                botan_pubkey_destroy(this->key);
                    257:                free(this);
                    258:        }
                    259: }
                    260: 
                    261: /**
                    262:  * Internal generic constructor
                    263:  */
                    264: static private_botan_rsa_public_key_t *create_empty()
                    265: {
                    266:        private_botan_rsa_public_key_t *this;
                    267: 
                    268:        INIT(this,
                    269:                .public = {
                    270:                        .key = {
                    271:                                .get_type = _get_type,
                    272:                                .verify = _verify,
                    273:                                .encrypt = _encrypt,
                    274:                                .equals = public_key_equals,
                    275:                                .get_keysize = _get_keysize,
                    276:                                .get_fingerprint = _get_fingerprint,
                    277:                                .has_fingerprint = public_key_has_fingerprint,
                    278:                                .get_encoding = _get_encoding,
                    279:                                .get_ref = _get_ref,
                    280:                                .destroy = _destroy,
                    281:                        },
                    282:                },
                    283:                .ref = 1,
                    284:        );
                    285: 
                    286:        return this;
                    287: }
                    288: 
                    289: /*
                    290:  * Described in header
                    291:  */
                    292: botan_rsa_public_key_t *botan_rsa_public_key_adopt(botan_pubkey_t key)
                    293: {
                    294:        private_botan_rsa_public_key_t *this;
                    295: 
                    296:        this = create_empty();
                    297:        this->key = key;
                    298: 
                    299:        return &this->public;
                    300: }
                    301: 
                    302: /*
                    303:  * Described in header
                    304:  */
                    305: botan_rsa_public_key_t *botan_rsa_public_key_load(key_type_t type,
                    306:                                                                                                  va_list args)
                    307: {
                    308:        private_botan_rsa_public_key_t *this = NULL;
                    309:        chunk_t n, e;
                    310: 
                    311:        n = e = chunk_empty;
                    312:        while (TRUE)
                    313:        {
                    314:                switch (va_arg(args, builder_part_t))
                    315:                {
                    316:                        case BUILD_RSA_MODULUS:
                    317:                                n = va_arg(args, chunk_t);
                    318:                                continue;
                    319:                        case BUILD_RSA_PUB_EXP:
                    320:                                e = va_arg(args, chunk_t);
                    321:                                continue;
                    322:                        case BUILD_END:
                    323:                                break;
                    324:                        default:
                    325:                                return NULL;
                    326:                }
                    327:                break;
                    328:        }
                    329: 
                    330:        if (n.ptr && e.ptr && type == KEY_RSA)
                    331:        {
                    332:                botan_mp_t mp_n, mp_e;
                    333: 
                    334:                if (!chunk_to_botan_mp(n, &mp_n))
                    335:                {
                    336:                        return NULL;
                    337:                }
                    338: 
                    339:                if (!chunk_to_botan_mp(e, &mp_e))
                    340:                {
                    341:                        botan_mp_destroy(mp_n);
                    342:                        return NULL;
                    343:                }
                    344: 
                    345:                this = create_empty();
                    346: 
                    347:                if (botan_pubkey_load_rsa(&this->key, mp_n, mp_e))
                    348:                {
                    349:                        botan_mp_destroy(mp_n);
                    350:                        botan_mp_destroy(mp_e);
                    351:                        free(this);
                    352:                        return NULL;
                    353:                }
                    354: 
                    355:                botan_mp_destroy(mp_n);
                    356:                botan_mp_destroy(mp_e);
                    357:        }
                    358: 
                    359:        return &this->public;
                    360: }
                    361: 
                    362: #endif

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