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

Unified Diff: runtime/bin/secure_socket.cc

Issue 1665433002: Adds SecurityContext.setTrustedCertificatesBytes (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: Merge with CL adding setClientAuthoritiesBytes Created 4 years, 10 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/io_natives.cc ('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 7f62fcf6adf913c003a6e38ac0a1d95f94aeef7d..0397f728d5659b0ecd709780cf4eed703320cf8e 100644
--- a/runtime/bin/secure_socket.cc
+++ b/runtime/bin/secure_socket.cc
@@ -376,17 +376,62 @@ void CheckStatus(int status,
}
+static bool GetBIOArgument(Dart_Handle object, BIO** bio) {
Bill Hesse 2016/02/05 14:48:17 I would call this FillMemBIO. "Argument" doesn't
zra 2016/02/05 17:18:22 Replaced these functions with MemBIOScope
+ ASSERT(bio != NULL);
+ if (!Dart_IsTypedData(object) && !Dart_IsList(object)) {
+ Dart_ThrowException(DartUtils::NewDartArgumentError(
+ "Argument is not a List<int>"));
+ }
+
+ uint8_t* bytes = NULL;
+ intptr_t bytes_len = 0;
+ bool is_typed_data = false;
+ if (Dart_IsTypedData(object)) {
+ is_typed_data = true;
+ Dart_TypedData_Type typ;
+ ThrowIfError(Dart_TypedDataAcquireData(
+ object,
+ &typ,
+ reinterpret_cast<void**>(&bytes),
+ &bytes_len));
+ } else {
+ ASSERT(Dart_IsList(object));
+ ThrowIfError(Dart_ListLength(object, &bytes_len));
+ bytes = new uint8_t[bytes_len];
+ Dart_Handle err =
+ Dart_ListGetAsBytes(object, 0, bytes, bytes_len);
+ if (Dart_IsError(err)) {
+ delete[] bytes;
+ Dart_PropagateError(err);
+ }
+ }
+
+ *bio = BIO_new_mem_buf(bytes, bytes_len);
+ return is_typed_data;
+}
+
+
Bill Hesse 2016/02/05 14:48:17 This seems really fragile (the typed data release)
zra 2016/02/05 17:18:22 Acknowledged.
+static void FreeBIO(Dart_Handle object, BIO* bio, bool is_typed_data) {
+ if (is_typed_data) {
+ BIO_free(bio);
+ ThrowIfError(Dart_TypedDataReleaseData(object));
+ } else {
+ uint8_t* bytes;
+ uintptr_t bytes_len;
+ if (BIO_mem_contents(
+ bio, const_cast<const uint8_t**>(&bytes), &bytes_len) != 0) {
+ ASSERT(bytes != NULL);
+ delete[] bytes;
+ }
+ BIO_free(bio);
+ }
+}
+
+
void FUNCTION_NAME(SecurityContext_UsePrivateKeyBytes)(
Dart_NativeArguments args) {
SSL_CTX* context = GetSecurityContext(args);
- Dart_Handle key_object = ThrowIfError(Dart_GetNativeArgument(args, 1));
- if (!Dart_IsTypedData(key_object) && !Dart_IsList(key_object)) {
- Dart_ThrowException(DartUtils::NewDartArgumentError(
- "keyBytes argument to SecurityContext.usePrivateKeyBytes "
- "is not a List<int>"));
- }
-
Dart_Handle password_object = ThrowIfError(Dart_GetNativeArgument(args, 2));
const char* password = NULL;
if (Dart_IsString(password_object)) {
@@ -403,40 +448,16 @@ void FUNCTION_NAME(SecurityContext_UsePrivateKeyBytes)(
"SecurityContext.usePrivateKey password is not a String or null"));
}
- uint8_t* key_bytes = NULL;
- intptr_t key_bytes_len = 0;
- bool is_typed_data = false;
- if (Dart_IsTypedData(key_object)) {
- is_typed_data = true;
- Dart_TypedData_Type typ;
- ThrowIfError(Dart_TypedDataAcquireData(
- key_object,
- &typ,
- reinterpret_cast<void**>(&key_bytes),
- &key_bytes_len));
- } else {
- ASSERT(Dart_IsList(key_object));
- ThrowIfError(Dart_ListLength(key_object, &key_bytes_len));
- key_bytes = new uint8_t[key_bytes_len];
- Dart_Handle err =
- Dart_ListGetAsBytes(key_object, 0, key_bytes, key_bytes_len);
- if (Dart_IsError(err)) {
- delete[] key_bytes;
- Dart_PropagateError(err);
- }
- }
- ASSERT(key_bytes != NULL);
+ BIO* bio = NULL;
+ Dart_Handle key_object = ThrowIfError(Dart_GetNativeArgument(args, 1));
+ bool is_typed_data = GetBIOArgument(key_object, &bio);
+ ASSERT(bio != NULL);
- BIO* bio = BIO_new_mem_buf(key_bytes, key_bytes_len);
EVP_PKEY *key = PEM_read_bio_PrivateKey(
bio, NULL, PasswordCallback, const_cast<char*>(password));
int status = SSL_CTX_use_PrivateKey(context, key);
- BIO_free(bio);
- if (is_typed_data) {
- ThrowIfError(Dart_TypedDataReleaseData(key_object));
- } else {
- delete[] key_bytes;
- }
+
+ FreeBIO(key_object, bio, is_typed_data);
// TODO(24184): Handle different expected errors here - file missing,
// incorrect password, file not a PEM, and throw exceptions.
@@ -445,29 +466,48 @@ void FUNCTION_NAME(SecurityContext_UsePrivateKeyBytes)(
}
-void FUNCTION_NAME(SecurityContext_SetTrustedCertificates)(
- Dart_NativeArguments args) {
- SSL_CTX* context = GetSecurityContext(args);
- Dart_Handle filename_object = ThrowIfError(Dart_GetNativeArgument(args, 1));
- const char* filename = NULL;
- if (Dart_IsString(filename_object)) {
- ThrowIfError(Dart_StringToCString(filename_object, &filename));
+static int SetTrustedCertificatesBytes(SSL_CTX* context, BIO* bio) {
+ X509_STORE* store = SSL_CTX_get_cert_store(context);
+
+ int status = 0;
+ X509* cert = NULL;
+ while ((cert = PEM_read_bio_X509(bio, NULL, NULL, NULL)) != NULL) {
+ status = X509_STORE_add_cert(store, cert);
+ if (status == 0) {
+ X509_free(cert);
+ return status;
+ }
}
- Dart_Handle directory_object = ThrowIfError(Dart_GetNativeArgument(args, 2));
- const char* directory = NULL;
- if (Dart_IsString(directory_object)) {
- ThrowIfError(Dart_StringToCString(directory_object, &directory));
- } else if (Dart_IsNull(directory_object)) {
- directory = NULL;
+
+ uint32_t err = ERR_peek_last_error();
+ if ((ERR_GET_LIB(err) == ERR_LIB_PEM) &&
+ (ERR_GET_REASON(err) == PEM_R_NO_START_LINE)) {
+ // Reached the end of the buffer.
+ ERR_clear_error();
} else {
- Dart_ThrowException(DartUtils::NewDartArgumentError(
- "Directory argument to SecurityContext.setTrustedCertificates is not "
- "a String or null"));
+ // Some real error happened.
+ status = 0;
}
- int status = SSL_CTX_load_verify_locations(context, filename, directory);
- CheckStatus(
- status, "TlsException", "SSL_CTX_load_verify_locations");
+ return status;
+}
+
+
+void FUNCTION_NAME(SecurityContext_SetTrustedCertificatesBytes)(
+ Dart_NativeArguments args) {
+ SSL_CTX* context = GetSecurityContext(args);
+
+ BIO* bio = NULL;
+ Dart_Handle certs_object = ThrowIfError(Dart_GetNativeArgument(args, 1));
+ bool is_typed_data = GetBIOArgument(certs_object, &bio);
+ ASSERT(bio != NULL);
+
+ int status = SetTrustedCertificatesBytes(context, bio);
+
+ FreeBIO(certs_object, bio, is_typed_data);
+ CheckStatus(status,
+ "TlsException",
+ "Failure in setTrustedCertificatesBytes");
}
@@ -489,17 +529,10 @@ void FUNCTION_NAME(SecurityContext_TrustBuiltinRoots)(
}
-static int UseChainBytes(
- SSL_CTX* context, uint8_t* chain_bytes, intptr_t chain_bytes_len) {
+static int UseChainBytes(SSL_CTX* context, BIO* bio) {
int status = 0;
- BIO* bio = BIO_new_mem_buf(chain_bytes, chain_bytes_len);
- if (bio == NULL) {
- return 0;
- }
-
X509* x509 = PEM_read_bio_X509_AUX(bio, NULL, NULL, NULL);
if (x509 == NULL) {
- BIO_free(bio);
return 0;
}
@@ -510,7 +543,6 @@ static int UseChainBytes(
}
if (status == 0) {
X509_free(x509);
- BIO_free(bio);
return status;
}
@@ -525,7 +557,6 @@ static int UseChainBytes(
if (status == 0) {
X509_free(ca);
X509_free(x509);
- BIO_free(bio);
return status;
}
// Note that we must not free `ca` if it was successfully added to the
@@ -544,7 +575,6 @@ static int UseChainBytes(
}
X509_free(x509);
- BIO_free(bio);
return status;
}
@@ -553,64 +583,67 @@ void FUNCTION_NAME(SecurityContext_UseCertificateChainBytes)(
Dart_NativeArguments args) {
SSL_CTX* context = GetSecurityContext(args);
+ BIO* bio = NULL;
Dart_Handle chain_object = ThrowIfError(Dart_GetNativeArgument(args, 1));
- if (!Dart_IsTypedData(chain_object) && !Dart_IsList(chain_object)) {
- Dart_ThrowException(DartUtils::NewDartArgumentError(
- "chainBytes argument to SecurityContext.useCertificateChainBytes "
- "is not a List<int>"));
+ bool is_typed_data = GetBIOArgument(chain_object, &bio);
+ ASSERT(bio != NULL);
+
+ int status = UseChainBytes(context, bio);
+
+ FreeBIO(chain_object, bio, is_typed_data);
+ CheckStatus(status,
+ "TlsException",
+ "Failure in useCertificateChainBytes");
+}
+
+
+static STACK_OF(X509_NAME)* GetCertificateNames(BIO* bio) {
+ STACK_OF(X509_NAME)* result = sk_X509_NAME_new_null();
+ if (result == NULL) {
+ return NULL;
}
- uint8_t* chain_bytes = NULL;
- intptr_t chain_bytes_len = 0;
- bool is_typed_data = false;
- if (Dart_IsTypedData(chain_object)) {
- is_typed_data = true;
- Dart_TypedData_Type typ;
- ThrowIfError(Dart_TypedDataAcquireData(
- chain_object,
- &typ,
- reinterpret_cast<void**>(&chain_bytes),
- &chain_bytes_len));
- } else {
- ASSERT(Dart_IsList(chain_object));
- ThrowIfError(Dart_ListLength(chain_object, &chain_bytes_len));
- chain_bytes = new uint8_t[chain_bytes_len];
- Dart_Handle err =
- Dart_ListGetAsBytes(chain_object, 0, chain_bytes, chain_bytes_len);
- if (Dart_IsError(err)) {
- delete[] chain_bytes;
- Dart_PropagateError(err);
+ while (true) {
+ X509* x509 = PEM_read_bio_X509(bio, NULL, NULL, NULL);
+ if (x509 == NULL) {
+ break;
}
- }
- ASSERT(chain_bytes != NULL);
- int status = UseChainBytes(context, chain_bytes, chain_bytes_len);
+ X509_NAME* x509_name = X509_get_subject_name(x509);
+ if (x509_name == NULL) {
+ sk_X509_NAME_pop_free(result, X509_NAME_free);
+ X509_free(x509);
+ return NULL;
+ }
- if (is_typed_data) {
- ThrowIfError(Dart_TypedDataReleaseData(chain_object));
- } else {
- delete[] chain_bytes;
+ // Duplicate the name to put it on the stack.
+ x509_name = X509_NAME_dup(x509_name);
+ if (x509_name == NULL) {
+ sk_X509_NAME_pop_free(result, X509_NAME_free);
+ X509_free(x509);
+ return NULL;
+ }
+ sk_X509_NAME_push(result, x509_name);
+ X509_free(x509);
}
- CheckStatus(status,
- "TlsException",
- "Failure in useCertificateChainBytes");
+
+ return result;
}
-void FUNCTION_NAME(SecurityContext_SetClientAuthorities)(
+void FUNCTION_NAME(SecurityContext_SetClientAuthoritiesBytes)(
Dart_NativeArguments args) {
SSL_CTX* context = GetSecurityContext(args);
- Dart_Handle filename_object = ThrowIfError(Dart_GetNativeArgument(args, 1));
- const char* filename = NULL;
- if (Dart_IsString(filename_object)) {
- ThrowIfError(Dart_StringToCString(filename_object, &filename));
- } else {
- Dart_ThrowException(DartUtils::NewDartArgumentError(
- "file argument in SecurityContext.setClientAuthorities"
- " is not a String"));
- }
- STACK_OF(X509_NAME)* certificate_names;
- certificate_names = SSL_load_client_CA_file(filename);
+
+ BIO* bio = NULL;
+ Dart_Handle certs_object = ThrowIfError(Dart_GetNativeArgument(args, 1));
+ bool is_typed_data = GetBIOArgument(certs_object, &bio);
+ ASSERT(bio != NULL);
+
+ STACK_OF(X509_NAME)* certificate_names = GetCertificateNames(bio);
+
+ FreeBIO(certs_object, bio, is_typed_data);
+
if (certificate_names != NULL) {
SSL_CTX_set_client_CA_list(context, certificate_names);
} else {
« no previous file with comments | « runtime/bin/io_natives.cc ('k') | runtime/bin/secure_socket_patch.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698