Annotation of embedaddon/strongswan/src/libstrongswan/plugins/botan/botan_ed_private_key.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_ed_private_key.h"
                     25: #include "botan_ed_public_key.h"
                     26: #include "botan_util.h"
                     27: 
                     28: #include <botan/build.h>
                     29: 
                     30: #ifdef BOTAN_HAS_ED25519
                     31: 
                     32: #include <asn1/asn1.h>
                     33: #include <utils/debug.h>
                     34: 
                     35: typedef struct private_private_key_t private_private_key_t;
                     36: 
                     37: #define ED25519_KEY_LEN 32
                     38: 
                     39: /**
                     40:  * Private data
                     41:  */
                     42: struct private_private_key_t {
                     43: 
                     44:        /**
                     45:         * Public interface
                     46:         */
                     47:        private_key_t public;
                     48: 
                     49:        /**
                     50:         * Botan private key object
                     51:         */
                     52:        botan_privkey_t key;
                     53: 
                     54:        /**
                     55:         * Reference count
                     56:         */
                     57:        refcount_t ref;
                     58: };
                     59: 
                     60: METHOD(private_key_t, sign, bool,
                     61:        private_private_key_t *this, signature_scheme_t scheme,
                     62:        void *params, chunk_t data, chunk_t *signature)
                     63: {
                     64:        switch (scheme)
                     65:        {
                     66:                case SIGN_ED25519:
                     67:                        return botan_get_signature(this->key, "Pure", data, signature);
                     68:                default:
                     69:                        DBG1(DBG_LIB, "signature scheme %N not supported via botan",
                     70:                                 signature_scheme_names, scheme);
                     71:                        return FALSE;
                     72:        }
                     73: }
                     74: 
                     75: METHOD(private_key_t, decrypt, bool,
                     76:        private_private_key_t *this, encryption_scheme_t scheme,
                     77:        chunk_t crypto, chunk_t *plain)
                     78: {
                     79:        DBG1(DBG_LIB, "EdDSA private key decryption not implemented");
                     80:        return FALSE;
                     81: }
                     82: 
                     83: METHOD(private_key_t, get_keysize, int,
                     84:        private_private_key_t *this)
                     85: {
                     86:        return ED25519_KEY_LEN * 8;
                     87: }
                     88: 
                     89: METHOD(private_key_t, get_type, key_type_t,
                     90:        private_private_key_t *this)
                     91: {
                     92:        return KEY_ED25519;
                     93: }
                     94: 
                     95: METHOD(private_key_t, get_public_key, public_key_t*,
                     96:        private_private_key_t *this)
                     97: {
                     98:        botan_pubkey_t pubkey;
                     99: 
                    100:        if (botan_privkey_export_pubkey(&pubkey, this->key))
                    101:        {
                    102:                return NULL;
                    103:        }
                    104:        return botan_ed_public_key_adopt(pubkey);
                    105: }
                    106: 
                    107: METHOD(private_key_t, get_fingerprint, bool,
                    108:        private_private_key_t *this, cred_encoding_type_t type,
                    109:        chunk_t *fingerprint)
                    110: {
                    111:        botan_pubkey_t pubkey;
                    112:        bool success = FALSE;
                    113: 
                    114:        /* check the cache before doing the export */
                    115:        if (lib->encoding->get_cache(lib->encoding, type, this, fingerprint))
                    116:        {
                    117:                return TRUE;
                    118:        }
                    119: 
                    120:        if (botan_privkey_export_pubkey(&pubkey, this->key))
                    121:        {
                    122:                return FALSE;
                    123:        }
                    124:        success = botan_get_fingerprint(pubkey, this, type, fingerprint);
                    125:        botan_pubkey_destroy(pubkey);
                    126:        return success;
                    127: }
                    128: 
                    129: METHOD(private_key_t, get_encoding, bool,
                    130:        private_private_key_t *this, cred_encoding_type_t type,
                    131:        chunk_t *encoding)
                    132: {
                    133:        return botan_get_privkey_encoding(this->key, type, encoding);
                    134: }
                    135: 
                    136: METHOD(private_key_t, get_ref, private_key_t*,
                    137:        private_private_key_t *this)
                    138: {
                    139:        ref_get(&this->ref);
                    140:        return &this->public;
                    141: }
                    142: 
                    143: METHOD(private_key_t, destroy, void,
                    144:        private_private_key_t *this)
                    145: {
                    146:        if (ref_put(&this->ref))
                    147:        {
                    148:                lib->encoding->clear_cache(lib->encoding, this);
                    149:                botan_privkey_destroy(this->key);
                    150:                free(this);
                    151:        }
                    152: }
                    153: 
                    154: /**
                    155:  * Internal generic constructor
                    156:  */
                    157: static private_private_key_t *create_empty()
                    158: {
                    159:        private_private_key_t *this;
                    160: 
                    161:        INIT(this,
                    162:                .public = {
                    163:                        .get_type = _get_type,
                    164:                        .sign = _sign,
                    165:                        .decrypt = _decrypt,
                    166:                        .get_keysize = _get_keysize,
                    167:                        .get_public_key = _get_public_key,
                    168:                        .equals = private_key_equals,
                    169:                        .belongs_to = private_key_belongs_to,
                    170:                        .get_fingerprint = _get_fingerprint,
                    171:                        .has_fingerprint = private_key_has_fingerprint,
                    172:                        .get_encoding = _get_encoding,
                    173:                        .get_ref = _get_ref,
                    174:                        .destroy = _destroy,
                    175:                },
                    176:                .ref = 1,
                    177:        );
                    178: 
                    179:        return this;
                    180: }
                    181: 
                    182: /*
                    183:  * Described in header
                    184:  */
                    185: private_key_t *botan_ed_private_key_adopt(botan_privkey_t key)
                    186: {
                    187:        private_private_key_t *this;
                    188: 
                    189:        this = create_empty();
                    190:        this->key = key;
                    191: 
                    192:        return &this->public;
                    193: }
                    194: 
                    195: /*
                    196:  * Described in header
                    197:  */
                    198: private_key_t *botan_ed_private_key_gen(key_type_t type, va_list args)
                    199: {
                    200:        private_private_key_t *this;
                    201:        botan_rng_t rng;
                    202: 
                    203:        while (TRUE)
                    204:        {
                    205:                switch (va_arg(args, builder_part_t))
                    206:                {
                    207:                        case BUILD_KEY_SIZE:
                    208:                                /* just ignore the key size */
                    209:                                va_arg(args, u_int);
                    210:                                continue;
                    211:                        case BUILD_END:
                    212:                                break;
                    213:                        default:
                    214:                                return NULL;
                    215:                }
                    216:                break;
                    217:        }
                    218: 
                    219:        if (botan_rng_init(&rng, "system"))
                    220:        {
                    221:                return NULL;
                    222:        }
                    223: 
                    224:        this = create_empty();
                    225: 
                    226:        if (botan_privkey_create(&this->key, "Ed25519", NULL, rng))
                    227:        {
                    228:                DBG1(DBG_LIB, "EdDSA private key generation failed");
                    229:                botan_rng_destroy(rng);
                    230:                free(this);
                    231:                return NULL;
                    232:        }
                    233: 
                    234:        botan_rng_destroy(rng);
                    235:        return &this->public;
                    236: }
                    237: 
                    238: /*
                    239:  * Described in header
                    240:  */
                    241: private_key_t *botan_ed_private_key_load(key_type_t type, va_list args)
                    242: {
                    243:        private_private_key_t *this;
                    244:        chunk_t key = chunk_empty;
                    245: 
                    246:        while (TRUE)
                    247:        {
                    248:                switch (va_arg(args, builder_part_t))
                    249:                {
                    250:                        case BUILD_EDDSA_PRIV_ASN1_DER:
                    251:                                key = va_arg(args, chunk_t);
                    252:                                continue;
                    253:                        case BUILD_END:
                    254:                                break;
                    255:                        default:
                    256:                                return NULL;
                    257:                }
                    258:                break;
                    259:        }
                    260: 
                    261:        /* PKCS#8-encoded keys are handled generically, so we only handle the
                    262:         * explicit case */
                    263:        if (asn1_unwrap(&key, &key) != ASN1_OCTET_STRING ||
                    264:                key.len != ED25519_KEY_LEN)
                    265:        {
                    266:                return NULL;
                    267:        }
                    268: 
                    269:        this = create_empty();
                    270: 
                    271:        if (botan_privkey_load_ed25519(&this->key, key.ptr))
                    272:        {
                    273:                free(this);
                    274:                return NULL;
                    275:        }
                    276:        return &this->public;
                    277: }
                    278: 
                    279: #endif

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