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,
{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)
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)
{
*/
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 */
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.
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