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

Unified 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « runtime/bin/secure_socket.h ('k') | runtime/bin/secure_socket_patch.dart » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: runtime/bin/secure_socket.cc
diff --git a/runtime/bin/secure_socket.cc b/runtime/bin/secure_socket.cc
index 2bfa94fa0c728da6c1c9e63eca583cf092258c65..50382660853172b36605cc876bf6efc560764490 100644
--- a/runtime/bin/secure_socket.cc
+++ b/runtime/bin/secure_socket.cc
@@ -10,12 +10,9 @@
#include <stdio.h>
#include <string.h>
-#include <certdb.h>
#include <key.h>
#include <keyt.h>
#include <nss.h>
-#include <p12.h>
-#include <p12plcy.h>
#include <pk11pub.h>
#include <prerror.h>
#include <prinit.h>
@@ -40,10 +37,10 @@ namespace bin {
bool SSLFilter::library_initialized_ = false;
// To protect library initialization.
-dart::Mutex* SSLFilter::mutex = new dart::Mutex();
+dart::Mutex* SSLFilter::mutex_ = new dart::Mutex();
// The password is needed when creating secure server sockets. It can
// be null if only secure client sockets are used.
-char* SSLFilter::password_ = NULL;
+const char* SSLFilter::password_ = NULL;
// Forward declaration.
static void ProcessFilter(Dart_Port dest_port_id,
@@ -232,7 +229,7 @@ void FUNCTION_NAME(SecureSocket_InitializeLibrary)
&certificate_database));
} else if (!Dart_IsNull(certificate_database_object)) {
Dart_ThrowException(DartUtils::NewDartArgumentError(
- "SecureSocket.initialize: database argument is not a String or null"));
+ "Non-String certificate directory argument to SetCertificateDatabase"));
}
// Leave certificate_database as NULL if no value was provided.
@@ -247,7 +244,7 @@ void FUNCTION_NAME(SecureSocket_InitializeLibrary)
password = "";
} else {
Dart_ThrowException(DartUtils::NewDartArgumentError(
- "SecureSocket.initialize: password argument is not a String or null"));
+ "Password argument to SetCertificateDatabase is not a String or null"));
}
Dart_Handle builtin_roots_object =
@@ -258,322 +255,10 @@ void FUNCTION_NAME(SecureSocket_InitializeLibrary)
ThrowIfError(Dart_BooleanValue(builtin_roots_object, &builtin_roots));
} else {
Dart_ThrowException(DartUtils::NewDartArgumentError(
- "SecureSocket.initialize: useBuiltinRoots argument is not a bool"));
+ "UseBuiltinRoots argument to SetCertificateDatabase is not a bool"));
}
- Dart_Handle read_only_object =
- ThrowIfError(Dart_GetNativeArgument(args, 3));
- // Check that the type is boolean, and get the boolean value from it.
- bool read_only = true;
- if (Dart_IsBoolean(read_only_object)) {
- ThrowIfError(Dart_BooleanValue(read_only_object, &read_only));
- } else {
- Dart_ThrowException(DartUtils::NewDartArgumentError(
- "SecureSocket.initialize: readOnly argument is not a bool"));
- }
-
- SSLFilter::InitializeLibrary(
- certificate_database, password, builtin_roots, read_only);
-}
-
-
-static Dart_Handle X509FromCertificate(CERTCertificate* certificate) {
- PRTime start_validity;
- PRTime end_validity;
- SECStatus status =
- CERT_GetCertTimes(certificate, &start_validity, &end_validity);
- if (status != SECSuccess) {
- ThrowPRException("CertificateException",
- "Cannot get validity times from certificate");
- }
- int64_t start_epoch_ms = start_validity / PR_USEC_PER_MSEC;
- int64_t end_epoch_ms = end_validity / PR_USEC_PER_MSEC;
- Dart_Handle subject_name_object =
- DartUtils::NewString(certificate->subjectName);
- Dart_Handle issuer_name_object =
- DartUtils::NewString(certificate->issuerName);
- Dart_Handle start_epoch_ms_int = Dart_NewInteger(start_epoch_ms);
- Dart_Handle end_epoch_ms_int = Dart_NewInteger(end_epoch_ms);
-
- Dart_Handle date_type =
- DartUtils::GetDartType(DartUtils::kCoreLibURL, "DateTime");
- Dart_Handle from_milliseconds =
- DartUtils::NewString("fromMillisecondsSinceEpoch");
-
- Dart_Handle start_validity_date =
- Dart_New(date_type, from_milliseconds, 1, &start_epoch_ms_int);
- Dart_Handle end_validity_date =
- Dart_New(date_type, from_milliseconds, 1, &end_epoch_ms_int);
-
- Dart_Handle x509_type =
- DartUtils::GetDartType(DartUtils::kIOLibURL, "X509Certificate");
- Dart_Handle arguments[] = { subject_name_object,
- issuer_name_object,
- start_validity_date,
- end_validity_date };
- return Dart_New(x509_type, Dart_Null(), 4, arguments);
-}
-
-
-char* PasswordCallback(PK11SlotInfo* slot, PRBool retry, void* arg) {
- if (!retry) {
- return PL_strdup(static_cast<char*>(arg)); // Freed by NSS internals.
- }
- return NULL;
-}
-
-
-void FUNCTION_NAME(SecureSocket_AddCertificate)
- (Dart_NativeArguments args) {
- Dart_Handle certificate_object =
- ThrowIfError(Dart_GetNativeArgument(args, 0));
- Dart_Handle trust_object = ThrowIfError(Dart_GetNativeArgument(args, 1));
-
- if (!Dart_IsList(certificate_object) || !Dart_IsString(trust_object)) {
- Dart_ThrowException(DartUtils::NewDartArgumentError(
- "Bad argument to SecureSocket.addCertificate"));
- }
-
- intptr_t length;
- ThrowIfError(Dart_ListLength(certificate_object, &length));
- uint8_t* certificate = reinterpret_cast<uint8_t*>(malloc(length + 1));
- if (certificate == NULL) {
- FATAL("Out of memory in SecureSocket.addCertificate");
- }
- ThrowIfError(Dart_ListGetAsBytes(
- certificate_object, 0, certificate, length));
-
- const char* trust_string;
- ThrowIfError(Dart_StringToCString(trust_object,
- &trust_string));
-
- PK11SlotInfo* slot = PK11_GetInternalKeySlot();
- SECStatus status = PK11_Authenticate(slot, PR_TRUE, SSLFilter::GetPassword());
- PK11_FreeSlot(slot);
- if (status == SECFailure) {
- ThrowPRException("CertificateException",
- "Could not authenticate to certificate database");
- }
-
- CERTCertificate* cert = CERT_DecodeCertFromPackage(
- reinterpret_cast<char*>(certificate), length);
- if (cert == NULL) {
- ThrowPRException("CertificateException", "Certificate cannot be decoded");
- }
- CERTCertTrust trust;
- status = CERT_DecodeTrustString(&trust, trust_string);
- if (status != SECSuccess) {
- ThrowPRException("CertificateException", "Trust string cannot be decoded");
- }
- {
- MutexLocker locker(SSLFilter::mutex);
- status = CERT_ChangeCertTrust(CERT_GetDefaultCertDB(), cert, &trust);
- }
- if (status != SECSuccess) {
- ThrowPRException("CertificateException", "Cannot set trust attributes");
- }
-
- Dart_SetReturnValue(args, X509FromCertificate(cert));
- return;
-}
-
-
-/*
- * Called by the PKCS#12 decoder if a certificate's nickname collides with
- * the nickname of a different existing certificate in the database.
- */
-SECItem* nickname_callback(SECItem *old_nickname,
- PRBool *cancel,
- void *arg) {
- *cancel = PR_TRUE;
- return NULL;
-}
-
-
-void FUNCTION_NAME(SecureSocket_ImportCertificatesWithPrivateKeys)
- (Dart_NativeArguments args) {
- Dart_Handle pk12_object = ThrowIfError(Dart_GetNativeArgument(args, 0));
- if (!Dart_IsList(pk12_object)) {
- Dart_ThrowException(DartUtils::NewDartArgumentError(
- "SecureSocket.importPrivateCertificates: certificates is not a List"));
- }
-
- Dart_Handle password_object = ThrowIfError(Dart_GetNativeArgument(args, 1));
- if (!Dart_IsString(password_object)) {
- Dart_ThrowException(DartUtils::NewDartArgumentError(
- "SecureSocket.importPrivateCertificates: password is not a String"));
- }
-
- intptr_t length;
- ThrowIfError(Dart_ListLength(pk12_object, &length));
- uint8_t* pk12 = Dart_ScopeAllocate(length);
- if (pk12 == NULL) {
- FATAL("Out of memory in SecureSocket.importPrivateCertificates");
- }
- ThrowIfError(Dart_ListGetAsBytes(pk12_object, 0, pk12, length));
-
- // A big-endian Unicode (UTF16) password.
- intptr_t password_length;
- ThrowIfError(Dart_StringLength(password_object, &password_length));
- password_length++;
- uint16_t* password = reinterpret_cast<uint16_t*>(
- Dart_ScopeAllocate(sizeof(uint16_t) * password_length));
- if (password == NULL) {
- FATAL("Out of memory in SecureSocket.importPrivateCertificates");
- }
- intptr_t returned_length = password_length;
- ThrowIfError(Dart_StringToUTF16(password_object, password, &returned_length));
- ASSERT(password_length == returned_length + 1);
- password[password_length - 1] = 0;
- for (int i = 0; i < password_length; ++i) {
- password[i] = Utils::HostToBigEndian16(password[i]);
- }
- SECItem p12_password;
- p12_password.type = siBuffer;
- p12_password.data = reinterpret_cast<unsigned char*>(password);
- p12_password.len = sizeof(uint16_t) * password_length;
-
- Dart_SetReturnValue(args, Dart_Null());
- // Set the password callback for the certificate database we are importing to.
- // The password for a slot is gotten from a callback, and it is freed by the
- // caller of the callback. The argument to the callback comes from the wincx
- // argument to a PK11 function.
- PK11SlotInfo* slot = PK11_GetInternalKeySlot();
- SECStatus status = PK11_Authenticate(slot, PR_TRUE, SSLFilter::GetPassword());
- if (status == SECFailure) {
- PK11_FreeSlot(slot);
- ThrowPRException("CertificateException",
- "Could not authenticate to certificate database");
- }
-
- SEC_PKCS12DecoderContext* context = SEC_PKCS12DecoderStart(
- &p12_password,
- slot,
- SSLFilter::GetPassword(),
- NULL,
- NULL,
- NULL,
- NULL,
- NULL);
- PK11_FreeSlot(slot);
- if (!context) {
- FATAL("Unexpected error: SecureSocket.addPrivateCertificates DecoderStart");
- }
- bool success;
- {
- MutexLocker locker(SSLFilter::mutex);
- success =
- SECSuccess == SEC_PKCS12DecoderUpdate(context, pk12, length) &&
- SECSuccess == SEC_PKCS12DecoderVerify(context) &&
- SECSuccess == SEC_PKCS12DecoderValidateBags(context,
- nickname_callback) &&
- SECSuccess == SEC_PKCS12DecoderImportBags(context);
- }
- SEC_PKCS12DecoderFinish(context);
- if (!success) {
- ThrowPRException("CertificateException", "Could not import PKCS#12 file");
- }
-}
-
-
-void FUNCTION_NAME(SecureSocket_ChangeTrust)(Dart_NativeArguments args) {
- Dart_Handle nickname_object = ThrowIfError(Dart_GetNativeArgument(args, 0));
- if (!Dart_IsString(nickname_object)) {
- Dart_ThrowException(DartUtils::NewDartArgumentError(
- "SecureSocket.changeTrust: nickname argument is not a String"));
- }
- const char* nickname;
- ThrowIfError(Dart_StringToCString(nickname_object, &nickname));
-
- Dart_Handle trust_object = ThrowIfError(Dart_GetNativeArgument(args, 1));
- if (!Dart_IsString(trust_object)) {
- Dart_ThrowException(DartUtils::NewDartArgumentError(
- "SecureSocket.changeTrust: trust argument is not a String"));
- }
- const char* trust_string;
- ThrowIfError(Dart_StringToCString(trust_object, &trust_string));
-
- PK11SlotInfo* slot = PK11_GetInternalKeySlot();
- SECStatus status = PK11_Authenticate(slot, PR_TRUE, SSLFilter::GetPassword());
- if (status == SECFailure) {
- ThrowPRException("CertificateException",
- "Could not authenticate to certificate database");
- }
- PK11_FreeSlot(slot);
-
- CERTCertificate* certificate =
- PK11_FindCertFromNickname(nickname, SSLFilter::GetPassword());
- if (certificate == NULL) {
- ThrowCertificateException("Cannot find certificate with nickname %s",
- nickname);
- }
- CERTCertTrust trust;
- if (SECSuccess != CERT_DecodeTrustString(&trust, trust_string)) {
- CERT_DestroyCertificate(certificate);
- ThrowPRException("CertificateException", "Trust string cannot be decoded");
- }
- {
- MutexLocker locker(SSLFilter::mutex);
- status = CERT_ChangeCertTrust(CERT_GetDefaultCertDB(), certificate, &trust);
- }
- if (status != SECSuccess) {
- CERT_DestroyCertificate(certificate);
- ThrowCertificateException("Cannot set trust on certificate %s", nickname);
- }
- Dart_SetReturnValue(args, X509FromCertificate(certificate));
- CERT_DestroyCertificate(certificate);
-}
-
-
-void FUNCTION_NAME(SecureSocket_GetCertificate)(Dart_NativeArguments args) {
- Dart_Handle nickname_object = ThrowIfError(Dart_GetNativeArgument(args, 0));
- if (!Dart_IsString(nickname_object)) {
- Dart_ThrowException(DartUtils::NewDartArgumentError(
- "SecureSocket.getCertificate: nickname argument is not a String"));
- }
- const char* nickname;
- ThrowIfError(Dart_StringToCString(nickname_object, &nickname));
-
- CERTCertificate* certificate = PK11_FindCertFromNickname(
- nickname, SSLFilter::GetPassword());
- if (certificate != NULL) {
- Dart_SetReturnValue(args, X509FromCertificate(certificate));
- CERT_DestroyCertificate(certificate);
- }
-}
-
-
-void FUNCTION_NAME(SecureSocket_RemoveCertificate)(Dart_NativeArguments args) {
- Dart_Handle nickname_object =
- ThrowIfError(Dart_GetNativeArgument(args, 0));
- if (!Dart_IsString(nickname_object)) {
- Dart_ThrowException(DartUtils::NewDartArgumentError(
- "SecureSocket.removeCertificate: nickname is not a String"));
- }
- const char* nickname;
- ThrowIfError(Dart_StringToCString(nickname_object, &nickname));
-
- CERTCertificate* certificate =
- PK11_FindCertFromNickname(nickname, SSLFilter::GetPassword());
- if (certificate == NULL) {
- ThrowCertificateException("Cannot find certificate with nickname %s",
- nickname);
- }
- SECKEYPrivateKey* key =
- PK11_FindKeyByAnyCert(certificate, SSLFilter::GetPassword());
- // Free the copy returned from FindKeyByAnyCert.
- SECKEY_DestroyPrivateKey(key);
- SECStatus status;
- {
- MutexLocker locker(SSLFilter::mutex);
- status = (key == NULL) ?
- SEC_DeletePermCertificate(certificate) :
- PK11_DeleteTokenCertAndKey(certificate, SSLFilter::GetPassword());
- }
- CERT_DestroyCertificate(certificate);
- if (status != SECSuccess) {
- ThrowCertificateException("Cannot remove certificate %s", nickname);
- }
+ SSLFilter::InitializeLibrary(certificate_database, password, builtin_roots);
}
@@ -723,9 +408,47 @@ bool SSLFilter::ProcessAllBuffers(int starts[kNumBuffers],
}
+static Dart_Handle X509FromCertificate(CERTCertificate* certificate) {
+ PRTime start_validity;
+ PRTime end_validity;
+ SECStatus status =
+ CERT_GetCertTimes(certificate, &start_validity, &end_validity);
+ if (status != SECSuccess) {
+ ThrowPRException("CertificateException",
+ "Cannot get validity times from certificate");
+ }
+ int64_t start_epoch_ms = start_validity / PR_USEC_PER_MSEC;
+ int64_t end_epoch_ms = end_validity / PR_USEC_PER_MSEC;
+ Dart_Handle subject_name_object =
+ DartUtils::NewString(certificate->subjectName);
+ Dart_Handle issuer_name_object =
+ DartUtils::NewString(certificate->issuerName);
+ Dart_Handle start_epoch_ms_int = Dart_NewInteger(start_epoch_ms);
+ Dart_Handle end_epoch_ms_int = Dart_NewInteger(end_epoch_ms);
+
+ Dart_Handle date_type =
+ DartUtils::GetDartType(DartUtils::kCoreLibURL, "DateTime");
+ Dart_Handle from_milliseconds =
+ DartUtils::NewString("fromMillisecondsSinceEpoch");
+
+ Dart_Handle start_validity_date =
+ Dart_New(date_type, from_milliseconds, 1, &start_epoch_ms_int);
+ Dart_Handle end_validity_date =
+ Dart_New(date_type, from_milliseconds, 1, &end_epoch_ms_int);
+
+ Dart_Handle x509_type =
+ DartUtils::GetDartType(DartUtils::kIOLibURL, "X509Certificate");
+ Dart_Handle arguments[] = { subject_name_object,
+ issuer_name_object,
+ start_validity_date,
+ end_validity_date };
+ return Dart_New(x509_type, Dart_Null(), 4, arguments);
+}
+
+
void SSLFilter::Init(Dart_Handle dart_this) {
if (!library_initialized_) {
- InitializeLibrary(NULL, "", true, true, false);
+ InitializeLibrary(NULL, "", true, false);
}
ASSERT(string_start_ == NULL);
string_start_ = Dart_NewPersistentHandle(DartUtils::NewString("start"));
@@ -798,6 +521,14 @@ void SSLFilter::RegisterBadCertificateCallback(Dart_Handle callback) {
}
+char* PasswordCallback(PK11SlotInfo* slot, PRBool retry, void* arg) {
+ if (!retry) {
+ return PL_strdup(static_cast<char*>(arg)); // Freed by NSS internals.
+ }
+ return NULL;
+}
+
+
static const char* builtin_roots_module =
#if defined(TARGET_OS_LINUX) || defined(TARGET_OS_ANDROID)
"name=\"Root Certs\" library=\"libnssckbi.so\"";
@@ -814,9 +545,8 @@ static const char* builtin_roots_module =
void SSLFilter::InitializeLibrary(const char* certificate_database,
const char* password,
bool use_builtin_root_certificates,
- bool read_only,
bool report_duplicate_initialization) {
- MutexLocker locker(mutex);
+ MutexLocker locker(mutex_);
SECStatus status;
if (!library_initialized_) {
PR_Init(PR_USER_THREAD, PR_PRIORITY_NORMAL, 0);
@@ -824,7 +554,7 @@ void SSLFilter::InitializeLibrary(const char* certificate_database,
if (certificate_database == NULL || certificate_database[0] == '\0') {
status = NSS_NoDB_Init(NULL);
if (status != SECSuccess) {
- mutex->Unlock(); // MutexLocker destructor not called when throwing.
+ mutex_->Unlock(); // MutexLocker destructor not called when throwing.
ThrowPRException("TlsException",
"Failed NSS_NoDB_Init call.");
}
@@ -832,13 +562,13 @@ void SSLFilter::InitializeLibrary(const char* certificate_database,
SECMODModule* module = SECMOD_LoadUserModule(
const_cast<char*>(builtin_roots_module), NULL, PR_FALSE);
if (!module) {
- mutex->Unlock(); // MutexLocker destructor not called when throwing.
+ mutex_->Unlock(); // MutexLocker destructor not called when throwing.
ThrowPRException("TlsException",
"Failed to load builtin root certificates.");
}
}
} else {
- PRUint32 init_flags = read_only ? NSS_INIT_READONLY : 0;
+ PRUint32 init_flags = NSS_INIT_READONLY;
if (!use_builtin_root_certificates) {
init_flags |= NSS_INIT_NOMODDB;
}
@@ -848,7 +578,7 @@ void SSLFilter::InitializeLibrary(const char* certificate_database,
SECMOD_DB,
init_flags);
if (status != SECSuccess) {
- mutex->Unlock(); // MutexLocker destructor not called when throwing.
+ mutex_->Unlock(); // MutexLocker destructor not called when throwing.
ThrowPRException("TlsException",
"Failed NSS_Init call.");
}
@@ -857,34 +587,28 @@ void SSLFilter::InitializeLibrary(const char* certificate_database,
}
library_initialized_ = true;
- // Allow encoding and decoding of private keys in PKCS#12 files.
- SEC_PKCS12EnableCipher(PKCS12_RC2_CBC_40, 1);
- SEC_PKCS12EnableCipher(PKCS12_DES_EDE3_168, 1);
- SEC_PKCS12SetPreferredCipher(PKCS12_DES_EDE3_168, 1);
-
status = NSS_SetDomesticPolicy();
if (status != SECSuccess) {
- mutex->Unlock(); // MutexLocker destructor not called when throwing.
+ mutex_->Unlock(); // MutexLocker destructor not called when throwing.
ThrowPRException("TlsException",
"Failed NSS_SetDomesticPolicy call.");
}
-
// Enable TLS, as well as SSL3 and SSL2.
status = SSL_OptionSetDefault(SSL_ENABLE_TLS, PR_TRUE);
if (status != SECSuccess) {
- mutex->Unlock(); // MutexLocker destructor not called when throwing.
+ mutex_->Unlock(); // MutexLocker destructor not called when throwing.
ThrowPRException("TlsException",
"Failed SSL_OptionSetDefault enable TLS call.");
}
status = SSL_ConfigServerSessionIDCache(0, 0, 0, NULL);
if (status != SECSuccess) {
- mutex->Unlock(); // MutexLocker destructor not called when throwing.
+ mutex_->Unlock(); // MutexLocker destructor not called when throwing.
ThrowPRException("TlsException",
"Failed SSL_ConfigServerSessionIDCache call.");
}
} else if (report_duplicate_initialization) {
- mutex->Unlock(); // MutexLocker destructor not called when throwing.
+ mutex_->Unlock(); // MutexLocker destructor not called when throwing.
// Like ThrowPRException, without adding an OSError.
Dart_ThrowException(DartUtils::NewDartIOException("TlsException",
"Called SecureSocket.initialize more than once",
@@ -959,20 +683,23 @@ void SSLFilter::Connect(const char* host_name,
const_cast<char*>(certificate_name));
if (certificate == NULL) {
ThrowCertificateException(
- "Cannot find server certificate with distinguished name %s",
+ "Cannot find server certificate by distinguished name: %s",
certificate_name);
}
} else {
// Look up certificate using the nickname certificate_name.
certificate = PK11_FindCertFromNickname(
- const_cast<char*>(certificate_name), GetPassword());
+ const_cast<char*>(certificate_name),
+ static_cast<void*>(const_cast<char*>(password_)));
if (certificate == NULL) {
ThrowCertificateException(
- "Cannot find server certificate with nickname %s",
+ "Cannot find server certificate by nickname: %s",
certificate_name);
}
}
- SECKEYPrivateKey* key = PK11_FindKeyByAnyCert(certificate, GetPassword());
+ SECKEYPrivateKey* key = PK11_FindKeyByAnyCert(
+ certificate,
+ static_cast<void*>(const_cast<char*>(password_)));
if (key == NULL) {
CERT_DestroyCertificate(certificate);
if (PR_GetError() == -8177) {
« 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