| // Copyright (c) 2013, 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. |
| |
| // @dart = 2.9 |
| |
| // OtherResources=certificates/server_chain.pem |
| // OtherResources=certificates/server_key.pem |
| // OtherResources=certificates/trusted_certs.pem |
| // OtherResources=certificates/client_authority.pem |
| // OtherResources=certificates/client1.pem |
| // OtherResources=certificates/client1_key.pem |
| // OtherResources=certificates/server_chain.p12 |
| // OtherResources=certificates/server_key.p12 |
| // OtherResources=certificates/trusted_certs.p12 |
| // OtherResources=certificates/client_authority.p12 |
| // OtherResources=certificates/client1.p12 |
| // OtherResources=certificates/client1_key.p12 |
| |
| import "dart:async"; |
| import "dart:io"; |
| |
| import "package:async_helper/async_helper.dart"; |
| import "package:expect/expect.dart"; |
| |
| InternetAddress HOST; |
| |
| 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) |
| ..setTrustedCertificates( |
| localFile('certificates/client_authority.$certType'), |
| password: password) |
| ..setClientAuthorities( |
| localFile('certificates/client_authority.$certType'), |
| password: password); |
| |
| SecurityContext clientCertContext(String certType, String password) => |
| new SecurityContext() |
| ..setTrustedCertificates( |
| localFile('certificates/trusted_certs.$certType'), |
| password: password) |
| ..useCertificateChain(localFile('certificates/client1.$certType'), |
| password: password) |
| ..usePrivateKey(localFile('certificates/client1_key.$certType'), |
| password: password); |
| |
| SecurityContext clientNoCertContext(String certType, String password) => |
| new SecurityContext() |
| ..setTrustedCertificates( |
| localFile('certificates/trusted_certs.$certType'), |
| password: password); |
| |
| Future testClientCertificate( |
| {bool required, bool sendCert, String certType, String password}) async { |
| var server = await SecureServerSocket.bind( |
| HOST, 0, serverContext(certType, password), |
| requestClientCertificate: true, requireClientCertificate: required); |
| var clientContext = sendCert |
| ? clientCertContext(certType, password) |
| : clientNoCertContext(certType, password); |
| var clientEndFuture = |
| SecureSocket.connect(HOST, server.port, context: clientContext); |
| if (required && !sendCert) { |
| final serverErrorCompleter = Completer<Exception>(); |
| server.listen((request) { |
| Expect.fail('Should not get a request through'); |
| }, onError: (e) => serverErrorCompleter.complete(e)); |
| |
| final clientDisconnected = Completer(); |
| final clientEnd = await clientEndFuture; |
| clientEnd.write(<int>[5, 6, 7, 8]); |
| clientEnd.close(); |
| clientEnd.listen((data) { |
| Expect.fail('Should not get data through'); |
| }, onError: (e) { |
| Expect.isTrue(e is SocketException); |
| }, onDone: () { |
| clientDisconnected.complete(); |
| }); |
| Expect.isTrue(await serverErrorCompleter.future is HandshakeException); |
| // Client might not report an error, might get just disconnected. |
| await clientDisconnected.future; |
| server.close(); |
| return; |
| } |
| var serverEnd = await server.first; |
| var clientEnd = await clientEndFuture; |
| |
| X509Certificate clientCertificate = serverEnd.peerCertificate; |
| if (sendCert) { |
| Expect.isNotNull(clientCertificate); |
| Expect.isTrue(clientCertificate.subject.contains("user1")); |
| Expect.isTrue(clientCertificate.issuer.contains("clientauthority")); |
| } else { |
| Expect.isNull(clientCertificate); |
| } |
| X509Certificate serverCertificate = clientEnd.peerCertificate; |
| Expect.isNotNull(serverCertificate); |
| Expect.isTrue(serverCertificate.subject.contains("localhost")); |
| Expect.isTrue(serverCertificate.issuer.contains("intermediateauthority")); |
| clientEnd.close(); |
| serverEnd.close(); |
| } |
| |
| main() async { |
| asyncStart(); |
| HOST = (await InternetAddress.lookup("localhost")).first; |
| await testClientCertificate( |
| required: false, sendCert: true, certType: 'pem', password: 'dartdart'); |
| await testClientCertificate( |
| required: true, sendCert: true, certType: 'pem', password: 'dartdart'); |
| await testClientCertificate( |
| required: false, sendCert: false, certType: 'pem', password: 'dartdart'); |
| await testClientCertificate( |
| required: true, sendCert: false, certType: 'pem', password: 'dartdart'); |
| |
| await testClientCertificate( |
| required: false, sendCert: true, certType: 'p12', password: 'dartdart'); |
| await testClientCertificate( |
| required: true, sendCert: true, certType: 'p12', password: 'dartdart'); |
| await testClientCertificate( |
| required: false, sendCert: false, certType: 'p12', password: 'dartdart'); |
| await testClientCertificate( |
| required: true, sendCert: false, certType: 'p12', password: 'dartdart'); |
| asyncEnd(); |
| } |