Dart Add SSL certificate and key to HttpClient

I'm trying to secure a REST API using TLS/SSL, to do so I needed to update my client to use the public key and certificate. The client is written in dart and here's how I implemented the SecurityContext :

SecurityContext clientContext = SecurityContext.defaultContext;

var certificate = (await rootBundle.load("assets/ssl/coastr.crt")).buffer.asInt8List();
print(certificate.toString());
clientContext.setTrustedCertificatesBytes(certificate);

/*var authorities = (await rootBundle.load('assets/ssl/coastr.ca-bundle')).buffer.asUint8List();
print(authorities.toString());
clientContext.setClientAuthoritiesBytes(authorities);*/

var key = (await rootBundle.load("assets/ssl/coastr_public.key")).buffer.asInt8List();
print(key.toString());
clientContext.usePrivateKeyBytes(key);

HttpClient client = HttpClient(context: clientContext);

HttpClientRequest request = await client.getUrl(Uri.parse(url));

HttpClientResponse response = await request.close();

The certificate (.crt file) is added without issue to the clientContext but adding the key to it returns me this error :

[ERROR:flutter/lib/ui/ui_dart_state.cc(148)] Unhandled Exception:
TlsException: Failure in usePrivateKeyBytes (OS Error: 
BAD_PKCS12_DATA(pkcs8_x509.c:606)
passed a null parameter(ssl_privkey.cc:375), errno = 0)

The files I'm using are :

I have no idea if I'm providing the wrong files to the client or if the error comes from elsewhere. The files where generated using openssl.

Thank you for your help.

Upvotes: 0

Views: 7509

Answers (2)

Moataz Hossam
Moataz Hossam

Reputation: 413

I solved this by exporting the chained certificate and using it. It contains 3 public keys above each others. enter image description here

Pick the second option then convert it to PEM and the issue should be fixed.

Upvotes: 0

Richard Heap
Richard Heap

Reputation: 51682

In general, you shouldn't have to add anything to the client to allow it to connect to a correctly configured HTTPS server. Hopefully, the server has a signed server side certificate. If that certificate is signed by a reputable CA, the client should automatically trust it. If it is signed by an in house CA, or self signed, you need to do some work. You need to provide the client with the signing certificate. In the former case that would be the root CA's certificate. In the latter case, supplying the server's certificate may work, though it's probably easier to disable the client check altogether.

The signing certificate is likely to be in CRT form as you've found. And you need to supply that exactly as you are doing. There's no need to supply any public keys as the are distributed in the certificates sent with the server hello.

Unless you want to use a client side certificate, there's no need to supply a private key, so you can skip the step that is failing. And supplying a public key to it is definitely not going to work, anyway.

Upvotes: 2

Related Questions