summaryrefslogtreecommitdiffstats
path: root/crypto/x509/v3_purp.c
diff options
context:
space:
mode:
Diffstat (limited to 'crypto/x509/v3_purp.c')
-rw-r--r--crypto/x509/v3_purp.c71
1 files changed, 47 insertions, 24 deletions
diff --git a/crypto/x509/v3_purp.c b/crypto/x509/v3_purp.c
index 5d9b947a39..1c0fba2743 100644
--- a/crypto/x509/v3_purp.c
+++ b/crypto/x509/v3_purp.c
@@ -14,6 +14,7 @@
#include <openssl/x509_vfy.h>
#include "crypto/x509.h"
#include "internal/tsan_assist.h"
+#include "x509_local.h"
DEFINE_STACK_OF(GENERAL_NAME)
DEFINE_STACK_OF(DIST_POINT)
@@ -346,6 +347,21 @@ static int setup_crldp(X509 *x)
return 1;
}
+/* Check that issuer public key algorithm matches subject signature algorithm */
+static int check_sig_alg_match(const EVP_PKEY *pkey, const X509 *subject)
+{
+ int pkey_nid;
+
+ if (pkey == NULL)
+ return X509_V_ERR_NO_ISSUER_PUBLIC_KEY;
+ if (OBJ_find_sigid_algs(OBJ_obj2nid(subject->cert_info.signature.algorithm),
+ NULL, &pkey_nid) == 0)
+ return X509_V_ERR_UNSUPPORTED_SIGNATURE_ALGORITHM;
+ if (EVP_PKEY_type(pkey_nid) != EVP_PKEY_base_id(pkey))
+ return X509_V_ERR_SIGNATURE_ALGORITHM_MISMATCH;
+ return X509_V_OK;
+}
+
#define V1_ROOT (EXFLAG_V1|EXFLAG_SS)
#define ku_reject(x, usage) \
(((x)->ex_flags & EXFLAG_KUSAGE) && !((x)->ex_kusage & (usage)))
@@ -815,39 +831,47 @@ static int no_check(const X509_PURPOSE *xp, const X509 *x, int ca)
* Returns 0 for OK, or positive for reason for mismatch
* where reason codes match those for X509_verify_cert().
*/
+int x509_check_issued_int(X509 *issuer, X509 *subject,
+ OPENSSL_CTX *libctx, const char *propq)
+{
+ int ret;
-int x509_check_issued_int(X509 *issuer, X509 *subject, OPENSSL_CTX *libctx,
- const char *propq)
+ if ((ret = x509_likely_issued(issuer, subject, libctx, propq)) != X509_V_OK)
+ return ret;
+ return x509_signing_allowed(issuer, subject);
+}
+
+/* do the checks 1., 2., and 3. as described above for X509_check_issued() */
+int x509_likely_issued(X509 *issuer, X509 *subject,
+ OPENSSL_CTX *libctx, const char *propq)
{
+ int ret;
+
if (X509_NAME_cmp(X509_get_subject_name(issuer),
- X509_get_issuer_name(subject)))
+ X509_get_issuer_name(subject)) != 0)
return X509_V_ERR_SUBJECT_ISSUER_MISMATCH;
if (!X509v3_cache_extensions(issuer, libctx, propq)
|| !X509v3_cache_extensions(subject, libctx, propq))
return X509_V_ERR_UNSPECIFIED;
- if (subject->akid) {
- int ret = X509_check_akid(issuer, subject->akid);
- if (ret != X509_V_OK)
- return ret;
- }
+ ret = X509_check_akid(issuer, subject->akid);
+ if (ret != X509_V_OK)
+ return ret;
/* check if the subject signature alg matches the issuer's PUBKEY alg */
- {
- 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;
- }
+ return check_sig_alg_match(X509_get0_pubkey(issuer), subject);
+}
+/*-
+ * Check if certificate I<issuer> is allowed to issue certificate I<subject>
+ * according to the B<keyUsage> field of I<issuer> if present
+ * depending on any proxyCertInfo extension of I<subject>.
+ * Returns 0 for OK, or positive for reason for rejection
+ * where reason codes match those for X509_verify_cert().
+ */
+int x509_signing_allowed(const X509 *issuer, const X509 *subject)
+{
if (subject->ex_flags & EXFLAG_PROXY) {
if (ku_reject(issuer, KU_DIGITAL_SIGNATURE))
return X509_V_ERR_KEYUSAGE_NO_DIGITAL_SIGNATURE;
@@ -863,8 +887,7 @@ int X509_check_issued(X509 *issuer, X509 *subject)
int X509_check_akid(X509 *issuer, AUTHORITY_KEYID *akid)
{
-
- if (!akid)
+ if (akid == NULL)
return X509_V_OK;
/* Check key ids (if present) */
@@ -894,7 +917,7 @@ int X509_check_akid(X509 *issuer, AUTHORITY_KEYID *akid)
break;
}
}
- if (nm && X509_NAME_cmp(nm, X509_get_issuer_name(issuer)))
+ if (nm != NULL && X509_NAME_cmp(nm, X509_get_issuer_name(issuer)) != 0)
return X509_V_ERR_AKID_ISSUER_SERIAL_MISMATCH;
}
return X509_V_OK;