| 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 |