Chromium Code Reviews| OLD | NEW |
|---|---|
| 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> |
| (...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 66 SetFilter(args, filter); | 66 SetFilter(args, filter); |
| 67 filter->Init(dart_this); | 67 filter->Init(dart_this); |
| 68 Dart_ExitScope(); | 68 Dart_ExitScope(); |
| 69 } | 69 } |
| 70 | 70 |
| 71 | 71 |
| 72 void FUNCTION_NAME(SecureSocket_Connect)(Dart_NativeArguments args) { | 72 void FUNCTION_NAME(SecureSocket_Connect)(Dart_NativeArguments args) { |
| 73 Dart_EnterScope(); | 73 Dart_EnterScope(); |
| 74 Dart_Handle host_name_object = ThrowIfError(Dart_GetNativeArgument(args, 1)); | 74 Dart_Handle host_name_object = ThrowIfError(Dart_GetNativeArgument(args, 1)); |
| 75 Dart_Handle port_object = ThrowIfError(Dart_GetNativeArgument(args, 2)); | 75 Dart_Handle port_object = ThrowIfError(Dart_GetNativeArgument(args, 2)); |
| 76 Dart_Handle is_server_object = ThrowIfError(Dart_GetNativeArgument(args, 3)); | 76 bool is_server = DartUtils::GetBooleanValue(Dart_GetNativeArgument(args, 3)); |
| 77 Dart_Handle certificate_name_object = | 77 Dart_Handle certificate_name_object = |
| 78 ThrowIfError(Dart_GetNativeArgument(args, 4)); | 78 ThrowIfError(Dart_GetNativeArgument(args, 4)); |
| 79 bool request_client_certificate = | |
| 80 DartUtils::GetBooleanValue(Dart_GetNativeArgument(args, 5)); | |
| 81 bool require_client_certificate = | |
| 82 DartUtils::GetBooleanValue(Dart_GetNativeArgument(args, 6)); | |
| 83 bool send_client_certificate = | |
| 84 DartUtils::GetBooleanValue(Dart_GetNativeArgument(args, 7)); | |
| 79 | 85 |
| 80 const char* host_name = NULL; | 86 const char* host_name = NULL; |
| 81 // TODO(whesse): Is truncating a Dart string containing \0 what we want? | 87 // TODO(whesse): Is truncating a Dart string containing \0 what we want? |
| 82 ThrowIfError(Dart_StringToCString(host_name_object, &host_name)); | 88 ThrowIfError(Dart_StringToCString(host_name_object, &host_name)); |
| 83 | 89 |
| 84 int64_t port; | 90 int64_t port; |
| 85 if (!DartUtils::GetInt64Value(port_object, &port) || | 91 if (!DartUtils::GetInt64Value(port_object, &port)) { |
| 86 port < 0 || port > 65535) { | 92 ASSERT(false); |
|
Mads Ager (google)
2012/12/11 07:45:27
Can we use FATAL here with a string explaining wha
Bill Hesse
2012/12/11 09:20:54
Done.
| |
| 87 Dart_ThrowException(DartUtils::NewDartArgumentError( | |
| 88 "Illegal port parameter in _SSLFilter.connect")); | |
| 89 } | 93 } |
| 90 | 94 |
| 91 if (!Dart_IsBoolean(is_server_object)) { | |
| 92 Dart_ThrowException(DartUtils::NewDartArgumentError( | |
| 93 "Illegal is_server parameter in _SSLFilter.connect")); | |
| 94 } | |
| 95 bool is_server = DartUtils::GetBooleanValue(is_server_object); | |
| 96 | |
| 97 const char* certificate_name = NULL; | 95 const char* certificate_name = NULL; |
| 98 // If this is a server connection, get the certificate to connect with. | 96 if (Dart_IsString(certificate_name_object)) { |
| 99 // TODO(whesse): Use this parameter for a client certificate as well. | |
| 100 if (is_server) { | |
| 101 if (!Dart_IsString(certificate_name_object)) { | |
| 102 Dart_ThrowException(DartUtils::NewDartArgumentError( | |
| 103 "Non-String certificate parameter in _SSLFilter.connect")); | |
| 104 } | |
| 105 ThrowIfError(Dart_StringToCString(certificate_name_object, | 97 ThrowIfError(Dart_StringToCString(certificate_name_object, |
| 106 &certificate_name)); | 98 &certificate_name)); |
| 107 } | 99 } |
| 100 // If this is a server connection, it must have a certificate to connect with. | |
| 101 ASSERT(!is_server || certificate_name != NULL); | |
| 108 | 102 |
| 109 GetFilter(args)->Connect(host_name, | 103 GetFilter(args)->Connect(host_name, |
| 110 static_cast<int>(port), | 104 static_cast<int>(port), |
| 111 is_server, | 105 is_server, |
| 112 certificate_name); | 106 certificate_name, |
| 107 request_client_certificate, | |
| 108 require_client_certificate, | |
| 109 send_client_certificate); | |
| 113 Dart_ExitScope(); | 110 Dart_ExitScope(); |
| 114 } | 111 } |
| 115 | 112 |
| 116 | 113 |
| 117 void FUNCTION_NAME(SecureSocket_Destroy)(Dart_NativeArguments args) { | 114 void FUNCTION_NAME(SecureSocket_Destroy)(Dart_NativeArguments args) { |
| 118 Dart_EnterScope(); | 115 Dart_EnterScope(); |
| 119 SSLFilter* filter = GetFilter(args); | 116 SSLFilter* filter = GetFilter(args); |
| 120 SetFilter(args, NULL); | 117 SetFilter(args, NULL); |
| 121 filter->Destroy(); | 118 filter->Destroy(); |
| 122 delete filter; | 119 delete filter; |
| (...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 214 } else { | 211 } else { |
| 215 Dart_ThrowException(DartUtils::NewDartArgumentError( | 212 Dart_ThrowException(DartUtils::NewDartArgumentError( |
| 216 "UseBuiltinRoots argument to SetCertificateDatabase is not a bool")); | 213 "UseBuiltinRoots argument to SetCertificateDatabase is not a bool")); |
| 217 } | 214 } |
| 218 | 215 |
| 219 SSLFilter::InitializeLibrary(certificate_database, password, builtin_roots); | 216 SSLFilter::InitializeLibrary(certificate_database, password, builtin_roots); |
| 220 Dart_ExitScope(); | 217 Dart_ExitScope(); |
| 221 } | 218 } |
| 222 | 219 |
| 223 | 220 |
| 224 static bool CallBadCertificateCallback(Dart_Handle callback, | 221 void FUNCTION_NAME(SecureSocket_PeerCertificate) |
| 225 const char* subject_name, | 222 (Dart_NativeArguments args) { |
| 226 const char* issuer_name, | |
| 227 int64_t start_validity, | |
| 228 int64_t end_validity) { | |
| 229 if (callback == NULL || Dart_IsNull(callback)) return false; | |
| 230 Dart_EnterScope(); | 223 Dart_EnterScope(); |
| 231 Dart_Handle subject_name_object = DartUtils::NewString(subject_name); | 224 Dart_SetReturnValue(args, GetFilter(args)->PeerCertificate()); |
| 232 Dart_Handle issuer_name_object = DartUtils::NewString(issuer_name); | 225 Dart_ExitScope(); |
| 233 Dart_Handle start_validity_int = Dart_NewInteger(start_validity); | 226 } |
| 234 Dart_Handle end_validity_int = Dart_NewInteger(end_validity); | 227 |
| 228 | |
| 229 static Dart_Handle X509FromCertificate(CERTCertificate* certificate) { | |
| 230 PRTime start_validity; | |
| 231 PRTime end_validity; | |
| 232 SECStatus status = | |
| 233 CERT_GetCertTimes(certificate, &start_validity, &end_validity); | |
| 234 if (status != SECSuccess) { | |
| 235 ThrowPRException("Cannot get validity times from certificate"); | |
| 236 } | |
| 237 int64_t start_epoch_ms = start_validity / PR_USEC_PER_MSEC; | |
| 238 int64_t end_epoch_ms = end_validity / PR_USEC_PER_MSEC; | |
| 239 Dart_Handle subject_name_object = | |
| 240 DartUtils::NewString(certificate->subjectName); | |
| 241 Dart_Handle issuer_name_object = | |
| 242 DartUtils::NewString(certificate->issuerName); | |
| 243 Dart_Handle start_epoch_ms_int = Dart_NewInteger(start_epoch_ms); | |
| 244 Dart_Handle end_epoch_ms_int = Dart_NewInteger(end_epoch_ms); | |
| 235 | 245 |
| 236 Dart_Handle date_class = | 246 Dart_Handle date_class = |
| 237 DartUtils::GetDartClass(DartUtils::kCoreLibURL, "Date"); | 247 DartUtils::GetDartClass(DartUtils::kCoreLibURL, "Date"); |
| 238 Dart_Handle from_milliseconds = | 248 Dart_Handle from_milliseconds = |
| 239 DartUtils::NewString("fromMillisecondsSinceEpoch"); | 249 DartUtils::NewString("fromMillisecondsSinceEpoch"); |
| 240 | 250 |
| 241 Dart_Handle start_validity_date = | 251 Dart_Handle start_validity_date = |
| 242 Dart_New(date_class, from_milliseconds, 1, &start_validity_int); | 252 Dart_New(date_class, from_milliseconds, 1, &start_epoch_ms_int); |
| 243 Dart_Handle end_validity_date = | 253 Dart_Handle end_validity_date = |
| 244 Dart_New(date_class, from_milliseconds, 1, &end_validity_int); | 254 Dart_New(date_class, from_milliseconds, 1, &end_epoch_ms_int); |
| 245 | 255 |
| 246 Dart_Handle x509_class = | 256 Dart_Handle x509_class = |
| 247 DartUtils::GetDartClass(DartUtils::kIOLibURL, "X509Certificate"); | 257 DartUtils::GetDartClass(DartUtils::kIOLibURL, "X509Certificate"); |
| 248 Dart_Handle arguments[] = { subject_name_object, | 258 Dart_Handle arguments[] = { subject_name_object, |
| 249 issuer_name_object, | 259 issuer_name_object, |
| 250 start_validity_date, | 260 start_validity_date, |
| 251 end_validity_date }; | 261 end_validity_date }; |
| 252 Dart_Handle certificate = Dart_New(x509_class, Dart_Null(), 4, arguments); | 262 return Dart_New(x509_class, Dart_Null(), 4, arguments); |
| 253 | |
| 254 Dart_Handle result = | |
| 255 ThrowIfError(Dart_InvokeClosure(callback, 1, &certificate)); | |
| 256 bool c_result = Dart_IsBoolean(result) && DartUtils::GetBooleanValue(result); | |
| 257 Dart_ExitScope(); | |
| 258 return c_result; | |
| 259 } | 263 } |
| 260 | 264 |
| 261 | 265 |
| 262 void SSLFilter::Init(Dart_Handle dart_this) { | 266 void SSLFilter::Init(Dart_Handle dart_this) { |
| 263 string_start_ = ThrowIfError( | 267 string_start_ = ThrowIfError( |
| 264 Dart_NewPersistentHandle(DartUtils::NewString("start"))); | 268 Dart_NewPersistentHandle(DartUtils::NewString("start"))); |
| 265 string_length_ = ThrowIfError( | 269 string_length_ = ThrowIfError( |
| 266 Dart_NewPersistentHandle(DartUtils::NewString("length"))); | 270 Dart_NewPersistentHandle(DartUtils::NewString("length"))); |
| 267 | 271 |
| 268 InitializeBuffers(dart_this); | 272 InitializeBuffers(dart_this); |
| (...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 334 } | 338 } |
| 335 if (!use_builtin_root_certificates) { | 339 if (!use_builtin_root_certificates) { |
| 336 init_flags |= NSS_INIT_NOMODDB; | 340 init_flags |= NSS_INIT_NOMODDB; |
| 337 } | 341 } |
| 338 SECStatus status = NSS_Initialize(certificate_database, | 342 SECStatus status = NSS_Initialize(certificate_database, |
| 339 "", | 343 "", |
| 340 "", | 344 "", |
| 341 SECMOD_DB, | 345 SECMOD_DB, |
| 342 init_flags); | 346 init_flags); |
| 343 if (status != SECSuccess) { | 347 if (status != SECSuccess) { |
| 344 ThrowPRException("Unsuccessful NSS_Init call."); | 348 ThrowPRException("Failed NSS_Init call."); |
| 345 } | 349 } |
| 346 | 350 |
| 347 status = NSS_SetDomesticPolicy(); | 351 status = NSS_SetDomesticPolicy(); |
| 348 if (status != SECSuccess) { | 352 if (status != SECSuccess) { |
| 349 ThrowPRException("Unsuccessful NSS_SetDomesticPolicy call."); | 353 ThrowPRException("Failed NSS_SetDomesticPolicy call."); |
| 350 } | 354 } |
| 351 // Enable TLS, as well as SSL3 and SSL2. | 355 // Enable TLS, as well as SSL3 and SSL2. |
| 352 status = SSL_OptionSetDefault(SSL_ENABLE_TLS, PR_TRUE); | 356 status = SSL_OptionSetDefault(SSL_ENABLE_TLS, PR_TRUE); |
| 353 if (status != SECSuccess) { | 357 if (status != SECSuccess) { |
| 354 ThrowPRException("Unsuccessful SSL_OptionSetDefault enable TLS call."); | 358 ThrowPRException("Failed SSL_OptionSetDefault enable TLS call."); |
| 355 } | 359 } |
| 356 status = SSL_ConfigServerSessionIDCache(0, 0, 0, NULL); | 360 status = SSL_ConfigServerSessionIDCache(0, 0, 0, NULL); |
| 357 if (status != SECSuccess) { | 361 if (status != SECSuccess) { |
| 358 ThrowPRException("Unsuccessful SSL_ConfigServerSessionIDCache call."); | 362 ThrowPRException("Failed SSL_ConfigServerSessionIDCache call."); |
| 359 } | 363 } |
| 360 | 364 |
| 361 } else { | 365 } else { |
| 362 ThrowException("Called SSLFilter::InitializeLibrary more than once"); | 366 ThrowException("Called SSLFilter::InitializeLibrary more than once"); |
| 363 } | 367 } |
| 364 } | 368 } |
| 365 | 369 |
| 366 | 370 |
| 367 char* PasswordCallback(PK11SlotInfo* slot, PRBool retry, void* arg) { | 371 char* PasswordCallback(PK11SlotInfo* slot, PRBool retry, void* arg) { |
| 368 if (!retry) { | 372 if (!retry) { |
| 369 return PL_strdup(static_cast<char*>(arg)); // Freed by NSS internals. | 373 return PL_strdup(static_cast<char*>(arg)); // Freed by NSS internals. |
| 370 } | 374 } |
| 371 return NULL; | 375 return NULL; |
| 372 } | 376 } |
| 373 | 377 |
| 374 | 378 |
| 375 SECStatus BadCertificateCallback(void* filter, PRFileDesc* fd) { | 379 SECStatus BadCertificateCallback(void* filter, PRFileDesc* fd) { |
| 376 return static_cast<SSLFilter*>(filter)->HandleBadCertificate(fd); | 380 SSLFilter* ssl_filter = static_cast<SSLFilter*>(filter); |
| 381 Dart_Handle callback = ssl_filter->bad_certificate_callback(); | |
| 382 if (callback == NULL || Dart_IsNull(callback)) return SECFailure; | |
| 383 | |
| 384 Dart_EnterScope(); | |
| 385 Dart_Handle x509_object = ssl_filter->PeerCertificate(); | |
| 386 Dart_Handle result = | |
| 387 ThrowIfError(Dart_InvokeClosure(callback, 1, &x509_object)); | |
| 388 bool c_result = Dart_IsBoolean(result) && DartUtils::GetBooleanValue(result); | |
| 389 Dart_ExitScope(); | |
| 390 return c_result ? SECSuccess : SECFailure; | |
| 377 } | 391 } |
| 378 | 392 |
| 379 | 393 |
| 380 SECStatus SSLFilter::HandleBadCertificate(PRFileDesc* fd) { | 394 Dart_Handle SSLFilter::PeerCertificate() { |
| 381 ASSERT(fd == filter_); | 395 CERTCertificate* certificate = SSL_PeerCertificate(filter_); |
| 382 CERTCertificate* certificate = SSL_PeerCertificate(fd); | 396 if (certificate == NULL) return Dart_Null(); |
| 383 PRTime start_validity; | 397 Dart_Handle x509_object = X509FromCertificate(certificate); |
| 384 PRTime end_validity; | |
| 385 SECStatus status = | |
| 386 CERT_GetCertTimes(certificate, &start_validity, &end_validity); | |
| 387 if (status != SECSuccess) { | |
| 388 ThrowPRException("Cannot get validity times from certificate"); | |
| 389 } | |
| 390 int64_t start_epoch_ms = start_validity / PR_USEC_PER_MSEC; | |
| 391 int64_t end_epoch_ms = end_validity / PR_USEC_PER_MSEC; | |
| 392 bool accept = CallBadCertificateCallback(bad_certificate_callback_, | |
| 393 certificate->subjectName, | |
| 394 certificate->issuerName, | |
| 395 start_epoch_ms, | |
| 396 end_epoch_ms); | |
| 397 CERT_DestroyCertificate(certificate); | 398 CERT_DestroyCertificate(certificate); |
| 398 return accept ? SECSuccess : SECFailure; | 399 return x509_object; |
| 399 } | 400 } |
| 400 | 401 |
| 401 | 402 |
| 402 void SSLFilter::Connect(const char* host_name, | 403 void SSLFilter::Connect(const char* host_name, |
| 403 int port, | 404 int port, |
| 404 bool is_server, | 405 bool is_server, |
| 405 const char* certificate_name) { | 406 const char* certificate_name, |
| 407 bool request_client_certificate, | |
| 408 bool require_client_certificate, | |
| 409 bool send_client_certificate) { | |
| 406 is_server_ = is_server; | 410 is_server_ = is_server; |
| 407 if (in_handshake_) { | 411 if (in_handshake_) { |
| 408 ThrowException("Connect called while already in handshake state."); | 412 ThrowException("Connect called while already in handshake state."); |
| 409 } | 413 } |
| 410 | 414 |
| 411 filter_ = SSL_ImportFD(NULL, filter_); | 415 filter_ = SSL_ImportFD(NULL, filter_); |
| 412 if (filter_ == NULL) { | 416 if (filter_ == NULL) { |
| 413 ThrowPRException("Unsuccessful SSL_ImportFD call"); | 417 ThrowPRException("Failed SSL_ImportFD call"); |
| 414 } | 418 } |
| 415 | 419 |
| 416 SECStatus status; | 420 SECStatus status; |
| 417 if (is_server) { | 421 if (is_server) { |
| 418 PK11_SetPasswordFunc(PasswordCallback); | 422 PK11_SetPasswordFunc(PasswordCallback); |
| 419 CERTCertDBHandle* certificate_database = CERT_GetDefaultCertDB(); | 423 CERTCertDBHandle* certificate_database = CERT_GetDefaultCertDB(); |
| 420 if (certificate_database == NULL) { | 424 if (certificate_database == NULL) { |
| 421 ThrowPRException("Certificate database cannot be loaded"); | 425 ThrowPRException("Certificate database cannot be loaded"); |
| 422 } | 426 } |
| 427 // TODO(whesse): Switch to a function that looks up certs by nickname, | |
| 428 // so that server and client uses of certificateName agree. | |
| 423 CERTCertificate* certificate = CERT_FindCertByNameString( | 429 CERTCertificate* certificate = CERT_FindCertByNameString( |
| 424 certificate_database, | 430 certificate_database, |
| 425 const_cast<char*>(certificate_name)); | 431 const_cast<char*>(certificate_name)); |
| 426 if (certificate == NULL) { | 432 if (certificate == NULL) { |
| 427 ThrowPRException("Cannot find server certificate by name"); | 433 ThrowPRException("Cannot find server certificate by name"); |
| 428 } | 434 } |
| 429 SECKEYPrivateKey* key = PK11_FindKeyByAnyCert( | 435 SECKEYPrivateKey* key = PK11_FindKeyByAnyCert( |
| 430 certificate, | 436 certificate, |
| 431 static_cast<void*>(const_cast<char*>(password_))); | 437 static_cast<void*>(const_cast<char*>(password_))); |
| 432 if (key == NULL) { | 438 if (key == NULL) { |
| 433 CERT_DestroyCertificate(certificate); | 439 CERT_DestroyCertificate(certificate); |
| 434 if (PR_GetError() == -8177) { | 440 if (PR_GetError() == -8177) { |
| 435 ThrowPRException("Certificate database password incorrect"); | 441 ThrowPRException("Certificate database password incorrect"); |
| 436 } else { | 442 } else { |
| 437 ThrowPRException("Unsuccessful PK11_FindKeyByAnyCert call." | 443 ThrowPRException("Failed PK11_FindKeyByAnyCert call." |
| 438 " Cannot find private key for certificate"); | 444 " Cannot find private key for certificate"); |
| 439 } | 445 } |
| 440 } | 446 } |
| 441 // kt_rsa (key type RSA) is an enum constant from the NSS libraries. | 447 // kt_rsa (key type RSA) is an enum constant from the NSS libraries. |
| 442 // TODO(whesse): Allow different key types. | 448 // TODO(whesse): Allow different key types. |
| 443 status = SSL_ConfigSecureServer(filter_, certificate, key, kt_rsa); | 449 status = SSL_ConfigSecureServer(filter_, certificate, key, kt_rsa); |
| 444 CERT_DestroyCertificate(certificate); | 450 CERT_DestroyCertificate(certificate); |
| 445 SECKEY_DestroyPrivateKey(key); | 451 SECKEY_DestroyPrivateKey(key); |
| 446 if (status != SECSuccess) { | 452 if (status != SECSuccess) { |
| 447 ThrowPRException("Unsuccessful SSL_ConfigSecureServer call"); | 453 ThrowPRException("Failed SSL_ConfigSecureServer call"); |
| 454 } | |
| 455 | |
| 456 if (request_client_certificate) { | |
| 457 status = SSL_OptionSet(filter_, SSL_REQUEST_CERTIFICATE, PR_TRUE); | |
| 458 if (status != SECSuccess) { | |
| 459 ThrowPRException("Failed SSL_OptionSet(REQUEST_CERTIFICATE) call"); | |
| 460 } | |
| 461 PRBool require_cert = require_client_certificate ? PR_TRUE : PR_FALSE; | |
| 462 status = SSL_OptionSet(filter_, SSL_REQUIRE_CERTIFICATE, require_cert); | |
| 463 if (status != SECSuccess) { | |
| 464 ThrowPRException("Failed SSL_OptionSet(REQUIRE_CERTIFICATE) call"); | |
| 465 } | |
| 448 } | 466 } |
| 449 } else { // Client. | 467 } else { // Client. |
| 450 if (SSL_SetURL(filter_, host_name) == -1) { | 468 if (SSL_SetURL(filter_, host_name) == -1) { |
| 451 ThrowPRException("Unsuccessful SetURL call"); | 469 ThrowPRException("Failed SetURL call"); |
| 452 } | 470 } |
| 453 | 471 |
| 454 // This disables the SSL session cache for client connections. | 472 // This disables the SSL session cache for client connections. |
| 455 // This resolves issue 7208, but degrades performance. | 473 // This resolves issue 7208, but degrades performance. |
| 456 // TODO(7230): Reenable session cache, without breaking client connections. | 474 // TODO(7230): Reenable session cache, without breaking client connections. |
| 457 status = SSL_OptionSet(filter_, SSL_NO_CACHE, PR_TRUE); | 475 status = SSL_OptionSet(filter_, SSL_NO_CACHE, PR_TRUE); |
| 458 if (status != SECSuccess) { | 476 if (status != SECSuccess) { |
| 459 ThrowPRException("Failed SSL_OptionSet(NO_CACHE) call"); | 477 ThrowPRException("Failed SSL_OptionSet(NO_CACHE) call"); |
| 460 } | 478 } |
| 479 | |
| 480 if (send_client_certificate) { | |
| 481 status = SSL_GetClientAuthDataHook( | |
| 482 filter_, | |
| 483 NSS_GetClientAuthData, | |
| 484 static_cast<void*>(const_cast<char*>(certificate_name))); | |
| 485 if (status != SECSuccess) { | |
| 486 ThrowPRException("Failed SSL_GetClientAuthDataHook call"); | |
| 487 } | |
| 488 } | |
| 461 } | 489 } |
| 462 | 490 |
| 463 // Install bad certificate callback, and pass 'this' to it if it is called. | 491 // Install bad certificate callback, and pass 'this' to it if it is called. |
| 464 status = SSL_BadCertHook(filter_, | 492 status = SSL_BadCertHook(filter_, |
| 465 BadCertificateCallback, | 493 BadCertificateCallback, |
| 466 static_cast<void*>(this)); | 494 static_cast<void*>(this)); |
| 467 | 495 |
| 468 PRBool as_server = is_server ? PR_TRUE : PR_FALSE; | 496 PRBool as_server = is_server ? PR_TRUE : PR_FALSE; |
| 469 status = SSL_ResetHandshake(filter_, as_server); | 497 status = SSL_ResetHandshake(filter_, as_server); |
| 470 if (status != SECSuccess) { | 498 if (status != SECSuccess) { |
| 471 ThrowPRException("Unsuccessful SSL_ResetHandshake call"); | 499 ThrowPRException("Failed SSL_ResetHandshake call"); |
| 472 } | 500 } |
| 473 | 501 |
| 474 // SetPeerAddress | 502 // SetPeerAddress |
| 475 PRNetAddr host_address; | 503 PRNetAddr host_address; |
| 476 char host_entry_buffer[PR_NETDB_BUF_SIZE]; | 504 char host_entry_buffer[PR_NETDB_BUF_SIZE]; |
| 477 PRHostEnt host_entry; | 505 PRHostEnt host_entry; |
| 478 PRStatus rv = PR_GetHostByName(host_name, host_entry_buffer, | 506 PRStatus rv = PR_GetHostByName(host_name, host_entry_buffer, |
| 479 PR_NETDB_BUF_SIZE, &host_entry); | 507 PR_NETDB_BUF_SIZE, &host_entry); |
| 480 if (rv != PR_SUCCESS) { | 508 if (rv != PR_SUCCESS) { |
| 481 ThrowPRException("Unsuccessful PR_GetHostByName call"); | 509 ThrowPRException("Failed PR_GetHostByName call"); |
| 482 } | 510 } |
| 483 | 511 |
| 484 int index = PR_EnumerateHostEnt(0, &host_entry, port, &host_address); | 512 int index = PR_EnumerateHostEnt(0, &host_entry, port, &host_address); |
| 485 if (index == -1 || index == 0) { | 513 if (index == -1 || index == 0) { |
| 486 ThrowPRException("Unsuccessful PR_EnumerateHostEnt call"); | 514 ThrowPRException("Failed PR_EnumerateHostEnt call"); |
| 487 } | 515 } |
| 488 memio_SetPeerName(filter_, &host_address); | 516 memio_SetPeerName(filter_, &host_address); |
| 489 } | 517 } |
| 490 | 518 |
| 491 | 519 |
| 492 void SSLFilter::Handshake() { | 520 void SSLFilter::Handshake() { |
| 493 SECStatus status = SSL_ForceHandshake(filter_); | 521 SECStatus status = SSL_ForceHandshake(filter_); |
| 494 if (status == SECSuccess) { | 522 if (status == SECSuccess) { |
| 495 if (in_handshake_) { | 523 if (in_handshake_) { |
| 496 ThrowIfError(Dart_InvokeClosure(handshake_complete_, 0, NULL)); | 524 ThrowIfError(Dart_InvokeClosure(handshake_complete_, 0, NULL)); |
| (...skipping 123 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 620 if (PR_WOULD_BLOCK_ERROR != pr_error) { | 648 if (PR_WOULD_BLOCK_ERROR != pr_error) { |
| 621 ThrowPRException("Error reading plaintext from SSLFilter"); | 649 ThrowPRException("Error reading plaintext from SSLFilter"); |
| 622 } | 650 } |
| 623 bytes_processed = 0; | 651 bytes_processed = 0; |
| 624 } | 652 } |
| 625 break; | 653 break; |
| 626 } | 654 } |
| 627 } | 655 } |
| 628 return bytes_processed; | 656 return bytes_processed; |
| 629 } | 657 } |
| OLD | NEW |