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