summaryrefslogtreecommitdiffstats
path: root/modules/ssl/ssl_util_ssl.c
diff options
context:
space:
mode:
Diffstat (limited to 'modules/ssl/ssl_util_ssl.c')
-rw-r--r--modules/ssl/ssl_util_ssl.c180
1 files changed, 128 insertions, 52 deletions
diff --git a/modules/ssl/ssl_util_ssl.c b/modules/ssl/ssl_util_ssl.c
index b7f0eca..44930b7 100644
--- a/modules/ssl/ssl_util_ssl.c
+++ b/modules/ssl/ssl_util_ssl.c
@@ -74,7 +74,7 @@ void modssl_set_app_data2(SSL *ssl, void *arg)
** _________________________________________________________________
*/
-EVP_PKEY *modssl_read_privatekey(const char* filename, EVP_PKEY **key, pem_password_cb *cb, void *s)
+EVP_PKEY *modssl_read_privatekey(const char *filename, pem_password_cb *cb, void *s)
{
EVP_PKEY *rc;
BIO *bioS;
@@ -83,7 +83,7 @@ EVP_PKEY *modssl_read_privatekey(const char* filename, EVP_PKEY **key, pem_passw
/* 1. try PEM (= DER+Base64+headers) */
if ((bioS=BIO_new_file(filename, "r")) == NULL)
return NULL;
- rc = PEM_read_bio_PrivateKey(bioS, key, cb, s);
+ rc = PEM_read_bio_PrivateKey(bioS, NULL, cb, s);
BIO_free(bioS);
if (rc == NULL) {
@@ -107,41 +107,9 @@ EVP_PKEY *modssl_read_privatekey(const char* filename, EVP_PKEY **key, pem_passw
BIO_free(bioS);
}
}
- if (rc != NULL && key != NULL) {
- if (*key != NULL)
- EVP_PKEY_free(*key);
- *key = rc;
- }
return rc;
}
-typedef struct {
- const char *pass;
- int pass_len;
-} pass_ctx;
-
-static int provide_pass(char *buf, int size, int rwflag, void *baton)
-{
- pass_ctx *ctx = baton;
- if (ctx->pass_len > 0) {
- if (ctx->pass_len < size) {
- size = (int)ctx->pass_len;
- }
- memcpy(buf, ctx->pass, size);
- }
- return ctx->pass_len;
-}
-
-EVP_PKEY *modssl_read_encrypted_pkey(const char *filename, EVP_PKEY **key,
- const char *pass, apr_size_t pass_len)
-{
- pass_ctx ctx;
-
- ctx.pass = pass;
- ctx.pass_len = pass_len;
- return modssl_read_privatekey(filename, key, provide_pass, &ctx);
-}
-
/* _________________________________________________________________
**
** Smart shutdown
@@ -156,7 +124,7 @@ int modssl_smart_shutdown(SSL *ssl)
/*
* Repeat the calls, because SSL_shutdown internally dispatches through a
- * little state machine. Usually only one or two interation should be
+ * little state machine. Usually only one or two iterations should be
* needed, so we restrict the total number of restrictions in order to
* avoid process hangs in case the client played bad with the socket
* connection and OpenSSL cannot recognize it.
@@ -166,7 +134,7 @@ int modssl_smart_shutdown(SSL *ssl)
for (i = 0; i < 4 /* max 2x pending + 2x data = 4 */; i++) {
rc = SSL_shutdown(ssl);
if (rc >= 0 && flush && (SSL_get_shutdown(ssl) & SSL_SENT_SHUTDOWN)) {
- /* Once the close notity is sent through the output filters,
+ /* Once the close notify is sent through the output filters,
* ensure it is flushed through the socket.
*/
if (BIO_flush(SSL_get_wbio(ssl)) <= 0) {
@@ -217,14 +185,27 @@ BOOL modssl_X509_getBC(X509 *cert, int *ca, int *pathlen)
return TRUE;
}
+char *modssl_bio_free_read(apr_pool_t *p, BIO *bio)
+{
+ int len = BIO_pending(bio);
+ char *result = NULL;
+
+ if (len > 0) {
+ result = apr_palloc(p, len+1);
+ len = BIO_read(bio, result, len);
+ result[len] = NUL;
+ }
+ BIO_free(bio);
+ return result;
+}
+
/* Convert ASN.1 string to a pool-allocated char * string, escaping
* control characters. If raw is zero, convert to UTF-8, otherwise
* unchanged from the character set. */
static char *asn1_string_convert(apr_pool_t *p, ASN1_STRING *asn1str, int raw)
{
- char *result = NULL;
BIO *bio;
- int len, flags = ASN1_STRFLGS_ESC_CTRL;
+ int flags = ASN1_STRFLGS_ESC_CTRL;
if ((bio = BIO_new(BIO_s_mem())) == NULL)
return NULL;
@@ -232,14 +213,8 @@ static char *asn1_string_convert(apr_pool_t *p, ASN1_STRING *asn1str, int raw)
if (!raw) flags |= ASN1_STRFLGS_UTF8_CONVERT;
ASN1_STRING_print_ex(bio, asn1str, flags);
- len = BIO_pending(bio);
- if (len > 0) {
- result = apr_palloc(p, len+1);
- len = BIO_read(bio, result, len);
- result[len] = NUL;
- }
- BIO_free(bio);
- return result;
+
+ return modssl_bio_free_read(p, bio);
}
#define asn1_string_to_utf8(p, a) asn1_string_convert(p, a, 0)
@@ -489,29 +464,52 @@ BOOL modssl_X509_match_name(apr_pool_t *p, X509 *x509, const char *name,
** _________________________________________________________________
*/
-DH *ssl_dh_GetParamFromFile(const char *file)
+#if OPENSSL_VERSION_NUMBER < 0x30000000L
+DH *modssl_dh_from_file(const char *file)
{
- DH *dh = NULL;
+ DH *dh;
BIO *bio;
if ((bio = BIO_new_file(file, "r")) == NULL)
return NULL;
dh = PEM_read_bio_DHparams(bio, NULL, NULL, NULL);
BIO_free(bio);
- return (dh);
+
+ return dh;
+}
+#else
+EVP_PKEY *modssl_dh_pkey_from_file(const char *file)
+{
+ EVP_PKEY *pkey;
+ BIO *bio;
+
+ if ((bio = BIO_new_file(file, "r")) == NULL)
+ return NULL;
+ pkey = PEM_read_bio_Parameters(bio, NULL);
+ BIO_free(bio);
+
+ return pkey;
}
+#endif
#ifdef HAVE_ECC
-EC_GROUP *ssl_ec_GetParamFromFile(const char *file)
+EC_GROUP *modssl_ec_group_from_file(const char *file)
{
- EC_GROUP *group = NULL;
+ EC_GROUP *group;
BIO *bio;
if ((bio = BIO_new_file(file, "r")) == NULL)
return NULL;
+#if OPENSSL_VERSION_NUMBER < 0x30000000L
group = PEM_read_bio_ECPKParameters(bio, NULL, NULL, NULL);
+#else
+ group = PEM_ASN1_read_bio((void *)d2i_ECPKParameters,
+ PEM_STRING_ECPARAMETERS, bio,
+ NULL, NULL, NULL);
+#endif
BIO_free(bio);
- return (group);
+
+ return group;
}
#endif
@@ -536,3 +534,81 @@ char *modssl_SSL_SESSION_id2sz(IDCONST unsigned char *id, int idlen,
return str;
}
+
+/* _________________________________________________________________
+**
+** Certificate/Key Stuff
+** _________________________________________________________________
+*/
+
+apr_status_t modssl_read_cert(apr_pool_t *p,
+ const char *cert_pem, const char *key_pem,
+ pem_password_cb *cb, void *ud,
+ X509 **pcert, EVP_PKEY **pkey)
+{
+ BIO *in;
+ X509 *x = NULL;
+ EVP_PKEY *key = NULL;
+ apr_status_t rv = APR_SUCCESS;
+
+ in = BIO_new_mem_buf(cert_pem, -1);
+ if (in == NULL) {
+ rv = APR_ENOMEM;
+ goto cleanup;
+ }
+
+ x = PEM_read_bio_X509(in, NULL, cb, ud);
+ if (x == NULL) {
+ rv = APR_ENOENT;
+ goto cleanup;
+ }
+
+ BIO_free(in);
+ in = BIO_new_mem_buf(key_pem? key_pem : cert_pem, -1);
+ if (in == NULL) {
+ rv = APR_ENOMEM;
+ goto cleanup;
+ }
+ key = PEM_read_bio_PrivateKey(in, NULL, cb, ud);
+ if (key == NULL) {
+ rv = APR_ENOENT;
+ goto cleanup;
+ }
+
+cleanup:
+ if (rv == APR_SUCCESS) {
+ *pcert = x;
+ *pkey = key;
+ }
+ else {
+ *pcert = NULL;
+ *pkey = NULL;
+ if (x) X509_free(x);
+ if (key) EVP_PKEY_free(key);
+ }
+ if (in != NULL) BIO_free(in);
+ return rv;
+}
+
+apr_status_t modssl_cert_get_pem(apr_pool_t *p,
+ X509 *cert1, X509 *cert2,
+ const char **ppem)
+{
+ apr_status_t rv = APR_ENOMEM;
+ BIO *bio;
+
+ if ((bio = BIO_new(BIO_s_mem())) == NULL) goto cleanup;
+ if (PEM_write_bio_X509(bio, cert1) != 1) goto cleanup;
+ if (cert2 && PEM_write_bio_X509(bio, cert2) != 1) goto cleanup;
+ rv = APR_SUCCESS;
+
+cleanup:
+ if (rv != APR_SUCCESS) {
+ *ppem = NULL;
+ if (bio) BIO_free(bio);
+ }
+ else {
+ *ppem = modssl_bio_free_read(p, bio);
+ }
+ return rv;
+}