OLD | NEW |
---|---|
1 // Copyright (c) 2009 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2009 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "base/crypto/cssm_init.h" | 5 #include "base/crypto/cssm_init.h" |
6 | |
7 #include <Security/SecBase.h> | |
8 | |
6 #include "base/logging.h" | 9 #include "base/logging.h" |
7 #include "base/singleton.h" | 10 #include "base/singleton.h" |
11 #include "base/sys_string_conversions.h" | |
8 | 12 |
9 // When writing crypto code for Mac OS X, you may find the following | 13 // When writing crypto code for Mac OS X, you may find the following |
10 // documentation useful: | 14 // documentation useful: |
11 // - Common Security: CDSA and CSSM, Version 2 (with corrigenda) | 15 // - Common Security: CDSA and CSSM, Version 2 (with corrigenda) |
12 // http://www.opengroup.org/security/cdsa.htm | 16 // http://www.opengroup.org/security/cdsa.htm |
13 // - Apple Cryptographic Service Provider Functional Specification | 17 // - Apple Cryptographic Service Provider Functional Specification |
14 // - CryptoSample: http://developer.apple.com/SampleCode/CryptoSample/ | 18 // - CryptoSample: http://developer.apple.com/SampleCode/CryptoSample/ |
15 | 19 |
16 namespace { | 20 namespace { |
17 | 21 |
18 class CSSMInitSingleton { | 22 class CSSMInitSingleton { |
19 public: | 23 public: |
20 CSSMInitSingleton() : inited_(false), loaded_(false) { | 24 CSSMInitSingleton() : inited_(false), loaded_(false), csp_handle_(NULL) { |
21 static CSSM_VERSION version = {2, 0}; | 25 static CSSM_VERSION version = {2, 0}; |
22 // TODO(wtc): what should our caller GUID be? | 26 // TODO(wtc): what should our caller GUID be? |
23 static const CSSM_GUID test_guid = { | 27 static const CSSM_GUID test_guid = { |
24 0xFADE, 0, 0, { 1, 2, 3, 4, 5, 6, 7, 0 } | 28 0xFADE, 0, 0, { 1, 2, 3, 4, 5, 6, 7, 0 } |
25 }; | 29 }; |
26 CSSM_RETURN crtn; | 30 CSSM_RETURN crtn; |
27 CSSM_PVC_MODE pvc_policy = CSSM_PVC_NONE; | 31 CSSM_PVC_MODE pvc_policy = CSSM_PVC_NONE; |
28 crtn = CSSM_Init(&version, CSSM_PRIVILEGE_SCOPE_NONE, &test_guid, | 32 crtn = CSSM_Init(&version, CSSM_PRIVILEGE_SCOPE_NONE, &test_guid, |
29 CSSM_KEY_HIERARCHY_NONE, &pvc_policy, NULL); | 33 CSSM_KEY_HIERARCHY_NONE, &pvc_policy, NULL); |
30 if (crtn) { | 34 if (crtn) { |
31 NOTREACHED(); | 35 NOTREACHED(); |
32 return; | 36 return; |
33 } | 37 } |
34 inited_ = true; | 38 inited_ = true; |
35 | 39 |
36 crtn = CSSM_ModuleLoad(&gGuidAppleCSP, CSSM_KEY_HIERARCHY_NONE, NULL, NULL); | 40 crtn = CSSM_ModuleLoad(&gGuidAppleCSP, CSSM_KEY_HIERARCHY_NONE, NULL, NULL); |
37 if (crtn) { | 41 if (crtn) { |
38 NOTREACHED(); | 42 NOTREACHED(); |
39 return; | 43 return; |
40 } | 44 } |
41 loaded_ = true; | 45 loaded_ = true; |
46 | |
47 crtn = CSSM_ModuleAttach(&gGuidAppleCSP, &version, | |
48 &base::kCssmMemoryFunctions, 0, | |
49 CSSM_SERVICE_CSP, 0, CSSM_KEY_HIERARCHY_NONE, | |
50 NULL, 0, NULL, &csp_handle_); | |
51 DCHECK(crtn == CSSM_OK); | |
42 } | 52 } |
43 | 53 |
44 ~CSSMInitSingleton() { | 54 ~CSSMInitSingleton() { |
45 CSSM_RETURN crtn; | 55 CSSM_RETURN crtn; |
56 if (csp_handle_) { | |
57 CSSM_RETURN crtn = CSSM_ModuleDetach(csp_handle_); | |
58 DCHECK(crtn == CSSM_OK); | |
59 } | |
46 if (loaded_) { | 60 if (loaded_) { |
47 crtn = CSSM_ModuleUnload(&gGuidAppleCSP, NULL, NULL); | 61 crtn = CSSM_ModuleUnload(&gGuidAppleCSP, NULL, NULL); |
48 DCHECK(crtn == CSSM_OK); | 62 DCHECK(crtn == CSSM_OK); |
49 } | 63 } |
50 if (inited_) { | 64 if (inited_) { |
51 crtn = CSSM_Terminate(); | 65 crtn = CSSM_Terminate(); |
52 DCHECK(crtn == CSSM_OK); | 66 DCHECK(crtn == CSSM_OK); |
53 } | 67 } |
54 } | 68 } |
55 | 69 |
70 CSSM_CSP_HANDLE csp_handle() const {return csp_handle_;} | |
71 | |
56 private: | 72 private: |
57 bool inited_; // True if CSSM_Init has been called successfully. | 73 bool inited_; // True if CSSM_Init has been called successfully. |
58 bool loaded_; // True if CSSM_ModuleLoad has been called successfully. | 74 bool loaded_; // True if CSSM_ModuleLoad has been called successfully. |
75 CSSM_CSP_HANDLE csp_handle_; | |
59 }; | 76 }; |
60 | 77 |
61 } // namespace | 78 } // namespace |
62 | 79 |
63 namespace base { | 80 namespace base { |
64 | 81 |
65 void EnsureCSSMInit() { | 82 void EnsureCSSMInit() { |
66 Singleton<CSSMInitSingleton>::get(); | 83 Singleton<CSSMInitSingleton>::get(); |
67 } | 84 } |
68 | 85 |
86 CSSM_CSP_HANDLE GetSharedCSPHandle() { | |
87 return Singleton<CSSMInitSingleton>::get()->csp_handle(); | |
88 } | |
89 | |
69 void* CSSMMalloc(CSSM_SIZE size, void *alloc_ref) { | 90 void* CSSMMalloc(CSSM_SIZE size, void *alloc_ref) { |
70 return malloc(size); | 91 return malloc(size); |
71 } | 92 } |
72 | 93 |
73 void CSSMFree(void* mem_ptr, void* alloc_ref) { | 94 void CSSMFree(void* mem_ptr, void* alloc_ref) { |
74 free(mem_ptr); | 95 free(mem_ptr); |
75 } | 96 } |
76 | 97 |
77 void* CSSMRealloc(void* ptr, CSSM_SIZE size, void* alloc_ref) { | 98 void* CSSMRealloc(void* ptr, CSSM_SIZE size, void* alloc_ref) { |
78 return realloc(ptr, size); | 99 return realloc(ptr, size); |
79 } | 100 } |
80 | 101 |
81 void* CSSMCalloc(uint32 num, CSSM_SIZE size, void* alloc_ref) { | 102 void* CSSMCalloc(uint32 num, CSSM_SIZE size, void* alloc_ref) { |
82 return calloc(num, size); | 103 return calloc(num, size); |
83 } | 104 } |
84 | 105 |
85 const CSSM_API_MEMORY_FUNCS kCssmMemoryFunctions = { | 106 const CSSM_API_MEMORY_FUNCS kCssmMemoryFunctions = { |
86 CSSMMalloc, | 107 CSSMMalloc, |
87 CSSMFree, | 108 CSSMFree, |
88 CSSMRealloc, | 109 CSSMRealloc, |
89 CSSMCalloc, | 110 CSSMCalloc, |
90 NULL | 111 NULL |
91 }; | 112 }; |
92 | 113 |
114 void LogCSSMError(const char *fn_name, CSSM_RETURN err) { | |
wtc
2010/03/26 21:14:30
Nit: I like the original |function_name| better.
| |
115 if (!err) | |
116 return; | |
117 CFStringRef cfstr = SecCopyErrorMessageString(err, NULL); | |
118 if (cfstr) { | |
119 std::string err_name = SysCFStringRefToUTF8(cfstr); | |
120 CFRelease(cfstr); | |
121 LOG(ERROR) << fn_name << " returned " << err << " (" << err_name << ")"; | |
122 } else { | |
123 LOG(ERROR) << fn_name << " returned " << err; | |
124 } | |
125 } | |
126 | |
93 } // namespace base | 127 } // namespace base |
OLD | NEW |