2

I do not know is it correct way or not but I am trying to get certificate from macos keychain and use it on flutter httpclient to establish a Certificate based connection. I just wonder is it possible or not.

For now i can get the certificate with native code with and i am returning the data:

  var certificate: SecCertificate?
  SecIdentityCopyCertificate(identityNotNil, &certificate)
  let data = SecCertificateCopyData(certificate!)

then i try to use it like inside flutter:

SecurityContext context = SecurityContext.defaultContext
   ..useCertificateChain(certificateByteArray, password: 'password');

var _client = HttpClient(context: context);

but i am getting error about bad certificate. Maybe there is a way to reach keychain directly from flutter.

Thank you.

To be more specific, i am trying to use a certificate like : https://developer.apple.com/documentation/usernotifications/setting_up_a_remote_notification_server/establishing_a_certificate-based_connection_to_apns

BarisY
  • 151
  • 1
  • 5

1 Answers1

2

I assume that your question relates to flutter web - not a standalone Mac OS application? Then I can think of the following scenarios:

  1. Use client certificates to establish an SSL based secure transport layer with certificate based authentication.

  2. Use client certificates to exchange encrypted messages with encryption done by the application (both client and server) or use client certificates on the application layer for Authentication only.

Scenario 1: SSL with client certificates

In flutter web, HTTP Connections are only supported via XMLHttpRequest - the underlying JavaScript Object - under the hood flutter web code is transformed into JavaScript code. XMLHTTPRequest does NOT support any Client Certificates.

But you can configure the Browser to use client certificates when connecting to a WebServer via SSL - this would be fully transparent to the flutter web app. All modern browsers support client certificates and do access the MacOS keychain.

Of course, the server need to support SSL with client certificates. E.g. if you want to use client certificates in order to authenticate to a Spring Application based on SSL client certificates, this is described here:

Spring Security - Pre-Authentication Scenarios

Scenario 2: Application layer encryption/authentication

This is a very unusual scenario, as web applications usually rely on SSL for many good reasons: No coding is required and its pretty secure. But of course, it is technically feasible to implement encryption of all messages exchanged with the server on your own.

Letting aside the pure coding work (encryption libraries also exist for flutter), the key problem is to get the certificate and the private key into the application. Loading the certificate from the server without prior authentication (like the web app itself or all assets) would be a major security flaw, because then an attacker could also easily download the certificate/private key.

The only secure way I can think of, is to obtain the certificate and private key form the client computer. Unfortunately, a flutter web app - like every JavaScript app - is running in a Sandbox within a Browser, which puts major constraints on the application - for good Browser security reasons. Due to this sandbox, the flutter web app CANNOT access the Mac OS keychain directly.

But you can let the user pick a file with the certificate and private key. This is described here:

How to Pick files and Images for upload with flutter web

Udo Knop
  • 81
  • 4
  • Thank you but my question about all macos, ios and web. If i could reach the keychain from flutter, is it possible to use it on connection. I also edit my question to be more clear Like : https://developer.apple.com/documentation/usernotifications/setting_up_a_remote_notification_server/establishing_a_certificate-based_connection_to_apns – BarisY Apr 07 '22 at 06:20
  • Perhaps, you could be more specific how you access the Mac OS key chain. Citing from the inline doc of SecuriyContext: `iOS note: As noted above, [usePrivateKey] does the job of both that call and this one. On iOS, this call is a no-op. void useCertificateChain(String file, {String? password});` `iOS note: Only PKCS12 data is supported. It should contain both the private key and the certificate chain. On iOS one call to [usePrivateKey] with this data is used instead of two calls to [useCertificateChain] and [usePrivateKey]. void usePrivateKey(String file, {String? password});` – Udo Knop Apr 07 '22 at 06:40
  • @UdoKnop TLDR : You cannot supply certs in flutter web ? Seems like a major limitation – Pranav Sawant Nov 14 '22 at 19:12
  • This is not a limitation of flutter web. It's a security limitation which every browser imposes on dynamic/JavaScript based web pages it renders - sandbox approch, see .e.g. https://www.lambdatest.com/blog/browser-sandboxing/ – Udo Knop Nov 15 '22 at 21:43