]> git.saurik.com Git - apple/security.git/blob - AppleX509TP/rootCerts.cpp
Security-54.1.9.tar.gz
[apple/security.git] / AppleX509TP / rootCerts.cpp
1 /*
2 * Copyright (c) 2000-2001 Apple Computer, Inc. All Rights Reserved.
3 *
4 * The contents of this file constitute Original Code as defined in and are
5 * subject to the Apple Public Source License Version 1.2 (the 'License').
6 * You may not use this file except in compliance with the License. Please
7 * obtain a copy of the License at http://www.apple.com/publicsource and
8 * read it before using this file.
9 *
10 * This Original Code and all software distributed under the License are
11 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
12 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
13 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, FITNESS
14 * FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. Please
15 * see the License for the specific language governing rights and
16 * limitations under the License.
17 */
18
19
20 /*
21 File: rootCerts.cp
22
23 Contains: Bridge between SecTrustGetCSSMAnchorCertificates() and
24 TP's internally cached tpRootCert array.
25
26 Written by: Doug Mitchell.
27
28 Copyright: Copyright 2002 by Apple Computer, Inc., all rights reserved.
29
30 */
31
32 #include "rootCerts.h"
33 #include "certGroupUtils.h"
34 #include <Security/Trust.h>
35 #include <Security/TrustStore.h>
36 #include <Security/debugging.h>
37 #include <Security/oidscert.h>
38
39 /* static in TPRootStore */
40 ModuleNexus<TPRootStore> TPRootStore::tpGlobalRoots;
41
42 TPRootStore::~TPRootStore()
43 {
44 /*
45 * Technically this never gets called because the only instance
46 * of a TPRootStore is via tpGlobalRoots. Freeing mRootCerts
47 * here really doesn't accomplish anything.
48 */
49 }
50
51 const tpRootCert *TPRootStore::rootCerts(
52 CSSM_CL_HANDLE clHand,
53 unsigned &numRootCerts)
54 {
55 StLock<Mutex> _(mLock);
56 if(mRootCerts) {
57 numRootCerts = mNumRootCerts;
58 return mRootCerts;
59 }
60
61 CssmAllocator &alloc(CssmAllocator::standard());
62 CertGroup roots;
63 tpRootCert *tpRoots = NULL; // copy to mRootCerts on success
64 unsigned numTpRoots = 0;
65
66 try {
67 /* Obtain system-wide root certs in blob format */
68 Security::KeychainCore::TrustStore &trustStore =
69 Security::KeychainCore::Trust::gStore();
70 trustStore.getCssmRootCertificates(roots);
71 if(roots.type() != CSSM_CERTGROUP_DATA) {
72 debug("tpAnchor", "Bad certGroup Type (%d)\n",
73 (int)roots.type());
74 return NULL;
75 }
76 numTpRoots = roots.count();
77 if(numTpRoots == 0) {
78 debug("tpAnchor", "empty certGroup\n");
79 return NULL;
80 }
81
82 /* set up tpRoots array, one for each cert in the group */
83 tpRoots =
84 (tpRootCert *)alloc.malloc(numTpRoots * sizeof(tpRootCert));
85 memset(tpRoots, 0, numTpRoots * sizeof(tpRootCert));
86 for(uint32 certNum=0; certNum<numTpRoots; certNum++) {
87 tpRootCert *tpRoot = &tpRoots[certNum];
88 const CSSM_DATA *certData = &((roots.blobCerts())[certNum]);
89
90 /* extract normalized subject name */
91 CSSM_DATA *field;
92 CSSM_HANDLE ResultsHandle;
93 uint32 numFields;
94 CSSM_RETURN crtn;
95 crtn = CSSM_CL_CertGetFirstFieldValue(
96 clHand,
97 certData,
98 &CSSMOID_X509V1SubjectName,
99 &ResultsHandle,
100 &numFields,
101 &field);
102 if(crtn) {
103 debug("tpAnchor", "GetFirstFieldValue error on cert %u",
104 (unsigned)certNum);
105 continue;
106 }
107 CSSM_CL_CertAbortQuery(clHand, ResultsHandle);
108 tpCopyCssmData(alloc, field, &tpRoot->subjectName);
109 CSSM_CL_FreeFieldValue(clHand, &CSSMOID_X509V1SubjectName,
110 field);
111
112 /* extract public key info - the blob and key size in bits */
113 CSSM_KEY_PTR key;
114 crtn = CSSM_CL_CertGetKeyInfo(clHand, certData, &key);
115 if(crtn) {
116 debug("tpAnchor", "CSSM_CL_CertGetKeyInfo error on cert %u",
117 (unsigned)certNum);
118 /* clear out this tpRoot? */
119 continue;
120 }
121 tpCopyCssmData(alloc, &key->KeyData, &tpRoot->publicKey);
122 tpRoot->keySize = key->KeyHeader.LogicalKeySizeInBits;
123
124 /* A hole in the CDSA API: there is no free function at the
125 * CL API for this key. It got mallocd with clHand's
126 * allocator....
127 */
128 CSSM_API_MEMORY_FUNCS memFuncs;
129 crtn = CSSM_GetAPIMemoryFunctions(clHand, &memFuncs);
130 if(crtn) {
131 debug("tpAnchor", "CSSM_GetAPIMemoryFunctions error");
132 /* Oh well.. */
133 continue;
134 }
135 memFuncs.free_func(key->KeyData.Data, memFuncs.AllocRef);
136 memFuncs.free_func(key, memFuncs.AllocRef);
137 } /* main loop */
138 }
139 catch(...) {
140 /* TBD */
141 return NULL;
142 }
143 mNumRootCerts = numTpRoots;
144 numRootCerts = mNumRootCerts;
145 mRootCerts = tpRoots;
146 return mRootCerts;
147 }