]> git.saurik.com Git - apple/security.git/blobdiff - libsecurity_smime/lib/crypto-embedded.c
Security-59754.80.3.tar.gz
[apple/security.git] / libsecurity_smime / lib / crypto-embedded.c
index da4b7956b896367475d1b00765e7c9a39cc537c2..8e9a4b9bd291362a73669b7e8cb5444bdeacb5da 100644 (file)
@@ -46,6 +46,7 @@
 #include <Security/SecIdentity.h>
 #include <Security/SecCertificateInternal.h>
 #include <Security/SecKeyPriv.h>
 #include <Security/SecIdentity.h>
 #include <Security/SecCertificateInternal.h>
 #include <Security/SecKeyPriv.h>
+#include <utilities/SecCFWrappers.h>
 
 #include <CommonCrypto/CommonDigest.h>
 #include <AssertMacros.h>
 
 #include <CommonCrypto/CommonDigest.h>
 #include <AssertMacros.h>
@@ -91,7 +92,6 @@ CERT_VerifyCert(SecKeychainRef keychainOrArray __unused, CFArrayRef certs,
                 PORT_SetError(SEC_ERROR_UNTRUSTED_CERT);
                 rv = SECFailure;
                 goto loser;
                 PORT_SetError(SEC_ERROR_UNTRUSTED_CERT);
                 rv = SECFailure;
                 goto loser;
-                break;
         }
     }
 
         }
     }
 
@@ -103,7 +103,7 @@ loser:
     return rv;
 }
 
     return rv;
 }
 
-static CFTypeRef CERT_FindItemInAllAvailableKeychains(CFDictionaryRef query) {
+static CF_RETURNS_RETAINED CFTypeRef CERT_FindItemInAllAvailableKeychains(CFDictionaryRef query) {
     CFTypeRef item = NULL;
     CFMutableDictionaryRef q = NULL;
     CFDictionaryRef whoAmI = NULL;
     CFTypeRef item = NULL;
     CFMutableDictionaryRef q = NULL;
     CFDictionaryRef whoAmI = NULL;
@@ -151,7 +151,7 @@ SecCertificateRef CERT_FindUserCertByUsage(SecKeychainRef keychainOrArray,
        return (SecCertificateRef)result;
 }
 
        return (SecCertificateRef)result;
 }
 
-CF_RETURNS_RETAINED CFArrayRef CERT_CertChainFromCert(SecCertificateRef cert, SECCertUsage usage, Boolean includeRoot)
+CF_RETURNS_RETAINED CFArrayRef CERT_CertChainFromCert(SecCertificateRef cert, SECCertUsage usage, Boolean includeRoot, Boolean mustIncludeRoot)
 {
     CFMutableArrayRef certs = NULL;
     SecPolicyRef policy = NULL;
 {
     CFMutableArrayRef certs = NULL;
     SecPolicyRef policy = NULL;
@@ -159,16 +159,19 @@ CF_RETURNS_RETAINED CFArrayRef CERT_CertChainFromCert(SecCertificateRef cert, SE
     CFArrayRef wrappedCert = NULL;
     
     policy = SecPolicyCreateBasicX509();
     CFArrayRef wrappedCert = NULL;
     
     policy = SecPolicyCreateBasicX509();
-    if (!policy)
+    if (!policy) {
         goto out;
         goto out;
+    }
     
     wrappedCert = CERT_CertListFromCert(cert);
     
     wrappedCert = CERT_CertListFromCert(cert);
-    if (SecTrustCreateWithCertificates(wrappedCert, policy, &trust))
+    if (SecTrustCreateWithCertificates(wrappedCert, policy, &trust)) {
         goto out;
         goto out;
+    }
 
        SecTrustResultType result;
 
        SecTrustResultType result;
-    if (SecTrustEvaluate(trust, &result))
+    if (SecTrustEvaluate(trust, &result)) {
         goto out;
         goto out;
+    }
     CFIndex idx, count = SecTrustGetCertificateCount(trust);
 
     /* If we weren't able to build a chain to a self-signed cert, warn. */
     CFIndex idx, count = SecTrustGetCertificateCount(trust);
 
     /* If we weren't able to build a chain to a self-signed cert, warn. */
@@ -177,26 +180,34 @@ CF_RETURNS_RETAINED CFArrayRef CERT_CertChainFromCert(SecCertificateRef cert, SE
     if (lastCert && (0 == SecCertificateIsSelfSigned(lastCert, &isSelfSigned)) && !isSelfSigned) {
         CFStringRef commonName = NULL;
         (void)SecCertificateCopyCommonName(cert, &commonName);
     if (lastCert && (0 == SecCertificateIsSelfSigned(lastCert, &isSelfSigned)) && !isSelfSigned) {
         CFStringRef commonName = NULL;
         (void)SecCertificateCopyCommonName(cert, &commonName);
-        fprintf(stderr, "Warning: unable to build chain to self-signed root for signer \"%s\"",
+        fprintf(stderr, "Warning: unable to build chain to self-signed root for signer \"%s\"\n",
                 commonName ? CFStringGetCStringPtr(commonName, kCFStringEncodingUTF8) : "");
         if (commonName) { CFRelease(commonName); }
                 commonName ? CFStringGetCStringPtr(commonName, kCFStringEncodingUTF8) : "");
         if (commonName) { CFRelease(commonName); }
+
+        // we don't have a root, so if the caller required one, fail
+        if (mustIncludeRoot) {
+            goto out;
+        }
     }
 
     /* We don't drop the root if there is only 1 certificate in the chain. */
     }
 
     /* We don't drop the root if there is only 1 certificate in the chain. */
-    if (!includeRoot && count > 1) { count--; }
+    if (isSelfSigned && !includeRoot && count > 1) {
+        count--;
+    }
     certs = CFArrayCreateMutable(kCFAllocatorDefault, count, &kCFTypeArrayCallBacks);
     certs = CFArrayCreateMutable(kCFAllocatorDefault, count, &kCFTypeArrayCallBacks);
-    for(idx = 0; idx < count; idx++)
+    for(idx = 0; idx < count; idx++) {
         CFArrayAppendValue(certs, SecTrustGetCertificateAtIndex(trust, idx));
         CFArrayAppendValue(certs, SecTrustGetCertificateAtIndex(trust, idx));
+    }
 
 out:
 
 out:
-    if (trust) CFRelease(trust);
-    if (policy) CFRelease(policy);
-    if (wrappedCert) CFRelease(wrappedCert);
+    if (trust) { CFRelease(trust); }
+    if (policy) { CFRelease(policy); }
+    if (wrappedCert) { CFRelease(wrappedCert); }
 
     return certs;
 }
 
 
     return certs;
 }
 
-CFArrayRef CERT_CertListFromCert(SecCertificateRef cert)
+CF_RETURNS_RETAINED CFArrayRef CERT_CertListFromCert(SecCertificateRef cert)
 {
     const void *value = cert;
     return cert ? CFArrayCreate(NULL, &value, 1, &kCFTypeArrayCallBacks) : NULL;
 {
     const void *value = cert;
     return cert ? CFArrayCreate(NULL, &value, 1, &kCFTypeArrayCallBacks) : NULL;
@@ -221,35 +232,40 @@ SecCmsIssuerAndSN *CERT_GetCertIssuerAndSN(PRArenaPool *pl, SecCertificateRef ce
 
     void *mark;
     mark = PORT_ArenaMark(pl);
 
     void *mark;
     mark = PORT_ArenaMark(pl);
-    CFDataRef serial_data = NULL;
     CFDataRef issuer_data = SecCertificateCopyIssuerSequence(cert);
     CFDataRef issuer_data = SecCertificateCopyIssuerSequence(cert);
-    if (!issuer_data)
-        goto loser;
-    serial_data = SecCertificateCopySerialNumberData(cert, NULL);
-    if (!serial_data)
+    CFDataRef serial_data = SecCertificateCopySerialNumberData(cert, NULL);
+    if (!issuer_data || !serial_data) {
         goto loser;
         goto loser;
-    
-    SecAsn1Item serialNumber = { CFDataGetLength(serial_data),
-        (uint8_t *)CFDataGetBytePtr(serial_data) };
-    SecAsn1Item issuer = { CFDataGetLength(issuer_data),
-        (uint8_t *)CFDataGetBytePtr(issuer_data) };
-    
-        /* Allocate the SecCmsIssuerAndSN struct. */
+    }
+
+    SecAsn1Item serialNumber = {
+        .Length = CFDataGetLength(serial_data),
+        .Data = (uint8_t *)CFDataGetBytePtr(serial_data)
+    };
+    SecAsn1Item issuer = {
+        .Length = CFDataGetLength(issuer_data),
+        .Data = (uint8_t *)CFDataGetBytePtr(issuer_data)
+    };
+
+    /* Allocate the SecCmsIssuerAndSN struct. */
     certIssuerAndSN = (SecCmsIssuerAndSN *)PORT_ArenaZAlloc (pl, sizeof(SecCmsIssuerAndSN));
     certIssuerAndSN = (SecCmsIssuerAndSN *)PORT_ArenaZAlloc (pl, sizeof(SecCmsIssuerAndSN));
-    if (certIssuerAndSN == NULL)
-       goto loser;
+    if (certIssuerAndSN == NULL) {
+        goto loser;
+    }
 
     /* Copy the issuer. */
     certIssuerAndSN->derIssuer.Data = (uint8_t *) PORT_ArenaAlloc(pl, issuer.Length);
 
     /* Copy the issuer. */
     certIssuerAndSN->derIssuer.Data = (uint8_t *) PORT_ArenaAlloc(pl, issuer.Length);
-    if (!certIssuerAndSN->derIssuer.Data)
-       goto loser;
+    if (!certIssuerAndSN->derIssuer.Data) {
+        goto loser;
+    }
     PORT_Memcpy(certIssuerAndSN->derIssuer.Data, issuer.Data, issuer.Length);
     certIssuerAndSN->derIssuer.Length = issuer.Length;
 
     /* Copy the serialNumber. */
     certIssuerAndSN->serialNumber.Data = (uint8_t *) PORT_ArenaAlloc(pl, serialNumber.Length);
     PORT_Memcpy(certIssuerAndSN->derIssuer.Data, issuer.Data, issuer.Length);
     certIssuerAndSN->derIssuer.Length = issuer.Length;
 
     /* Copy the serialNumber. */
     certIssuerAndSN->serialNumber.Data = (uint8_t *) PORT_ArenaAlloc(pl, serialNumber.Length);
-    if (!certIssuerAndSN->serialNumber.Data)
-       goto loser;
+    if (!certIssuerAndSN->serialNumber.Data) {
+        goto loser;
+    }
     PORT_Memcpy(certIssuerAndSN->serialNumber.Data, serialNumber.Data, serialNumber.Length);
     certIssuerAndSN->serialNumber.Length = serialNumber.Length;
 
     PORT_Memcpy(certIssuerAndSN->serialNumber.Data, serialNumber.Data, serialNumber.Length);
     certIssuerAndSN->serialNumber.Length = serialNumber.Length;
 
@@ -257,14 +273,12 @@ SecCmsIssuerAndSN *CERT_GetCertIssuerAndSN(PRArenaPool *pl, SecCertificateRef ce
     CFRelease(issuer_data);
 
     PORT_ArenaUnmark(pl, mark);
     CFRelease(issuer_data);
 
     PORT_ArenaUnmark(pl, mark);
-    
+
     return certIssuerAndSN;
 
 loser:
     return certIssuerAndSN;
 
 loser:
-    if (serial_data)
-        CFRelease(serial_data);
-    if (issuer_data)
-        CFRelease(issuer_data);
+    CFReleaseNull(serial_data);
+    CFReleaseNull(issuer_data);
     PORT_ArenaRelease(pl, mark);
     PORT_SetError(SEC_INTERNAL_ONLY);
 
     PORT_ArenaRelease(pl, mark);
     PORT_SetError(SEC_INTERNAL_ONLY);
 
@@ -279,7 +293,7 @@ SecAsn1Item *CERT_FindSMimeProfile(SecCertificateRef cert)
 
 // Generate a certificate key from the issuer and serialnumber, then look it up in the database.
 // Return the cert if found. "issuerAndSN" is the issuer and serial number to look for
 
 // Generate a certificate key from the issuer and serialnumber, then look it up in the database.
 // Return the cert if found. "issuerAndSN" is the issuer and serial number to look for
-static CFTypeRef CERT_FindByIssuerAndSN (CFTypeRef keychainOrArray, CFTypeRef class, const SecCmsIssuerAndSN *issuerAndSN)
+static CF_RETURNS_RETAINED CFTypeRef CERT_FindByIssuerAndSN (CFTypeRef keychainOrArray, CFTypeRef class, const SecCmsIssuerAndSN *issuerAndSN)
 {
     CFTypeRef ident = NULL;
        CFDictionaryRef query = NULL;
 {
     CFTypeRef ident = NULL;
        CFDictionaryRef query = NULL;
@@ -344,7 +358,7 @@ SecCertificateRef CERT_FindCertificateByIssuerAndSN (CFTypeRef keychainOrArray,
 
 // Generate a certificate key from the Subject Key ID, then look it up in the database.
 // Return the cert if found. "subjKeyID" is the Subject Key ID to look for
 
 // Generate a certificate key from the Subject Key ID, then look it up in the database.
 // Return the cert if found. "subjKeyID" is the Subject Key ID to look for
-static CFTypeRef CERT_FindBySubjectKeyID (CFTypeRef keychainOrArray, CFTypeRef class, const SecAsn1Item *subjKeyID)
+static CF_RETURNS_RETAINED CFTypeRef CERT_FindBySubjectKeyID (CFTypeRef keychainOrArray, CFTypeRef class, const SecAsn1Item *subjKeyID)
 {
     CFTypeRef ident = NULL;
     CFDictionaryRef query = NULL;
 {
     CFTypeRef ident = NULL;
     CFDictionaryRef query = NULL;
@@ -400,7 +414,7 @@ SecPublicKeyRef SECKEY_CopyPublicKey(SecPublicKeyRef pubKey)
     return pubKey;
 }
 
     return pubKey;
 }
 
-void SECKEY_DestroyPublicKey(SecPublicKeyRef pubKey)
+void SECKEY_DestroyPublicKey(SecPublicKeyRef CF_CONSUMED pubKey)
 {
     CFRelease(pubKey);
 }
 {
     CFRelease(pubKey);
 }