changeset 3171:6a9918e92494

6495595 KMF incorrectly checks the CA constraint 6495596 KMF_OpenSSL plugin incorrectly clears memory from returned cert list.
author wyllys
date Mon, 27 Nov 2006 05:48:20 -0800
parents ff80d4b3644b
children 303483377c70
files usr/src/lib/libkmf/libkmf/common/certop.c usr/src/lib/libkmf/plugins/kmf_openssl/common/openssl_spi.c
diffstat 2 files changed, 36 insertions(+), 17 deletions(-) [+]
line wrap: on
line diff
--- a/usr/src/lib/libkmf/libkmf/common/certop.c	Sun Nov 26 16:30:59 2006 -0800
+++ b/usr/src/lib/libkmf/libkmf/common/certop.c	Mon Nov 27 05:48:20 2006 -0800
@@ -1337,6 +1337,8 @@
 	KMF_POLICY_RECORD *policy;
 	KMF_X509EXT_KEY_USAGE keyusage;
 	KMF_RETURN ret = KMF_OK;
+	KMF_X509EXT_BASICCONSTRAINTS constraint;
+	KMF_BOOL	critical = B_FALSE;
 
 	if (handle == NULL || cert == NULL)
 		return (KMF_ERR_BAD_PARAMETER);
@@ -1361,6 +1363,23 @@
 	}
 
 	/*
+	 * If KeyCertSign is set, then constraints.cA must be TRUE and
+	 * marked critical.
+	 */
+	if ((keyusage.KeyUsageBits & KMF_keyCertSign)) {
+		(void) memset(&constraint, 0, sizeof (constraint));
+		ret = KMF_GetCertBasicConstraintExt(cert,
+			&critical, &constraint);
+
+		if (ret != KMF_OK) {
+			/* real error */
+			return (ret);
+		}
+		if (!constraint.cA || !critical)
+			return (KMF_ERR_KEYUSAGE);
+	}
+
+	/*
 	 * Rule: if the KU bit is set in policy, the corresponding KU bit
 	 * must be set in the certificate (but not vice versa).
 	 */
@@ -1376,8 +1395,6 @@
 cert_eku_check(KMF_HANDLE_T handle, KMF_DATA *cert)
 {
 	KMF_POLICY_RECORD *policy;
-	KMF_X509EXT_BASICCONSTRAINTS constraint;
-	KMF_BOOL	critical = B_FALSE;
 	KMF_RETURN ret = KMF_OK;
 	KMF_X509EXT_EKU eku;
 	uint16_t cert_eku = 0, policy_eku = 0;
@@ -1386,20 +1403,13 @@
 	if (handle == NULL || cert == NULL)
 		return (KMF_ERR_BAD_PARAMETER);
 	policy = handle->policy;
-	(void) memset(&constraint, 0, sizeof (constraint));
-
-	ret = KMF_GetCertBasicConstraintExt(cert,
-	    &critical, &constraint);
-
-	if ((ret != KMF_ERR_EXTENSION_NOT_FOUND) && (ret != KMF_OK)) {
-		/* real error */
-		return (ret);
-	}
-
-	if (constraint.cA) {
-		/* EKU extension appears only in end entity certificates */
-		return (KMF_ERR_KEYUSAGE);
-	}
+
+	/*
+	 * If the policy does not have any EKU, then there is
+	 * nothing further to check.
+	 */
+	if (policy->eku_set.eku_count == 0)
+		return (KMF_OK);
 
 	ret = KMF_GetCertEKU(cert, &eku);
 	if ((ret != KMF_ERR_EXTENSION_NOT_FOUND) && (ret != KMF_OK)) {
@@ -1438,6 +1448,7 @@
 		} /* for */
 	}
 
+
 	/*
 	 * Build the EKU bitmap based on the policy
 	 */
@@ -1708,9 +1719,14 @@
 	if (ret != KMF_OK)
 		goto out;
 
-	ret = KMF_CompareRDNs(user_issuerDN, &ta_subjectDN);
+	if (KMF_CompareRDNs(user_issuerDN, &ta_subjectDN) != 0)
+		ret = KMF_ERR_CERT_NOT_FOUND;
+
 	KMF_FreeDN(&ta_subjectDN);
 
+	/* Make sure the TA cert has the correct extensions */
+	if (ret == KMF_OK)
+		ret = check_key_usage(handle, ta_cert, KMF_KU_SIGN_CERT);
 out:
 	if (ta_retrCert.certificate.Data)
 		KMF_FreeKMFCert(handle, &ta_retrCert);
--- a/usr/src/lib/libkmf/plugins/kmf_openssl/common/openssl_spi.c	Sun Nov 26 16:30:59 2006 -0800
+++ b/usr/src/lib/libkmf/plugins/kmf_openssl/common/openssl_spi.c	Mon Nov 27 05:48:20 2006 -0800
@@ -704,6 +704,9 @@
 				kmf_cert[n].kmf_private.flags =
 					KMF_FLAG_CERT_VALID;
 				kmf_cert[n].kmf_private.label = fname;
+
+				certdata.Data = NULL;
+				certdata.Length = 0;
 			} else {
 				free(fname);
 				KMF_FreeData(&certdata);