Explorar el Código

X509: Add "code sign" as purpose for verification of certificates

Code signing certificates have other properties as for example described in
CA Browser Forum documents. This leads to "unsupported certificate purpose" errors when
verifying signed objects.
This patch adds the purpose "codesign" to the table in X.509 certificate verification and
the verification parameter "code_sign" to X509_VERIFY_PARAM.

Reviewed-by: Paul Dale <pauli@openssl.org>
Reviewed-by: Tomas Mraz <tomas@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/18567)
Lutz Jaenicke hace 2 años
padre
commit
178696d602

+ 56 - 0
crypto/x509/v3_purp.c

@@ -32,6 +32,8 @@ static int check_purpose_crl_sign(const X509_PURPOSE *xp, const X509 *x,
                                   int require_ca);
 static int check_purpose_timestamp_sign(const X509_PURPOSE *xp, const X509 *x,
                                         int require_ca);
+static int check_purpose_code_sign(const X509_PURPOSE *xp, const X509 *x,
+                                        int require_ca);
 static int no_check_purpose(const X509_PURPOSE *xp, const X509 *x,
                             int require_ca);
 static int check_purpose_ocsp_helper(const X509_PURPOSE *xp, const X509 *x,
@@ -61,6 +63,9 @@ static X509_PURPOSE xstandard[] = {
     {X509_PURPOSE_TIMESTAMP_SIGN, X509_TRUST_TSA, 0,
      check_purpose_timestamp_sign, "Time Stamp signing", "timestampsign",
      NULL},
+    {X509_PURPOSE_CODE_SIGN, X509_TRUST_OBJECT_SIGN, 0,
+     check_purpose_code_sign, "Code signing", "codesign",
+     NULL},
 };
 
 #define X509_PURPOSE_COUNT OSSL_NELEM(xstandard)
@@ -865,6 +870,57 @@ static int check_purpose_timestamp_sign(const X509_PURPOSE *xp, const X509 *x,
     return 1;
 }
 
+static int check_purpose_code_sign(const X509_PURPOSE *xp, const X509 *x,
+                                   int require_ca)
+{
+    int i_ext;
+
+    /* If ca is true we must return if this is a valid CA certificate. */
+    if (require_ca)
+        return check_ca(x);
+
+    /*
+     * Check the key usage and extended key usage fields:
+     *
+     * Reference: CA Browser Forum,
+     * Baseline Requirements for the Issuance and Management of 
+     * Publicly‐Trusted Code Signing Certificates, Version 3.0.0,
+     * Section 7.1.2.3: Code signing and Timestamp Certificate
+     *
+     * Checking covers Key Usage and Extended Key Usage attributes.
+     * Other properties like CRL Distribution Points and Authoriy
+     * Information Access (AIA) are not checked.
+     */
+    /* Key Usage */
+    if ((x->ex_flags & EXFLAG_KUSAGE) == 0)
+        return 0;
+    if ((x->ex_kusage & KU_DIGITAL_SIGNATURE) == 0)
+        return 0;
+    if ((x->ex_kusage & (KU_KEY_CERT_SIGN | KU_CRL_SIGN)) != 0)
+        return 0;
+
+    /* Key Usage MUST be critical */
+    i_ext = X509_get_ext_by_NID(x, NID_key_usage, -1);
+    if (i_ext < 0)
+        return 0;
+    if (i_ext >= 0) {
+        X509_EXTENSION *ext = X509_get_ext((X509 *)x, i_ext);
+        if (!X509_EXTENSION_get_critical(ext))
+            return 0;
+    }
+
+    /* Extended Key Usage */
+    if ((x->ex_flags & EXFLAG_XKUSAGE) == 0)
+        return 0;
+    if ((x->ex_xkusage & XKU_CODE_SIGN) == 0)
+        return 0;
+    if ((x->ex_xkusage & (XKU_ANYEKU | XKU_SSL_SERVER)) != 0)
+        return 0;
+
+    return 1;
+
+}
+
 static int no_check_purpose(const X509_PURPOSE *xp, const X509 *x,
                             int require_ca)
 {

+ 12 - 0
crypto/x509/x509_vpm.c

@@ -502,6 +502,18 @@ const char *X509_VERIFY_PARAM_get0_name(const X509_VERIFY_PARAM *param)
  */
 
 static const X509_VERIFY_PARAM default_table[] = {
+    {
+     "code_sign",               /* Code sign parameters */
+     0,                         /* check time to use */
+     0,                         /* inheritance flags */
+     0,                         /* flags */
+     X509_PURPOSE_CODE_SIGN,    /* purpose */
+     X509_TRUST_OBJECT_SIGN,    /* trust */
+     -1,                        /* depth */
+     -1,                        /* auth_level */
+     NULL,                      /* policies */
+     vpm_empty_id
+    },
     {
      "default",                 /* X509 default parameters */
      0,                         /* check time to use */

+ 1 - 1
doc/man1/openssl-verification-options.pod

@@ -458,7 +458,7 @@ Set policy variable inhibit-policy-mapping (see RFC5280).
 The intended use for the certificate.
 Currently defined purposes are C<sslclient>, C<sslserver>, C<nssslserver>,
 C<smimesign>, C<smimeencrypt>, C<crlsign>, C<ocsphelper>, C<timestampsign>,
-and C<any>.
+C<codesign> and C<any>.
 If peer certificate verification is enabled, by default the TLS implementation
 as well as the commands B<s_client> and B<s_server> check for consistency
 with TLS server or TLS client use, respectively.

+ 2 - 1
doc/man3/X509_STORE_CTX_new.pod

@@ -187,7 +187,8 @@ verified in the I<ctx>. Built-in available values for the I<purpose> argument
 are B<X509_PURPOSE_SSL_CLIENT>, B<X509_PURPOSE_SSL_SERVER>,
 B<X509_PURPOSE_NS_SSL_SERVER>, B<X509_PURPOSE_SMIME_SIGN>,
 B<X509_PURPOSE_SMIME_ENCRYPT>, B<X509_PURPOSE_CRL_SIGN>, B<X509_PURPOSE_ANY>,
-B<X509_PURPOSE_OCSP_HELPER> and B<X509_PURPOSE_TIMESTAMP_SIGN>. It is also
+B<X509_PURPOSE_OCSP_HELPER>, B<X509_PURPOSE_TIMESTAMP_SIGN> and
+B<X509_PURPOSE_CODE_SIGN>.  It is also
 possible to create a custom purpose value. Setting a purpose will ensure that
 the key usage declared within certificates in the chain being verified is
 consistent with that purpose as well as, potentially, other checks. Every

+ 1 - 0
doc/man3/X509_check_purpose.pod

@@ -29,6 +29,7 @@ Below are the potential ID's that can be checked:
  # define X509_PURPOSE_ANY               7
  # define X509_PURPOSE_OCSP_HELPER       8
  # define X509_PURPOSE_TIMESTAMP_SIGN    9
+ # define X509_PURPOSE_CODE_SIGN        10
 
 The checks performed take into account the X.509 extensions
 keyUsage, extendedKeyUsage, and basicConstraints.

+ 2 - 1
include/openssl/x509v3.h.in

@@ -478,9 +478,10 @@ typedef struct x509_purpose_st {
 # define X509_PURPOSE_ANY                7
 # define X509_PURPOSE_OCSP_HELPER        8
 # define X509_PURPOSE_TIMESTAMP_SIGN     9
+# define X509_PURPOSE_CODE_SIGN         10
 
 # define X509_PURPOSE_MIN                1
-# define X509_PURPOSE_MAX                9
+# define X509_PURPOSE_MAX               10
 
 /* Flags for X509V3_EXT_print() */