LibreOffice Module onlineupdate (master) 1
MacVerifyCrypto.cpp
Go to the documentation of this file.
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/. */
4
5#include <CoreFoundation/CoreFoundation.h>
6#include <Security/Security.h>
7#include <dlfcn.h>
8
9#include "cryptox.h"
10
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
13// Transforms.
14extern "C" {
15 const CFStringRef kSecTransformInputAttributeName = CFSTR("INPUT");
16 typedef CFTypeRef SecTransformRef;
17 typedef struct OpaqueSecKeyRef* SecKeyRef;
18
20 (CFReadStreamRef inputStream);
23 typedef CFTypeRef (*SecTransformExecuteFunc)(SecTransformRef transform,
24 CFErrorRef* error);
27 CFDataRef signature,
28 CFErrorRef* error);
31 CFStringRef key,
32 CFTypeRef value,
33 CFErrorRef* error);
35}
36
37#define MAC_OS_X_VERSION_10_7_HEX 0x00001070
38
39static int sOnLionOrLater = -1;
40
41static bool OnLionOrLater()
42{
43 if (sOnLionOrLater < 0) {
44 SInt32 major = 0, minor = 0;
45
46 CFURLRef url =
47 CFURLCreateWithString(kCFAllocatorDefault,
48 CFSTR("file:///System/Library/CoreServices/SystemVersion.plist"),
49 NULL);
50 CFReadStreamRef stream =
51 CFReadStreamCreateWithFile(kCFAllocatorDefault, url);
52 CFReadStreamOpen(stream);
53 CFDictionaryRef sysVersionPlist = (CFDictionaryRef)
54 CFPropertyListCreateWithStream(kCFAllocatorDefault,
55 stream, 0, kCFPropertyListImmutable,
56 NULL, NULL);
57 CFReadStreamClose(stream);
58 CFRelease(stream);
59 CFRelease(url);
60
61 CFStringRef versionString = (CFStringRef)
62 CFDictionaryGetValue(sysVersionPlist, CFSTR("ProductVersion"));
63 CFArrayRef versions =
64 CFStringCreateArrayBySeparatingStrings(kCFAllocatorDefault,
65 versionString, CFSTR("."));
66 CFIndex count = CFArrayGetCount(versions);
67 if (count > 0) {
68 CFStringRef component = (CFStringRef) CFArrayGetValueAtIndex(versions, 0);
69 major = CFStringGetIntValue(component);
70 if (count > 1) {
71 component = (CFStringRef) CFArrayGetValueAtIndex(versions, 1);
72 minor = CFStringGetIntValue(component);
73 }
74 }
75 CFRelease(sysVersionPlist);
76 CFRelease(versions);
77
78 if (major < 10) {
80 } else {
81 int version = 0x1000 + (minor << 4);
82 sOnLionOrLater = version >= MAC_OS_X_VERSION_10_7_HEX ? 1 : 0;
83 }
84 }
85
86 return sOnLionOrLater > 0 ? true : false;
87}
88
89static bool sCssmInitialized = false;
90static CSSM_VERSION sCssmVersion = {2, 0};
91static const CSSM_GUID sMozCssmGuid =
92 { 0x9243121f, 0x5820, 0x4b41,
93 { 0xa6, 0x52, 0xba, 0xb6, 0x3f, 0x9d, 0x3d, 0x7f }};
94static CSSM_CSP_HANDLE sCspHandle = CSSM_INVALID_HANDLE;
95
96void* cssmMalloc (CSSM_SIZE aSize, void* aAllocRef) {
97 (void)aAllocRef;
98 return malloc(aSize);
99}
100
101void cssmFree (void* aPtr, void* aAllocRef) {
102 (void)aAllocRef;
103 free(aPtr);
104 return;
105}
106
107void* cssmRealloc (void* aPtr, CSSM_SIZE aSize, void* aAllocRef) {
108 (void)aAllocRef;
109 return realloc(aPtr, aSize);
110}
111
112void* cssmCalloc (uint32 aNum, CSSM_SIZE aSize, void* aAllocRef) {
113 (void)aAllocRef;
114 return calloc(aNum, aSize);
115}
116
117static CSSM_API_MEMORY_FUNCS cssmMemFuncs = {
118 &cssmMalloc,
119 &cssmFree,
121 &cssmCalloc,
122 NULL
123 };
124
127{
128 if (!OnLionOrLater()) {
129 return CryptoX_Success;
130 }
131
135 dlsym(RTLD_DEFAULT, "SecTransformCreateReadTransformWithReadStream");
136 }
139 dlsym(RTLD_DEFAULT, "SecTransformExecute");
140 }
143 dlsym(RTLD_DEFAULT, "SecVerifyTransformCreate");
144 }
147 dlsym(RTLD_DEFAULT, "SecTransformSetAttribute");
148 }
153 return CryptoX_Error;
154 }
155 return CryptoX_Success;
156}
157
160{
161 if (!aInputData) {
162 return CryptoX_Error;
163 }
164
165 void* inputData = CFDataCreateMutable(kCFAllocatorDefault, 0);
166 if (!inputData) {
167 return CryptoX_Error;
168 }
169
170 if (!OnLionOrLater()) {
171 CSSM_DATA_PTR cssmData = (CSSM_DATA_PTR)malloc(sizeof(CSSM_DATA));
172 if (!cssmData) {
173 CFRelease(inputData);
174 return CryptoX_Error;
175 }
176 cssmData->Data = (uint8*)inputData;
177 cssmData->Length = 0;
178 *aInputData = cssmData;
179 return CryptoX_Success;
180 }
181
182 *aInputData = inputData;
183 return CryptoX_Success;
184}
185
188 unsigned int aLen)
189{
190 if (aLen == 0) {
191 return CryptoX_Success;
192 }
193 if (!aInputData || !*aInputData) {
194 return CryptoX_Error;
195 }
196
197 CFMutableDataRef inputData;
198 if (!OnLionOrLater()) {
199 inputData = (CFMutableDataRef)((CSSM_DATA_PTR)*aInputData)->Data;
200 ((CSSM_DATA_PTR)*aInputData)->Length += aLen;
201 } else {
202 inputData = (CFMutableDataRef)*aInputData;
203 }
204
205 CFDataAppendBytes(inputData, (const uint8*)aBuf, aLen);
206 return CryptoX_Success;
207}
208
210CryptoMac_LoadPublicKey(const unsigned char* aCertData,
211 unsigned int aDataSize,
212 CryptoX_PublicKey* aPublicKey)
213{
214 if (!aCertData || aDataSize == 0 || !aPublicKey) {
215 return CryptoX_Error;
216 }
217 *aPublicKey = NULL;
218
219 if (!OnLionOrLater()) {
220 if (!sCspHandle) {
221 CSSM_RETURN rv;
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,
228 &pvcPolicy,
229 NULL);
230 if (rv != CSSM_OK) {
231 return CryptoX_Error;
232 }
233 sCssmInitialized = true;
234 }
235
236 rv = CSSM_ModuleLoad(&gGuidAppleCSP,
237 CSSM_KEY_HIERARCHY_NONE,
238 NULL,
239 NULL);
240 if (rv != CSSM_OK) {
241 return CryptoX_Error;
242 }
243
244 CSSM_CSP_HANDLE cspHandle;
245 rv = CSSM_ModuleAttach(&gGuidAppleCSP,
248 0,
249 CSSM_SERVICE_CSP,
250 0,
251 CSSM_KEY_HIERARCHY_NONE,
252 NULL,
253 0,
254 NULL,
255 &cspHandle);
256 if (rv != CSSM_OK) {
257 return CryptoX_Error;
258 }
259 sCspHandle = cspHandle;
260 }
261 }
262
263 CFDataRef certData = CFDataCreate(kCFAllocatorDefault,
264 aCertData,
265 aDataSize);
266 if (!certData) {
267 return CryptoX_Error;
268 }
269
270 SecCertificateRef cert = SecCertificateCreateWithData(kCFAllocatorDefault,
271 certData);
272 CFRelease(certData);
273 if (!cert) {
274 return CryptoX_Error;
275 }
276
277 OSStatus status = SecCertificateCopyPublicKey(cert,
278 (SecKeyRef*)aPublicKey);
279 CFRelease(cert);
280 if (status != 0) {
281 return CryptoX_Error;
282 }
283
284 return CryptoX_Success;
285}
286
289 CryptoX_PublicKey* aPublicKey,
290 const unsigned char* aSignature,
291 unsigned int aSignatureLen)
292{
293 if (!aInputData || !*aInputData || !aPublicKey || !*aPublicKey ||
294 !aSignature || aSignatureLen == 0) {
295 return CryptoX_Error;
296 }
297
298 if (!OnLionOrLater()) {
299 if (!sCspHandle) {
300 return CryptoX_Error;
301 }
302
303 CSSM_KEY* publicKey;
304 OSStatus status = SecKeyGetCSSMKey((SecKeyRef)*aPublicKey,
305 (const CSSM_KEY**)&publicKey);
306 if (status) {
307 return CryptoX_Error;
308 }
309
310 CSSM_CC_HANDLE ccHandle;
311 if (CSSM_CSP_CreateSignatureContext(sCspHandle,
312 CSSM_ALGID_SHA1WithRSA,
313 NULL,
314 publicKey,
315 &ccHandle) != CSSM_OK) {
316 return CryptoX_Error;
317 }
318
320 CSSM_DATA signatureData;
321 signatureData.Data = (uint8*)aSignature;
322 signatureData.Length = aSignatureLen;
323 CSSM_DATA inputData;
324 inputData.Data =
325 CFDataGetMutableBytePtr((CFMutableDataRef)
326 (((CSSM_DATA_PTR)*aInputData)->Data));
327 inputData.Length = ((CSSM_DATA_PTR)*aInputData)->Length;
328 if (CSSM_VerifyData(ccHandle,
329 &inputData,
330 1,
331 CSSM_ALGID_NONE,
332 &signatureData) == CSSM_OK) {
334 }
335 return result;
336 }
337
338 CFDataRef signatureData = CFDataCreate(kCFAllocatorDefault,
339 aSignature, aSignatureLen);
340 if (!signatureData) {
341 return CryptoX_Error;
342 }
343
344 CFErrorRef error;
345 SecTransformRef verifier =
347 signatureData,
348 &error);
349 if (!verifier || error) {
350 CFRelease(signatureData);
351 return CryptoX_Error;
352 }
353
356 (CFDataRef)*aInputData,
357 &error);
358 if (error) {
359 CFRelease(signatureData);
360 CFRelease(verifier);
361 return CryptoX_Error;
362 }
363
365 CFTypeRef rv = SecTransformExecutePtr(verifier, &error);
366 if (error) {
367 CFRelease(signatureData);
368 CFRelease(verifier);
369 return CryptoX_Error;
370 }
371
372 if (CFGetTypeID(rv) == CFBooleanGetTypeID() &&
373 CFBooleanGetValue((CFBooleanRef)rv) == true) {
375 }
376
377 CFRelease(signatureData);
378 CFRelease(verifier);
379
380 return result;
381}
382
383void
385{
386 if (!aInputData || !*aInputData) {
387 return;
388 }
389
390 CFMutableDataRef inputData = NULL;
391 if (OnLionOrLater()) {
392 inputData = (CFMutableDataRef)*aInputData;
393 } else {
394 inputData = (CFMutableDataRef)((CSSM_DATA_PTR)*aInputData)->Data;
395 }
396
397 CFRelease(inputData);
398 if (!OnLionOrLater()) {
399 free((CSSM_DATA_PTR)*aInputData);
400 }
401}
402
403void
405{
406 if (!aPublicKey || !*aPublicKey) {
407 return;
408 }
409 if (!OnLionOrLater() && sCspHandle != CSSM_INVALID_HANDLE) {
410 CSSM_ModuleDetach(sCspHandle);
411 sCspHandle = CSSM_INVALID_HANDLE;
412 }
413 CFRelease((SecKeyRef)*aPublicKey);
414}
CryptoX_Result CryptoMac_LoadPublicKey(const unsigned char *aCertData, unsigned int aDataSize, CryptoX_PublicKey *aPublicKey)
SecVerifyTransformCreateFunc SecVerifyTransformCreatePtr
static CSSM_API_MEMORY_FUNCS cssmMemFuncs
SecTransformRef(* SecTransformCreateReadTransformWithReadStreamFunc)(CFReadStreamRef inputStream)
struct OpaqueSecKeyRef * SecKeyRef
SecTransformCreateReadTransformWithReadStreamFunc SecTransformCreateReadTransformWithReadStreamPtr
void CryptoMac_FreePublicKey(CryptoX_PublicKey *aPublicKey)
static const CSSM_GUID sMozCssmGuid
const CFStringRef kSecTransformInputAttributeName
static int sOnLionOrLater
CFTypeRef(* SecTransformExecuteFunc)(SecTransformRef transform, CFErrorRef *error)
static bool OnLionOrLater()
static CSSM_CSP_HANDLE sCspHandle
SecTransformRef(* SecVerifyTransformCreateFunc)(SecKeyRef key, CFDataRef signature, CFErrorRef *error)
CryptoX_Result CryptoMac_VerifyUpdate(CryptoX_SignatureHandle *aInputData, void *aBuf, unsigned int aLen)
static CSSM_VERSION sCssmVersion
void * cssmRealloc(void *aPtr, CSSM_SIZE aSize, void *aAllocRef)
void CryptoMac_FreeSignatureHandle(CryptoX_SignatureHandle *aInputData)
SecTransformExecuteFunc SecTransformExecutePtr
CryptoX_Result CryptoMac_InitCryptoProvider()
static bool sCssmInitialized
CFTypeRef SecTransformRef
#define MAC_OS_X_VERSION_10_7_HEX
void cssmFree(void *aPtr, void *aAllocRef)
CryptoX_Result CryptoMac_VerifySignature(CryptoX_SignatureHandle *aInputData, CryptoX_PublicKey *aPublicKey, const unsigned char *aSignature, unsigned int aSignatureLen)
void * cssmMalloc(CSSM_SIZE aSize, void *aAllocRef)
SecTransformSetAttributeFunc SecTransformSetAttributePtr
CryptoX_Result CryptoMac_VerifyBegin(CryptoX_SignatureHandle *aInputData)
Boolean(* SecTransformSetAttributeFunc)(SecTransformRef transform, CFStringRef key, CFTypeRef value, CFErrorRef *error)
void * cssmCalloc(uint32 aNum, CSSM_SIZE aSize, void *aAllocRef)
Any value
#define CryptoX_Error
Definition: cryptox.h:12
#define CryptoX_Success
Definition: cryptox.h:11
#define CryptoX_Result
Definition: cryptox.h:10
#define CryptoX_PublicKey
Definition: cryptox.h:157
#define CryptoX_SignatureHandle
Definition: cryptox.h:156
Reference< XOutputStream > stream
return NULL
aBuf
Any result