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

Unified Diff: dart/runtime/bin/secure_socket.cc

Issue 625953002: Support for the ALPN extension of the TLS protocol for Client and Server (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge
Patch Set: Add test for ALPN negotiation Created 6 years, 2 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
Index: dart/runtime/bin/secure_socket.cc
diff --git a/dart/runtime/bin/secure_socket.cc b/dart/runtime/bin/secure_socket.cc
index 350bc64afa395e1ca399f5441a3b524712b3ceaf..24c7ba43194db24c8a1675e877d5f679bf4c24ea 100644
--- a/dart/runtime/bin/secure_socket.cc
+++ b/dart/runtime/bin/secure_socket.cc
@@ -121,6 +121,8 @@ void FUNCTION_NAME(SecureSocket_Connect)(Dart_NativeArguments args) {
DartUtils::GetBooleanValue(Dart_GetNativeArgument(args, 7));
bool send_client_certificate =
DartUtils::GetBooleanValue(Dart_GetNativeArgument(args, 8));
+ Dart_Handle client_protocols_handle =
+ ThrowIfError(Dart_GetNativeArgument(args, 9));
const char* host_name = NULL;
// TODO(whesse): Is truncating a Dart string containing \0 what we want?
@@ -142,6 +144,28 @@ void FUNCTION_NAME(SecureSocket_Connect)(Dart_NativeArguments args) {
// If this is a server connection, it must have a certificate to connect with.
ASSERT(!is_server || certificate_name != NULL);
+
+
+ Dart_TypedData_Type protocols_type;
+ uint8_t* protocol_string = NULL;
+ intptr_t protocol_string_len = 0;
+
+ ASSERT(!Dart_IsNull(client_protocols_handle));
+ Dart_Handle result = Dart_TypedDataAcquireData(
+ client_protocols_handle,
+ &protocols_type,
+ reinterpret_cast<void**>(&protocol_string),
+ &protocol_string_len);
+ if (Dart_IsError(result)) {
+ Dart_PropagateError(result);
+ }
+
+ if (protocols_type != Dart_TypedData_kUint8) {
+ Dart_TypedDataReleaseData(client_protocols_handle);
+ Dart_PropagateError(
+ Dart_NewApiError("Unexpected type for protocols"));
+ }
+
GetFilter(args)->Connect(host_name,
&raw_addr,
static_cast<int>(port),
@@ -149,7 +173,10 @@ void FUNCTION_NAME(SecureSocket_Connect)(Dart_NativeArguments args) {
certificate_name,
request_client_certificate,
require_client_certificate,
- send_client_certificate);
+ send_client_certificate,
+ protocol_string,
+ protocol_string_len);
kustermann 2014/10/03 13:25:26 If GetFilter(args)->Connect() fails, can it unwind
Søren Gjesse 2014/10/03 15:47:04 As discussed off-line you need to release it befor
kustermann 2014/11/07 16:20:03 Instead of making more calls into the VM & copying
+ Dart_TypedDataReleaseData(client_protocols_handle);
}
@@ -166,6 +193,12 @@ void FUNCTION_NAME(SecureSocket_Handshake)(Dart_NativeArguments args) {
}
+void FUNCTION_NAME(SecureSocket_GetSelectedProtocol)(
+ Dart_NativeArguments args) {
+ GetFilter(args)->GetSelectedProtocol(args);
+}
+
+
void FUNCTION_NAME(SecureSocket_Renegotiate)(Dart_NativeArguments args) {
bool use_session_cache =
DartUtils::GetBooleanValue(Dart_GetNativeArgument(args, 1));
@@ -658,7 +691,9 @@ void SSLFilter::Connect(const char* host_name,
const char* certificate_name,
bool request_client_certificate,
bool require_client_certificate,
- bool send_client_certificate) {
+ bool send_client_certificate,
+ uint8_t *protocols,
+ intptr_t protocols_len) {
is_server_ = is_server;
if (in_handshake_) {
FATAL("Connect called twice on the same _SecureFilter.");
@@ -673,12 +708,22 @@ void SSLFilter::Connect(const char* host_name,
ThrowPRException("TlsException", "Failed SSL_ImportFD call");
}
+
+ SECStatus status;
+
+ if (protocols_len > 0) {
+ status = SSL_OptionSet(filter_, SSL_ENABLE_ALPN, PR_TRUE);
+ ASSERT(status == SECSuccess);
+
+ status = SSL_SetNextProtoNego(filter_, protocols, protocols_len);
+ ASSERT(status == SECSuccess);
+ }
+
SSLVersionRange vrange;
vrange.min = SSL_LIBRARY_VERSION_3_0;
vrange.max = SSL_LIBRARY_VERSION_TLS_1_2;
SSL_VersionRangeSet(filter_, &vrange);
- SECStatus status;
if (is_server) {
CERTCertificate* certificate = NULL;
if (strstr(certificate_name, "CN=") != NULL) {
@@ -823,6 +868,45 @@ void SSLFilter::Handshake() {
}
}
+void SSLFilter::GetSelectedProtocol(Dart_NativeArguments args) {
+ // Space for the selected protocol.
+ const intptr_t kBufferSize = 256;
+ unsigned char buffer[kBufferSize + 1];
+
+ unsigned int outLength = 0;
+ SSLNextProtoState outState;
+
+ SECStatus status = SSL_GetNextProto(
+ filter_, &outState, buffer, &outLength, kBufferSize);
+ if (status == SECSuccess) {
+ if (outState == SSL_NEXT_PROTO_SELECTED ||
+ outState == SSL_NEXT_PROTO_NEGOTIATED) {
+ ASSERT(outLength <= kBufferSize);
+ buffer[outLength] = '\0';
+ Dart_Handle protocol_string = DartUtils::NewString(
+ reinterpret_cast<const char *>(&buffer[0]));
+ if (Dart_IsError(protocol_string)) {
+ ThrowPRException("HandshakeException",
+ "Protocol selected via ALPN was non-UTF8");
Søren Gjesse 2014/10/03 15:47:04 In principle this could also be an OOM i think, or
kustermann 2014/11/07 16:20:02 Rephrased message.
+ } else {
+ Dart_SetReturnValue(args, protocol_string);
+ }
+ } else if (outState == SSL_NEXT_PROTO_NO_OVERLAP) {
+ ThrowPRException("HandshakeException",
+ "Client and Server could not agree upon a protocol");
+ } else if (outState == SSL_NEXT_PROTO_NO_SUPPORT) {
+ // A value of `null` denotes that the client did not support protocol
+ // negogiation.
+ Dart_SetReturnValue(args, Dart_Null());
+ } else {
+ UNREACHABLE();
+ }
+ } else {
+ ThrowPRException("HandshakeException",
+ "Could not retrieve selected protocol via ALPN");
+ }
+}
+
void SSLFilter::Renegotiate(bool use_session_cache,
bool request_client_certificate,

Powered by Google App Engine
This is Rietveld 408576698