]> git.saurik.com Git - apple/security.git/blobdiff - OSX/libsecurity_apple_x509_tp/lib/tpPolicies.cpp
Security-58286.260.20.tar.gz
[apple/security.git] / OSX / libsecurity_apple_x509_tp / lib / tpPolicies.cpp
index 761dc806be4f349153415e5fe2c04fd079bd4fa5..786c21f1e55f70bbbc9eece37f4e5df4c69a7c4b 100644 (file)
@@ -75,14 +75,18 @@ typedef struct {
        iSignExtenInfo          inhibitAnyPolicy;
        iSignExtenInfo          certificatePolicies;
 
+       /* flag indicating presence of CSSMOID_APPLE_EXTENSION_PROVISIONING_PROFILE_SIGNING */
+       CSSM_BOOL                       foundProvisioningProfileSigningMarker;
        /* flag indicating presence of CSSMOID_APPLE_EXTENSION_PASSBOOK_SIGNING */
-       CSSM_BOOL                       foundPassbookSigning;
+       CSSM_BOOL                       foundPassbookSigningMarker;
        /* flag indicating presence of CSSMOID_APPLE_EXTENSION_SYSINT2_INTERMEDIATE */
        CSSM_BOOL                       foundAppleSysInt2Marker;
        /* flag indicating presence of CSSMOID_APPLE_EXTENSION_SERVER_AUTHENTICATION */
        CSSM_BOOL                       foundAppleServerAuthMarker;
        /* flag indicating presence of CSSMOID_APPLE_EXTENSION_ESCROW_SERVICE */
        CSSM_BOOL                       foundEscrowServiceMarker;
+       /* flag indicating presence of CSSMOID_APPLE_EXTENSION_WWDR_INTERMEDIATE */
+       CSSM_BOOL                       foundAppleWWDRIntMarker;
        /* flag indicating presence of a critical extension we don't understand */
        CSSM_BOOL                       foundUnknownCritical;
        /* flag indicating that this certificate was signed with a known-broken algorithm */
@@ -163,9 +167,6 @@ const CSSM_OID      CSSMOID_PIV_AUTH   = {PIV_AUTH_OID_LEN, (uint8 *)OID_PIV_AUTH};
 static const uint8     OID_PIV_AUTH_2048[] = {PIV_AUTH_2048_OID};
 const CSSM_OID CSSMOID_PIV_AUTH_2048   = {PIV_AUTH_2048_OID_LEN, (uint8 *)OID_PIV_AUTH_2048};
 
-static CSSM_RETURN tp_verifyAppleIDSharingOpts(TPCertGroup &certGroup,
-                                                                                               const CSSM_DATA *fieldOpts,                     // optional Common Name
-                                                                                               const iSignCertInfo *certInfo);
 /*
  * Setup a single iSignExtenInfo. Called once per known extension
  * per cert.
@@ -254,8 +255,10 @@ static CSSM_RETURN iSignSearchUnknownExtensions(
        CSSM_HANDLE             searchHand = CSSM_INVALID_HANDLE;
        uint32                  numFields = 0;
 
-       certInfo->foundPassbookSigning = CSSM_FALSE;
+       certInfo->foundProvisioningProfileSigningMarker = CSSM_FALSE;
+       certInfo->foundPassbookSigningMarker = CSSM_FALSE;
        certInfo->foundAppleSysInt2Marker = CSSM_FALSE;
+       certInfo->foundAppleWWDRIntMarker = CSSM_FALSE;
        certInfo->foundEscrowServiceMarker = CSSM_FALSE;
 
        crtn = CSSM_CL_CertGetFirstCachedFieldValue(tpCert->clHand(),
@@ -285,7 +288,7 @@ static CSSM_RETURN iSignSearchUnknownExtensions(
                !memcmp(cssmExt->extnId.Data, CSSMOID_APPLE_EXTENSION_PASSBOOK_SIGNING.Data,
                APPLE_EXTENSION_CODE_SIGNING_LENGTH+1)) {
                /* this is the Passbook Signing extension */
-               certInfo->foundPassbookSigning = CSSM_TRUE;
+               certInfo->foundPassbookSigningMarker = CSSM_TRUE;
        }
        if (cssmExt->extnId.Length == APPLE_EXTENSION_SYSINT2_INTERMEDIATE_LENGTH &&
                !memcmp(cssmExt->extnId.Data, CSSMOID_APPLE_EXTENSION_SYSINT2_INTERMEDIATE.Data,
@@ -299,6 +302,18 @@ static CSSM_RETURN iSignSearchUnknownExtensions(
                /* this is the Escrow Service Signing extension */
                certInfo->foundEscrowServiceMarker = CSSM_TRUE;
        }
+       if (cssmExt->extnId.Length == APPLE_EXTENSION_PROVISIONING_PROFILE_SIGNING_LENGTH &&
+               !memcmp(cssmExt->extnId.Data, CSSMOID_APPLE_EXTENSION_PROVISIONING_PROFILE_SIGNING.Data,
+                APPLE_EXTENSION_PROVISIONING_PROFILE_SIGNING_LENGTH)) {
+               /* this is the Provisioning Profile Signing extension */
+               certInfo->foundProvisioningProfileSigningMarker = CSSM_TRUE;
+       }
+       if (cssmExt->extnId.Length == APPLE_EXTENSION_WWDR_INTERMEDIATE_LENGTH &&
+               !memcmp(cssmExt->extnId.Data, CSSMOID_APPLE_EXTENSION_WWDR_INTERMEDIATE.Data,
+                APPLE_EXTENSION_WWDR_INTERMEDIATE_LENGTH)) {
+               /* this is the Apple WWDR extension */
+               certInfo->foundAppleWWDRIntMarker = CSSM_TRUE;
+       }
 
        if(iSignVerifyCriticalExtension(cssmExt) != CSSM_OK) {
                /* BRRZAPP! Found an unknown extension marked critical */
@@ -333,7 +348,7 @@ static CSSM_RETURN iSignSearchUnknownExtensions(
                                !memcmp(cssmExt->extnId.Data, CSSMOID_APPLE_EXTENSION_PASSBOOK_SIGNING.Data,
                                        APPLE_EXTENSION_CODE_SIGNING_LENGTH+1)) {
                        /* this is the Passbook Signing extension */
-                       certInfo->foundPassbookSigning = CSSM_TRUE;
+                       certInfo->foundPassbookSigningMarker = CSSM_TRUE;
                }
                if (cssmExt->extnId.Length == APPLE_EXTENSION_SYSINT2_INTERMEDIATE_LENGTH &&
                                !memcmp(cssmExt->extnId.Data, CSSMOID_APPLE_EXTENSION_SYSINT2_INTERMEDIATE.Data,
@@ -353,6 +368,18 @@ static CSSM_RETURN iSignSearchUnknownExtensions(
                        /* this is the Escrow Service Signing extension */
                        certInfo->foundEscrowServiceMarker = CSSM_TRUE;
                }
+               if (cssmExt->extnId.Length == APPLE_EXTENSION_PROVISIONING_PROFILE_SIGNING_LENGTH &&
+                               !memcmp(cssmExt->extnId.Data, CSSMOID_APPLE_EXTENSION_PROVISIONING_PROFILE_SIGNING.Data,
+                                       APPLE_EXTENSION_PROVISIONING_PROFILE_SIGNING_LENGTH)) {
+                       /* this is the Provisioning Profile Signing extension */
+                       certInfo->foundProvisioningProfileSigningMarker = CSSM_TRUE;
+               }
+               if (cssmExt->extnId.Length == APPLE_EXTENSION_WWDR_INTERMEDIATE_LENGTH &&
+                               !memcmp(cssmExt->extnId.Data, CSSMOID_APPLE_EXTENSION_WWDR_INTERMEDIATE.Data,
+                                       APPLE_EXTENSION_WWDR_INTERMEDIATE_LENGTH)) {
+                       /* this is the Apple WWDR extension */
+                       certInfo->foundAppleWWDRIntMarker = CSSM_TRUE;
+               }
 
                if(iSignVerifyCriticalExtension(cssmExt) != CSSM_OK) {
                        /* BRRZAPP! Found an unknown extension marked critical */
@@ -606,7 +633,7 @@ static CSSM_BOOL tpCompareSubjectName(
        CSSM_BOOL               ourRtn = CSSM_FALSE;
        const CSSM_OID  *oidSrch;
 
-       const char x500_userid_oid[] = { 0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x01 };
+       const unsigned char x500_userid_oid[] = { 0x09,0x92,0x26,0x89,0x93,0xF2,0x2C,0x64,0x01,0x01 };
        CSSM_OID X500_UserID_OID = { sizeof(x500_userid_oid), (uint8*)x500_userid_oid };
 
        fieldFound = false;
@@ -658,7 +685,7 @@ static CSSM_BOOL tpCompareSubjectName(
                                        case SN_CommonName:
                                        {
                                                /* handle odd encodings that we need to convert to 8-bit */
-                                               CFStringBuiltInEncodings encoding;
+                                               CFStringBuiltInEncodings encoding = kCFStringEncodingUnicode;
                                                CFDataRef cfd = NULL;
                                                bool doConvert = false;
                                                switch(ptvp->valueType) {
@@ -935,7 +962,7 @@ static CSSM_BOOL tpIsNumeric(
  * CFStringRef. Caller owns and must release the result. NULL return means
  * unconvertible input "string".
  */
-static CFStringRef tpTvpToCfString(
+static CFStringRef CF_RETURNS_RETAINED tpTvpToCfString(
        const CSSM_X509_TYPE_VALUE_PAIR *tvp)
 {
        CFStringBuiltInEncodings encoding;
@@ -1960,7 +1987,7 @@ static CSSM_RETURN tp_verifyMacAppStoreReceiptOpts(
 
        if (!isCertInfo->basicConstraints.present)
        {
-               tpPolicyError("tp_verifyAppleIDSharingOpts: no basicConstraints in intermediate");
+               tpPolicyError("tp_verifyMacAppStoreReceiptOpts: no basicConstraints in intermediate");
                if (tpCert->addStatusCode(CSSMERR_APPLETP_CS_NO_BASIC_CONSTRAINTS))
                        return CSSMERR_APPLETP_CS_NO_BASIC_CONSTRAINTS;
        }
@@ -2007,177 +2034,6 @@ bool certificatePoliciesContainsOID(const CE_CertPolicies *certPolicies, const C
        return false;
 }
 
-
-/*
- * Verify Apple ID Sharing options.
- *
- * -- Do basic cert validation (OCSP-based certs)
- * -- Validate that the cert is an Apple ID sharing cert:
- *             has a custom extension: OID: Apple ID Sharing Certificate ( 1 2 840 113635 100 4 7 )
- *                     (CSSMOID_APPLE_EXTENSION_APPLEID_SHARING)
- *             EKU should have both client and server authentication
- *             chains to the "Apple Application Integration Certification Authority" intermediate
- * -- optionally has a client-specified common name, which is the Apple ID account's UUID.
-
- * -- Must have one intermediate cert ("Apple Application Integration Certification Authority")
- * -- intermediate must have basic constraints with path length 0
- * -- intermediate has CSSMOID_APPLE_EXTENSION_AAI_INTERMEDIATE extension (OID 1 2 840 113635 100 6 2 3)
- OR APPLE_EXTENSION_AAI_INTERMEDIATE_2
- */
-
-static CSSM_RETURN tp_verifyAppleIDSharingOpts(TPCertGroup &certGroup,
-                                                                                               const CSSM_DATA *fieldOpts,                     // optional Common Name
-                                                                                               const iSignCertInfo *certInfo)          // all certs, size certGroup.numCerts()
-{
-       unsigned numCerts = certGroup.numCerts();
-       const iSignCertInfo *isCertInfo;
-       TPCertInfo *tpCert;
-       //      const CE_BasicConstraints *bc;          // currently unused
-       CE_ExtendedKeyUsage *eku;
-       CSSM_RETURN crtn = CSSM_OK;
-       unsigned int serverNameLen = 0;
-       const char *serverName = NULL;
-
-       // The CSSM_APPLE_TP_SMIME_OPTIONS pointer is optional as is everything in it.
-    if (fieldOpts && fieldOpts->Data)
-    {
-               CSSM_APPLE_TP_SSL_OPTIONS *sslOpts = (CSSM_APPLE_TP_SSL_OPTIONS *)fieldOpts->Data;
-        switch (sslOpts->Version)
-        {
-        case CSSM_APPLE_TP_SSL_OPTS_VERSION:
-            if (fieldOpts->Length != sizeof(CSSM_APPLE_TP_SSL_OPTIONS))
-                return CSSMERR_TP_INVALID_POLICY_IDENTIFIERS;
-            break;
-            /* handle backwards compatibility here if necessary */
-        default:
-            return CSSMERR_TP_INVALID_POLICY_IDENTIFIERS;
-               }
-               serverNameLen = sslOpts->ServerNameLen;
-               serverName = sslOpts->ServerName;
-       }
-
-       //------------------------------------------------------------------------
-
-       if (numCerts != 3)
-       {
-               if (!certGroup.isAllowedError(CSSMERR_APPLETP_CS_BAD_CERT_CHAIN_LENGTH))
-               {
-                       tpPolicyError("tp_verifyAppleIDSharingOpts: numCerts %u", numCerts);
-                       return CSSMERR_APPLETP_CS_BAD_CERT_CHAIN_LENGTH;
-               }
-               else
-               if (numCerts < 3)
-               {
-                       /* this error allowed, but no intermediate...check leaf */
-                       goto checkLeaf;
-               }
-       }
-
-       /* verify intermediate cert */
-       isCertInfo = &certInfo[1];
-       tpCert = certGroup.certAtIndex(1);
-
-       if (!isCertInfo->basicConstraints.present)
-       {
-               tpPolicyError("tp_verifyAppleIDSharingOpts: no basicConstraints in intermediate");
-               if (tpCert->addStatusCode(CSSMERR_APPLETP_CS_NO_BASIC_CONSTRAINTS))
-                       return CSSMERR_APPLETP_CS_NO_BASIC_CONSTRAINTS;
-       }
-
-checkLeaf:
-
-       /* verify leaf cert */
-       isCertInfo = &certInfo[0];
-       tpCert = certGroup.certAtIndex(0);
-
-       /* host name check is optional */
-       if (serverNameLen != 0)
-       {
-               if (serverName == NULL)
-                       return CSSMERR_TP_INVALID_POINTER;
-
-               /* convert caller's hostname string to lower case */
-               char *hostName = (char *)certGroup.alloc().malloc(serverNameLen);
-               memmove(hostName, serverName, serverNameLen);
-               tpToLower(hostName, serverNameLen);
-
-               /* Check common name... */
-
-               bool fieldFound;
-               CSSM_BOOL match = tpCompareSubjectName(*tpCert, SN_CommonName, false, hostName,
-                                                                        serverNameLen, fieldFound);
-
-               certGroup.alloc().free(hostName);
-               if (!match && tpCert->addStatusCode(CSSMERR_APPLETP_HOSTNAME_MISMATCH))
-            return CSSMERR_APPLETP_HOSTNAME_MISMATCH;
-       }
-
-       if (certInfo->certificatePolicies.present)
-       {
-               const CE_CertPolicies *certPolicies =
-                               &isCertInfo->certificatePolicies.extnData->certPolicies;
-               if (!certificatePoliciesContainsOID(certPolicies, &CSSMOID_APPLEID_SHARING_CERT_POLICY))
-                       if (tpCert->addStatusCode(CSSMERR_APPLETP_MISSING_REQUIRED_EXTENSION))
-                               return CSSMERR_APPLETP_MISSING_REQUIRED_EXTENSION;
-       }
-       else
-       if (tpCert->addStatusCode(CSSMERR_APPLETP_MISSING_REQUIRED_EXTENSION))
-               return CSSMERR_APPLETP_MISSING_REQUIRED_EXTENSION;
-
-       if (!isCertInfo->extendKeyUsage.present)
-    {
-               tpPolicyError("tp_verifyAppleIDSharingOpts: no extendedKeyUse in leaf");
-               if (tpCert->addStatusCode(CSSMERR_APPLETP_CS_NO_EXTENDED_KEY_USAGE))
-                       return crtn ? crtn : CSSMERR_APPLETP_CS_NO_EXTENDED_KEY_USAGE;
-
-        /* have to skip remainder */
-        return CSSM_OK;
-       }
-
-       // Check that certificate can do Client and Server Authentication (EKU)
-       eku = &isCertInfo->extendKeyUsage.extnData->extendedKeyUsage;
-       assert(eku != NULL);
-       if(eku->numPurposes != 2)
-       {
-               tpPolicyError("tp_verifyAppleIDSharingOpts: bad eku->numPurposes (%lu)",
-                                         (unsigned long)eku->numPurposes);
-               if (tpCert->addStatusCode(CSSMERR_APPLETP_INVALID_EXTENDED_KEY_USAGE))
-               {
-                       if (crtn == CSSM_OK)
-                               crtn = CSSMERR_APPLETP_INVALID_EXTENDED_KEY_USAGE;
-               }
-               return crtn;
-       }
-       bool canDoClientAuth = false, canDoServerAuth = false, ekuError = false;
-       for (int ix=0;ix<2;ix++)
-       {
-               if (tpCompareOids(&eku->purposes[ix], &CSSMOID_ClientAuth))
-                       canDoClientAuth = true;
-               else
-               if (tpCompareOids(&eku->purposes[ix], &CSSMOID_ServerAuth))
-                       canDoServerAuth = true;
-               else
-               {
-                       ekuError = true;
-                       break;
-               }
-       }
-
-       if (!(canDoClientAuth && canDoServerAuth))
-               ekuError = true;
-       if (ekuError)
-       {
-               tpPolicyError("tp_verifyAppleIDSharingOpts: bad EKU in leaf");
-               if (tpCert->addStatusCode(CSSMERR_APPLETP_INVALID_EXTENDED_KEY_USAGE))
-               {
-                       if (crtn == CSSM_OK)
-                               crtn = CSSMERR_APPLETP_INVALID_EXTENDED_KEY_USAGE;
-               }
-       }
-
-       return crtn;
-}
-
 /*
  * Verify Time Stamping (RFC3161) policy options.
  *
@@ -2336,7 +2192,7 @@ static CSSM_RETURN tp_verifyPassbookSigningOpts(TPCertGroup &certGroup,
        }
 
        /* Check that Passbook Signing marker extension is present */
-       if (!(isCertInfo->foundPassbookSigning == CSSM_TRUE)) {
+       if (!(isCertInfo->foundPassbookSigningMarker == CSSM_TRUE)) {
                tpPolicyError("tp_verifyPassbookSigningOpts: no Passbook Signing extension in leaf");
                tpCert->addStatusCode(CSSMERR_APPLETP_MISSING_REQUIRED_EXTENSION);
                crtn = CSSMERR_APPLETP_MISSING_REQUIRED_EXTENSION;
@@ -2573,6 +2429,68 @@ static CSSM_RETURN tp_verifyPCSEscrowServiceSigningOpts(TPCertGroup &certGroup,
        return tp_verifyEscrowServiceCommon(certGroup, fieldOpts, certInfo, kSecCertificateProductionPCSEscrowRoot);
 }
 
+/*
+ * Verify Provisioning Profile Signing policy options.
+ *
+ * -- Do basic cert validation (OCSP-based certs)
+ * -- Chains to the Apple root CA
+ * -- Leaf has Provisioning Profile marker OID (1.2.840.113635.100.4.11)
+ * -- Intermediate has WWDR marker OID (1.2.840.113635.100.6.2.1)
+ */
+static CSSM_RETURN tp_verifyProvisioningProfileSigningOpts(TPCertGroup &certGroup,
+                                                                                        const CSSM_DATA *fieldOpts,
+                                                                                        const iSignCertInfo *certInfo)         // all certs, size certGroup.numCerts()
+{
+       unsigned numCerts = certGroup.numCerts();
+       const iSignCertInfo *isCertInfo;
+       TPCertInfo *tpCert;
+       CSSM_RETURN crtn = CSSM_OK;
+
+       isCertInfo = &certInfo[0];
+       tpCert = certGroup.certAtIndex(0);
+
+       /* Check that cert chain is anchored by the Apple Root CA */
+       if (numCerts < 3) {
+               tpPolicyError("tp_verifyProvisioningProfileSigningOpts: numCerts %u", numCerts);
+               crtn = CSSMERR_APPLETP_CS_BAD_CERT_CHAIN_LENGTH;
+               goto cleanup;
+       }
+       else {
+               tpCert = certGroup.certAtIndex(numCerts-1);
+               const CSSM_DATA *certData = tpCert->itemData();
+               unsigned char digest[CC_SHA1_DIGEST_LENGTH];
+               CC_SHA1(certData->Data, (CC_LONG)certData->Length, digest);
+               if (memcmp(digest, kAppleCASHA1, sizeof(digest))) {
+                       tpPolicyError("tp_verifyProvisioningProfileSigningOpts: invalid anchor for policy");
+                       tpCert->addStatusCode(CSSMERR_APPLETP_CS_BAD_CERT_CHAIN_LENGTH);
+                       crtn = CSSMERR_APPLETP_CS_BAD_CERT_CHAIN_LENGTH;
+                       goto cleanup;
+               }
+       }
+
+       /* Check that Provisioning Profile Signing marker extension is present */
+       if (!(isCertInfo->foundProvisioningProfileSigningMarker == CSSM_TRUE)) {
+               tpPolicyError("tp_verifyProvisioningProfileSigningOpts: no Provisioning Profile Signing extension in leaf");
+               tpCert->addStatusCode(CSSMERR_APPLETP_MISSING_REQUIRED_EXTENSION);
+               crtn = CSSMERR_APPLETP_MISSING_REQUIRED_EXTENSION;
+               goto cleanup;
+       }
+
+       /* Check that Apple WWDR marker extension is present in intermediate */
+       isCertInfo = &certInfo[1];
+       tpCert = certGroup.certAtIndex(1);
+       if (!(isCertInfo->foundAppleWWDRIntMarker == CSSM_TRUE)) {
+               tpPolicyError("tp_verifyProvisioningProfileSigningOpts: intermediate marker extension not found");
+               tpCert->addStatusCode(CSSMERR_APPLETP_MISSING_REQUIRED_EXTENSION);
+               crtn = CSSMERR_APPLETP_MISSING_REQUIRED_EXTENSION;
+               goto cleanup;
+       }
+
+cleanup:
+       return crtn;
+
+}
+
 /*
  * Verify Configuration Profile Signing policy options.
  *
@@ -3233,8 +3151,11 @@ CSSM_RETURN tp_policyVerify(
                        policyError = tp_verifyMacAppStoreReceiptOpts(*certGroup, policyFieldData, certInfo);
                        break;
                case kTP_AppleIDSharing:
-                       policyError = tp_verifyAppleIDSharingOpts(*certGroup, policyFieldData, certInfo);
-                       break;
+                       /* As of macOS 10.12, this code path should be unused. Until we can remove this
+                        * module entirely, ensure that no Apple ID evaluations take this path. [10119995] */
+                       tpPolicyError("tp_policyVerify: unexpected attempt to use legacy kTP_AppleIDSharing");
+                       policyFail = CSSM_TRUE;
+                       abort();
                case kTP_TimeStamping:
                        policyError = tp_verifyTimeStampingOpts(*certGroup, policyFieldData, certInfo);
                        break;
@@ -3259,6 +3180,9 @@ CSSM_RETURN tp_policyVerify(
                case kTP_PCSEscrowService:
                        policyError = tp_verifyPCSEscrowServiceSigningOpts(*certGroup, policyFieldData, certInfo);
                        break;
+               case kTP_ProvisioningProfileSigning:
+                       policyError = tp_verifyProvisioningProfileSigningOpts(*certGroup, policyFieldData, certInfo);
+                       break;
                case kTPx509Basic:
                case kTPiSign:
                case kCrlPolicy: