1 /* This Source Code Form is subject to the terms of the Mozilla Public
2 * License, v. 2.0. If a copy of the MPL was not distributed with this
3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
5 #include <CoreFoundation/CoreFoundation.h>
6 #include <Security/Security.h>
11 // We declare the necessary parts of the Security Transforms API here since
12 // we're building with the 10.6 SDK, which doesn't know about Security
15 const CFStringRef kSecTransformInputAttributeName
= CFSTR("INPUT");
16 typedef CFTypeRef SecTransformRef
;
17 typedef struct OpaqueSecKeyRef
* SecKeyRef
;
19 typedef SecTransformRef (*SecTransformCreateReadTransformWithReadStreamFunc
)
20 (CFReadStreamRef inputStream
);
21 SecTransformCreateReadTransformWithReadStreamFunc
22 SecTransformCreateReadTransformWithReadStreamPtr
= NULL
;
23 typedef CFTypeRef (*SecTransformExecuteFunc
)(SecTransformRef transform
,
25 SecTransformExecuteFunc SecTransformExecutePtr
= NULL
;
26 typedef SecTransformRef (*SecVerifyTransformCreateFunc
)(SecKeyRef key
,
29 SecVerifyTransformCreateFunc SecVerifyTransformCreatePtr
= NULL
;
30 typedef Boolean (*SecTransformSetAttributeFunc
)(SecTransformRef transform
,
34 SecTransformSetAttributeFunc SecTransformSetAttributePtr
= NULL
;
37 #define MAC_OS_X_VERSION_10_7_HEX 0x00001070
39 static int sOnLionOrLater
= -1;
41 static bool OnLionOrLater()
43 if (sOnLionOrLater
< 0) {
44 SInt32 major
= 0, minor
= 0;
47 CFURLCreateWithString(kCFAllocatorDefault
,
48 CFSTR("file:///System/Library/CoreServices/SystemVersion.plist"),
50 CFReadStreamRef stream
=
51 CFReadStreamCreateWithFile(kCFAllocatorDefault
, url
);
52 CFReadStreamOpen(stream
);
53 CFDictionaryRef sysVersionPlist
= (CFDictionaryRef
)
54 CFPropertyListCreateWithStream(kCFAllocatorDefault
,
55 stream
, 0, kCFPropertyListImmutable
,
57 CFReadStreamClose(stream
);
61 CFStringRef versionString
= (CFStringRef
)
62 CFDictionaryGetValue(sysVersionPlist
, CFSTR("ProductVersion"));
64 CFStringCreateArrayBySeparatingStrings(kCFAllocatorDefault
,
65 versionString
, CFSTR("."));
66 CFIndex count
= CFArrayGetCount(versions
);
68 CFStringRef component
= (CFStringRef
) CFArrayGetValueAtIndex(versions
, 0);
69 major
= CFStringGetIntValue(component
);
71 component
= (CFStringRef
) CFArrayGetValueAtIndex(versions
, 1);
72 minor
= CFStringGetIntValue(component
);
75 CFRelease(sysVersionPlist
);
81 int version
= 0x1000 + (minor
<< 4);
82 sOnLionOrLater
= version
>= MAC_OS_X_VERSION_10_7_HEX
? 1 : 0;
86 return sOnLionOrLater
> 0 ? true : false;
89 static bool sCssmInitialized
= false;
90 static CSSM_VERSION sCssmVersion
= {2, 0};
91 static const CSSM_GUID sMozCssmGuid
=
92 { 0x9243121f, 0x5820, 0x4b41,
93 { 0xa6, 0x52, 0xba, 0xb6, 0x3f, 0x9d, 0x3d, 0x7f }};
94 static CSSM_CSP_HANDLE sCspHandle
= CSSM_INVALID_HANDLE
;
96 void* cssmMalloc (CSSM_SIZE aSize
, void* aAllocRef
) {
101 void cssmFree (void* aPtr
, void* aAllocRef
) {
107 void* cssmRealloc (void* aPtr
, CSSM_SIZE aSize
, void* aAllocRef
) {
109 return realloc(aPtr
, aSize
);
112 void* cssmCalloc (uint32 aNum
, CSSM_SIZE aSize
, void* aAllocRef
) {
114 return calloc(aNum
, aSize
);
117 static CSSM_API_MEMORY_FUNCS cssmMemFuncs
= {
126 CryptoMac_InitCryptoProvider()
128 if (!OnLionOrLater()) {
129 return CryptoX_Success
;
132 if (!SecTransformCreateReadTransformWithReadStreamPtr
) {
133 SecTransformCreateReadTransformWithReadStreamPtr
=
134 (SecTransformCreateReadTransformWithReadStreamFunc
)
135 dlsym(RTLD_DEFAULT
, "SecTransformCreateReadTransformWithReadStream");
137 if (!SecTransformExecutePtr
) {
138 SecTransformExecutePtr
= (SecTransformExecuteFunc
)
139 dlsym(RTLD_DEFAULT
, "SecTransformExecute");
141 if (!SecVerifyTransformCreatePtr
) {
142 SecVerifyTransformCreatePtr
= (SecVerifyTransformCreateFunc
)
143 dlsym(RTLD_DEFAULT
, "SecVerifyTransformCreate");
145 if (!SecTransformSetAttributePtr
) {
146 SecTransformSetAttributePtr
= (SecTransformSetAttributeFunc
)
147 dlsym(RTLD_DEFAULT
, "SecTransformSetAttribute");
149 if (!SecTransformCreateReadTransformWithReadStreamPtr
||
150 !SecTransformExecutePtr
||
151 !SecVerifyTransformCreatePtr
||
152 !SecTransformSetAttributePtr
) {
153 return CryptoX_Error
;
155 return CryptoX_Success
;
159 CryptoMac_VerifyBegin(CryptoX_SignatureHandle
* aInputData
)
162 return CryptoX_Error
;
165 void* inputData
= CFDataCreateMutable(kCFAllocatorDefault
, 0);
167 return CryptoX_Error
;
170 if (!OnLionOrLater()) {
171 CSSM_DATA_PTR cssmData
= (CSSM_DATA_PTR
)malloc(sizeof(CSSM_DATA
));
173 CFRelease(inputData
);
174 return CryptoX_Error
;
176 cssmData
->Data
= (uint8
*)inputData
;
177 cssmData
->Length
= 0;
178 *aInputData
= cssmData
;
179 return CryptoX_Success
;
182 *aInputData
= inputData
;
183 return CryptoX_Success
;
187 CryptoMac_VerifyUpdate(CryptoX_SignatureHandle
* aInputData
, void* aBuf
,
191 return CryptoX_Success
;
193 if (!aInputData
|| !*aInputData
) {
194 return CryptoX_Error
;
197 CFMutableDataRef inputData
;
198 if (!OnLionOrLater()) {
199 inputData
= (CFMutableDataRef
)((CSSM_DATA_PTR
)*aInputData
)->Data
;
200 ((CSSM_DATA_PTR
)*aInputData
)->Length
+= aLen
;
202 inputData
= (CFMutableDataRef
)*aInputData
;
205 CFDataAppendBytes(inputData
, (const uint8
*)aBuf
, aLen
);
206 return CryptoX_Success
;
210 CryptoMac_LoadPublicKey(const unsigned char* aCertData
,
211 unsigned int aDataSize
,
212 CryptoX_PublicKey
* aPublicKey
)
214 if (!aCertData
|| aDataSize
== 0 || !aPublicKey
) {
215 return CryptoX_Error
;
219 if (!OnLionOrLater()) {
222 if (!sCssmInitialized
) {
223 CSSM_PVC_MODE pvcPolicy
= CSSM_PVC_NONE
;
224 rv
= CSSM_Init(&sCssmVersion
,
225 CSSM_PRIVILEGE_SCOPE_PROCESS
,
227 CSSM_KEY_HIERARCHY_NONE
,
231 return CryptoX_Error
;
233 sCssmInitialized
= true;
236 rv
= CSSM_ModuleLoad(&gGuidAppleCSP
,
237 CSSM_KEY_HIERARCHY_NONE
,
241 return CryptoX_Error
;
244 CSSM_CSP_HANDLE cspHandle
;
245 rv
= CSSM_ModuleAttach(&gGuidAppleCSP
,
251 CSSM_KEY_HIERARCHY_NONE
,
257 return CryptoX_Error
;
259 sCspHandle
= cspHandle
;
263 CFDataRef certData
= CFDataCreate(kCFAllocatorDefault
,
267 return CryptoX_Error
;
270 SecCertificateRef cert
= SecCertificateCreateWithData(kCFAllocatorDefault
,
274 return CryptoX_Error
;
277 OSStatus status
= SecCertificateCopyPublicKey(cert
,
278 (SecKeyRef
*)aPublicKey
);
281 return CryptoX_Error
;
284 return CryptoX_Success
;
288 CryptoMac_VerifySignature(CryptoX_SignatureHandle
* aInputData
,
289 CryptoX_PublicKey
* aPublicKey
,
290 const unsigned char* aSignature
,
291 unsigned int aSignatureLen
)
293 if (!aInputData
|| !*aInputData
|| !aPublicKey
|| !*aPublicKey
||
294 !aSignature
|| aSignatureLen
== 0) {
295 return CryptoX_Error
;
298 if (!OnLionOrLater()) {
300 return CryptoX_Error
;
304 OSStatus status
= SecKeyGetCSSMKey((SecKeyRef
)*aPublicKey
,
305 (const CSSM_KEY
**)&publicKey
);
307 return CryptoX_Error
;
310 CSSM_CC_HANDLE ccHandle
;
311 if (CSSM_CSP_CreateSignatureContext(sCspHandle
,
312 CSSM_ALGID_SHA1WithRSA
,
315 &ccHandle
) != CSSM_OK
) {
316 return CryptoX_Error
;
319 CryptoX_Result result
= CryptoX_Error
;
320 CSSM_DATA signatureData
;
321 signatureData
.Data
= (uint8
*)aSignature
;
322 signatureData
.Length
= aSignatureLen
;
325 CFDataGetMutableBytePtr((CFMutableDataRef
)
326 (((CSSM_DATA_PTR
)*aInputData
)->Data
));
327 inputData
.Length
= ((CSSM_DATA_PTR
)*aInputData
)->Length
;
328 if (CSSM_VerifyData(ccHandle
,
332 &signatureData
) == CSSM_OK
) {
333 result
= CryptoX_Success
;
338 CFDataRef signatureData
= CFDataCreate(kCFAllocatorDefault
,
339 aSignature
, aSignatureLen
);
340 if (!signatureData
) {
341 return CryptoX_Error
;
345 SecTransformRef verifier
=
346 SecVerifyTransformCreatePtr((SecKeyRef
)*aPublicKey
,
349 if (!verifier
|| error
) {
350 CFRelease(signatureData
);
351 return CryptoX_Error
;
354 SecTransformSetAttributePtr(verifier
,
355 kSecTransformInputAttributeName
,
356 (CFDataRef
)*aInputData
,
359 CFRelease(signatureData
);
361 return CryptoX_Error
;
364 CryptoX_Result result
= CryptoX_Error
;
365 CFTypeRef rv
= SecTransformExecutePtr(verifier
, &error
);
367 CFRelease(signatureData
);
369 return CryptoX_Error
;
372 if (CFGetTypeID(rv
) == CFBooleanGetTypeID() &&
373 CFBooleanGetValue((CFBooleanRef
)rv
) == true) {
374 result
= CryptoX_Success
;
377 CFRelease(signatureData
);
384 CryptoMac_FreeSignatureHandle(CryptoX_SignatureHandle
* aInputData
)
386 if (!aInputData
|| !*aInputData
) {
390 CFMutableDataRef inputData
= NULL
;
391 if (OnLionOrLater()) {
392 inputData
= (CFMutableDataRef
)*aInputData
;
394 inputData
= (CFMutableDataRef
)((CSSM_DATA_PTR
)*aInputData
)->Data
;
397 CFRelease(inputData
);
398 if (!OnLionOrLater()) {
399 free((CSSM_DATA_PTR
)*aInputData
);
404 CryptoMac_FreePublicKey(CryptoX_PublicKey
* aPublicKey
)
406 if (!aPublicKey
|| !*aPublicKey
) {
409 if (!OnLionOrLater() && sCspHandle
!= CSSM_INVALID_HANDLE
) {
410 CSSM_ModuleDetach(sCspHandle
);
411 sCspHandle
= CSSM_INVALID_HANDLE
;
413 CFRelease((SecKeyRef
)*aPublicKey
);