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

Support for RP authentication with X.509 certificates that do not contain a dns name #320

Open
martijnharing opened this issue Nov 12, 2024 · 11 comments

Comments

@martijnharing
Copy link

The specification currently does not support RP authentication with X.509 certificates that do not have a DNS name.

There can be multiple reasons why an RP may not have a DNS name in their certificates, examples include re-using an existing certificate that does not have a DNS name, an RP certificate issuer that does not want or cannot verify binding to a DNS name or using the same certificate for in-person as well as remote.

Two possible solutions are to add another client identifier scheme, or to not use a client_id when such a certificate is used.

@bc-pi
Copy link
Member

bc-pi commented Nov 12, 2024

What about the x509_san_uri Client Identifier Scheme?

@martijnharing
Copy link
Author

x509_san_uri has the same issues as x509_san_dns since the same reasons why an RP certificate may not have a DNS name can also apply to a URI.

@Sakurann
Copy link
Collaborator

Sakurann commented Nov 19, 2024

so, this requirement is important since it proves that the identifier of the client belongs to the entity producing the signature and is being authenticated.

My suggestion would be to define a behavior what to do when a client_id does not match a DNS name in the certificate - basically something like, "the wallet MAY accept a request with client_id_scheme x509_san_dns (or x509_san_uri FWIW) where client_id does not match DNS name in the cert, at its own risk, and only if the wallet has obtained out of band a list of a trusted combination of client_ids and root certs". Can do a PR if this is acceptable

@martijnharing
Copy link
Author

I don't think that would address it. In the case of using an X.509 certificate to identify the Reader, as a wallet you care whether the RP is authenticated. The X.509 certificate tells you whether it's trusted. What trusted means in this context is likely ecosystem specific.
The client_id doesn't necessarily come into play, since (depending on the ecosystem) the X.509 certificate can already tell you everything you need to know about the RP.
For example as a wallet I could trust all RPs that have a certificate issued by root X, and there is an RP that signs the request with a certificate issued by root X with a subject that says "company Y". As a wallet I could show this to the user (what exactly to show to the user would be ecosystem/wallet specific), who can choose to proceed or not based on that information.
The RP signs the jwks with the key in this certificate and I would encrypt the response to this key. For this particular flow it's not required to actually use the client_id or check it against something. So I don't think there is always a security benefit (at least not in this particular example) to requiring the wallet to have a list of client_ids vs RP certificates.

@Sakurann
Copy link
Collaborator

The client_id doesn't necessarily come into play, since (depending on the ecosystem) the X.509 certificate can already tell you everything you need to know about the RP.

client_id does come into play because it is a security mechanism: aud in KB JWT and W3C VPs must equal client_id and session transcript in mdocs includes client_id

@danielfett
Copy link
Contributor

Yes, indeed. Just the encryption of the response is not enough. The aud value is important.

A solution might be something like x509_thumbprint.

@Sakurann Sakurann added the ISO? label Nov 21, 2024
@martijnharing
Copy link
Author

The client_id doesn't necessarily come into play, since (depending on the ecosystem) the X.509 certificate can already tell you everything you need to know about the RP.

client_id does come into play because it is a security mechanism: aud in KB JWT and W3C VPs must equal client_id and session transcript in mdocs includes client_id

But in the context of the example given, I don't think the clientID mitigates against situations that aren't already mitigated by the presence of the origin in the session transcript.
If that's indeed the case, then the requirement that the wallet has a list of client_ids vs root certs should not apply. While such a requirement has significant difficulties for scalability.

@c2bo
Copy link
Member

c2bo commented Nov 24, 2024

Yes, indeed. Just the encryption of the response is not enough. The aud value is important.

A solution might be something like x509_thumbprint.

I agree, thumbprint sounds like a reasonable idea imho

@Sakurann
Copy link
Collaborator

Sakurann commented Nov 28, 2024

WG discussion. in oid4vp over the browser API with unsigned request, aud is origin (need to define this better for the credential formats), so client_id might be less important.
but for vanilla oid4vp, and oid4vp over the browser API with signed request, client_id is an aud value, and for this case, consensus forming towards introducing x509_thumbprint, where client_id value is a thumbprint of the cert - how to do the thumbprint needs to be specified (is it already defined somewhere?)?

@David-Chadwick @awoie please provide more info re how to calculate a thumbprint and/or what can be used as the client_id

@David-Chadwick
Copy link
Contributor

The existing X.509 certificate thumbprints in web browsers are actually called "fingerprints", and they are usually of two types: SHA-256 and SHA-1. Here is an example of how they are displayed

SHA-256 19:50:2F:18:CB:63:B8:01:A9:4B:5E:93:29:F8:6C:1D:09:27:55:7B:F3:29:27:77:CE:08:3E:87:67:31:C2:81
SHA-1 C7:08:90:10:44:14:F8:94:06:E6:9D:2F:92:FE:19:77:E8:1B:5C:43

So we could say that the client id should be the SHA-256 value in hex, or we could say that the client id should be encoded as alg?hexvalue e.g.

SHA-256?19:50:2F:18:CB:63:B8:01:A9:4B:5E:93:29:F8:6C:1D:09:27:55:7B:F3:29:27:77:CE:08:3E:87:67:31:C2:81
or
SHA-1?C7:08:90:10:44:14:F8:94:06:E6:9D:2F:92:FE:19:77:E8:1B:5C:43

The later encoding is more future proofed as it caters for when new hashing algorithms are defined.

@martijnharing
Copy link
Author

But it's not yet clear what the threat model is that the client_id protects against. If in some cases a part of the subject (e.g. the dns name or URI) is sufficient, but in other cases the full thumbprint is needed. To know what exactly is needed (or whether something is needed at all) we need to determine the threat.

Also if the client_id value in the request must be a copy of other information that's also transmitted (e.g. the X.509 certificate itself), the actual client_id value in the request doesn't actually provide any value but only leads to complications.
e.g. is it mandatory, optional or recommended to reject a request if the client_id and the certificate don't match? If it's mandatory, is the check mandatory even if you don't use/parse the X.509 certificate? When there are multiple signatures , is it required to do this check for all of them?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

6 participants