Chromium Code Reviews| 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 | 6 |
| 7 #include <Security/SecBase.h> | 7 #include <Security/SecBase.h> |
| 8 | 8 |
| 9 #include "base/logging.h" | 9 #include "base/logging.h" |
| 10 #include "base/mac/scoped_cftyperef.h" | |
| 10 #include "base/singleton.h" | 11 #include "base/singleton.h" |
| 11 #include "base/synchronization/lock.h" | 12 #include "base/synchronization/lock.h" |
| 12 #include "base/sys_string_conversions.h" | 13 #include "base/sys_string_conversions.h" |
| 13 | 14 |
| 14 // When writing crypto code for Mac OS X, you may find the following | 15 // When writing crypto code for Mac OS X, you may find the following |
| 15 // documentation useful: | 16 // documentation useful: |
| 16 // - Common Security: CDSA and CSSM, Version 2 (with corrigenda) | 17 // - Common Security: CDSA and CSSM, Version 2 (with corrigenda) |
| 17 // http://www.opengroup.org/security/cdsa.htm | 18 // http://www.opengroup.org/security/cdsa.htm |
| 18 // - Apple Cryptographic Service Provider Functional Specification | 19 // - Apple Cryptographic Service Provider Functional Specification |
| 19 // - CryptoSample: http://developer.apple.com/SampleCode/CryptoSample/ | 20 // - CryptoSample: http://developer.apple.com/SampleCode/CryptoSample/ |
| 20 | 21 |
| 21 namespace { | 22 namespace { |
| 22 | 23 |
| 24 void* CSSMMalloc(CSSM_SIZE size, void *alloc_ref) { | |
|
Ryan Sleevi
2011/02/05 00:23:37
nit: void *alloc_ref -> void* alloc_ref
dmac
2011/02/08 01:23:45
Done.
| |
| 25 return malloc(size); | |
| 26 } | |
| 27 | |
| 28 void CSSMFree(void* mem_ptr, void* alloc_ref) { | |
| 29 free(mem_ptr); | |
| 30 } | |
| 31 | |
| 32 void* CSSMRealloc(void* ptr, CSSM_SIZE size, void* alloc_ref) { | |
| 33 return realloc(ptr, size); | |
| 34 } | |
| 35 | |
| 36 void* CSSMCalloc(uint32 num, CSSM_SIZE size, void* alloc_ref) { | |
| 37 return calloc(num, size); | |
| 38 } | |
| 39 | |
| 23 class CSSMInitSingleton { | 40 class CSSMInitSingleton { |
| 24 public: | 41 public: |
| 25 static CSSMInitSingleton* GetInstance() { | 42 static CSSMInitSingleton* GetInstance() { |
| 26 return Singleton<CSSMInitSingleton, | 43 return Singleton<CSSMInitSingleton, |
| 27 LeakySingletonTraits<CSSMInitSingleton> >::get(); | 44 LeakySingletonTraits<CSSMInitSingleton> >::get(); |
| 28 } | 45 } |
| 29 | 46 |
| 30 CSSM_CSP_HANDLE csp_handle() const { return csp_handle_; } | 47 CSSM_CSP_HANDLE csp_handle() const { return csp_handle_; } |
| 48 CSSM_CL_HANDLE cl_handle() const { return cl_handle_; } | |
|
Ryan Sleevi
2011/02/05 00:23:37
nit: only once space between const and {
dmac
2011/02/08 01:23:45
Done.
| |
| 49 CSSM_TP_HANDLE tp_handle() const { return tp_handle_; } | |
| 31 | 50 |
| 32 private: | 51 private: |
| 33 CSSMInitSingleton() : inited_(false), loaded_(false), csp_handle_(NULL) { | 52 CSSMInitSingleton() |
| 53 : inited_(false), csp_loaded_(false), cl_loaded_(false), | |
| 54 tp_loaded_(false), csp_handle_(NULL), cl_handle_(NULL), | |
| 55 tp_handle_(NULL) { | |
| 34 static CSSM_VERSION version = {2, 0}; | 56 static CSSM_VERSION version = {2, 0}; |
| 35 // TODO(wtc): what should our caller GUID be? | 57 // TODO(wtc): what should our caller GUID be? |
| 36 static const CSSM_GUID test_guid = { | 58 static const CSSM_GUID test_guid = { |
| 37 0xFADE, 0, 0, { 1, 2, 3, 4, 5, 6, 7, 0 } | 59 0xFADE, 0, 0, { 1, 2, 3, 4, 5, 6, 7, 0 } |
| 38 }; | 60 }; |
| 39 CSSM_RETURN crtn; | 61 CSSM_RETURN crtn; |
| 40 CSSM_PVC_MODE pvc_policy = CSSM_PVC_NONE; | 62 CSSM_PVC_MODE pvc_policy = CSSM_PVC_NONE; |
| 41 crtn = CSSM_Init(&version, CSSM_PRIVILEGE_SCOPE_NONE, &test_guid, | 63 crtn = CSSM_Init(&version, CSSM_PRIVILEGE_SCOPE_NONE, &test_guid, |
| 42 CSSM_KEY_HIERARCHY_NONE, &pvc_policy, NULL); | 64 CSSM_KEY_HIERARCHY_NONE, &pvc_policy, NULL); |
| 43 if (crtn) { | 65 if (crtn) { |
| 44 NOTREACHED(); | 66 NOTREACHED(); |
| 45 return; | 67 return; |
| 46 } | 68 } |
| 47 inited_ = true; | 69 inited_ = true; |
| 48 | 70 |
| 49 crtn = CSSM_ModuleLoad(&gGuidAppleCSP, CSSM_KEY_HIERARCHY_NONE, NULL, NULL); | 71 crtn = CSSM_ModuleLoad(&gGuidAppleCSP, CSSM_KEY_HIERARCHY_NONE, NULL, NULL); |
| 50 if (crtn) { | 72 if (crtn) { |
| 51 NOTREACHED(); | 73 NOTREACHED(); |
| 52 return; | 74 return; |
| 53 } | 75 } |
| 54 loaded_ = true; | 76 csp_loaded_ = true; |
| 77 crtn = CSSM_ModuleLoad( | |
| 78 &gGuidAppleX509CL, CSSM_KEY_HIERARCHY_NONE, NULL, NULL); | |
| 79 if (crtn) { | |
| 80 NOTREACHED(); | |
| 81 return; | |
| 82 } | |
| 83 cl_loaded_ = true; | |
| 84 crtn = CSSM_ModuleLoad( | |
| 85 &gGuidAppleX509TP, CSSM_KEY_HIERARCHY_NONE, NULL, NULL); | |
| 86 if (crtn) { | |
| 87 NOTREACHED(); | |
| 88 return; | |
| 89 } | |
| 90 tp_loaded_ = true; | |
| 55 | 91 |
| 56 crtn = CSSM_ModuleAttach(&gGuidAppleCSP, &version, | 92 const CSSM_API_MEMORY_FUNCS cssmMemoryFunctions = { |
| 57 &base::kCssmMemoryFunctions, 0, | 93 CSSMMalloc, |
| 94 CSSMFree, | |
| 95 CSSMRealloc, | |
| 96 CSSMCalloc, | |
| 97 NULL | |
| 98 }; | |
| 99 | |
| 100 crtn = CSSM_ModuleAttach(&gGuidAppleCSP, &version, &cssmMemoryFunctions, 0, | |
| 58 CSSM_SERVICE_CSP, 0, CSSM_KEY_HIERARCHY_NONE, | 101 CSSM_SERVICE_CSP, 0, CSSM_KEY_HIERARCHY_NONE, |
| 59 NULL, 0, NULL, &csp_handle_); | 102 NULL, 0, NULL, &csp_handle_); |
| 60 DCHECK(crtn == CSSM_OK); | 103 DCHECK(crtn == CSSM_OK); |
| 104 crtn = CSSM_ModuleAttach(&gGuidAppleX509CL, &version, &cssmMemoryFunctions, | |
| 105 0, CSSM_SERVICE_CL, 0, CSSM_KEY_HIERARCHY_NONE, | |
| 106 NULL, 0, NULL, &cl_handle_); | |
| 107 DCHECK(crtn == CSSM_OK); | |
| 108 crtn = CSSM_ModuleAttach(&gGuidAppleX509TP, &version, &cssmMemoryFunctions, | |
| 109 0, CSSM_SERVICE_TP, 0, CSSM_KEY_HIERARCHY_NONE, | |
| 110 NULL, 0, NULL, &tp_handle_); | |
| 111 DCHECK(crtn == CSSM_OK); | |
| 61 } | 112 } |
| 62 | 113 |
| 63 ~CSSMInitSingleton() { | 114 ~CSSMInitSingleton() { |
| 64 CSSM_RETURN crtn; | 115 CSSM_RETURN crtn; |
| 65 if (csp_handle_) { | 116 if (csp_handle_) { |
| 66 CSSM_RETURN crtn = CSSM_ModuleDetach(csp_handle_); | 117 CSSM_RETURN crtn = CSSM_ModuleDetach(csp_handle_); |
| 67 DCHECK(crtn == CSSM_OK); | 118 DCHECK(crtn == CSSM_OK); |
| 68 } | 119 } |
| 69 if (loaded_) { | 120 if (cl_handle_) { |
| 121 CSSM_RETURN crtn = CSSM_ModuleDetach(cl_handle_); | |
| 122 DCHECK(crtn == CSSM_OK); | |
| 123 } | |
| 124 if (tp_handle_) { | |
| 125 CSSM_RETURN crtn = CSSM_ModuleDetach(tp_handle_); | |
| 126 DCHECK(crtn == CSSM_OK); | |
| 127 } | |
| 128 if (csp_loaded_) { | |
| 70 crtn = CSSM_ModuleUnload(&gGuidAppleCSP, NULL, NULL); | 129 crtn = CSSM_ModuleUnload(&gGuidAppleCSP, NULL, NULL); |
| 71 DCHECK(crtn == CSSM_OK); | 130 DCHECK(crtn == CSSM_OK); |
| 72 } | 131 } |
| 132 if (cl_loaded_) { | |
| 133 crtn = CSSM_ModuleUnload(&gGuidAppleX509CL, NULL, NULL); | |
| 134 DCHECK(crtn == CSSM_OK); | |
| 135 } | |
| 136 if (tp_loaded_) { | |
| 137 crtn = CSSM_ModuleUnload(&gGuidAppleX509TP, NULL, NULL); | |
| 138 DCHECK(crtn == CSSM_OK); | |
| 139 } | |
| 73 if (inited_) { | 140 if (inited_) { |
| 74 crtn = CSSM_Terminate(); | 141 crtn = CSSM_Terminate(); |
| 75 DCHECK(crtn == CSSM_OK); | 142 DCHECK(crtn == CSSM_OK); |
| 76 } | 143 } |
| 77 } | 144 } |
| 78 | 145 |
| 79 bool inited_; // True if CSSM_Init has been called successfully. | 146 bool inited_; // True if CSSM_Init has been called successfully. |
| 80 bool loaded_; // True if CSSM_ModuleLoad has been called successfully. | 147 bool csp_loaded_; // True if gGuidAppleCSP has been loaded |
| 148 bool cl_loaded_; // True if gGuidAppleX509CL has been loaded. | |
| 149 bool tp_loaded_; // True if gGuidAppleX509TP has been loaded. | |
| 81 CSSM_CSP_HANDLE csp_handle_; | 150 CSSM_CSP_HANDLE csp_handle_; |
| 151 CSSM_CL_HANDLE cl_handle_; | |
| 152 CSSM_TP_HANDLE tp_handle_; | |
| 82 | 153 |
| 83 friend struct DefaultSingletonTraits<CSSMInitSingleton>; | 154 friend struct DefaultSingletonTraits<CSSMInitSingleton>; |
| 84 }; | 155 }; |
| 85 | 156 |
| 86 // This singleton is separate as it pertains to Apple's wrappers over | 157 // This singleton is separate as it pertains to Apple's wrappers over |
| 87 // their own CSSM handles, as opposed to our own CSSM_CSP_HANDLE. | 158 // their own CSSM handles, as opposed to our own CSSM_CSP_HANDLE. |
| 88 class SecurityServicesSingleton { | 159 class SecurityServicesSingleton { |
| 89 public: | 160 public: |
| 90 static SecurityServicesSingleton* GetInstance() { | 161 static SecurityServicesSingleton* GetInstance() { |
| 91 return Singleton<SecurityServicesSingleton, | 162 return Singleton<SecurityServicesSingleton, |
| (...skipping 18 matching lines...) Expand all Loading... | |
| 110 namespace base { | 181 namespace base { |
| 111 | 182 |
| 112 void EnsureCSSMInit() { | 183 void EnsureCSSMInit() { |
| 113 CSSMInitSingleton::GetInstance(); | 184 CSSMInitSingleton::GetInstance(); |
| 114 } | 185 } |
| 115 | 186 |
| 116 CSSM_CSP_HANDLE GetSharedCSPHandle() { | 187 CSSM_CSP_HANDLE GetSharedCSPHandle() { |
| 117 return CSSMInitSingleton::GetInstance()->csp_handle(); | 188 return CSSMInitSingleton::GetInstance()->csp_handle(); |
| 118 } | 189 } |
| 119 | 190 |
| 120 void* CSSMMalloc(CSSM_SIZE size, void *alloc_ref) { | 191 CSSM_CL_HANDLE GetSharedCLHandle() { |
| 121 return malloc(size); | 192 return CSSMInitSingleton::GetInstance()->cl_handle(); |
| 122 } | 193 } |
| 123 | 194 |
| 124 void CSSMFree(void* mem_ptr, void* alloc_ref) { | 195 CSSM_TP_HANDLE GetSharedTPHandle() { |
| 125 free(mem_ptr); | 196 return CSSMInitSingleton::GetInstance()->tp_handle(); |
| 126 } | 197 } |
| 127 | 198 |
| 128 void* CSSMRealloc(void* ptr, CSSM_SIZE size, void* alloc_ref) { | 199 void CSSMFree(void* ptr) { |
| 129 return realloc(ptr, size); | 200 ::CSSMFree(ptr, NULL); |
| 130 } | 201 } |
| 131 | 202 |
| 132 void* CSSMCalloc(uint32 num, CSSM_SIZE size, void* alloc_ref) { | |
| 133 return calloc(num, size); | |
| 134 } | |
| 135 | |
| 136 const CSSM_API_MEMORY_FUNCS kCssmMemoryFunctions = { | |
| 137 CSSMMalloc, | |
| 138 CSSMFree, | |
| 139 CSSMRealloc, | |
| 140 CSSMCalloc, | |
| 141 NULL | |
| 142 }; | |
| 143 | |
| 144 void LogCSSMError(const char *fn_name, CSSM_RETURN err) { | 203 void LogCSSMError(const char *fn_name, CSSM_RETURN err) { |
|
Ryan Sleevi
2011/02/05 00:23:37
nit: const char *fn_name -> const char* fn_name
dmac
2011/02/08 01:23:45
Done.
| |
| 145 if (!err) | 204 if (!err) |
| 146 return; | 205 return; |
| 147 CFStringRef cfstr = SecCopyErrorMessageString(err, NULL); | 206 base::mac::ScopedCFTypeRef<CFStringRef> cfstr( |
| 148 if (cfstr) { | 207 SecCopyErrorMessageString(err, NULL)); |
| 149 std::string err_name = SysCFStringRefToUTF8(cfstr); | 208 LOG(ERROR) << fn_name << " returned " << err |
| 150 CFRelease(cfstr); | 209 << " (" << SysCFStringRefToUTF8(cfstr) << ")"; |
| 151 LOG(ERROR) << fn_name << " returned " << err << " (" << err_name << ")"; | |
| 152 } else { | |
| 153 LOG(ERROR) << fn_name << " returned " << err; | |
| 154 } | |
| 155 } | 210 } |
| 156 | 211 |
| 157 base::Lock& GetMacSecurityServicesLock() { | 212 base::Lock& GetMacSecurityServicesLock() { |
| 158 return SecurityServicesSingleton::GetInstance()->lock(); | 213 return SecurityServicesSingleton::GetInstance()->lock(); |
| 159 } | 214 } |
| 160 | 215 |
| 216 ScopedCSSMData::ScopedCSSMData() { | |
| 217 memset(&data_, 0, sizeof(data_)); | |
| 218 } | |
| 219 | |
| 220 ScopedCSSMData::~ScopedCSSMData() { | |
| 221 if (data_.Data) { | |
| 222 CSSMFree(data_.Data); | |
| 223 data_.Data = NULL; | |
| 224 } | |
| 225 } | |
| 226 | |
| 161 } // namespace base | 227 } // namespace base |
| OLD | NEW |