libmatoya icon indicating copy to clipboard operation
libmatoya copied to clipboard

Proposal: Change API for certificate pinning

Open roman-mazur opened this issue 2 years ago • 5 comments

The purpose of the PR is to open a discussion on what could be done to enable certificates pinning functionality for the HTTP request in the net module.

There is a need to implement certificate public key info pinning on the application side, which is not possible with the existing API.

This proposal adds API to make an HTTP request (async requests would be done similarly, not included here for brevity) with a provided MTY_TLS context that can be configured to perform either certificate or public key fingerprint check.

The check would be done on the certificate chain of the peer and succeed if one of the pins matches one of the certs in the chain.

Let me know what you think. Thanks.

roman-mazur avatar Aug 06 '21 13:08 roman-mazur

cc @chrisd1100 @RonaldH

roman-mazur avatar Aug 06 '21 13:08 roman-mazur

I know that OpenSSL, and probably all of these TLS engines, allow you to set a hard coded list of CA certs instead of pulling them from the OS. I think that gets us most of the way there, perhaps a globally interface like MTY_HttpSetCACerts(const char *certs)?

chrisd1100 avatar Aug 10 '21 12:08 chrisd1100

And the string would include a list of these: -----BEGIN CERTIFICATE----- MIIDdTCCAl2gAwIBAgILBAAAAAABFUtaw5QwDQYJKoZIhvcNAQEFBQAwVzELMAkGA1UEBhMCQkUx GTAXBgNVBAoTEEdsb2JhbFNpZ24gbnYtc2ExEDAOBgNVBAsTB1Jvb3QgQ0ExGzAZBgNVBAMTEkds b2JhbFNpZ24gUm9vdCBDQTAeFw05ODA5MDExMjAwMDBaFw0yODAxMjgxMjAwMDBaMFcxCzAJBgNV BAYTAkJFMRkwFwYDVQQKExBHbG9iYWxTaWduIG52LXNhMRAwDgYDVQQLEwdSb290IENBMRswGQYD VQQDExJHbG9iYWxTaWduIFJvb3QgQ0EwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDa DuaZjc6j40+Kfvvxi4Mla+pIH/EqsLmVEQS98GPR4mdmzxzdzxtIK+6NiY6arymAZavpxy0Sy6sc THAHoT0KMM0VjU/43dSMUBUc71DuxC73/OlS8pF94G3VNTCOXkNz8kHp1Wrjsok6Vjk4bwY8iGlb Kk3Fp1S4bInMm/k8yuX9ifUSPJJ4ltbcdG6TRGHRjcdGsnUOhugZitVtbNV4FpWi6cgKOOvyJBNP c1STE4U6G7weNLWLBYy5d4ux2x8gkasJU26Qzns3dLlwR5EiUWMWea6xrkEmCMgZK9FGqkjWZCrX gzT/LCrBbBlDSgeF59N89iFo7+ryUp9/k5DPAgMBAAGjQjBAMA4GA1UdDwEB/wQEAwIBBjAPBgNV HRMBAf8EBTADAQH/MB0GA1UdDgQWBBRge2YaRQ2XyolQL30EzTSo//z9SzANBgkqhkiG9w0BAQUF AAOCAQEA1nPnfE920I2/7LqivjTFKDK1fPxsnCwrvQmeU79rXqoRSLblCKOzyj1hTdNGCbM+w6Dj Y1Ub8rrvrTnhQ7k4o+YviiY776BQVvnGCv04zcQLcFGUl5gE38NflNUVyRRBnMRddWQVDf9VMOyG j/8N7yy5Y0b2qvzfvGn9LhJIZJrglfCm7ymPAbEVtQwdpf5pLGkkeB6zpxxxYu7KyJesF12KwvhH hm4qxFYxldBniYUr+WymXUadDKqC5JlR3XC321Y9YeRq4VzW9v493kHMB65jUr9TU/Qr6cf9tveC X4XSQRjbgbMEHMUfpIBvFSDJ3gyICh3WZlXi/EjJKSZp4A== -----END CERTIFICATE-----

chrisd1100 avatar Aug 10 '21 12:08 chrisd1100

The main idea is to have the ability to pin a public key, not the whole certificate.

On the implementation side, I actually have troubles finding how to provide a custom CA list with WinHttp. There is WINHTTP_OPTION_SERVER_CERT_CHAIN_CONTEXT that can be used to get the server chain and actually implement the pinning. But I don't see how the CA list could be provided.

roman-mazur avatar Aug 10 '21 16:08 roman-mazur

Another argument for passing the TLS context object (or something similar) in HTTP and websocket functions is that such an interface allows you to send requests with a client certificate.

@chrisd1100 let me know if you think this approach does not make sense

roman-mazur avatar Aug 13 '21 07:08 roman-mazur

In the coming months, we're switching HTTP/WebSocket behavior under the hood which may improve this issue, or at least will make us have to rethink this interface. If you care to revisit, let's pick it back up when the phase3 branch is merged.

chrisd1100 avatar Feb 11 '23 13:02 chrisd1100