| 913 | } |
| 914 | |
| 915 | static bool |
| 916 | SSLPrivateKeyHandler(SSL_CTX *ctx, const char *keyPath, const char *secret_data, int secret_data_len) |
| 917 | { |
| 918 | EVP_PKEY *pkey = nullptr; |
| 919 | #if HAVE_ENGINE_GET_DEFAULT_RSA && HAVE_ENGINE_LOAD_PRIVATE_KEY |
| 920 | ENGINE *e = ENGINE_get_default_RSA(); |
| 921 | if (e != nullptr) { |
| 922 | pkey = ENGINE_load_private_key(e, keyPath, nullptr, nullptr); |
| 923 | if (pkey) { |
| 924 | if (!SSL_CTX_use_PrivateKey(ctx, pkey)) { |
| 925 | Dbg(dbg_ctl_ssl_load, "failed to load server private key from engine"); |
| 926 | EVP_PKEY_free(pkey); |
| 927 | return false; |
| 928 | } |
| 929 | } |
| 930 | } |
| 931 | #else |
| 932 | void *e = nullptr; |
| 933 | #endif |
| 934 | if (pkey == nullptr) { |
| 935 | scoped_BIO bio(BIO_new_mem_buf(secret_data, secret_data_len)); |
| 936 | |
| 937 | pem_password_cb *password_cb = SSL_CTX_get_default_passwd_cb(ctx); |
| 938 | void *u = SSL_CTX_get_default_passwd_cb_userdata(ctx); |
| 939 | pkey = PEM_read_bio_PrivateKey(bio.get(), nullptr, password_cb, u); |
| 940 | if (nullptr == pkey) { |
| 941 | Dbg(dbg_ctl_ssl_load, "failed to load server private key (%.*s) from %s", secret_data_len < 50 ? secret_data_len : 50, |
| 942 | secret_data, (!keyPath || keyPath[0] == '\0') ? "[empty key path]" : keyPath); |
| 943 | return false; |
| 944 | } |
| 945 | if (!SSL_CTX_use_PrivateKey(ctx, pkey)) { |
| 946 | Dbg(dbg_ctl_ssl_load, "failed to attach server private key loaded from %s", |
| 947 | (!keyPath || keyPath[0] == '\0') ? "[empty key path]" : keyPath); |
| 948 | EVP_PKEY_free(pkey); |
| 949 | return false; |
| 950 | } |
| 951 | if (e == nullptr && !SSL_CTX_check_private_key(ctx)) { |
| 952 | Dbg(dbg_ctl_ssl_load, "server private key does not match the certificate public key"); |
| 953 | return false; |
| 954 | } |
| 955 | } |
| 956 | |
| 957 | return true; |
| 958 | } |
| 959 | |
| 960 | /** |
| 961 | returns 0 on OK or negative value on failure and update log as appropriate. |