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

Multiple domain components in issuer #301

Open
wants to merge 2 commits into
base: main
Choose a base branch
from

Conversation

da-kami
Copy link

@da-kami da-kami commented Nov 21, 2024

See: #300

I did not invest a big amount of time into changing the interface; please let me know if this PR is welcome otherwise I'm happy to close it. It would be great if #300 can be overcome at some point.

@da-kami da-kami force-pushed the multiple-domain-components-in-issuer branch from 5243530 to 7192b84 Compare November 21, 2024 09:49
Copy link
Member

@cpu cpu left a comment

Choose a reason for hiding this comment

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

Hi there, thanks for the issue/PR.

I haven't sat down to form a strong opinion on the core subject, but the specific spot in 5280 you cite and the linked cert-manager issue don't strike me as strong motivation. I think I should page in more context and revisit.

With respect to the diff: it's fairly invasive for an issue that at first glance feels uncommon/niche. Certainly the semver break would be important to avoid unless critical.

WDYT about getting CI to pass and reworking to be semver compatible as a first step?

rcgen/src/lib.rs Show resolved Hide resolved
@da-kami da-kami force-pushed the multiple-domain-components-in-issuer branch from 7192b84 to b327923 Compare December 8, 2024 04:52
@da-kami da-kami force-pushed the multiple-domain-components-in-issuer branch from b327923 to 062af97 Compare January 14, 2025 01:08
@da-kami da-kami marked this pull request as draft January 14, 2025 01:08
@da-kami da-kami force-pushed the multiple-domain-components-in-issuer branch 2 times, most recently from e12523c to 0ecfc1b Compare January 14, 2025 02:42
@da-kami da-kami marked this pull request as ready for review January 14, 2025 02:51
rcgen/src/lib.rs Outdated Show resolved Hide resolved
rcgen/src/lib.rs Outdated Show resolved Hide resolved
rcgen/src/lib.rs Show resolved Hide resolved
rcgen/src/lib.rs Outdated Show resolved Hide resolved
rcgen/tests/openssl.rs Outdated Show resolved Hide resolved
rcgen/tests/openssl.rs Outdated Show resolved Hide resolved
There can be multiple of the same entry, e.g. DC (domain component) entries in an issuer.
@da-kami da-kami force-pushed the multiple-domain-components-in-issuer branch from 2e18fbb to 8e0466f Compare January 21, 2025 10:12
@cpu cpu self-assigned this Jan 21, 2025
@da-kami da-kami force-pushed the multiple-domain-components-in-issuer branch from 8e0466f to dd62f8c Compare January 21, 2025 21:09
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.

Thanks, this looks good to me!

Copy link
Member

@cpu cpu left a comment

Choose a reason for hiding this comment

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

Sorry for the delay in taking a look at this. I've wanted to do it with some care and its harder to find time for that vs simpler PRs. I'm afraid as of now I don't feel comfortable +1ing this branch.

Firstly, unless I'm mistaken it still seems to be a semver breaking change and I don't think the necessity of the feature justifies that.

Secondly, I think while it's true that some distinguished name types should allow multiple value I don't think it's a universal property. In particular I'm nervous that this will encourage users to try things like adding two common names to the certificate subject instead of using the subject alternative names extension. You haven't offered a strong citation to a standards document that supports the idea that all DN types should allow multiple values and so I think this wariness is justified.

I do agree that for domain components in particular it should be possible to encode multiple values, but I think the API as designed here is too broad a change. For comparsion, see how Go's x509 package's pkix.Name.ToRdnSequence() only treats a specific set of dn types as multi-value (and as expected, OrganizationalUnit is one of them).

Could we think up a more complex API that works similar to Go's that would be less likely to cause misuse? Probably. Is it worth the effort? I'm not so sure.

@djc @est31 WDYT?

/// Replaces the *first occurrence* of a type with a new value.
/// This is a convenience function to avoid duplicating values.
///
/// If there are multiple occurrences of a type there is currently no way of changing them besides iterating over the types and values of an existing instance and creating a new instance.
Copy link
Member

@cpu cpu Jan 30, 2025

Choose a reason for hiding this comment

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

Suggested change
/// If there are multiple occurrences of a type there is currently no way of changing them besides iterating over the types and values of an existing instance and creating a new instance.
/// If there are multiple occurrences of a type that you wish to replace you must iterate over the types and values of an existing instance and create a new instance.

Comment on lines +548 to +550
#[test]
#[cfg(feature = "x509-parser")]
fn test_parse_certificate_with_multiple_domain_components() {
Copy link
Member

Choose a reason for hiding this comment

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

I think this test should be moved to tests/generic.rs since it only relies on x509-parser.

While the static test certificate was generated with the openssl command line tool, it's not using the Rust openssl crate dependency like the other tests in this file.

Comment on lines +594 to +596
let domain_component_values = param.distinguished_name.get(&DnType::CustomDnType(vec![
0, 9, 2342, 19200300, 100, 1, 25,
]));
Copy link
Member

Choose a reason for hiding this comment

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

Since you have x509-parser for this test you can avoid the hardcoded bare OID with a feature-guarded import of x509_parser::oid_registry::OID_DOMAIN_COMPONENT:

	let domain_component_values = param.distinguished_name.get(&DnType::CustomDnType(
		OID_DOMAIN_COMPONENT.iter().unwrap().collect(),
	));

Comment on lines +800 to +801
// Domain Component (DC)
let dc_type = DnType::CustomDnType(vec![0, 9, 2342, 19200300, 100, 1, 25]);
Copy link
Member

@cpu cpu Jan 30, 2025

Choose a reason for hiding this comment

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

It seems unimportant for the test added in this file that the DnType be a Custom one for DC. I think you could avoid some duplication by using a predefined DnType. WDYT?

@@ -309,20 +307,22 @@ impl DistinguishedName {
Self::default()
}
/// Obtains the attribute value for the given attribute type
pub fn get(&self, ty: &DnType) -> Option<&DnValue> {
self.entries.get(ty)
pub fn get(&self, ty: &DnType) -> Vec<&DnValue> {
Copy link
Member

Choose a reason for hiding this comment

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

Isn't this a breaking API change? That conclusion also seems to be supported by the necessity to change the example code on push().

Copy link
Member

Choose a reason for hiding this comment

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

Yup, it is -- sorry I missed that.

@djc
Copy link
Member

djc commented Feb 1, 2025

I do agree that for domain components in particular it should be possible to encode multiple values, but I think the API as designed here is too broad a change. For comparsion, see how Go's x509 package's pkix.Name.ToRdnSequence() only treats a specific set of dn types as multi-value (and as expected, OrganizationalUnit is one of them).

Could we think up a more complex API that works similar to Go's that would be less likely to cause misuse? Probably. Is it worth the effort? I'm not so sure.

@djc @est31 WDYT?

"worth the effort" implies a benefit/cost trade-off. I tend to feel that there is a decent amount of value in designing/maintaining careful, misuse-resistant APIs for libraries like this even if the amount of usage is fairly small, because the API itself can help more people guide towards doing the right thing. Realistically, the alternative is that someone faced with this use case will throw together their certs with a less careful API which overall will decrease the quality of certificates in the ecosystem.

(There might be a corollary to Postel's law in here, but I'm not sure I have a pithy formulation of it.)

So that brings us to the cost -- someone has to bear the cost of designing and reviewing such an API, and it's not completely obvious to me who might be interested in and capable of designing it right in this case.

@cpu
Copy link
Member

cpu commented Feb 1, 2025

"worth the effort" implies a benefit/cost trade-off. I tend to feel that there is a decent amount of value in designing/maintaining careful, misuse-resistant APIs for libraries like this even if the amount of usage is fairly small

I agree with that in the abstract, but in practice I think there's a fixed amount of time anyone can spend on this project and so we should direct it towards improvements that offer the most bang for the buck.

Putting that aside, is it fair to say we're in agreement the proposed updated API is not a careful, misuse-resistant API, or is there some disagreement there?

Realistically, the alternative is that someone faced with this use case will throw together their certs with a less careful API which overall will decrease the quality of certificates in the ecosystem.

True, but there are many projects that would allow someone to do this outside of rcgen. My principle concern is not making the outcome impossible, but ensuring that any change we make to support niche use-cases doesn't encourage misuse in the more common circumstances.

So that brings us to the cost -- someone has to bear the cost of designing and reviewing such an API, and it's not completely obvious to me who might be interested in and capable of designing it right in this case.

Indeed, and I think I'm unlikely to want to spend considerable time on this myself. The lag in review is also good evidence I can't prioritize this in practice.

Maybe we should take a step back and learn more about the use-case that is driving this feature request? In #301 the problem was described as one of extant certs with multiple-DCs not parsing correctly, but here we have an API to produce such certificates. I feel like I'm missing some details on how we went from A to B.

@djc
Copy link
Member

djc commented Feb 1, 2025

"worth the effort" implies a benefit/cost trade-off. I tend to feel that there is a decent amount of value in designing/maintaining careful, misuse-resistant APIs for libraries like this even if the amount of usage is fairly small

I agree with that in the abstract, but in practice I think there's a fixed amount of time anyone can spend on this project and so we should direct it towards improvements that offer the most bang for the buck.

Putting that aside, is it fair to say we're in agreement the proposed updated API is not a careful, misuse-resistant API, or is there some disagreement there?

Yes, I agree with that.

Indeed, and I think I'm unlikely to want to spend considerable time on this myself. The lag in review is also good evidence I can't prioritize this in practice.

Maybe we should take a step back and learn more about the use-case that is driving this feature request? In #301 the problem was described as one of extant certs with multiple-DCs not parsing correctly, but here we have an API to produce such certificates. I feel like I'm missing some details on how we went from A to B.

That's definitely fair. @da-kami can you give us more details about what you are trying to achieve?

@cpu cpu removed their assignment Feb 1, 2025
@est31
Copy link
Member

est31 commented Feb 3, 2025

I'm fine with making the API more complex, especially I prefer explicit complexity over implicit complexity (which is C style: you need to use the "simple" API correctly and respect the implicit invariants). Ideally there would still be a "simple" API for the 90% of users who don't need multiple domain components.

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.

4 participants