From: Adriaan de Jong Date: Thu, 30 Jun 2011 12:55:53 +0000 (+0200) Subject: Refactored CRL checks X-Git-Tag: v2.3-alpha1~116 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=83c49a3ef135141101b71037f315099d32219bbf;p=thirdparty%2Fopenvpn.git Refactored CRL checks Signed-off-by: Adriaan de Jong Acked-by: James Yonan Signed-off-by: David Sommerseth --- diff --git a/ssl.c b/ssl.c index f171ed651..310e3cd31 100644 --- a/ssl.c +++ b/ssl.c @@ -410,73 +410,12 @@ verify_cert(struct tls_session *session, x509_cert_t *cert, int cert_depth) { if (opt->ssl_flags & SSLF_CRL_VERIFY_DIR) { - char fn[256]; - int fd; - char *serial = verify_get_serial(cert); - if (!openvpn_snprintf(fn, sizeof(fn), "%s%c%s", opt->crl_file, OS_SPECIFIC_DIRSEP, serial)) - { - msg (D_HANDSHAKE, "VERIFY CRL: filename overflow"); - verify_free_serial(serial); - goto err; - } - fd = open (fn, O_RDONLY); - if (fd >= 0) - { - msg (D_HANDSHAKE, "VERIFY CRL: certificate serial number %s is revoked", serial); - verify_free_serial(serial); - close(fd); - goto err; - } - verify_free_serial(serial); + if (verify_check_crl_dir(opt->crl_file, cert)) + goto err; } else { - X509_CRL *crl=NULL; - X509_REVOKED *revoked; - BIO *in=NULL; - int n,i,retval = 0; - - in=BIO_new(BIO_s_file()); - - if (in == NULL) { - msg (M_ERR, "CRL: BIO err"); - goto end; - } - if (BIO_read_filename(in, opt->crl_file) <= 0) { - msg (M_ERR, "CRL: cannot read: %s", opt->crl_file); - goto end; - } - crl=PEM_read_bio_X509_CRL(in,NULL,NULL,NULL); - if (crl == NULL) { - msg (M_ERR, "CRL: cannot read CRL from file %s", opt->crl_file); - goto end; - } - - if (X509_NAME_cmp(X509_CRL_get_issuer(crl), X509_get_issuer_name(cert)) != 0) { - msg (M_WARN, "CRL: CRL %s is from a different issuer than the issuer of certificate %s", opt->crl_file, subject); - retval = 1; - goto end; - } - - n = sk_X509_REVOKED_num(X509_CRL_get_REVOKED(crl)); - - for (i = 0; i < n; i++) { - revoked = (X509_REVOKED *)sk_X509_REVOKED_value(X509_CRL_get_REVOKED(crl), i); - if (ASN1_INTEGER_cmp(revoked->serialNumber, X509_get_serialNumber(cert)) == 0) { - msg (D_HANDSHAKE, "CRL CHECK FAILED: %s is REVOKED",subject); - goto end; - } - } - - retval = 1; - msg (D_HANDSHAKE, "CRL CHECK OK: %s",subject); - - end: - - BIO_free(in); - if (crl) - X509_CRL_free (crl); - if (!retval) + if (verify_check_crl(opt->crl_file, cert, subject)) goto err; } } diff --git a/ssl_verify.c b/ssl_verify.c index d9acae9ae..2609c1dc9 100644 --- a/ssl_verify.c +++ b/ssl_verify.c @@ -532,6 +532,35 @@ verify_cert_call_command(const char *verify_command, struct env_set *es, return 1; /* Reject connection */ } +/* + * check peer cert against CRL directory + */ +bool +verify_check_crl_dir(const char *crl_dir, X509 *cert) +{ + char fn[256]; + int fd; + char *serial = verify_get_serial(cert); + + if (!openvpn_snprintf(fn, sizeof(fn), "%s%c%s", crl_dir, OS_SPECIFIC_DIRSEP, serial)) + { + msg (D_HANDSHAKE, "VERIFY CRL: filename overflow"); + verify_free_serial(serial); + return true; + } + fd = open (fn, O_RDONLY); + if (fd >= 0) + { + msg (D_HANDSHAKE, "VERIFY CRL: certificate serial number %s is revoked", serial); + verify_free_serial(serial); + close(fd); + return true; + } + + verify_free_serial(serial); + + return false; +} /* *************************************************************************** * Functions for the management of deferred authentication when using diff --git a/ssl_verify.h b/ssl_verify.h index 5be262783..7e53513ff 100644 --- a/ssl_verify.h +++ b/ssl_verify.h @@ -253,6 +253,7 @@ int verify_cert_call_plugin(const struct plugin_list *plugins, struct env_set *e int cert_depth, x509_cert_t *cert, char *subject); int verify_cert_call_command(const char *verify_command, struct env_set *es, int cert_depth, x509_cert_t *cert, char *subject, const char *verify_export_cert); +bool verify_check_crl_dir(const char *crl_dir, X509 *cert); #endif /* SSL_VERIFY_H_ */ diff --git a/ssl_verify_backend.h b/ssl_verify_backend.h index a551bebcd..e6dfc592a 100644 --- a/ssl_verify_backend.h +++ b/ssl_verify_backend.h @@ -192,4 +192,18 @@ bool verify_cert_eku (x509_cert_t *x509, const char * const expected_oid); const char *write_peer_cert(x509_cert_t *cert, const char *tmp_dir, struct gc_arena *gc); +/* + * Check the certificate against a CRL file. + * + * @param crl_file File name of the CRL file + * @param cert Certificate to verify + * @param subject Subject of the given certificate + * + * @return \c 1 if the CRL was not signed by the issuer of the + * certificate or does not contain an entry for it. + * \c 0 otherwise. + */ +bool verify_check_crl(const char *crl_file, x509_cert_t *cert, + const char *subject); + #endif /* SSL_VERIFY_BACKEND_H_ */ diff --git a/ssl_verify_openssl.c b/ssl_verify_openssl.c index cde100cce..8bc49d70d 100644 --- a/ssl_verify_openssl.c +++ b/ssl_verify_openssl.c @@ -521,3 +521,56 @@ write_peer_cert(X509 *peercert, const char *tmp_dir, struct gc_arena *gc) #endif /* OPENSSL_VERSION_NUMBER */ +/* + * check peer cert against CRL + */ +bool +verify_check_crl(const char *crl_file, X509 *peer_cert, const char *subject) +{ + X509_CRL *crl=NULL; + X509_REVOKED *revoked; + BIO *in=NULL; + int n,i,retval = 0; + + in=BIO_new(BIO_s_file()); + + if (in == NULL) { + msg (M_ERR, "CRL: BIO err"); + goto end; + } + if (BIO_read_filename(in, crl_file) <= 0) { + msg (M_ERR, "CRL: cannot read: %s", crl_file); + goto end; + } + crl=PEM_read_bio_X509_CRL(in,NULL,NULL,NULL); + if (crl == NULL) { + msg (M_ERR, "CRL: cannot read CRL from file %s", crl_file); + goto end; + } + + if (X509_NAME_cmp(X509_CRL_get_issuer(crl), X509_get_issuer_name(peer_cert)) != 0) { + msg (M_WARN, "CRL: CRL %s is from a different issuer than the issuer of " + "certificate %s", crl_file, subject); + retval = 1; + goto end; + } + + n = sk_X509_REVOKED_num(X509_CRL_get_REVOKED(crl)); + for (i = 0; i < n; i++) { + revoked = (X509_REVOKED *)sk_X509_REVOKED_value(X509_CRL_get_REVOKED(crl), i); + if (ASN1_INTEGER_cmp(revoked->serialNumber, X509_get_serialNumber(peer_cert)) == 0) { + msg (D_HANDSHAKE, "CRL CHECK FAILED: %s is REVOKED",subject); + goto end; + } + } + + retval = 1; + msg (D_HANDSHAKE, "CRL CHECK OK: %s",subject); + +end: + BIO_free(in); + if (crl) + X509_CRL_free (crl); + + return !retval; +}