Skip to content

Commit ddb0f88

Browse files
authored
Initial OpenID4VCI support (#322)
Initial OpenID4VCI support
1 parent e779e59 commit ddb0f88

File tree

115 files changed

+5870
-549
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

115 files changed

+5870
-549
lines changed

composer.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@
3131
"psr/container": "^2.0",
3232
"psr/log": "^3",
3333
"simplesamlphp/composer-module-installer": "^1.3",
34-
"simplesamlphp/openid": "~0.0.18",
34+
"simplesamlphp/openid": "~0.1.0",
3535
"spomky-labs/base64url": "^2.0",
3636
"symfony/expression-language": "^6.3",
3737
"symfony/psr-http-message-bridge": "^7.1",

config/module_oidc.php.dist

Lines changed: 354 additions & 0 deletions
Large diffs are not rendered by default.

docker/apache-override.cf

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
11
RewriteEngine On
22
RewriteRule ^/.well-known/openid-configuration(.*) /${SSP_APACHE_ALIAS}module.php/oidc/.well-known/openid-configuration$1 [PT]
33
RewriteRule ^/.well-known/openid-federation(.*) /${SSP_APACHE_ALIAS}module.php/oidc/.well-known/openid-federation$1 [PT]
4+
RewriteRule ^/.well-known/openid-credential-issuer(.*) /${SSP_APACHE_ALIAS}module.php/oidc/.well-known/openid-credential-issuer$1 [PT]
5+
RewriteRule ^/.well-known/oauth-authorization-server(.*) /${SSP_APACHE_ALIAS}module.php/oidc/.well-known/oauth-authorization-server$1 [PT]
6+
RewriteRule ^/.well-known/jwt-vc-issuer(.*) /${SSP_APACHE_ALIAS}module.php/oidc/.well-known/jwt-vc-issuer$1 [PT]
47

58
# Leave Authorization header with Bearer tokens available in requests.
69
# Solution 1:

docker/conformance.sql

Lines changed: 33 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -43,30 +43,36 @@ CREATE TABLE oidc_client (
4343
updated_at TIMESTAMP NULL DEFAULT NULL,
4444
created_at TIMESTAMP NULL DEFAULT NULL,
4545
expires_at TIMESTAMP NULL DEFAULT NULL,
46-
is_federated BOOLEAN NOT NULL DEFAULT false
46+
is_federated BOOLEAN NOT NULL DEFAULT false,
47+
is_generic BOOLEAN NOT NULL DEFAULT false
4748
);
4849
-- Used 'httpd' host for back-channel logout url (https://httpd:8443/test/a/simplesamlphp-module-oidc/backchannel_logout)
4950
-- since this is the hostname of conformance server while running in container environment
50-
INSERT INTO oidc_client VALUES('_55a99a1d298da921cb27d700d4604352e51171ebc4','_8967dd97d07cc59db7055e84ac00e79005157c1132','Conformance Client 1',replace('Client 1 for Conformance Testing https://openid.net/certification/connect_op_testing/\n','\n',char(10)),'example-userpass','["https:\/\/localhost.emobix.co.uk:8443\/test\/a\/simplesamlphp-module-oidc\/callback","https:\/\/www.certification.openid.net\/test\/a\/simplesamlphp-module-oidc\/callback"]','["openid","profile","email","address","phone","offline_access"]',1,1,NULL,'["https:\/\/localhost.emobix.co.uk:8443\/test\/a\/simplesamlphp-module-oidc\/post_logout_redirect"]','https://httpd:8443/test/a/simplesamlphp-module-oidc/backchannel_logout',NULL,NULL, NULL, NULL, NULL, NULL, 'manual', NULL, NULL, NULL, false);
51-
INSERT INTO oidc_client VALUES('_34efb61060172a11d62101bc804db789f8f9100b0e','_91a4607a1c10ba801268929b961b3f6c067ff82d21','Conformance Client 2','','example-userpass','["https:\/\/localhost.emobix.co.uk:8443\/test\/a\/simplesamlphp-module-oidc\/callback","https:\/\/www.certification.openid.net\/test\/a\/simplesamlphp-module-oidc\/callback"]','["openid","profile","email","offline_access"]',1,1,NULL,NULL,NULL,NULL,NULL, NULL, NULL, NULL, NULL, 'manual', NULL, NULL, NULL, false);
52-
INSERT INTO oidc_client VALUES('_0afb7d18e54b2de8205a93e38ca119e62ee321d031','_944e73bbeec7850d32b68f1b5c780562c955967e4e','Conformance Client 3','Client for client_secret_post','example-userpass','["https:\/\/localhost.emobix.co.uk:8443\/test\/a\/simplesamlphp-module-oidc\/callback","https:\/\/www.certification.openid.net\/test\/a\/simplesamlphp-module-oidc\/callback"]','["openid","profile","email"]',1,1,NULL,NULL,NULL,NULL,NULL, NULL, NULL, NULL, NULL, 'manual', NULL, NULL, NULL, false);
53-
INSERT INTO oidc_client VALUES('_8957eda35234902ba8343c0cdacac040310f17dfca','_322d16999f9da8b5abc9e9c0c08e853f60f4dc4804','RP-Initiated Logout Client','Client for testing RP-Initiated Logout','example-userpass','["https:\/\/localhost.emobix.co.uk:8443\/test\/a\/simplesamlphp-module-oidc\/callback","https:\/\/www.certification.openid.net\/test\/a\/simplesamlphp-module-oidc\/callback"]','["openid","profile","email","address","phone"]',1,1,NULL,'["https:\/\/localhost.emobix.co.uk:8443\/test\/a\/simplesamlphp-module-oidc\/post_logout_redirect"]',NULL,NULL,NULL, NULL, NULL, NULL, NULL, 'manual', NULL, NULL, NULL, false);
54-
INSERT INTO oidc_client VALUES('_9fe2f7589ece1b71f5ef75a91847d71bc5125ec2a6','_3c0beb20194179c01d7796c6836f62801e9ed4b368','Back-Channel Logout Client','Client for testing Back-Channel Logout','example-userpass','["https:\/\/localhost.emobix.co.uk:8443\/test\/a\/simplesamlphp-module-oidc\/callback","https:\/\/www.certification.openid.net\/test\/a\/simplesamlphp-module-oidc\/callback"]','["openid","profile","email","address","phone"]',1,1,NULL,'["https:\/\/localhost.emobix.co.uk:8443\/test\/a\/simplesamlphp-module-oidc\/post_logout_redirect"]','https://httpd:8443/test/a/simplesamlphp-module-oidc/backchannel_logout',NULL,NULL, NULL, NULL, NULL, NULL, 'manual', NULL, NULL, NULL, false);
51+
INSERT INTO oidc_client VALUES('_55a99a1d298da921cb27d700d4604352e51171ebc4','_8967dd97d07cc59db7055e84ac00e79005157c1132','Conformance Client 1',replace('Client 1 for Conformance Testing https://openid.net/certification/connect_op_testing/\n','\n',char(10)),'example-userpass','["https:\/\/localhost.emobix.co.uk:8443\/test\/a\/simplesamlphp-module-oidc\/callback","https:\/\/www.certification.openid.net\/test\/a\/simplesamlphp-module-oidc\/callback"]','["openid","profile","email","address","phone","offline_access"]',1,1,NULL,'["https:\/\/localhost.emobix.co.uk:8443\/test\/a\/simplesamlphp-module-oidc\/post_logout_redirect"]','https://httpd:8443/test/a/simplesamlphp-module-oidc/backchannel_logout',NULL,NULL, NULL, NULL, NULL, NULL, 'manual', NULL, NULL, NULL, false, false);
52+
INSERT INTO oidc_client VALUES('_34efb61060172a11d62101bc804db789f8f9100b0e','_91a4607a1c10ba801268929b961b3f6c067ff82d21','Conformance Client 2','','example-userpass','["https:\/\/localhost.emobix.co.uk:8443\/test\/a\/simplesamlphp-module-oidc\/callback","https:\/\/www.certification.openid.net\/test\/a\/simplesamlphp-module-oidc\/callback"]','["openid","profile","email","offline_access"]',1,1,NULL,NULL,NULL,NULL,NULL, NULL, NULL, NULL, NULL, 'manual', NULL, NULL, NULL, false, false);
53+
INSERT INTO oidc_client VALUES('_0afb7d18e54b2de8205a93e38ca119e62ee321d031','_944e73bbeec7850d32b68f1b5c780562c955967e4e','Conformance Client 3','Client for client_secret_post','example-userpass','["https:\/\/localhost.emobix.co.uk:8443\/test\/a\/simplesamlphp-module-oidc\/callback","https:\/\/www.certification.openid.net\/test\/a\/simplesamlphp-module-oidc\/callback"]','["openid","profile","email"]',1,1,NULL,NULL,NULL,NULL,NULL, NULL, NULL, NULL, NULL, 'manual', NULL, NULL, NULL, false, false);
54+
INSERT INTO oidc_client VALUES('_8957eda35234902ba8343c0cdacac040310f17dfca','_322d16999f9da8b5abc9e9c0c08e853f60f4dc4804','RP-Initiated Logout Client','Client for testing RP-Initiated Logout','example-userpass','["https:\/\/localhost.emobix.co.uk:8443\/test\/a\/simplesamlphp-module-oidc\/callback","https:\/\/www.certification.openid.net\/test\/a\/simplesamlphp-module-oidc\/callback"]','["openid","profile","email","address","phone"]',1,1,NULL,'["https:\/\/localhost.emobix.co.uk:8443\/test\/a\/simplesamlphp-module-oidc\/post_logout_redirect"]',NULL,NULL,NULL, NULL, NULL, NULL, NULL, 'manual', NULL, NULL, NULL, false, false);
55+
INSERT INTO oidc_client VALUES('_9fe2f7589ece1b71f5ef75a91847d71bc5125ec2a6','_3c0beb20194179c01d7796c6836f62801e9ed4b368','Back-Channel Logout Client','Client for testing Back-Channel Logout','example-userpass','["https:\/\/localhost.emobix.co.uk:8443\/test\/a\/simplesamlphp-module-oidc\/callback","https:\/\/www.certification.openid.net\/test\/a\/simplesamlphp-module-oidc\/callback"]','["openid","profile","email","address","phone"]',1,1,NULL,'["https:\/\/localhost.emobix.co.uk:8443\/test\/a\/simplesamlphp-module-oidc\/post_logout_redirect"]','https://httpd:8443/test/a/simplesamlphp-module-oidc/backchannel_logout',NULL,NULL, NULL, NULL, NULL, NULL, 'manual', NULL, NULL, NULL, false, false);
5556
CREATE TABLE oidc_access_token (
5657
id VARCHAR(191) PRIMARY KEY NOT NULL,
5758
scopes TEXT,
5859
expires_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
59-
user_id VARCHAR(191) NOT NULL,
60+
user_id VARCHAR(191) NOT NULL,
6061
client_id VARCHAR(191) NOT NULL,
6162
is_revoked BOOLEAN NOT NULL DEFAULT false,
6263
auth_code_id varchar(191) DEFAULT NULL, requested_claims TEXT NULL,
63-
CONSTRAINT FK_43C1650EA76ED395 FOREIGN KEY (user_id)
64-
REFERENCES oidc_user (id) ON DELETE CASCADE,
65-
CONSTRAINT FK_43C1650E19EB6921 FOREIGN KEY (client_id)
66-
REFERENCES oidc_client (id) ON DELETE CASCADE
64+
flow_type CHAR(64) NULL,
65+
authorization_details TEXT NULL,
66+
bound_client_id TEXT NULL,
67+
bound_redirect_uri TEXT NULL,
68+
issuer_state TEXT NULL,
69+
CONSTRAINT FK_43C1650EA76ED395 FOREIGN KEY (user_id)
70+
REFERENCES oidc_user (id) ON DELETE CASCADE,
71+
CONSTRAINT FK_43C1650E19EB6921 FOREIGN KEY (client_id)
72+
REFERENCES oidc_client (id) ON DELETE CASCADE
6773
);
6874
CREATE TABLE oidc_refresh_token (
69-
id VARCHAR(191) PRIMARY KEY NOT NULL,
75+
id VARCHAR(191) PRIMARY KEY NOT NULL,
7076
expires_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
7177
access_token_id VARCHAR(191) NOT NULL,
7278
is_revoked BOOLEAN NOT NULL DEFAULT false,
@@ -78,14 +84,20 @@ CREATE TABLE oidc_auth_code (
7884
id VARCHAR(191) PRIMARY KEY NOT NULL,
7985
scopes TEXT,
8086
expires_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
81-
user_id VARCHAR(191) NOT NULL,
87+
user_id VARCHAR(191) NOT NULL,
8288
client_id VARCHAR(191) NOT NULL,
8389
is_revoked BOOLEAN NOT NULL DEFAULT false,
8490
redirect_uri TEXT NOT NULL, nonce TEXT NULL,
91+
flow_type CHAR(64) DEFAULT NULL,
92+
tx_code varchar(191) DEFAULT NULL,
93+
authorization_details TEXT NULL,
94+
bound_client_id TEXT NULL,
95+
bound_redirect_uri TEXT NULL,
96+
issuer_state TEXT NULL,
8597
CONSTRAINT FK_97D32CA7A76ED395 FOREIGN KEY (user_id)
86-
REFERENCES oidc_user (id) ON DELETE CASCADE,
98+
REFERENCES oidc_user (id) ON DELETE CASCADE,
8799
CONSTRAINT FK_97D32CA719EB6921 FOREIGN KEY (client_id)
88-
REFERENCES oidc_client (id) ON DELETE CASCADE
100+
REFERENCES oidc_client (id) ON DELETE CASCADE
89101
);
90102
CREATE TABLE oidc_allowed_origin (
91103
client_id varchar(191) NOT NULL,
@@ -98,4 +110,10 @@ CREATE TABLE oidc_session_logout_ticket (
98110
sid VARCHAR(191) NOT NULL,
99111
created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP
100112
);
113+
CREATE TABLE oidc_vci_issuer_state (
114+
value CHAR(64) PRIMARY KEY NOT NULL,
115+
created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
116+
expires_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
117+
is_revoked BOOLEAN NOT NULL DEFAULT false
118+
);
101119
COMMIT;

docs/1-oidc.md

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,26 @@ Currently supported OIDFed features:
3030
OIDFed is implemented using the
3131
[SimpleSAMLphp OpenID library](https://github.com/simplesamlphp/openid).
3232

33+
## Note on OpenID for Verifiable Credential Issuance (OpenID4VCI) support
34+
35+
OpenID4VCI support was done as per draft 15 of the specification and is in the
36+
experimental stage. You should NOT use it in production environments.
37+
38+
Currently implemented OpenID4VCI features:
39+
40+
- Grant types:
41+
- Pre-authorized Code flow (new flow defined by the OpenID4VCI spec)
42+
- Authorization Code flow
43+
- Credential formats:
44+
- jwt_vc_json, using VCDM v1.1
45+
- dc+sd-jwt (previously vc+sd-jwt) (SD-JWT VC)
46+
- Proof types:
47+
- jwt
48+
- API for credential offer fetching
49+
50+
OpenID4VCI is also implemented using the
51+
[SimpleSAMLphp OpenID library](https://github.com/simplesamlphp/openid).
52+
3353
## Version compatibility
3454

3555
Minor versions listed show which SimpleSAMLphp versions were used during

docs/2-oidc-installation.md

Lines changed: 40 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,12 +34,14 @@ and ensure at least the following parameters are set:
3434

3535
Note: SQLite, PostgreSQL, and MySQL are supported.
3636

37-
## 4. Create RSA key pairs
37+
## 4. Create key pairs
3838

3939
ID and Access tokens are signed JWTs. Create a public/private RSA key
4040
pair for OIDC protocol operations. If you plan to use OpenID Federation,
4141
create a separate key pair for federation operations.
4242

43+
### RSA key pair generation
44+
4345
Generate private keys without a passphrase:
4446

4547
```bash
@@ -73,6 +75,43 @@ openssl rsa -in cert/oidc_module_federation.key -passin pass:myPassPhrase -pubou
7375
If you use different file names or a passphrase, update
7476
`config/module_oidc.php` accordingly.
7577

78+
### EC key pair generation
79+
80+
If you prefer to use Elliptic Curve Cryptography (ECC) instead of RSA.
81+
82+
Generate private keys without a passphrase:
83+
84+
```bash
85+
openssl ecparam -name prime256v1 -genkey -noout -out cert/oidc_module.key
86+
openssl ecparam -name prime256v1 -genkey -noout -out cert/oidc_module_federation.key
87+
```
88+
89+
Generate private keys with a passphrase:
90+
91+
```bash
92+
openssl ecparam -genkey -name secp384r1 -noout -out cert/oidc_module.key -passout pass:myPassPhrase
93+
openssl ecparam -genkey -name secp384r1 -noout -out cert/oidc_module_federation.key -passout pass:myPassPhrase
94+
```
95+
96+
Extract public keys:
97+
98+
Without passphrase:
99+
100+
```bash
101+
openssl ec -in cert/oidc_module.key -pubout -out cert/oidc_module.crt
102+
openssl ec -in cert/oidc_module_federation.key -pubout -out cert/oidc_module_federation.crt
103+
```
104+
105+
With a passphrase:
106+
107+
```bash
108+
openssl ec -in cert/oidc_module.key -passin pass:myPassPhrase -pubout -out cert/oidc_module.crt
109+
openssl ec -in cert/oidc_module.key -passin pass:myPassPhrase -pubout -out cert/oidc_module.crt
110+
```
111+
112+
If you use different file names or a passphrase, update
113+
`config/module_oidc.php` accordingly.
114+
76115
## 5. Enable the module
77116

78117
Edit `config/config.php` and enable `oidc`:

docs/3-oidc-configuration.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,12 @@ There you can see discovery URLs. Typical discovery endpoints are:
5454
[https://yourserver/simplesaml/module.php/oidc/.well-known/openid-configuration](https://yourserver/simplesaml/module.php/oidc/.well-known/openid-configuration)
5555
- OpenID Federation configuration:
5656
[https://yourserver/simplesaml/module.php/oidc/.well-known/openid-federation](https://yourserver/simplesaml/module.php/oidc/.well-known/openid-federation)
57+
- OpenID for Verifiable Credential Issuance configuration:
58+
[https://yourserver/simplesaml/module.php/oidc/.well-known/openid-credential-issuer](https://yourserver/simplesaml/module.php/oidc/.well-known/openid-credential-issuer)
59+
- OAuth2 Authorization Server configuration:
60+
[https://yourserver/simplesaml/module.php/oidc/.well-known/oauth-authorization-server](https://yourserver/simplesaml/module.php/oidc/.well-known/oauth-authorization-server)
61+
- JWT VC Issuer configuration:
62+
[https://yourserver/simplesaml/module.php/oidc/.well-known/jwt-vc-issuer](https://yourserver/simplesaml/module.php/oidc/.well-known/jwt-vc-issuer)
5763

5864
You may publish these as ".well-known" URLs at the web root using your
5965
web server. For example, for `openid-configuration`:

docs/6-oidc-upgrade.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,14 @@ apply those relevant to your deployment.
77

88
New features:
99

10+
- Initial support for OpenID for Verifiable Credential Issuance
11+
(OpenID4VCI). Note that the implementation is experimental. You should not use
12+
it in production yet.
13+
1014
New configuration options:
1115

16+
- Several new options regarding support for OpenID4VCI.
17+
1218
Major impact changes:
1319

1420
- In v6 of the module, when defining custom scopes, there was a possibility to

0 commit comments

Comments
 (0)