OLD | NEW |
1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2010 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 "net/base/keygen_handler.h" | 5 #include "net/base/keygen_handler.h" |
6 | 6 |
7 #include <Security/SecAsn1Coder.h> | 7 #include <Security/SecAsn1Coder.h> |
8 #include <Security/SecAsn1Templates.h> | 8 #include <Security/SecAsn1Templates.h> |
9 #include <Security/Security.h> | 9 #include <Security/Security.h> |
10 | 10 |
11 #include "base/base64.h" | 11 #include "base/base64.h" |
12 #include "base/crypto/cssm_init.h" | 12 #include "base/crypto/cssm_init.h" |
13 #include "base/lock.h" | 13 #include "base/lock.h" |
14 #include "base/logging.h" | 14 #include "base/logging.h" |
15 #include "base/scoped_cftyperef.h" | 15 #include "base/scoped_cftyperef.h" |
| 16 #include "base/string_util.h" |
| 17 #include "base/sys_string_conversions.h" |
16 | 18 |
17 // These are in Security.framework but not declared in a public header. | 19 // These are in Security.framework but not declared in a public header. |
18 extern const SecAsn1Template kSecAsn1AlgorithmIDTemplate[]; | 20 extern const SecAsn1Template kSecAsn1AlgorithmIDTemplate[]; |
19 extern const SecAsn1Template kSecAsn1SubjectPublicKeyInfoTemplate[]; | 21 extern const SecAsn1Template kSecAsn1SubjectPublicKeyInfoTemplate[]; |
20 | 22 |
21 namespace net { | 23 namespace net { |
22 | 24 |
23 // Declarations of Netscape keygen cert structures for ASN.1 encoding: | 25 // Declarations of Netscape keygen cert structures for ASN.1 encoding: |
24 | 26 |
25 struct PublicKeyAndChallenge { | 27 struct PublicKeyAndChallenge { |
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
82 SEC_ASN1_BIT_STRING, | 84 SEC_ASN1_BIT_STRING, |
83 offsetof(SignedPublicKeyAndChallenge, signature) | 85 offsetof(SignedPublicKeyAndChallenge, signature) |
84 }, | 86 }, |
85 { | 87 { |
86 0 | 88 0 |
87 } | 89 } |
88 }; | 90 }; |
89 | 91 |
90 | 92 |
91 static OSStatus CreateRSAKeyPair(int size_in_bits, | 93 static OSStatus CreateRSAKeyPair(int size_in_bits, |
| 94 SecAccessRef initial_access, |
92 SecKeyRef* out_pub_key, | 95 SecKeyRef* out_pub_key, |
93 SecKeyRef* out_priv_key); | 96 SecKeyRef* out_priv_key); |
94 static OSStatus SignData(CSSM_DATA data, | 97 static OSStatus SignData(CSSM_DATA data, |
95 SecKeyRef private_key, | 98 SecKeyRef private_key, |
96 CSSM_DATA* signature); | 99 CSSM_DATA* signature); |
97 | 100 |
98 std::string KeygenHandler::GenKeyAndSignChallenge() { | 101 std::string KeygenHandler::GenKeyAndSignChallenge() { |
99 std::string result; | 102 std::string result; |
100 OSStatus err; | 103 OSStatus err; |
| 104 SecAccessRef initial_access = NULL; |
101 SecKeyRef public_key = NULL; | 105 SecKeyRef public_key = NULL; |
102 SecKeyRef private_key = NULL; | 106 SecKeyRef private_key = NULL; |
103 SecAsn1CoderRef coder = NULL; | 107 SecAsn1CoderRef coder = NULL; |
104 CSSM_DATA signature = {0, NULL}; | 108 CSSM_DATA signature = {0, NULL}; |
105 | 109 |
106 { | 110 { |
| 111 if (url_.has_host()) { |
| 112 // TODO(davidben): Use something like "Key generated for |
| 113 // example.com", but localize it. |
| 114 scoped_cftyperef<CFStringRef> label( |
| 115 base::SysUTF8ToCFStringRef(url_.host())); |
| 116 // Create an initial access object to set the SecAccessRef. This |
| 117 // sets a label on the Keychain dialogs. Pass NULL as the second |
| 118 // argument to use the default trusted list; only allow the |
| 119 // current application to access without user confirmation. |
| 120 err = SecAccessCreate(label, NULL, &initial_access); |
| 121 // If we fail, just continue without a label. |
| 122 if (err) |
| 123 base::LogCSSMError("SecAccessCreate", err); |
| 124 } |
| 125 |
107 // Create the key-pair. | 126 // Create the key-pair. |
108 err = CreateRSAKeyPair(key_size_in_bits_, &public_key, &private_key); | 127 err = CreateRSAKeyPair(key_size_in_bits_, initial_access, |
| 128 &public_key, &private_key); |
109 if (err) | 129 if (err) |
110 goto failure; | 130 goto failure; |
111 | 131 |
112 // Get the public key data (DER sequence of modulus, exponent). | 132 // Get the public key data (DER sequence of modulus, exponent). |
113 CFDataRef key_data = NULL; | 133 CFDataRef key_data = NULL; |
114 err = SecKeychainItemExport(public_key, kSecFormatBSAFE, 0, NULL, | 134 err = SecKeychainItemExport(public_key, kSecFormatBSAFE, 0, NULL, |
115 &key_data); | 135 &key_data); |
116 if (err) { | 136 if (err) { |
117 base::LogCSSMError("SecKeychainItemExpor", err); | 137 base::LogCSSMError("SecKeychainItemExpor", err); |
118 goto failure; | 138 goto failure; |
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
181 if (public_key) | 201 if (public_key) |
182 SecKeychainItemDelete(reinterpret_cast<SecKeychainItemRef>(public_key)); | 202 SecKeychainItemDelete(reinterpret_cast<SecKeychainItemRef>(public_key)); |
183 if (private_key) | 203 if (private_key) |
184 SecKeychainItemDelete(reinterpret_cast<SecKeychainItemRef>(private_key)); | 204 SecKeychainItemDelete(reinterpret_cast<SecKeychainItemRef>(private_key)); |
185 } | 205 } |
186 | 206 |
187 // Clean up: | 207 // Clean up: |
188 free(signature.Data); | 208 free(signature.Data); |
189 if (coder) | 209 if (coder) |
190 SecAsn1CoderRelease(coder); | 210 SecAsn1CoderRelease(coder); |
| 211 if (initial_access) |
| 212 CFRelease(initial_access); |
191 if (public_key) | 213 if (public_key) |
192 CFRelease(public_key); | 214 CFRelease(public_key); |
193 if (private_key) | 215 if (private_key) |
194 CFRelease(private_key); | 216 CFRelease(private_key); |
195 return result; | 217 return result; |
196 } | 218 } |
197 | 219 |
198 | 220 |
199 static OSStatus CreateRSAKeyPair(int size_in_bits, | 221 static OSStatus CreateRSAKeyPair(int size_in_bits, |
| 222 SecAccessRef initial_access, |
200 SecKeyRef* out_pub_key, | 223 SecKeyRef* out_pub_key, |
201 SecKeyRef* out_priv_key) { | 224 SecKeyRef* out_priv_key) { |
202 OSStatus err; | 225 OSStatus err; |
203 SecKeychainRef keychain; | 226 SecKeychainRef keychain; |
204 err = SecKeychainCopyDefault(&keychain); | 227 err = SecKeychainCopyDefault(&keychain); |
205 if (err) { | 228 if (err) { |
206 base::LogCSSMError("SecKeychainCopyDefault", err); | 229 base::LogCSSMError("SecKeychainCopyDefault", err); |
207 return err; | 230 return err; |
208 } | 231 } |
209 scoped_cftyperef<SecKeychainRef> scoped_keychain(keychain); | 232 scoped_cftyperef<SecKeychainRef> scoped_keychain(keychain); |
210 { | 233 { |
211 AutoLock locked(base::GetMacSecurityServicesLock()); | 234 AutoLock locked(base::GetMacSecurityServicesLock()); |
212 err = SecKeyCreatePair( | 235 err = SecKeyCreatePair( |
213 keychain, | 236 keychain, |
214 CSSM_ALGID_RSA, | 237 CSSM_ALGID_RSA, |
215 size_in_bits, | 238 size_in_bits, |
216 0LL, | 239 0LL, |
217 // public key usage and attributes: | 240 // public key usage and attributes: |
218 CSSM_KEYUSE_ENCRYPT | CSSM_KEYUSE_VERIFY | CSSM_KEYUSE_WRAP, | 241 CSSM_KEYUSE_ENCRYPT | CSSM_KEYUSE_VERIFY | CSSM_KEYUSE_WRAP, |
219 CSSM_KEYATTR_EXTRACTABLE | CSSM_KEYATTR_PERMANENT, | 242 CSSM_KEYATTR_EXTRACTABLE | CSSM_KEYATTR_PERMANENT, |
220 // private key usage and attributes: | 243 // private key usage and attributes: |
221 CSSM_KEYUSE_DECRYPT | CSSM_KEYUSE_SIGN | CSSM_KEYUSE_UNWRAP, | 244 CSSM_KEYUSE_DECRYPT | CSSM_KEYUSE_SIGN | CSSM_KEYUSE_UNWRAP, |
222 CSSM_KEYATTR_EXTRACTABLE | CSSM_KEYATTR_PERMANENT | | 245 CSSM_KEYATTR_EXTRACTABLE | CSSM_KEYATTR_PERMANENT | |
223 CSSM_KEYATTR_SENSITIVE, | 246 CSSM_KEYATTR_SENSITIVE, |
224 NULL, | 247 initial_access, |
225 out_pub_key, out_priv_key); | 248 out_pub_key, out_priv_key); |
226 } | 249 } |
227 if (err) | 250 if (err) |
228 base::LogCSSMError("SecKeyCreatePair", err); | 251 base::LogCSSMError("SecKeyCreatePair", err); |
229 return err; | 252 return err; |
230 } | 253 } |
231 | 254 |
232 static OSStatus CreateSignatureContext(SecKeyRef key, | 255 static OSStatus CreateSignatureContext(SecKeyRef key, |
233 CSSM_ALGORITHMS algorithm, | 256 CSSM_ALGORITHMS algorithm, |
234 CSSM_CC_HANDLE* out_cc_handle) { | 257 CSSM_CC_HANDLE* out_cc_handle) { |
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
288 return err; | 311 return err; |
289 } | 312 } |
290 err = CSSM_SignData(cc_handle, &data, 1, CSSM_ALGID_NONE, signature); | 313 err = CSSM_SignData(cc_handle, &data, 1, CSSM_ALGID_NONE, signature); |
291 if (err) | 314 if (err) |
292 base::LogCSSMError("CSSM_SignData", err); | 315 base::LogCSSMError("CSSM_SignData", err); |
293 CSSM_DeleteContext(cc_handle); | 316 CSSM_DeleteContext(cc_handle); |
294 return err; | 317 return err; |
295 } | 318 } |
296 | 319 |
297 } // namespace net | 320 } // namespace net |
OLD | NEW |