Skip to content

Make it easier to work with server and client certificates in the client #2647

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

Merged
merged 6 commits into from
Mar 22, 2017

Conversation

Mpdreamz
Copy link
Member

@Mpdreamz Mpdreamz commented Mar 2, 2017

Server certificates

Rather then making folks register their ServerCertificateValidation callback globally on the static ServicePointManager or subclass HttpConnection to set it on the request/itself
we now expose it on ConnectionSettings this callback is fired for each unique endpoint (node) until it returns true after which its cached for the duration of that servicepoint.

We also ship with handy baked in validations on CertificateValidations:

  • CertificateValidations.AllowAll simply returns true
  • CertificateValidations.DenyAll simply returns false

If your client application however has access to the public CA certificate locally Elasticsearch.NET/NEST ships with handy helpers that assert that the certificate that the server presented was one that came from our local CA certificate. If you use x-pack's certgen tool to generate SSL certificates the generated node certificate does not include the CA in the certificate chain. This to cut back on SSL handshake size. In those case you can use CertificateValidations.AuthorityIsRoot and pass it your local copy of the CA public key to assert that the certificate the server presented was generated off that.

If you go for a vendor generated SSL certificate its common practice for them to include the CA and any intermediary CA's in the certificate chain in those case use CertificateValidations.AuthorityPartOfChain which validates that the local CA certificate is part of that chain and was used to generate the servers key.

Client certificates

ConnectionSettings now also accepts ClientCertificates as a collection or ClientCertificate as a single certificate to be used as the user authentication for ALL requests.
RequestConfiguration accepts the same but will be the client certificate for that single request only.

The client certificate should be a certificate that has the public and private key available (pfx or p12) however x-pack certgen generates two separate cer and key files.

For .NET 4.5/4.6 we ship with a helper that creates a proper self contained certificate from these two files ClientCertificate.LoadWithPrivateKey but because we can no longer update a
certificates PublicKey algorithm in .NET core the setter is no longer there. Its typically recommended to generate a single pfx or p12 file using openssl or pvk2pfx since those can simply be passed to X509Certificate's constructor directly

Test runner changes

ClusterBase can signal the port it wants to run under, since our test validation clusters need to be isolated each one runs on a different port so that we do not run into cached callbacks.

It can also now indicate the cluster expects to be running under SSL and include its own installation tasks.

These changes need to be hand picked and ported back to 2.x where it makes sense.

@Mpdreamz Mpdreamz force-pushed the feature/easy-certificate-handling branch from 60370a2 to 9ec4a19 Compare March 13, 2017 23:41
Copy link
Contributor

@gmarz gmarz left a comment

Choose a reason for hiding this comment

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

Awesome work @Mpdreamz

### Server certificates

Rather then making folks register their ServerCertificateValidation callback globally on the static `ServicePointManager` or subclass `HttpConnection` to set it on the request/itself
we now expose it on `ConnectionSettings` this callback is fired for each unique endpoint (node) until it returns true after which its cached for the duration of that servicepoint.

We also ship with handy baked in validations on `CertificateValidations`:

* `CertificateValidations.AllowAll` simply returns true
* `CertificateValidations.DenyAll` simply returns false

If your client application however has access to the public CA certificate locally Elasticsearch.NET/NEST ships with handy helpers that assert
that the certificate that the server presented was one that came from our local CA certificate. If you use x-pack's `certgen` tool to
[generate SSL certificates](https://www.elastic.co/guide/en/x-pack/current/ssl-tls.html) the generated node certificate does not include the CA in the
certificate chain. This to cut back on SSL handshake size. In those case you can use `CertificateValidations.AuthorityIsRoot` and pass it your local copy
of the CA public key to assert that the certificate the server presented was generated off that.

If you go for a vendor generated SSL certificate its common practice for them to include the CA and any intermediary CA's in the certificate chain
in those case use `CertificateValidations.AuthorityPartOfChain` which validates that the local CA certificate is part of that chain and was used to
generate the servers key.

### Client certificates

`ConnectionSettings` now also accepts `ClientCertificates` as a collection or `ClientCertificate` as a single certificate to be used as the user authentication for ALL requests.
`RequestConfiguration` accepts the same but will be the client certificate for that single request only.

The client certificate should be a certificate that has the public and private key available (`pfx` or `p12`) however x-pack `certgen` generates two separate `cer` and `key` files.

For .NET 4.5/4.6 we ship with a helper that creates a proper self contained certificate from these two files `ClientCertificate.LoadWithPrivateKey` but because we can no longer update a
certificates `PublicKey` algorithm in .NET core this is not available there. Its typically recommended to generate a single pfx or p12 file since those can just be passed to `X509Certificate`'s
constructor
…rely on a disk on file, also make sure cluster base does not do the desiredport check when running in unit test mode
@Mpdreamz Mpdreamz force-pushed the feature/easy-certificate-handling branch from 9cdd84b to 9066248 Compare March 22, 2017 18:41
@Mpdreamz Mpdreamz merged commit d3ea346 into 5.x Mar 22, 2017
@Mpdreamz Mpdreamz deleted the feature/easy-certificate-handling branch March 22, 2017 18:42
Mpdreamz added a commit that referenced this pull request Mar 22, 2017
…ent (#2647)

* Make it easier to work with server and client certificates in the client

### Server certificates

Rather then making folks register their ServerCertificateValidation callback globally on the static `ServicePointManager` or subclass `HttpConnection` to set it on the request/itself
we now expose it on `ConnectionSettings` this callback is fired for each unique endpoint (node) until it returns true after which its cached for the duration of that servicepoint.

We also ship with handy baked in validations on `CertificateValidations`:

* `CertificateValidations.AllowAll` simply returns true
* `CertificateValidations.DenyAll` simply returns false

If your client application however has access to the public CA certificate locally Elasticsearch.NET/NEST ships with handy helpers that assert
that the certificate that the server presented was one that came from our local CA certificate. If you use x-pack's `certgen` tool to
[generate SSL certificates](https://www.elastic.co/guide/en/x-pack/current/ssl-tls.html) the generated node certificate does not include the CA in the
certificate chain. This to cut back on SSL handshake size. In those case you can use `CertificateValidations.AuthorityIsRoot` and pass it your local copy
of the CA public key to assert that the certificate the server presented was generated off that.

If you go for a vendor generated SSL certificate its common practice for them to include the CA and any intermediary CA's in the certificate chain
in those case use `CertificateValidations.AuthorityPartOfChain` which validates that the local CA certificate is part of that chain and was used to
generate the servers key.

### Client certificates

`ConnectionSettings` now also accepts `ClientCertificates` as a collection or `ClientCertificate` as a single certificate to be used as the user authentication for ALL requests.
`RequestConfiguration` accepts the same but will be the client certificate for that single request only.

The client certificate should be a certificate that has the public and private key available (`pfx` or `p12`) however x-pack `certgen` generates two separate `cer` and `key` files.

For .NET 4.5/4.6 we ship with a helper that creates a proper self contained certificate from these two files `ClientCertificate.LoadWithPrivateKey` but because we can no longer update a
certificates `PublicKey` algorithm in .NET core this is not available there. Its typically recommended to generate a single pfx or p12 file since those can just be passed to `X509Certificate`'s
constructor

* spacing and visibillity changes

* try fix mono build of .net 4.* HttpConnection

* make sure in unit test mode we skip the certificate tests since they rely on a disk on file, also make sure cluster base does not do the desiredport check when running in unit test mode

* only throw when attempting to set callback on mono when callback is not null

* callback not in ifdef scope
@Mpdreamz
Copy link
Member Author

ported to master

Mpdreamz added a commit that referenced this pull request Mar 22, 2017
…ent (#2647)

* Make it easier to work with server and client certificates in the client

Rather then making folks register their ServerCertificateValidation callback globally on the static `ServicePointManager` or subclass `HttpConnection` to set it on the request/itself
we now expose it on `ConnectionSettings` this callback is fired for each unique endpoint (node) until it returns true after which its cached for the duration of that servicepoint.

We also ship with handy baked in validations on `CertificateValidations`:

* `CertificateValidations.AllowAll` simply returns true
* `CertificateValidations.DenyAll` simply returns false

If your client application however has access to the public CA certificate locally Elasticsearch.NET/NEST ships with handy helpers that assert
that the certificate that the server presented was one that came from our local CA certificate. If you use x-pack's `certgen` tool to
[generate SSL certificates](https://www.elastic.co/guide/en/x-pack/current/ssl-tls.html) the generated node certificate does not include the CA in the
certificate chain. This to cut back on SSL handshake size. In those case you can use `CertificateValidations.AuthorityIsRoot` and pass it your local copy
of the CA public key to assert that the certificate the server presented was generated off that.

If you go for a vendor generated SSL certificate its common practice for them to include the CA and any intermediary CA's in the certificate chain
in those case use `CertificateValidations.AuthorityPartOfChain` which validates that the local CA certificate is part of that chain and was used to
generate the servers key.

`ConnectionSettings` now also accepts `ClientCertificates` as a collection or `ClientCertificate` as a single certificate to be used as the user authentication for ALL requests.
`RequestConfiguration` accepts the same but will be the client certificate for that single request only.

The client certificate should be a certificate that has the public and private key available (`pfx` or `p12`) however x-pack `certgen` generates two separate `cer` and `key` files.

For .NET 4.5/4.6 we ship with a helper that creates a proper self contained certificate from these two files `ClientCertificate.LoadWithPrivateKey` but because we can no longer update a
certificates `PublicKey` algorithm in .NET core this is not available there. Its typically recommended to generate a single pfx or p12 file since those can just be passed to `X509Certificate`'s
constructor

* spacing and visibillity changes

* try fix mono build of .net 4.* HttpConnection

* make sure in unit test mode we skip the certificate tests since they rely on a disk on file, also make sure cluster base does not do the desiredport check when running in unit test mode

* only throw when attempting to set callback on mono when callback is not null

* callback not in ifdef scope

Conflicts:
	src/Elasticsearch.Net/Configuration/ConnectionConfiguration.cs
	src/Elasticsearch.Net/Configuration/IConnectionConfigurationValues.cs
	src/Elasticsearch.Net/Configuration/RequestConfiguration.cs
	src/Elasticsearch.Net/Transport/Pipeline/RequestData.cs
	src/Tests/Framework/ManagedElasticsearch/Nodes/ElasticsearchNode.cs
	src/Tests/Tests.csproj
@Mpdreamz
Copy link
Member Author

ported to 2.x but the integration tests are not ported because the setup would be to laborious there without certgen. cc @forloop @gmarz

awelburn pushed a commit to Artesian/elasticsearch-net that referenced this pull request Nov 6, 2017
…ent (elastic#2647)

* Make it easier to work with server and client certificates in the client

### Server certificates

Rather then making folks register their ServerCertificateValidation callback globally on the static `ServicePointManager` or subclass `HttpConnection` to set it on the request/itself
we now expose it on `ConnectionSettings` this callback is fired for each unique endpoint (node) until it returns true after which its cached for the duration of that servicepoint.

We also ship with handy baked in validations on `CertificateValidations`:

* `CertificateValidations.AllowAll` simply returns true
* `CertificateValidations.DenyAll` simply returns false

If your client application however has access to the public CA certificate locally Elasticsearch.NET/NEST ships with handy helpers that assert
that the certificate that the server presented was one that came from our local CA certificate. If you use x-pack's `certgen` tool to
[generate SSL certificates](https://www.elastic.co/guide/en/x-pack/current/ssl-tls.html) the generated node certificate does not include the CA in the
certificate chain. This to cut back on SSL handshake size. In those case you can use `CertificateValidations.AuthorityIsRoot` and pass it your local copy
of the CA public key to assert that the certificate the server presented was generated off that.

If you go for a vendor generated SSL certificate its common practice for them to include the CA and any intermediary CA's in the certificate chain
in those case use `CertificateValidations.AuthorityPartOfChain` which validates that the local CA certificate is part of that chain and was used to
generate the servers key.

### Client certificates

`ConnectionSettings` now also accepts `ClientCertificates` as a collection or `ClientCertificate` as a single certificate to be used as the user authentication for ALL requests.
`RequestConfiguration` accepts the same but will be the client certificate for that single request only.

The client certificate should be a certificate that has the public and private key available (`pfx` or `p12`) however x-pack `certgen` generates two separate `cer` and `key` files.

For .NET 4.5/4.6 we ship with a helper that creates a proper self contained certificate from these two files `ClientCertificate.LoadWithPrivateKey` but because we can no longer update a
certificates `PublicKey` algorithm in .NET core this is not available there. Its typically recommended to generate a single pfx or p12 file since those can just be passed to `X509Certificate`'s
constructor

* spacing and visibillity changes

* try fix mono build of .net 4.* HttpConnection

* make sure in unit test mode we skip the certificate tests since they rely on a disk on file, also make sure cluster base does not do the desiredport check when running in unit test mode

* only throw when attempting to set callback on mono when callback is not null

* callback not in ifdef scope
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants