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>