+++ /dev/null
-/*
- * crypto-embedded.c
- * libsecurity_smime
- *
- * Created by Conrad Sauerwald on 2/7/08.
- * Copyright (c) 2008-2011,2013 Apple Inc. All Rights Reserved.
- *
- */
-
-#include <stdio.h>
-
-#include "cert.h"
-#include "cryptohi.h"
-
-#include "cmstpriv.h"
-#include "secoid.h"
-#include "cmspriv.h"
-
-#include <libDER/DER_Decode.h>
-#include <security_asn1/secerr.h>
-#include <security_asn1/secport.h>
-
-#include <Security/SecBase.h>
-
-#include <CoreFoundation/CFNumber.h>
-#include <CoreFoundation/CFString.h>
-
-#include <Security/oidsalg.h>
-#include <Security/SecPolicy.h>
-#include <Security/SecItem.h>
-#include <Security/SecIdentity.h>
-#include <Security/SecCertificateInternal.h>
-#include <Security/SecKeyPriv.h>
-
-#include <CommonCrypto/CommonDigest.h>
-#include <AssertMacros.h>
-
-SECStatus
-CERT_VerifyCert(SecKeychainRef keychainOrArray __unused, CFArrayRef certs,
- CFTypeRef policies, CFAbsoluteTime stime, SecTrustRef *trustRef)
-{
- SecTrustRef trust = NULL;
- OSStatus rv;
-
- rv = SecTrustCreateWithCertificates(certs, policies, &trust);
- if (rv)
- goto loser;
-
- CFDateRef verifyDate = CFDateCreate(NULL, stime);
- rv = SecTrustSetVerifyDate(trust, verifyDate);
- CFRelease(verifyDate);
- if (rv)
- goto loser;
-
- if (trustRef)
- {
- *trustRef = trust;
- }
- else
- {
- SecTrustResultType result;
- /* The caller doesn't want a SecTrust object, so let's evaluate it for them. */
- rv = SecTrustEvaluate(trust, &result);
- if (rv)
- goto loser;
-
- switch (result)
- {
- case kSecTrustResultProceed:
- case kSecTrustResultUnspecified:
- /* TP Verification succeeded and there was either a UserTurst entry
- telling us to procceed, or no user trust setting was specified. */
- CFRelease(trust);
- break;
- default:
- PORT_SetError(SEC_ERROR_UNTRUSTED_CERT);
- rv = SECFailure;
- goto loser;
- break;
- }
- }
-
- return SECSuccess;
-loser:
- if (trust)
- CFRelease(trust);
-
- return rv;
-}
-
-
-SecCertificateRef CERT_FindUserCertByUsage(SecKeychainRef keychainOrArray,
- char *nickname,SECCertUsage usage,Boolean validOnly,void *proto_win)
-{
- CFStringRef nickname_cfstr = CFStringCreateWithCString(kCFAllocatorDefault, nickname, kCFStringEncodingUTF8);
- const void *keys[] = { kSecClass, kSecAttrLabel };
- const void *values[] = { kSecClassCertificate, nickname_cfstr };
- CFDictionaryRef query = CFDictionaryCreate(kCFAllocatorDefault, keys, values, sizeof(keys)/sizeof(*keys), NULL, NULL);
- CFTypeRef result = NULL;
- SecItemCopyMatching(query, &result);
- CFRelease(query);
- CFRelease(nickname_cfstr);
- return (SecCertificateRef)result;
-}
-
-CF_RETURNS_RETAINED CFArrayRef CERT_CertChainFromCert(SecCertificateRef cert, SECCertUsage usage, Boolean includeRoot)
-{
- CFMutableArrayRef certs = NULL;
- SecPolicyRef policy = NULL;
- SecTrustRef trust = NULL;
- CFArrayRef wrappedCert = NULL;
-
- policy = SecPolicyCreateBasicX509();
- if (!policy)
- goto out;
-
- wrappedCert = CERT_CertListFromCert(cert);
- if (SecTrustCreateWithCertificates(wrappedCert, policy, &trust))
- goto out;
-
- SecTrustResultType result;
- if (SecTrustEvaluate(trust, &result))
- goto out;
- CFIndex idx, count = SecTrustGetCertificateCount(trust);
- certs = CFArrayCreateMutable(kCFAllocatorDefault, count, &kCFTypeArrayCallBacks);
- for(idx = 0; idx < count; idx++)
- CFArrayAppendValue(certs, SecTrustGetCertificateAtIndex(trust, idx));
-
-out:
- if (trust) CFRelease(trust);
- if (policy) CFRelease(policy);
- if (wrappedCert) CFRelease(wrappedCert);
-
- return certs;
-}
-
-CFArrayRef CERT_CertListFromCert(SecCertificateRef cert)
-{
- const void *value = cert;
- return cert ? CFArrayCreate(NULL, &value, 1, &kCFTypeArrayCallBacks) : NULL;
-}
-
-CFArrayRef CERT_DupCertList(CFArrayRef oldList)
-{
- CFRetain(oldList);
- return oldList;
-}
-
-// Extract a public key object from a SubjectPublicKeyInfo
-SecPublicKeyRef CERT_ExtractPublicKey(SecCertificateRef cert)
-{
- return SecCertificateCopyPublicKey(cert);
-}
-
-// Extract the issuer and serial number from a certificate
-SecCmsIssuerAndSN *CERT_GetCertIssuerAndSN(PRArenaPool *pl, SecCertificateRef cert)
-{
- SecCmsIssuerAndSN *certIssuerAndSN;
-
- void *mark;
- mark = PORT_ArenaMark(pl);
- CFDataRef serial_data = NULL;
- CFDataRef issuer_data = SecCertificateCopyIssuerSequence(cert);
- if (!issuer_data)
- goto loser;
- serial_data = SecCertificateCopySerialNumber(cert);
- if (!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. */
- certIssuerAndSN = (SecCmsIssuerAndSN *)PORT_ArenaZAlloc (pl, sizeof(SecCmsIssuerAndSN));
- if (certIssuerAndSN == NULL)
- goto loser;
-
- /* Copy the issuer. */
- certIssuerAndSN->derIssuer.Data = (uint8_t *) PORT_ArenaAlloc(pl, issuer.Length);
- 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;
- PORT_Memcpy(certIssuerAndSN->serialNumber.Data, serialNumber.Data, serialNumber.Length);
- certIssuerAndSN->serialNumber.Length = serialNumber.Length;
-
- CFRelease(serial_data);
- CFRelease(issuer_data);
-
- PORT_ArenaUnmark(pl, mark);
-
- return certIssuerAndSN;
-
-loser:
- if (serial_data)
- CFRelease(serial_data);
- if (issuer_data)
- CFRelease(issuer_data);
- PORT_ArenaRelease(pl, mark);
- PORT_SetError(SEC_INTERNAL_ONLY);
-
- return NULL;
-}
-
-// find the smime symmetric capabilities profile for a given cert
-SecAsn1Item *CERT_FindSMimeProfile(SecCertificateRef cert)
-{
- return NULL;
-}
-
-// 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)
-{
- CFTypeRef ident = NULL;
- CFDictionaryRef query = NULL;
- CFDataRef issuer = NULL;
- CFDataRef serial = CFDataCreateWithBytesNoCopy(kCFAllocatorDefault,
- issuerAndSN->serialNumber.Data, issuerAndSN->serialNumber.Length,
- kCFAllocatorNull);
-
- DERItem der_issuer = { issuerAndSN->derIssuer.Data,
- issuerAndSN->derIssuer.Length };
- DERDecodedInfo content;
- require_noerr_quiet(DERDecodeItem(&der_issuer, &content), out);
- require_quiet(issuer = createNormalizedX501Name(kCFAllocatorDefault,
- &content.content), out);
-
- if (keychainOrArray && (CFGetTypeID(keychainOrArray) == CFArrayGetTypeID()) && CFEqual(class, kSecClassCertificate))
- {
- CFIndex c, count = CFArrayGetCount((CFArrayRef)keychainOrArray);
- for (c = 0; c < count; c++) {
- SecCertificateRef cert = (SecCertificateRef)CFArrayGetValueAtIndex((CFArrayRef)keychainOrArray, c);
- CFDataRef nic = (cert) ? SecCertificateGetNormalizedIssuerContent(cert) : NULL;
- if (nic && CFEqual(nic, issuer)) {
- CFDataRef cert_serial = SecCertificateCopySerialNumber(cert);
- if (cert_serial) {
- bool found = CFEqual(cert_serial, serial);
- CFRelease(cert_serial);
- if (found) {
- CFRetain(cert);
- ident = cert;
- goto out;
- }
- }
- }
- }
- }
-
- const void *keys[] = { kSecClass, kSecAttrIssuer, kSecAttrSerialNumber, kSecReturnRef };
- const void *values[] = { class, issuer, serial, kCFBooleanTrue };
- query = CFDictionaryCreate(kCFAllocatorDefault, keys, values, sizeof(keys)/sizeof(*keys), NULL, NULL);
- require_noerr_quiet(SecItemCopyMatching(query, (CFTypeRef*)&ident), out);
-
-out:
- if (query)
- CFRelease(query);
- if (issuer)
- CFRelease(issuer);
- if (serial)
- CFRelease(serial);
-
- return ident;
-}
-
-SecIdentityRef CERT_FindIdentityByIssuerAndSN (CFTypeRef keychainOrArray, const SecCmsIssuerAndSN *issuerAndSN)
-{
- return (SecIdentityRef)CERT_FindByIssuerAndSN(keychainOrArray, kSecClassIdentity, issuerAndSN);
-}
-
-SecCertificateRef CERT_FindCertificateByIssuerAndSN (CFTypeRef keychainOrArray, const SecCmsIssuerAndSN *issuerAndSN)
-{
- return (SecCertificateRef)CERT_FindByIssuerAndSN(keychainOrArray, kSecClassCertificate, issuerAndSN);
-}
-
-SecIdentityRef CERT_FindIdentityBySubjectKeyID (CFTypeRef keychainOrArray __unused, const SecAsn1Item *subjKeyID)
-{
- SecIdentityRef ident = NULL;
- CFDictionaryRef query = NULL;
- CFDataRef subjectkeyid = CFDataCreateWithBytesNoCopy(kCFAllocatorDefault, subjKeyID->Data, subjKeyID->Length, kCFAllocatorNull);
-
- const void *keys[] = { kSecClass, kSecAttrSubjectKeyID, kSecReturnRef };
- const void *values[] = { kSecClassIdentity, subjectkeyid, kCFBooleanTrue };
- query = CFDictionaryCreate(kCFAllocatorDefault, keys, values, sizeof(keys)/sizeof(*keys), NULL, NULL);
- require_noerr_quiet(SecItemCopyMatching(query, (CFTypeRef*)&ident), out);
-
-out:
- if (query)
- CFRelease(query);
- if (subjectkeyid)
- CFRelease(subjectkeyid);
-
- return ident;
-}
-
-
-
-SecPublicKeyRef SECKEY_CopyPublicKey(SecPublicKeyRef pubKey)
-{
- CFRetain(pubKey);
- return pubKey;
-}
-
-void SECKEY_DestroyPublicKey(SecPublicKeyRef pubKey)
-{
- CFRelease(pubKey);
-}
-
-SecPublicKeyRef SECKEY_CopyPrivateKey(SecPublicKeyRef privKey)
-{
- CFRetain(privKey);
- return privKey;
-}
-
-void SECKEY_DestroyPrivateKey(SecPublicKeyRef privKey)
-{
- CFRelease(privKey);
-}
-
-void CERT_DestroyCertificate(SecCertificateRef cert)
-{
- CFRelease(cert);
-}
-
-SecCertificateRef CERT_DupCertificate(SecCertificateRef cert)
-{
- CFRetain(cert);
- return cert;
-}
-
-SECStatus
-WRAP_PubWrapSymKey(SecPublicKeyRef publickey,
- SecSymmetricKeyRef bulkkey,
- SecAsn1Item * encKey)
-{
- return SecKeyEncrypt(publickey, kSecPaddingPKCS1,
- CFDataGetBytePtr(bulkkey), CFDataGetLength(bulkkey),
- encKey->Data, &encKey->Length);
-}
-
-SecSymmetricKeyRef
-WRAP_PubUnwrapSymKey(SecPrivateKeyRef privkey, const SecAsn1Item *encKey, SECOidTag bulkalgtag)
-{
- size_t bulkkey_size = encKey->Length;
- uint8_t bulkkey_buffer[bulkkey_size];
- if (SecKeyDecrypt(privkey, kSecPaddingPKCS1,
- encKey->Data, encKey->Length, bulkkey_buffer, &bulkkey_size))
- return NULL;
-
- CFDataRef bulkkey = CFDataCreate(kCFAllocatorDefault, bulkkey_buffer, bulkkey_size);
- return (SecSymmetricKeyRef)bulkkey;
-}
-
-
-bool
-CERT_CheckIssuerAndSerial(SecCertificateRef cert, SecAsn1Item *issuer, SecAsn1Item *serial)
-{
- do {
- CFDataRef cert_issuer = SecCertificateCopyIssuerSequence(cert);
- if (!cert_issuer)
- break;
- if ((issuer->Length != (size_t)CFDataGetLength(cert_issuer)) ||
- memcmp(issuer->Data, CFDataGetBytePtr(cert_issuer), issuer->Length)) {
- CFRelease(cert_issuer);
- break;
- }
- CFRelease(cert_issuer);
- CFDataRef cert_serial = SecCertificateCopySerialNumber(cert);
- if (!cert_serial)
- break;
- if ((serial->Length != (size_t)CFDataGetLength(cert_serial)) ||
- memcmp(serial->Data, CFDataGetBytePtr(cert_serial), serial->Length)) {
- CFRelease(cert_serial);
- break;
- }
- CFRelease(cert_serial);
- return true;
- } while(0);
- return false;
-}