Return to botan_rsa_public_key.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: * Copyright (C) 2018 Andreas Steffen 4: * HSR Hochschule fuer Technik Rapperswil 5: * 6: * Copyright (C) 2018 René Korthaus 7: * Rohde & Schwarz Cybersecurity GmbH 8: * 9: * Permission is hereby granted, free of charge, to any person obtaining a copy 10: * of this software and associated documentation files (the "Software"), to deal 11: * in the Software without restriction, including without limitation the rights 12: * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 13: * copies of the Software, and to permit persons to whom the Software is 14: * furnished to do so, subject to the following conditions: 15: * 16: * The above copyright notice and this permission notice shall be included in 17: * all copies or substantial portions of the Software. 18: * 19: * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 20: * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 21: * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 22: * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 23: * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 24: * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 25: * THE SOFTWARE. 26: */ 27: 28: #include "botan_rsa_public_key.h" 29: 30: #include <botan/build.h> 31: 32: #ifdef BOTAN_HAS_RSA 33: 34: #include "botan_util.h" 35: 36: #include <asn1/oid.h> 37: #include <asn1/asn1.h> 38: #include <asn1/asn1_parser.h> 39: 40: #include <utils/debug.h> 41: 42: #include <botan/ffi.h> 43: 44: typedef struct private_botan_rsa_public_key_t private_botan_rsa_public_key_t; 45: 46: /** 47: * Private data structure with signing context. 48: */ 49: struct private_botan_rsa_public_key_t { 50: 51: /** 52: * Public interface for this signer 53: */ 54: botan_rsa_public_key_t public; 55: 56: /** 57: * Botan public key 58: */ 59: botan_pubkey_t key; 60: 61: /** 62: * Reference counter 63: */ 64: refcount_t ref; 65: }; 66: 67: /** 68: * Defined in botan_rsa_private_key.c 69: */ 70: bool botan_emsa_pss_identifier(rsa_pss_params_t *params, char *id, size_t len); 71: 72: /** 73: * Verification of an EMSA PSS signature described in PKCS#1 74: */ 75: static bool verify_emsa_pss_signature(private_botan_rsa_public_key_t *this, 76: rsa_pss_params_t *params, chunk_t data, 77: chunk_t signature) 78: { 79: char hash_and_padding[BUF_LEN]; 80: 81: if (!botan_emsa_pss_identifier(params, hash_and_padding, 82: sizeof(hash_and_padding))) 83: { 84: return FALSE; 85: } 86: return botan_verify_signature(this->key, hash_and_padding, data, signature); 87: } 88: 89: METHOD(public_key_t, get_type, key_type_t, 90: private_botan_rsa_public_key_t *this) 91: { 92: return KEY_RSA; 93: } 94: 95: METHOD(public_key_t, verify, bool, 96: private_botan_rsa_public_key_t *this, signature_scheme_t scheme, 97: void *params, chunk_t data, chunk_t signature) 98: { 99: switch (scheme) 100: { 101: case SIGN_RSA_EMSA_PKCS1_NULL: 102: return botan_verify_signature(this->key, "EMSA_PKCS1(Raw)", data, 103: signature); 104: case SIGN_RSA_EMSA_PKCS1_SHA1: 105: return botan_verify_signature(this->key, "EMSA_PKCS1(SHA-1)", data, 106: signature); 107: case SIGN_RSA_EMSA_PKCS1_SHA2_224: 108: return botan_verify_signature(this->key, "EMSA_PKCS1(SHA-224)", 109: data, signature); 110: case SIGN_RSA_EMSA_PKCS1_SHA2_256: 111: return botan_verify_signature(this->key, "EMSA_PKCS1(SHA-256)", 112: data, signature); 113: case SIGN_RSA_EMSA_PKCS1_SHA2_384: 114: return botan_verify_signature(this->key, "EMSA_PKCS1(SHA-384)", 115: data, signature); 116: case SIGN_RSA_EMSA_PKCS1_SHA2_512: 117: return botan_verify_signature(this->key, "EMSA_PKCS1(SHA-512)", 118: data, signature); 119: case SIGN_RSA_EMSA_PKCS1_SHA3_224: 120: return botan_verify_signature(this->key, "EMSA_PKCS1(SHA-3(224)", 121: data, signature); 122: case SIGN_RSA_EMSA_PKCS1_SHA3_256: 123: return botan_verify_signature(this->key, "EMSA_PKCS1(SHA-3(256))", 124: data, signature); 125: case SIGN_RSA_EMSA_PKCS1_SHA3_384: 126: return botan_verify_signature(this->key, "EMSA_PKCS1(SHA-3(384))", 127: data, signature); 128: case SIGN_RSA_EMSA_PKCS1_SHA3_512: 129: return botan_verify_signature(this->key, "EMSA_PKCS1(SHA-3(512))", 130: data, signature); 131: case SIGN_RSA_EMSA_PSS: 132: return verify_emsa_pss_signature(this, params, data, signature); 133: default: 134: DBG1(DBG_LIB, "signature scheme %N not supported via botan", 135: signature_scheme_names, scheme); 136: return FALSE; 137: } 138: } 139: 140: METHOD(public_key_t, encrypt, bool, 141: private_botan_rsa_public_key_t *this, encryption_scheme_t scheme, 142: chunk_t plain, chunk_t *crypto) 143: { 144: botan_pk_op_encrypt_t encrypt_op; 145: botan_rng_t rng; 146: const char* padding; 147: 148: switch (scheme) 149: { 150: case ENCRYPT_RSA_PKCS1: 151: padding = "PKCS1v15"; 152: break; 153: case ENCRYPT_RSA_OAEP_SHA1: 154: padding = "OAEP(SHA-1)"; 155: break; 156: case ENCRYPT_RSA_OAEP_SHA224: 157: padding = "OAEP(SHA-224)"; 158: break; 159: case ENCRYPT_RSA_OAEP_SHA256: 160: padding = "OAEP(SHA-256)"; 161: break; 162: case ENCRYPT_RSA_OAEP_SHA384: 163: padding = "OAEP(SHA-384)"; 164: break; 165: case ENCRYPT_RSA_OAEP_SHA512: 166: padding = "OAEP(SHA-512)"; 167: break; 168: default: 169: DBG1(DBG_LIB, "encryption scheme %N not supported via botan", 170: encryption_scheme_names, scheme); 171: return FALSE; 172: } 173: 174: if (botan_rng_init(&rng, "user")) 175: { 176: return FALSE; 177: } 178: 179: if (botan_pk_op_encrypt_create(&encrypt_op, this->key, padding, 0)) 180: { 181: botan_rng_destroy(rng); 182: return FALSE; 183: } 184: 185: crypto->len = 0; 186: if (botan_pk_op_encrypt_output_length(encrypt_op, plain.len, &crypto->len)) 187: { 188: botan_rng_destroy(rng); 189: botan_pk_op_encrypt_destroy(encrypt_op); 190: return FALSE; 191: } 192: 193: *crypto = chunk_alloc(crypto->len); 194: if (botan_pk_op_encrypt(encrypt_op, rng, crypto->ptr, &crypto->len, 195: plain.ptr, plain.len)) 196: { 197: chunk_free(crypto); 198: botan_rng_destroy(rng); 199: botan_pk_op_encrypt_destroy(encrypt_op); 200: return FALSE; 201: } 202: botan_rng_destroy(rng); 203: botan_pk_op_encrypt_destroy(encrypt_op); 204: return TRUE; 205: } 206: 207: METHOD(public_key_t, get_keysize, int, 208: private_botan_rsa_public_key_t *this) 209: { 210: botan_mp_t n; 211: size_t bits = 0; 212: 213: if (botan_mp_init(&n)) 214: { 215: return 0; 216: } 217: 218: if (botan_pubkey_get_field(n, this->key, "n") || 219: botan_mp_num_bits(n, &bits)) 220: { 221: botan_mp_destroy(n); 222: return 0; 223: } 224: 225: botan_mp_destroy(n); 226: return bits; 227: } 228: 229: METHOD(public_key_t, get_fingerprint, bool, 230: private_botan_rsa_public_key_t *this, cred_encoding_type_t type, 231: chunk_t *fp) 232: { 233: return botan_get_fingerprint(this->key, this, type, fp); 234: } 235: 236: METHOD(public_key_t, get_encoding, bool, 237: private_botan_rsa_public_key_t *this, cred_encoding_type_t type, 238: chunk_t *encoding) 239: { 240: return botan_get_encoding(this->key, type, encoding); 241: } 242: 243: METHOD(public_key_t, get_ref, public_key_t*, 244: private_botan_rsa_public_key_t *this) 245: { 246: ref_get(&this->ref); 247: return &this->public.key; 248: } 249: 250: METHOD(public_key_t, destroy, void, 251: private_botan_rsa_public_key_t *this) 252: { 253: if (ref_put(&this->ref)) 254: { 255: lib->encoding->clear_cache(lib->encoding, this); 256: botan_pubkey_destroy(this->key); 257: free(this); 258: } 259: } 260: 261: /** 262: * Internal generic constructor 263: */ 264: static private_botan_rsa_public_key_t *create_empty() 265: { 266: private_botan_rsa_public_key_t *this; 267: 268: INIT(this, 269: .public = { 270: .key = { 271: .get_type = _get_type, 272: .verify = _verify, 273: .encrypt = _encrypt, 274: .equals = public_key_equals, 275: .get_keysize = _get_keysize, 276: .get_fingerprint = _get_fingerprint, 277: .has_fingerprint = public_key_has_fingerprint, 278: .get_encoding = _get_encoding, 279: .get_ref = _get_ref, 280: .destroy = _destroy, 281: }, 282: }, 283: .ref = 1, 284: ); 285: 286: return this; 287: } 288: 289: /* 290: * Described in header 291: */ 292: botan_rsa_public_key_t *botan_rsa_public_key_adopt(botan_pubkey_t key) 293: { 294: private_botan_rsa_public_key_t *this; 295: 296: this = create_empty(); 297: this->key = key; 298: 299: return &this->public; 300: } 301: 302: /* 303: * Described in header 304: */ 305: botan_rsa_public_key_t *botan_rsa_public_key_load(key_type_t type, 306: va_list args) 307: { 308: private_botan_rsa_public_key_t *this = NULL; 309: chunk_t n, e; 310: 311: n = e = chunk_empty; 312: while (TRUE) 313: { 314: switch (va_arg(args, builder_part_t)) 315: { 316: case BUILD_RSA_MODULUS: 317: n = va_arg(args, chunk_t); 318: continue; 319: case BUILD_RSA_PUB_EXP: 320: e = va_arg(args, chunk_t); 321: continue; 322: case BUILD_END: 323: break; 324: default: 325: return NULL; 326: } 327: break; 328: } 329: 330: if (n.ptr && e.ptr && type == KEY_RSA) 331: { 332: botan_mp_t mp_n, mp_e; 333: 334: if (!chunk_to_botan_mp(n, &mp_n)) 335: { 336: return NULL; 337: } 338: 339: if (!chunk_to_botan_mp(e, &mp_e)) 340: { 341: botan_mp_destroy(mp_n); 342: return NULL; 343: } 344: 345: this = create_empty(); 346: 347: if (botan_pubkey_load_rsa(&this->key, mp_n, mp_e)) 348: { 349: botan_mp_destroy(mp_n); 350: botan_mp_destroy(mp_e); 351: free(this); 352: return NULL; 353: } 354: 355: botan_mp_destroy(mp_n); 356: botan_mp_destroy(mp_e); 357: } 358: 359: return &this->public; 360: } 361: 362: #endif