]> git.saurik.com Git - apple/security.git/blobdiff - SecureTransport/sslKeychain.cpp
Security-176.tar.gz
[apple/security.git] / SecureTransport / sslKeychain.cpp
index 9ad65d545e5ed9bae2a30f7da480af33d9649acb..28e372258f7aabc5d93ad021264a480c7c38b190 100644 (file)
 #include <string.h>
 #include <assert.h>
 #include <CoreServices/../Frameworks/CarbonCore.framework/Headers/MacErrors.h>
-#include <Security/cssm.h>
-/* these are to be replaced by Security/Security.h */
-#include <Security/SecCertificate.h>
-#include <Security/SecKeychainItem.h>
-#include <Security/SecKeychain.h>
-#include <Security/SecIdentity.h>
-#include <Security/SecIdentitySearch.h>
-#include <Security/SecKey.h>
-
-#if            ST_MANAGES_TRUSTED_ROOTS
-static OSStatus
-addCertData(
-       SSLContext              *ctx,
-       KCItemRef               kcItem,
-       CSSM_DATA_PTR   certData,
-       Boolean                 *goodCert);             /* RETURNED */
-#endif /* ST_MANAGES_TRUSTED_ROOTS */
+#include <Security/Security.h>
 
 /*
  * Given an array of certs (as SecIdentityRefs, specified by caller
@@ -103,20 +87,12 @@ parseIncomingCerts(
        CFArrayRef              certs,
        SSLCertificate  **destCert,             /* &ctx->{localCert,encryptCert} */
        CSSM_KEY_PTR    *pubKey,                /* &ctx->signingPubKey, etc. */
-       CSSM_KEY_PTR    *privKey,               /* &ctx->signingPrivKey, etc. */
-       CSSM_CSP_HANDLE *cspHand                /* &ctx->signingKeyCsp, etc. */
-       #if             ST_KC_KEYS_NEED_REF
-       ,
-       SecKeychainRef  *privKeyRef)    /* &ctx->signingKeyRef, etc. */
-       #else
-       )
-       #endif  /* ST_KC_KEYS_NEED_REF */
+       SecKeyRef               *privKeyRef)    /* &ctx->signingPrivKeyRef, etc. */
 {
        CFIndex                         numCerts;
        CFIndex                         cert;
        SSLCertificate          *certChain = NULL;
        SSLCertificate          *thisSslCert;
-       SecKeychainRef          kcRef;
        OSStatus                        ortn;
        SecIdentityRef          identity;
        SecCertificateRef       certRef;
@@ -128,14 +104,12 @@ parseIncomingCerts(
        assert(ctx != NULL);
        assert(destCert != NULL);               /* though its referent may be NULL */
        assert(pubKey != NULL);
-       assert(privKey != NULL);
-       assert(cspHand != NULL);
+       assert(privKeyRef != NULL);
        
        sslDeleteCertificateChain(*destCert, ctx);
        *destCert = NULL;
        *pubKey   = NULL;
-       *privKey  = NULL;
-       *cspHand  = 0;
+       *privKeyRef = NULL;
        
        if(certs == NULL) {
                sslErrorLog("parseIncomingCerts: NULL incoming cert array\n");
@@ -149,7 +123,7 @@ parseIncomingCerts(
        
        /* 
         * Certs[0] is an SecIdentityRef from which we extract subject cert,
-        * privKey, pubKey, and cspHand.
+        * privKeyRef, pubKey.
         *
         * 1. ensure the first element is a SecIdentityRef.
         */
@@ -164,7 +138,7 @@ parseIncomingCerts(
        }
        
        /* 
-        * 2. Extract cert, keys, CSP handle and convert to local format. 
+        * 2. Extract cert, keys and convert to local format. 
         */
        ortn = SecIdentityCopyCertificate(identity, &certRef);
        if(ortn) {
@@ -187,13 +161,7 @@ parseIncomingCerts(
                        (int)ortn);
                return ortn;
        }
-       ortn = SecKeyGetCSSMKey(keyRef, (const CSSM_KEY **)privKey);
-       if(ortn) {
-               sslErrorLog("parseIncomingCerts: SecKeyGetCSSMKey err %d\n",
-                       (int)ortn);
-               return ortn;
-       }
-       /* FIXME = release keyRef? */
+       *privKeyRef = keyRef;
        
        /* obtain public key from cert */
        ortn = SecCertificateGetCLHandle(certRef, &clHand);
@@ -210,20 +178,6 @@ parseIncomingCerts(
                return (OSStatus)crtn;
        }
        
-       /* obtain keychain from key, CSP handle from keychain */
-       ortn = SecKeychainItemCopyKeychain((SecKeychainItemRef)keyRef, &kcRef);
-       if(ortn) {
-               sslErrorLog("parseIncomingCerts: SecKeychainItemCopyKeychain err %d\n",
-                       (int)ortn);
-               return ortn;
-       }
-       ortn = SecKeychainGetCSPHandle(kcRef, cspHand);
-       if(ortn) {
-               sslErrorLog("parseIncomingCerts: SecKeychainGetCSPHandle err %d\n",
-                       (int)ortn);
-               return ortn;
-       }
-       
        /* OK, that's the subject cert. Fetch optional remaining certs. */
        /* 
         * Convert: CFArray of SecCertificateRefs --> chain of SSLCertificates. 
@@ -253,12 +207,6 @@ parseIncomingCerts(
                certChain = thisSslCert;
        }
        
-       /* validate the whole mess, skipping host name verify */
-       ortn = sslVerifyCertChain(ctx, *certChain, false);
-       if(ortn) {
-               goto errOut;
-       }
-               
        /* SUCCESS */ 
        *destCert = certChain;
        return noErr;
@@ -270,318 +218,4 @@ errOut:
        return ortn;
 }
 
-/*
- * Add Apple built-in root certs to ctx->trustedCerts.
- */
-OSStatus addBuiltInCerts       (SSLContextRef          ctx)
-{
-       #if             ST_MANAGES_TRUSTED_ROOTS
-       OSStatus                        ortn;
-       KCRef                           kc = nil;
-       
-       ortn = KCDispatch(kKCGetRootCertificateKeychain, &kc);
-       if(ortn) {
-               sslErrorLog("KCDispatch(kKCGetRootCertificateKeychain) returned %d\n", 
-                       ortn);
-               return ortn;
-       }
-       return parseTrustedKeychain(ctx, kc);
-       #else
-       /* nothing for now */
-       return noErr;
-       #endif  /* ST_MANAGES_TRUSTED_ROOTS */
-}
-
-#if            ST_MANAGES_TRUSTED_ROOTS
-
-/*
- * Given an open Keychain:
- * -- Get raw cert data, add to array of CSSM_DATAs in 
- *    ctx->trustedCerts 
- * -- verify that each of these is a valid (self-verifying)
- *    root cert
- * -- add each subject name to acceptableDNList
- */
-OSStatus
-parseTrustedKeychain           (SSLContextRef          ctx,
-                                                        KCRef                          keyChainRef)
-{
-       CFMutableArrayRef       kcCerts = NULL;         /* all certs in one keychain */
-       uint32                          numGoodCerts = 0;       /* # of good root certs */
-       CSSM_DATA_PTR           certData = NULL;        /* array of CSSM_DATAs */
-       CFIndex                         certDex;                        /* index into kcCerts */
-       CFIndex                         certsPerKc;                     /* # of certs in this KC */
-       OSStatus                        ortn;
-       KCItemRef                       kcItem;                         /* one cert */
-       Boolean                         goodCert;
-       
-       assert(ctx != NULL);
-       if(keyChainRef == NULL) {
-               return paramErr;
-       }
-       
-       ortn = KCFindX509Certificates(keyChainRef,
-               NULL,                           // name, XXX
-               NULL,                           // emailAddress, XXX
-               kCertSearchAny,         // options
-               &kcCerts);                      // results
-       switch(ortn) {
-               case noErr:
-                       break;                                  // proceed
-               case errKCItemNotFound:
-                       return noErr;                   // no certs; done
-               default:
-                       sslErrorLog("parseTrustedKeychains: KCFindX509Certificates returned %d\n",
-                               ortn);
-                       return ortn;
-       }
-       if(kcCerts == NULL) {
-               sslErrorLog("parseTrustedKeychains: no certs in KC\n");
-               return noErr;
-       }
-       
-       /* Note kcCerts must be released on any exit, successful or
-        * otherwise. */
-       
-       certsPerKc = CFArrayGetCount(kcCerts);  
-
-       /* 
-        * This array gets allocd locally; we'll add it to 
-        * ctx->trustedCerts when we're done.
-        */
-       certData = sslMalloc(certsPerKc * sizeof(CSSM_DATA));
-       if(certData == NULL) {
-               ortn = memFullErr;
-               goto errOut;
-       }
-       memset(certData, 0, certsPerKc * sizeof(CSSM_DATA));
-       
-       /* 
-        * Build up local certData one root cert at a time. 
-        * Some certs might not pass muster, hence the numGoodCerts
-        * which may or may not increment each time thru.
-        */
-       for(certDex=0; certDex<certsPerKc; certDex++) {
-               kcItem = (KCItemRef)CFArrayGetValueAtIndex(kcCerts, certDex);
-               if(kcItem == NULL) {
-                       sslErrorLog("parseTrustedKeychains: CF error 1\n");
-                       ortn = errSSLInternal;
-                       goto errOut;
-               }
-               if(!KCIsRootCertificate(kcItem)) {
-                       /* not root, OK, skip to next cert */
-                       sslErrorLog("parseTrustedKeychains: cert %d NOT ROOT\n",
-                                       certDex);
-                       continue;
-               }
-               ortn = addCertData(ctx,
-                       kcItem, 
-                       &certData[numGoodCerts], 
-                       &goodCert);
-               if(ortn) {
-                       goto errOut;
-               }
-               if(goodCert) {
-                       /* added valid root to certData */
-                       numGoodCerts++;
-               }
-       }       /* for each cert in kcCerts */
-
-       #if     SSL_DEBUG
-       verifyTrustedRoots(ctx, certData, numGoodCerts);
-       #endif
-
-       /* Realloc ctx->trustedCerts, add new root certs */
-       ctx->trustedCerts = sslRealloc(ctx->trustedCerts, 
-               ctx->numTrustedCerts * sizeof(CSSM_DATA),
-               (ctx->numTrustedCerts + numGoodCerts) * sizeof(CSSM_DATA));
-       if(ctx->trustedCerts == NULL) {
-               ortn = memFullErr;
-               goto errOut;
-       }
-       for(certDex=0; certDex<numGoodCerts; certDex++) {
-               ctx->trustedCerts[ctx->numTrustedCerts + certDex] = certData[certDex];
-       }
-       ctx->numTrustedCerts += numGoodCerts;
-       ortn = noErr;
-       
-       #if     SSL_DEBUG
-       verifyTrustedRoots(ctx, ctx->trustedCerts, ctx->numTrustedCerts);
-       #endif
-       
-errOut:
-       sslFree(certData);
-       if(kcCerts != NULL) {
-               CFRelease(kcCerts);
-       }
-       return ortn;
-}
-
-/*
- * Given a (supposedly) root cert as a KCItemRef:
- * -- verify that the cert self-verifies
- * -- add its DER-encoded data *certData.
- * -- Add its subjectName to acceptableDNList.
- * -- If all is well, return True in *goodCert.
- *
- * The actual CSSM_DATA.Data is mallocd via CSSM_Malloc. 
- */
-static OSStatus
-addCertData(
-       SSLContext              *ctx,
-       KCItemRef               kcItem,
-       CSSM_DATA_PTR   certData,
-       Boolean                 *goodCert)              /* RETURNED */
-{      
-       UInt32                  certSize;
-       OSStatus                ortn;
-       CSSM_BOOL               subjectExpired;
-       
-       assert(ctx != NULL);
-       assert(certData != NULL);       
-       assert(kcItem != NULL);
-       assert(goodCert != NULL);
-       
-       *goodCert = false; 
-       
-       /* how big is the cert? */
-       ortn = KCGetData (kcItem, 0,  NULL, &certSize);
-       if(ortn != noErr) {
-               sslErrorLog("addCertData: KCGetData(1) returned %d\n", ortn);
-               return ortn;
-       }
-
-       /* Allocate the buffer. */
-       ortn = stSetUpCssmData(certData, certSize);
-       if(ortn) {
-               return ortn;
-       }
-       
-       /* Get the data. */
-       ortn = KCGetData (kcItem, certSize, certData->Data, &certSize);
-       if(ortn) {
-               sslErrorLog("addCertData: KCGetData(2) returned %d\n", ortn);
-               stFreeCssmData(certData, CSSM_FALSE);
-               return ortn;
-       }
-
-       /* 
-        * Do actual cert verify, which 
-     * KCIsRootCertificate does not do. A failure isn't
-     * fatal; we just don't add the cert to the array in
-     * that case.
-     *
-     * FIXME - we assume here that our common cspHand can
-     * do this cert verify; if not, we have some API work to 
-     * do (to let the caller specify which CSP to use with 
-     * trusted certs).
-     */
-       if(!sslVerifyCert(ctx,  
-                       certData,
-                       certData,
-                       ctx->cspHand,
-                       &subjectExpired)) {                     
-               sslErrorLog("addCertData: cert does not self-verify!\n");
-               stFreeCssmData(certData, CSSM_FALSE);
-               return noErr;
-       }
-       
-       /* FIXME - needs update for MANAGES_TRUSTED_ROOTS */
-       /* Add this cert's subject name to (poss. existing) acceptableDNList */
-       CSSM_DATA_PTR dnData = sslGetCertSubjectName(ctx, certData);
-       if(dnData) {
-               DNListElem *dn = sslMalloc(sizeof(DNListElem));
-               if(dn == NULL) {
-                       return memFullErr;
-               }
-               dn->next = ctx->acceptableDNList;
-               ctx->acceptableDNList = dn;
-               
-               /* move actual data to dn; free the CSSM_DATA struct (must be
-                * via CSSM_Free()!) */
-               CSSM_TO_SSLBUF(dnData, &dn->derDN);
-               sslFree(dnData);
-       }
-       
-       *goodCert = true;
-       return noErr;
-}
-
-/*
- * Given a newly encountered root cert (obtained from a peer's cert chain),
- * add it to newRootCertKc if the user so allows, and if so, add it to 
- * trustedCerts.
- */
-OSStatus
-sslAddNewRoot(
-       SSLContext                      *ctx, 
-       const CSSM_DATA_PTR     rootCert)
-{
-       KCRef                   defaultKc;
-       Boolean                 bDefaultKcExists;
-       KCItemRef               certRef = NULL;
-       OSStatus                ortn;
-       CSSM_DATA_PTR   newTrustee;
-       OSStatus                        serr;
-       
-       assert(ctx != NULL);
-       assert(rootCert != NULL);
-       assert(ctx->newRootCertKc != NULL);     /* caller verifies this */
-       
-       /*
-        * Get default KC, temporarily set new default.
-        */
-       ortn = KCGetDefaultKeychain(&defaultKc);
-       if(ortn) {
-               bDefaultKcExists = false;
-       }
-       else {
-               bDefaultKcExists = true;
-       }
-       ortn = KCSetDefaultKeychain(ctx->newRootCertKc);
-       if(ortn) {
-               sslErrorLog("sslAddNewRoot: KCSetDefaultKeychain returned %d\n", ortn);
-               return errSSLUnknownRootCert;
-       }
-
-       /*      
-        * Add cert to newRootCertKc. This may well fail due to user
-        * interaction ("Do you want to add this root cert...?").
-        */
-       ortn = KCAddX509Certificate(rootCert->Data, rootCert->Length, &certRef);
-       
-       /* restore default KC in any case */
-       if(bDefaultKcExists) {
-               KCSetDefaultKeychain(defaultKc);
-       }
-       if(ortn) {
-               sslErrorLog("sslAddNewRoot: KCAddX509Certificate returned %d\n", ortn);
-               return errSSLUnknownRootCert;
-       }
-
-       /* 
-        * OK, user accepted new root. Now add to our private stash of 
-        * trusted roots. Realloc the whole pile... 
-        */
-       ctx->trustedCerts = (CSSM_DATA_PTR)sslRealloc(ctx->trustedCerts,
-               (ctx->numTrustedCerts * sizeof(CSSM_DATA)),
-               ((ctx->numTrustedCerts + 1) * sizeof(CSSM_DATA)));
-       if(ctx->trustedCerts == NULL) {
-               return memFullErr;
-       }
-       
-       /* Now add a copy of the new root. */
-       newTrustee = &ctx->trustedCerts[ctx->numTrustedCerts];
-       newTrustee->Data = NULL;
-       newTrustee->Length = 0;
-       serr = stSetUpCssmData(newTrustee, rootCert->Length);
-       if(serr) {
-               return serr;
-       }
-       BlockMove(rootCert->Data, newTrustee->Data, rootCert->Length);
-       (ctx->numTrustedCerts)++;
-       return noErr;
-}
-
-#endif /* ST_MANAGES_TRUSTED_ROOTS */