4 Description: common CDSA access utilities
8 Copyright: © Copyright 2001 Apple Computer, Inc. All rights reserved.
10 Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple
11 Computer, Inc. ("Apple") in consideration of your agreement to
12 the following terms, and your use, installation, modification
13 or redistribution of this Apple software constitutes acceptance
14 of these terms. If you do not agree with these terms, please
15 do not use, install, modify or redistribute this Apple software.
17 In consideration of your agreement to abide by the following
18 terms, and subject to these terms, Apple grants you a personal,
19 non-exclusive license, under Apple's copyrights in this
20 original Apple software (the "Apple Software"), to use,
21 reproduce, modify and redistribute the Apple Software, with
22 or without modifications, in source and/or binary forms;
23 provided that if you redistribute the Apple Software in
24 its entirety and without modifications, you must retain
25 this notice and the following text and disclaimers in all
26 such redistributions of the Apple Software. Neither the
27 name, trademarks, service marks or logos of Apple Computer,
28 Inc. may be used to endorse or promote products derived from the
29 Apple Software without specific prior written permission from
30 Apple. Except as expressly stated in this notice, no other
31 rights or licenses, express or implied, are granted by Apple
32 herein, including but not limited to any patent rights that
33 may be infringed by your derivative works or by other works
34 in which the Apple Software may be incorporated.
36 The Apple Software is provided by Apple on an "AS IS" basis.
37 APPLE MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING
38 WITHOUT LIMITATION THE IMPLIED WARRANTIES OF NON-INFRINGEMENT,
39 MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE,
40 REGARDING THE APPLE SOFTWARE OR ITS USE AND OPERATION ALONE
41 OR IN COMBINATION WITH YOUR PRODUCTS.
43 IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT,
44 INCIDENTAL OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
45 LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
46 LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
47 ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, MODIFICATION
48 AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED
49 AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING
50 NEGLIGENCE), STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE
51 HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
54 #include "srCdsaUtils.h"
57 #include <Security/SecCertificate.h>
58 #include <Security/cssmapple.h> /* for cssmPerror() */
59 #include <Security/oidsalg.h> /* for cssmPerror() */
62 static CSSM_VERSION vers
= {2, 0};
63 static const CSSM_GUID testGuid
= { 0xFADE, 0, 0, { 1,2,3,4,5,6,7,0 }};
66 * Standard app-level memory functions required by CDSA.
68 void * srAppMalloc (uint32 size
, void *allocRef
) {
69 return( malloc(size
) );
72 void srAppFree (void *mem_ptr
, void *allocRef
) {
77 void * srAppRealloc (void *ptr
, uint32 size
, void *allocRef
) {
78 return( realloc( ptr
, size
) );
81 void * srAppCalloc (uint32 num
, uint32 size
, void *allocRef
) {
82 return( calloc( num
, size
) );
85 static CSSM_API_MEMORY_FUNCS memFuncs
= {
93 CSSM_BOOL
srCompareCssmData(const CSSM_DATA
*d1
,
96 if(d1
->Length
!= d2
->Length
) {
99 if(memcmp(d1
->Data
, d2
->Data
, d1
->Length
)) {
106 * Init CSSM; returns CSSM_FALSE on error. Reusable.
108 static CSSM_BOOL cssmInitd
= CSSM_FALSE
;
110 CSSM_BOOL
srCssmStartup()
113 CSSM_PVC_MODE pvcPolicy
= CSSM_PVC_NONE
;
118 crtn
= CSSM_Init (&vers
,
119 CSSM_PRIVILEGE_SCOPE_NONE
,
121 CSSM_KEY_HIERARCHY_NONE
,
123 NULL
/* reserved */);
126 srPrintError("CSSM_Init", crtn
);
130 cssmInitd
= CSSM_TRUE
;
136 * Attach to CSP. Returns zero on error.
138 CSSM_CSP_HANDLE
srCspStartup(
139 CSSM_BOOL bareCsp
) // true ==> CSP, false ==> CSP/DL
141 CSSM_CSP_HANDLE cspHand
;
143 const CSSM_GUID
*guid
;
145 /* common CSSM init */
146 if(srCssmStartup() == CSSM_FALSE
) {
150 guid
= &gGuidAppleCSP
;
153 guid
= &gGuidAppleCSPDL
;
155 crtn
= CSSM_ModuleLoad(guid
,
156 CSSM_KEY_HIERARCHY_NONE
,
157 NULL
, // eventHandler
158 NULL
); // AppNotifyCallbackCtx
160 srPrintError("CSSM_ModuleLoad()", crtn
);
163 crtn
= CSSM_ModuleAttach (guid
,
165 &memFuncs
, // memFuncs
169 CSSM_KEY_HIERARCHY_NONE
,
170 NULL
, // FunctionTable
175 srPrintError("CSSM_ModuleAttach()", crtn
);
181 /* Attach to DL side of CSPDL */
182 CSSM_DL_HANDLE
srDlStartup()
184 CSSM_DL_HANDLE dlHand
= 0;
187 if(srCssmStartup() == CSSM_FALSE
) {
190 crtn
= CSSM_ModuleLoad(&gGuidAppleCSPDL
,
191 CSSM_KEY_HIERARCHY_NONE
,
192 NULL
, // eventHandler
193 NULL
); // AppNotifyCallbackCtx
195 srPrintError("CSSM_ModuleLoad(Apple CSPDL)", crtn
);
198 crtn
= CSSM_ModuleAttach (&gGuidAppleCSPDL
,
200 &memFuncs
, // memFuncs
204 CSSM_KEY_HIERARCHY_NONE
,
205 NULL
, // FunctionTable
210 srPrintError("CSSM_ModuleAttach(Apple CSPDL)", crtn
);
216 CSSM_CL_HANDLE
srClStartup()
218 CSSM_CL_HANDLE clHand
;
221 if(srCssmStartup() == CSSM_FALSE
) {
224 crtn
= CSSM_ModuleLoad(&gGuidAppleX509CL
,
225 CSSM_KEY_HIERARCHY_NONE
,
226 NULL
, // eventHandler
227 NULL
); // AppNotifyCallbackCtx
229 srPrintError("CSSM_ModuleLoad(AppleCL)", crtn
);
232 crtn
= CSSM_ModuleAttach (&gGuidAppleX509CL
,
234 &memFuncs
, // memFuncs
236 CSSM_SERVICE_CL
, // SubserviceFlags - Where is this used?
238 CSSM_KEY_HIERARCHY_NONE
,
239 NULL
, // FunctionTable
244 srPrintError("CSSM_ModuleAttach(AppleCL)", crtn
);
252 CSSM_TP_HANDLE
srTpStartup()
254 CSSM_TP_HANDLE tpHand
;
257 if(srCssmStartup() == CSSM_FALSE
) {
260 crtn
= CSSM_ModuleLoad(&gGuidAppleX509TP
,
261 CSSM_KEY_HIERARCHY_NONE
,
262 NULL
, // eventHandler
263 NULL
); // AppNotifyCallbackCtx
265 srPrintError("CSSM_ModuleLoad(AppleTP)", crtn
);
268 crtn
= CSSM_ModuleAttach (&gGuidAppleX509TP
,
270 &memFuncs
, // memFuncs
272 CSSM_SERVICE_TP
, // SubserviceFlags
274 CSSM_KEY_HIERARCHY_NONE
,
275 NULL
, // FunctionTable
280 srPrintError("CSSM_ModuleAttach(AppleTP)", crtn
);
289 * Given a context specified via a CSSM_CC_HANDLE, add a new
290 * CSSM_CONTEXT_ATTRIBUTE to the context as specified by AttributeType,
291 * AttributeLength, and an untyped pointer.
293 CSSM_RETURN
srAddContextAttribute(CSSM_CC_HANDLE CCHandle
,
294 uint32 AttributeType
,
295 uint32 AttributeLength
,
296 const void *AttributePtr
)
298 CSSM_CONTEXT_ATTRIBUTE newAttr
;
301 newAttr
.AttributeType
= AttributeType
;
302 newAttr
.AttributeLength
= AttributeLength
;
303 newAttr
.Attribute
.Data
= (CSSM_DATA_PTR
)AttributePtr
;
304 crtn
= CSSM_UpdateContextAttributes(CCHandle
, 1, &newAttr
);
306 srPrintError("CSSM_UpdateContextAttributes", crtn
);
313 * Derive symmetric key.
314 * Note in the X CSP, we never return an IV.
316 CSSM_RETURN
srCspDeriveKey(CSSM_CSP_HANDLE cspHand
,
317 uint32 keyAlg
, // CSSM_ALGID_RC5, etc.
318 const char *keyLabel
,
319 unsigned keyLabelLen
,
320 uint32 keyUsage
, // CSSM_KEYUSE_ENCRYPT, etc.
321 uint32 keySizeInBits
,
322 CSSM_DATA_PTR password
, // in PKCS-5 lingo
323 CSSM_DATA_PTR salt
, // ditto
324 uint32 iterationCnt
, // ditto
328 CSSM_CC_HANDLE ccHand
;
330 CSSM_DATA dummyLabel
;
331 CSSM_PKCS5_PBKDF2_PARAMS pbeParams
;
333 CSSM_ACCESS_CREDENTIALS creds
;
335 memset(key
, 0, sizeof(CSSM_KEY
));
336 memset(&creds
, 0, sizeof(CSSM_ACCESS_CREDENTIALS
));
337 crtn
= CSSM_CSP_CreateDeriveKeyContext(cspHand
,
338 CSSM_ALGID_PKCS5_PBKDF2
,
348 srPrintError("CSSM_CSP_CreateDeriveKeyContext", crtn
);
351 keyAttr
= CSSM_KEYATTR_EXTRACTABLE
| CSSM_KEYATTR_RETURN_REF
|
352 CSSM_KEYATTR_SENSITIVE
;
353 dummyLabel
.Length
= keyLabelLen
;
354 dummyLabel
.Data
= (uint8
*)keyLabel
;
356 /* passing in password is pretty strange....*/
357 pbeParams
.Passphrase
= *password
;
358 pbeParams
.PseudoRandomFunction
= CSSM_PKCS5_PBKDF2_PRF_HMAC_SHA1
;
359 pbeData
.Data
= (uint8
*)&pbeParams
;
360 pbeData
.Length
= sizeof(pbeParams
);
361 crtn
= CSSM_DeriveKey(ccHand
,
366 NULL
, // cred and acl
369 srPrintError("CSSM_DeriveKey", crtn
);
372 crtn
= CSSM_DeleteContext(ccHand
);
374 srPrintError("CSSM_DeleteContext", crtn
);
380 * Generate key pair of arbitrary algorithm.
383 /* CSP DL currently does not perform DSA generate params; let CSP do it implicitly */
384 #define DO_DSA_GEN_PARAMS 0
386 CSSM_RETURN
srCspGenKeyPair(CSSM_CSP_HANDLE cspHand
,
387 CSSM_DL_DB_HANDLE
*dlDbHand
, // optional
389 const char *keyLabel
,
390 unsigned keyLabelLen
,
391 uint32 keySize
, // in bits
392 CSSM_KEY_PTR pubKey
, // mallocd by caller
393 CSSM_KEYUSE pubKeyUsage
, // CSSM_KEYUSE_ENCRYPT, etc.
394 CSSM_KEYATTR_FLAGS pubAttrs
, // CSSM_KEYATTR_EXTRACTABLE, etc.
395 CSSM_KEY_PTR privKey
, // mallocd by caller
396 CSSM_KEYUSE privKeyUsage
, // CSSM_KEYUSE_DECRYPT, etc.
397 CSSM_KEYATTR_FLAGS privAttrs
) // CSSM_KEYATTR_EXTRACTABLE, etc.
401 CSSM_CC_HANDLE ccHand
;
402 CSSM_DATA keyLabelData
;
404 keyLabelData
.Data
= (uint8
*)keyLabel
,
405 keyLabelData
.Length
= keyLabelLen
;
406 memset(pubKey
, 0, sizeof(CSSM_KEY
));
407 memset(privKey
, 0, sizeof(CSSM_KEY
));
409 crtn
= CSSM_CSP_CreateKeyGenContext(cspHand
,
419 srPrintError("CSSM_CSP_CreateKeyGenContext", crtn
);
423 /* post-context-create algorithm-specific stuff */
425 #if DO_DSA_GEN_PARAMS
428 * extra step - generate params - this just adds some
429 * info to the context
432 CSSM_DATA dummy
= {0, NULL
};
433 crtn
= CSSM_GenerateAlgorithmParams(ccHand
,
436 srPrintError("CSSM_GenerateAlgorithmParams", crtn
);
437 CSSM_DeleteContext(ccHand
);
440 srAppFree(dummy
.Data
, NULL
);
443 #endif /* DO_DSA_GEN_PARAMS */
448 /* optionally specify DL/DB storage location */
450 crtn
= srAddContextAttribute(ccHand
,
451 CSSM_ATTRIBUTE_DL_DB_HANDLE
,
452 sizeof(CSSM_ATTRIBUTE_DL_DB_HANDLE
),
455 CSSM_DeleteContext(ccHand
);
459 ocrtn
= CSSM_GenerateKeyPair(ccHand
,
466 &keyLabelData
, // same labels
467 NULL
, // CredAndAclEntry
470 srPrintError("CSSM_GenerateKeyPair", ocrtn
);
472 crtn
= CSSM_DeleteContext(ccHand
);
474 srPrintError("CSSM_DeleteContext", crtn
);
475 if(ocrtn
== CSSM_OK
) {
476 /* error on CSSM_GenerateKeyPair takes precedence */
485 * Add a certificate to an open Keychain.
487 CSSM_RETURN
srAddCertToKC(
488 SecKeychainRef keychain
,
489 const CSSM_DATA
*cert
,
490 CSSM_CERT_TYPE certType
,
491 CSSM_CERT_ENCODING certEncoding
,
492 const char *printName
, // C string
493 const CSSM_DATA
*keyLabel
) // ??
495 SecCertificateRef certificate
;
497 OSStatus rslt
= SecCertificateCreateFromData(cert
, certType
, certEncoding
, &certificate
);
500 rslt
= SecCertificateAddToKeychain(certificate
, keychain
);
501 CFRelease(certificate
);
508 * Convert a CSSM_DATA_PTR, referring to a DER-encoded int, to an
511 unsigned srDER_ToInt(const CSSM_DATA
*DER_Data
)
516 while(i
< DER_Data
->Length
) {
517 rtn
|= DER_Data
->Data
[i
];
518 if(++i
== DER_Data
->Length
) {
529 void srPrintError(char *op
, CSSM_RETURN err
)
535 * Convert a CFString into a C string as safely as we can. Caller must
538 char *srCfStrToCString(
541 CFIndex len
= CFStringGetLength(cfStr
) + 1;
542 char *cstr
= (char *)malloc(len
);
546 if(!CFStringGetCString(cfStr
, cstr
, len
, kCFStringEncodingASCII
)) {
547 printf("***CFStringGetCString error\n");