Skip to content

Commit

Permalink
Integrate ca-cert variable into full JWT Authentication flow
Browse files Browse the repository at this point in the history
The ca-cert value contains the X.509 public key certificate or certificate bundle. Each certificate in the bundle should be in PEM (RFC7468) format.
The certificate(s) from the variable is/are replacing default operating system CA certificates bundle during fetching JWK Set from remote URI.
Use the variable in order to establish TLS connection and validate server identity when the server is using self-signed certificate or certificate is signed by 3rd party CA.
  • Loading branch information
sashaCher committed Jan 13, 2022
1 parent 54d0c93 commit 26cf81e
Show file tree
Hide file tree
Showing 5 changed files with 54 additions and 36 deletions.
11 changes: 11 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,17 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.

## [Unreleased]

### Added
- Added an ability to fetch signing keys from JWKS endpoints is using self-signed
certificate or certificate signed by 3rd party CA to JWT generic vendor configuration.
[#2462](https://github.com/cyberark/conjur/pull/2462)
[#2461](https://github.com/cyberark/conjur/pull/2461)
[#2456](https://github.com/cyberark/conjur/pull/2456)
[#2455](https://github.com/cyberark/conjur/pull/2455)
[#2457](https://github.com/cyberark/conjur/pull/2457)
[#2452](https://github.com/cyberark/conjur/pull/2452)
[#2447](https://github.com/cyberark/conjur/pull/2447)

## [1.15.0] - 2021-12-21

### Added
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,7 @@ def fetch_jwks_uri_signing_key
)
@fetch_jwks_uri_signing_key ||= @fetch_jwks_uri_signing_key_class.new(
jwks_uri: signing_key_settings.uri,
cert_store: signing_key_settings.cert_store,
fetch_signing_key: @fetch_signing_key
)
end
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ class FetchJwksUriSigningKey
def initialize(
jwks_uri:,
fetch_signing_key:,
ca_cert: nil,
cert_store: nil,
http_lib: Net::HTTP,
create_jwks_from_http_response: CreateJwksFromHttpResponse.new,
logger: Rails.logger
Expand All @@ -22,7 +22,7 @@ def initialize(

@jwks_uri = jwks_uri
@fetch_signing_key = fetch_signing_key
@ca_cert = ca_cert
@cert_store = cert_store
end

def call(force_fetch:)
Expand Down Expand Up @@ -63,14 +63,14 @@ def jwks_keys
end

def net_http_start(host, port, use_ssl, &block)
if @ca_cert && !use_ssl
if @cert_store && !use_ssl
raise Errors::Authentication::AuthnJwt::FetchJwksKeysFailed.new(
@jwks_uri,
"TLS misconfiguration - ca-cert is provided but jwks-uri URI scheme is http"
)
end

if @ca_cert
if @cert_store
net_http_start_with_ca_cert(host, port, use_ssl, &block)
else
net_http_start_without_ca_cert(host, port, use_ssl, &block)
Expand All @@ -82,7 +82,7 @@ def net_http_start_with_ca_cert(host, port, use_ssl, &block)
host,
port,
use_ssl: use_ssl,
cert_store: @ca_cert,
cert_store: @cert_store,
&block
)
end
Expand Down
64 changes: 35 additions & 29 deletions cucumber/authenticators_jwt/features/authn_jwt_ca_cert.feature
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,7 @@ Feature: JWT Authenticator - ca-cert variable tests
All tests are using status API for validation.

Background:
Given I initialize JWKS endpoint with file "ca-cert.json"
And I load a policy:
Given I load a policy:
"""
- !policy
id: conjur/authn-jwt/raw
Expand All @@ -16,31 +15,33 @@ Feature: JWT Authenticator - ca-cert variable tests
"""

Scenario: ONYX-15311: Self-signed jwks-uri no ca-cert variable
Given I am the super-user
And I successfully set authn-jwt "jwks-uri" variable to value "https://jwks/ca-cert.json"
Given I initialize JWKS endpoint with file "ca-cert-ONYX-15311.json"
And I am the super-user
And I successfully set authn-jwt "jwks-uri" variable to value "https://jwks/ca-cert-ONYX-15311.json"
When I GET "/authn-jwt/raw/cucumber/status"
Then the HTTP response status code is 500
And the authenticator status check fails with error "CONJ00087E Failed to fetch JWKS from 'https://jwks/ca-cert.json'. Reason: '#<OpenSSL::SSL::SSLError: SSL_connect returned=1 errno=0 state=error: certificate verify failed (self signed certificate)>'>"
And the authenticator status check fails with error "CONJ00087E Failed to fetch JWKS from 'https://jwks/ca-cert-ONYX-15311.json'. Reason: '#<OpenSSL::SSL::SSLError: SSL_connect returned=1 errno=0 state=error: certificate verify failed (self signed certificate)>'>"

@skip
@sanity
Scenario: ONYX-15312: Self-signed jwks-uri with valid ca-cert variable value
Given I am the super-user
Given I initialize JWKS endpoint with file "ca-cert-ONYX-15312.json"
And I am the super-user
And I extend the policy with:
"""
- !variable conjur/authn-jwt/raw/ca-cert
"""
And I successfully set authn-jwt "jwks-uri" variable to value "https://jwks/ca-cert.json"
And I successfully set authn-jwt "jwks-uri" variable to value "https://jwks/ca-cert-ONYX-15312.json"
And I fetch root certificate from https://jwks endpoint as "self"
And I successfully set authn-jwt "ca-cert" variable value to the "self" certificate
When I GET "/authn-jwt/raw/cucumber/status"
Then the HTTP response status code is 200
And the HTTP response content type is "application/json"
And the authenticator status check succeeds

@skip
Scenario Outline: ONYX-15313/6: Self-signed jwks-uri with ca-cert contains bundle includes the valid certificate
Given I am the super-user
Given I initialize JWKS endpoint with file "ca-cert-ONYX-15313.json"
And I initialize JWKS endpoint with file "ca-cert-ONYX-15316.json"
And I am the super-user
And I extend the policy with:
"""
- !variable conjur/authn-jwt/raw/ca-cert
Expand All @@ -59,42 +60,38 @@ Feature: JWT Authenticator - ca-cert variable tests
And the HTTP response content type is "application/json"
And the authenticator status check succeeds
Examples:
| jwks-uri |
| https://jwks/ca-cert.json |
| https://chained.mycompany.local/ca-cert.json |
| jwks-uri |
| https://jwks/ca-cert-ONYX-15313.json |
| https://chained.mycompany.local/ca-cert-ONYX-15316.json |

Scenario: ONYX-15314: Chained jwks-uri no ca-cert variable
Given I am the super-user
And I successfully set authn-jwt "jwks-uri" variable to value "https://chained.mycompany.local/ca-cert.json"
Given I initialize JWKS endpoint with file "ca-cert-ONYX-15314.json"
And I am the super-user
And I successfully set authn-jwt "jwks-uri" variable to value "https://chained.mycompany.local/ca-cert-ONYX-15314.json"
When I GET "/authn-jwt/raw/cucumber/status"
Then the HTTP response status code is 500
And the authenticator status check fails with error "CONJ00087E Failed to fetch JWKS from 'https://chained.mycompany.local/ca-cert.json'. Reason: '#<OpenSSL::SSL::SSLError: SSL_connect returned=1 errno=0 state=error: certificate verify failed (self signed certificate in certificate chain)>'>"
And the authenticator status check fails with error "CONJ00087E Failed to fetch JWKS from 'https://chained.mycompany.local/ca-cert-ONYX-15314.json'. Reason: '#<OpenSSL::SSL::SSLError: SSL_connect returned=1 errno=0 state=error: certificate verify failed (self signed certificate in certificate chain)>'>"

@skip
@sanity
Scenario: ONYX-15315: Self-signed jwks-uri with valid ca-cert variable value
Given I am the super-user
Given I initialize JWKS endpoint with file "ca-cert-ONYX-15315.json"
And I am the super-user
And I extend the policy with:
"""
- !variable conjur/authn-jwt/raw/ca-cert
"""
And I successfully set authn-jwt "jwks-uri" variable to value "https://chained.mycompany.local/ca-cert.json"
And I successfully set authn-jwt "jwks-uri" variable to value "https://chained.mycompany.local/ca-cert-ONYX-15315.json"
And I fetch root certificate from https://chained.mycompany.local endpoint as "chained"
And I successfully set authn-jwt "ca-cert" variable value to the "chained" certificate
When I GET "/authn-jwt/raw/cucumber/status"
Then the HTTP response status code is 200
And the HTTP response content type is "application/json"
And the authenticator status check succeeds

Scenario: ONYX-15317: Google's jwks-uri no ca-cert variable
Given I am the super-user
And I successfully set authn-jwt "jwks-uri" variable to value "https://www.googleapis.com/oauth2/v3/certs"
When I GET "/authn-jwt/raw/cucumber/status"
Then the HTTP response status code is 200
And the HTTP response content type is "application/json"
And the authenticator status check succeeds

@skip
# ONYX-15318 and ONYX-15317 are order sensitive tests
# ONYX-15317 stores keys in cash and ONYX-15318 will fail
# if it's running after ONYX-15317
# ONYX-15318 demands conjur restart once ONYX-15317 passed
@sanity
Scenario: ONYX-15318: Google's jwks-uri with invalid ca-cert variable value
Given I am the super-user
Expand All @@ -107,4 +104,13 @@ Feature: JWT Authenticator - ca-cert variable tests
And I successfully set authn-jwt "ca-cert" variable value to the "chained" certificate
When I GET "/authn-jwt/raw/cucumber/status"
Then the HTTP response status code is 500
And the authenticator status check fails with error "CONJ00087E Failed to fetch JWKS from 'https://www.googleapis.com/oauth2/v3/certs'. Reason: '#<OpenSSL::SSL::SSLError: SSL_connect returned=1 errno=0 state=error: certificate verify failed (self signed certificate in certificate chain)>'>"
And the authenticator status check fails with error "CONJ00087E Failed to fetch JWKS from 'https://www.googleapis.com/oauth2/v3/certs'. Reason: '#<OpenSSL::SSL::SSLError: SSL_connect returned=1 errno=0 state=error: certificate verify failed (unable to get local issuer certificate)>'>"

Scenario: ONYX-15317: Google's jwks-uri no ca-cert variable
Given I am the super-user
And I successfully set authn-jwt "jwks-uri" variable to value "https://www.googleapis.com/oauth2/v3/certs"
When I GET "/authn-jwt/raw/cucumber/status"
Then the HTTP response status code is 200
And the HTTP response content type is "application/json"
And the authenticator status check succeeds

Original file line number Diff line number Diff line change
Expand Up @@ -126,7 +126,7 @@
context "when it present" do
subject do
::Authentication::AuthnJwt::SigningKey::FetchJwksUriSigningKey.new(jwks_uri: jwks_uri_https,
ca_cert: cert_store_present,
cert_store: cert_store_present,
fetch_signing_key: mocked_fetch_signing_key,
logger: mocked_logger,
http_lib: mocked_http_response_ca_cert_present,
Expand All @@ -142,7 +142,7 @@
context "when it present but uri is http" do
subject do
::Authentication::AuthnJwt::SigningKey::FetchJwksUriSigningKey.new(jwks_uri: jwks_uri_http,
ca_cert: cert_store_present,
cert_store: cert_store_present,
fetch_signing_key: mocked_fetch_signing_key,
logger: mocked_logger,
http_lib: mocked_http_response_ca_cert_present,
Expand Down

0 comments on commit 26cf81e

Please sign in to comment.