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

rework dns_names helper, remove alloc req. #178

Merged
merged 22 commits into from
Sep 20, 2023

Conversation

cpu
Copy link
Member

@cpu cpu commented Sep 14, 2023

Description

This branch reworks the EndEntityCert's dns_names helper. Principally it:

  • Simplifies the unit testing, and cleans up some misc nits.
  • Reworks dns_names and the corresponding subject_name::list_cert_dns_names fns to be infallible, this better matches how we're ignoring invalid DNS names when validating a subject name since ignore invalid value validating dns name list #69.
  • Removes the alloc requirement for the dns_names fn.
  • Reworks the name ref types to use as_str instead of a From impl
  • Removes the GeneralDnsNameRef type (with the potential to restore as future work c.f. Restore GeneralDnsNameRef, use in GeneralName::DnsName. #183)
  • Moves the subject_name::list_cert_dns_names free-standing fn to be associated with Cert and named valid_dns_names.

Resolves #46, replaces #50

@cpu
Copy link
Member Author

cpu commented Sep 14, 2023

@djc Interested in your thoughts on this branch. Mostly wanted to clear the path for #159 but then got a little bit carried away.

@codecov
Copy link

codecov bot commented Sep 14, 2023

Codecov Report

Merging #178 (64fb1b7) into main (8d6a733) will increase coverage by 0.21%.
Report is 23 commits behind head on main.
The diff coverage is 92.30%.

@@            Coverage Diff             @@
##             main     #178      +/-   ##
==========================================
+ Coverage   96.31%   96.53%   +0.21%     
==========================================
  Files          17       19       +2     
  Lines        4510     4496      -14     
==========================================
- Hits         4344     4340       -4     
+ Misses        166      156      -10     
Files Changed Coverage Δ
src/signed_data.rs 100.00% <ø> (ø)
src/subject_name/dns_name.rs 88.66% <85.71%> (+1.79%) ⬆️
src/cert.rs 97.58% <100.00%> (+0.10%) ⬆️
src/end_entity.rs 100.00% <100.00%> (ø)
src/subject_name/verify.rs 91.89% <100.00%> (-0.21%) ⬇️

... and 8 files with indirect coverage changes

📣 We’re building smart automated test selection to slash your CI/CD build times. Learn more

Copy link
Member

@djc djc left a comment

Choose a reason for hiding this comment

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

In general I feel that the GeneralDnsNameRef and WildcardDnsNameRef names are not that obvious and fairly verbose, so that is one reason that keeping them private made sense to me. Especially the notion of "General", I suppose? What does that mean?

src/subject_name/mod.rs Outdated Show resolved Hide resolved
src/subject_name/dns_name.rs Outdated Show resolved Hide resolved
src/subject_name/verify.rs Outdated Show resolved Hide resolved
src/subject_name/verify.rs Outdated Show resolved Hide resolved
@cpu cpu marked this pull request as draft September 14, 2023 22:18
We switched to using `doc_auto_cfg` to automatically indicate in
Rustdocs when an item requires a particular feature. This comment about
the `dns_name::DnsName` re-export requiring alloc isn't necessary
anymore.
We switched to `doc_auto_cfg` and don't need to manually annotate
`cfg(feature ...)` annotations for docsrs purposes anymore.
This is what most consumers of the API are interested in, and avoids
needing to export the `GeneralDnsNameRef` and `WildcardDnsNameRef`
types.
We can express this test with the `expect_cert_dns_names` helper.
Prior to this commit the rustdoc comment on `EndEntityCert.dns_names`
mentioned using `verify_is_valid_for_dns_name` and
`verify_is_valid_for_at_least_one_dns_name`, but these functions don't
exist anymore.

This commit updates the comment to point to
`EndEntityCert::verify_is_valid_for_subject_name`, and does so with
a proper Rustdoc link so that future updates will be caught by `cargo
doc` if we forget to fix this reference to match.
@cpu cpu marked this pull request as ready for review September 18, 2023 15:44
@cpu cpu changed the title rework dns_names helper, expose more types, remove alloc req. rework dns_names helper, remove alloc req. Sep 18, 2023
@cpu
Copy link
Member Author

cpu commented Sep 18, 2023

ci / Measure coverage (pull_request) Failing after 28s

This is time-rs/time#618

ci / Build+test (--all-features, nightly, ubuntu-20.04) (pull_request) Failing after 45s

I think this is a nightly bug? It seems like it doesn't like the . in the ASN.1 language specifier on the backtick code fence:

/// ```ASN.1
/// Certificate (SEQUENCE) {
/// tbsCertificate TBSCertificate,
/// signatureAlgorithm AlgorithmIdentifier,
/// signatureValue BIT STRING
/// }

Switching to asn1 fixes the compile error, but that's not the name Linguist/GitHub use for ASN.1 syntax highlighting.

@ctz
Copy link
Member

ctz commented Sep 18, 2023

I think this is a nightly bug?

I think we're just missing an end to the code block?

(the upstream issue that has changed the parser is rust-lang/rust#110800 in case we do need to report the regression though.)

@cpu
Copy link
Member Author

cpu commented Sep 18, 2023

I think we're just missing an end to the code block?

Ah, good catch. I fixed that in this branch, but it's still generating a warning.

I was also able to reproduce with a minimal example for an upstream issue:

/// This is a test:
/// ```ASN.1
/// foo
/// ```
fn main() {
    println!("Hello, world!");
}

(the upstream issue that has changed the parser is rust-lang/rust#110800 in case we do need to report the regression though.)

Thanks! I'll mention that in the issue.

@cpu cpu mentioned this pull request Sep 18, 2023
@djc djc mentioned this pull request Sep 20, 2023
@djc
Copy link
Member

djc commented Sep 20, 2023

Feedback in cpu#1. I think these changes together mean that we can revert/simplify a bunch of the additions from #42, which would be nice?

@cpu
Copy link
Member Author

cpu commented Sep 20, 2023

I think these changes together mean that we can revert/simplify a bunch of the additions from #42, which would be nice?

@djc Thanks, the majority of these changes seem good to me, but I think we might want to consider leaving the GeneralDnsNameRef type.

I thought about removing it when I reworked this branch to iterate w/ &str but after revisiting the context from #42 while working on this branch I remembered that the purpose of this type was to enable something like briansmith/webpki#66 It seemed to me like that's still worthwhile to pursue, but since it's a little bit more involved (and crate-internal) I didn't want to do it for the 0.102 release (or at least, not until I've finished more of the Rustls release blocker work).

WDYT?

@djc
Copy link
Member

djc commented Sep 20, 2023

That's fair. So what do you want to do with cpu#1? Merge it on top of this without making further changes? (I didn't finish reviewing all commits here after I got myself distracted from removing the use of .into().)

@cpu
Copy link
Member Author

cpu commented Sep 20, 2023

That's fair. So what do you want to do with cpu#1? Merge it on top of this without making further changes?

That sounds good to me. I can merge it in and then back out 27a1234.

@djc
Copy link
Member

djc commented Sep 20, 2023

Hmm, yeah, I think that'll leave us with a bunch of warnings -- I'm not sure putting allow(dead_code) on a bunch of stuff here is a great alternative.

Maybe better to remove this code and create a follow-up issue to bring back the ideas from briansmith/webpki#66? Probably something I could pick up soon.

@cpu
Copy link
Member Author

cpu commented Sep 20, 2023

I'm not sure putting allow(dead_code) on a bunch of stuff here is a great alternative.

Good point.

Maybe better to remove this code and create a follow-up issue to bring back the ideas from briansmith/webpki#66? Probably something I could pick up soon.

That sounds good to me. 👍

@cpu
Copy link
Member Author

cpu commented Sep 20, 2023

Maybe better to remove this code and create a follow-up issue

#183

@cpu
Copy link
Member Author

cpu commented Sep 20, 2023

@ctz Could you give this branch an independent review since both myself and Djc have contributed code to it? 🙇

Copy link
Member

@djc djc left a comment

Choose a reason for hiding this comment

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

As a further change, how do we feel about attaching list_cert_dns_names() to EndEntityCert, or, even better, Cert, as a method? Feels right to me. Maybe change the name to valid_dns_names()?

src/end_entity.rs Show resolved Hide resolved
The purpose of the `dns_names` helper on an `EndEntityCert` is to
provide users the opportunity to get information on the dNSName SAN
values in a certificate for **non-validation** purposes. Checking that
a certificate is valid for a particular name should always be done with
`verify_is_valid_for_at_least_one_dns_name`.

With that use-case in mind, we can make the `dns_names` helper easier
for consumers to use by filtering out invalid general names, returning
an `Iterator<Item = &'a str>` unconditionally, instead of
a `Result`. This better matches the updated name validation semantics
where we ignore `MalformedDnsIdentifier` errors to continue to try to
find a valid name to validate against.
@cpu cpu force-pushed the cpu-rework-dns-names-iter branch 2 times, most recently from 5379817 to 49067e2 Compare September 20, 2023 15:18
@cpu
Copy link
Member Author

cpu commented Sep 20, 2023

As a further change, how do we feel about attaching list_cert_dns_names() to EndEntityCert, or, even better, Cert, as a method? Feels right to me. Maybe change the name to valid_dns_names()?

Good idea 👍 I put it on Cert as valid_dns_names.

tests/integration.rs Outdated Show resolved Hide resolved
src/end_entity.rs Show resolved Hide resolved
cpu and others added 11 commits September 20, 2023 11:25
With the update to the `dns_names` function in the previous commit we
can now make `EndEntity.dns_names` work without requiring `alloc`.
Avoid combinator chaining, use explicit `match`.
The From impl feels a little unidiomatic because the DnsNameRef is not
consumed. An AsRef impl would unnecessarily constrain the lifetime of
the output value to `&self`, whereas it can live as long as `'a`.
The From impl feels a little unidiomatic because the WildcardDnsNameRef is
not consumed. An AsRef impl would unnecessarily constrain the lifetime of
the output value to `&self`, whereas it can live as long as `'a`.
The From impl feels a little unidiomatic because the GeneralDnsNameRef is
not consumed. An AsRef impl would unnecessarily constrain the lifetime of
the output value to `&self`, whereas it can live as long as `'a`.
This commit lifts the free-standing `list_cert_dns_names` helper from
the `subject_name` module to be associated with a `Cert`. Doing so also
requires making the `subject_name::NameIterator` and
`subject_name::WildcardDnsNameRef` `pub(crate)` visible.
@cpu cpu added this pull request to the merge queue Sep 20, 2023
Merged via the queue into rustls:main with commit dc9c85c Sep 20, 2023
28 of 29 checks passed
@cpu cpu deleted the cpu-rework-dns-names-iter branch September 20, 2023 15:35
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Refactor verify.rs list_cert_dns_names to avoid allocations.
4 participants