udap_security_test_kit 0.10.0 → 0.10.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/lib/udap_security_test_kit/authorization_code_group.rb +4 -0
- data/lib/udap_security_test_kit/authorization_code_redirect_test.rb +44 -3
- data/lib/udap_security_test_kit/authorization_code_token_exchange_test.rb +0 -2
- data/lib/udap_security_test_kit/client_credentials_group.rb +4 -0
- data/lib/udap_security_test_kit/dynamic_client_registration_group.rb +27 -7
- data/lib/udap_security_test_kit/redirect_uri.rb +3 -0
- data/lib/udap_security_test_kit/registration_success_contents_test.rb +18 -7
- data/lib/udap_security_test_kit/registration_success_test.rb +15 -1
- data/lib/udap_security_test_kit/software_statement_builder.rb +2 -1
- data/lib/udap_security_test_kit/version.rb +1 -1
- data/lib/udap_security_test_kit.rb +10 -1
- metadata +5 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 99975cd9d20b91185600d35dca498008f7bd4dc7cb1ae66eb59c572298f55ab0
|
4
|
+
data.tar.gz: 0ff38d8f44564d5fa998e1801f5dd9255613e7060ea78802194cdf8560c39596
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 456628c19deb09f55ab5494e719d0045ea8a19ed93e314a4e75810d688e8f0d18acb1bf1c2261750b03bd6e1128720d662c80802686ddb4cd4a2e52e40868136
|
7
|
+
data.tar.gz: 9a60fd1649675528705afe7a52f3d9057f411001fee1d641e9fffbd0995aad6ea6395dcb5a1d1e9ba6cd215fc5569cc78779663df479f5d67e967b66262c195c
|
@@ -49,6 +49,9 @@ module UDAPSecurityTestKit
|
|
49
49
|
default: 'authorization_code',
|
50
50
|
locked: true
|
51
51
|
},
|
52
|
+
udap_client_registration_status: {
|
53
|
+
name: :udap_auth_code_flow_client_registration_status
|
54
|
+
},
|
52
55
|
udap_client_cert_pem: {
|
53
56
|
name: :udap_auth_code_flow_client_cert_pem,
|
54
57
|
title: 'Authorization Code Client Certificate(s) (PEM Format)'
|
@@ -90,6 +93,7 @@ module UDAPSecurityTestKit
|
|
90
93
|
} do
|
91
94
|
input_order :udap_registration_endpoint,
|
92
95
|
:udap_auth_code_flow_registration_grant_type,
|
96
|
+
:udap_auth_code_flow_client_registration_status,
|
93
97
|
:udap_auth_code_flow_client_cert_pem,
|
94
98
|
:udap_auth_code_flow_client_private_key,
|
95
99
|
:udap_auth_code_flow_cert_iss,
|
@@ -1,3 +1,4 @@
|
|
1
|
+
require_relative '../udap_security_test_kit'
|
1
2
|
module UDAPSecurityTestKit
|
2
3
|
class AuthorizationCodeRedirectTest < Inferno::Test
|
3
4
|
title 'Authorization server redirects client to redirect URI'
|
@@ -8,6 +9,10 @@ module UDAPSecurityTestKit
|
|
8
9
|
the provided client redirection URI using an HTTP redirection response.
|
9
10
|
)
|
10
11
|
|
12
|
+
input :udap_fhir_base_url,
|
13
|
+
title: 'FHIR Server Base URL',
|
14
|
+
description: 'Base FHIR URL of FHIR Server.'
|
15
|
+
|
11
16
|
input :udap_authorization_endpoint,
|
12
17
|
title: 'Authorization Endpoint',
|
13
18
|
description: 'The full URL from which Inferno will request an authorization code.'
|
@@ -16,12 +21,37 @@ module UDAPSecurityTestKit
|
|
16
21
|
title: 'Client ID',
|
17
22
|
description: 'Client ID as registered with the authorization server.'
|
18
23
|
|
24
|
+
input :udap_authorization_code_request_scopes,
|
25
|
+
title: 'Scope Parameter for Authorization Request',
|
26
|
+
description: %(
|
27
|
+
A list of space-separated scopes to include in the authorization request. If included, these may be equal
|
28
|
+
to or a subset of the scopes requested during registration.
|
29
|
+
If empty, scope will be omitted as a parameter to the authorization endpoint.
|
30
|
+
),
|
31
|
+
optional: true
|
32
|
+
|
33
|
+
input :udap_authorization_code_request_aud,
|
34
|
+
title: "Audience ('aud') Parameter for Authorization Request",
|
35
|
+
type: 'checkbox',
|
36
|
+
options: {
|
37
|
+
list_options: [
|
38
|
+
{
|
39
|
+
label: "Include 'aud' parameter",
|
40
|
+
value: 'include_aud'
|
41
|
+
}
|
42
|
+
]
|
43
|
+
},
|
44
|
+
description: %(
|
45
|
+
If selected, the Base FHIR URL will be used as the 'aud' parameter in the request to the authorization
|
46
|
+
endpoint.
|
47
|
+
),
|
48
|
+
optional: true
|
49
|
+
|
19
50
|
output :udap_authorization_code_state
|
51
|
+
output :udap_authorization_redirect_url
|
20
52
|
|
21
53
|
receives_request :redirect
|
22
54
|
|
23
|
-
config options: { redirect_uri: "#{Inferno::Application['base_url']}/custom/udap_security_test_kit/redirect" }
|
24
|
-
|
25
55
|
def wait_message(auth_url)
|
26
56
|
if config.options[:redirect_message_proc].present?
|
27
57
|
return instance_exec(auth_url, &config.options[:redirect_message_proc])
|
@@ -49,13 +79,22 @@ module UDAPSecurityTestKit
|
|
49
79
|
end
|
50
80
|
|
51
81
|
run do
|
82
|
+
assert_valid_http_uri(
|
83
|
+
udap_authorization_endpoint,
|
84
|
+
"UDAP authorization endpoint '#{udap_authorization_endpoint}' is not a valid URI"
|
85
|
+
)
|
86
|
+
|
52
87
|
output udap_authorization_code_state: SecureRandom.uuid
|
53
88
|
|
89
|
+
aud = udap_fhir_base_url if udap_authorization_code_request_aud.include? 'include_aud'
|
90
|
+
|
54
91
|
oauth2_params = {
|
55
92
|
'response_type' => 'code',
|
56
93
|
'client_id' => udap_client_id,
|
57
94
|
'redirect_uri' => config.options[:redirect_uri],
|
58
|
-
'state' => udap_authorization_code_state
|
95
|
+
'state' => udap_authorization_code_state,
|
96
|
+
'scope' => udap_authorization_code_request_scopes,
|
97
|
+
'aud' => aud
|
59
98
|
}.compact
|
60
99
|
|
61
100
|
authorization_url = authorization_url_builder(
|
@@ -65,6 +104,8 @@ module UDAPSecurityTestKit
|
|
65
104
|
|
66
105
|
info("Inferno redirecting browser to #{authorization_url}.")
|
67
106
|
|
107
|
+
output udap_authorization_redirect_url: authorization_url
|
108
|
+
|
68
109
|
wait(
|
69
110
|
identifier: udap_authorization_code_state,
|
70
111
|
message: wait_message(authorization_url)
|
@@ -62,8 +62,6 @@ module UDAPSecurityTestKit
|
|
62
62
|
|
63
63
|
makes_request :token_exchange
|
64
64
|
|
65
|
-
config options: { redirect_uri: "#{Inferno::Application['base_url']}/custom/udap_security_test_kit/redirect" }
|
66
|
-
|
67
65
|
run do
|
68
66
|
client_assertion_payload = UDAPClientAssertionPayloadBuilder.build(
|
69
67
|
udap_client_id,
|
@@ -51,6 +51,9 @@ module UDAPSecurityTestKit
|
|
51
51
|
default: 'client_credentials',
|
52
52
|
locked: true
|
53
53
|
},
|
54
|
+
udap_client_registration_status: {
|
55
|
+
name: :udap_client_credentials_flow_client_registration_status
|
56
|
+
},
|
54
57
|
udap_client_cert_pem: {
|
55
58
|
name: :udap_client_credentials_flow_client_cert_pem,
|
56
59
|
title: 'Client Credentials Client Certificate(s) (PEM Format)'
|
@@ -92,6 +95,7 @@ module UDAPSecurityTestKit
|
|
92
95
|
} do
|
93
96
|
input_order :udap_registration_endpoint,
|
94
97
|
:udap_client_credentials_flow_registration_grant_type,
|
98
|
+
:udap_client_credentials_flow_client_registration_status,
|
95
99
|
:udap_client_credentials_flow_client_cert_pem,
|
96
100
|
:udap_client_credentials_flow_client_private_key,
|
97
101
|
:udap_cert_iss_client_creds_flow,
|
@@ -19,13 +19,12 @@ module UDAPSecurityTestKit
|
|
19
19
|
establish a trust chain.
|
20
20
|
|
21
21
|
Cancelling a UDAP client's registration is not a required server capability and as such the Inferno client has no
|
22
|
-
way of resetting state on the authorization server after a successful registration attempt.
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
- Provide a different client certificate and its associated URI to register a new logical client
|
22
|
+
way of resetting state on the authorization server after a successful registration attempt. If a given
|
23
|
+
certificate and issuer URI identity combination has already been registered with the authorization server, testers
|
24
|
+
whose systems support registration modifications
|
25
|
+
may select the "Update Registration" option under Client Registration Status. This option will accept either a
|
26
|
+
`200 OK` or `201 Created` return status. Registration attempts for a new client may only return `201 Created`,
|
27
|
+
per the [IG](https://hl7.org/fhir/us/udap-security/STU1/registration.html#request-body).
|
29
28
|
)
|
30
29
|
end
|
31
30
|
|
@@ -57,6 +56,27 @@ module UDAPSecurityTestKit
|
|
57
56
|
]
|
58
57
|
}
|
59
58
|
|
59
|
+
input :udap_client_registration_status,
|
60
|
+
title: 'Client Registration Status',
|
61
|
+
description: %(
|
62
|
+
If the client's iss and certificate combination has already been registered with the authorization server
|
63
|
+
prior to this test run, select 'Update'.
|
64
|
+
),
|
65
|
+
type: 'radio',
|
66
|
+
options: {
|
67
|
+
list_options: [
|
68
|
+
{
|
69
|
+
label: 'New Registration (201 Response Code Expected)',
|
70
|
+
value: 'new'
|
71
|
+
},
|
72
|
+
{
|
73
|
+
label: 'Update Registration (200 or 201 Response Code Expected)',
|
74
|
+
value: 'update'
|
75
|
+
}
|
76
|
+
]
|
77
|
+
},
|
78
|
+
default: 'new'
|
79
|
+
|
60
80
|
input :udap_client_cert_pem,
|
61
81
|
title: 'X.509 Client Certificate(s) (PEM Format)',
|
62
82
|
description: %(
|
@@ -15,14 +15,25 @@ module UDAPSecurityTestKit
|
|
15
15
|
> use by the Client App, the software statement as submitted by the Client App, and all of the registration
|
16
16
|
> related parameters that were included in the software statement.
|
17
17
|
|
18
|
+
[UDAP STU 1.1](https://hl7.org/fhir/us/udap-security/STU1.1/registration.html#request-body) clarifies that,
|
19
|
+
in accordance with [Section 3.2.1 of RFC 7591](https://datatracker.ietf.org/doc/html/rfc7591#section-3.2.1):
|
20
|
+
> The authorization server MAY reject or replace any of the client's requested metadata values submitted during
|
21
|
+
> the registration and substitute them with suitable values.
|
22
|
+
|
18
23
|
This test verifies:
|
19
|
-
- `client_id` claim is
|
20
|
-
- `
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
24
|
+
- `client_id` claim is present in the registration response and its value is not blank.
|
25
|
+
- `scope` and `client_name` claims are present in the registration response and their values are not blank.
|
26
|
+
- `software_statement`, `grant_types`, and `token_endpoint_auth_method` claims are present in the registration
|
27
|
+
response and their values match those in the originally submitted software statement.
|
28
|
+
- If the registered grant type is `authorization_code`, then the `redirect_uris` and `response_type` claims are
|
29
|
+
present in the registration response and their values match in the originally submitted software statement.
|
30
|
+
|
31
|
+
In order for downstream tests to succeed, it is
|
32
|
+
essential that the client and server are in agreement on the values of most of the software statement
|
33
|
+
parameters. The exception is `client_name`, which does not impact behavior. For this reason, an exact match
|
34
|
+
between the request and response values for `client_name` is not required.
|
35
|
+
Additionally, an exact match between `scope` request and response value is also not required because the
|
36
|
+
authorization server may grant different scopes than those orignally requested by the client.
|
26
37
|
)
|
27
38
|
|
28
39
|
input :udap_software_statement_json
|
@@ -13,6 +13,14 @@ module UDAPSecurityTestKit
|
|
13
13
|
The [UDAP IG Section 3.2.3](https://hl7.org/fhir/us/udap-security/STU1/registration.html#request-body) states:
|
14
14
|
> If a new registration is successful, the Authorization Server SHALL return a registration response with a 201
|
15
15
|
> Created HTTP response code as per Section 5.1 of UDAP Dynamic Client Registration
|
16
|
+
|
17
|
+
If the tester indicated this registration attempt represents a modification of an existing registration entry,
|
18
|
+
the [UDAP IG Section 3.4](https://hl7.org/fhir/us/udap-security/STU1/registration.html#modifying-and-cancelling-registrations)
|
19
|
+
states:
|
20
|
+
> If the Authorization Server returns the same client_id in the registration response for a modification request,
|
21
|
+
> it SHOULD also return a 200 OK HTTP response code.
|
22
|
+
|
23
|
+
In this case, the test will require either a 201 or 200 response code to pass.
|
16
24
|
)
|
17
25
|
|
18
26
|
input :udap_client_cert_pem
|
@@ -20,6 +28,7 @@ module UDAPSecurityTestKit
|
|
20
28
|
input :udap_cert_iss
|
21
29
|
|
22
30
|
input :udap_registration_endpoint
|
31
|
+
input :udap_client_registration_status
|
23
32
|
input :udap_jwt_signing_alg
|
24
33
|
input :udap_registration_requested_scope
|
25
34
|
input :udap_registration_grant_type
|
@@ -60,7 +69,12 @@ module UDAPSecurityTestKit
|
|
60
69
|
|
61
70
|
post(udap_registration_endpoint, body: reg_body, headers: reg_headers)
|
62
71
|
|
63
|
-
|
72
|
+
if udap_client_registration_status == 'new'
|
73
|
+
assert_response_status(201)
|
74
|
+
elsif udap_client_registration_status == 'update'
|
75
|
+
assert_response_status([200, 201])
|
76
|
+
end
|
77
|
+
|
64
78
|
assert_valid_json(response[:body])
|
65
79
|
output udap_registration_response: response[:body]
|
66
80
|
end
|
@@ -1,10 +1,11 @@
|
|
1
1
|
require 'jwt'
|
2
|
+
require_relative 'redirect_uri'
|
2
3
|
|
3
4
|
module UDAPSecurityTestKit
|
4
5
|
class SoftwareStatementBuilder
|
5
6
|
def self.build_payload(iss, aud, grant_type, scope)
|
6
7
|
if grant_type == 'authorization_code'
|
7
|
-
redirect_uris = [
|
8
|
+
redirect_uris = [UDAPSecurityTestKit::UDAP_REDIRECT_URI]
|
8
9
|
response_types = ['code']
|
9
10
|
client_name = 'Inferno UDAP Authorization Code Test Client'
|
10
11
|
elsif grant_type == 'client_credentials'
|
@@ -1,6 +1,7 @@
|
|
1
1
|
require_relative 'udap_security_test_kit/authorization_code_group'
|
2
2
|
require_relative 'udap_security_test_kit/client_credentials_group'
|
3
3
|
require_relative 'udap_security_test_kit/version'
|
4
|
+
require_relative 'udap_security_test_kit/redirect_uri'
|
4
5
|
|
5
6
|
module UDAPSecurityTestKit
|
6
7
|
class Suite < Inferno::TestSuite
|
@@ -17,7 +18,8 @@ module UDAPSecurityTestKit
|
|
17
18
|
2. Dynamic Client Registration
|
18
19
|
3. Authorization & Authentication
|
19
20
|
|
20
|
-
|
21
|
+
In this test suite, Inferno acts as a mock UDAP client to test *server conformance* to the HL7 UDAP IG. Tests are
|
22
|
+
grouped according to the OAuth2.0 flow used in the authorization and authentication step:
|
21
23
|
1. Authorization Code flow, which supports
|
22
24
|
[Consumer-Facing](https://hl7.org/fhir/us/udap-security/STU1/consumer.html) or [Business-to-Business (B2B)](https://hl7.org/fhir/us/udap-security/STU1/b2b.html)
|
23
25
|
use cases
|
@@ -25,6 +27,9 @@ module UDAPSecurityTestKit
|
|
25
27
|
[B2B](https://hl7.org/fhir/us/udap-security/STU1/b2b.html) use case
|
26
28
|
|
27
29
|
Testers may test one or both flows based on their system under test.
|
30
|
+
|
31
|
+
This test suite does NOT assess [Tiered OAuth for User Authentication](https://hl7.org/fhir/us/udap-security/STU1/user.html)
|
32
|
+
(which is not a required capability) or client conformance to the HL7 UDAP IG.
|
28
33
|
)
|
29
34
|
|
30
35
|
input_instructions %(
|
@@ -57,6 +62,10 @@ module UDAPSecurityTestKit
|
|
57
62
|
request.query_parameters['state']
|
58
63
|
end
|
59
64
|
|
65
|
+
config options: {
|
66
|
+
redirect_uri: UDAPSecurityTestKit::UDAP_REDIRECT_URI
|
67
|
+
}
|
68
|
+
|
60
69
|
links [
|
61
70
|
{
|
62
71
|
label: 'Report Issue',
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: udap_security_test_kit
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.10.
|
4
|
+
version: 0.10.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Stephen MacVicar
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2024-
|
12
|
+
date: 2024-12-20 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: inferno_core
|
@@ -17,14 +17,14 @@ dependencies:
|
|
17
17
|
requirements:
|
18
18
|
- - ">="
|
19
19
|
- !ruby/object:Gem::Version
|
20
|
-
version: 0.
|
20
|
+
version: 0.5.1
|
21
21
|
type: :runtime
|
22
22
|
prerelease: false
|
23
23
|
version_requirements: !ruby/object:Gem::Requirement
|
24
24
|
requirements:
|
25
25
|
- - ">="
|
26
26
|
- !ruby/object:Gem::Version
|
27
|
-
version: 0.
|
27
|
+
version: 0.5.1
|
28
28
|
- !ruby/object:Gem::Dependency
|
29
29
|
name: jwt
|
30
30
|
requirement: !ruby/object:Gem::Requirement
|
@@ -67,6 +67,7 @@ files:
|
|
67
67
|
- lib/udap_security_test_kit/dynamic_client_registration_group.rb
|
68
68
|
- lib/udap_security_test_kit/generate_client_certs_test.rb
|
69
69
|
- lib/udap_security_test_kit/grant_types_supported_field_test.rb
|
70
|
+
- lib/udap_security_test_kit/redirect_uri.rb
|
70
71
|
- lib/udap_security_test_kit/reg_endpoint_jwt_signing_alg_values_supported_field_test.rb
|
71
72
|
- lib/udap_security_test_kit/registration_endpoint_field_test.rb
|
72
73
|
- lib/udap_security_test_kit/registration_failure_invalid_contents_test.rb
|