OLD | NEW |
1 /* | 1 /* |
2 * Platform specific crypto wrappers | 2 * Platform specific crypto wrappers |
3 * | 3 * |
4 * ***** BEGIN LICENSE BLOCK ***** | 4 * ***** BEGIN LICENSE BLOCK ***** |
5 * Version: MPL 1.1/GPL 2.0/LGPL 2.1 | 5 * Version: MPL 1.1/GPL 2.0/LGPL 2.1 |
6 * | 6 * |
7 * The contents of this file are subject to the Mozilla Public License Version | 7 * The contents of this file are subject to the Mozilla Public License Version |
8 * 1.1 (the "License"); you may not use this file except in compliance with | 8 * 1.1 (the "License"); you may not use this file except in compliance with |
9 * the License. You may obtain a copy of the License at | 9 * the License. You may obtain a copy of the License at |
10 * http://www.mozilla.org/MPL/ | 10 * http://www.mozilla.org/MPL/ |
(...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
94 if (arena) { | 94 if (arena) { |
95 PORT_FreeArena(arena, PR_FALSE); | 95 PORT_FreeArena(arena, PR_FALSE); |
96 } | 96 } |
97 return NULL; | 97 return NULL; |
98 } | 98 } |
99 | 99 |
100 #if defined(XP_WIN32) | 100 #if defined(XP_WIN32) |
101 void | 101 void |
102 ssl_FreePlatformKey(PlatformKey key) | 102 ssl_FreePlatformKey(PlatformKey key) |
103 { | 103 { |
104 CryptReleaseContext(key, 0); | 104 if (key) { |
| 105 if (key->dwKeySpec != CERT_NCRYPT_KEY_SPEC) |
| 106 CryptReleaseContext(key->hCryptProv, 0); |
| 107 /* FIXME(rsleevi): Close CNG keys. */ |
| 108 PORT_Free(key); |
| 109 } |
105 } | 110 } |
106 | 111 |
107 void | 112 void |
108 ssl_FreePlatformAuthInfo(PlatformAuthInfo* info) | 113 ssl_FreePlatformAuthInfo(PlatformAuthInfo* info) |
109 { | 114 { |
110 if (info->provider != NULL) { | 115 if (info->provider != NULL) { |
111 PORT_Free(info->provider); | 116 PORT_Free(info->provider); |
112 info->provider = NULL; | 117 info->provider = NULL; |
113 } | 118 } |
114 if (info->container != NULL) { | 119 if (info->container != NULL) { |
(...skipping 26 matching lines...) Expand all Loading... |
141 CryptReleaseContext(prov, 0); | 146 CryptReleaseContext(prov, 0); |
142 return PR_TRUE; | 147 return PR_TRUE; |
143 } | 148 } |
144 | 149 |
145 void | 150 void |
146 ssl_GetPlatformAuthInfoForKey(PlatformKey key, | 151 ssl_GetPlatformAuthInfoForKey(PlatformKey key, |
147 PlatformAuthInfo *info) | 152 PlatformAuthInfo *info) |
148 { | 153 { |
149 DWORD bytesNeeded = 0; | 154 DWORD bytesNeeded = 0; |
150 ssl_InitPlatformAuthInfo(info); | 155 ssl_InitPlatformAuthInfo(info); |
| 156 if (!key || key->dwKeySpec == CERT_NCRYPT_KEY_SPEC) |
| 157 goto error; |
| 158 |
151 bytesNeeded = sizeof(info->provType); | 159 bytesNeeded = sizeof(info->provType); |
152 if (!CryptGetProvParam(key, PP_PROVTYPE, (BYTE*)&info->provType, | 160 if (!CryptGetProvParam(key->hCryptProv, PP_PROVTYPE, |
153 &bytesNeeded, 0)) | 161 (BYTE*)&info->provType, &bytesNeeded, 0)) |
154 goto error; | 162 goto error; |
155 | 163 |
156 bytesNeeded = 0; | 164 bytesNeeded = 0; |
157 if (!CryptGetProvParam(key, PP_CONTAINER, NULL, &bytesNeeded, 0)) | 165 if (!CryptGetProvParam(key->hCryptProv, PP_CONTAINER, NULL, &bytesNeeded, |
| 166 0)) |
158 goto error; | 167 goto error; |
159 info->container = (char*)PORT_Alloc(bytesNeeded); | 168 info->container = (char*)PORT_Alloc(bytesNeeded); |
160 if (info->container == NULL) | 169 if (info->container == NULL) |
161 goto error; | 170 goto error; |
162 if (!CryptGetProvParam(key, PP_CONTAINER, (BYTE*)info->container, | 171 if (!CryptGetProvParam(key->hCryptProv, PP_CONTAINER, |
163 &bytesNeeded, 0)) | 172 (BYTE*)info->container, &bytesNeeded, 0)) |
164 goto error; | 173 goto error; |
165 | 174 |
166 bytesNeeded = 0; | 175 bytesNeeded = 0; |
167 if (!CryptGetProvParam(key, PP_NAME, NULL, &bytesNeeded, 0)) | 176 if (!CryptGetProvParam(key->hCryptProv, PP_NAME, NULL, &bytesNeeded, 0)) |
168 goto error; | 177 goto error; |
169 info->provider = (char*)PORT_Alloc(bytesNeeded); | 178 info->provider = (char*)PORT_Alloc(bytesNeeded); |
170 if (info->provider == NULL) | 179 if (info->provider == NULL) |
171 goto error; | 180 goto error; |
172 if (!CryptGetProvParam(key, PP_NAME, (BYTE*)info->provider, | 181 if (!CryptGetProvParam(key->hCryptProv, PP_NAME, (BYTE*)info->provider, |
173 &bytesNeeded, 0)) | 182 &bytesNeeded, 0)) |
174 goto error; | 183 goto error; |
175 | 184 |
176 goto done; | 185 goto done; |
177 error: | 186 error: |
178 ssl_FreePlatformAuthInfo(info); | 187 ssl_FreePlatformAuthInfo(info); |
179 | 188 |
180 done: | 189 done: |
181 return; | 190 return; |
182 } | 191 } |
183 | 192 |
184 SECStatus | 193 SECStatus |
185 ssl3_PlatformSignHashes(SSL3Hashes *hash, PlatformKey key, SECItem *buf, | 194 ssl3_PlatformSignHashes(SSL3Hashes *hash, PlatformKey key, SECItem *buf, |
186 PRBool isTLS) | 195 PRBool isTLS) |
187 { | 196 { |
188 SECStatus rv = SECFailure; | 197 SECStatus rv = SECFailure; |
189 PRBool doDerEncode = PR_FALSE; | 198 PRBool doDerEncode = PR_FALSE; |
190 SECItem hashItem; | 199 SECItem hashItem; |
191 /* TODO(rsleevi): Should AT_SIGNATURE also be checked if doing client | |
192 * auth? | |
193 */ | |
194 DWORD keySpec = AT_KEYEXCHANGE; | |
195 HCRYPTKEY hKey = 0; | 200 HCRYPTKEY hKey = 0; |
196 DWORD argLen = 0; | 201 DWORD argLen = 0; |
197 ALG_ID keyAlg = 0; | 202 ALG_ID keyAlg = 0; |
198 DWORD signatureLen = 0; | 203 DWORD signatureLen = 0; |
199 ALG_ID hashAlg = 0; | 204 ALG_ID hashAlg = 0; |
200 HCRYPTHASH hHash = 0; | 205 HCRYPTHASH hHash = 0; |
201 DWORD hashLen = 0; | 206 DWORD hashLen = 0; |
202 unsigned int i = 0; | 207 unsigned int i = 0; |
203 | 208 |
204 buf->data = NULL; | 209 buf->data = NULL; |
205 if (!CryptGetUserKey(key, keySpec, &hKey)) { | 210 if (!CryptGetUserKey(key->hCryptProv, key->dwKeySpec, &hKey)) { |
206 if (GetLastError() == NTE_NO_KEY) { | 211 if (GetLastError() == NTE_NO_KEY) { |
207 PORT_SetError(SEC_ERROR_NO_KEY); | 212 PORT_SetError(SEC_ERROR_NO_KEY); |
208 } else { | 213 } else { |
209 PORT_SetError(SEC_ERROR_INVALID_KEY); | 214 PORT_SetError(SEC_ERROR_INVALID_KEY); |
210 } | 215 } |
211 goto done; | 216 goto done; |
212 } | 217 } |
213 | 218 |
214 argLen = sizeof(keyAlg); | 219 argLen = sizeof(keyAlg); |
215 if (!CryptGetKeyParam(hKey, KP_ALGID, (BYTE*)&keyAlg, &argLen, 0)) { | 220 if (!CryptGetKeyParam(hKey, KP_ALGID, (BYTE*)&keyAlg, &argLen, 0)) { |
216 PORT_SetError(SEC_ERROR_INVALID_KEY); | 221 PORT_SetError(SEC_ERROR_INVALID_KEY); |
217 goto done; | 222 goto done; |
218 } | 223 } |
219 | 224 |
220 switch (keyAlg) { | 225 switch (keyAlg) { |
221 case CALG_RSA_KEYX: | 226 case CALG_RSA_KEYX: |
222 case CALG_RSA_SIGN: | 227 case CALG_RSA_SIGN: |
223 hashAlg = CALG_SSL3_SHAMD5; | 228 hashAlg = CALG_SSL3_SHAMD5; |
224 hashItem.data = hash->md5; | 229 hashItem.data = hash->md5; |
225 hashItem.len = sizeof(SSL3Hashes); | 230 hashItem.len = sizeof(SSL3Hashes); |
226 break; | 231 break; |
227 case CALG_DSS_SIGN: | 232 case CALG_DSS_SIGN: |
228 /* TODO: Support CALG_ECDSA once tested */ | |
229 case CALG_ECDSA: | 233 case CALG_ECDSA: |
230 if (keyAlg == CALG_ECDSA) { | 234 if (keyAlg == CALG_ECDSA) { |
231 doDerEncode = PR_TRUE; | 235 doDerEncode = PR_TRUE; |
232 } else { | 236 } else { |
233 doDerEncode = isTLS; | 237 doDerEncode = isTLS; |
234 } | 238 } |
235 hashAlg = CALG_SHA1; | 239 hashAlg = CALG_SHA1; |
236 hashItem.data = hash->sha; | 240 hashItem.data = hash->sha; |
237 hashItem.len = sizeof(hash->sha); | 241 hashItem.len = sizeof(hash->sha); |
238 break; | 242 break; |
239 default: | 243 default: |
240 PORT_SetError(SEC_ERROR_INVALID_KEY); | 244 PORT_SetError(SEC_ERROR_INVALID_KEY); |
241 goto done; | 245 goto done; |
242 } | 246 } |
243 PRINT_BUF(60, (NULL, "hash(es) to be signed", hashItem.data, hashItem.len)); | 247 PRINT_BUF(60, (NULL, "hash(es) to be signed", hashItem.data, hashItem.len)); |
244 | 248 |
245 if (!CryptCreateHash(key, hashAlg, 0, 0, &hHash)) { | 249 if (!CryptCreateHash(key->hCryptProv, hashAlg, 0, 0, &hHash)) { |
246 PORT_SetError(SSL_ERROR_SIGN_HASHES_FAILURE); | 250 PORT_SetError(SSL_ERROR_SIGN_HASHES_FAILURE); |
247 goto done; | 251 goto done; |
248 } | 252 } |
249 argLen = sizeof(hashLen); | 253 argLen = sizeof(hashLen); |
250 if (!CryptGetHashParam(hHash, HP_HASHSIZE, (BYTE*)&hashLen, &argLen, 0)) { | 254 if (!CryptGetHashParam(hHash, HP_HASHSIZE, (BYTE*)&hashLen, &argLen, 0)) { |
251 PORT_SetError(SSL_ERROR_SIGN_HASHES_FAILURE); | 255 PORT_SetError(SSL_ERROR_SIGN_HASHES_FAILURE); |
252 goto done; | 256 goto done; |
253 } | 257 } |
254 if (hashLen != hashItem.len) { | 258 if (hashLen != hashItem.len) { |
255 PORT_SetError(SSL_ERROR_SIGN_HASHES_FAILURE); | 259 PORT_SetError(SSL_ERROR_SIGN_HASHES_FAILURE); |
256 goto done; | 260 goto done; |
257 } | 261 } |
258 if (!CryptSetHashParam(hHash, HP_HASHVAL, (BYTE*)hashItem.data, 0)) { | 262 if (!CryptSetHashParam(hHash, HP_HASHVAL, (BYTE*)hashItem.data, 0)) { |
259 PORT_SetError(SSL_ERROR_SIGN_HASHES_FAILURE); | 263 PORT_SetError(SSL_ERROR_SIGN_HASHES_FAILURE); |
260 goto done; | 264 goto done; |
261 } | 265 } |
262 if (!CryptSignHash(hHash, keySpec, NULL, CRYPT_NOHASHOID, | 266 if (!CryptSignHash(hHash, key->dwKeySpec, NULL, CRYPT_NOHASHOID, |
263 NULL, &signatureLen) || signatureLen == 0) { | 267 NULL, &signatureLen) || signatureLen == 0) { |
264 PORT_SetError(SSL_ERROR_SIGN_HASHES_FAILURE); | 268 PORT_SetError(SSL_ERROR_SIGN_HASHES_FAILURE); |
265 goto done; | 269 goto done; |
266 } | 270 } |
267 buf->data = (unsigned char *)PORT_Alloc(signatureLen); | 271 buf->data = (unsigned char *)PORT_Alloc(signatureLen); |
268 if (!buf->data) | 272 if (!buf->data) |
269 goto done; /* error code was set. */ | 273 goto done; /* error code was set. */ |
270 | 274 |
271 if (!CryptSignHash(hHash, keySpec, NULL, CRYPT_NOHASHOID, | 275 if (!CryptSignHash(hHash, key->dwKeySpec, NULL, CRYPT_NOHASHOID, |
272 (BYTE*)buf->data, &signatureLen)) { | 276 (BYTE*)buf->data, &signatureLen)) { |
273 PORT_SetError(SSL_ERROR_SIGN_HASHES_FAILURE); | 277 PORT_SetError(SSL_ERROR_SIGN_HASHES_FAILURE); |
274 goto done; | 278 goto done; |
275 } | 279 } |
276 buf->len = signatureLen; | 280 buf->len = signatureLen; |
277 | 281 |
278 /* CryptoAPI signs in little-endian, so reverse */ | 282 /* CryptoAPI signs in little-endian, so reverse */ |
279 for (i = 0; i < buf->len / 2; ++i) { | 283 for (i = 0; i < buf->len / 2; ++i) { |
280 unsigned char tmp = buf->data[i]; | 284 unsigned char tmp = buf->data[i]; |
281 buf->data[i] = buf->data[buf->len - 1 - i]; | 285 buf->data[i] = buf->data[buf->len - 1 - i]; |
(...skipping 276 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
558 SECStatus | 562 SECStatus |
559 ssl3_PlatformSignHashes(SSL3Hashes *hash, PlatformKey key, SECItem *buf, | 563 ssl3_PlatformSignHashes(SSL3Hashes *hash, PlatformKey key, SECItem *buf, |
560 PRBool isTLS) | 564 PRBool isTLS) |
561 { | 565 { |
562 PORT_SetError(PR_NOT_IMPLEMENTED_ERROR); | 566 PORT_SetError(PR_NOT_IMPLEMENTED_ERROR); |
563 return SECFailure; | 567 return SECFailure; |
564 } | 568 } |
565 #endif | 569 #endif |
566 | 570 |
567 #endif /* NSS_PLATFORM_CLIENT_AUTH */ | 571 #endif /* NSS_PLATFORM_CLIENT_AUTH */ |
OLD | NEW |