mirror of
https://github.com/dart-lang/sdk
synced 2024-09-15 22:31:50 +00:00
[VM / IO] Fix cases where TlsExceptions were being created with an
OSError code of 0 One such example was _SecurityContext.setTrustedCertificatesBytes TEST=new tests added Change-Id: Ibc5d06b83bb1bb93e12f79100acc60546554c268 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/239863 Reviewed-by: Alexander Aprelev <aam@google.com> Commit-Queue: Siva Annamalai <asiva@google.com>
This commit is contained in:
parent
4f76b9535d
commit
89f5b68ca1
|
@ -21,9 +21,13 @@ namespace bin {
|
|||
|
||||
// Get the error messages from BoringSSL, and put them in buffer as a
|
||||
// null-terminated string.
|
||||
void SecureSocketUtils::FetchErrorString(const SSL* ssl,
|
||||
TextBuffer* text_buffer) {
|
||||
// This function extracts all the error messages into a string and returns
|
||||
// the first error code so that this error can be passed in as the OSError
|
||||
// error code to the IOException.
|
||||
uint32_t SecureSocketUtils::FetchErrorString(const SSL* ssl,
|
||||
TextBuffer* text_buffer) {
|
||||
const char* sep = File::PathSeparator();
|
||||
uint32_t errCode = 0;
|
||||
while (true) {
|
||||
const char* path = NULL;
|
||||
int line = -1;
|
||||
|
@ -31,6 +35,9 @@ void SecureSocketUtils::FetchErrorString(const SSL* ssl,
|
|||
if (error == 0) {
|
||||
break;
|
||||
}
|
||||
if (errCode == 0) {
|
||||
errCode = error;
|
||||
}
|
||||
text_buffer->Printf("\n\t%s", ERR_reason_error_string(error));
|
||||
if ((ssl != NULL) && (ERR_GET_LIB(error) == ERR_LIB_SSL) &&
|
||||
(ERR_GET_REASON(error) == SSL_R_CERTIFICATE_VERIFY_FAILED)) {
|
||||
|
@ -43,6 +50,7 @@ void SecureSocketUtils::FetchErrorString(const SSL* ssl,
|
|||
text_buffer->Printf("(%s:%d)", path, line);
|
||||
}
|
||||
}
|
||||
return errCode;
|
||||
}
|
||||
|
||||
// Handle an error reported from the BoringSSL library.
|
||||
|
@ -53,7 +61,10 @@ void SecureSocketUtils::ThrowIOException(int status,
|
|||
Dart_Handle exception;
|
||||
{
|
||||
TextBuffer error_string(SSL_ERROR_MESSAGE_BUFFER_SIZE);
|
||||
SecureSocketUtils::FetchErrorString(ssl, &error_string);
|
||||
uint32_t errCode = SecureSocketUtils::FetchErrorString(ssl, &error_string);
|
||||
if (status == 0) {
|
||||
status = errCode;
|
||||
}
|
||||
OSError os_error_struct(status, error_string.buffer(), OSError::kBoringSSL);
|
||||
Dart_Handle os_error = DartUtils::NewDartOSError(&os_error_struct);
|
||||
exception =
|
||||
|
|
|
@ -47,7 +47,7 @@ class SecureSocketUtils : public AllStatic {
|
|||
(ERR_GET_REASON(last_error) == PEM_R_NO_START_LINE);
|
||||
}
|
||||
|
||||
static void FetchErrorString(const SSL* ssl, TextBuffer* text_buffer);
|
||||
static uint32_t FetchErrorString(const SSL* ssl, TextBuffer* text_buffer);
|
||||
};
|
||||
|
||||
// Where the argument to the constructor is the handle for an object
|
||||
|
|
88
tests/standalone/io/secure_socket_error_test.dart
Normal file
88
tests/standalone/io/secure_socket_error_test.dart
Normal file
|
@ -0,0 +1,88 @@
|
|||
// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
|
||||
// for details. All rights reserved. Use of this source code is governed by a
|
||||
// BSD-style license that can be found in the LICENSE file.
|
||||
//
|
||||
// OtherResources=certificates/server_chain.pem
|
||||
// OtherResources=certificates/server_key.pem
|
||||
// OtherResources=certificates/trusted_certs.pem
|
||||
// OtherResources=certificates/server_chain.p12
|
||||
// OtherResources=certificates/server_key.p12
|
||||
// OtherResources=certificates/trusted_certs.p12
|
||||
|
||||
import "package:async_helper/async_helper.dart";
|
||||
import "package:expect/expect.dart";
|
||||
import "package:path/path.dart";
|
||||
import "dart:async";
|
||||
import "dart:io";
|
||||
|
||||
String localFile(path) => Platform.script.resolve(path).toFilePath();
|
||||
|
||||
SecurityContext serverContext(String certType, String password) =>
|
||||
new SecurityContext()
|
||||
..useCertificateChain(localFile('certificates/server_chain.$certType'),
|
||||
password: password)
|
||||
..usePrivateKey(localFile('certificates/server_key.$certType'),
|
||||
password: password);
|
||||
|
||||
SecurityContext clientContext(String certType, String password) =>
|
||||
new SecurityContext()
|
||||
..setTrustedCertificates(
|
||||
localFile('certificates/trusted_certs.$certType'),
|
||||
password: password);
|
||||
|
||||
Future<HttpServer> startServer(String certType, String password) {
|
||||
return HttpServer.bindSecure(
|
||||
"localhost", 0, serverContext(certType, password),
|
||||
backlog: 5)
|
||||
.then((server) {
|
||||
server.listen((HttpRequest request) {
|
||||
request.listen((_) {}, onDone: () {
|
||||
request.response.contentLength = 100;
|
||||
for (int i = 0; i < 10; i++) {
|
||||
request.response.add([0, 1, 2, 3, 4, 5, 6, 7, 8, 9]);
|
||||
}
|
||||
request.response.close();
|
||||
});
|
||||
});
|
||||
return server;
|
||||
});
|
||||
}
|
||||
|
||||
Future test(String certType, String password) {
|
||||
List<int> body = <int>[];
|
||||
Completer completer = new Completer();
|
||||
startServer(certType, password).then((server) {
|
||||
try {
|
||||
SecureSocket.connect("localhost", server.port,
|
||||
context: clientContext(certType, 'junkjunk'))
|
||||
.then((socket) {
|
||||
socket.write("GET / HTTP/1.0\r\nHost: localhost\r\n\r\n");
|
||||
socket.close();
|
||||
socket.listen((List<int> data) {
|
||||
body.addAll(data);
|
||||
}, onDone: () {
|
||||
server.close();
|
||||
completer.complete(null);
|
||||
}, onError: (e, trace) {
|
||||
server.close();
|
||||
completer.complete(null);
|
||||
});
|
||||
});
|
||||
} catch (e) {
|
||||
Expect.isTrue(e is TlsException);
|
||||
var err = (e as TlsException).osError;
|
||||
Expect.isTrue(err is OSError);
|
||||
Expect.isTrue(err!.errorCode != 0);
|
||||
server.close();
|
||||
completer.complete(null);
|
||||
}
|
||||
});
|
||||
return completer.future;
|
||||
}
|
||||
|
||||
main() async {
|
||||
asyncStart();
|
||||
await test('pem', 'dartdart');
|
||||
await test('p12', 'dartdart');
|
||||
asyncEnd();
|
||||
}
|
88
tests/standalone_2/io/secure_socket_error_test.dart
Normal file
88
tests/standalone_2/io/secure_socket_error_test.dart
Normal file
|
@ -0,0 +1,88 @@
|
|||
// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
|
||||
// for details. All rights reserved. Use of this source code is governed by a
|
||||
// BSD-style license that can be found in the LICENSE file.
|
||||
//
|
||||
// OtherResources=certificates/server_chain.pem
|
||||
// OtherResources=certificates/server_key.pem
|
||||
// OtherResources=certificates/trusted_certs.pem
|
||||
// OtherResources=certificates/server_chain.p12
|
||||
// OtherResources=certificates/server_key.p12
|
||||
// OtherResources=certificates/trusted_certs.p12
|
||||
|
||||
import "package:async_helper/async_helper.dart";
|
||||
import "package:expect/expect.dart";
|
||||
import "package:path/path.dart";
|
||||
import "dart:async";
|
||||
import "dart:io";
|
||||
|
||||
String localFile(path) => Platform.script.resolve(path).toFilePath();
|
||||
|
||||
SecurityContext serverContext(String certType, String password) =>
|
||||
new SecurityContext()
|
||||
..useCertificateChain(localFile('certificates/server_chain.$certType'),
|
||||
password: password)
|
||||
..usePrivateKey(localFile('certificates/server_key.$certType'),
|
||||
password: password);
|
||||
|
||||
SecurityContext clientContext(String certType, String password) =>
|
||||
new SecurityContext()
|
||||
..setTrustedCertificates(
|
||||
localFile('certificates/trusted_certs.$certType'),
|
||||
password: password);
|
||||
|
||||
Future<HttpServer> startServer(String certType, String password) {
|
||||
return HttpServer.bindSecure(
|
||||
"localhost", 0, serverContext(certType, password),
|
||||
backlog: 5)
|
||||
.then((server) {
|
||||
server.listen((HttpRequest request) {
|
||||
request.listen((_) {}, onDone: () {
|
||||
request.response.contentLength = 100;
|
||||
for (int i = 0; i < 10; i++) {
|
||||
request.response.add([0, 1, 2, 3, 4, 5, 6, 7, 8, 9]);
|
||||
}
|
||||
request.response.close();
|
||||
});
|
||||
});
|
||||
return server;
|
||||
});
|
||||
}
|
||||
|
||||
Future test(String certType, String password) {
|
||||
List<int> body = <int>[];
|
||||
Completer completer = new Completer();
|
||||
startServer(certType, password).then((server) {
|
||||
try {
|
||||
SecureSocket.connect("localhost", server.port,
|
||||
context: clientContext(certType, 'junkjunk'))
|
||||
.then((socket) {
|
||||
socket.write("GET / HTTP/1.0\r\nHost: localhost\r\n\r\n");
|
||||
socket.close();
|
||||
socket.listen((List<int> data) {
|
||||
body.addAll(data);
|
||||
}, onDone: () {
|
||||
server.close();
|
||||
completer.complete(null);
|
||||
}, onError: (e, trace) {
|
||||
server.close();
|
||||
completer.complete(null);
|
||||
});
|
||||
});
|
||||
} catch (e) {
|
||||
Expect.isTrue(e is TlsException);
|
||||
var err = (e as TlsException).osError;
|
||||
Expect.isTrue(err is OSError);
|
||||
Expect.isTrue(err!.errorCode != 0);
|
||||
server.close();
|
||||
completer.complete(null);
|
||||
}
|
||||
});
|
||||
return completer.future;
|
||||
}
|
||||
|
||||
main() async {
|
||||
asyncStart();
|
||||
await test('pem', 'dartdart');
|
||||
await test('p12', 'dartdart');
|
||||
asyncEnd();
|
||||
}
|
Loading…
Reference in a new issue