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/rsa_private_key.h" | 5 #include "base/crypto/rsa_private_key.h" |
6 | 6 |
7 #include <list> | 7 #include <list> |
8 | 8 |
9 #include "base/crypto/cssm_init.h" | 9 #include "base/crypto/cssm_init.h" |
10 #include "base/logging.h" | 10 #include "base/logging.h" |
11 #include "base/scoped_ptr.h" | 11 #include "base/scoped_ptr.h" |
12 | 12 |
13 namespace base { | 13 namespace base { |
14 | 14 |
15 // static | 15 // static |
16 RSAPrivateKey* RSAPrivateKey::Create(uint16 num_bits) { | 16 RSAPrivateKey* RSAPrivateKey::Create(uint16 num_bits) { |
17 scoped_ptr<RSAPrivateKey> result(new RSAPrivateKey); | 17 scoped_ptr<RSAPrivateKey> result(new RSAPrivateKey); |
18 | 18 |
19 CSSM_CC_HANDLE cc_handle; | 19 CSSM_CC_HANDLE cc_handle; |
20 CSSM_RETURN crtn; | 20 CSSM_RETURN crtn; |
21 crtn = CSSM_CSP_CreateKeyGenContext(result->csp_handle(), CSSM_ALGID_RSA, | 21 crtn = CSSM_CSP_CreateKeyGenContext(GetSharedCSPHandle(), CSSM_ALGID_RSA, |
22 num_bits, NULL, NULL, NULL, NULL, NULL, | 22 num_bits, NULL, NULL, NULL, NULL, NULL, |
23 &cc_handle); | 23 &cc_handle); |
24 if (crtn) { | 24 if (crtn) { |
25 NOTREACHED() << "CSSM_CSP_CreateKeyGenContext failed: " << crtn; | 25 NOTREACHED() << "CSSM_CSP_CreateKeyGenContext failed: " << crtn; |
26 return NULL; | 26 return NULL; |
27 } | 27 } |
28 | 28 |
29 CSSM_KEY public_key; | 29 CSSM_KEY public_key; |
30 memset(&public_key, 0, sizeof(CSSM_KEY)); | 30 memset(&public_key, 0, sizeof(CSSM_KEY)); |
31 CSSM_DATA label = { 9, | 31 CSSM_DATA label = { 9, |
32 const_cast<uint8*>(reinterpret_cast<const uint8*>("temp_key")) }; | 32 const_cast<uint8*>(reinterpret_cast<const uint8*>("temp_key")) }; |
33 crtn = CSSM_GenerateKeyPair(cc_handle, | 33 crtn = CSSM_GenerateKeyPair(cc_handle, |
34 CSSM_KEYUSE_VERIFY, | 34 CSSM_KEYUSE_VERIFY, |
35 CSSM_KEYATTR_RETURN_DATA | CSSM_KEYATTR_EXTRACTABLE, &label, | 35 CSSM_KEYATTR_RETURN_DATA | CSSM_KEYATTR_EXTRACTABLE, &label, |
36 &public_key, CSSM_KEYUSE_SIGN, | 36 &public_key, CSSM_KEYUSE_SIGN, |
37 CSSM_KEYATTR_RETURN_DATA | CSSM_KEYATTR_EXTRACTABLE, &label, NULL, | 37 CSSM_KEYATTR_RETURN_DATA | CSSM_KEYATTR_EXTRACTABLE, &label, NULL, |
38 result->key()); | 38 result->key()); |
39 CSSM_DeleteContext(cc_handle); | 39 CSSM_DeleteContext(cc_handle); |
40 if (crtn) { | 40 if (crtn) { |
41 NOTREACHED() << "CSSM_CSP_CreateKeyGenContext failed: " << crtn; | 41 NOTREACHED() << "CSSM_CSP_CreateKeyGenContext failed: " << crtn; |
42 return NULL; | 42 return NULL; |
43 } | 43 } |
44 | 44 |
45 // Public key is not needed. | 45 // Public key is not needed. |
46 CSSM_FreeKey(result->csp_handle(), NULL, &public_key, CSSM_FALSE); | 46 CSSM_FreeKey(GetSharedCSPHandle(), NULL, &public_key, CSSM_FALSE); |
47 | 47 |
48 return result.release(); | 48 return result.release(); |
49 } | 49 } |
50 | 50 |
51 // static | 51 // static |
52 RSAPrivateKey* RSAPrivateKey::CreateFromPrivateKeyInfo( | 52 RSAPrivateKey* RSAPrivateKey::CreateFromPrivateKeyInfo( |
53 const std::vector<uint8>& input) { | 53 const std::vector<uint8>& input) { |
54 if (input.empty()) | 54 if (input.empty()) |
55 return NULL; | 55 return NULL; |
56 | 56 |
57 scoped_ptr<RSAPrivateKey> result(new RSAPrivateKey); | 57 scoped_ptr<RSAPrivateKey> result(new RSAPrivateKey); |
58 | 58 |
59 CSSM_KEY key; | 59 CSSM_KEY key; |
60 memset(&key, 0, sizeof(key)); | 60 memset(&key, 0, sizeof(key)); |
61 key.KeyData.Data = const_cast<uint8*>(&input.front()); | 61 key.KeyData.Data = const_cast<uint8*>(&input.front()); |
62 key.KeyData.Length = input.size(); | 62 key.KeyData.Length = input.size(); |
63 key.KeyHeader.Format = CSSM_KEYBLOB_RAW_FORMAT_PKCS8; | 63 key.KeyHeader.Format = CSSM_KEYBLOB_RAW_FORMAT_PKCS8; |
64 key.KeyHeader.HeaderVersion = CSSM_KEYHEADER_VERSION; | 64 key.KeyHeader.HeaderVersion = CSSM_KEYHEADER_VERSION; |
65 key.KeyHeader.BlobType = CSSM_KEYBLOB_RAW; | 65 key.KeyHeader.BlobType = CSSM_KEYBLOB_RAW; |
66 key.KeyHeader.AlgorithmId = CSSM_ALGID_RSA; | 66 key.KeyHeader.AlgorithmId = CSSM_ALGID_RSA; |
67 key.KeyHeader.KeyClass = CSSM_KEYCLASS_PRIVATE_KEY; | 67 key.KeyHeader.KeyClass = CSSM_KEYCLASS_PRIVATE_KEY; |
68 key.KeyHeader.KeyAttr = CSSM_KEYATTR_EXTRACTABLE; | 68 key.KeyHeader.KeyAttr = CSSM_KEYATTR_EXTRACTABLE; |
69 key.KeyHeader.KeyUsage = CSSM_KEYUSE_ANY; | 69 key.KeyHeader.KeyUsage = CSSM_KEYUSE_ANY; |
70 | 70 |
71 CSSM_KEY_SIZE key_size; | 71 CSSM_KEY_SIZE key_size; |
72 CSSM_RETURN crtn; | 72 CSSM_RETURN crtn; |
73 crtn = CSSM_QueryKeySizeInBits(result->csp_handle(), NULL, &key, &key_size); | 73 crtn = CSSM_QueryKeySizeInBits(GetSharedCSPHandle(), NULL, &key, &key_size); |
74 if (crtn) { | 74 if (crtn) { |
75 NOTREACHED() << "CSSM_QueryKeySizeInBits failed: " << crtn; | 75 NOTREACHED() << "CSSM_QueryKeySizeInBits failed: " << crtn; |
76 return NULL; | 76 return NULL; |
77 } | 77 } |
78 key.KeyHeader.LogicalKeySizeInBits = key_size.LogicalKeySizeInBits; | 78 key.KeyHeader.LogicalKeySizeInBits = key_size.LogicalKeySizeInBits; |
79 | 79 |
80 // Perform a NULL unwrap operation on the key so that result's key_ | 80 // Perform a NULL unwrap operation on the key so that result's key_ |
81 // instance variable points to a key that can be released via CSSM_FreeKey(). | 81 // instance variable points to a key that can be released via CSSM_FreeKey(). |
82 CSSM_ACCESS_CREDENTIALS creds; | 82 CSSM_ACCESS_CREDENTIALS creds; |
83 memset(&creds, 0, sizeof(CSSM_ACCESS_CREDENTIALS)); | 83 memset(&creds, 0, sizeof(CSSM_ACCESS_CREDENTIALS)); |
84 CSSM_CC_HANDLE cc_handle; | 84 CSSM_CC_HANDLE cc_handle; |
85 crtn = CSSM_CSP_CreateSymmetricContext(result->csp_handle(), CSSM_ALGID_NONE, | 85 crtn = CSSM_CSP_CreateSymmetricContext(GetSharedCSPHandle(), CSSM_ALGID_NONE, |
86 CSSM_ALGMODE_NONE, &creds, NULL, NULL, CSSM_PADDING_NONE, 0, &cc_handle); | 86 CSSM_ALGMODE_NONE, &creds, NULL, NULL, CSSM_PADDING_NONE, 0, &cc_handle); |
87 if (crtn) { | 87 if (crtn) { |
88 NOTREACHED() << "CSSM_CSP_CreateSymmetricContext failed: " << crtn; | 88 NOTREACHED() << "CSSM_CSP_CreateSymmetricContext failed: " << crtn; |
89 return NULL; | 89 return NULL; |
90 } | 90 } |
91 CSSM_DATA label_data, desc_data = { 0, NULL }; | 91 CSSM_DATA label_data, desc_data = { 0, NULL }; |
92 label_data.Data = | 92 label_data.Data = |
93 const_cast<uint8*>(reinterpret_cast<const uint8*>("unwrapped")); | 93 const_cast<uint8*>(reinterpret_cast<const uint8*>("unwrapped")); |
94 label_data.Length = 9; | 94 label_data.Length = 9; |
95 crtn = CSSM_UnwrapKey(cc_handle, NULL, &key, CSSM_KEYUSE_ANY, | 95 crtn = CSSM_UnwrapKey(cc_handle, NULL, &key, CSSM_KEYUSE_ANY, |
96 CSSM_KEYATTR_RETURN_DATA | CSSM_KEYATTR_EXTRACTABLE, &label_data, | 96 CSSM_KEYATTR_RETURN_DATA | CSSM_KEYATTR_EXTRACTABLE, &label_data, |
97 NULL, result->key(), &desc_data); | 97 NULL, result->key(), &desc_data); |
98 if (crtn) { | 98 if (crtn) { |
99 NOTREACHED() << "CSSM_UnwrapKey failed: " << crtn; | 99 NOTREACHED() << "CSSM_UnwrapKey failed: " << crtn; |
100 return NULL; | 100 return NULL; |
101 } | 101 } |
102 | 102 |
103 return result.release(); | 103 return result.release(); |
104 } | 104 } |
105 | 105 |
106 RSAPrivateKey::RSAPrivateKey() : csp_handle_(0) { | 106 RSAPrivateKey::RSAPrivateKey() { |
107 memset(&key_, 0, sizeof(key_)); | 107 memset(&key_, 0, sizeof(key_)); |
108 | 108 |
109 EnsureCSSMInit(); | 109 EnsureCSSMInit(); |
110 | |
111 static CSSM_VERSION version = {2, 0}; | |
112 CSSM_RETURN crtn; | |
113 crtn = CSSM_ModuleAttach(&gGuidAppleCSP, &version, &kCssmMemoryFunctions, 0, | |
114 CSSM_SERVICE_CSP, 0, CSSM_KEY_HIERARCHY_NONE, | |
115 NULL, 0, NULL, &csp_handle_); | |
116 DCHECK(crtn == CSSM_OK); | |
117 } | 110 } |
118 | 111 |
119 RSAPrivateKey::~RSAPrivateKey() { | 112 RSAPrivateKey::~RSAPrivateKey() { |
120 if (csp_handle_) { | 113 if (key_.KeyData.Data) { |
121 if (key_.KeyData.Data) { | 114 CSSM_FreeKey(GetSharedCSPHandle(), NULL, &key_, CSSM_FALSE); |
122 CSSM_FreeKey(csp_handle_, NULL, &key_, CSSM_FALSE); | |
123 } | |
124 CSSM_RETURN crtn = CSSM_ModuleDetach(csp_handle_); | |
125 DCHECK(crtn == CSSM_OK); | |
126 } | 115 } |
127 } | 116 } |
128 | 117 |
129 bool RSAPrivateKey::ExportPrivateKey(std::vector<uint8>* output) { | 118 bool RSAPrivateKey::ExportPrivateKey(std::vector<uint8>* output) { |
130 if (!key_.KeyData.Data || !key_.KeyData.Length) { | 119 if (!key_.KeyData.Data || !key_.KeyData.Length) { |
131 return false; | 120 return false; |
132 } | 121 } |
133 output->clear(); | 122 output->clear(); |
134 output->insert(output->end(), key_.KeyData.Data, | 123 output->insert(output->end(), key_.KeyData.Data, |
135 key_.KeyData.Data + key_.KeyData.Length); | 124 key_.KeyData.Data + key_.KeyData.Length); |
136 return true; | 125 return true; |
137 } | 126 } |
138 | 127 |
139 bool RSAPrivateKey::ExportPublicKey(std::vector<uint8>* output) { | 128 bool RSAPrivateKey::ExportPublicKey(std::vector<uint8>* output) { |
140 PrivateKeyInfoCodec private_key_info(true); | 129 PrivateKeyInfoCodec private_key_info(true); |
141 std::vector<uint8> private_key_data; | 130 std::vector<uint8> private_key_data; |
142 private_key_data.assign(key_.KeyData.Data, | 131 private_key_data.assign(key_.KeyData.Data, |
143 key_.KeyData.Data + key_.KeyData.Length); | 132 key_.KeyData.Data + key_.KeyData.Length); |
144 return (private_key_info.Import(private_key_data) && | 133 return (private_key_info.Import(private_key_data) && |
145 private_key_info.ExportPublicKeyInfo(output)); | 134 private_key_info.ExportPublicKeyInfo(output)); |
146 } | 135 } |
147 | 136 |
148 } // namespace base | 137 } // namespace base |
OLD | NEW |