diff options
author | Adriaan de Jong <dejong@fox-it.com> | 2011-07-01 14:39:13 +0200 |
---|---|---|
committer | David Sommerseth <davids@redhat.com> | 2011-10-22 11:44:36 +0200 |
commit | fceecbab9ddd58ccec28aeafa7be39c65f313458 (patch) | |
tree | e8f261d594931caa3587f77d122e6be547f27326 | |
parent | a4da1fe776b774670948f00898d370da614960f5 (diff) | |
download | openvpn-fceecbab9ddd58ccec28aeafa7be39c65f313458.tar.gz openvpn-fceecbab9ddd58ccec28aeafa7be39c65f313458.tar.xz openvpn-fceecbab9ddd58ccec28aeafa7be39c65f313458.zip |
Final cleanup before PolarSSL addition:
- Remove stray X509 entries
- Remove unnecessary USE_OPENSSL ifdefs
- Normalised x509_get_sha1_hash to look similar to x509_get_* functions
Signed-off-by: Adriaan de Jong <dejong@fox-it.com>
Acked-by: James Yonan <james@openvpn.net>
Signed-off-by: David Sommerseth <davids@redhat.com>
-rw-r--r-- | ssl.c | 2 | ||||
-rw-r--r-- | ssl_backend.h | 6 | ||||
-rw-r--r-- | ssl_openssl.c | 76 | ||||
-rw-r--r-- | ssl_verify.c | 14 | ||||
-rw-r--r-- | ssl_verify_backend.h | 30 | ||||
-rw-r--r-- | ssl_verify_openssl.c | 25 |
6 files changed, 97 insertions, 56 deletions
@@ -345,7 +345,7 @@ init_ssl (const struct options *options, struct tls_root_ctx *new_ctx) #ifdef MANAGMENT_EXTERNAL_KEY else if ((options->management_flags & MF_EXTERNAL_KEY) && options->cert_file) { - X509 *my_cert = NULL; + x509_cert_t *my_cert = NULL; tls_ctx_load_cert_file(new_ctx, options->cert_file, options->cert_file_inline, &my_cert); tls_ctx_use_external_private_key(new_ctx, my_cert); diff --git a/ssl_backend.h b/ssl_backend.h index b0c9a6d..324fc33 100644 --- a/ssl_backend.h +++ b/ssl_backend.h @@ -173,6 +173,8 @@ void tls_ctx_load_cryptoapi(struct tls_root_ctx *ctx, const char *cryptoapi_cert * Load certificate file into the given TLS context. If the given certificate * file contains a certificate chain, load the whole chain. * + * If the x509 parameter is not NULL, the certificate will be returned in it. + * * @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. @@ -186,7 +188,7 @@ 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 + x509_cert_t **x509 ); /** @@ -219,7 +221,7 @@ int tls_ctx_load_priv_file (struct tls_root_ctx *ctx, const char *priv_key_file * @return 1 if an error occurred, 0 if parsing was * successful. */ -int tls_ctx_use_external_private_key (struct tls_root_ctx *ctx, X509 *cert); +int tls_ctx_use_external_private_key (struct tls_root_ctx *ctx, x509_cert_t *cert); #endif diff --git a/ssl_openssl.c b/ssl_openssl.c index ca3f01d..35f9b14 100644 --- a/ssl_openssl.c +++ b/ssl_openssl.c @@ -809,7 +809,41 @@ tls_ctx_load_ca (struct tls_root_ctx *ctx, const char *ca_file, msg (M_SSLERR, "Cannot load CA certificate file %s (SSL_load_client_CA_file)", ca_file); SSL_CTX_set_client_CA_list (ctx->ctx, cert_names); } +} + +void +tls_ctx_load_extra_certs (struct tls_root_ctx *ctx, const char *extra_certs_file +#if ENABLE_INLINE_FILES + , const char *extra_certs_file_inline +#endif + ) +{ + BIO *bio; + X509 *cert; +#if ENABLE_INLINE_FILES + if (!strcmp (extra_certs_file, INLINE_FILE_TAG) && extra_certs_file_inline) + { + bio = BIO_new_mem_buf ((char *)extra_certs_file_inline, -1); + } + else +#endif + { + bio = BIO_new(BIO_s_file()); + if (BIO_read_filename(bio, extra_certs_file) <= 0) + msg (M_SSLERR, "Cannot load extra-certs file: %s", extra_certs_file); + } + for (;;) + { + cert = NULL; + if (!PEM_read_bio_X509 (bio, &cert, 0, NULL)) /* takes ownership of cert */ + break; + if (!cert) + msg (M_SSLERR, "Error reading extra-certs certificate"); + if (SSL_CTX_add_extra_chain_cert(ctx->ctx, cert) != 1) + msg (M_SSLERR, "Error adding extra-certs certificate"); + } + BIO_free (bio); } /* ************************************** @@ -1099,11 +1133,9 @@ key_state_write_plaintext_const (struct key_state_ssl *ks_ssl, const uint8_t *da int ret = 0; perf_push (PERF_BIO_WRITE_PLAINTEXT); -#ifdef USE_OPENSSL ASSERT (NULL != ks_ssl); ret = bio_write (ks_ssl->ssl_bio, data, len, "tls_write_plaintext_const"); -#endif /* USE_OPENSSL */ perf_pop (); return ret; @@ -1116,11 +1148,9 @@ key_state_read_ciphertext (struct key_state_ssl *ks_ssl, struct buffer *buf, int ret = 0; perf_push (PERF_BIO_READ_CIPHERTEXT); -#ifdef USE_OPENSSL ASSERT (NULL != ks_ssl); ret = bio_read (ks_ssl->ct_out, buf, maxlen, "tls_read_ciphertext"); -#endif /* USE_OPENSSL */ perf_pop (); return ret; @@ -1132,12 +1162,10 @@ key_state_write_ciphertext (struct key_state_ssl *ks_ssl, struct buffer *buf) int ret = 0; perf_push (PERF_BIO_WRITE_CIPHERTEXT); -#ifdef USE_OPENSSL ASSERT (NULL != ks_ssl); ret = bio_write (ks_ssl->ct_in, BPTR(buf), BLEN(buf), "tls_write_ciphertext"); bio_write_post (ret, buf); -#endif /* USE_OPENSSL */ perf_pop (); return ret; @@ -1150,11 +1178,9 @@ key_state_read_plaintext (struct key_state_ssl *ks_ssl, struct buffer *buf, int ret = 0; perf_push (PERF_BIO_READ_PLAINTEXT); -#ifdef USE_OPENSSL ASSERT (NULL != ks_ssl); ret = bio_read (ks_ssl->ssl_bio, buf, maxlen, "tls_read_plaintext"); -#endif /* USE_OPENSSL */ perf_pop (); return ret; @@ -1210,40 +1236,6 @@ print_details (struct key_state_ssl * ks_ssl, const char *prefix) } void -tls_ctx_load_extra_certs (struct tls_root_ctx *ctx, const char *extra_certs_file -#if ENABLE_INLINE_FILES - , const char *extra_certs_file_inline -#endif - ) -{ - BIO *bio; - X509 *cert; -#if ENABLE_INLINE_FILES - if (!strcmp (extra_certs_file, INLINE_FILE_TAG) && extra_certs_file_inline) - { - bio = BIO_new_mem_buf ((char *)extra_certs_file_inline, -1); - } - else -#endif - { - bio = BIO_new(BIO_s_file()); - if (BIO_read_filename(bio, extra_certs_file) <= 0) - msg (M_SSLERR, "Cannot load extra-certs file: %s", extra_certs_file); - } - for (;;) - { - cert = NULL; - if (!PEM_read_bio_X509 (bio, &cert, 0, NULL)) /* takes ownership of cert */ - break; - if (!cert) - msg (M_SSLERR, "Error reading extra-certs certificate"); - if (SSL_CTX_add_extra_chain_cert(ctx->ctx, cert) != 1) - msg (M_SSLERR, "Error adding extra-certs certificate"); - } - BIO_free (bio); -} - -void show_available_tls_ciphers () { SSL_CTX *ctx; diff --git a/ssl_verify.c b/ssl_verify.c index 804abe7..ac5c03b 100644 --- a/ssl_verify.c +++ b/ssl_verify.c @@ -433,9 +433,12 @@ verify_cert_set_env(struct env_set *es, x509_cert_t *peer_cert, int cert_depth, /* export X509 cert SHA1 fingerprint */ { struct gc_arena gc = gc_new (); + unsigned char *sha1_hash = x509_get_sha1_hash(peer_cert); + openvpn_snprintf (envname, sizeof(envname), "tls_digest_%d", cert_depth); - setenv_str (es, envname, - format_hex_ex(peer_cert->sha1_hash, SHA_DIGEST_LENGTH, 0, 1, ":", &gc)); + setenv_str (es, envname, format_hex_ex(sha1_hash, SHA_DIGEST_LENGTH, 0, 1, + ":", &gc)); + x509_free_sha1_hash(sha1_hash); gc_free(&gc); } #endif @@ -536,7 +539,7 @@ verify_cert_call_command(const char *verify_command, struct env_set *es, * check peer cert against CRL directory */ static bool -verify_check_crl_dir(const char *crl_dir, X509 *cert) +verify_check_crl_dir(const char *crl_dir, x509_cert_t *cert) { char fn[256]; int fd; @@ -615,11 +618,14 @@ verify_cert(struct tls_session *session, x509_cert_t *cert, int cert_depth) /* verify level 1 cert, i.e. the CA that signed our leaf cert */ if (cert_depth == 1 && opt->verify_hash) { - if (memcmp (cert->sha1_hash, opt->verify_hash, SHA_DIGEST_LENGTH)) + unsigned char *sha1_hash = x509_get_sha1_hash(cert); + if (memcmp (sha1_hash, opt->verify_hash, SHA_DIGEST_LENGTH)) { msg (D_TLS_ERRORS, "TLS Error: level-1 certificate hash verification failed"); + x509_free_sha1_hash(sha1_hash); goto err; } + x509_free_sha1_hash(sha1_hash); } /* save common name in session object */ diff --git a/ssl_verify_backend.h b/ssl_verify_backend.h index cab847d..f3773b3 100644 --- a/ssl_verify_backend.h +++ b/ssl_verify_backend.h @@ -73,7 +73,7 @@ void cert_hash_remember (struct tls_session *session, const int cert_depth, */ /* - * Retrieve certificate's subject name, and place it in **subject. + * Retrieve certificate's subject name. * * The returned string must be freed with \c verify_free_subject() * @@ -84,12 +84,30 @@ void cert_hash_remember (struct tls_session *session, const int cert_depth, char *x509_get_subject (x509_cert_t *cert); /* - * Free a subjectnumber string as returned by \c verify_get_subject() + * Free a subject string as returned by \c verify_get_subject() * * @param subject The subject to be freed. */ void x509_free_subject (char *subject); +/* Retrieve the certificate's SHA1 hash. + * + * The returned string must be freed with \c verify_free_sha1_hash() + * + * @param cert Certificate to retrieve the hash from. + * + * @return a string containing the SHA1 hash of the certificate + */ + +unsigned char *x509_get_sha1_hash (x509_cert_t *cert); + +/* + * Free a hash as returned by \c verify_get_hash() + * + * @param hash The subject to be freed. + */ +void x509_free_sha1_hash (unsigned char *hash); + /* * Retrieve the certificate's username from the specified field. * @@ -126,7 +144,9 @@ char *x509_get_serial (x509_cert_t *cert); void x509_free_serial (char *serial); /* - * TODO: document + * Save X509 fields to environment, using the naming convention: + * + * X509_{cert_depth}_{name}={value} * * @param xt * @param es Environment set to save variables in @@ -160,6 +180,8 @@ void x509_setenv (struct env_set *es, int cert_depth, x509_cert_t *cert); */ bool x509_verify_ns_cert_type(const x509_cert_t *cert, const int usage); +#if OPENSSL_VERSION_NUMBER >= 0x00907000L || USE_POLARSSL + /* * Verify X.509 key usage extension field. * @@ -188,6 +210,8 @@ bool x509_verify_cert_ku (x509_cert_t *x509, const unsigned * const expected_ku, */ bool x509_verify_cert_eku (x509_cert_t *x509, const char * const expected_oid); +#endif + /* * Store the given certificate in pem format in a temporary file in tmp_dir * diff --git a/ssl_verify_openssl.c b/ssl_verify_openssl.c index f6d27b1..1d32255 100644 --- a/ssl_verify_openssl.c +++ b/ssl_verify_openssl.c @@ -37,6 +37,7 @@ verify_callback (int preverify_ok, X509_STORE_CTX * ctx) { struct tls_session *session; SSL *ssl; + unsigned char *sha1_hash = NULL; /* get the tls_session pointer */ ssl = X509_STORE_CTX_get_ex_data (ctx, SSL_get_ex_data_X509_STORE_CTX_idx()); @@ -44,14 +45,15 @@ verify_callback (int preverify_ok, X509_STORE_CTX * ctx) session = (struct tls_session *) SSL_get_ex_data (ssl, mydata_index); ASSERT (session); - cert_hash_remember (session, ctx->error_depth, ctx->current_cert->sha1_hash); + sha1_hash = x509_get_sha1_hash(ctx->current_cert); + cert_hash_remember (session, ctx->error_depth, sha1_hash); + x509_free_sha1_hash(sha1_hash); /* did peer present cert which was signed by our root cert? */ if (!preverify_ok) { /* get the X509 name */ - char *subject = X509_NAME_oneline ( - X509_get_subject_name (ctx->current_cert), NULL, 0); + char *subject = x509_get_serial(ctx->current_cert); if (subject) { @@ -60,7 +62,7 @@ verify_callback (int preverify_ok, X509_STORE_CTX * ctx) ctx->error_depth, X509_verify_cert_error_string (ctx->error), subject); - free (subject); + x509_free_subject(subject); } ERR_clear_error(); @@ -222,6 +224,21 @@ x509_free_serial (char *serial) OPENSSL_free(serial); } +unsigned char * +x509_get_sha1_hash (X509 *cert) +{ + char *hash = malloc(SHA_DIGEST_LENGTH); + memcpy(hash, cert->sha1_hash, SHA_DIGEST_LENGTH); + return cert->sha1_hash; +} + +void +x509_free_sha1_hash (unsigned char *hash) +{ + if (hash) + free(hash); +} + char * x509_get_subject (X509 *cert) { |