Signed-off-by: Adriaan de Jong <dejong@fox-it.com>
Acked-by: Gert Doering <gert@greenie.muc.de>
Acked-by: James Yonan <james@openvpn.net>
Signed-off-by: David Sommerseth <davids@redhat.com>
... | ... |
@@ -1989,86 +1989,9 @@ init_ssl (const struct options *options, struct tls_root_ctx *new_ctx) |
1989 | 1989 |
|
1990 | 1990 |
if (options->pkcs12_file) |
1991 | 1991 |
{ |
1992 |
- /* Use PKCS #12 file for key, cert and CA certs */ |
|
1993 |
- |
|
1994 |
- FILE *fp; |
|
1995 |
- EVP_PKEY *pkey; |
|
1996 |
- X509 *cert; |
|
1997 |
- STACK_OF(X509) *ca = NULL; |
|
1998 |
- PKCS12 *p12=NULL; |
|
1999 |
- int i; |
|
2000 |
- char password[256]; |
|
2001 |
- |
|
2002 |
-#if ENABLE_INLINE_FILES |
|
2003 |
- if (!strcmp (options->pkcs12_file, INLINE_FILE_TAG) && options->pkcs12_file_inline) |
|
2004 |
- { |
|
2005 |
- BIO *b64 = BIO_new (BIO_f_base64()); |
|
2006 |
- BIO *bio = BIO_new_mem_buf ((void *)options->pkcs12_file_inline, (int)strlen(options->pkcs12_file_inline)); |
|
2007 |
- ASSERT(b64 && bio); |
|
2008 |
- BIO_push (b64, bio); |
|
2009 |
- p12 = d2i_PKCS12_bio(b64, NULL); |
|
2010 |
- if (!p12) |
|
2011 |
- msg (M_SSLERR, "Error reading inline PKCS#12 file"); |
|
2012 |
- BIO_free (b64); |
|
2013 |
- BIO_free (bio); |
|
2014 |
- } |
|
2015 |
- else |
|
2016 |
-#endif |
|
2017 |
- { |
|
2018 |
- /* Load the PKCS #12 file */ |
|
2019 |
- if (!(fp = fopen(options->pkcs12_file, "rb"))) |
|
2020 |
- msg (M_SSLERR, "Error opening file %s", options->pkcs12_file); |
|
2021 |
- p12 = d2i_PKCS12_fp(fp, NULL); |
|
2022 |
- fclose (fp); |
|
2023 |
- if (!p12) |
|
2024 |
- msg (M_SSLERR, "Error reading PKCS#12 file %s", options->pkcs12_file); |
|
2025 |
- } |
|
2026 |
- |
|
2027 |
- /* Parse the PKCS #12 file */ |
|
2028 |
- if (!PKCS12_parse(p12, "", &pkey, &cert, &ca)) |
|
2029 |
- { |
|
2030 |
- pem_password_callback (password, sizeof(password) - 1, 0, NULL); |
|
2031 |
- /* Reparse the PKCS #12 file with password */ |
|
2032 |
- ca = NULL; |
|
2033 |
- if (!PKCS12_parse(p12, password, &pkey, &cert, &ca)) |
|
2034 |
- { |
|
2035 |
-#ifdef ENABLE_MANAGEMENT |
|
2036 |
- if (management && (ERR_GET_REASON (ERR_peek_error()) == PKCS12_R_MAC_VERIFY_FAILURE)) |
|
2037 |
- management_auth_failure (management, UP_TYPE_PRIVATE_KEY, NULL); |
|
2038 |
-#endif |
|
2039 |
- PKCS12_free(p12); |
|
2040 |
- goto err; |
|
2041 |
- } |
|
2042 |
- } |
|
2043 |
- PKCS12_free(p12); |
|
2044 |
- |
|
2045 |
- /* Load Certificate */ |
|
2046 |
- if (!SSL_CTX_use_certificate (ctx, cert)) |
|
2047 |
- msg (M_SSLERR, "Cannot use certificate"); |
|
2048 |
- |
|
2049 |
- /* Load Private Key */ |
|
2050 |
- if (!SSL_CTX_use_PrivateKey (ctx, pkey)) |
|
2051 |
- msg (M_SSLERR, "Cannot use private key"); |
|
2052 |
- warn_if_group_others_accessible (options->pkcs12_file); |
|
2053 |
- |
|
2054 |
- /* Check Private Key */ |
|
2055 |
- if (!SSL_CTX_check_private_key (ctx)) |
|
2056 |
- msg (M_SSLERR, "Private key does not match the certificate"); |
|
2057 |
- |
|
2058 |
- /* Set Certificate Verification chain */ |
|
2059 |
- if (!options->ca_file) |
|
2060 |
- { |
|
2061 |
- if (ca && sk_X509_num(ca)) |
|
2062 |
- { |
|
2063 |
- for (i = 0; i < sk_X509_num(ca); i++) |
|
2064 |
- { |
|
2065 |
- if (!X509_STORE_add_cert(ctx->cert_store,sk_X509_value(ca, i))) |
|
2066 |
- msg (M_SSLERR, "Cannot add certificate to certificate chain (X509_STORE_add_cert)"); |
|
2067 |
- if (options->tls_server && !SSL_CTX_add_client_CA(ctx, sk_X509_value(ca, i))) |
|
2068 |
- msg (M_SSLERR, "Cannot add certificate to client CA list (SSL_CTX_add_client_CA)"); |
|
2069 |
- } |
|
2070 |
- } |
|
2071 |
- } |
|
1992 |
+ if (0 != tls_ctx_load_pkcs12(new_ctx, options->pkcs12_file, |
|
1993 |
+ options->pkcs12_file_inline, !options->ca_file)) |
|
1994 |
+ goto err; |
|
2072 | 1995 |
} |
2073 | 1996 |
else |
2074 | 1997 |
{ |
... | ... |
@@ -57,10 +57,6 @@ |
57 | 57 |
/* Used in the TLS PRF function */ |
58 | 58 |
#define KEY_EXPANSION_ID "OpenVPN" |
59 | 59 |
|
60 |
-/* passwords */ |
|
61 |
-#define UP_TYPE_AUTH "Auth" |
|
62 |
-#define UP_TYPE_PRIVATE_KEY "Private Key" |
|
63 |
- |
|
64 | 60 |
/* packet opcode (high 5 bits) and key-id (low 3 bits) are combined in one byte */ |
65 | 61 |
#define P_KEY_ID_MASK 0x07 |
66 | 62 |
#define P_OPCODE_SHIFT 3 |
... | ... |
@@ -116,7 +116,7 @@ bool tls_ctx_initialised(struct tls_root_ctx *ctx); |
116 | 116 |
*/ |
117 | 117 |
void tls_ctx_set_options (struct tls_root_ctx *ctx, unsigned int ssl_flags); |
118 | 118 |
|
119 |
-/* |
|
119 |
+/** |
|
120 | 120 |
* Load Diffie Hellman Parameters, and load them into the library-specific |
121 | 121 |
* TLS context. |
122 | 122 |
* |
... | ... |
@@ -131,7 +131,26 @@ void tls_ctx_load_dh_params(struct tls_root_ctx *ctx, const char *dh_file |
131 | 131 |
#endif /* ENABLE_INLINE_FILES */ |
132 | 132 |
); |
133 | 133 |
|
134 |
-/* |
|
134 |
+/** |
|
135 |
+ * Load PKCS #12 file for key, cert and (optionally) CA certs, and add to |
|
136 |
+ * library-specific TLS context. |
|
137 |
+ * |
|
138 |
+ * @param ctx TLS context to use |
|
139 |
+ * @param pkcs12_file The file name to load the information from, or |
|
140 |
+ * "[[INLINE]]" in the case of inline files. |
|
141 |
+ * @param pkcs12_file_inline A string containing the information |
|
142 |
+ * |
|
143 |
+ * @return 1 if an error occurred, 0 if parsing was |
|
144 |
+ * successful. |
|
145 |
+ */ |
|
146 |
+int tls_ctx_load_pkcs12(struct tls_root_ctx *ctx, const char *pkcs12_file, |
|
147 |
+#if ENABLE_INLINE_FILES |
|
148 |
+ const char *pkcs12_file_inline, |
|
149 |
+#endif /* ENABLE_INLINE_FILES */ |
|
150 |
+ bool load_ca_file |
|
151 |
+ ); |
|
152 |
+ |
|
153 |
+/** |
|
135 | 154 |
* Show the TLS ciphers that are available for us to use in the OpenSSL |
136 | 155 |
* library. |
137 | 156 |
*/ |
... | ... |
@@ -38,6 +38,10 @@ |
38 | 38 |
|
39 | 39 |
#include "ssl_backend.h" |
40 | 40 |
|
41 |
+/* passwords */ |
|
42 |
+#define UP_TYPE_AUTH "Auth" |
|
43 |
+#define UP_TYPE_PRIVATE_KEY "Private Key" |
|
44 |
+ |
|
41 | 45 |
/* configuration file boolean options */ |
42 | 46 |
# define SSLF_CLIENT_CERT_NOT_REQUIRED (1<<0) |
43 | 47 |
# define SSLF_USERNAME_AS_COMMON_NAME (1<<1) |
... | ... |
@@ -221,6 +221,98 @@ tls_ctx_load_dh_params (struct tls_root_ctx *ctx, const char *dh_file |
221 | 221 |
DH_free (dh); |
222 | 222 |
} |
223 | 223 |
|
224 |
+int |
|
225 |
+tls_ctx_load_pkcs12(struct tls_root_ctx *ctx, const char *pkcs12_file, |
|
226 |
+#if ENABLE_INLINE_FILES |
|
227 |
+ const char *pkcs12_file_inline, |
|
228 |
+#endif /* ENABLE_INLINE_FILES */ |
|
229 |
+ bool load_ca_file |
|
230 |
+ ) |
|
231 |
+{ |
|
232 |
+ FILE *fp; |
|
233 |
+ EVP_PKEY *pkey; |
|
234 |
+ X509 *cert; |
|
235 |
+ STACK_OF(X509) *ca = NULL; |
|
236 |
+ PKCS12 *p12; |
|
237 |
+ int i; |
|
238 |
+ char password[256]; |
|
239 |
+ |
|
240 |
+ ASSERT(NULL != ctx); |
|
241 |
+ |
|
242 |
+#if ENABLE_INLINE_FILES |
|
243 |
+ if (!strcmp (pkcs12_file, INLINE_FILE_TAG) && pkcs12_file_inline) |
|
244 |
+ { |
|
245 |
+ BIO *b64 = BIO_new(BIO_f_base64()); |
|
246 |
+ BIO *bio = BIO_new_mem_buf((void *) pkcs12_file_inline, |
|
247 |
+ (int) strlen(pkcs12_file_inline)); |
|
248 |
+ ASSERT(b64 && bio); |
|
249 |
+ BIO_push(b64, bio); |
|
250 |
+ p12 = d2i_PKCS12_bio(b64, NULL); |
|
251 |
+ if (!p12) |
|
252 |
+ msg(M_SSLERR, "Error reading inline PKCS#12 file"); |
|
253 |
+ BIO_free(b64); |
|
254 |
+ BIO_free(bio); |
|
255 |
+ } |
|
256 |
+ else |
|
257 |
+#endif |
|
258 |
+ { |
|
259 |
+ /* Load the PKCS #12 file */ |
|
260 |
+ if (!(fp = fopen(pkcs12_file, "rb"))) |
|
261 |
+ msg(M_SSLERR, "Error opening file %s", pkcs12_file); |
|
262 |
+ p12 = d2i_PKCS12_fp(fp, NULL); |
|
263 |
+ fclose(fp); |
|
264 |
+ if (!p12) |
|
265 |
+ msg(M_SSLERR, "Error reading PKCS#12 file %s", pkcs12_file); |
|
266 |
+ } |
|
267 |
+ |
|
268 |
+ /* Parse the PKCS #12 file */ |
|
269 |
+ if (!PKCS12_parse(p12, "", &pkey, &cert, &ca)) |
|
270 |
+ { |
|
271 |
+ pem_password_callback (password, sizeof(password) - 1, 0, NULL); |
|
272 |
+ /* Reparse the PKCS #12 file with password */ |
|
273 |
+ ca = NULL; |
|
274 |
+ if (!PKCS12_parse(p12, password, &pkey, &cert, &ca)) |
|
275 |
+ { |
|
276 |
+#ifdef ENABLE_MANAGEMENT |
|
277 |
+ if (management && (ERR_GET_REASON (ERR_peek_error()) == PKCS12_R_MAC_VERIFY_FAILURE)) |
|
278 |
+ management_auth_failure (management, UP_TYPE_PRIVATE_KEY, NULL); |
|
279 |
+#endif |
|
280 |
+ PKCS12_free(p12); |
|
281 |
+ return 1; |
|
282 |
+ } |
|
283 |
+ } |
|
284 |
+ PKCS12_free(p12); |
|
285 |
+ |
|
286 |
+ /* Load Certificate */ |
|
287 |
+ if (!SSL_CTX_use_certificate (ctx->ctx, cert)) |
|
288 |
+ msg (M_SSLERR, "Cannot use certificate"); |
|
289 |
+ |
|
290 |
+ /* Load Private Key */ |
|
291 |
+ if (!SSL_CTX_use_PrivateKey (ctx->ctx, pkey)) |
|
292 |
+ msg (M_SSLERR, "Cannot use private key"); |
|
293 |
+ warn_if_group_others_accessible (pkcs12_file); |
|
294 |
+ |
|
295 |
+ /* Check Private Key */ |
|
296 |
+ if (!SSL_CTX_check_private_key (ctx->ctx)) |
|
297 |
+ msg (M_SSLERR, "Private key does not match the certificate"); |
|
298 |
+ |
|
299 |
+ /* Set Certificate Verification chain */ |
|
300 |
+ if (load_ca_file) |
|
301 |
+ { |
|
302 |
+ if (ca && sk_X509_num(ca)) |
|
303 |
+ { |
|
304 |
+ for (i = 0; i < sk_X509_num(ca); i++) |
|
305 |
+ { |
|
306 |
+ if (!X509_STORE_add_cert(ctx->ctx->cert_store,sk_X509_value(ca, i))) |
|
307 |
+ msg (M_SSLERR, "Cannot add certificate to certificate chain (X509_STORE_add_cert)"); |
|
308 |
+ if (!SSL_CTX_add_client_CA(ctx->ctx, sk_X509_value(ca, i))) |
|
309 |
+ msg (M_SSLERR, "Cannot add certificate to client CA list (SSL_CTX_add_client_CA)"); |
|
310 |
+ } |
|
311 |
+ } |
|
312 |
+ } |
|
313 |
+ return 0; |
|
314 |
+} |
|
315 |
+ |
|
224 | 316 |
void |
225 | 317 |
show_available_tls_ciphers () |
226 | 318 |
{ |