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

1.1       misho       1: /*
                      2:  * Copyright (C) 2018 Tobias Brunner
                      3:  * HSR Hochschule fuer Technik Rapperswil
                      4:  *
                      5:  * Permission is hereby granted, free of charge, to any person obtaining a copy
                      6:  * of this software and associated documentation files (the "Software"), to deal
                      7:  * in the Software without restriction, including without limitation the rights
                      8:  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
                      9:  * copies of the Software, and to permit persons to whom the Software is
                     10:  * furnished to do so, subject to the following conditions:
                     11:  *
                     12:  * The above copyright notice and this permission notice shall be included in
                     13:  * all copies or substantial portions of the Software.
                     14:  *
                     15:  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
                     16:  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
                     17:  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
                     18:  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
                     19:  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
                     20:  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
                     21:  * THE SOFTWARE.
                     22:  */
                     23: 
1.1.1.2 ! misho      24: #include "botan_util.h"
1.1       misho      25: #include "botan_util_keys.h"
                     26: #include "botan_ec_public_key.h"
                     27: #include "botan_ec_private_key.h"
                     28: #include "botan_ed_public_key.h"
                     29: #include "botan_ed_private_key.h"
                     30: #include "botan_rsa_public_key.h"
                     31: #include "botan_rsa_private_key.h"
                     32: 
                     33: #include <asn1/asn1.h>
                     34: #include <asn1/oid.h>
                     35: 
                     36: /**
                     37:  * Get the algorithm name of a public key
                     38:  */
                     39: static char *get_algo_name(botan_pubkey_t pubkey)
                     40: {
                     41:        char *name;
                     42:        size_t len = 0;
                     43: 
                     44:        if (botan_pubkey_algo_name(pubkey, NULL, &len)
                     45:                != BOTAN_FFI_ERROR_INSUFFICIENT_BUFFER_SPACE)
                     46:        {
                     47:                return NULL;
                     48:        }
                     49: 
                     50:        name = malloc(len);
                     51:        if (botan_pubkey_algo_name(pubkey, name, &len))
                     52:        {
                     53:                free(name);
                     54:                return NULL;
                     55:        }
                     56:        return name;
                     57: }
                     58: 
                     59: /*
                     60:  * Described in header
                     61:  */
                     62: public_key_t *botan_public_key_load(key_type_t type, va_list args)
                     63: {
                     64:        public_key_t *this = NULL;
                     65:        botan_pubkey_t pubkey;
                     66:        chunk_t blob = chunk_empty;
                     67:        botan_rng_t rng;
                     68:        char *name;
                     69: 
                     70:        while (TRUE)
                     71:        {
                     72:                switch (va_arg(args, builder_part_t))
                     73:                {
                     74:                        case BUILD_BLOB_ASN1_DER:
                     75:                                blob = va_arg(args, chunk_t);
                     76:                                continue;
                     77:                        case BUILD_END:
                     78:                                break;
                     79:                        default:
                     80:                                return NULL;
                     81:                }
                     82:                break;
                     83:        }
                     84: 
1.1.1.2 ! misho      85:        if (!botan_get_rng(&rng, RNG_STRONG))
1.1       misho      86:        {
                     87:                return NULL;
                     88:        }
                     89:        if (botan_pubkey_load(&pubkey, blob.ptr, blob.len))
                     90:        {
                     91:                botan_rng_destroy(rng);
                     92:                return NULL;
                     93:        }
                     94:        if (botan_pubkey_check_key(pubkey, rng, BOTAN_CHECK_KEY_EXPENSIVE_TESTS))
                     95:        {
                     96:                DBG1(DBG_LIB, "public key failed key checks");
                     97:                botan_pubkey_destroy(pubkey);
                     98:                botan_rng_destroy(rng);
                     99:                return NULL;
                    100:        }
                    101:        botan_rng_destroy(rng);
                    102: 
                    103:        name = get_algo_name(pubkey);
                    104:        if (!name)
                    105:        {
                    106:                botan_pubkey_destroy(pubkey);
                    107:                return NULL;
                    108:        }
                    109: 
                    110: #ifdef BOTAN_HAS_RSA
                    111:        if (streq(name, "RSA") && (type == KEY_ANY || type == KEY_RSA))
                    112:        {
                    113:                this = (public_key_t*)botan_rsa_public_key_adopt(pubkey);
                    114:        }
                    115:        else
                    116: #endif
                    117: #ifdef BOTAN_HAS_ECDSA
                    118:        if (streq(name, "ECDSA") && (type == KEY_ANY || type == KEY_ECDSA))
                    119:        {
                    120:                this = (public_key_t*)botan_ec_public_key_adopt(pubkey);
                    121:        }
                    122:        else
                    123: #endif
                    124: #ifdef BOTAN_HAS_ED25519
                    125:        if (streq(name, "Ed25519") && (type == KEY_ANY || type == KEY_ED25519))
                    126:        {
                    127:                this = botan_ed_public_key_adopt(pubkey);
                    128:        }
                    129:        else
                    130: #endif
                    131:        {
                    132:                botan_pubkey_destroy(pubkey);
                    133:        }
                    134:        free(name);
                    135:        return this;
                    136: }
                    137: 
                    138: #ifdef BOTAN_HAS_ECDSA
                    139: /**
                    140:  * Determine the curve OID from a PKCS#8 structure
                    141:  */
                    142: static int determine_ec_oid(chunk_t pkcs8)
                    143: {
                    144:        int oid = OID_UNKNOWN;
                    145:        chunk_t inner, params = chunk_empty;
                    146: 
                    147:        if (asn1_unwrap(&pkcs8, &pkcs8) == ASN1_SEQUENCE &&
                    148:                asn1_unwrap(&pkcs8, &inner) == ASN1_INTEGER &&
                    149:                asn1_parse_integer_uint64(inner) == 0 &&
                    150:                asn1_parse_algorithmIdentifier(pkcs8, 0, &params) == OID_EC_PUBLICKEY &&
                    151:                params.len &&
                    152:                asn1_unwrap(&params, &params) == ASN1_OID)
                    153:        {
                    154:                oid = asn1_known_oid(params);
                    155:        }
                    156:        return oid;
                    157: }
                    158: #endif
                    159: 
                    160: /*
                    161:  * Described in header
                    162:  */
                    163: private_key_t *botan_private_key_load(key_type_t type, va_list args)
                    164: {
                    165:        private_key_t *this = NULL;
                    166:        botan_privkey_t key;
                    167:        botan_pubkey_t pubkey;
                    168:        chunk_t blob = chunk_empty;
                    169:        botan_rng_t rng;
                    170:        char *name;
                    171: 
                    172:        while (TRUE)
                    173:        {
                    174:                switch (va_arg(args, builder_part_t))
                    175:                {
                    176:                        case BUILD_BLOB_ASN1_DER:
                    177:                                blob = va_arg(args, chunk_t);
                    178:                                continue;
                    179:                        case BUILD_END:
                    180:                                break;
                    181:                        default:
                    182:                                return NULL;
                    183:                }
                    184:                break;
                    185:        }
                    186: 
1.1.1.2 ! misho     187:        if (!botan_get_rng(&rng, RNG_STRONG))
1.1       misho     188:        {
                    189:                return NULL;
                    190:        }
                    191:        if (botan_privkey_load(&key, rng, blob.ptr, blob.len, NULL))
                    192:        {
                    193:                botan_rng_destroy(rng);
                    194:                return NULL;
                    195:        }
                    196:        botan_rng_destroy(rng);
                    197: 
                    198:        if (botan_privkey_export_pubkey(&pubkey, key))
                    199:        {
                    200:                botan_privkey_destroy(key);
                    201:                return NULL;
                    202:        }
                    203:        name = get_algo_name(pubkey);
                    204:        botan_pubkey_destroy(pubkey);
                    205:        if (!name)
                    206:        {
                    207:                botan_privkey_destroy(key);
                    208:                return NULL;
                    209:        }
                    210: 
                    211: #ifdef BOTAN_HAS_RSA
                    212:        if (streq(name, "RSA") && (type == KEY_ANY || type == KEY_RSA))
                    213:        {
                    214:                this = (private_key_t*)botan_rsa_private_key_adopt(key);
                    215:        }
                    216:        else
                    217: #endif
                    218: #ifdef BOTAN_HAS_ECDSA
                    219:        if (streq(name, "ECDSA") && (type == KEY_ANY || type == KEY_ECDSA))
                    220:        {
                    221:                int oid = determine_ec_oid(blob);
                    222:                if (oid != OID_UNKNOWN)
                    223:                {
                    224:                        this = (private_key_t*)botan_ec_private_key_adopt(key, oid);
                    225:                }
                    226:        }
                    227:        else
                    228: #endif
                    229: #ifdef BOTAN_HAS_ED25519
                    230:        if (streq(name, "Ed25519") && (type == KEY_ANY || type == KEY_ED25519))
                    231:        {
                    232:                this = botan_ed_private_key_adopt(key);
                    233:        }
                    234: #endif
                    235: 
                    236:        if (!this)
                    237:        {
                    238:                botan_privkey_destroy(key);
                    239:        }
                    240:        free(name);
                    241:        return this;
                    242: }

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