return "OCSP verification failed";
case X509_V_ERR_OCSP_CERT_UNKNOWN:
return "OCSP unknown cert";
+ case X509_V_ERR_SIGNATURE_ALGORITHM_MISMATCH:
+ return "Subject signature algorithm and issuer public key algorithm mismatch";
+ case X509_V_ERR_NO_ISSUER_PUBLIC_KEY:
+ return "Issuer certificate doesn't have a public key";
default:
/* Printing an error number into a static buffer is not thread-safe */
* subject name.
* These are:
* 1. Check issuer_name(subject) == subject_name(issuer)
- * 2. If akid(subject) exists check it matches issuer
- * 3. If key_usage(issuer) exists check it supports certificate signing
+ * 2. If akid(subject) exists, check that it matches issuer
+ * 3. Check that issuer public key algorithm matches subject signature algorithm
+ * 4. If key_usage(issuer) exists, check that it supports certificate signing
* returns 0 for OK, positive for reason for mismatch, reasons match
* codes for X509_verify_cert()
*/
return ret;
}
+ {
+ /*
+ * Check if the subject signature algorithm matches the issuer's PUBKEY
+ * algorithm
+ */
+ EVP_PKEY *i_pkey = X509_get0_pubkey(issuer);
+ X509_ALGOR *s_algor = &subject->cert_info.signature;
+ int s_pknid = NID_undef, s_mdnid = NID_undef;
+
+ if (i_pkey == NULL)
+ return X509_V_ERR_NO_ISSUER_PUBLIC_KEY;
+
+ if (!OBJ_find_sigid_algs(OBJ_obj2nid(s_algor->algorithm),
+ &s_mdnid, &s_pknid)
+ || EVP_PKEY_type(s_pknid) != EVP_PKEY_base_id(i_pkey))
+ return X509_V_ERR_SIGNATURE_ALGORITHM_MISMATCH;
+ }
+
if (subject->ex_flags & EXFLAG_PROXY) {
if (ku_reject(issuer, KU_DIGITAL_SIGNATURE))
return X509_V_ERR_KEYUSAGE_NO_DIGITAL_SIGNATURE;
# define X509_V_ERR_OCSP_VERIFY_FAILED 74 /* Couldn't verify cert through OCSP */
# define X509_V_ERR_OCSP_CERT_UNKNOWN 75 /* Certificate wasn't recognized by the OCSP responder */
+# define X509_V_ERR_SIGNATURE_ALGORITHM_MISMATCH 76
+# define X509_V_ERR_NO_ISSUER_PUBLIC_KEY 77
+
+
/* Certificate verify flags */
# if !OPENSSL_API_1_1_0