2 * Copyright (c) 2000-2001 Apple Computer, Inc. All Rights Reserved.
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
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.
20 // Session_Cert.cpp - cert-related session functions.
23 #include "AppleX509CLSession.h"
24 #include "DecodedCert.h"
25 #include "CLCachedEntry.h"
26 #include "cldebugging.h"
27 #include <Security/oidscert.h>
30 AppleX509CLSession::CertDescribeFormat(
31 uint32
&NumberOfFields
,
32 CSSM_OID_PTR
&OidList
)
34 DecodedCert::describeFormat(*this, NumberOfFields
, OidList
);
38 AppleX509CLSession::CertGetAllFields(
40 uint32
&NumberOfFields
,
41 CSSM_FIELD_PTR
&CertFields
)
43 class DecodedCert
decodedCert(*this, Cert
);
44 decodedCert
.getAllParsedCertFields(NumberOfFields
, CertFields
);
49 AppleX509CLSession::CertGetFirstFieldValue(
50 const CssmData
&EncodedCert
,
51 const CssmData
&CertField
,
52 uint32
&NumberOfMatchedFields
,
55 NumberOfMatchedFields
= 0;
57 CssmAutoData
aData(*this);
59 DecodedCert
*decodedCert
= new DecodedCert(*this, EncodedCert
);
62 /* this returns false if field not there, throws on bad OID */
65 brtn
= decodedCert
->getCertFieldData(CertField
,
76 return CSSM_INVALID_HANDLE
;
79 /* cook up a CLCachedCert, stash it in cache */
80 CLCachedCert
*cachedCert
= new CLCachedCert(*decodedCert
);
81 cacheMap
.addEntry(*cachedCert
, cachedCert
->handle());
83 /* cook up a CLQuery, stash it */
84 CLQuery
*query
= new CLQuery(
89 cachedCert
->handle());
90 queryMap
.addEntry(*query
, query
->handle());
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();
101 AppleX509CLSession::CertGetNextFieldValue(
102 CSSM_HANDLE ResultsHandle
,
103 CSSM_DATA_PTR
&Value
)
105 /* fetch & validate the query */
106 CLQuery
*query
= queryMap
.lookupEntry(ResultsHandle
);
108 CssmError::throwMe(CSSMERR_CL_INVALID_RESULTS_HANDLE
);
110 if(query
->nextIndex() >= query
->numFields()) {
114 /* fetch the associated cached cert */
115 CLCachedCert
*cachedCert
= lookupCachedCert(query
->cachedObject());
117 CssmAutoData
aData(*this);
118 if(!cachedCert
->cert().getCertFieldData(query
->fieldId(),
125 /* success - copy field data to outgoing Value */
126 Value
= (CSSM_DATA_PTR
)malloc(sizeof(CSSM_DATA
));
127 *Value
= aData
.release();
128 query
->incrementIndex();
133 AppleX509CLSession::CertCache(
134 const CssmData
&EncodedCert
,
135 CSSM_HANDLE
&CertHandle
)
137 DecodedCert
*decodedCert
= new DecodedCert(*this, EncodedCert
);
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();
146 AppleX509CLSession::CertGetFirstCachedFieldValue(
147 CSSM_HANDLE CertHandle
,
148 const CssmData
&CertField
,
149 uint32
&NumberOfMatchedFields
,
150 CSSM_DATA_PTR
&Value
)
152 /* fetch the associated cached cert */
153 CLCachedCert
*cachedCert
= lookupCachedCert(CertHandle
);
154 if(cachedCert
== NULL
) {
155 CssmError::throwMe(CSSMERR_CL_INVALID_CACHE_HANDLE
);
158 CssmAutoData
aData(*this);
161 /* this returns false if field not there, throws on bad OID */
162 if(!cachedCert
->cert().getCertFieldData(CertField
,
166 return CSSM_INVALID_HANDLE
;
169 /* cook up a CLQuery, stash it */
170 CLQuery
*query
= new CLQuery(
175 cachedCert
->handle());
176 queryMap
.addEntry(*query
, query
->handle());
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();
187 AppleX509CLSession::CertGetNextCachedFieldValue(
188 CSSM_HANDLE ResultsHandle
,
189 CSSM_DATA_PTR
&Value
)
191 /* Identical to, so just call... */
192 return CertGetNextFieldValue(ResultsHandle
, Value
);
196 AppleX509CLSession::CertAbortCache(
197 CSSM_HANDLE CertHandle
)
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
);
205 cacheMap
.removeEntry(cachedCert
->handle());
210 * Abort either type of cert field query (cache based or non-cache based)
213 AppleX509CLSession::CertAbortQuery(
214 CSSM_HANDLE ResultsHandle
)
216 /* fetch & validate the query */
217 CLQuery
*query
= queryMap
.lookupEntry(ResultsHandle
);
219 CssmError::throwMe(CSSMERR_CL_INVALID_RESULTS_HANDLE
);
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
);
230 cacheMap
.removeEntry(cachedCert
->handle());
233 queryMap
.removeEntry(query
->handle());
238 AppleX509CLSession::CertCreateTemplate(
239 uint32 NumberOfFields
,
240 const CSSM_FIELD CertFields
[],
241 CssmData
&CertTemplate
)
243 /* cook up an empty Cert */
244 DecodedCert
cert(*this);
246 /* grind thru specified fields; exceptions are fatal */
247 for(uint32 dex
=0; dex
<NumberOfFields
; dex
++) {
249 CssmOid::overlay(CertFields
[dex
].FieldOid
),
250 CssmData::overlay(CertFields
[dex
].FieldValue
));
253 /* TBD - ensure all required fields are set? We do this
254 * when we sign the cert; maybe we should do it here. */
257 * We have the CertificateToSign in snacc format. Encode.
259 CssmRemoteData
rData(*this, CertTemplate
);
260 cert
.encodeTbs(rData
);
266 AppleX509CLSession::CertGetAllTemplateFields(
267 const CssmData
&CertTemplate
,
268 uint32
&NumberOfFields
,
269 CSSM_FIELD_PTR
&CertFields
)
271 DecodedCert
cert(*this); // empty
272 cert
.decodeTbs(CertTemplate
);
273 cert
.getAllParsedCertFields(NumberOfFields
, CertFields
);
277 AppleX509CLSession::FreeFields(
278 uint32 NumberOfFields
,
279 CSSM_FIELD_PTR
&FieldArray
)
282 CSSM_FIELD_PTR thisField
;
283 CSSM_OID_PTR thisOid
;
285 for(i
=0; i
<NumberOfFields
; i
++) {
286 thisField
= &FieldArray
[i
];
287 thisOid
= &thisField
->FieldOid
;
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).
294 CssmData
&cData
= CssmData::overlay(thisField
->FieldValue
);
295 CssmRemoteData
rData(*this, cData
);
296 DecodedCert::freeCertFieldData(CssmOid::overlay(*thisOid
), rData
);
298 /* and the oid itself */
300 thisOid
->Data
= NULL
;
307 AppleX509CLSession::FreeFieldValue(
308 const CssmData
&CertOrCrlOid
,
312 CssmError::throwMe(CSSM_ERRCODE_INVALID_FIELD_POINTER
);
314 CssmRemoteData
cd(*this, *Value
);
315 /* TBD - if this fails, call tbd DecodedCRL::freeCertFieldData */
316 DecodedCert::freeCertFieldData(CertOrCrlOid
, cd
);
321 AppleX509CLSession::CertGroupFromVerifiedBundle(
322 CSSM_CC_HANDLE CCHandle
,
323 const CSSM_CERT_BUNDLE
&CertBundle
,
324 const CssmData
*SignerCert
,
325 CSSM_CERTGROUP_PTR
&CertGroup
)
331 AppleX509CLSession::CertGroupToSignedBundle(
332 CSSM_CC_HANDLE CCHandle
,
333 const CSSM_CERTGROUP
&CertGroupToBundle
,
334 const CSSM_CERT_BUNDLE_HEADER
*BundleInfo
,
335 CssmData
&SignedBundle
)
341 AppleX509CLSession::PassThrough(
342 CSSM_CC_HANDLE CCHandle
,
343 uint32 PassThroughId
,
344 const void *InputParams
,