How To Establishing a Certificate-Based Connection to APNs - swift

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

I assume that your question relates to flutter web - not a standalone Mac OS application? Then I can think of the following scenarios:
Use client certificates to establish an SSL based secure transport layer with certificate based authentication.
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

Related

OpenID Connect: transparent authentication for legacy clients using Resource Owner Password Credentials

We're currently rewriting various services to use OpenID Connect (via Keycloak).
This works great for any modern browser-based clients, but in our case we also need to support legacy IoT devices, which:
cannot receive a firmware update (and thus are stuck in their current modes of authentication/communication)
are not aware of Keycloak and are not configured to participate in OpenID Connect. (and are also only aware of the application's URL and not the Keycloak URL)
authenticate directly with the application using either Basic Authentication or SSL Client Authentication with a certificate.
From the documentation we gathered that mapping each device to a Keycloak user and using the
Resource Owner Password Credentials would be the way to go in such cases.
We were thinking that it'd be nice to add centralized support for such devices by exposing a reverse proxy that sits in front of all services and performs the following steps:
Receive the IoT device requests (and optionally terminate SSL)
Extract the credentials from the request (either basic auth / client certificate)
Perform the Resource Owner Password Credentials Flow against Keycloak to exchange the credentials for an access token (where the IoT device acts as the OAuth Resource Owner and the reverse proxy acts as the OAuth Client
If successful, enrich the original request with the retrieved access token and forward it to the proxied service
In that way the entire OpenID Connect authentication is transparent for any legacy devices.
This design could be further improved/optimized by caching the access tokens for the duration they are valid for (using the credentials as the cache key) and refreshing them when they expire.
Now, this idea seems like such a no-brainer, that we were surprised that we couldn't find any existing gateways, reverse proxies or plugins that do this.
So I guess we're in need of a sanity check on:
Is this something that can work as described or are there any obvious flaws with the idea?
Why isn't anyone doing this already? (assuming that supporting legacy devices is a major pain point when switching to OpenID Connect)
UPDATE 1: (responding to question) The described legacy IoT devices are (physically) Arduino microcontrollers with baked-in unique credentials. In the context of Keycloak, each such Arduino microcontroller is mapped as a Keycloak user. We're open for suggestions if this is not the most adequate mapping for this use-case.
UPDATE 2: (responding to question) Agreed that the Client Credentials Flow would be semantically more correct for such a device-to-device authentication and any future devices we produce will use it. However we can't use it for the existing legacy devices for two reasons: 1) the devices only know the server's URL and can't authenticate directly against Keycloak and 2) we also want to support SSL Client Authentication using a X.509 certificate and from our understanding Keycloak only supports X.509 client certificate user authentication for users, and not for clients.
Is this something that can work as described or are there any obvious flaws with the idea?
It works fine, so long as your OP supports the Resource Owner Password Credentials flow, which is deprecated and removed from modern OAuth2.
Why isn't anyone doing this already? (assuming that supporting legacy devices is a major pain point when switching to OpenID Connect)
Lots of reverse proxies do this, just not with resource owner credentials. The ROPC flow was never a good idea, exists for legacy reasons, and has been removed from OAuth 2.1.
I suspect that most people move away from storing and transmitting resource owner credentials as they modernize their architecture.

Configure IBM Cloud Application with "request of client certificate"

I need to configure an application to accept connection only from client with a certificate, the client should be ApiGateway.
I followed this step by step tutorial. But when I should upload a certificate and enable a checkbox called "Enable request of client certificate" in upload dialog box it disappear.
I tried with many browser (Chrome, Firefox, Safari) on a Mac. I'm quite that this not depend on browser, so now how can do the same thing?
Thanks for every answer.
From my understanding, the given task needs to be separated into two activities.
Client with certificate
A client with DNS APIgateway
Client with Certificate
In general, when we create an API, we expose with a gateway via HTTP protocol which has some signed certificate (Production). Please provide that public certificate to the consumer of your API. And you can test this using postman, we have an option of SSL certificate upload in Postman, make a use of it for testing.
Client with DNS Name
For this, in Datapower (API Gateway), you can create an Access control list following this IBM documentation. Access control list is something, we allow or restrict the host that we consume the services exposed using Datapower.

How to use application's client certificate with Charles?

Trying to investigate private APIs on apps installed on my Android, I've noticed most modern apps use custom client certificate meaning with the trusted root certificate installed on the Android, Charles still cannot monitor the traffic because the server would reject the handshake from Charles. I imagine either I will need a different tool for the traffic monitoring or I will need to direct Charles to use some custom certificate file embedded in the app itself.
You need that certificate file at hand (I don't know if and how you can extract it from application).
You also need to know the passphrase (password) for that certificate. Charles will ask it when you connect to selected host for 1st time.
Then just use latest Charles (tested on version 4.2.1) menu Proxy -> SSL Proxying Settings, tab Client Certificates and add certificate (PKCS#12 key file) for selected host and port.

Certificates being renewed yearly - how to reliably find them in the cert store?

I've been tasked to add security by means of certificates to an external web service we call from our ASP.NET 4.0 Webforms application.
I've been able to play around with the certificate and get the code to work properly, but there are still a lot of questions unanswered when it comes to deployment of that solution. I'm pretty new to actually using (and dealing with) certificates - I understand the basic theory behind them, just never used them much myself.
The service is an external REST webservice provided by a company which also issues the certificates - and those will expire on a yearly basis and need to be renewed yearly. So "baking" them into the ASP.NET app as an internal resource doesn't seem like a good idea.
I'm leaning towards putting them into the certificate store on the Windows 2008 Server. That works fine, but what I'm not sure about: how do I FIND the appropriate certificate from code? I know about the X509Certificate2 and X509Store classes - but what criteria should I search for?
What item (Serial number? Thumbprint?) would remain the same if that cert has to be renewed every year? Or do I have to update my config and store a new serial number or thumbprint every time the cert has been renewed?
If I understand correctly you need to ensure that you are communicating with correct web service.
You are using https to connect to the REST service. Is it a WCF service or Web API? Either way the web server will handle the SSL part (hmm, only if hosted on a web server and not self hosted). So if we make it easy then the web service is hosted on a web server. The web server will handle establishing SSL connection and will send you server certificate.
Then you need to check if you are communicating with correct web server. Your options are:
manually update config file with thumbprint that will change every time the certificate of web server will be renewed. Also serial number will change when they renew the certificate.
check for common name in the subject or better if the is correct DNS name (of the web server) in Subject alternative name (SAN = extension in the certificate) or in CN (when SAN is not in the certificate)
build a certificate chain (using X509Chain.Build method) from web server's certificate and check if it contains a CA certificate that you have embedded in ASP.NET application or if it matches given thumbprint of CA from you config.
1) - will work but you have to ensure to update config file every year
2) - will work nice until they change DNS name of the web server, but it would result in change of your web.config so ... it will work. One thing to note is that extracting any extension from X509Certificate2 class using standard .NET framework is not easy. You would need to either go to ASN.1 level or use some crypto library that can extract the SAN in a friendly way.
3) - will work nicely. You can use Root CA certificate or dedicated intermediate CA certificate. You have to ensure that web server certificate is trusted for certificate chain to be built but that applies generally to all solutions. It will work pretty long time because CA certificates are issued to i.e. 20-30 years.

is there any secure websocket (wss protocol) client browser plugin available?

we would like to test our secure websocket (i.e wss) end point. I am looking for easy tool to test the endpoint. is there browser plugin available for wss protocol?
I used "Simple WebSocket Client" chrome plugin to test wss endpoint. If your websocket is using self signed certificate, you to need add that certificate as a trusted certificated in your browser.
I followed below steps to add the self signed in my chrome browser.
suppose your websocket url is "wss://host1:port1/testSocket" . Then type urls as https:// host1:port1/testSocket
and trust the certificate.
AutobahnTestsuite is an automated WebSocket protocol test suite that supports WSS. It is used by most WebSocket implementors to test their implementations for compliance and interoperability.
Disclosure: I am original author of the testsuite.
I've run into this issue often enough that I finally created my own barebones GUI for testing websockets. It's called Socket Wrench, it supports
multiple concurrent connections to servers (with all responses and connections displayed in the same view),
comprehensive message history to enable easy re-use of messages, and
custom headers for the initial connection request.
It's available for Mac OS X, Windows and Linux and you can get it from here.