Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[System]: Epic: Client Certificate Support - Part One. #8756

Merged
merged 6 commits into from
May 24, 2018

Conversation

baulig
Copy link
Contributor

@baulig baulig commented May 17, 2018

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

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.
@baulig baulig self-assigned this May 17, 2018
baulig pushed a commit to baulig/mono that referenced this pull request May 18, 2018
This is the second and final part and it should be landed on top of mono#8756.

* `Mono.Security.Interface.IMonoSslStream`: Add `CanRenegotiate` and `RenegotiateAsync()`.

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

* `AppleTlsContext`: fully support renegotiation.
  - we may now receive `SslStatus.PeerAuthCompleted` and `SslStatus.PeerClientCertRequested`
    during `Read()`.  It should in theory not happen during `Write()`, but I added it there
    as well just to be on the safe side.
  - `SetSessionOption()` may only be called before the initial handshake.

* `MobileAuthenticatedStream`: this is the major part of the work and the most complex one.
  - added a new `Operation` enum to keep track of what is going on and detect invalid state.
  - a renegotion may only be triggered while we're idle - that is no handshake, read or write
    operation is currently active.
  - `InternalWrite()` may now be called from `SSLRead()`, the new `Operation` tells us what
    is currently happening.
  - `ProcessHandshake()` now takes a `bool renegotiate` argument.
  - added sanity checks to `ProcessRead()` and `ProcessWrite()`.

* `MobileTlsContext.SelectClientCertificate()`: check for
  `MonoTlsSettings.DisallowUnauthenticatedCertificateRequest`
baulig pushed a commit to baulig/mono that referenced this pull request May 18, 2018
This is the second and final part to bring Client Certificate support.
It needs to be landed on top of mono#8753 and mono#8756.

* `Mono.Security.Interface.IMonoSslStream`: Add `CanRenegotiate` and `RenegotiateAsync()`.

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

* `AppleTlsContext`: fully support renegotiation.
  - we may now receive `SslStatus.PeerAuthCompleted` and `SslStatus.PeerClientCertRequested`
    during `Read()`.  It should in theory not happen during `Write()`, but I added it there
    as well just to be on the safe side.
  - `SetSessionOption()` may only be called before the initial handshake.

* `MobileAuthenticatedStream`: this is the major part of the work and the most complex one.
  - added a new `Operation` enum to keep track of what is going on and detect invalid state.
  - a renegotion may only be triggered while we're idle - that is no handshake, read or write
    operation is currently active.
  - `InternalWrite()` may now be called from `SSLRead()`, the new `Operation` tells us what
    is currently happening.
  - `ProcessHandshake()` now takes a `bool renegotiate` argument.
  - added sanity checks to `ProcessRead()` and `ProcessWrite()`.

* `MobileTlsContext.SelectClientCertificate()`: check for
  `MonoTlsSettings.DisallowUnauthenticatedCertificateRequest`

* `MonoTlsProviderFactory.InternalVersion`: bump the internal version number.

Tests have already been added to `web-tests/master`, they will auto-enable themselves when
using a Mono runtime that contains this code.
@baulig baulig mentioned this pull request May 18, 2018
9 tasks
@baulig
Copy link
Contributor Author

baulig commented May 22, 2018

@monojenkins commit apidiff

monojenkins added a commit to mono/api-snapshot that referenced this pull request May 22, 2018
@baulig baulig requested a review from luhenry as a code owner May 22, 2018 16:30
@@ -56,6 +56,9 @@ static class MonoBtlsError
[DllImport (MonoBtlsObject.BTLS_DYLIB)]
extern static void mono_btls_error_get_error_string_n (int error, IntPtr buf, int len);

[DllImport (MonoBtlsObject.BTLS_DYLIB)]
extern static int mono_btls_error_get_reason (int error);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should bump mscorlib (to ensure unmanaged bits don't get out of sync)

akoeplinger pushed a commit to mono/api-snapshot that referenced this pull request May 24, 2018
@akoeplinger akoeplinger merged commit 0c2e513 into mono:master May 24, 2018
baulig pushed a commit to baulig/mono that referenced this pull request May 24, 2018
This is the second and final part to bring Client Certificate support.
It needs to be landed on top of mono#8753 and mono#8756.

* `Mono.Security.Interface.IMonoSslStream`: Add `CanRenegotiate` and `RenegotiateAsync()`.

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

* `AppleTlsContext`: fully support renegotiation.
  - we may now receive `SslStatus.PeerAuthCompleted` and `SslStatus.PeerClientCertRequested`
    during `Read()`.  It should in theory not happen during `Write()`, but I added it there
    as well just to be on the safe side.
  - `SetSessionOption()` may only be called before the initial handshake.

* `MobileAuthenticatedStream`: this is the major part of the work and the most complex one.
  - added a new `Operation` enum to keep track of what is going on and detect invalid state.
  - a renegotion may only be triggered while we're idle - that is no handshake, read or write
    operation is currently active.
  - `InternalWrite()` may now be called from `SSLRead()`, the new `Operation` tells us what
    is currently happening.
  - `ProcessHandshake()` now takes a `bool renegotiate` argument.
  - added sanity checks to `ProcessRead()` and `ProcessWrite()`.

* `MobileTlsContext.SelectClientCertificate()`: check for
  `MonoTlsSettings.DisallowUnauthenticatedCertificateRequest`

* `MonoTlsProviderFactory.InternalVersion`: bump the internal version number.

Tests have already been added to `web-tests/master`, they will auto-enable themselves when
using a Mono runtime that contains this code.
baulig pushed a commit to baulig/mono that referenced this pull request May 24, 2018
This is the second and final part to bring Client Certificate support.
It needs to be landed on top of mono#8753 and mono#8756.

* `Mono.Security.Interface.IMonoSslStream`: Add `CanRenegotiate` and `RenegotiateAsync()`.

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

* `AppleTlsContext`: fully support renegotiation.
  - we may now receive `SslStatus.PeerAuthCompleted` and `SslStatus.PeerClientCertRequested`
    during `Read()`.  It should in theory not happen during `Write()`, but I added it there
    as well just to be on the safe side.
  - `SetSessionOption()` may only be called before the initial handshake.

* `MobileAuthenticatedStream`: this is the major part of the work and the most complex one.
  - added a new `Operation` enum to keep track of what is going on and detect invalid state.
  - a renegotion may only be triggered while we're idle - that is no handshake, read or write
    operation is currently active.
  - `InternalWrite()` may now be called from `SSLRead()`, the new `Operation` tells us what
    is currently happening.
  - `ProcessHandshake()` now takes a `bool renegotiate` argument.
  - added sanity checks to `ProcessRead()` and `ProcessWrite()`.

* `MobileTlsContext.SelectClientCertificate()`: check for
  `MonoTlsSettings.DisallowUnauthenticatedCertificateRequest`

* `MonoTlsProviderFactory.InternalVersion`: bump the internal version number.

Tests have already been added to `web-tests/master`, they will auto-enable themselves when
using a Mono runtime that contains this code.
@baulig baulig deleted the epic-client-certificates-part-one branch May 24, 2018 20:19
marek-safar pushed a commit that referenced this pull request May 25, 2018
This is the second and final part to bring Client Certificate support.
It needs to be landed on top of #8753 and #8756.

* `Mono.Security.Interface.IMonoSslStream`: Add `CanRenegotiate` and `RenegotiateAsync()`.

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

* `AppleTlsContext`: fully support renegotiation.
  - we may now receive `SslStatus.PeerAuthCompleted` and `SslStatus.PeerClientCertRequested`
    during `Read()`.  It should in theory not happen during `Write()`, but I added it there
    as well just to be on the safe side.
  - `SetSessionOption()` may only be called before the initial handshake.

* `MobileAuthenticatedStream`: this is the major part of the work and the most complex one.
  - added a new `Operation` enum to keep track of what is going on and detect invalid state.
  - a renegotion may only be triggered while we're idle - that is no handshake, read or write
    operation is currently active.
  - `InternalWrite()` may now be called from `SSLRead()`, the new `Operation` tells us what
    is currently happening.
  - `ProcessHandshake()` now takes a `bool renegotiate` argument.
  - added sanity checks to `ProcessRead()` and `ProcessWrite()`.

* `MobileTlsContext.SelectClientCertificate()`: check for
  `MonoTlsSettings.DisallowUnauthenticatedCertificateRequest`

* `MonoTlsProviderFactory.InternalVersion`: bump the internal version number.

Tests have already been added to `web-tests/master`, they will auto-enable themselves when
using a Mono runtime that contains this code.
picenka21 pushed a commit to picenka21/runtime that referenced this pull request Feb 18, 2022
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 mono/mono#7075

Commit migrated from mono/mono@0c2e513
picenka21 pushed a commit to picenka21/runtime that referenced this pull request Feb 18, 2022
This is the second and final part to bring Client Certificate support.
It needs to be landed on top of mono/mono#8753 and mono/mono#8756.

* `Mono.Security.Interface.IMonoSslStream`: Add `CanRenegotiate` and `RenegotiateAsync()`.

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

* `AppleTlsContext`: fully support renegotiation.
  - we may now receive `SslStatus.PeerAuthCompleted` and `SslStatus.PeerClientCertRequested`
    during `Read()`.  It should in theory not happen during `Write()`, but I added it there
    as well just to be on the safe side.
  - `SetSessionOption()` may only be called before the initial handshake.

* `MobileAuthenticatedStream`: this is the major part of the work and the most complex one.
  - added a new `Operation` enum to keep track of what is going on and detect invalid state.
  - a renegotion may only be triggered while we're idle - that is no handshake, read or write
    operation is currently active.
  - `InternalWrite()` may now be called from `SSLRead()`, the new `Operation` tells us what
    is currently happening.
  - `ProcessHandshake()` now takes a `bool renegotiate` argument.
  - added sanity checks to `ProcessRead()` and `ProcessWrite()`.

* `MobileTlsContext.SelectClientCertificate()`: check for
  `MonoTlsSettings.DisallowUnauthenticatedCertificateRequest`

* `MonoTlsProviderFactory.InternalVersion`: bump the internal version number.

Tests have already been added to `web-tests/master`, they will auto-enable themselves when
using a Mono runtime that contains this code.


Commit migrated from mono/mono@5715aee
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

4 participants