You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
refactor(x509-cert): decompose AsExtension into Criticality + AsExtension
The existing `AsExtension` trait has two design problems:
1. **Criticality is coupled to the type.** The `critical()` method attempts
to determine criticality from `subject` and `extensions`, but these are
not the only factors. Policy decisions, certificate profiles, or issuer
preferences may also influence criticality. Some extensions (like
`BasicConstraints`) "MAY appear as critical or non-critical" per RFC 5280.
2. **Requires `der::Encode`.** The trait bounds force all extensions to be
DER-encodable, but an extension's `extnValue` is just an `OCTET STRING` -
the encoding could theoretically be anything.
This refactor extracts a new `Criticality` trait and simplifies `AsExtension`:
```rust
pub trait Criticality {
fn criticality(&self, subject: &Name, extensions: &[Extension]) -> bool;
}
pub trait AsExtension {
type Error;
fn to_extension(&self, subject: &Name, extensions: &[Extension])
-> Result<Extension, Self::Error>;
}
```
A blanket impl provides `AsExtension` for `T: Criticality + AssociatedOid + der::Encode`,
so most existing extension types just need to rename their impl.
**New capabilities:**
1. Override criticality at the call site using a tuple:
```rust
// Use default criticality.
builder.add_extension(&SubjectAltName(names)))?;
// Override default criticality.
builder.add_extension(&(true, SubjectAltName(names)))?;
```
2. Implement `AsExtension` directly for non-DER-encoded extensions:
```rust
impl AsExtension for MyCustomExtension {
type Error = MyError;
fn to_extension(&self, ..) -> Result<Extension, MyError> {
// Custom encoding logic
}
}
```
3. Builders return `E::Error` directly, letting callers decide error handling:
```rust
builder.add_extension(&ext)?; // propagate E::Error
builder.add_extension(&ext).map_err(…)? // convert to another type
```
**Migration:** Replace `impl AsExtension` with `impl Criticality` and rename
`critical()` to `criticality()`. The blanket impl provides `AsExtension`
automatically.
0 commit comments