1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "crypto/cssm_init.h"
7 #include <Security/SecBase.h>
9 #include "base/logging.h"
10 #include "base/mac/scoped_cftyperef.h"
11 #include "base/memory/singleton.h"
12 #include "base/strings/sys_string_conversions.h"
14 // When writing crypto code for Mac OS X, you may find the following
15 // documentation useful:
16 // - Common Security: CDSA and CSSM, Version 2 (with corrigenda)
17 // http://www.opengroup.org/security/cdsa.htm
18 // - Apple Cryptographic Service Provider Functional Specification
19 // - CryptoSample: http://developer.apple.com/SampleCode/CryptoSample/
23 void* CSSMMalloc(CSSM_SIZE size
, void* alloc_ref
) {
27 void CSSMFree(void* mem_ptr
, void* alloc_ref
) {
31 void* CSSMRealloc(void* ptr
, CSSM_SIZE size
, void* alloc_ref
) {
32 return realloc(ptr
, size
);
35 void* CSSMCalloc(uint32 num
, CSSM_SIZE size
, void* alloc_ref
) {
36 return calloc(num
, size
);
39 class CSSMInitSingleton
{
41 static CSSMInitSingleton
* GetInstance() {
42 return base::Singleton
<CSSMInitSingleton
, base::LeakySingletonTraits
<
43 CSSMInitSingleton
>>::get();
46 CSSM_CSP_HANDLE
csp_handle() const { return csp_handle_
; }
47 CSSM_CL_HANDLE
cl_handle() const { return cl_handle_
; }
48 CSSM_TP_HANDLE
tp_handle() const { return tp_handle_
; }
52 : inited_(false), csp_loaded_(false), cl_loaded_(false),
53 tp_loaded_(false), csp_handle_(CSSM_INVALID_HANDLE
),
54 cl_handle_(CSSM_INVALID_HANDLE
), tp_handle_(CSSM_INVALID_HANDLE
) {
55 static CSSM_VERSION version
= {2, 0};
56 // TODO(wtc): what should our caller GUID be?
57 static const CSSM_GUID test_guid
= {
58 0xFADE, 0, 0, { 1, 2, 3, 4, 5, 6, 7, 0 }
61 CSSM_PVC_MODE pvc_policy
= CSSM_PVC_NONE
;
62 crtn
= CSSM_Init(&version
, CSSM_PRIVILEGE_SCOPE_NONE
, &test_guid
,
63 CSSM_KEY_HIERARCHY_NONE
, &pvc_policy
, NULL
);
70 crtn
= CSSM_ModuleLoad(&gGuidAppleCSP
, CSSM_KEY_HIERARCHY_NONE
, NULL
, NULL
);
76 crtn
= CSSM_ModuleLoad(
77 &gGuidAppleX509CL
, CSSM_KEY_HIERARCHY_NONE
, NULL
, NULL
);
83 crtn
= CSSM_ModuleLoad(
84 &gGuidAppleX509TP
, CSSM_KEY_HIERARCHY_NONE
, NULL
, NULL
);
91 const CSSM_API_MEMORY_FUNCS cssmMemoryFunctions
= {
99 crtn
= CSSM_ModuleAttach(&gGuidAppleCSP
, &version
, &cssmMemoryFunctions
, 0,
100 CSSM_SERVICE_CSP
, 0, CSSM_KEY_HIERARCHY_NONE
,
101 NULL
, 0, NULL
, &csp_handle_
);
102 DCHECK_EQ(CSSM_OK
, crtn
);
103 crtn
= CSSM_ModuleAttach(&gGuidAppleX509CL
, &version
, &cssmMemoryFunctions
,
104 0, CSSM_SERVICE_CL
, 0, CSSM_KEY_HIERARCHY_NONE
,
105 NULL
, 0, NULL
, &cl_handle_
);
106 DCHECK_EQ(CSSM_OK
, crtn
);
107 crtn
= CSSM_ModuleAttach(&gGuidAppleX509TP
, &version
, &cssmMemoryFunctions
,
108 0, CSSM_SERVICE_TP
, 0, CSSM_KEY_HIERARCHY_NONE
,
109 NULL
, 0, NULL
, &tp_handle_
);
110 DCHECK_EQ(CSSM_OK
, crtn
);
113 ~CSSMInitSingleton() {
116 CSSM_RETURN crtn
= CSSM_ModuleDetach(csp_handle_
);
117 DCHECK_EQ(CSSM_OK
, crtn
);
120 CSSM_RETURN crtn
= CSSM_ModuleDetach(cl_handle_
);
121 DCHECK_EQ(CSSM_OK
, crtn
);
124 CSSM_RETURN crtn
= CSSM_ModuleDetach(tp_handle_
);
125 DCHECK_EQ(CSSM_OK
, crtn
);
128 crtn
= CSSM_ModuleUnload(&gGuidAppleCSP
, NULL
, NULL
);
129 DCHECK_EQ(CSSM_OK
, crtn
);
132 crtn
= CSSM_ModuleUnload(&gGuidAppleX509CL
, NULL
, NULL
);
133 DCHECK_EQ(CSSM_OK
, crtn
);
136 crtn
= CSSM_ModuleUnload(&gGuidAppleX509TP
, NULL
, NULL
);
137 DCHECK_EQ(CSSM_OK
, crtn
);
140 crtn
= CSSM_Terminate();
141 DCHECK_EQ(CSSM_OK
, crtn
);
145 bool inited_
; // True if CSSM_Init has been called successfully.
146 bool csp_loaded_
; // True if gGuidAppleCSP has been loaded
147 bool cl_loaded_
; // True if gGuidAppleX509CL has been loaded.
148 bool tp_loaded_
; // True if gGuidAppleX509TP has been loaded.
149 CSSM_CSP_HANDLE csp_handle_
;
150 CSSM_CL_HANDLE cl_handle_
;
151 CSSM_TP_HANDLE tp_handle_
;
153 friend struct base::DefaultSingletonTraits
<CSSMInitSingleton
>;
160 void EnsureCSSMInit() {
161 CSSMInitSingleton::GetInstance();
164 CSSM_CSP_HANDLE
GetSharedCSPHandle() {
165 return CSSMInitSingleton::GetInstance()->csp_handle();
168 CSSM_CL_HANDLE
GetSharedCLHandle() {
169 return CSSMInitSingleton::GetInstance()->cl_handle();
172 CSSM_TP_HANDLE
GetSharedTPHandle() {
173 return CSSMInitSingleton::GetInstance()->tp_handle();
176 void* CSSMMalloc(CSSM_SIZE size
) {
177 return ::CSSMMalloc(size
, NULL
);
180 void CSSMFree(void* ptr
) {
181 ::CSSMFree(ptr
, NULL
);
184 void LogCSSMError(const char* fn_name
, CSSM_RETURN err
) {
187 base::ScopedCFTypeRef
<CFStringRef
> cfstr(
188 SecCopyErrorMessageString(err
, NULL
));
189 LOG(ERROR
) << fn_name
<< " returned " << err
190 << " (" << base::SysCFStringRefToUTF8(cfstr
) << ")";
193 ScopedCSSMData::ScopedCSSMData() {
194 memset(&data_
, 0, sizeof(data_
));
197 ScopedCSSMData::~ScopedCSSMData() {
199 CSSMFree(data_
.Data
);
204 } // namespace crypto