diff options
Diffstat (limited to 'ext/openssl/ossl_ssl.c')
-rw-r--r-- | ext/openssl/ossl_ssl.c | 35 |
1 files changed, 33 insertions, 2 deletions
diff --git a/ext/openssl/ossl_ssl.c b/ext/openssl/ossl_ssl.c index ee56edc0..d1eb977e 100644 --- a/ext/openssl/ossl_ssl.c +++ b/ext/openssl/ossl_ssl.c @@ -1354,14 +1354,45 @@ static VALUE ossl_sslctx_add_certificate_chain_file(VALUE self, VALUE certs_path, VALUE pkey_path) { SSL_CTX *ctx; + X509 *x509; + char *ccerts_path, *cpkey_path; + FILE *fp; + EVP_PKEY *pkey, *pub_pkey; GetSSLCTX(self, ctx); + /* Retrieve private key */ + cpkey_path = StringValueCStr(pkey_path); + fp = fopen(cpkey_path, "r"); + if (!fp) + rb_raise(rb_eArgError, "failed to open pkey file"); + pkey = PEM_read_PrivateKey(fp, NULL, 0, NULL); + fclose(fp); + if (!pkey) + rb_raise(rb_eArgError, "failed to open pkey file"); + /* Retrieve public key */ + ccerts_path = StringValueCStr(certs_path); + fp = fopen(ccerts_path, "r"); + if (!fp) + rb_raise(rb_eArgError, "failed to open certs file"); + x509 = PEM_read_X509(fp, NULL, 0, NULL); + fclose(fp); + if (!x509) + rb_raise(rb_eArgError, "failed to open certs file"); + pub_pkey = X509_get_pubkey(x509); + /* The reference counter is bumped, and decremented immediately. */ + EVP_PKEY_free(pub_pkey); + if (!pub_pkey) + rb_raise(rb_eArgError, "certificate does not contain public key"); + + if (EVP_PKEY_cmp(pub_pkey, pkey) != 1) + rb_raise(rb_eArgError, "public key mismatch"); + /* SSL_CTX_use_certificate_chain_file() loads PEM format file. */ - if (SSL_CTX_use_certificate_chain_file(ctx, StringValueCStr(certs_path)) != 1) + if (SSL_CTX_use_certificate_chain_file(ctx, ccerts_path) != 1) ossl_raise(eSSLError, "SSL_CTX_use_certificate_chain_file"); - if (SSL_CTX_use_PrivateKey_file(ctx, StringValueCStr(pkey_path), SSL_FILETYPE_PEM) != 1) + if (SSL_CTX_use_PrivateKey_file(ctx, cpkey_path, SSL_FILETYPE_PEM) != 1) ossl_raise(eSSLError, "SSL_CTX_use_PrivateKey_file"); return self; |