From: Adriaan de Jong Date: Wed, 29 Jun 2011 15:59:55 +0000 (+0200) Subject: Refactored load certificate functions X-Git-Tag: v2.3-alpha1~148 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=f4047d7420bac6bce5e8862771f0c20d42ba68ed;p=thirdparty%2Fopenvpn.git Refactored load certificate functions Signed-off-by: Adriaan de Jong Acked-by: James Yonan Signed-off-by: David Sommerseth --- diff --git a/ssl.c b/ssl.c index a308598ec..343097211 100644 --- a/ssl.c +++ b/ssl.c @@ -1734,63 +1734,6 @@ use_external_private_key (SSL_CTX *ssl_ctx, X509 *cert) return 0; } -/* - * Basically a clone of SSL_CTX_use_certificate_file, but also return - * the x509 object. - */ -static int -use_certificate_file(SSL_CTX *ctx, const char *file, int type, X509 **x509) -{ - int j; - BIO *in; - int ret=0; - X509 *x=NULL; - - in=BIO_new(BIO_s_file_internal()); - if (in == NULL) - { - SSLerr(SSL_F_SSL_CTX_USE_CERTIFICATE_FILE,ERR_R_BUF_LIB); - goto end; - } - - if (BIO_read_filename(in,file) <= 0) - { - SSLerr(SSL_F_SSL_CTX_USE_CERTIFICATE_FILE,ERR_R_SYS_LIB); - goto end; - } - if (type == SSL_FILETYPE_ASN1) - { - j=ERR_R_ASN1_LIB; - x=d2i_X509_bio(in,NULL); - } - else if (type == SSL_FILETYPE_PEM) - { - j=ERR_R_PEM_LIB; - x=PEM_read_bio_X509(in,NULL,ctx->default_passwd_callback,ctx->default_passwd_callback_userdata); - } - else - { - SSLerr(SSL_F_SSL_CTX_USE_CERTIFICATE_FILE,SSL_R_BAD_SSL_FILETYPE); - goto end; - } - - if (x == NULL) - { - SSLerr(SSL_F_SSL_CTX_USE_CERTIFICATE_FILE,j); - goto end; - } - - ret=SSL_CTX_use_certificate(ctx,x); - end: - if (in != NULL) - BIO_free(in); - if (x509) - *x509 = x; - else if (x) - X509_free (x); - return(ret); -} - #endif #if ENABLE_INLINE_FILES @@ -1899,36 +1842,6 @@ use_inline_load_client_CA_file (SSL_CTX *ctx, const char *ca_string) return(ret); } -static int -use_inline_certificate_file (SSL_CTX *ctx, const char *cert_string, X509 **x509) -{ - BIO *in = NULL; - X509 *x = NULL; - int ret = 0; - - in = BIO_new_mem_buf ((char *)cert_string, -1); - if (!in) - goto end; - - x = PEM_read_bio_X509 (in, - NULL, - ctx->default_passwd_callback, - ctx->default_passwd_callback_userdata); - if (!x) - goto end; - - ret = SSL_CTX_use_certificate(ctx, x); - - end: - if (in) - BIO_free (in); - if (x509) - *x509 = x; - else if (x) - X509_free (x); - return ret; -} - static int use_inline_PrivateKey_file (SSL_CTX *ctx, const char *key_string) { @@ -1967,7 +1880,6 @@ void init_ssl (const struct options *options, struct tls_root_ctx *new_ctx) { SSL_CTX *ctx = NULL; - bool using_cert_file = false; ASSERT(NULL != new_ctx); @@ -2006,43 +1918,29 @@ init_ssl (const struct options *options, struct tls_root_ctx *new_ctx) tls_ctx_load_cryptoapi(new_ctx, options->cryptoapi_cert); } #endif - else - { - X509 *my_cert = NULL; - - /* Load Certificate */ - if (options->cert_file) - { -#if ENABLE_INLINE_FILES - if (!strcmp (options->cert_file, INLINE_FILE_TAG) && options->cert_file_inline) - { - if (!use_inline_certificate_file (ctx, options->cert_file_inline, &my_cert)) - msg (M_SSLERR, "Cannot load inline certificate file"); - } - else -#endif - { #ifdef MANAGMENT_EXTERNAL_KEY - if (!use_certificate_file (ctx, options->cert_file, SSL_FILETYPE_PEM, &my_cert)) -#else - if (!SSL_CTX_use_certificate_file (ctx, options->cert_file, SSL_FILETYPE_PEM)) -#endif - msg (M_SSLERR, "Cannot load certificate file %s", options->cert_file); - using_cert_file = true; - } - } + else if (options->management_flags & MF_EXTERNAL_KEY) + { + X509 *my_cert = NULL; -#ifdef MANAGMENT_EXTERNAL_KEY - if (options->management_flags & MF_EXTERNAL_KEY) - { - ASSERT (my_cert); - if (!use_external_private_key(ctx, my_cert)) - msg (M_SSLERR, "Cannot enable SSL external private key capability"); - if (my_cert) - X509_free(my_cert); - } - else + if (options->cert_file) + { + tls_ctx_load_cert_file(new_ctx, options->cert_file, options->cert_file_inline, &my_cert); + } + ASSERT (my_cert); + if (!use_external_private_key(new_ctx->ctx, my_cert)) + msg (M_SSLERR, "Cannot enable SSL external private key capability"); + X509_free(my_cert); + } #endif + else + { + /* Use seperate PEM files for key, cert and CA certs */ + /* Load Certificate */ + if (options->cert_file) + { + tls_ctx_load_cert_file(new_ctx, options->cert_file, options->cert_file_inline, NULL); + } /* Load Private Key */ if (options->priv_key_file) @@ -2135,13 +2033,6 @@ init_ssl (const struct options *options, struct tls_root_ctx *new_ctx) } } - /* Enable the use of certificate chains */ - if (using_cert_file) - { - if (!SSL_CTX_use_certificate_chain_file (ctx, options->cert_file)) - msg (M_SSLERR, "Cannot load certificate chain file %s (SSL_use_certificate_chain_file)", options->cert_file); - } - /* Load extra certificates that are part of our own certificate chain but shouldn't be included in the verify chain */ if (options->extra_certs_file || options->extra_certs_file_inline) diff --git a/ssl_backend.h b/ssl_backend.h index 127647f09..0af14697b 100644 --- a/ssl_backend.h +++ b/ssl_backend.h @@ -172,6 +172,26 @@ int tls_ctx_load_pkcs11(struct tls_root_ctx *ctx, void tls_ctx_load_cryptoapi(struct tls_root_ctx *ctx, const char *cryptoapi_cert); #endif /* WIN32 */ +/** + * Load certificate file into the given TLS context. If the given certificate + * file contains a certificate chain, load the whole chain. + * + * @param ctx TLS context to use + * @param cert_file The file name to load the certificate from, or + * "[[INLINE]]" in the case of inline files. + * @param cert_file_inline A string containing the certificate + * @param x509 An optional certificate, if x509 is NULL, + * do nothing, if x509 is not NULL, *x509 will be + * allocated and filled with the loaded certificate. + * *x509 must be NULL. + */ +void tls_ctx_load_cert_file (struct tls_root_ctx *ctx, const char *cert_file, +#if ENABLE_INLINE_FILES + const char *cert_file_inline, +#endif + X509 **x509 + ); + /** * Show the TLS ciphers that are available for us to use in the OpenSSL * library. diff --git a/ssl_openssl.c b/ssl_openssl.c index e774f56df..5980080ef 100644 --- a/ssl_openssl.c +++ b/ssl_openssl.c @@ -343,6 +343,101 @@ tls_ctx_load_cryptoapi(struct tls_root_ctx *ctx, const char *cryptoapi_cert) } #endif /* WIN32 */ +/* + * Based on SSL_CTX_use_certificate_file, return an x509 object for the + * given file. + */ +static int +tls_ctx_read_certificate_file(SSL_CTX *ctx, const char *file, X509 **x509) +{ + int j; + BIO *in; + int ret=0; + X509 *x=NULL; + + in=BIO_new(BIO_s_file_internal()); + if (in == NULL) + { + SSLerr(SSL_F_SSL_CTX_USE_CERTIFICATE_FILE, ERR_R_BUF_LIB); + goto end; + } + + if (BIO_read_filename(in,file) <= 0) + { + SSLerr(SSL_F_SSL_CTX_USE_CERTIFICATE_FILE, ERR_R_SYS_LIB); + goto end; + } + + x = PEM_read_bio_X509(in, NULL, ctx->default_passwd_callback, + ctx->default_passwd_callback_userdata); + if (x == NULL) + { + SSLerr(SSL_F_SSL_CTX_USE_CERTIFICATE_FILE, ERR_R_PEM_LIB); + goto end; + } + + end: + if (in != NULL) + BIO_free(in); + if (x509) + *x509 = x; + else if (x) + X509_free (x); + return(ret); +} + +void +tls_ctx_load_cert_file (struct tls_root_ctx *ctx, const char *cert_file, +#if ENABLE_INLINE_FILES + const char *cert_file_inline, +#endif + X509 **x509 + ) +{ + ASSERT(NULL != ctx); + if (NULL != x509) + ASSERT(NULL == *x509); + +#if ENABLE_INLINE_FILES + if (!strcmp (cert_file, INLINE_FILE_TAG) && cert_file_inline) + { + BIO *in = NULL; + X509 *x = NULL; + int ret = 0; + + in = BIO_new_mem_buf ((char *)cert_file_inline, -1); + if (in) + { + x = PEM_read_bio_X509 (in, + NULL, + ctx->ctx->default_passwd_callback, + ctx->ctx->default_passwd_callback_userdata); + BIO_free (in); + if (x) { + ret = SSL_CTX_use_certificate(ctx->ctx, x); + if (x509) + *x509 = x; + else + X509_free (x); + } + } + + if (!ret) + msg (M_SSLERR, "Cannot load inline certificate file"); + } + else +#endif /* ENABLE_INLINE_FILES */ + { + if (!SSL_CTX_use_certificate_chain_file (ctx->ctx, cert_file)) + msg (M_SSLERR, "Cannot load certificate file %s", cert_file); + if (x509) + { + if (!tls_ctx_read_certificate_file(ctx->ctx, cert_file, x509)) + msg (M_SSLERR, "Cannot load certificate file %s", cert_file); + } + } +} + void show_available_tls_ciphers () {