- 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>
... | ... |
@@ -345,7 +345,7 @@ init_ssl (const struct options *options, struct tls_root_ctx *new_ctx) |
345 | 345 |
#ifdef MANAGMENT_EXTERNAL_KEY |
346 | 346 |
else if ((options->management_flags & MF_EXTERNAL_KEY) && options->cert_file) |
347 | 347 |
{ |
348 |
- X509 *my_cert = NULL; |
|
348 |
+ x509_cert_t *my_cert = NULL; |
|
349 | 349 |
tls_ctx_load_cert_file(new_ctx, options->cert_file, options->cert_file_inline, |
350 | 350 |
&my_cert); |
351 | 351 |
tls_ctx_use_external_private_key(new_ctx, my_cert); |
... | ... |
@@ -173,6 +173,8 @@ void tls_ctx_load_cryptoapi(struct tls_root_ctx *ctx, const char *cryptoapi_cert |
173 | 173 |
* Load certificate file into the given TLS context. If the given certificate |
174 | 174 |
* file contains a certificate chain, load the whole chain. |
175 | 175 |
* |
176 |
+ * If the x509 parameter is not NULL, the certificate will be returned in it. |
|
177 |
+ * |
|
176 | 178 |
* @param ctx TLS context to use |
177 | 179 |
* @param cert_file The file name to load the certificate from, or |
178 | 180 |
* "[[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, |
186 | 186 |
#if ENABLE_INLINE_FILES |
187 | 187 |
const char *cert_file_inline, |
188 | 188 |
#endif |
189 |
- X509 **x509 |
|
189 |
+ x509_cert_t **x509 |
|
190 | 190 |
); |
191 | 191 |
|
192 | 192 |
/** |
... | ... |
@@ -219,7 +221,7 @@ int tls_ctx_load_priv_file (struct tls_root_ctx *ctx, const char *priv_key_file |
219 | 219 |
* @return 1 if an error occurred, 0 if parsing was |
220 | 220 |
* successful. |
221 | 221 |
*/ |
222 |
-int tls_ctx_use_external_private_key (struct tls_root_ctx *ctx, X509 *cert); |
|
222 |
+int tls_ctx_use_external_private_key (struct tls_root_ctx *ctx, x509_cert_t *cert); |
|
223 | 223 |
|
224 | 224 |
#endif |
225 | 225 |
|
... | ... |
@@ -809,7 +809,41 @@ tls_ctx_load_ca (struct tls_root_ctx *ctx, const char *ca_file, |
809 | 809 |
msg (M_SSLERR, "Cannot load CA certificate file %s (SSL_load_client_CA_file)", ca_file); |
810 | 810 |
SSL_CTX_set_client_CA_list (ctx->ctx, cert_names); |
811 | 811 |
} |
812 |
+} |
|
813 |
+ |
|
812 | 814 |
|
815 |
+void |
|
816 |
+tls_ctx_load_extra_certs (struct tls_root_ctx *ctx, const char *extra_certs_file |
|
817 |
+#if ENABLE_INLINE_FILES |
|
818 |
+ , const char *extra_certs_file_inline |
|
819 |
+#endif |
|
820 |
+ ) |
|
821 |
+{ |
|
822 |
+ BIO *bio; |
|
823 |
+ X509 *cert; |
|
824 |
+#if ENABLE_INLINE_FILES |
|
825 |
+ if (!strcmp (extra_certs_file, INLINE_FILE_TAG) && extra_certs_file_inline) |
|
826 |
+ { |
|
827 |
+ bio = BIO_new_mem_buf ((char *)extra_certs_file_inline, -1); |
|
828 |
+ } |
|
829 |
+ else |
|
830 |
+#endif |
|
831 |
+ { |
|
832 |
+ bio = BIO_new(BIO_s_file()); |
|
833 |
+ if (BIO_read_filename(bio, extra_certs_file) <= 0) |
|
834 |
+ msg (M_SSLERR, "Cannot load extra-certs file: %s", extra_certs_file); |
|
835 |
+ } |
|
836 |
+ for (;;) |
|
837 |
+ { |
|
838 |
+ cert = NULL; |
|
839 |
+ if (!PEM_read_bio_X509 (bio, &cert, 0, NULL)) /* takes ownership of cert */ |
|
840 |
+ break; |
|
841 |
+ if (!cert) |
|
842 |
+ msg (M_SSLERR, "Error reading extra-certs certificate"); |
|
843 |
+ if (SSL_CTX_add_extra_chain_cert(ctx->ctx, cert) != 1) |
|
844 |
+ msg (M_SSLERR, "Error adding extra-certs certificate"); |
|
845 |
+ } |
|
846 |
+ BIO_free (bio); |
|
813 | 847 |
} |
814 | 848 |
|
815 | 849 |
/* ************************************** |
... | ... |
@@ -1099,11 +1133,9 @@ key_state_write_plaintext_const (struct key_state_ssl *ks_ssl, const uint8_t *da |
1099 | 1099 |
int ret = 0; |
1100 | 1100 |
perf_push (PERF_BIO_WRITE_PLAINTEXT); |
1101 | 1101 |
|
1102 |
-#ifdef USE_OPENSSL |
|
1103 | 1102 |
ASSERT (NULL != ks_ssl); |
1104 | 1103 |
|
1105 | 1104 |
ret = bio_write (ks_ssl->ssl_bio, data, len, "tls_write_plaintext_const"); |
1106 |
-#endif /* USE_OPENSSL */ |
|
1107 | 1105 |
|
1108 | 1106 |
perf_pop (); |
1109 | 1107 |
return ret; |
... | ... |
@@ -1116,11 +1148,9 @@ key_state_read_ciphertext (struct key_state_ssl *ks_ssl, struct buffer *buf, |
1116 | 1116 |
int ret = 0; |
1117 | 1117 |
perf_push (PERF_BIO_READ_CIPHERTEXT); |
1118 | 1118 |
|
1119 |
-#ifdef USE_OPENSSL |
|
1120 | 1119 |
ASSERT (NULL != ks_ssl); |
1121 | 1120 |
|
1122 | 1121 |
ret = bio_read (ks_ssl->ct_out, buf, maxlen, "tls_read_ciphertext"); |
1123 |
-#endif /* USE_OPENSSL */ |
|
1124 | 1122 |
|
1125 | 1123 |
perf_pop (); |
1126 | 1124 |
return ret; |
... | ... |
@@ -1132,12 +1162,10 @@ key_state_write_ciphertext (struct key_state_ssl *ks_ssl, struct buffer *buf) |
1132 | 1132 |
int ret = 0; |
1133 | 1133 |
perf_push (PERF_BIO_WRITE_CIPHERTEXT); |
1134 | 1134 |
|
1135 |
-#ifdef USE_OPENSSL |
|
1136 | 1135 |
ASSERT (NULL != ks_ssl); |
1137 | 1136 |
|
1138 | 1137 |
ret = bio_write (ks_ssl->ct_in, BPTR(buf), BLEN(buf), "tls_write_ciphertext"); |
1139 | 1138 |
bio_write_post (ret, buf); |
1140 |
-#endif /* USE_OPENSSL */ |
|
1141 | 1139 |
|
1142 | 1140 |
perf_pop (); |
1143 | 1141 |
return ret; |
... | ... |
@@ -1150,11 +1178,9 @@ key_state_read_plaintext (struct key_state_ssl *ks_ssl, struct buffer *buf, |
1150 | 1150 |
int ret = 0; |
1151 | 1151 |
perf_push (PERF_BIO_READ_PLAINTEXT); |
1152 | 1152 |
|
1153 |
-#ifdef USE_OPENSSL |
|
1154 | 1153 |
ASSERT (NULL != ks_ssl); |
1155 | 1154 |
|
1156 | 1155 |
ret = bio_read (ks_ssl->ssl_bio, buf, maxlen, "tls_read_plaintext"); |
1157 |
-#endif /* USE_OPENSSL */ |
|
1158 | 1156 |
|
1159 | 1157 |
perf_pop (); |
1160 | 1158 |
return ret; |
... | ... |
@@ -1210,40 +1236,6 @@ print_details (struct key_state_ssl * ks_ssl, const char *prefix) |
1210 | 1210 |
} |
1211 | 1211 |
|
1212 | 1212 |
void |
1213 |
-tls_ctx_load_extra_certs (struct tls_root_ctx *ctx, const char *extra_certs_file |
|
1214 |
-#if ENABLE_INLINE_FILES |
|
1215 |
- , const char *extra_certs_file_inline |
|
1216 |
-#endif |
|
1217 |
- ) |
|
1218 |
-{ |
|
1219 |
- BIO *bio; |
|
1220 |
- X509 *cert; |
|
1221 |
-#if ENABLE_INLINE_FILES |
|
1222 |
- if (!strcmp (extra_certs_file, INLINE_FILE_TAG) && extra_certs_file_inline) |
|
1223 |
- { |
|
1224 |
- bio = BIO_new_mem_buf ((char *)extra_certs_file_inline, -1); |
|
1225 |
- } |
|
1226 |
- else |
|
1227 |
-#endif |
|
1228 |
- { |
|
1229 |
- bio = BIO_new(BIO_s_file()); |
|
1230 |
- if (BIO_read_filename(bio, extra_certs_file) <= 0) |
|
1231 |
- msg (M_SSLERR, "Cannot load extra-certs file: %s", extra_certs_file); |
|
1232 |
- } |
|
1233 |
- for (;;) |
|
1234 |
- { |
|
1235 |
- cert = NULL; |
|
1236 |
- if (!PEM_read_bio_X509 (bio, &cert, 0, NULL)) /* takes ownership of cert */ |
|
1237 |
- break; |
|
1238 |
- if (!cert) |
|
1239 |
- msg (M_SSLERR, "Error reading extra-certs certificate"); |
|
1240 |
- if (SSL_CTX_add_extra_chain_cert(ctx->ctx, cert) != 1) |
|
1241 |
- msg (M_SSLERR, "Error adding extra-certs certificate"); |
|
1242 |
- } |
|
1243 |
- BIO_free (bio); |
|
1244 |
-} |
|
1245 |
- |
|
1246 |
-void |
|
1247 | 1213 |
show_available_tls_ciphers () |
1248 | 1214 |
{ |
1249 | 1215 |
SSL_CTX *ctx; |
... | ... |
@@ -433,9 +433,12 @@ verify_cert_set_env(struct env_set *es, x509_cert_t *peer_cert, int cert_depth, |
433 | 433 |
/* export X509 cert SHA1 fingerprint */ |
434 | 434 |
{ |
435 | 435 |
struct gc_arena gc = gc_new (); |
436 |
+ unsigned char *sha1_hash = x509_get_sha1_hash(peer_cert); |
|
437 |
+ |
|
436 | 438 |
openvpn_snprintf (envname, sizeof(envname), "tls_digest_%d", cert_depth); |
437 |
- setenv_str (es, envname, |
|
438 |
- format_hex_ex(peer_cert->sha1_hash, SHA_DIGEST_LENGTH, 0, 1, ":", &gc)); |
|
439 |
+ setenv_str (es, envname, format_hex_ex(sha1_hash, SHA_DIGEST_LENGTH, 0, 1, |
|
440 |
+ ":", &gc)); |
|
441 |
+ x509_free_sha1_hash(sha1_hash); |
|
439 | 442 |
gc_free(&gc); |
440 | 443 |
} |
441 | 444 |
#endif |
... | ... |
@@ -536,7 +539,7 @@ verify_cert_call_command(const char *verify_command, struct env_set *es, |
536 | 536 |
* check peer cert against CRL directory |
537 | 537 |
*/ |
538 | 538 |
static bool |
539 |
-verify_check_crl_dir(const char *crl_dir, X509 *cert) |
|
539 |
+verify_check_crl_dir(const char *crl_dir, x509_cert_t *cert) |
|
540 | 540 |
{ |
541 | 541 |
char fn[256]; |
542 | 542 |
int fd; |
... | ... |
@@ -615,11 +618,14 @@ verify_cert(struct tls_session *session, x509_cert_t *cert, int cert_depth) |
615 | 615 |
/* verify level 1 cert, i.e. the CA that signed our leaf cert */ |
616 | 616 |
if (cert_depth == 1 && opt->verify_hash) |
617 | 617 |
{ |
618 |
- if (memcmp (cert->sha1_hash, opt->verify_hash, SHA_DIGEST_LENGTH)) |
|
618 |
+ unsigned char *sha1_hash = x509_get_sha1_hash(cert); |
|
619 |
+ if (memcmp (sha1_hash, opt->verify_hash, SHA_DIGEST_LENGTH)) |
|
619 | 620 |
{ |
620 | 621 |
msg (D_TLS_ERRORS, "TLS Error: level-1 certificate hash verification failed"); |
622 |
+ x509_free_sha1_hash(sha1_hash); |
|
621 | 623 |
goto err; |
622 | 624 |
} |
625 |
+ x509_free_sha1_hash(sha1_hash); |
|
623 | 626 |
} |
624 | 627 |
|
625 | 628 |
/* save common name in session object */ |
... | ... |
@@ -73,7 +73,7 @@ void cert_hash_remember (struct tls_session *session, const int cert_depth, |
73 | 73 |
*/ |
74 | 74 |
|
75 | 75 |
/* |
76 |
- * Retrieve certificate's subject name, and place it in **subject. |
|
76 |
+ * Retrieve certificate's subject name. |
|
77 | 77 |
* |
78 | 78 |
* The returned string must be freed with \c verify_free_subject() |
79 | 79 |
* |
... | ... |
@@ -84,12 +84,30 @@ void cert_hash_remember (struct tls_session *session, const int cert_depth, |
84 | 84 |
char *x509_get_subject (x509_cert_t *cert); |
85 | 85 |
|
86 | 86 |
/* |
87 |
- * Free a subjectnumber string as returned by \c verify_get_subject() |
|
87 |
+ * Free a subject string as returned by \c verify_get_subject() |
|
88 | 88 |
* |
89 | 89 |
* @param subject The subject to be freed. |
90 | 90 |
*/ |
91 | 91 |
void x509_free_subject (char *subject); |
92 | 92 |
|
93 |
+/* Retrieve the certificate's SHA1 hash. |
|
94 |
+ * |
|
95 |
+ * The returned string must be freed with \c verify_free_sha1_hash() |
|
96 |
+ * |
|
97 |
+ * @param cert Certificate to retrieve the hash from. |
|
98 |
+ * |
|
99 |
+ * @return a string containing the SHA1 hash of the certificate |
|
100 |
+ */ |
|
101 |
+ |
|
102 |
+unsigned char *x509_get_sha1_hash (x509_cert_t *cert); |
|
103 |
+ |
|
104 |
+/* |
|
105 |
+ * Free a hash as returned by \c verify_get_hash() |
|
106 |
+ * |
|
107 |
+ * @param hash The subject to be freed. |
|
108 |
+ */ |
|
109 |
+void x509_free_sha1_hash (unsigned char *hash); |
|
110 |
+ |
|
93 | 111 |
/* |
94 | 112 |
* Retrieve the certificate's username from the specified field. |
95 | 113 |
* |
... | ... |
@@ -126,7 +144,9 @@ char *x509_get_serial (x509_cert_t *cert); |
126 | 126 |
void x509_free_serial (char *serial); |
127 | 127 |
|
128 | 128 |
/* |
129 |
- * TODO: document |
|
129 |
+ * Save X509 fields to environment, using the naming convention: |
|
130 |
+ * |
|
131 |
+ * X509_{cert_depth}_{name}={value} |
|
130 | 132 |
* |
131 | 133 |
* @param xt |
132 | 134 |
* @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); |
160 | 160 |
*/ |
161 | 161 |
bool x509_verify_ns_cert_type(const x509_cert_t *cert, const int usage); |
162 | 162 |
|
163 |
+#if OPENSSL_VERSION_NUMBER >= 0x00907000L || USE_POLARSSL |
|
164 |
+ |
|
163 | 165 |
/* |
164 | 166 |
* Verify X.509 key usage extension field. |
165 | 167 |
* |
... | ... |
@@ -188,6 +210,8 @@ bool x509_verify_cert_ku (x509_cert_t *x509, const unsigned * const expected_ku, |
188 | 188 |
*/ |
189 | 189 |
bool x509_verify_cert_eku (x509_cert_t *x509, const char * const expected_oid); |
190 | 190 |
|
191 |
+#endif |
|
192 |
+ |
|
191 | 193 |
/* |
192 | 194 |
* Store the given certificate in pem format in a temporary file in tmp_dir |
193 | 195 |
* |
... | ... |
@@ -37,6 +37,7 @@ verify_callback (int preverify_ok, X509_STORE_CTX * ctx) |
37 | 37 |
{ |
38 | 38 |
struct tls_session *session; |
39 | 39 |
SSL *ssl; |
40 |
+ unsigned char *sha1_hash = NULL; |
|
40 | 41 |
|
41 | 42 |
/* get the tls_session pointer */ |
42 | 43 |
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) |
44 | 44 |
session = (struct tls_session *) SSL_get_ex_data (ssl, mydata_index); |
45 | 45 |
ASSERT (session); |
46 | 46 |
|
47 |
- cert_hash_remember (session, ctx->error_depth, ctx->current_cert->sha1_hash); |
|
47 |
+ sha1_hash = x509_get_sha1_hash(ctx->current_cert); |
|
48 |
+ cert_hash_remember (session, ctx->error_depth, sha1_hash); |
|
49 |
+ x509_free_sha1_hash(sha1_hash); |
|
48 | 50 |
|
49 | 51 |
/* did peer present cert which was signed by our root cert? */ |
50 | 52 |
if (!preverify_ok) |
51 | 53 |
{ |
52 | 54 |
/* get the X509 name */ |
53 |
- char *subject = X509_NAME_oneline ( |
|
54 |
- X509_get_subject_name (ctx->current_cert), NULL, 0); |
|
55 |
+ char *subject = x509_get_serial(ctx->current_cert); |
|
55 | 56 |
|
56 | 57 |
if (subject) |
57 | 58 |
{ |
... | ... |
@@ -60,7 +62,7 @@ verify_callback (int preverify_ok, X509_STORE_CTX * ctx) |
60 | 60 |
ctx->error_depth, |
61 | 61 |
X509_verify_cert_error_string (ctx->error), |
62 | 62 |
subject); |
63 |
- free (subject); |
|
63 |
+ x509_free_subject(subject); |
|
64 | 64 |
} |
65 | 65 |
|
66 | 66 |
ERR_clear_error(); |
... | ... |
@@ -222,6 +224,21 @@ x509_free_serial (char *serial) |
222 | 222 |
OPENSSL_free(serial); |
223 | 223 |
} |
224 | 224 |
|
225 |
+unsigned char * |
|
226 |
+x509_get_sha1_hash (X509 *cert) |
|
227 |
+{ |
|
228 |
+ char *hash = malloc(SHA_DIGEST_LENGTH); |
|
229 |
+ memcpy(hash, cert->sha1_hash, SHA_DIGEST_LENGTH); |
|
230 |
+ return cert->sha1_hash; |
|
231 |
+} |
|
232 |
+ |
|
233 |
+void |
|
234 |
+x509_free_sha1_hash (unsigned char *hash) |
|
235 |
+{ |
|
236 |
+ if (hash) |
|
237 |
+ free(hash); |
|
238 |
+} |
|
239 |
+ |
|
225 | 240 |
char * |
226 | 241 |
x509_get_subject (X509 *cert) |
227 | 242 |
{ |