if (tmp_akid == NULL && i != -1)
tmp_ex_flags |= EXFLAG_INVALID;
- /* Check if subject name matches issuer */
+ /* This is very similar to ossl_x509_likely_issued(const_x, const_x) == X509_V_OK */
if (X509_NAME_cmp(X509_get_subject_name(const_x), X509_get_issuer_name(const_x)) == 0) {
- tmp_ex_flags |= EXFLAG_SI; /* Cert is self-issued */
- if (X509_check_akid(const_x, tmp_akid) == X509_V_OK /* SKID matches AKID */
- /* .. and the signature alg matches the PUBKEY alg: */
- && check_sig_alg_match(X509_get0_pubkey(const_x), const_x) == X509_V_OK)
- tmp_ex_flags |= EXFLAG_SS; /* indicate self-signed */
- /* This is very related to ossl_x509_likely_issued(x, x) == X509_V_OK */
+ tmp_ex_flags |= EXFLAG_SI; /* Certificate is self-issued: subject == issuer */
+ /*
+ * When the SKID is missing, which is rare for self-issued certs,
+ * we could afford doing the (accurate) actual self-signature check, but
+ * decided against it for efficiency reasons and according to RFC 5280,
+ * CA certs MUST have an SKID and non-root certs MUST have an AKID.
+ */
+ if (X509_check_akid(const_x, tmp_akid) == X509_V_OK
+ && check_sig_alg_match(X509_get0_pubkey(const_x), const_x) == X509_V_OK) {
+ /*
+ * Assume self-signed if the signature alg matches the pkey alg and
+ * AKID is missing or matches respective fields in the same cert
+ * Not checking if any given key usage extension allows signing.
+ */
+ tmp_ex_flags |= EXFLAG_SS;
+ }
}
/* Handle subject alternative names and various other extensions */
return X509_V_OK;
}
+/*
+ * check if all sub-fields of the authority key identifier information akid,
+ * as far as present, match the respective subjectKeyIdentifier extension (if
+ * present in issuer), serialNumber field, and issuer fields of issuer.
+ * returns X509_V_OK also if akid is NULL because this means no restriction.
+ */
int X509_check_akid(const X509 *issuer, const AUTHORITY_KEYID *akid)
{
if (akid == NULL)