Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(383)

Side by Side Diff: runtime/bin/secure_socket.cc

Issue 22887014: Remove the certificate management methods from dart:io (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 7 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « runtime/bin/secure_socket.h ('k') | runtime/bin/secure_socket_patch.dart » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a 2 // for details. All rights reserved. Use of this source code is governed by a
3 // BSD-style license that can be found in the LICENSE file. 3 // BSD-style license that can be found in the LICENSE file.
4 4
5 #include "bin/secure_socket.h" 5 #include "bin/secure_socket.h"
6 6
7 #include <errno.h> 7 #include <errno.h>
8 #include <fcntl.h> 8 #include <fcntl.h>
9 #include <sys/stat.h> 9 #include <sys/stat.h>
10 #include <stdio.h> 10 #include <stdio.h>
11 #include <string.h> 11 #include <string.h>
12 12
13 #include <certdb.h>
14 #include <key.h> 13 #include <key.h>
15 #include <keyt.h> 14 #include <keyt.h>
16 #include <nss.h> 15 #include <nss.h>
17 #include <p12.h>
18 #include <p12plcy.h>
19 #include <pk11pub.h> 16 #include <pk11pub.h>
20 #include <prerror.h> 17 #include <prerror.h>
21 #include <prinit.h> 18 #include <prinit.h>
22 #include <prnetdb.h> 19 #include <prnetdb.h>
23 #include <secmod.h> 20 #include <secmod.h>
24 #include <ssl.h> 21 #include <ssl.h>
25 #include <sslproto.h> 22 #include <sslproto.h>
26 23
27 #include "bin/builtin.h" 24 #include "bin/builtin.h"
28 #include "bin/dartutils.h" 25 #include "bin/dartutils.h"
29 #include "bin/net/nss_memio.h" 26 #include "bin/net/nss_memio.h"
30 #include "bin/socket.h" 27 #include "bin/socket.h"
31 #include "bin/thread.h" 28 #include "bin/thread.h"
32 #include "bin/utils.h" 29 #include "bin/utils.h"
33 #include "platform/utils.h" 30 #include "platform/utils.h"
34 31
35 #include "include/dart_api.h" 32 #include "include/dart_api.h"
36 33
37 34
38 namespace dart { 35 namespace dart {
39 namespace bin { 36 namespace bin {
40 37
41 bool SSLFilter::library_initialized_ = false; 38 bool SSLFilter::library_initialized_ = false;
42 // To protect library initialization. 39 // To protect library initialization.
43 dart::Mutex* SSLFilter::mutex = new dart::Mutex(); 40 dart::Mutex* SSLFilter::mutex_ = new dart::Mutex();
44 // The password is needed when creating secure server sockets. It can 41 // The password is needed when creating secure server sockets. It can
45 // be null if only secure client sockets are used. 42 // be null if only secure client sockets are used.
46 char* SSLFilter::password_ = NULL; 43 const char* SSLFilter::password_ = NULL;
47 44
48 // Forward declaration. 45 // Forward declaration.
49 static void ProcessFilter(Dart_Port dest_port_id, 46 static void ProcessFilter(Dart_Port dest_port_id,
50 Dart_Port reply_port_id, 47 Dart_Port reply_port_id,
51 Dart_CObject* message); 48 Dart_CObject* message);
52 49
53 NativeService SSLFilter::filter_service_("FilterService", ProcessFilter, 16); 50 NativeService SSLFilter::filter_service_("FilterService", ProcessFilter, 16);
54 51
55 static const int kSSLFilterNativeFieldIndex = 0; 52 static const int kSSLFilterNativeFieldIndex = 0;
56 53
(...skipping 168 matching lines...) Expand 10 before | Expand all | Expand 10 after
225 (Dart_NativeArguments args) { 222 (Dart_NativeArguments args) {
226 Dart_Handle certificate_database_object = 223 Dart_Handle certificate_database_object =
227 ThrowIfError(Dart_GetNativeArgument(args, 0)); 224 ThrowIfError(Dart_GetNativeArgument(args, 0));
228 // Check that the type is string, and get the UTF-8 C string value from it. 225 // Check that the type is string, and get the UTF-8 C string value from it.
229 const char* certificate_database = NULL; 226 const char* certificate_database = NULL;
230 if (Dart_IsString(certificate_database_object)) { 227 if (Dart_IsString(certificate_database_object)) {
231 ThrowIfError(Dart_StringToCString(certificate_database_object, 228 ThrowIfError(Dart_StringToCString(certificate_database_object,
232 &certificate_database)); 229 &certificate_database));
233 } else if (!Dart_IsNull(certificate_database_object)) { 230 } else if (!Dart_IsNull(certificate_database_object)) {
234 Dart_ThrowException(DartUtils::NewDartArgumentError( 231 Dart_ThrowException(DartUtils::NewDartArgumentError(
235 "SecureSocket.initialize: database argument is not a String or null")); 232 "Non-String certificate directory argument to SetCertificateDatabase"));
236 } 233 }
237 // Leave certificate_database as NULL if no value was provided. 234 // Leave certificate_database as NULL if no value was provided.
238 235
239 Dart_Handle password_object = ThrowIfError(Dart_GetNativeArgument(args, 1)); 236 Dart_Handle password_object = ThrowIfError(Dart_GetNativeArgument(args, 1));
240 // Check that the type is string or null, 237 // Check that the type is string or null,
241 // and get the UTF-8 C string value from it. 238 // and get the UTF-8 C string value from it.
242 const char* password = NULL; 239 const char* password = NULL;
243 if (Dart_IsString(password_object)) { 240 if (Dart_IsString(password_object)) {
244 ThrowIfError(Dart_StringToCString(password_object, &password)); 241 ThrowIfError(Dart_StringToCString(password_object, &password));
245 } else if (Dart_IsNull(password_object)) { 242 } else if (Dart_IsNull(password_object)) {
246 // Pass the empty string as the password. 243 // Pass the empty string as the password.
247 password = ""; 244 password = "";
248 } else { 245 } else {
249 Dart_ThrowException(DartUtils::NewDartArgumentError( 246 Dart_ThrowException(DartUtils::NewDartArgumentError(
250 "SecureSocket.initialize: password argument is not a String or null")); 247 "Password argument to SetCertificateDatabase is not a String or null"));
251 } 248 }
252 249
253 Dart_Handle builtin_roots_object = 250 Dart_Handle builtin_roots_object =
254 ThrowIfError(Dart_GetNativeArgument(args, 2)); 251 ThrowIfError(Dart_GetNativeArgument(args, 2));
255 // Check that the type is boolean, and get the boolean value from it. 252 // Check that the type is boolean, and get the boolean value from it.
256 bool builtin_roots = true; 253 bool builtin_roots = true;
257 if (Dart_IsBoolean(builtin_roots_object)) { 254 if (Dart_IsBoolean(builtin_roots_object)) {
258 ThrowIfError(Dart_BooleanValue(builtin_roots_object, &builtin_roots)); 255 ThrowIfError(Dart_BooleanValue(builtin_roots_object, &builtin_roots));
259 } else { 256 } else {
260 Dart_ThrowException(DartUtils::NewDartArgumentError( 257 Dart_ThrowException(DartUtils::NewDartArgumentError(
261 "SecureSocket.initialize: useBuiltinRoots argument is not a bool")); 258 "UseBuiltinRoots argument to SetCertificateDatabase is not a bool"));
262 } 259 }
263 260
264 Dart_Handle read_only_object = 261 SSLFilter::InitializeLibrary(certificate_database, password, builtin_roots);
265 ThrowIfError(Dart_GetNativeArgument(args, 3));
266 // Check that the type is boolean, and get the boolean value from it.
267 bool read_only = true;
268 if (Dart_IsBoolean(read_only_object)) {
269 ThrowIfError(Dart_BooleanValue(read_only_object, &read_only));
270 } else {
271 Dart_ThrowException(DartUtils::NewDartArgumentError(
272 "SecureSocket.initialize: readOnly argument is not a bool"));
273 }
274
275 SSLFilter::InitializeLibrary(
276 certificate_database, password, builtin_roots, read_only);
277 } 262 }
278 263
279 264
280 static Dart_Handle X509FromCertificate(CERTCertificate* certificate) {
281 PRTime start_validity;
282 PRTime end_validity;
283 SECStatus status =
284 CERT_GetCertTimes(certificate, &start_validity, &end_validity);
285 if (status != SECSuccess) {
286 ThrowPRException("CertificateException",
287 "Cannot get validity times from certificate");
288 }
289 int64_t start_epoch_ms = start_validity / PR_USEC_PER_MSEC;
290 int64_t end_epoch_ms = end_validity / PR_USEC_PER_MSEC;
291 Dart_Handle subject_name_object =
292 DartUtils::NewString(certificate->subjectName);
293 Dart_Handle issuer_name_object =
294 DartUtils::NewString(certificate->issuerName);
295 Dart_Handle start_epoch_ms_int = Dart_NewInteger(start_epoch_ms);
296 Dart_Handle end_epoch_ms_int = Dart_NewInteger(end_epoch_ms);
297
298 Dart_Handle date_type =
299 DartUtils::GetDartType(DartUtils::kCoreLibURL, "DateTime");
300 Dart_Handle from_milliseconds =
301 DartUtils::NewString("fromMillisecondsSinceEpoch");
302
303 Dart_Handle start_validity_date =
304 Dart_New(date_type, from_milliseconds, 1, &start_epoch_ms_int);
305 Dart_Handle end_validity_date =
306 Dart_New(date_type, from_milliseconds, 1, &end_epoch_ms_int);
307
308 Dart_Handle x509_type =
309 DartUtils::GetDartType(DartUtils::kIOLibURL, "X509Certificate");
310 Dart_Handle arguments[] = { subject_name_object,
311 issuer_name_object,
312 start_validity_date,
313 end_validity_date };
314 return Dart_New(x509_type, Dart_Null(), 4, arguments);
315 }
316
317
318 char* PasswordCallback(PK11SlotInfo* slot, PRBool retry, void* arg) {
319 if (!retry) {
320 return PL_strdup(static_cast<char*>(arg)); // Freed by NSS internals.
321 }
322 return NULL;
323 }
324
325
326 void FUNCTION_NAME(SecureSocket_AddCertificate)
327 (Dart_NativeArguments args) {
328 Dart_Handle certificate_object =
329 ThrowIfError(Dart_GetNativeArgument(args, 0));
330 Dart_Handle trust_object = ThrowIfError(Dart_GetNativeArgument(args, 1));
331
332 if (!Dart_IsList(certificate_object) || !Dart_IsString(trust_object)) {
333 Dart_ThrowException(DartUtils::NewDartArgumentError(
334 "Bad argument to SecureSocket.addCertificate"));
335 }
336
337 intptr_t length;
338 ThrowIfError(Dart_ListLength(certificate_object, &length));
339 uint8_t* certificate = reinterpret_cast<uint8_t*>(malloc(length + 1));
340 if (certificate == NULL) {
341 FATAL("Out of memory in SecureSocket.addCertificate");
342 }
343 ThrowIfError(Dart_ListGetAsBytes(
344 certificate_object, 0, certificate, length));
345
346 const char* trust_string;
347 ThrowIfError(Dart_StringToCString(trust_object,
348 &trust_string));
349
350 PK11SlotInfo* slot = PK11_GetInternalKeySlot();
351 SECStatus status = PK11_Authenticate(slot, PR_TRUE, SSLFilter::GetPassword());
352 PK11_FreeSlot(slot);
353 if (status == SECFailure) {
354 ThrowPRException("CertificateException",
355 "Could not authenticate to certificate database");
356 }
357
358 CERTCertificate* cert = CERT_DecodeCertFromPackage(
359 reinterpret_cast<char*>(certificate), length);
360 if (cert == NULL) {
361 ThrowPRException("CertificateException", "Certificate cannot be decoded");
362 }
363 CERTCertTrust trust;
364 status = CERT_DecodeTrustString(&trust, trust_string);
365 if (status != SECSuccess) {
366 ThrowPRException("CertificateException", "Trust string cannot be decoded");
367 }
368 {
369 MutexLocker locker(SSLFilter::mutex);
370 status = CERT_ChangeCertTrust(CERT_GetDefaultCertDB(), cert, &trust);
371 }
372 if (status != SECSuccess) {
373 ThrowPRException("CertificateException", "Cannot set trust attributes");
374 }
375
376 Dart_SetReturnValue(args, X509FromCertificate(cert));
377 return;
378 }
379
380
381 /*
382 * Called by the PKCS#12 decoder if a certificate's nickname collides with
383 * the nickname of a different existing certificate in the database.
384 */
385 SECItem* nickname_callback(SECItem *old_nickname,
386 PRBool *cancel,
387 void *arg) {
388 *cancel = PR_TRUE;
389 return NULL;
390 }
391
392
393 void FUNCTION_NAME(SecureSocket_ImportCertificatesWithPrivateKeys)
394 (Dart_NativeArguments args) {
395 Dart_Handle pk12_object = ThrowIfError(Dart_GetNativeArgument(args, 0));
396 if (!Dart_IsList(pk12_object)) {
397 Dart_ThrowException(DartUtils::NewDartArgumentError(
398 "SecureSocket.importPrivateCertificates: certificates is not a List"));
399 }
400
401 Dart_Handle password_object = ThrowIfError(Dart_GetNativeArgument(args, 1));
402 if (!Dart_IsString(password_object)) {
403 Dart_ThrowException(DartUtils::NewDartArgumentError(
404 "SecureSocket.importPrivateCertificates: password is not a String"));
405 }
406
407 intptr_t length;
408 ThrowIfError(Dart_ListLength(pk12_object, &length));
409 uint8_t* pk12 = Dart_ScopeAllocate(length);
410 if (pk12 == NULL) {
411 FATAL("Out of memory in SecureSocket.importPrivateCertificates");
412 }
413 ThrowIfError(Dart_ListGetAsBytes(pk12_object, 0, pk12, length));
414
415 // A big-endian Unicode (UTF16) password.
416 intptr_t password_length;
417 ThrowIfError(Dart_StringLength(password_object, &password_length));
418 password_length++;
419 uint16_t* password = reinterpret_cast<uint16_t*>(
420 Dart_ScopeAllocate(sizeof(uint16_t) * password_length));
421 if (password == NULL) {
422 FATAL("Out of memory in SecureSocket.importPrivateCertificates");
423 }
424 intptr_t returned_length = password_length;
425 ThrowIfError(Dart_StringToUTF16(password_object, password, &returned_length));
426 ASSERT(password_length == returned_length + 1);
427 password[password_length - 1] = 0;
428 for (int i = 0; i < password_length; ++i) {
429 password[i] = Utils::HostToBigEndian16(password[i]);
430 }
431 SECItem p12_password;
432 p12_password.type = siBuffer;
433 p12_password.data = reinterpret_cast<unsigned char*>(password);
434 p12_password.len = sizeof(uint16_t) * password_length;
435
436 Dart_SetReturnValue(args, Dart_Null());
437 // Set the password callback for the certificate database we are importing to.
438 // The password for a slot is gotten from a callback, and it is freed by the
439 // caller of the callback. The argument to the callback comes from the wincx
440 // argument to a PK11 function.
441 PK11SlotInfo* slot = PK11_GetInternalKeySlot();
442 SECStatus status = PK11_Authenticate(slot, PR_TRUE, SSLFilter::GetPassword());
443 if (status == SECFailure) {
444 PK11_FreeSlot(slot);
445 ThrowPRException("CertificateException",
446 "Could not authenticate to certificate database");
447 }
448
449 SEC_PKCS12DecoderContext* context = SEC_PKCS12DecoderStart(
450 &p12_password,
451 slot,
452 SSLFilter::GetPassword(),
453 NULL,
454 NULL,
455 NULL,
456 NULL,
457 NULL);
458 PK11_FreeSlot(slot);
459 if (!context) {
460 FATAL("Unexpected error: SecureSocket.addPrivateCertificates DecoderStart");
461 }
462 bool success;
463 {
464 MutexLocker locker(SSLFilter::mutex);
465 success =
466 SECSuccess == SEC_PKCS12DecoderUpdate(context, pk12, length) &&
467 SECSuccess == SEC_PKCS12DecoderVerify(context) &&
468 SECSuccess == SEC_PKCS12DecoderValidateBags(context,
469 nickname_callback) &&
470 SECSuccess == SEC_PKCS12DecoderImportBags(context);
471 }
472 SEC_PKCS12DecoderFinish(context);
473 if (!success) {
474 ThrowPRException("CertificateException", "Could not import PKCS#12 file");
475 }
476 }
477
478
479 void FUNCTION_NAME(SecureSocket_ChangeTrust)(Dart_NativeArguments args) {
480 Dart_Handle nickname_object = ThrowIfError(Dart_GetNativeArgument(args, 0));
481 if (!Dart_IsString(nickname_object)) {
482 Dart_ThrowException(DartUtils::NewDartArgumentError(
483 "SecureSocket.changeTrust: nickname argument is not a String"));
484 }
485 const char* nickname;
486 ThrowIfError(Dart_StringToCString(nickname_object, &nickname));
487
488 Dart_Handle trust_object = ThrowIfError(Dart_GetNativeArgument(args, 1));
489 if (!Dart_IsString(trust_object)) {
490 Dart_ThrowException(DartUtils::NewDartArgumentError(
491 "SecureSocket.changeTrust: trust argument is not a String"));
492 }
493 const char* trust_string;
494 ThrowIfError(Dart_StringToCString(trust_object, &trust_string));
495
496 PK11SlotInfo* slot = PK11_GetInternalKeySlot();
497 SECStatus status = PK11_Authenticate(slot, PR_TRUE, SSLFilter::GetPassword());
498 if (status == SECFailure) {
499 ThrowPRException("CertificateException",
500 "Could not authenticate to certificate database");
501 }
502 PK11_FreeSlot(slot);
503
504 CERTCertificate* certificate =
505 PK11_FindCertFromNickname(nickname, SSLFilter::GetPassword());
506 if (certificate == NULL) {
507 ThrowCertificateException("Cannot find certificate with nickname %s",
508 nickname);
509 }
510 CERTCertTrust trust;
511 if (SECSuccess != CERT_DecodeTrustString(&trust, trust_string)) {
512 CERT_DestroyCertificate(certificate);
513 ThrowPRException("CertificateException", "Trust string cannot be decoded");
514 }
515 {
516 MutexLocker locker(SSLFilter::mutex);
517 status = CERT_ChangeCertTrust(CERT_GetDefaultCertDB(), certificate, &trust);
518 }
519 if (status != SECSuccess) {
520 CERT_DestroyCertificate(certificate);
521 ThrowCertificateException("Cannot set trust on certificate %s", nickname);
522 }
523 Dart_SetReturnValue(args, X509FromCertificate(certificate));
524 CERT_DestroyCertificate(certificate);
525 }
526
527
528 void FUNCTION_NAME(SecureSocket_GetCertificate)(Dart_NativeArguments args) {
529 Dart_Handle nickname_object = ThrowIfError(Dart_GetNativeArgument(args, 0));
530 if (!Dart_IsString(nickname_object)) {
531 Dart_ThrowException(DartUtils::NewDartArgumentError(
532 "SecureSocket.getCertificate: nickname argument is not a String"));
533 }
534 const char* nickname;
535 ThrowIfError(Dart_StringToCString(nickname_object, &nickname));
536
537 CERTCertificate* certificate = PK11_FindCertFromNickname(
538 nickname, SSLFilter::GetPassword());
539 if (certificate != NULL) {
540 Dart_SetReturnValue(args, X509FromCertificate(certificate));
541 CERT_DestroyCertificate(certificate);
542 }
543 }
544
545
546 void FUNCTION_NAME(SecureSocket_RemoveCertificate)(Dart_NativeArguments args) {
547 Dart_Handle nickname_object =
548 ThrowIfError(Dart_GetNativeArgument(args, 0));
549 if (!Dart_IsString(nickname_object)) {
550 Dart_ThrowException(DartUtils::NewDartArgumentError(
551 "SecureSocket.removeCertificate: nickname is not a String"));
552 }
553 const char* nickname;
554 ThrowIfError(Dart_StringToCString(nickname_object, &nickname));
555
556 CERTCertificate* certificate =
557 PK11_FindCertFromNickname(nickname, SSLFilter::GetPassword());
558 if (certificate == NULL) {
559 ThrowCertificateException("Cannot find certificate with nickname %s",
560 nickname);
561 }
562 SECKEYPrivateKey* key =
563 PK11_FindKeyByAnyCert(certificate, SSLFilter::GetPassword());
564 // Free the copy returned from FindKeyByAnyCert.
565 SECKEY_DestroyPrivateKey(key);
566 SECStatus status;
567 {
568 MutexLocker locker(SSLFilter::mutex);
569 status = (key == NULL) ?
570 SEC_DeletePermCertificate(certificate) :
571 PK11_DeleteTokenCertAndKey(certificate, SSLFilter::GetPassword());
572 }
573 CERT_DestroyCertificate(certificate);
574 if (status != SECSuccess) {
575 ThrowCertificateException("Cannot remove certificate %s", nickname);
576 }
577 }
578
579
580 void FUNCTION_NAME(SecureSocket_PeerCertificate) 265 void FUNCTION_NAME(SecureSocket_PeerCertificate)
581 (Dart_NativeArguments args) { 266 (Dart_NativeArguments args) {
582 Dart_SetReturnValue(args, GetFilter(args)->PeerCertificate()); 267 Dart_SetReturnValue(args, GetFilter(args)->PeerCertificate());
583 } 268 }
584 269
585 270
586 void FUNCTION_NAME(SecureSocket_FilterPointer)(Dart_NativeArguments args) { 271 void FUNCTION_NAME(SecureSocket_FilterPointer)(Dart_NativeArguments args) {
587 intptr_t filter_pointer = reinterpret_cast<intptr_t>(GetFilter(args)); 272 intptr_t filter_pointer = reinterpret_cast<intptr_t>(GetFilter(args));
588 Dart_SetReturnValue(args, Dart_NewInteger(filter_pointer)); 273 Dart_SetReturnValue(args, Dart_NewInteger(filter_pointer));
589 } 274 }
(...skipping 126 matching lines...) Expand 10 before | Expand all | Expand 10 after
716 starts[i] = start; 401 starts[i] = start;
717 break; 402 break;
718 default: 403 default:
719 UNREACHABLE(); 404 UNREACHABLE();
720 } 405 }
721 } 406 }
722 return true; 407 return true;
723 } 408 }
724 409
725 410
411 static Dart_Handle X509FromCertificate(CERTCertificate* certificate) {
412 PRTime start_validity;
413 PRTime end_validity;
414 SECStatus status =
415 CERT_GetCertTimes(certificate, &start_validity, &end_validity);
416 if (status != SECSuccess) {
417 ThrowPRException("CertificateException",
418 "Cannot get validity times from certificate");
419 }
420 int64_t start_epoch_ms = start_validity / PR_USEC_PER_MSEC;
421 int64_t end_epoch_ms = end_validity / PR_USEC_PER_MSEC;
422 Dart_Handle subject_name_object =
423 DartUtils::NewString(certificate->subjectName);
424 Dart_Handle issuer_name_object =
425 DartUtils::NewString(certificate->issuerName);
426 Dart_Handle start_epoch_ms_int = Dart_NewInteger(start_epoch_ms);
427 Dart_Handle end_epoch_ms_int = Dart_NewInteger(end_epoch_ms);
428
429 Dart_Handle date_type =
430 DartUtils::GetDartType(DartUtils::kCoreLibURL, "DateTime");
431 Dart_Handle from_milliseconds =
432 DartUtils::NewString("fromMillisecondsSinceEpoch");
433
434 Dart_Handle start_validity_date =
435 Dart_New(date_type, from_milliseconds, 1, &start_epoch_ms_int);
436 Dart_Handle end_validity_date =
437 Dart_New(date_type, from_milliseconds, 1, &end_epoch_ms_int);
438
439 Dart_Handle x509_type =
440 DartUtils::GetDartType(DartUtils::kIOLibURL, "X509Certificate");
441 Dart_Handle arguments[] = { subject_name_object,
442 issuer_name_object,
443 start_validity_date,
444 end_validity_date };
445 return Dart_New(x509_type, Dart_Null(), 4, arguments);
446 }
447
448
726 void SSLFilter::Init(Dart_Handle dart_this) { 449 void SSLFilter::Init(Dart_Handle dart_this) {
727 if (!library_initialized_) { 450 if (!library_initialized_) {
728 InitializeLibrary(NULL, "", true, true, false); 451 InitializeLibrary(NULL, "", true, false);
729 } 452 }
730 ASSERT(string_start_ == NULL); 453 ASSERT(string_start_ == NULL);
731 string_start_ = Dart_NewPersistentHandle(DartUtils::NewString("start")); 454 string_start_ = Dart_NewPersistentHandle(DartUtils::NewString("start"));
732 ASSERT(string_start_ != NULL); 455 ASSERT(string_start_ != NULL);
733 ASSERT(string_length_ == NULL); 456 ASSERT(string_length_ == NULL);
734 string_length_ = Dart_NewPersistentHandle(DartUtils::NewString("length")); 457 string_length_ = Dart_NewPersistentHandle(DartUtils::NewString("length"));
735 ASSERT(string_length_ != NULL); 458 ASSERT(string_length_ != NULL);
736 ASSERT(bad_certificate_callback_ == NULL); 459 ASSERT(bad_certificate_callback_ == NULL);
737 bad_certificate_callback_ = Dart_NewPersistentHandle(Dart_Null()); 460 bad_certificate_callback_ = Dart_NewPersistentHandle(Dart_Null());
738 ASSERT(bad_certificate_callback_ != NULL); 461 ASSERT(bad_certificate_callback_ != NULL);
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after
791 514
792 515
793 void SSLFilter::RegisterBadCertificateCallback(Dart_Handle callback) { 516 void SSLFilter::RegisterBadCertificateCallback(Dart_Handle callback) {
794 ASSERT(bad_certificate_callback_ != NULL); 517 ASSERT(bad_certificate_callback_ != NULL);
795 Dart_DeletePersistentHandle(bad_certificate_callback_); 518 Dart_DeletePersistentHandle(bad_certificate_callback_);
796 bad_certificate_callback_ = Dart_NewPersistentHandle(callback); 519 bad_certificate_callback_ = Dart_NewPersistentHandle(callback);
797 ASSERT(bad_certificate_callback_ != NULL); 520 ASSERT(bad_certificate_callback_ != NULL);
798 } 521 }
799 522
800 523
524 char* PasswordCallback(PK11SlotInfo* slot, PRBool retry, void* arg) {
525 if (!retry) {
526 return PL_strdup(static_cast<char*>(arg)); // Freed by NSS internals.
527 }
528 return NULL;
529 }
530
531
801 static const char* builtin_roots_module = 532 static const char* builtin_roots_module =
802 #if defined(TARGET_OS_LINUX) || defined(TARGET_OS_ANDROID) 533 #if defined(TARGET_OS_LINUX) || defined(TARGET_OS_ANDROID)
803 "name=\"Root Certs\" library=\"libnssckbi.so\""; 534 "name=\"Root Certs\" library=\"libnssckbi.so\"";
804 #elif defined(TARGET_OS_MACOS) 535 #elif defined(TARGET_OS_MACOS)
805 "name=\"Root Certs\" library=\"libnssckbi.dylib\""; 536 "name=\"Root Certs\" library=\"libnssckbi.dylib\"";
806 #elif defined(TARGET_OS_WINDOWS) 537 #elif defined(TARGET_OS_WINDOWS)
807 "name=\"Root Certs\" library=\"nssckbi.dll\""; 538 "name=\"Root Certs\" library=\"nssckbi.dll\"";
808 #else 539 #else
809 #error Automatic target os detection failed. 540 #error Automatic target os detection failed.
810 #endif 541 #endif
811 542
812 543
813 544
814 void SSLFilter::InitializeLibrary(const char* certificate_database, 545 void SSLFilter::InitializeLibrary(const char* certificate_database,
815 const char* password, 546 const char* password,
816 bool use_builtin_root_certificates, 547 bool use_builtin_root_certificates,
817 bool read_only,
818 bool report_duplicate_initialization) { 548 bool report_duplicate_initialization) {
819 MutexLocker locker(mutex); 549 MutexLocker locker(mutex_);
820 SECStatus status; 550 SECStatus status;
821 if (!library_initialized_) { 551 if (!library_initialized_) {
822 PR_Init(PR_USER_THREAD, PR_PRIORITY_NORMAL, 0); 552 PR_Init(PR_USER_THREAD, PR_PRIORITY_NORMAL, 0);
823 // TODO(whesse): Verify there are no UTF-8 issues here. 553 // TODO(whesse): Verify there are no UTF-8 issues here.
824 if (certificate_database == NULL || certificate_database[0] == '\0') { 554 if (certificate_database == NULL || certificate_database[0] == '\0') {
825 status = NSS_NoDB_Init(NULL); 555 status = NSS_NoDB_Init(NULL);
826 if (status != SECSuccess) { 556 if (status != SECSuccess) {
827 mutex->Unlock(); // MutexLocker destructor not called when throwing. 557 mutex_->Unlock(); // MutexLocker destructor not called when throwing.
828 ThrowPRException("TlsException", 558 ThrowPRException("TlsException",
829 "Failed NSS_NoDB_Init call."); 559 "Failed NSS_NoDB_Init call.");
830 } 560 }
831 if (use_builtin_root_certificates) { 561 if (use_builtin_root_certificates) {
832 SECMODModule* module = SECMOD_LoadUserModule( 562 SECMODModule* module = SECMOD_LoadUserModule(
833 const_cast<char*>(builtin_roots_module), NULL, PR_FALSE); 563 const_cast<char*>(builtin_roots_module), NULL, PR_FALSE);
834 if (!module) { 564 if (!module) {
835 mutex->Unlock(); // MutexLocker destructor not called when throwing. 565 mutex_->Unlock(); // MutexLocker destructor not called when throwing.
836 ThrowPRException("TlsException", 566 ThrowPRException("TlsException",
837 "Failed to load builtin root certificates."); 567 "Failed to load builtin root certificates.");
838 } 568 }
839 } 569 }
840 } else { 570 } else {
841 PRUint32 init_flags = read_only ? NSS_INIT_READONLY : 0; 571 PRUint32 init_flags = NSS_INIT_READONLY;
842 if (!use_builtin_root_certificates) { 572 if (!use_builtin_root_certificates) {
843 init_flags |= NSS_INIT_NOMODDB; 573 init_flags |= NSS_INIT_NOMODDB;
844 } 574 }
845 status = NSS_Initialize(certificate_database, 575 status = NSS_Initialize(certificate_database,
846 "", 576 "",
847 "", 577 "",
848 SECMOD_DB, 578 SECMOD_DB,
849 init_flags); 579 init_flags);
850 if (status != SECSuccess) { 580 if (status != SECSuccess) {
851 mutex->Unlock(); // MutexLocker destructor not called when throwing. 581 mutex_->Unlock(); // MutexLocker destructor not called when throwing.
852 ThrowPRException("TlsException", 582 ThrowPRException("TlsException",
853 "Failed NSS_Init call."); 583 "Failed NSS_Init call.");
854 } 584 }
855 password_ = strdup(password); // This one copy persists until Dart exits. 585 password_ = strdup(password); // This one copy persists until Dart exits.
856 PK11_SetPasswordFunc(PasswordCallback); 586 PK11_SetPasswordFunc(PasswordCallback);
857 } 587 }
858 library_initialized_ = true; 588 library_initialized_ = true;
859 589
860 // Allow encoding and decoding of private keys in PKCS#12 files.
861 SEC_PKCS12EnableCipher(PKCS12_RC2_CBC_40, 1);
862 SEC_PKCS12EnableCipher(PKCS12_DES_EDE3_168, 1);
863 SEC_PKCS12SetPreferredCipher(PKCS12_DES_EDE3_168, 1);
864
865 status = NSS_SetDomesticPolicy(); 590 status = NSS_SetDomesticPolicy();
866 if (status != SECSuccess) { 591 if (status != SECSuccess) {
867 mutex->Unlock(); // MutexLocker destructor not called when throwing. 592 mutex_->Unlock(); // MutexLocker destructor not called when throwing.
868 ThrowPRException("TlsException", 593 ThrowPRException("TlsException",
869 "Failed NSS_SetDomesticPolicy call."); 594 "Failed NSS_SetDomesticPolicy call.");
870 } 595 }
871
872 // Enable TLS, as well as SSL3 and SSL2. 596 // Enable TLS, as well as SSL3 and SSL2.
873 status = SSL_OptionSetDefault(SSL_ENABLE_TLS, PR_TRUE); 597 status = SSL_OptionSetDefault(SSL_ENABLE_TLS, PR_TRUE);
874 if (status != SECSuccess) { 598 if (status != SECSuccess) {
875 mutex->Unlock(); // MutexLocker destructor not called when throwing. 599 mutex_->Unlock(); // MutexLocker destructor not called when throwing.
876 ThrowPRException("TlsException", 600 ThrowPRException("TlsException",
877 "Failed SSL_OptionSetDefault enable TLS call."); 601 "Failed SSL_OptionSetDefault enable TLS call.");
878 } 602 }
879 status = SSL_ConfigServerSessionIDCache(0, 0, 0, NULL); 603 status = SSL_ConfigServerSessionIDCache(0, 0, 0, NULL);
880 if (status != SECSuccess) { 604 if (status != SECSuccess) {
881 mutex->Unlock(); // MutexLocker destructor not called when throwing. 605 mutex_->Unlock(); // MutexLocker destructor not called when throwing.
882 ThrowPRException("TlsException", 606 ThrowPRException("TlsException",
883 "Failed SSL_ConfigServerSessionIDCache call."); 607 "Failed SSL_ConfigServerSessionIDCache call.");
884 } 608 }
885 609
886 } else if (report_duplicate_initialization) { 610 } else if (report_duplicate_initialization) {
887 mutex->Unlock(); // MutexLocker destructor not called when throwing. 611 mutex_->Unlock(); // MutexLocker destructor not called when throwing.
888 // Like ThrowPRException, without adding an OSError. 612 // Like ThrowPRException, without adding an OSError.
889 Dart_ThrowException(DartUtils::NewDartIOException("TlsException", 613 Dart_ThrowException(DartUtils::NewDartIOException("TlsException",
890 "Called SecureSocket.initialize more than once", 614 "Called SecureSocket.initialize more than once",
891 Dart_Null())); 615 Dart_Null()));
892 } 616 }
893 } 617 }
894 618
895 619
896 SECStatus BadCertificateCallback(void* filter, PRFileDesc* fd) { 620 SECStatus BadCertificateCallback(void* filter, PRFileDesc* fd) {
897 SSLFilter* ssl_filter = static_cast<SSLFilter*>(filter); 621 SSLFilter* ssl_filter = static_cast<SSLFilter*>(filter);
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after
952 // Look up certificate using the distinguished name (DN) certificate_name. 676 // Look up certificate using the distinguished name (DN) certificate_name.
953 CERTCertDBHandle* certificate_database = CERT_GetDefaultCertDB(); 677 CERTCertDBHandle* certificate_database = CERT_GetDefaultCertDB();
954 if (certificate_database == NULL) { 678 if (certificate_database == NULL) {
955 ThrowPRException("CertificateException", 679 ThrowPRException("CertificateException",
956 "Certificate database cannot be loaded"); 680 "Certificate database cannot be loaded");
957 } 681 }
958 certificate = CERT_FindCertByNameString(certificate_database, 682 certificate = CERT_FindCertByNameString(certificate_database,
959 const_cast<char*>(certificate_name)); 683 const_cast<char*>(certificate_name));
960 if (certificate == NULL) { 684 if (certificate == NULL) {
961 ThrowCertificateException( 685 ThrowCertificateException(
962 "Cannot find server certificate with distinguished name %s", 686 "Cannot find server certificate by distinguished name: %s",
963 certificate_name); 687 certificate_name);
964 } 688 }
965 } else { 689 } else {
966 // Look up certificate using the nickname certificate_name. 690 // Look up certificate using the nickname certificate_name.
967 certificate = PK11_FindCertFromNickname( 691 certificate = PK11_FindCertFromNickname(
968 const_cast<char*>(certificate_name), GetPassword()); 692 const_cast<char*>(certificate_name),
693 static_cast<void*>(const_cast<char*>(password_)));
969 if (certificate == NULL) { 694 if (certificate == NULL) {
970 ThrowCertificateException( 695 ThrowCertificateException(
971 "Cannot find server certificate with nickname %s", 696 "Cannot find server certificate by nickname: %s",
972 certificate_name); 697 certificate_name);
973 } 698 }
974 } 699 }
975 SECKEYPrivateKey* key = PK11_FindKeyByAnyCert(certificate, GetPassword()); 700 SECKEYPrivateKey* key = PK11_FindKeyByAnyCert(
701 certificate,
702 static_cast<void*>(const_cast<char*>(password_)));
976 if (key == NULL) { 703 if (key == NULL) {
977 CERT_DestroyCertificate(certificate); 704 CERT_DestroyCertificate(certificate);
978 if (PR_GetError() == -8177) { 705 if (PR_GetError() == -8177) {
979 ThrowPRException("CertificateException", 706 ThrowPRException("CertificateException",
980 "Certificate database password incorrect"); 707 "Certificate database password incorrect");
981 } else { 708 } else {
982 ThrowCertificateException( 709 ThrowCertificateException(
983 "Cannot find private key for certificate %s", 710 "Cannot find private key for certificate %s",
984 certificate_name); 711 certificate_name);
985 } 712 }
(...skipping 263 matching lines...) Expand 10 before | Expand all | Expand 10 after
1249 if (service_port != ILLEGAL_PORT) { 976 if (service_port != ILLEGAL_PORT) {
1250 // Return a send port for the service port. 977 // Return a send port for the service port.
1251 Dart_Handle send_port = Dart_NewSendPort(service_port); 978 Dart_Handle send_port = Dart_NewSendPort(service_port);
1252 Dart_SetReturnValue(args, send_port); 979 Dart_SetReturnValue(args, send_port);
1253 } 980 }
1254 } 981 }
1255 982
1256 983
1257 } // namespace bin 984 } // namespace bin
1258 } // namespace dart 985 } // namespace dart
OLDNEW
« no previous file with comments | « runtime/bin/secure_socket.h ('k') | runtime/bin/secure_socket_patch.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698