]> git.saurik.com Git - apple/security.git/blame - AppleX509CL/Session_Cert.cpp
Security-54.1.3.tar.gz
[apple/security.git] / AppleX509CL / Session_Cert.cpp
CommitLineData
bac41a7b
A
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
29void
30AppleX509CLSession::CertDescribeFormat(
31 uint32 &NumberOfFields,
32 CSSM_OID_PTR &OidList)
33{
34 DecodedCert::describeFormat(*this, NumberOfFields, OidList);
35}
36
37void
38AppleX509CLSession::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
48CSSM_HANDLE
49AppleX509CLSession::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
100bool
101AppleX509CLSession::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
132void
133AppleX509CLSession::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
145CSSM_HANDLE
146AppleX509CLSession::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
186bool
187AppleX509CLSession::CertGetNextCachedFieldValue(
188 CSSM_HANDLE ResultsHandle,
189 CSSM_DATA_PTR &Value)
190{
191 /* Identical to, so just call... */
192 return CertGetNextFieldValue(ResultsHandle, Value);
193}
194
195void
196AppleX509CLSession::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 */
212void
213AppleX509CLSession::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
237void
238AppleX509CLSession::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
265void
266AppleX509CLSession::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
276void
277AppleX509CLSession::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
306void
307AppleX509CLSession::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
320void
321AppleX509CLSession::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
330void
331AppleX509CLSession::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
340void
341AppleX509CLSession::PassThrough(
342 CSSM_CC_HANDLE CCHandle,
343 uint32 PassThroughId,
344 const void *InputParams,
345 void **OutputParams)
346{
29654253
A
347 switch(PassThroughId) {
348 case CSSM_APPLEX509CL_OBTAIN_CSR:
349 {
350 /*
351 * Create a Cert Signing Request (CSR).
352 * Input is a CSSM_APPLE_CL_CSR_REQUEST.
353 * Output is a PEM-encoded CertSigningRequest (SNACC type
354 * CertificationRequest from pkcs10).
355 */
356 if(InputParams == NULL) {
357 CssmError::throwMe(CSSMERR_CL_INVALID_INPUT_POINTER);
358 }
359 if(OutputParams == NULL) {
360 CssmError::throwMe(CSSMERR_CL_INVALID_OUTPUT_POINTER);
361 }
362 CSSM_APPLE_CL_CSR_REQUEST *csrReq =
363 (CSSM_APPLE_CL_CSR_REQUEST *)InputParams;
364 if((csrReq->subjectNameX509 == NULL) ||
365 (csrReq->signatureOid.Data == NULL) ||
366 (csrReq->subjectPublicKey == NULL) ||
367 (csrReq->subjectPrivateKey == NULL)) {
368 CssmError::throwMe(CSSMERR_CL_INVALID_INPUT_POINTER);
369 }
370 CSSM_DATA_PTR csrPtr = NULL;
371 generateCsr(CCHandle, csrReq, csrPtr);
372 *OutputParams = csrPtr;
373 break;
374 }
375 case CSSM_APPLEX509CL_VERIFY_CSR:
376 {
377 /*
378 * Perform signature verify of a CSR.
379 * Input: CSSM_DATA referring to a DER-encoded CSR.
380 * Output: Nothing, throws CSSMERR_CL_VERIFICATION_FAILURE
381 * on failure.
382 */
383 if(InputParams == NULL) {
384 CssmError::throwMe(CSSMERR_CL_INVALID_INPUT_POINTER);
385 }
386 const CSSM_DATA *csrPtr = (const CSSM_DATA *)InputParams;
387 verifyCsr(csrPtr);
388 break;
389 }
390 default:
391 CssmError::throwMe(CSSMERR_CL_INVALID_PASSTHROUGH_ID);
392 }
bac41a7b 393}
29654253 394