]> git.saurik.com Git - apple/security.git/blob - AppleX509CL/Session_Cert.cpp
Security-28.tar.gz
[apple/security.git] / AppleX509CL / Session_Cert.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 obtain
7 * a copy of the License at http://www.apple.com/publicsource and read it before
8 * 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 EXPRESS
12 * OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, INCLUDING WITHOUT
13 * LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
14 * PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. Please see the License for the
15 * specific language governing rights and limitations under the License.
16 */
17
18
19 //
20 // Session_Cert.cpp - cert-related session functions.
21 //
22
23 #include "AppleX509CLSession.h"
24 #include "DecodedCert.h"
25 #include "CLCachedEntry.h"
26 #include "cldebugging.h"
27 #include <Security/oidscert.h>
28
29 void
30 AppleX509CLSession::CertDescribeFormat(
31 uint32 &NumberOfFields,
32 CSSM_OID_PTR &OidList)
33 {
34 DecodedCert::describeFormat(*this, NumberOfFields, OidList);
35 }
36
37 void
38 AppleX509CLSession::CertGetAllFields(
39 const CssmData &Cert,
40 uint32 &NumberOfFields,
41 CSSM_FIELD_PTR &CertFields)
42 {
43 class DecodedCert decodedCert(*this, Cert);
44 decodedCert.getAllParsedCertFields(NumberOfFields, CertFields);
45 }
46
47
48 CSSM_HANDLE
49 AppleX509CLSession::CertGetFirstFieldValue(
50 const CssmData &EncodedCert,
51 const CssmData &CertField,
52 uint32 &NumberOfMatchedFields,
53 CSSM_DATA_PTR &Value)
54 {
55 NumberOfMatchedFields = 0;
56 Value = NULL;
57 CssmAutoData aData(*this);
58
59 DecodedCert *decodedCert = new DecodedCert(*this, EncodedCert);
60 uint32 numMatches;
61
62 /* this returns false if field not there, throws on bad OID */
63 bool brtn;
64 try {
65 brtn = decodedCert->getCertFieldData(CertField,
66 0, // index
67 numMatches,
68 aData);
69 }
70 catch (...) {
71 delete decodedCert;
72 throw;
73 }
74 if(!brtn) {
75 delete decodedCert;
76 return CSSM_INVALID_HANDLE;
77 }
78
79 /* cook up a CLCachedCert, stash it in cache */
80 CLCachedCert *cachedCert = new CLCachedCert(*decodedCert);
81 cacheMap.addEntry(*cachedCert, cachedCert->handle());
82
83 /* cook up a CLQuery, stash it */
84 CLQuery *query = new CLQuery(
85 CLQ_Cert,
86 CertField,
87 numMatches,
88 false, // isFromCache
89 cachedCert->handle());
90 queryMap.addEntry(*query, query->handle());
91
92 /* success - copy field data to outgoing Value */
93 Value = (CSSM_DATA_PTR)malloc(sizeof(CSSM_DATA));
94 *Value = aData.release();
95 NumberOfMatchedFields = numMatches;
96 return query->handle();
97 }
98
99
100 bool
101 AppleX509CLSession::CertGetNextFieldValue(
102 CSSM_HANDLE ResultsHandle,
103 CSSM_DATA_PTR &Value)
104 {
105 /* fetch & validate the query */
106 CLQuery *query = queryMap.lookupEntry(ResultsHandle);
107 if(query == NULL) {
108 CssmError::throwMe(CSSMERR_CL_INVALID_RESULTS_HANDLE);
109 }
110 if(query->nextIndex() >= query->numFields()) {
111 return false;
112 }
113
114 /* fetch the associated cached cert */
115 CLCachedCert *cachedCert = lookupCachedCert(query->cachedObject());
116 uint32 dummy;
117 CssmAutoData aData(*this);
118 if(!cachedCert->cert().getCertFieldData(query->fieldId(),
119 query->nextIndex(),
120 dummy,
121 aData)) {
122 return false;
123 }
124
125 /* success - copy field data to outgoing Value */
126 Value = (CSSM_DATA_PTR)malloc(sizeof(CSSM_DATA));
127 *Value = aData.release();
128 query->incrementIndex();
129 return true;
130 }
131
132 void
133 AppleX509CLSession::CertCache(
134 const CssmData &EncodedCert,
135 CSSM_HANDLE &CertHandle)
136 {
137 DecodedCert *decodedCert = new DecodedCert(*this, EncodedCert);
138
139 /* cook up a CLCachedCert, stash it in cache */
140 CLCachedCert *cachedCert = new CLCachedCert(*decodedCert);
141 cacheMap.addEntry(*cachedCert, cachedCert->handle());
142 CertHandle = cachedCert->handle();
143 }
144
145 CSSM_HANDLE
146 AppleX509CLSession::CertGetFirstCachedFieldValue(
147 CSSM_HANDLE CertHandle,
148 const CssmData &CertField,
149 uint32 &NumberOfMatchedFields,
150 CSSM_DATA_PTR &Value)
151 {
152 /* fetch the associated cached cert */
153 CLCachedCert *cachedCert = lookupCachedCert(CertHandle);
154 if(cachedCert == NULL) {
155 CssmError::throwMe(CSSMERR_CL_INVALID_CACHE_HANDLE);
156 }
157
158 CssmAutoData aData(*this);
159 uint32 numMatches;
160
161 /* this returns false if field not there, throws on bad OID */
162 if(!cachedCert->cert().getCertFieldData(CertField,
163 0, // index
164 numMatches,
165 aData)) {
166 return CSSM_INVALID_HANDLE;
167 }
168
169 /* cook up a CLQuery, stash it */
170 CLQuery *query = new CLQuery(
171 CLQ_Cert,
172 CertField,
173 numMatches,
174 true, // isFromCache
175 cachedCert->handle());
176 queryMap.addEntry(*query, query->handle());
177
178 /* success - copy field data to outgoing Value */
179 Value = (CSSM_DATA_PTR)malloc(sizeof(CSSM_DATA));
180 *Value = aData.release();
181 NumberOfMatchedFields = numMatches;
182 return query->handle();
183 }
184
185
186 bool
187 AppleX509CLSession::CertGetNextCachedFieldValue(
188 CSSM_HANDLE ResultsHandle,
189 CSSM_DATA_PTR &Value)
190 {
191 /* Identical to, so just call... */
192 return CertGetNextFieldValue(ResultsHandle, Value);
193 }
194
195 void
196 AppleX509CLSession::CertAbortCache(
197 CSSM_HANDLE CertHandle)
198 {
199 /* fetch the associated cached cert, remove from map, delete it */
200 CLCachedCert *cachedCert = lookupCachedCert(CertHandle);
201 if(cachedCert == NULL) {
202 errorLog0("CertAbortCache: cachedCert not found\n");
203 CssmError::throwMe(CSSMERR_CL_INVALID_CACHE_HANDLE);
204 }
205 cacheMap.removeEntry(cachedCert->handle());
206 delete cachedCert;
207 }
208
209 /*
210 * Abort either type of cert field query (cache based or non-cache based)
211 */
212 void
213 AppleX509CLSession::CertAbortQuery(
214 CSSM_HANDLE ResultsHandle)
215 {
216 /* fetch & validate the query */
217 CLQuery *query = queryMap.lookupEntry(ResultsHandle);
218 if(query == NULL) {
219 CssmError::throwMe(CSSMERR_CL_INVALID_RESULTS_HANDLE);
220 }
221
222 if(!query->fromCache()) {
223 /* the associated cached cert was created just for this query; dispose */
224 CLCachedCert *cachedCert = lookupCachedCert(query->cachedObject());
225 if(cachedCert == NULL) {
226 /* should never happen */
227 errorLog0("CertAbortQuery: cachedCert not found\n");
228 CssmError::throwMe(CSSMERR_CL_INTERNAL_ERROR);
229 }
230 cacheMap.removeEntry(cachedCert->handle());
231 delete cachedCert;
232 }
233 queryMap.removeEntry(query->handle());
234 delete query;
235 }
236
237 void
238 AppleX509CLSession::CertCreateTemplate(
239 uint32 NumberOfFields,
240 const CSSM_FIELD CertFields[],
241 CssmData &CertTemplate)
242 {
243 /* cook up an empty Cert */
244 DecodedCert cert(*this);
245
246 /* grind thru specified fields; exceptions are fatal */
247 for(uint32 dex=0; dex<NumberOfFields; dex++) {
248 cert.setCertField(
249 CssmOid::overlay(CertFields[dex].FieldOid),
250 CssmData::overlay(CertFields[dex].FieldValue));
251 }
252
253 /* TBD - ensure all required fields are set? We do this
254 * when we sign the cert; maybe we should do it here. */
255
256 /*
257 * We have the CertificateToSign in snacc format. Encode.
258 */
259 CssmRemoteData rData(*this, CertTemplate);
260 cert.encodeTbs(rData);
261 rData.release();
262 }
263
264
265 void
266 AppleX509CLSession::CertGetAllTemplateFields(
267 const CssmData &CertTemplate,
268 uint32 &NumberOfFields,
269 CSSM_FIELD_PTR &CertFields)
270 {
271 DecodedCert cert(*this); // empty
272 cert.decodeTbs(CertTemplate);
273 cert.getAllParsedCertFields(NumberOfFields, CertFields);
274 }
275
276 void
277 AppleX509CLSession::FreeFields(
278 uint32 NumberOfFields,
279 CSSM_FIELD_PTR &FieldArray)
280 {
281 unsigned i;
282 CSSM_FIELD_PTR thisField;
283 CSSM_OID_PTR thisOid;
284
285 for(i=0; i<NumberOfFields; i++) {
286 thisField = &FieldArray[i];
287 thisOid = &thisField->FieldOid;
288
289 /* oid-specific handling of value */
290 /* TBD - if this fails, call tbd DecodedCRL::freeCertFieldData */
291 /* BUG - the CssmRemoteData constructor clears the referent,
292 * iff the referent is a CSSSM_DATA (as opposed to a CssmData).
293 */
294 CssmData &cData = CssmData::overlay(thisField->FieldValue);
295 CssmRemoteData rData(*this, cData);
296 DecodedCert::freeCertFieldData(CssmOid::overlay(*thisOid), rData);
297
298 /* and the oid itself */
299 free(thisOid->Data);
300 thisOid->Data = NULL;
301 thisOid->Length = 0;
302 }
303 free(FieldArray);
304 }
305
306 void
307 AppleX509CLSession::FreeFieldValue(
308 const CssmData &CertOrCrlOid,
309 CssmData *Value)
310 {
311 if(Value == NULL) {
312 CssmError::throwMe(CSSM_ERRCODE_INVALID_FIELD_POINTER);
313 }
314 CssmRemoteData cd(*this, *Value);
315 /* TBD - if this fails, call tbd DecodedCRL::freeCertFieldData */
316 DecodedCert::freeCertFieldData(CertOrCrlOid, cd);
317 free(Value);
318 }
319
320 void
321 AppleX509CLSession::CertGroupFromVerifiedBundle(
322 CSSM_CC_HANDLE CCHandle,
323 const CSSM_CERT_BUNDLE &CertBundle,
324 const CssmData *SignerCert,
325 CSSM_CERTGROUP_PTR &CertGroup)
326 {
327 unimplemented();
328 }
329
330 void
331 AppleX509CLSession::CertGroupToSignedBundle(
332 CSSM_CC_HANDLE CCHandle,
333 const CSSM_CERTGROUP &CertGroupToBundle,
334 const CSSM_CERT_BUNDLE_HEADER *BundleInfo,
335 CssmData &SignedBundle)
336 {
337 unimplemented();
338 }
339
340 void
341 AppleX509CLSession::PassThrough(
342 CSSM_CC_HANDLE CCHandle,
343 uint32 PassThroughId,
344 const void *InputParams,
345 void **OutputParams)
346 {
347 unimplemented();
348 }