]> git.ipfire.org Git - thirdparty/openvpn.git/commitdiff
Refactored CRL checks
authorAdriaan de Jong <dejong@fox-it.com>
Thu, 30 Jun 2011 12:55:53 +0000 (14:55 +0200)
committerDavid Sommerseth <davids@redhat.com>
Sat, 22 Oct 2011 09:32:40 +0000 (11:32 +0200)
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>
ssl.c
ssl_verify.c
ssl_verify.h
ssl_verify_backend.h
ssl_verify_openssl.c

diff --git a/ssl.c b/ssl.c
index f171ed6515216ebc274bc7ed64ec2f5bfae7ec49..310e3cd31e2aec938184e9471a5aeb7704201b64 100644 (file)
--- 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;
        }
     }
index d9acae9ae56a297e780a18949c12729cb1a1639e..2609c1dc92d4918b3be2a968a2e62de425949f6d 100644 (file)
@@ -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
index 5be262783cb4517c4763f69b83d19db5790b6dd3..7e53513ff9a6555bb3d0c7f30345b2f1a129f453 100644 (file)
@@ -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_ */
 
index a551bebcdb0cfe803344ea6cbfc951880f423eba..e6dfc592a11b516efb0cb0bc3c6e378d002a4531 100644 (file)
@@ -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_ */
index cde100cce14fd0141a8ad61bc96d9cbacddf267f..8bc49d70d33b5104d609e90c545a42d6acc783f1 100644 (file)
@@ -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;
+}