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

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: 
                     24: #include "botan_util_keys.h"
                     25: #include "botan_ec_public_key.h"
                     26: #include "botan_ec_private_key.h"
                     27: #include "botan_ed_public_key.h"
                     28: #include "botan_ed_private_key.h"
                     29: #include "botan_rsa_public_key.h"
                     30: #include "botan_rsa_private_key.h"
                     31: 
                     32: #include <asn1/asn1.h>
                     33: #include <asn1/oid.h>
                     34: 
                     35: /**
                     36:  * Get the algorithm name of a public key
                     37:  */
                     38: static char *get_algo_name(botan_pubkey_t pubkey)
                     39: {
                     40:        char *name;
                     41:        size_t len = 0;
                     42: 
                     43:        if (botan_pubkey_algo_name(pubkey, NULL, &len)
                     44:                != BOTAN_FFI_ERROR_INSUFFICIENT_BUFFER_SPACE)
                     45:        {
                     46:                return NULL;
                     47:        }
                     48: 
                     49:        name = malloc(len);
                     50:        if (botan_pubkey_algo_name(pubkey, name, &len))
                     51:        {
                     52:                free(name);
                     53:                return NULL;
                     54:        }
                     55:        return name;
                     56: }
                     57: 
                     58: /*
                     59:  * Described in header
                     60:  */
                     61: public_key_t *botan_public_key_load(key_type_t type, va_list args)
                     62: {
                     63:        public_key_t *this = NULL;
                     64:        botan_pubkey_t pubkey;
                     65:        chunk_t blob = chunk_empty;
                     66:        botan_rng_t rng;
                     67:        char *name;
                     68: 
                     69:        while (TRUE)
                     70:        {
                     71:                switch (va_arg(args, builder_part_t))
                     72:                {
                     73:                        case BUILD_BLOB_ASN1_DER:
                     74:                                blob = va_arg(args, chunk_t);
                     75:                                continue;
                     76:                        case BUILD_END:
                     77:                                break;
                     78:                        default:
                     79:                                return NULL;
                     80:                }
                     81:                break;
                     82:        }
                     83: 
                     84:        if (botan_rng_init(&rng, "user"))
                     85:        {
                     86:                return NULL;
                     87:        }
                     88:        if (botan_pubkey_load(&pubkey, blob.ptr, blob.len))
                     89:        {
                     90:                botan_rng_destroy(rng);
                     91:                return NULL;
                     92:        }
                     93:        if (botan_pubkey_check_key(pubkey, rng, BOTAN_CHECK_KEY_EXPENSIVE_TESTS))
                     94:        {
                     95:                DBG1(DBG_LIB, "public key failed key checks");
                     96:                botan_pubkey_destroy(pubkey);
                     97:                botan_rng_destroy(rng);
                     98:                return NULL;
                     99:        }
                    100:        botan_rng_destroy(rng);
                    101: 
                    102:        name = get_algo_name(pubkey);
                    103:        if (!name)
                    104:        {
                    105:                botan_pubkey_destroy(pubkey);
                    106:                return NULL;
                    107:        }
                    108: 
                    109: #ifdef BOTAN_HAS_RSA
                    110:        if (streq(name, "RSA") && (type == KEY_ANY || type == KEY_RSA))
                    111:        {
                    112:                this = (public_key_t*)botan_rsa_public_key_adopt(pubkey);
                    113:        }
                    114:        else
                    115: #endif
                    116: #ifdef BOTAN_HAS_ECDSA
                    117:        if (streq(name, "ECDSA") && (type == KEY_ANY || type == KEY_ECDSA))
                    118:        {
                    119:                this = (public_key_t*)botan_ec_public_key_adopt(pubkey);
                    120:        }
                    121:        else
                    122: #endif
                    123: #ifdef BOTAN_HAS_ED25519
                    124:        if (streq(name, "Ed25519") && (type == KEY_ANY || type == KEY_ED25519))
                    125:        {
                    126:                this = botan_ed_public_key_adopt(pubkey);
                    127:        }
                    128:        else
                    129: #endif
                    130:        {
                    131:                botan_pubkey_destroy(pubkey);
                    132:        }
                    133:        free(name);
                    134:        return this;
                    135: }
                    136: 
                    137: #ifdef BOTAN_HAS_ECDSA
                    138: /**
                    139:  * Determine the curve OID from a PKCS#8 structure
                    140:  */
                    141: static int determine_ec_oid(chunk_t pkcs8)
                    142: {
                    143:        int oid = OID_UNKNOWN;
                    144:        chunk_t inner, params = chunk_empty;
                    145: 
                    146:        if (asn1_unwrap(&pkcs8, &pkcs8) == ASN1_SEQUENCE &&
                    147:                asn1_unwrap(&pkcs8, &inner) == ASN1_INTEGER &&
                    148:                asn1_parse_integer_uint64(inner) == 0 &&
                    149:                asn1_parse_algorithmIdentifier(pkcs8, 0, &params) == OID_EC_PUBLICKEY &&
                    150:                params.len &&
                    151:                asn1_unwrap(&params, &params) == ASN1_OID)
                    152:        {
                    153:                oid = asn1_known_oid(params);
                    154:        }
                    155:        return oid;
                    156: }
                    157: #endif
                    158: 
                    159: /*
                    160:  * Described in header
                    161:  */
                    162: private_key_t *botan_private_key_load(key_type_t type, va_list args)
                    163: {
                    164:        private_key_t *this = NULL;
                    165:        botan_privkey_t key;
                    166:        botan_pubkey_t pubkey;
                    167:        chunk_t blob = chunk_empty;
                    168:        botan_rng_t rng;
                    169:        char *name;
                    170: 
                    171:        while (TRUE)
                    172:        {
                    173:                switch (va_arg(args, builder_part_t))
                    174:                {
                    175:                        case BUILD_BLOB_ASN1_DER:
                    176:                                blob = va_arg(args, chunk_t);
                    177:                                continue;
                    178:                        case BUILD_END:
                    179:                                break;
                    180:                        default:
                    181:                                return NULL;
                    182:                }
                    183:                break;
                    184:        }
                    185: 
                    186:        if (botan_rng_init(&rng, "user"))
                    187:        {
                    188:                return NULL;
                    189:        }
                    190:        if (botan_privkey_load(&key, rng, blob.ptr, blob.len, NULL))
                    191:        {
                    192:                botan_rng_destroy(rng);
                    193:                return NULL;
                    194:        }
                    195:        botan_rng_destroy(rng);
                    196: 
                    197:        if (botan_privkey_export_pubkey(&pubkey, key))
                    198:        {
                    199:                botan_privkey_destroy(key);
                    200:                return NULL;
                    201:        }
                    202:        name = get_algo_name(pubkey);
                    203:        botan_pubkey_destroy(pubkey);
                    204:        if (!name)
                    205:        {
                    206:                botan_privkey_destroy(key);
                    207:                return NULL;
                    208:        }
                    209: 
                    210: #ifdef BOTAN_HAS_RSA
                    211:        if (streq(name, "RSA") && (type == KEY_ANY || type == KEY_RSA))
                    212:        {
                    213:                this = (private_key_t*)botan_rsa_private_key_adopt(key);
                    214:        }
                    215:        else
                    216: #endif
                    217: #ifdef BOTAN_HAS_ECDSA
                    218:        if (streq(name, "ECDSA") && (type == KEY_ANY || type == KEY_ECDSA))
                    219:        {
                    220:                int oid = determine_ec_oid(blob);
                    221:                if (oid != OID_UNKNOWN)
                    222:                {
                    223:                        this = (private_key_t*)botan_ec_private_key_adopt(key, oid);
                    224:                }
                    225:        }
                    226:        else
                    227: #endif
                    228: #ifdef BOTAN_HAS_ED25519
                    229:        if (streq(name, "Ed25519") && (type == KEY_ANY || type == KEY_ED25519))
                    230:        {
                    231:                this = botan_ed_private_key_adopt(key);
                    232:        }
                    233: #endif
                    234: 
                    235:        if (!this)
                    236:        {
                    237:                botan_privkey_destroy(key);
                    238:        }
                    239:        free(name);
                    240:        return this;
                    241: }

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