Distinguish between self-issued certificates and self-signed certificates.
authorjsing <jsing@openbsd.org>
Thu, 22 Jun 2017 17:28:00 +0000 (17:28 +0000)
committerjsing <jsing@openbsd.org>
Thu, 22 Jun 2017 17:28:00 +0000 (17:28 +0000)
The certificate verification code has special cases for self-signed
certificates and without this change, self-issued certificates (which it
seems are common place with openvpn/easyrsa) were also being included in
this category.

Based on BoringSSL.

Thanks to Dale Ghent <daleg at elemental dot org> for assisting in
identifying the issue and testing this fix.

ok inoguchi@

lib/libcrypto/x509v3/v3_purp.c
lib/libcrypto/x509v3/x509v3.h

index bdcdf95..d692a19 100644 (file)
@@ -1,4 +1,4 @@
-/* $OpenBSD: v3_purp.c,v 1.29 2017/01/29 17:49:23 beck Exp $ */
+/* $OpenBSD: v3_purp.c,v 1.30 2017/06/22 17:28:00 jsing Exp $ */
 /* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
  * project 2001.
  */
 #include <openssl/x509v3.h>
 #include <openssl/x509_vfy.h>
 
+#define V1_ROOT (EXFLAG_V1|EXFLAG_SS)
+#define ku_reject(x, usage) \
+       (((x)->ex_flags & EXFLAG_KUSAGE) && !((x)->ex_kusage & (usage)))
+#define xku_reject(x, usage) \
+       (((x)->ex_flags & EXFLAG_XKUSAGE) && !((x)->ex_xkusage & (usage)))
+#define ns_reject(x, usage) \
+       (((x)->ex_flags & EXFLAG_NSCERT) && !((x)->ex_nscert & (usage)))
+
 static void x509v3_cache_extensions(X509 *x);
 
 static int check_ssl_ca(const X509 *x);
@@ -427,19 +435,19 @@ x509v3_cache_extensions(X509 *x)
        ASN1_BIT_STRING *ns;
        EXTENDED_KEY_USAGE *extusage;
        X509_EXTENSION *ex;
-
        int i;
+
        if (x->ex_flags & EXFLAG_SET)
                return;
+
 #ifndef OPENSSL_NO_SHA
        X509_digest(x, EVP_sha1(), x->sha1_hash, NULL);
 #endif
-       /* Does subject name match issuer ? */
-       if (!X509_NAME_cmp(X509_get_subject_name(x), X509_get_issuer_name(x)))
-               x->ex_flags |= EXFLAG_SI;
+
        /* V1 should mean no extensions ... */
        if (!X509_get_version(x))
                x->ex_flags |= EXFLAG_V1;
+
        /* Handle basic constraints */
        if ((bs = X509_get_ext_d2i(x, NID_basic_constraints, NULL, NULL))) {
                if (bs->ca)
@@ -456,6 +464,7 @@ x509v3_cache_extensions(X509 *x)
                BASIC_CONSTRAINTS_free(bs);
                x->ex_flags |= EXFLAG_BCONS;
        }
+
        /* Handle proxy certificates */
        if ((pci = X509_get_ext_d2i(x, NID_proxyCertInfo, NULL, NULL))) {
                if (x->ex_flags & EXFLAG_CA ||
@@ -477,6 +486,7 @@ x509v3_cache_extensions(X509 *x)
                PROXY_CERT_INFO_EXTENSION_free(pci);
                x->ex_flags |= EXFLAG_PROXY;
        }
+
        /* Handle key usage */
        if ((usage = X509_get_ext_d2i(x, NID_key_usage, NULL, NULL))) {
                if (usage->length > 0) {
@@ -541,6 +551,16 @@ x509v3_cache_extensions(X509 *x)
 
        x->skid = X509_get_ext_d2i(x, NID_subject_key_identifier, NULL, NULL);
        x->akid = X509_get_ext_d2i(x, NID_authority_key_identifier, NULL, NULL);
+
+       /* Does subject name match issuer? */
+       if (!X509_NAME_cmp(X509_get_subject_name(x), X509_get_issuer_name(x))) {
+               x->ex_flags |= EXFLAG_SI;
+               /* If SKID matches AKID also indicate self signed. */
+               if (X509_check_akid(x, x->akid) == X509_V_OK &&
+                   !ku_reject(x, KU_KEY_CERT_SIGN))
+                       x->ex_flags |= EXFLAG_SS;
+       }
+
        x->altname = X509_get_ext_d2i(x, NID_subject_alt_name, NULL, NULL);
        x->nc = X509_get_ext_d2i(x, NID_name_constraints, &i, NULL);
        if (!x->nc && (i != -1))
@@ -571,14 +591,6 @@ x509v3_cache_extensions(X509 *x)
  * 4 basicConstraints absent but keyUsage present and keyCertSign asserted.
  */
 
-#define V1_ROOT (EXFLAG_V1|EXFLAG_SS)
-#define ku_reject(x, usage) \
-       (((x)->ex_flags & EXFLAG_KUSAGE) && !((x)->ex_kusage & (usage)))
-#define xku_reject(x, usage) \
-       (((x)->ex_flags & EXFLAG_XKUSAGE) && !((x)->ex_xkusage & (usage)))
-#define ns_reject(x, usage) \
-       (((x)->ex_flags & EXFLAG_NSCERT) && !((x)->ex_nscert & (usage)))
-
 static int
 check_ca(const X509 *x)
 {
index 0a8f66f..fbafd69 100644 (file)
@@ -1,4 +1,4 @@
-/* $OpenBSD: x509v3.h,v 1.21 2016/12/30 16:19:24 jsing Exp $ */
+/* $OpenBSD: x509v3.h,v 1.22 2017/06/22 17:28:00 jsing Exp $ */
 /* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
  * project 1999.
  */
@@ -411,23 +411,21 @@ struct ISSUING_DIST_POINT_st
 
 /* X509_PURPOSE stuff */
 
-#define EXFLAG_BCONS           0x1
-#define EXFLAG_KUSAGE          0x2
-#define EXFLAG_XKUSAGE         0x4
-#define EXFLAG_NSCERT          0x8
-
-#define EXFLAG_CA              0x10
-/* Really self issued not necessarily self signed */
-#define EXFLAG_SI              0x20
-#define EXFLAG_SS              0x20
-#define EXFLAG_V1              0x40
-#define EXFLAG_INVALID         0x80
-#define EXFLAG_SET             0x100
-#define EXFLAG_CRITICAL                0x200
-#define EXFLAG_PROXY           0x400
-
-#define EXFLAG_INVALID_POLICY  0x800
+#define EXFLAG_BCONS           0x0001
+#define EXFLAG_KUSAGE          0x0002
+#define EXFLAG_XKUSAGE         0x0004
+#define EXFLAG_NSCERT          0x0008
+
+#define EXFLAG_CA              0x0010
+#define EXFLAG_SI              0x0020  /* Self issued. */
+#define EXFLAG_V1              0x0040
+#define EXFLAG_INVALID         0x0080
+#define EXFLAG_SET             0x0100
+#define EXFLAG_CRITICAL                0x0200
+#define EXFLAG_PROXY           0x0400
+#define EXFLAG_INVALID_POLICY  0x0800
 #define EXFLAG_FRESHEST                0x1000
+#define EXFLAG_SS               0x2000 /* Self signed. */
 
 #define KU_DIGITAL_SIGNATURE   0x0080
 #define KU_NON_REPUDIATION     0x0040