While crl files can change regulary and it is usually not a good idea to
statically include them into config files, handling multiple files and
updating files on mobile devices is tiresome/problematic. Inlining a static
version of the crl file is better in these use cases than to use no crl at
all.
OpenVPN 3 already supports inlining crl-verify, so <crl-verify> is already
used in config files.
V2: Fixed PolarSSL and made formatting respect the 80 column limit
V3: Accidentally reverted one change too much in V2
Acked-by: Steffan Karger <steffan.karger@fox-it.com>
Message-Id: <1457293149-10526-1-git-send-email-arne@rfc2549.org>
URL: http://article.gmane.org/gmane.network.openvpn.devel/11337
Signed-off-by: Gert Doering <gert@greenie.muc.de>
... | ... |
@@ -6490,7 +6490,8 @@ X509_1_C=KG |
6490 | 6490 |
.\"********************************************************* |
6491 | 6491 |
.SH INLINE FILE SUPPORT |
6492 | 6492 |
OpenVPN allows including files in the main configuration for the |
6493 |
-.B \-\-ca, \-\-cert, \-\-dh, \-\-extra\-certs, \-\-key, \-\-pkcs12, \-\-secret |
|
6493 |
+.B \-\-ca, \-\-cert, \-\-dh, \-\-extra\-certs, \-\-key, \-\-pkcs12, \-\-secret, |
|
6494 |
+.B \-\-crl-verify |
|
6494 | 6495 |
and |
6495 | 6496 |
.B \-\-tls\-auth |
6496 | 6497 |
options. |
... | ... |
@@ -2323,6 +2323,7 @@ do_init_crypto_tls (struct context *c, const unsigned int flags) |
2323 | 2323 |
to.verify_x509_type = (options->verify_x509_type & 0xff); |
2324 | 2324 |
to.verify_x509_name = options->verify_x509_name; |
2325 | 2325 |
to.crl_file = options->crl_file; |
2326 |
+ to.crl_file_inline = options->crl_file_inline; |
|
2326 | 2327 |
to.ssl_flags = options->ssl_flags; |
2327 | 2328 |
to.ns_cert_type = options->ns_cert_type; |
2328 | 2329 |
memmove (to.remote_cert_ku, options->remote_cert_ku, sizeof (to.remote_cert_ku)); |
... | ... |
@@ -2747,8 +2747,8 @@ options_postprocess_filechecks (struct options *options) |
2747 | 2747 |
errs |= check_file_access_chroot (options->chroot_dir, CHKACC_FILE, options->crl_file, R_OK|X_OK, |
2748 | 2748 |
"--crl-verify directory"); |
2749 | 2749 |
else |
2750 |
- errs |= check_file_access_chroot (options->chroot_dir, CHKACC_FILE, options->crl_file, R_OK, |
|
2751 |
- "--crl-verify"); |
|
2750 |
+ errs |= check_file_access_chroot (options->chroot_dir, CHKACC_FILE|CHKACC_INLINE, |
|
2751 |
+ options->crl_file, R_OK, "--crl-verify"); |
|
2752 | 2752 |
|
2753 | 2753 |
errs |= check_file_access (CHKACC_FILE|CHKACC_INLINE, options->tls_auth_file, R_OK, |
2754 | 2754 |
"--tls-auth"); |
... | ... |
@@ -6783,12 +6783,17 @@ add_option (struct options *options, |
6783 | 6783 |
VERIFY_PERMISSION (OPT_P_GENERAL); |
6784 | 6784 |
options->cipher_list = p[1]; |
6785 | 6785 |
} |
6786 |
- else if (streq (p[0], "crl-verify") && p[1] && ((p[2] && streq(p[2], "dir")) || !p[2]) && !p[3]) |
|
6786 |
+ else if (streq (p[0], "crl-verify") && p[1] && ((p[2] && streq(p[2], "dir")) |
|
6787 |
+ || (p[2] && streq (p[1], INLINE_FILE_TAG) ) || !p[2]) && !p[3]) |
|
6787 | 6788 |
{ |
6788 | 6789 |
VERIFY_PERMISSION (OPT_P_GENERAL); |
6789 | 6790 |
if (p[2] && streq(p[2], "dir")) |
6790 | 6791 |
options->ssl_flags |= SSLF_CRL_VERIFY_DIR; |
6791 | 6792 |
options->crl_file = p[1]; |
6793 |
+ if (streq (p[1], INLINE_FILE_TAG) && p[2]) |
|
6794 |
+ { |
|
6795 |
+ options->crl_file_inline = p[2]; |
|
6796 |
+ } |
|
6792 | 6797 |
} |
6793 | 6798 |
else if (streq (p[0], "tls-verify") && p[1]) |
6794 | 6799 |
{ |
... | ... |
@@ -511,6 +511,7 @@ struct options |
511 | 511 |
const char *ca_file_inline; |
512 | 512 |
const char *cert_file_inline; |
513 | 513 |
const char *extra_certs_file_inline; |
514 |
+ const char *crl_file_inline; |
|
514 | 515 |
char *priv_key_file_inline; |
515 | 516 |
const char *dh_file_inline; |
516 | 517 |
const char *pkcs12_file_inline; /* contains the base64 encoding of pkcs12 file */ |
... | ... |
@@ -690,7 +690,7 @@ verify_cert(struct tls_session *session, openvpn_x509_cert_t *cert, int cert_dep |
690 | 690 |
} |
691 | 691 |
else |
692 | 692 |
{ |
693 |
- if (SUCCESS != x509_verify_crl(opt->crl_file, cert, subject)) |
|
693 |
+ if (SUCCESS != x509_verify_crl(opt->crl_file, opt->crl_file_inline, cert, subject)) |
|
694 | 694 |
goto cleanup; |
695 | 695 |
} |
696 | 696 |
} |
... | ... |
@@ -248,13 +248,14 @@ result_t x509_write_pem(FILE *peercert_file, openvpn_x509_cert_t *peercert); |
248 | 248 |
* |
249 | 249 |
* @param crl_file File name of the CRL file |
250 | 250 |
* @param cert Certificate to verify |
251 |
+ * @param crl_inline Contents of the crl file if it is inlined |
|
251 | 252 |
* @param subject Subject of the given certificate |
252 | 253 |
* |
253 | 254 |
* @return \c SUCCESS if the CRL was not signed by the issuer of the |
254 | 255 |
* certificate or does not contain an entry for it. |
255 | 256 |
* \c FAILURE otherwise. |
256 | 257 |
*/ |
257 |
-result_t x509_verify_crl(const char *crl_file, openvpn_x509_cert_t *cert, |
|
258 |
- const char *subject); |
|
258 |
+result_t x509_verify_crl(const char *crl_file, const char *crl_inline, |
|
259 |
+ openvpn_x509_cert_t *cert, const char *subject); |
|
259 | 260 |
|
260 | 261 |
#endif /* SSL_VERIFY_BACKEND_H_ */ |
... | ... |
@@ -613,7 +613,8 @@ x509_write_pem(FILE *peercert_file, X509 *peercert) |
613 | 613 |
* check peer cert against CRL |
614 | 614 |
*/ |
615 | 615 |
result_t |
616 |
-x509_verify_crl(const char *crl_file, X509 *peer_cert, const char *subject) |
|
616 |
+x509_verify_crl(const char *crl_file, const char* crl_inline, |
|
617 |
+ X509 *peer_cert, const char *subject) |
|
617 | 618 |
{ |
618 | 619 |
X509_CRL *crl=NULL; |
619 | 620 |
X509_REVOKED *revoked; |
... | ... |
@@ -623,7 +624,10 @@ x509_verify_crl(const char *crl_file, X509 *peer_cert, const char *subject) |
623 | 623 |
struct gc_arena gc = gc_new(); |
624 | 624 |
char *serial; |
625 | 625 |
|
626 |
- in = BIO_new_file (crl_file, "r"); |
|
626 |
+ if (!strcmp (crl_file, INLINE_FILE_TAG) && crl_inline) |
|
627 |
+ in = BIO_new_mem_buf ((char *)crl_inline, -1); |
|
628 |
+ else |
|
629 |
+ in = BIO_new_file (crl_file, "r"); |
|
627 | 630 |
|
628 | 631 |
if (in == NULL) { |
629 | 632 |
msg (M_WARN, "CRL: cannot read: %s", crl_file); |
... | ... |
@@ -359,18 +359,30 @@ x509_write_pem(FILE *peercert_file, x509_crt *peercert) |
359 | 359 |
* check peer cert against CRL |
360 | 360 |
*/ |
361 | 361 |
result_t |
362 |
-x509_verify_crl(const char *crl_file, x509_crt *cert, const char *subject) |
|
362 |
+x509_verify_crl(const char *crl_file, const char* crl_inline, |
|
363 |
+ x509_crt *cert, const char *subject) |
|
363 | 364 |
{ |
364 | 365 |
result_t retval = FAILURE; |
365 | 366 |
x509_crl crl = {0}; |
366 | 367 |
struct gc_arena gc = gc_new(); |
367 | 368 |
char *serial; |
368 | 369 |
|
369 |
- if (!polar_ok(x509_crl_parse_file(&crl, crl_file))) |
|
370 |
+ if (!strcmp (crl_file, INLINE_FILE_TAG) && crl_inline) |
|
370 | 371 |
{ |
371 |
- msg (M_WARN, "CRL: cannot read CRL from file %s", crl_file); |
|
372 |
- goto end; |
|
372 |
+ if (!polar_ok(x509_crl_parse(&crl, crl_inline, strlen(crl_inline)))) |
|
373 |
+ { |
|
374 |
+ msg (M_WARN, "CRL: cannot parse inline CRL"); |
|
375 |
+ goto end; |
|
376 |
+ } |
|
373 | 377 |
} |
378 |
+ else |
|
379 |
+ { |
|
380 |
+ if (!polar_ok(x509_crl_parse_file(&crl, crl_file))) |
|
381 |
+ { |
|
382 |
+ msg (M_WARN, "CRL: cannot read CRL from file %s", crl_file); |
|
383 |
+ goto end; |
|
384 |
+ } |
|
385 |
+ } |
|
374 | 386 |
|
375 | 387 |
if(cert->issuer_raw.len != crl.issuer_raw.len || |
376 | 388 |
memcmp(crl.issuer_raw.p, cert->issuer_raw.p, crl.issuer_raw.len) != 0) |