Return to wolfssl_ed_public_key.c CVS log | Up to [ELWIX - Embedded LightWeight unIX -] / embedaddon / strongswan / src / libstrongswan / plugins / wolfssl |
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 */