Annotation of embedaddon/strongswan/src/libstrongswan/plugins/openssl/openssl_plugin.c, revision 1.1
1.1 ! misho 1: /*
! 2: * Copyright (C) 2008-2020 Tobias Brunner
! 3: * Copyright (C) 2008 Martin Willi
! 4: * HSR Hochschule fuer Technik Rapperswil
! 5: *
! 6: * This program is free software; you can redistribute it and/or modify it
! 7: * under the terms of the GNU General Public License as published by the
! 8: * Free Software Foundation; either version 2 of the License, or (at your
! 9: * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
! 10: *
! 11: * This program is distributed in the hope that it will be useful, but
! 12: * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
! 13: * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
! 14: * for more details.
! 15: */
! 16:
! 17: #include <library.h>
! 18: #include <utils/debug.h>
! 19: #include <threading/thread.h>
! 20: #include <threading/mutex.h>
! 21: #include <threading/thread_value.h>
! 22:
! 23: #include <openssl/err.h>
! 24: #include <openssl/evp.h>
! 25: #include <openssl/conf.h>
! 26: #include <openssl/rand.h>
! 27: #include <openssl/crypto.h>
! 28: #ifndef OPENSSL_NO_ENGINE
! 29: #include <openssl/engine.h>
! 30: #endif
! 31:
! 32: #include "openssl_plugin.h"
! 33: #include "openssl_util.h"
! 34: #include "openssl_crypter.h"
! 35: #include "openssl_hasher.h"
! 36: #include "openssl_sha1_prf.h"
! 37: #include "openssl_diffie_hellman.h"
! 38: #include "openssl_ec_diffie_hellman.h"
! 39: #include "openssl_rsa_private_key.h"
! 40: #include "openssl_rsa_public_key.h"
! 41: #include "openssl_ec_private_key.h"
! 42: #include "openssl_ec_public_key.h"
! 43: #include "openssl_x509.h"
! 44: #include "openssl_crl.h"
! 45: #include "openssl_pkcs7.h"
! 46: #include "openssl_pkcs12.h"
! 47: #include "openssl_rng.h"
! 48: #include "openssl_hmac.h"
! 49: #include "openssl_aead.h"
! 50: #include "openssl_x_diffie_hellman.h"
! 51: #include "openssl_ed_public_key.h"
! 52: #include "openssl_ed_private_key.h"
! 53: #include "openssl_xof.h"
! 54:
! 55: #ifndef FIPS_MODE
! 56: #define FIPS_MODE 0
! 57: #endif
! 58:
! 59: typedef struct private_openssl_plugin_t private_openssl_plugin_t;
! 60:
! 61: /**
! 62: * private data of openssl_plugin
! 63: */
! 64: struct private_openssl_plugin_t {
! 65:
! 66: /**
! 67: * public functions
! 68: */
! 69: openssl_plugin_t public;
! 70: };
! 71:
! 72: /**
! 73: * OpenSSL is thread-safe since 1.1.0
! 74: */
! 75: #if OPENSSL_VERSION_NUMBER < 0x10100000L
! 76:
! 77: /**
! 78: * Array of static mutexs, with CRYPTO_num_locks() mutex
! 79: */
! 80: static mutex_t **mutex = NULL;
! 81:
! 82: /**
! 83: * Locking callback for static locks
! 84: */
! 85: static void locking_function(int mode, int type, const char *file, int line)
! 86: {
! 87: if (mutex)
! 88: {
! 89: if (mode & CRYPTO_LOCK)
! 90: {
! 91: mutex[type]->lock(mutex[type]);
! 92: }
! 93: else
! 94: {
! 95: mutex[type]->unlock(mutex[type]);
! 96: }
! 97: }
! 98: }
! 99:
! 100: /**
! 101: * Implementation of dynlock
! 102: */
! 103: struct CRYPTO_dynlock_value {
! 104: mutex_t *mutex;
! 105: };
! 106:
! 107: /**
! 108: * Callback to create a dynamic lock
! 109: */
! 110: static struct CRYPTO_dynlock_value *create_function(const char *file, int line)
! 111: {
! 112: struct CRYPTO_dynlock_value *lock;
! 113:
! 114: lock = malloc_thing(struct CRYPTO_dynlock_value);
! 115: lock->mutex = mutex_create(MUTEX_TYPE_DEFAULT);
! 116: return lock;
! 117: }
! 118:
! 119: /**
! 120: * Callback to (un-)lock a dynamic lock
! 121: */
! 122: static void lock_function(int mode, struct CRYPTO_dynlock_value *lock,
! 123: const char *file, int line)
! 124: {
! 125: if (mode & CRYPTO_LOCK)
! 126: {
! 127: lock->mutex->lock(lock->mutex);
! 128: }
! 129: else
! 130: {
! 131: lock->mutex->unlock(lock->mutex);
! 132: }
! 133: }
! 134:
! 135: /**
! 136: * Callback to destroy a dynamic lock
! 137: */
! 138: static void destroy_function(struct CRYPTO_dynlock_value *lock,
! 139: const char *file, int line)
! 140: {
! 141: lock->mutex->destroy(lock->mutex);
! 142: free(lock);
! 143: }
! 144:
! 145: /**
! 146: * Thread-local value used to cleanup thread-specific error buffers
! 147: */
! 148: static thread_value_t *cleanup;
! 149:
! 150: /**
! 151: * Called when a thread is destroyed. Avoid recursion by setting the thread id
! 152: * explicitly.
! 153: */
! 154: static void cleanup_thread(void *arg)
! 155: {
! 156: #if OPENSSL_VERSION_NUMBER >= 0x1000000fL
! 157: CRYPTO_THREADID tid;
! 158:
! 159: CRYPTO_THREADID_set_numeric(&tid, (u_long)(uintptr_t)arg);
! 160: ERR_remove_thread_state(&tid);
! 161: #else
! 162: ERR_remove_state((u_long)(uintptr_t)arg);
! 163: #endif
! 164: }
! 165:
! 166: /**
! 167: * Thread-ID callback function
! 168: */
! 169: static u_long id_function(void)
! 170: {
! 171: u_long id;
! 172:
! 173: /* ensure the thread ID is never zero, otherwise OpenSSL might try to
! 174: * acquire locks recursively */
! 175: id = 1 + (u_long)thread_current_id();
! 176:
! 177: /* cleanup a thread's state later if OpenSSL interacted with it */
! 178: cleanup->set(cleanup, (void*)(uintptr_t)id);
! 179: return id;
! 180: }
! 181:
! 182: #if OPENSSL_VERSION_NUMBER >= 0x1000000fL
! 183: /**
! 184: * Callback for thread ID
! 185: */
! 186: static void threadid_function(CRYPTO_THREADID *threadid)
! 187: {
! 188: CRYPTO_THREADID_set_numeric(threadid, id_function());
! 189: }
! 190: #endif /* OPENSSL_VERSION_NUMBER */
! 191:
! 192: /**
! 193: * initialize OpenSSL for multi-threaded use
! 194: */
! 195: static void threading_init()
! 196: {
! 197: int i, num_locks;
! 198:
! 199: cleanup = thread_value_create(cleanup_thread);
! 200:
! 201: #if OPENSSL_VERSION_NUMBER >= 0x1000000fL
! 202: CRYPTO_THREADID_set_callback(threadid_function);
! 203: #else
! 204: CRYPTO_set_id_callback(id_function);
! 205: #endif
! 206:
! 207: CRYPTO_set_locking_callback(locking_function);
! 208:
! 209: CRYPTO_set_dynlock_create_callback(create_function);
! 210: CRYPTO_set_dynlock_lock_callback(lock_function);
! 211: CRYPTO_set_dynlock_destroy_callback(destroy_function);
! 212:
! 213: num_locks = CRYPTO_num_locks();
! 214: mutex = malloc(sizeof(mutex_t*) * num_locks);
! 215: for (i = 0; i < num_locks; i++)
! 216: {
! 217: mutex[i] = mutex_create(MUTEX_TYPE_DEFAULT);
! 218: }
! 219: }
! 220:
! 221: /**
! 222: * cleanup OpenSSL threading locks
! 223: */
! 224: static void threading_cleanup()
! 225: {
! 226: int i, num_locks;
! 227:
! 228: num_locks = CRYPTO_num_locks();
! 229: for (i = 0; i < num_locks; i++)
! 230: {
! 231: mutex[i]->destroy(mutex[i]);
! 232: }
! 233: free(mutex);
! 234: mutex = NULL;
! 235:
! 236: cleanup->destroy(cleanup);
! 237: }
! 238:
! 239: #else /* OPENSSL_VERSION_NUMBER */
! 240:
! 241: #define threading_init()
! 242:
! 243: #define threading_cleanup()
! 244:
! 245: #endif
! 246:
! 247: #if OPENSSL_VERSION_NUMBER < 0x1010100fL
! 248: /**
! 249: * Seed the OpenSSL RNG, if required
! 250: * Not necessary anymore with OpenSSL 1.1.1 (maybe wasn't already earlier, but
! 251: * it's now explicitly mentioned in the documentation).
! 252: */
! 253: static bool seed_rng()
! 254: {
! 255: rng_t *rng = NULL;
! 256: char buf[32];
! 257:
! 258: while (RAND_status() != 1)
! 259: {
! 260: if (!rng)
! 261: {
! 262: rng = lib->crypto->create_rng(lib->crypto, RNG_STRONG);
! 263: if (!rng)
! 264: {
! 265: return FALSE;
! 266: }
! 267: }
! 268: if (!rng->get_bytes(rng, sizeof(buf), buf))
! 269: {
! 270: rng->destroy(rng);
! 271: return FALSE;
! 272: }
! 273: RAND_seed(buf, sizeof(buf));
! 274: }
! 275: DESTROY_IF(rng);
! 276: return TRUE;
! 277: }
! 278: #endif /* OPENSSL_VERSION_NUMBER */
! 279:
! 280: /**
! 281: * Generic key loader
! 282: */
! 283: static private_key_t *openssl_private_key_load(key_type_t type, va_list args)
! 284: {
! 285: chunk_t blob = chunk_empty;
! 286: EVP_PKEY *key;
! 287:
! 288: while (TRUE)
! 289: {
! 290: switch (va_arg(args, builder_part_t))
! 291: {
! 292: case BUILD_BLOB_ASN1_DER:
! 293: blob = va_arg(args, chunk_t);
! 294: continue;
! 295: case BUILD_END:
! 296: break;
! 297: default:
! 298: return NULL;
! 299: }
! 300: break;
! 301: }
! 302:
! 303: if (blob.ptr)
! 304: {
! 305: key = d2i_AutoPrivateKey(NULL, (const u_char**)&blob.ptr, blob.len);
! 306: if (key)
! 307: {
! 308: switch (EVP_PKEY_base_id(key))
! 309: {
! 310: #ifndef OPENSSL_NO_RSA
! 311: case EVP_PKEY_RSA:
! 312: return openssl_rsa_private_key_create(key, FALSE);
! 313: #endif
! 314: #ifndef OPENSSL_NO_ECDSA
! 315: case EVP_PKEY_EC:
! 316: return openssl_ec_private_key_create(key, FALSE);
! 317: #endif
! 318: #if OPENSSL_VERSION_NUMBER >= 0x1010100fL && !defined(OPENSSL_NO_EC)
! 319: case EVP_PKEY_ED25519:
! 320: case EVP_PKEY_ED448:
! 321: return openssl_ed_private_key_create(key, FALSE);
! 322: #endif /* OPENSSL_VERSION_NUMBER */
! 323: default:
! 324: EVP_PKEY_free(key);
! 325: break;
! 326: }
! 327: }
! 328: }
! 329: return NULL;
! 330: }
! 331:
! 332: #ifndef OPENSSL_NO_ENGINE
! 333: /**
! 334: * Login to engine with a PIN specified for a keyid
! 335: */
! 336: static bool login(ENGINE *engine, chunk_t keyid)
! 337: {
! 338: enumerator_t *enumerator;
! 339: shared_key_t *shared;
! 340: identification_t *id;
! 341: chunk_t key;
! 342: char pin[64];
! 343: bool found = FALSE, success = FALSE;
! 344:
! 345: id = identification_create_from_encoding(ID_KEY_ID, keyid);
! 346: enumerator = lib->credmgr->create_shared_enumerator(lib->credmgr,
! 347: SHARED_PIN, id, NULL);
! 348: while (enumerator->enumerate(enumerator, &shared, NULL, NULL))
! 349: {
! 350: found = TRUE;
! 351: key = shared->get_key(shared);
! 352: if (snprintf(pin, sizeof(pin),
! 353: "%.*s", (int)key.len, key.ptr) >= sizeof(pin))
! 354: {
! 355: continue;
! 356: }
! 357: if (ENGINE_ctrl_cmd_string(engine, "PIN", pin, 0))
! 358: {
! 359: success = TRUE;
! 360: break;
! 361: }
! 362: else
! 363: {
! 364: DBG1(DBG_CFG, "setting PIN on engine failed");
! 365: }
! 366: }
! 367: enumerator->destroy(enumerator);
! 368: id->destroy(id);
! 369: if (!found)
! 370: {
! 371: DBG1(DBG_CFG, "no PIN found for %#B", &keyid);
! 372: }
! 373: return success;
! 374: }
! 375: #endif /* OPENSSL_NO_ENGINE */
! 376:
! 377: /**
! 378: * Load private key via engine
! 379: */
! 380: static private_key_t *openssl_private_key_connect(key_type_t type,
! 381: va_list args)
! 382: {
! 383: #ifndef OPENSSL_NO_ENGINE
! 384: char *engine_id = NULL;
! 385: char keyname[BUF_LEN];
! 386: chunk_t keyid = chunk_empty;
! 387: EVP_PKEY *key;
! 388: ENGINE *engine;
! 389: int slot = -1;
! 390:
! 391: while (TRUE)
! 392: {
! 393: switch (va_arg(args, builder_part_t))
! 394: {
! 395: case BUILD_PKCS11_KEYID:
! 396: keyid = va_arg(args, chunk_t);
! 397: continue;
! 398: case BUILD_PKCS11_SLOT:
! 399: slot = va_arg(args, int);
! 400: continue;
! 401: case BUILD_PKCS11_MODULE:
! 402: engine_id = va_arg(args, char*);
! 403: continue;
! 404: case BUILD_END:
! 405: break;
! 406: default:
! 407: return NULL;
! 408: }
! 409: break;
! 410: }
! 411: if (!keyid.len)
! 412: {
! 413: return NULL;
! 414: }
! 415:
! 416: memset(keyname, 0, sizeof(keyname));
! 417: if (slot != -1)
! 418: {
! 419: snprintf(keyname, sizeof(keyname), "%d:", slot);
! 420: }
! 421: if (sizeof(keyname) - strlen(keyname) <= keyid.len * 2 + 1)
! 422: {
! 423: return NULL;
! 424: }
! 425: chunk_to_hex(keyid, keyname + strlen(keyname), FALSE);
! 426:
! 427: if (!engine_id)
! 428: {
! 429: engine_id = lib->settings->get_str(lib->settings,
! 430: "%s.plugins.openssl.engine_id", "pkcs11", lib->ns);
! 431: }
! 432: engine = ENGINE_by_id(engine_id);
! 433: if (!engine)
! 434: {
! 435: DBG2(DBG_LIB, "engine '%s' is not available", engine_id);
! 436: return NULL;
! 437: }
! 438: if (!ENGINE_init(engine))
! 439: {
! 440: DBG1(DBG_LIB, "failed to initialize engine '%s'", engine_id);
! 441: ENGINE_free(engine);
! 442: return NULL;
! 443: }
! 444: ENGINE_free(engine);
! 445: if (!login(engine, keyid))
! 446: {
! 447: DBG1(DBG_LIB, "login to engine '%s' failed", engine_id);
! 448: ENGINE_finish(engine);
! 449: return NULL;
! 450: }
! 451: key = ENGINE_load_private_key(engine, keyname, NULL, NULL);
! 452: ENGINE_finish(engine);
! 453: if (!key)
! 454: {
! 455: DBG1(DBG_LIB, "failed to load private key with ID '%s' from "
! 456: "engine '%s'", keyname, engine_id);
! 457: return NULL;
! 458: }
! 459:
! 460: switch (EVP_PKEY_base_id(key))
! 461: {
! 462: #ifndef OPENSSL_NO_RSA
! 463: case EVP_PKEY_RSA:
! 464: return openssl_rsa_private_key_create(key, TRUE);
! 465: #endif
! 466: #ifndef OPENSSL_NO_ECDSA
! 467: case EVP_PKEY_EC:
! 468: return openssl_ec_private_key_create(key, TRUE);
! 469: #endif
! 470: #if OPENSSL_VERSION_NUMBER >= 0x1010100fL && !defined(OPENSSL_NO_EC)
! 471: case EVP_PKEY_ED25519:
! 472: case EVP_PKEY_ED448:
! 473: return openssl_ed_private_key_create(key, TRUE);
! 474: #endif /* OPENSSL_VERSION_NUMBER */
! 475: default:
! 476: EVP_PKEY_free(key);
! 477: break;
! 478: }
! 479: #endif /* OPENSSL_NO_ENGINE */
! 480: return NULL;
! 481: }
! 482:
! 483: METHOD(plugin_t, get_name, char*,
! 484: private_openssl_plugin_t *this)
! 485: {
! 486: return "openssl";
! 487: }
! 488:
! 489: METHOD(plugin_t, get_features, int,
! 490: private_openssl_plugin_t *this, plugin_feature_t *features[])
! 491: {
! 492: static plugin_feature_t f[] = {
! 493: /* we provide OpenSSL threading callbacks */
! 494: PLUGIN_PROVIDE(CUSTOM, "openssl-threading"),
! 495: /* crypters */
! 496: PLUGIN_REGISTER(CRYPTER, openssl_crypter_create),
! 497: #ifndef OPENSSL_NO_AES
! 498: PLUGIN_PROVIDE(CRYPTER, ENCR_AES_CBC, 16),
! 499: PLUGIN_PROVIDE(CRYPTER, ENCR_AES_CBC, 24),
! 500: PLUGIN_PROVIDE(CRYPTER, ENCR_AES_CBC, 32),
! 501: PLUGIN_PROVIDE(CRYPTER, ENCR_AES_ECB, 16),
! 502: PLUGIN_PROVIDE(CRYPTER, ENCR_AES_ECB, 24),
! 503: PLUGIN_PROVIDE(CRYPTER, ENCR_AES_ECB, 32),
! 504: #endif
! 505: #ifndef OPENSSL_NO_CAMELLIA
! 506: PLUGIN_PROVIDE(CRYPTER, ENCR_CAMELLIA_CBC, 16),
! 507: PLUGIN_PROVIDE(CRYPTER, ENCR_CAMELLIA_CBC, 24),
! 508: PLUGIN_PROVIDE(CRYPTER, ENCR_CAMELLIA_CBC, 32),
! 509: #endif
! 510: #ifndef OPENSSL_NO_RC5
! 511: PLUGIN_PROVIDE(CRYPTER, ENCR_RC5, 0),
! 512: #endif
! 513: #ifndef OPENSSL_NO_CAST
! 514: PLUGIN_PROVIDE(CRYPTER, ENCR_CAST, 0),
! 515: #endif
! 516: #ifndef OPENSSL_NO_BLOWFISH
! 517: PLUGIN_PROVIDE(CRYPTER, ENCR_BLOWFISH, 0),
! 518: #endif
! 519: #ifndef OPENSSL_NO_IDEA
! 520: PLUGIN_PROVIDE(CRYPTER, ENCR_IDEA, 16),
! 521: #endif
! 522: #ifndef OPENSSL_NO_DES
! 523: PLUGIN_PROVIDE(CRYPTER, ENCR_3DES, 24),
! 524: PLUGIN_PROVIDE(CRYPTER, ENCR_DES, 8),
! 525: PLUGIN_PROVIDE(CRYPTER, ENCR_DES_ECB, 8),
! 526: #endif
! 527: PLUGIN_PROVIDE(CRYPTER, ENCR_NULL, 0),
! 528: /* hashers */
! 529: PLUGIN_REGISTER(HASHER, openssl_hasher_create),
! 530: #ifndef OPENSSL_NO_MD2
! 531: PLUGIN_PROVIDE(HASHER, HASH_MD2),
! 532: #endif
! 533: #ifndef OPENSSL_NO_MD4
! 534: PLUGIN_PROVIDE(HASHER, HASH_MD4),
! 535: #endif
! 536: #ifndef OPENSSL_NO_MD5
! 537: PLUGIN_PROVIDE(HASHER, HASH_MD5),
! 538: #endif
! 539: #ifndef OPENSSL_NO_SHA1
! 540: PLUGIN_PROVIDE(HASHER, HASH_SHA1),
! 541: #endif
! 542: #ifndef OPENSSL_NO_SHA256
! 543: PLUGIN_PROVIDE(HASHER, HASH_SHA224),
! 544: PLUGIN_PROVIDE(HASHER, HASH_SHA256),
! 545: #endif
! 546: #ifndef OPENSSL_NO_SHA512
! 547: PLUGIN_PROVIDE(HASHER, HASH_SHA384),
! 548: PLUGIN_PROVIDE(HASHER, HASH_SHA512),
! 549: #endif
! 550: /* SHA3/SHAKE was added with OpenSSL 1.1.1, it doesn't seem to be possible to
! 551: * disable it, defining the checked var prevents registration, though */
! 552: #if OPENSSL_VERSION_NUMBER >= 0x1010100fL && !defined(OPENSSL_NO_SHA3)
! 553: PLUGIN_PROVIDE(HASHER, HASH_SHA3_224),
! 554: PLUGIN_PROVIDE(HASHER, HASH_SHA3_256),
! 555: PLUGIN_PROVIDE(HASHER, HASH_SHA3_384),
! 556: PLUGIN_PROVIDE(HASHER, HASH_SHA3_512),
! 557: #endif
! 558: #if OPENSSL_VERSION_NUMBER >= 0x1010100fL && !defined(OPENSSL_NO_SHAKE)
! 559: PLUGIN_REGISTER(XOF, openssl_xof_create),
! 560: PLUGIN_PROVIDE(XOF, XOF_SHAKE_128),
! 561: PLUGIN_PROVIDE(XOF, XOF_SHAKE_256),
! 562: #endif
! 563: #ifndef OPENSSL_NO_SHA1
! 564: /* keyed sha1 hasher (aka prf) */
! 565: PLUGIN_REGISTER(PRF, openssl_sha1_prf_create),
! 566: PLUGIN_PROVIDE(PRF, PRF_KEYED_SHA1),
! 567: #endif
! 568: #ifndef OPENSSL_NO_HMAC
! 569: PLUGIN_REGISTER(PRF, openssl_hmac_prf_create),
! 570: #ifndef OPENSSL_NO_MD5
! 571: PLUGIN_PROVIDE(PRF, PRF_HMAC_MD5),
! 572: #endif
! 573: #ifndef OPENSSL_NO_SHA1
! 574: PLUGIN_PROVIDE(PRF, PRF_HMAC_SHA1),
! 575: #endif
! 576: #ifndef OPENSSL_NO_SHA256
! 577: PLUGIN_PROVIDE(PRF, PRF_HMAC_SHA2_256),
! 578: #endif
! 579: #ifndef OPENSSL_NO_SHA512
! 580: PLUGIN_PROVIDE(PRF, PRF_HMAC_SHA2_384),
! 581: PLUGIN_PROVIDE(PRF, PRF_HMAC_SHA2_512),
! 582: #endif
! 583: PLUGIN_REGISTER(SIGNER, openssl_hmac_signer_create),
! 584: #ifndef OPENSSL_NO_MD5
! 585: PLUGIN_PROVIDE(SIGNER, AUTH_HMAC_MD5_96),
! 586: PLUGIN_PROVIDE(SIGNER, AUTH_HMAC_MD5_128),
! 587: #endif
! 588: #ifndef OPENSSL_NO_SHA1
! 589: PLUGIN_PROVIDE(SIGNER, AUTH_HMAC_SHA1_96),
! 590: PLUGIN_PROVIDE(SIGNER, AUTH_HMAC_SHA1_128),
! 591: PLUGIN_PROVIDE(SIGNER, AUTH_HMAC_SHA1_160),
! 592: #endif
! 593: #ifndef OPENSSL_NO_SHA256
! 594: PLUGIN_PROVIDE(SIGNER, AUTH_HMAC_SHA2_256_128),
! 595: PLUGIN_PROVIDE(SIGNER, AUTH_HMAC_SHA2_256_256),
! 596: #endif
! 597: #ifndef OPENSSL_NO_SHA512
! 598: PLUGIN_PROVIDE(SIGNER, AUTH_HMAC_SHA2_384_192),
! 599: PLUGIN_PROVIDE(SIGNER, AUTH_HMAC_SHA2_384_384),
! 600: PLUGIN_PROVIDE(SIGNER, AUTH_HMAC_SHA2_512_256),
! 601: PLUGIN_PROVIDE(SIGNER, AUTH_HMAC_SHA2_512_512),
! 602: #endif
! 603: #endif /* OPENSSL_NO_HMAC */
! 604: #if (OPENSSL_VERSION_NUMBER >= 0x1000100fL && !defined(OPENSSL_NO_AES)) || \
! 605: (OPENSSL_VERSION_NUMBER >= 0x1010000fL && !defined(OPENSSL_NO_CHACHA))
! 606: /* AEAD (AES GCM since 1.0.1, ChaCha20-Poly1305 since 1.1.0) */
! 607: PLUGIN_REGISTER(AEAD, openssl_aead_create),
! 608: #ifndef OPENSSL_NO_AES
! 609: PLUGIN_PROVIDE(AEAD, ENCR_AES_GCM_ICV16, 16),
! 610: PLUGIN_PROVIDE(AEAD, ENCR_AES_GCM_ICV16, 24),
! 611: PLUGIN_PROVIDE(AEAD, ENCR_AES_GCM_ICV16, 32),
! 612: PLUGIN_PROVIDE(AEAD, ENCR_AES_GCM_ICV12, 16),
! 613: PLUGIN_PROVIDE(AEAD, ENCR_AES_GCM_ICV12, 24),
! 614: PLUGIN_PROVIDE(AEAD, ENCR_AES_GCM_ICV12, 32),
! 615: PLUGIN_PROVIDE(AEAD, ENCR_AES_GCM_ICV8, 16),
! 616: PLUGIN_PROVIDE(AEAD, ENCR_AES_GCM_ICV8, 24),
! 617: PLUGIN_PROVIDE(AEAD, ENCR_AES_GCM_ICV8, 32),
! 618: #endif /* OPENSSL_NO_AES */
! 619: #if OPENSSL_VERSION_NUMBER >= 0x1010000fL && !defined(OPENSSL_NO_CHACHA)
! 620: PLUGIN_PROVIDE(AEAD, ENCR_CHACHA20_POLY1305, 32),
! 621: #endif /* OPENSSL_NO_CHACHA */
! 622: #endif /* OPENSSL_VERSION_NUMBER */
! 623: #ifndef OPENSSL_NO_ECDH
! 624: /* EC DH groups */
! 625: PLUGIN_REGISTER(DH, openssl_ec_diffie_hellman_create),
! 626: PLUGIN_PROVIDE(DH, ECP_256_BIT),
! 627: PLUGIN_PROVIDE(DH, ECP_384_BIT),
! 628: PLUGIN_PROVIDE(DH, ECP_521_BIT),
! 629: PLUGIN_PROVIDE(DH, ECP_224_BIT),
! 630: PLUGIN_PROVIDE(DH, ECP_192_BIT),
! 631: PLUGIN_PROVIDE(DH, ECP_256_BP),
! 632: PLUGIN_PROVIDE(DH, ECP_384_BP),
! 633: PLUGIN_PROVIDE(DH, ECP_512_BP),
! 634: PLUGIN_PROVIDE(DH, ECP_224_BP),
! 635: #endif /* OPENSSL_NO_ECDH */
! 636: #ifndef OPENSSL_NO_DH
! 637: /* MODP DH groups */
! 638: PLUGIN_REGISTER(DH, openssl_diffie_hellman_create),
! 639: PLUGIN_PROVIDE(DH, MODP_3072_BIT),
! 640: PLUGIN_PROVIDE(DH, MODP_4096_BIT),
! 641: PLUGIN_PROVIDE(DH, MODP_6144_BIT),
! 642: PLUGIN_PROVIDE(DH, MODP_8192_BIT),
! 643: PLUGIN_PROVIDE(DH, MODP_2048_BIT),
! 644: PLUGIN_PROVIDE(DH, MODP_2048_224),
! 645: PLUGIN_PROVIDE(DH, MODP_2048_256),
! 646: PLUGIN_PROVIDE(DH, MODP_1536_BIT),
! 647: PLUGIN_PROVIDE(DH, MODP_1024_BIT),
! 648: PLUGIN_PROVIDE(DH, MODP_1024_160),
! 649: PLUGIN_PROVIDE(DH, MODP_768_BIT),
! 650: PLUGIN_PROVIDE(DH, MODP_CUSTOM),
! 651: #endif
! 652: #ifndef OPENSSL_NO_RSA
! 653: /* RSA private/public key loading */
! 654: PLUGIN_REGISTER(PRIVKEY, openssl_rsa_private_key_load, TRUE),
! 655: PLUGIN_PROVIDE(PRIVKEY, KEY_RSA),
! 656: PLUGIN_REGISTER(PRIVKEY_GEN, openssl_rsa_private_key_gen, FALSE),
! 657: PLUGIN_PROVIDE(PRIVKEY_GEN, KEY_RSA),
! 658: PLUGIN_REGISTER(PUBKEY, openssl_rsa_public_key_load, TRUE),
! 659: PLUGIN_PROVIDE(PUBKEY, KEY_RSA),
! 660: PLUGIN_REGISTER(PUBKEY, openssl_rsa_public_key_load, TRUE),
! 661: PLUGIN_PROVIDE(PUBKEY, KEY_ANY),
! 662: /* signature/encryption schemes */
! 663: PLUGIN_PROVIDE(PRIVKEY_SIGN, SIGN_RSA_EMSA_PKCS1_NULL),
! 664: PLUGIN_PROVIDE(PUBKEY_VERIFY, SIGN_RSA_EMSA_PKCS1_NULL),
! 665: #if OPENSSL_VERSION_NUMBER >= 0x10000000L
! 666: PLUGIN_PROVIDE(PRIVKEY_SIGN, SIGN_RSA_EMSA_PSS),
! 667: PLUGIN_PROVIDE(PUBKEY_VERIFY, SIGN_RSA_EMSA_PSS),
! 668: #endif
! 669: #ifndef OPENSSL_NO_SHA1
! 670: PLUGIN_PROVIDE(PRIVKEY_SIGN, SIGN_RSA_EMSA_PKCS1_SHA1),
! 671: PLUGIN_PROVIDE(PUBKEY_VERIFY, SIGN_RSA_EMSA_PKCS1_SHA1),
! 672: #endif
! 673: #ifndef OPENSSL_NO_SHA256
! 674: PLUGIN_PROVIDE(PRIVKEY_SIGN, SIGN_RSA_EMSA_PKCS1_SHA2_224),
! 675: PLUGIN_PROVIDE(PRIVKEY_SIGN, SIGN_RSA_EMSA_PKCS1_SHA2_256),
! 676: PLUGIN_PROVIDE(PUBKEY_VERIFY, SIGN_RSA_EMSA_PKCS1_SHA2_224),
! 677: PLUGIN_PROVIDE(PUBKEY_VERIFY, SIGN_RSA_EMSA_PKCS1_SHA2_256),
! 678: #endif
! 679: #ifndef OPENSSL_NO_SHA512
! 680: PLUGIN_PROVIDE(PRIVKEY_SIGN, SIGN_RSA_EMSA_PKCS1_SHA2_384),
! 681: PLUGIN_PROVIDE(PRIVKEY_SIGN, SIGN_RSA_EMSA_PKCS1_SHA2_512),
! 682: PLUGIN_PROVIDE(PUBKEY_VERIFY, SIGN_RSA_EMSA_PKCS1_SHA2_384),
! 683: PLUGIN_PROVIDE(PUBKEY_VERIFY, SIGN_RSA_EMSA_PKCS1_SHA2_512),
! 684: #endif
! 685: #ifndef OPENSSL_NO_MD5
! 686: PLUGIN_PROVIDE(PRIVKEY_SIGN, SIGN_RSA_EMSA_PKCS1_MD5),
! 687: PLUGIN_PROVIDE(PUBKEY_VERIFY, SIGN_RSA_EMSA_PKCS1_MD5),
! 688: #endif
! 689: PLUGIN_PROVIDE(PRIVKEY_DECRYPT, ENCRYPT_RSA_PKCS1),
! 690: PLUGIN_PROVIDE(PUBKEY_ENCRYPT, ENCRYPT_RSA_PKCS1),
! 691: #endif /* OPENSSL_NO_RSA */
! 692: /* certificate/CRL loading */
! 693: PLUGIN_REGISTER(CERT_DECODE, openssl_x509_load, TRUE),
! 694: PLUGIN_PROVIDE(CERT_DECODE, CERT_X509),
! 695: PLUGIN_SDEPEND(PUBKEY, KEY_RSA),
! 696: PLUGIN_SDEPEND(PUBKEY, KEY_ECDSA),
! 697: PLUGIN_SDEPEND(PUBKEY, KEY_DSA),
! 698: PLUGIN_REGISTER(CERT_DECODE, openssl_crl_load, TRUE),
! 699: PLUGIN_PROVIDE(CERT_DECODE, CERT_X509_CRL),
! 700: #if OPENSSL_VERSION_NUMBER >= 0x0090807fL
! 701: #ifndef OPENSSL_NO_CMS
! 702: PLUGIN_REGISTER(CONTAINER_DECODE, openssl_pkcs7_load, TRUE),
! 703: PLUGIN_PROVIDE(CONTAINER_DECODE, CONTAINER_PKCS7),
! 704: #endif /* OPENSSL_NO_CMS */
! 705: #endif /* OPENSSL_VERSION_NUMBER */
! 706: PLUGIN_REGISTER(CONTAINER_DECODE, openssl_pkcs12_load, TRUE),
! 707: PLUGIN_PROVIDE(CONTAINER_DECODE, CONTAINER_PKCS12),
! 708: #ifndef OPENSSL_NO_ECDSA
! 709: /* EC private/public key loading */
! 710: PLUGIN_REGISTER(PRIVKEY, openssl_ec_private_key_load, TRUE),
! 711: PLUGIN_PROVIDE(PRIVKEY, KEY_ECDSA),
! 712: PLUGIN_REGISTER(PRIVKEY_GEN, openssl_ec_private_key_gen, FALSE),
! 713: PLUGIN_PROVIDE(PRIVKEY_GEN, KEY_ECDSA),
! 714: PLUGIN_REGISTER(PUBKEY, openssl_ec_public_key_load, TRUE),
! 715: PLUGIN_PROVIDE(PUBKEY, KEY_ECDSA),
! 716: /* signature encryption schemes */
! 717: PLUGIN_PROVIDE(PRIVKEY_SIGN, SIGN_ECDSA_WITH_NULL),
! 718: PLUGIN_PROVIDE(PUBKEY_VERIFY, SIGN_ECDSA_WITH_NULL),
! 719: #ifndef OPENSSL_NO_SHA1
! 720: PLUGIN_PROVIDE(PRIVKEY_SIGN, SIGN_ECDSA_WITH_SHA1_DER),
! 721: PLUGIN_PROVIDE(PUBKEY_VERIFY, SIGN_ECDSA_WITH_SHA1_DER),
! 722: #endif
! 723: #ifndef OPENSSL_NO_SHA256
! 724: PLUGIN_PROVIDE(PRIVKEY_SIGN, SIGN_ECDSA_WITH_SHA256_DER),
! 725: PLUGIN_PROVIDE(PUBKEY_VERIFY, SIGN_ECDSA_WITH_SHA256_DER),
! 726: PLUGIN_PROVIDE(PRIVKEY_SIGN, SIGN_ECDSA_256),
! 727: PLUGIN_PROVIDE(PUBKEY_VERIFY, SIGN_ECDSA_256),
! 728: #endif
! 729: #ifndef OPENSSL_NO_SHA512
! 730: PLUGIN_PROVIDE(PRIVKEY_SIGN, SIGN_ECDSA_WITH_SHA384_DER),
! 731: PLUGIN_PROVIDE(PRIVKEY_SIGN, SIGN_ECDSA_WITH_SHA512_DER),
! 732: PLUGIN_PROVIDE(PUBKEY_VERIFY, SIGN_ECDSA_WITH_SHA384_DER),
! 733: PLUGIN_PROVIDE(PUBKEY_VERIFY, SIGN_ECDSA_WITH_SHA512_DER),
! 734: PLUGIN_PROVIDE(PRIVKEY_SIGN, SIGN_ECDSA_384),
! 735: PLUGIN_PROVIDE(PRIVKEY_SIGN, SIGN_ECDSA_521),
! 736: PLUGIN_PROVIDE(PUBKEY_VERIFY, SIGN_ECDSA_384),
! 737: PLUGIN_PROVIDE(PUBKEY_VERIFY, SIGN_ECDSA_521),
! 738: #endif
! 739: #endif /* OPENSSL_NO_ECDSA */
! 740: #if OPENSSL_VERSION_NUMBER >= 0x1010100fL && !defined(OPENSSL_NO_EC)
! 741: PLUGIN_REGISTER(DH, openssl_x_diffie_hellman_create),
! 742: /* available since 1.1.0a, but we require 1.1.1 features */
! 743: PLUGIN_PROVIDE(DH, CURVE_25519),
! 744: /* available since 1.1.1 */
! 745: PLUGIN_PROVIDE(DH, CURVE_448),
! 746: /* EdDSA private/public key loading */
! 747: PLUGIN_REGISTER(PUBKEY, openssl_ed_public_key_load, TRUE),
! 748: PLUGIN_PROVIDE(PUBKEY, KEY_ED25519),
! 749: PLUGIN_PROVIDE(PUBKEY, KEY_ED448),
! 750: PLUGIN_REGISTER(PRIVKEY, openssl_ed_private_key_load, TRUE),
! 751: PLUGIN_PROVIDE(PRIVKEY, KEY_ED25519),
! 752: PLUGIN_PROVIDE(PRIVKEY, KEY_ED448),
! 753: PLUGIN_REGISTER(PRIVKEY_GEN, openssl_ed_private_key_gen, FALSE),
! 754: PLUGIN_PROVIDE(PRIVKEY_GEN, KEY_ED25519),
! 755: PLUGIN_PROVIDE(PRIVKEY_GEN, KEY_ED448),
! 756: PLUGIN_PROVIDE(PRIVKEY_SIGN, SIGN_ED25519),
! 757: PLUGIN_PROVIDE(PRIVKEY_SIGN, SIGN_ED448),
! 758: PLUGIN_PROVIDE(PUBKEY_VERIFY, SIGN_ED25519),
! 759: PLUGIN_PROVIDE(PUBKEY_VERIFY, SIGN_ED448),
! 760: /* register a pro forma identity hasher, never instantiated */
! 761: PLUGIN_REGISTER(HASHER, return_null),
! 762: PLUGIN_PROVIDE(HASHER, HASH_IDENTITY),
! 763: #endif /* OPENSSL_VERSION_NUMBER && !OPENSSL_NO_EC */
! 764: /* generic key loader */
! 765: PLUGIN_REGISTER(PRIVKEY, openssl_private_key_load, TRUE),
! 766: PLUGIN_PROVIDE(PRIVKEY, KEY_ANY),
! 767: PLUGIN_REGISTER(PRIVKEY, openssl_private_key_connect, FALSE),
! 768: PLUGIN_PROVIDE(PRIVKEY, KEY_ANY),
! 769: PLUGIN_REGISTER(RNG, openssl_rng_create),
! 770: PLUGIN_PROVIDE(RNG, RNG_STRONG),
! 771: PLUGIN_PROVIDE(RNG, RNG_WEAK),
! 772: };
! 773: *features = f;
! 774: return countof(f);
! 775: }
! 776:
! 777: METHOD(plugin_t, destroy, void,
! 778: private_openssl_plugin_t *this)
! 779: {
! 780: /* OpenSSL 1.1.0 cleans up itself at exit and while OPENSSL_cleanup() exists we
! 781: * can't call it as we couldn't re-initialize the library (as required by the
! 782: * unit tests and the Android app) */
! 783: #if OPENSSL_VERSION_NUMBER < 0x10100000L
! 784: #ifndef OPENSSL_IS_BORINGSSL
! 785: CONF_modules_free();
! 786: OBJ_cleanup();
! 787: #endif
! 788: EVP_cleanup();
! 789: #ifndef OPENSSL_NO_ENGINE
! 790: ENGINE_cleanup();
! 791: #endif /* OPENSSL_NO_ENGINE */
! 792: CRYPTO_cleanup_all_ex_data();
! 793: threading_cleanup();
! 794: ERR_free_strings();
! 795: #endif /* OPENSSL_VERSION_NUMBER */
! 796:
! 797: free(this);
! 798: }
! 799:
! 800: /*
! 801: * see header file
! 802: */
! 803: plugin_t *openssl_plugin_create()
! 804: {
! 805: private_openssl_plugin_t *this;
! 806: int fips_mode;
! 807:
! 808: fips_mode = lib->settings->get_int(lib->settings,
! 809: "%s.plugins.openssl.fips_mode", FIPS_MODE, lib->ns);
! 810: #ifdef OPENSSL_FIPS
! 811: if (fips_mode)
! 812: {
! 813: if (FIPS_mode() != fips_mode && !FIPS_mode_set(fips_mode))
! 814: {
! 815: DBG1(DBG_LIB, "unable to set openssl FIPS mode(%d) from (%d)",
! 816: fips_mode, FIPS_mode());
! 817: return NULL;
! 818: }
! 819: }
! 820: #else
! 821: if (fips_mode)
! 822: {
! 823: DBG1(DBG_LIB, "openssl FIPS mode(%d) unavailable", fips_mode);
! 824: return NULL;
! 825: }
! 826: #endif
! 827:
! 828: INIT(this,
! 829: .public = {
! 830: .plugin = {
! 831: .get_name = _get_name,
! 832: .get_features = _get_features,
! 833: .destroy = _destroy,
! 834: },
! 835: },
! 836: );
! 837:
! 838: #if OPENSSL_VERSION_NUMBER >= 0x10100000L && !defined(LIBRESSL_VERSION_NUMBER)
! 839: /* note that we can't call OPENSSL_cleanup() when the plugin is destroyed
! 840: * as we couldn't initialize the library again afterwards */
! 841: OPENSSL_init_crypto(OPENSSL_INIT_LOAD_CONFIG |
! 842: OPENSSL_INIT_ENGINE_ALL_BUILTIN, NULL);
! 843: #else /* OPENSSL_VERSION_NUMBER */
! 844: threading_init();
! 845: #ifndef OPENSSL_IS_BORINGSSL
! 846: OPENSSL_config(NULL);
! 847: #endif
! 848: OpenSSL_add_all_algorithms();
! 849: #ifndef OPENSSL_NO_ENGINE
! 850: /* activate support for hardware accelerators */
! 851: ENGINE_load_builtin_engines();
! 852: ENGINE_register_all_complete();
! 853: #endif /* OPENSSL_NO_ENGINE */
! 854: #endif /* OPENSSL_VERSION_NUMBER */
! 855:
! 856: #ifdef OPENSSL_FIPS
! 857: /* we do this here as it may have been enabled via openssl.conf */
! 858: fips_mode = FIPS_mode();
! 859: dbg(DBG_LIB, strpfx(lib->ns, "charon") ? 1 : 2,
! 860: "openssl FIPS mode(%d) - %sabled ", fips_mode, fips_mode ? "en" : "dis");
! 861: #endif /* OPENSSL_FIPS */
! 862:
! 863: #if OPENSSL_VERSION_NUMBER < 0x1010100fL
! 864: if (!seed_rng())
! 865: {
! 866: DBG1(DBG_CFG, "no RNG found to seed OpenSSL");
! 867: destroy(this);
! 868: return NULL;
! 869: }
! 870: #endif /* OPENSSL_VERSION_NUMBER */
! 871:
! 872: return &this->public.plugin;
! 873: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>