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

Throwing serverCertificateHashes related errors #489

Merged
merged 9 commits into from
May 23, 2023

Conversation

nidhijaju
Copy link
Member

@nidhijaju nidhijaju commented Mar 10, 2023

This change specifies where the NotSupportedError and trust errors should be thrown when handling serverCertificateHashes. It also adds explicit parameters to the certificate hash algorithms.

Fixes #456 and fixes #359.


Preview | Diff

Copy link
Contributor

@ricea ricea left a comment

Choose a reason for hiding this comment

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

lgtm

index.bs Outdated Show resolved Hide resolved
@nidhijaju nidhijaju requested a review from vasilvv March 13, 2023 01:02
@jan-ivar
Copy link
Member

jan-ivar commented Mar 14, 2023

Meeting:

  • @vasilvv to provide comments:
    • seems to be in the wrong place but no better place at the time
    • don't reveal info ahead of acceptance of connection

index.bs Outdated Show resolved Hide resolved
index.bs Outdated Show resolved Hide resolved
@nidhijaju nidhijaju force-pushed the certhash-notsupported branch from 1f0a8a4 to fd6fab2 Compare April 20, 2023 09:01
index.bs Outdated Show resolved Hide resolved
@jan-ivar
Copy link
Member

@martinthomson to have a look.

index.bs Outdated Show resolved Hide resolved
index.bs Outdated
|serverCertificateHashes| is specified instead of the default certificate version algorithm,
validate the certificate against [=custom certificate requirements=], and then
[=verify a certificate hash|verify the certificate hash=] against |serverCertificateHashes|.
The certificate is considered valid if and only if both of those checks pass.
Copy link
Member

Choose a reason for hiding this comment

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

When you say "both", do you refer to (hash check 1, hash check 2) or (hash checks, other stuff)?

Also, if the certificate is not valid, isn't there something you need to do? Like consider the connection to have failed?

Copy link
Member Author

Choose a reason for hiding this comment

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

I was referring to both the certificate meeting the custom certificate requirements and verifying the hash against the serverCertificateHashes.

I tried rephrasing the sentences, and mentioning that the connection should have failed if either of those conditions are not met, but does it look better?

index.bs Outdated Show resolved Hide resolved
index.bs Outdated Show resolved Hide resolved
@nidhijaju nidhijaju force-pushed the certhash-notsupported branch from 803701c to 2ea5b59 Compare April 25, 2023 23:58
Comment on lines +794 to +799
|congestionControl| for sending of data on this |connection|. When obtaining a connection, if
|serverCertificateHashes| is specified, instead of using the default certificate verification
algorithm, consider the certificate valid if it meets the [=custom certificate
requirements=] and if [=verify a certificate hash|verifying the certificate hash=] against
|serverCertificateHashes| returns true. If either condition is not met, let |connection| be
failure.
Copy link
Member

Choose a reason for hiding this comment

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

This bit about serverCertificateHashes might be better as a substep:

1. If |serverCertificateHashes| is specified, run the following steps:
    1.  If the certificate does not meet the [=custom certificate requirements=], mark the |connection| as failed.
    1. If the [=verify a certificate hash|verifying the certificate hash=] against |serverCertificateHashes| returns false, mark the |connection| as failed.

Copy link
Member Author

Choose a reason for hiding this comment

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

I actually initially had this as substeps in earlier commits, but based on #489 (comment), I changed it to be part of the same step. Since these steps are a modification of the "obtain a connection" step in Fetch, I think we should keep this part of the same step so as to make it clear that these checks happen during the "obtain a connection" step, as opposed to after.

Copy link
Member

Choose a reason for hiding this comment

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

I don't think that conceptualizing these as part of "obtain a connection" helps. It is cleaner if you regard these as checks that occur after a connection was successfully obtained.

Copy link
Member Author

Choose a reason for hiding this comment

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

I slightly prefer keeping it part of the same step, but either seems workable, so I'll update it to whatever seems best to you and @vasilvv.

Copy link
Contributor

Choose a reason for hiding this comment

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

I don't think that conceptualizing these as part of "obtain a connection" helps. It is cleaner if you regard these as checks that occur after a connection was successfully obtained.

I'm not sure I understand why this would be a separate check, since presumably you would want to perform it at the place you would normally perform certificate validation (as soon as you receive a certificate), which is in the middle of obtaining a connection (e.g. there might be steps after, like sending H/3 settings; also from error handling perspective, that means that a failure against certificate hash list is equivalent to failure against Web PKI in terms of how it's reported to the application).

Copy link
Contributor

@ekinnear ekinnear May 23, 2023

Choose a reason for hiding this comment

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

It does seem like it ends up in a different subsystem and is something that is done during connection configuration at setup.

In other words, in code, this isn't something that we check afterwards, but rather something that we configure as part of setting up a connection object and starting it. We don't really want to connect somewhere and then decide "nevermind" because we didn't like the certificate presented during the handshake.

algorithm, consider the certificate valid if it meets the [=custom certificate
requirements=] and if [=verify a certificate hash|verifying the certificate hash=] against
|serverCertificateHashes| returns true. If either condition is not met, let |connection| be
failure.
1. If |connection| is failure, then abort the remaining steps and [=queue a network task=] with
Copy link
Member

Choose a reason for hiding this comment

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

The phrasing here is a bit odd. Maybe if |connection| failed for any reason.

Copy link
Member Author

Choose a reason for hiding this comment

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

"Obtain a connection" actually returns "failure" if the connection fails, which is what this step is checking.

Copy link
Member

Choose a reason for hiding this comment

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

Ah, I see what you are doing. This is like a Rust Result<T, E> where you get a composite object that is either success (a connection) or an error. You are checking if the result was an error.

The problem I have is that - while this fine if you are writing code, this is terribly stilted prose. It reads as a grammatical error.

Copy link
Member Author

Choose a reason for hiding this comment

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

Yes, while I agree that it sounds odd, I think this is a fairly standard pattern throughout the spec ecosystem. For example, step 2 of https://url.spec.whatwg.org/#concept-url-parser and step 2 of https://encoding.spec.whatwg.org/#dom-textdecoder have similar text saying "if x is failure". There's also an open issue about clarifying what "failure" is at whatwg/infra#545, so perhaps when that is fixed, we can update it in the WebTransport spec.

@jan-ivar jan-ivar merged commit fefcd4d into w3c:main May 23, 2023
github-actions bot added a commit that referenced this pull request May 23, 2023
SHA: fefcd4d
Reason: push, by jan-ivar

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
6 participants