[System]: Epic: Client Certificate Support - Part One. (#8756)
commit0c2e5133d33549d0b14f06043672b429c9e76ec5
authorMartin Baulig <mabaul@microsoft.com>
Thu, 24 May 2018 19:12:49 +0000 (24 15:12 -0400)
committerAlexander Köplinger <alex.koeplinger@outlook.com>
Thu, 24 May 2018 19:12:49 +0000 (24 21:12 +0200)
tree3c014ea497a72ad0ce51db9fd8c5f2de924eda85
parentd6af9f7bf76e79131e220c4ea24ef7330dc9189d
[System]: Epic: Client Certificate Support - Part One. (#8756)

This is the first of two Pull Requests to implement Client Certificates :-)

Part One binds the new native APIs that will be used internally, finishes
the certificate selection callbacks, but without the more riskly changes
to the underlying handshake and I/O layer.

Part Two will bring support for TLS Renegotiation - and due to the required
changes in the underlying handshake, it is the more risky one.

* `Mono.Security.Interface.MonoTlsSettings`: Add `ClientCertificateIssuers`.

* `MobileTlsContext`:
  - fully implement `SelectClientCertificate()`; the `acceptableIssuers` parameter
    is now actually set and we also have a reasonable default selection.
  - add `CanRenegotiate` and `RenegotiateAsync()` - these are not hooked up yet.

* `AppleTlsContext`:
  - we will only ever call `RequirePeerTrust()` once per session, so we can
    also remove it alltogether and just use `EvaluatePeerTrust()` instead.
  - use proper exceptions for `SslStatus.PeerNoRenegotiation` and `PeerUnexpectedMsg`.
  - don't call `SetClientSideAuthenticate()` on the client side.
  - bind and hook up `SSLAddDistinguishedName()` and `SSLCopyDistinguishedNames()`.
  - bind `SSLReHandshake()`.

* `MobileAuthenticatedStream`: minor cleanups; there will be more uses of the new
  `GetInvalidNestedCallException()` helper class once Part Two lands.

* Enable some more constants in `SecureTransport.cs`.

* Add new `MonoBtlsError.GetErrorReason()` and `mono_btls_error_get_reason()`
  implementation, only supporting `SSL_R_NO_RENEGOTIATION` at the moment.

* Add new native `mono_btls_ssl_ctx_set_client_ca_list()` function and managed
  `MonoBtlsSslCtx.SetClientCertificateIssuers()`; hooked up via
  `MonoTlsSettings.ClientCertificateIssuers`.

* According to a comment in the header file, `SSL_get_client_CA_list()` may only
  be called during the selection callback or while the handshake is paused.
  To respect this restriction, we now call it during the client certificate
  selection callback and pass the list from native to managed.
  - changed signature of `MonoBtlsSelectFunc` from
    `int (* MonoBtlsSelectFunc) (void *instance)` to
    `int (* MonoBtlsSelectFunc) (void *instance, int countIssuers, const int *sizes, void **issuerData)`.
  - the managed counter-part is in `MonoBtlsSslCtx.NativeSelectFunc` / `NativeSelectCallback`.

* MonoBtlsContext:
  - use the new `MonoBtlsError.GetErrorReason()` to throw a `TlsException` with
    `AlertDescription.NoRenegotiation` that can be checked for by user code.
  - `SelectCallback()` now has a `string[] acceptableIssuers` argument; pass it
    to `SelectClientCertificate()`.
  - the native backend does not support TLS Renegotiation, so `CanRenegotiate`
    always returns false.

Implements #7075
15 files changed:
external/api-snapshot
mcs/class/Mono.Security/Mono.Security.Interface/MonoTlsSettings.cs
mcs/class/System/Mono.AppleTls/AppleTlsContext.cs
mcs/class/System/Mono.AppleTls/SecureTransport.cs
mcs/class/System/Mono.Btls/MonoBtlsContext.cs
mcs/class/System/Mono.Btls/MonoBtlsError.cs
mcs/class/System/Mono.Btls/MonoBtlsSsl.cs
mcs/class/System/Mono.Btls/MonoBtlsSslCtx.cs
mcs/class/System/Mono.Net.Security/LegacySslStream.cs
mcs/class/System/Mono.Net.Security/MobileAuthenticatedStream.cs
mcs/class/System/Mono.Net.Security/MobileTlsContext.cs
mono/btls/btls-error.c
mono/btls/btls-error.h
mono/btls/btls-ssl-ctx.c
mono/btls/btls-ssl-ctx.h