Skip to content

Feature: Certificate policies#406

Draft
Gabgobie wants to merge 16 commits intorustls:mainfrom
Gabgobie:certificate-policies
Draft

Feature: Certificate policies#406
Gabgobie wants to merge 16 commits intorustls:mainfrom
Gabgobie:certificate-policies

Conversation

@Gabgobie
Copy link

@Gabgobie Gabgobie commented Jan 16, 2026

Thanks for offering to review the PR @djc

Adds the following extensions

This PR handles two of the extensions listed/requested in #370

Questions

What is or is not our responsiblity? Is producing conforming or even recommended extensions the library's or the library consumer's responsibility?

Examples for directives we could enforce

A certificate policy OID MUST NOT appear more than once in a certificate policies extension.

An explicitText field includes the textual statement directly in the certificate. The explicitText field is a string with a maximum size of 200 characters. Conforming CAs SHOULD use the UTF8String encoding for explicitText, but MAY use IA5String. Conforming CAs MUST NOT encode explicitText as VisibleString or BMPString. The explicitText string SHOULD NOT include any control characters (e.g., U+0000 to U+001F and U+007F to U+009F). When the UTF8String encoding is used, all character sequences SHOULD be normalized according to Unicode normalization form C (NFC) [NFC].

Do we need to ensure these terms are met or is it the consumer's responsibility? Should we provide access to all string types or only UTF8String?

Internal representation (related to the question about responsibilities)

Should we stay close to the ASN.1 definitions or can/should we diverge as long as the (de-)serialization works? Sometimes RFC5280 asserts that entries must be unique in text but uses a SEQUENCE OF in the ASN.1 definition. I feel like using a HashSet would be the logical choice for unique entries when the order carries no meaning. An example for this would be CertificatePolicies::policy_information.

#265 has raised the same question about key_usages and seems to plan making this change for the next major release. As raised over there, this would introduce a non-deterministic order.

Compatibility check screenshots

Requested Screenshots

OpenSSL (WSL)

  • cd certs
  • openssl x509 --in cert.pem --text --noout
grafik

Windows "Krypto-Shellerweiterungen"

Ausstellerklärung:

grafik

Unfortunately the window can't be resized

grafik grafik grafik

Browsers

Minimal webserver

from uvicorn import run
from fastapi import FastAPI

run(
    FastAPI(),
    host="127.0.0.1",
    port=443,
    ssl_certfile="certs/cert.pem",
    ssl_keyfile="certs/key.pem",
)

Firefox

grafik

Chromium (Edge)

grafik grafik

ASN.1 JavaScript decoder

Decode of a generated cert by cargo run --example certificate_policies

grafik

TODO

Taking another look at the Error variants, there seem to be highly specific errors. I'll continue with this style by adding specific instead of generic errors as well.

As part of my own review I tried consuming the new extension and am not happy with the current handling. I'll be changing the instantiation process to be more ergonomic.

@Gabgobie
Copy link
Author

I'll take another look at test coverage and the pipeline checks in the coming days but wanted to get this out here since the output seems to at least be valid.

@Gabgobie Gabgobie marked this pull request as draft January 16, 2026 18:18
@Gabgobie Gabgobie force-pushed the certificate-policies branch from fd4cb64 to 64ee5b1 Compare January 17, 2026 09:04
@Gabgobie Gabgobie marked this pull request as ready for review January 18, 2026 18:43
@Gabgobie
Copy link
Author

Suppose this is about as ready for review as it can get. There are still changes to be made but I'll need to know which direction they should go in.

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.

1200 lines of code is a lot. I added a bunch of notes on how to pare that down.

Comment on lines +841 to +842
/// ```rust
/// use rcgen::{CertificatePolicies, PolicyInformation, Error};
Copy link
Member

Choose a reason for hiding this comment

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

Also too much.

Comment on lines 997 to 1033
/// When a CA does not wish to limit the set of policies
/// for certification paths that include this certificate,
/// it MAY assert the special policy anyPolicy, with a
/// value of { 2 5 29 32 0 }.
pub fn any_policy() -> Self {
Self::new_oid_only(vec![2, 5, 29, 32, 0])
}

/// Certificate issued in compliance with the Extended Validation Guidelines
pub fn extended_validation() -> Self {
Self::new_oid_only(vec![2, 23, 140, 1, 1])
}

/// Certificate issued in compliance with the TLS Baseline Requirements – No entity identity asserted
pub fn domain_validated() -> Self {
Self::new_oid_only(vec![2, 23, 140, 1, 2, 1])
}

/// Certificate issued in compliance with the TLS Baseline Requirements – Organization identity asserted
pub fn organization_validated() -> Self {
Self::new_oid_only(vec![2, 23, 140, 1, 2, 2])
}

/// Certificate issued in compliance with the TLS Baseline Requirements – Individual identity asserted
pub fn individual_validated() -> Self {
Self::new_oid_only(vec![2, 23, 140, 1, 2, 3])
}

/// > The CPS Pointer qualifier contains a pointer to a Certification
/// > Practice Statement (CPS) published by the CA. The pointer is in the
/// > form of a URI. Processing requirements for this qualifier are a
/// > local matter. No action is mandated by this specification regardless
/// > of the criticality value asserted for the extension.
pub fn cps_uri(cps_uris: Vec<string::Ia5String>) -> Self {
Self::new_oid_qualifiers(
// Didn't find this one in RFC5280 and took it from PKIOverheid (Dutch Government PKI) using Firefox certificate inspection
// Is it plausible, that this is matching the PolicyQualifierInfo OID?
Copy link
Member

Choose a reason for hiding this comment

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

Let's avoid adding any particular policies for this PR.

@cpu
Copy link
Member

cpu commented Jan 19, 2026

For whatever it's worth I remain not keen on supporting certificate policies and don't plan to try to review this work.

@Gabgobie Gabgobie force-pushed the certificate-policies branch 2 times, most recently from 3fca22b to b92ec85 Compare January 19, 2026 16:44
@Gabgobie Gabgobie force-pushed the certificate-policies branch from 86d4652 to 275c30c Compare January 19, 2026 17:51
@Gabgobie
Copy link
Author

My apologies. I just took a look at the PR from a private window and noticed that my replies were never published. PR inexperience...

I thought you were just busy! I'll look into what it takes to publish a response.


@cpu Should I take your comment as active opposition to this PR? I'll be happy to make more changes but it would have been nice if you were clear about that beforehand. I interpreted your previous comment as indifference/approval. I also found more use-cases for policies aside from user notices, some of which I posted in the original issue.

I'm not strictly opposed to support if you can write a clean PR with appropriate test coverage without a lot of guidance1 but I'm having a hard time seeing this as a genuine use case that will benefit a large enough number of people to be worth the ongoing maintenance.

@cpu
Copy link
Member

cpu commented Feb 12, 2026

@cpu Should I take your comment as active opposition to this PR?

No, I wouldn't characterize it as active opposition in the sense that I would be in favour of blocking a PR that other maintainers wanted to approve or something like that. If you can get approvals, I won't stand in the way :-)

it would have been nice if you were clear about that beforehand. I interpreted your previous comment as indifference/approval.

My previous comment also emphasized a desire for a clean PR with appropriate test coverage. I haven't looked at the substance of the diff, but the commit history is pretty messy in the current state. Apologies if I misrepresented my interest/availability for reviewing the work in general, but I think you still have a path forward with djc/est31.

@Gabgobie
Copy link
Author

Thank you for clarifying. I am trying to do as much on my own as possible but this being my first larger PR I am not sure about the design decisions you - as in all maintainers of this project - would prefer. Maybe it would be better if I just make a decision over trying to add suggestions to pick from.

I wasn't aware that a clean history is valuable since it will be squashed on merge anyways. I will look into cleaning that up as well.

I'll also give reviewing my own changes another try. Not having looked at it for ~3 weeks I should have a fresh pair of eyes.

@Gabgobie Gabgobie marked this pull request as draft February 12, 2026 23:40
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.

3 participants