X-Git-Url: https://git.saurik.com/apple/security.git/blobdiff_plain/0e1db9d189370fed9f1993183ec38d748a8812f7..refs/heads/master:/libsecurity_smime/lib/crypto-embedded.c diff --git a/libsecurity_smime/lib/crypto-embedded.c b/libsecurity_smime/lib/crypto-embedded.c index da4b7956..8e9a4b9b 100644 --- a/libsecurity_smime/lib/crypto-embedded.c +++ b/libsecurity_smime/lib/crypto-embedded.c @@ -46,6 +46,7 @@ #include #include #include +#include #include #include @@ -91,7 +92,6 @@ CERT_VerifyCert(SecKeychainRef keychainOrArray __unused, CFArrayRef certs, PORT_SetError(SEC_ERROR_UNTRUSTED_CERT); rv = SECFailure; goto loser; - break; } } @@ -103,7 +103,7 @@ loser: 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; @@ -151,7 +151,7 @@ SecCertificateRef CERT_FindUserCertByUsage(SecKeychainRef keychainOrArray, 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; @@ -159,16 +159,19 @@ CF_RETURNS_RETAINED CFArrayRef CERT_CertChainFromCert(SecCertificateRef cert, SE CFArrayRef wrappedCert = NULL; policy = SecPolicyCreateBasicX509(); - if (!policy) + if (!policy) { goto out; + } wrappedCert = CERT_CertListFromCert(cert); - if (SecTrustCreateWithCertificates(wrappedCert, policy, &trust)) + if (SecTrustCreateWithCertificates(wrappedCert, policy, &trust)) { goto out; + } SecTrustResultType result; - if (SecTrustEvaluate(trust, &result)) + if (SecTrustEvaluate(trust, &result)) { goto out; + } 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); - 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); } + + // 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. */ - if (!includeRoot && count > 1) { count--; } + if (isSelfSigned && !includeRoot && count > 1) { + count--; + } certs = CFArrayCreateMutable(kCFAllocatorDefault, count, &kCFTypeArrayCallBacks); - for(idx = 0; idx < count; idx++) + for(idx = 0; idx < count; idx++) { CFArrayAppendValue(certs, SecTrustGetCertificateAtIndex(trust, idx)); + } 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; } -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; @@ -221,35 +232,40 @@ SecCmsIssuerAndSN *CERT_GetCertIssuerAndSN(PRArenaPool *pl, SecCertificateRef ce void *mark; mark = PORT_ArenaMark(pl); - CFDataRef serial_data = NULL; 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; - - 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)); - if (certIssuerAndSN == NULL) - goto loser; + if (certIssuerAndSN == NULL) { + goto loser; + } /* 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); - 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; @@ -257,14 +273,12 @@ SecCmsIssuerAndSN *CERT_GetCertIssuerAndSN(PRArenaPool *pl, SecCertificateRef ce CFRelease(issuer_data); PORT_ArenaUnmark(pl, mark); - + 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); @@ -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 -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; @@ -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 -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; @@ -400,7 +414,7 @@ SecPublicKeyRef SECKEY_CopyPublicKey(SecPublicKeyRef pubKey) return pubKey; } -void SECKEY_DestroyPublicKey(SecPublicKeyRef pubKey) +void SECKEY_DestroyPublicKey(SecPublicKeyRef CF_CONSUMED pubKey) { CFRelease(pubKey); }