Annotation of embedaddon/strongswan/src/libstrongswan/plugins/wolfssl/wolfssl_ed_public_key.c, revision 1.1

1.1     ! misho       1: /*
        !             2:  * Copyright (C) 2019 Sean Parkinson, wolfSSL Inc.
        !             3:  *
        !             4:  * Permission is hereby granted, free of charge, to any person obtaining a copy
        !             5:  * of this software and associated documentation files (the "Software"), to deal
        !             6:  * in the Software without restriction, including without limitation the rights
        !             7:  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
        !             8:  * copies of the Software, and to permit persons to whom the Software is
        !             9:  * furnished to do so, subject to the following conditions:
        !            10:  *
        !            11:  * The above copyright notice and this permission notice shall be included in
        !            12:  * all copies or substantial portions of the Software.
        !            13:  *
        !            14:  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
        !            15:  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
        !            16:  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
        !            17:  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
        !            18:  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
        !            19:  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
        !            20:  * THE SOFTWARE.
        !            21:  */
        !            22: 
        !            23: #include "wolfssl_common.h"
        !            24: 
        !            25: #ifdef HAVE_ED25519
        !            26: 
        !            27: #include "wolfssl_ed_public_key.h"
        !            28: 
        !            29: #include <utils/debug.h>
        !            30: #include <asn1/asn1.h>
        !            31: 
        !            32: #include <wolfssl/wolfcrypt/ed25519.h>
        !            33: #include <wolfssl/wolfcrypt/asn.h>
        !            34: 
        !            35: typedef struct private_public_key_t private_public_key_t;
        !            36: 
        !            37: /**
        !            38:  * Private data
        !            39:  */
        !            40: struct private_public_key_t {
        !            41: 
        !            42:        /**
        !            43:         * Public interface
        !            44:         */
        !            45:        public_key_t public;
        !            46: 
        !            47:        /**
        !            48:         * Key object
        !            49:         */
        !            50:        ed25519_key key;
        !            51: 
        !            52:        /**
        !            53:         * Reference count
        !            54:         */
        !            55:        refcount_t ref;
        !            56: };
        !            57: 
        !            58: METHOD(public_key_t, get_type, key_type_t,
        !            59:        private_public_key_t *this)
        !            60: {
        !            61:        return KEY_ED25519;
        !            62: }
        !            63: 
        !            64: METHOD(public_key_t, verify, bool,
        !            65:        private_public_key_t *this, signature_scheme_t scheme,
        !            66:        void *params, chunk_t data, chunk_t signature)
        !            67: {
        !            68:        byte dummy[1];
        !            69:        int ret, res;
        !            70: 
        !            71:        if (scheme != SIGN_ED25519)
        !            72:        {
        !            73:                DBG1(DBG_LIB, "signature scheme %N not supported by %N key",
        !            74:                         signature_scheme_names, scheme, key_type_names, KEY_ED25519);
        !            75:                return FALSE;
        !            76:        }
        !            77: 
        !            78:        if (!data.ptr && !data.len)
        !            79:        {
        !            80:                data.ptr = dummy;
        !            81:        }
        !            82: 
        !            83:        ret = wc_ed25519_verify_msg(signature.ptr, signature.len, data.ptr,
        !            84:                                                                data.len, &res, &this->key);
        !            85:        return ret == 0 && res == 1;
        !            86: }
        !            87: 
        !            88: METHOD(public_key_t, encrypt, bool,
        !            89:        private_public_key_t *this, encryption_scheme_t scheme,
        !            90:        chunk_t crypto, chunk_t *plain)
        !            91: {
        !            92:        DBG1(DBG_LIB, "encryption scheme %N not supported", encryption_scheme_names,
        !            93:                 scheme);
        !            94:        return FALSE;
        !            95: }
        !            96: 
        !            97: METHOD(public_key_t, get_keysize, int,
        !            98:        private_public_key_t *this)
        !            99: {
        !           100:        return ED25519_KEY_SIZE * 8;
        !           101: }
        !           102: 
        !           103: /**
        !           104:  * Encode the given public key as ASN.1 DER with algorithm identifier
        !           105:  */
        !           106: static bool encode_pubkey(ed25519_key *key, chunk_t *encoding)
        !           107: {
        !           108:        int ret;
        !           109: 
        !           110:        /* account for algorithmIdentifier/bitString */
        !           111:        *encoding = chunk_alloc(ED25519_PUB_KEY_SIZE + 2 * MAX_SEQ_SZ +
        !           112:                                                        MAX_ALGO_SZ + TRAILING_ZERO);
        !           113:        ret = wc_Ed25519PublicKeyToDer(key, encoding->ptr, encoding->len, 1);
        !           114:        if (ret < 0)
        !           115:        {
        !           116:                return FALSE;
        !           117:        }
        !           118:        encoding->len = ret;
        !           119:        return TRUE;
        !           120: }
        !           121: 
        !           122: /**
        !           123:  * Calculate fingerprint from an EdDSA key, also used in ed private key.
        !           124:  */
        !           125: bool wolfssl_ed_fingerprint(ed25519_key *key, cred_encoding_type_t type,
        !           126:                                                        chunk_t *fp)
        !           127: {
        !           128:        hasher_t *hasher;
        !           129:        chunk_t blob;
        !           130:        word32 len;
        !           131:        bool success = FALSE;
        !           132: 
        !           133:        if (lib->encoding->get_cache(lib->encoding, type, key, fp))
        !           134:        {
        !           135:                return TRUE;
        !           136:        }
        !           137:        switch (type)
        !           138:        {
        !           139:                case KEYID_PUBKEY_SHA1:
        !           140:                        len = ED25519_PUB_KEY_SIZE;
        !           141:                        blob = chunk_alloc(len);
        !           142:                        if (wc_ed25519_export_public(key, blob.ptr, &len) != 0)
        !           143:                        {
        !           144:                                return FALSE;
        !           145:                        }
        !           146:                        break;
        !           147:                case KEYID_PUBKEY_INFO_SHA1:
        !           148:                        if (!encode_pubkey(key, &blob))
        !           149:                        {
        !           150:                                return FALSE;
        !           151:                        }
        !           152:                        break;
        !           153:                default:
        !           154:                        return FALSE;
        !           155:        }
        !           156:        hasher = lib->crypto->create_hasher(lib->crypto, HASH_SHA1);
        !           157:        if (!hasher || !hasher->allocate_hash(hasher, blob, fp))
        !           158:        {
        !           159:                DBG1(DBG_LIB, "SHA1 not supported, fingerprinting failed");
        !           160:        }
        !           161:        else
        !           162:        {
        !           163:                lib->encoding->cache(lib->encoding, type, key, *fp);
        !           164:                success = TRUE;
        !           165:        }
        !           166:        DESTROY_IF(hasher);
        !           167:        chunk_free(&blob);
        !           168:        return success;
        !           169: }
        !           170: 
        !           171: METHOD(public_key_t, get_fingerprint, bool,
        !           172:        private_public_key_t *this, cred_encoding_type_t type, chunk_t *fingerprint)
        !           173: {
        !           174:        return wolfssl_ed_fingerprint(&this->key, type, fingerprint);
        !           175: }
        !           176: 
        !           177: METHOD(public_key_t, get_encoding, bool,
        !           178:        private_public_key_t *this, cred_encoding_type_t type, chunk_t *encoding)
        !           179: {
        !           180:        bool success = TRUE;
        !           181: 
        !           182:        if (!encode_pubkey(&this->key, encoding))
        !           183:        {
        !           184:                return FALSE;
        !           185:        }
        !           186: 
        !           187:        if (type != PUBKEY_SPKI_ASN1_DER)
        !           188:        {
        !           189:                chunk_t asn1_encoding = *encoding;
        !           190: 
        !           191:                success = lib->encoding->encode(lib->encoding, type,
        !           192:                                                                NULL, encoding, CRED_PART_EDDSA_PUB_ASN1_DER,
        !           193:                                                                asn1_encoding, CRED_PART_END);
        !           194:                chunk_free(&asn1_encoding);
        !           195:        }
        !           196:        return success;
        !           197: }
        !           198: 
        !           199: METHOD(public_key_t, get_ref, public_key_t*,
        !           200:        private_public_key_t *this)
        !           201: {
        !           202:        ref_get(&this->ref);
        !           203:        return &this->public;
        !           204: }
        !           205: 
        !           206: METHOD(public_key_t, destroy, void,
        !           207:        private_public_key_t *this)
        !           208: {
        !           209:        if (ref_put(&this->ref))
        !           210:        {
        !           211:                lib->encoding->clear_cache(lib->encoding, &this->key);
        !           212:                wc_ed25519_free(&this->key);
        !           213:                free(this);
        !           214:        }
        !           215: }
        !           216: 
        !           217: /**
        !           218:  * Generic private constructor
        !           219:  */
        !           220: static private_public_key_t *create_empty()
        !           221: {
        !           222:        private_public_key_t *this;
        !           223: 
        !           224:        INIT(this,
        !           225:                .public = {
        !           226:                        .get_type = _get_type,
        !           227:                        .verify = _verify,
        !           228:                        .encrypt = _encrypt,
        !           229:                        .get_keysize = _get_keysize,
        !           230:                        .equals = public_key_equals,
        !           231:                        .get_fingerprint = _get_fingerprint,
        !           232:                        .has_fingerprint = public_key_has_fingerprint,
        !           233:                        .get_encoding = _get_encoding,
        !           234:                        .get_ref = _get_ref,
        !           235:                        .destroy = _destroy,
        !           236:                },
        !           237:                .ref = 1,
        !           238:        );
        !           239: 
        !           240:        if (wc_ed25519_init(&this->key) != 0)
        !           241:        {
        !           242:                free(this);
        !           243:                return NULL;
        !           244:        }
        !           245:        return this;
        !           246: }
        !           247: 
        !           248: /*
        !           249:  * Described in header
        !           250:  */
        !           251: public_key_t *wolfssl_ed_public_key_load(key_type_t type, va_list args)
        !           252: {
        !           253:        private_public_key_t *this;
        !           254:        chunk_t blob = chunk_empty, pub = chunk_empty;
        !           255:        int idx;
        !           256:        int ret = -1;
        !           257: 
        !           258:        while (TRUE)
        !           259:        {
        !           260:                switch (va_arg(args, builder_part_t))
        !           261:                {
        !           262:                        case BUILD_BLOB_ASN1_DER:
        !           263:                                blob = va_arg(args, chunk_t);
        !           264:                                continue;
        !           265:                        case BUILD_EDDSA_PUB:
        !           266:                                pub = va_arg(args, chunk_t);
        !           267:                                continue;
        !           268:                        case BUILD_END:
        !           269:                                break;
        !           270:                        default:
        !           271:                                return NULL;
        !           272:                }
        !           273:                break;
        !           274:        }
        !           275: 
        !           276:        this = create_empty();
        !           277:        if (!this)
        !           278:        {
        !           279:                return NULL;
        !           280:        }
        !           281: 
        !           282:        if (pub.len)
        !           283:        {
        !           284:                ret = wc_ed25519_import_public(pub.ptr, pub.len, &this->key);
        !           285:        }
        !           286:        else if (blob.len)
        !           287:        {
        !           288:                idx = 0;
        !           289:                ret = wc_Ed25519PublicKeyDecode(blob.ptr, &idx, &this->key, blob.len);
        !           290:        }
        !           291:        if (ret != 0)
        !           292:        {
        !           293:                destroy(this);
        !           294:                return NULL;
        !           295:        }
        !           296:        return &this->public;
        !           297: }
        !           298: 
        !           299: #endif /* HAVE_ED25519 */

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