Hacktoberfest 2026: le issue che i maintainer hanno segnato per ottobre, aperte e adatte ai principianti. Sfoglia le issue Hacktoberfest

x509-cert - GeneralSubtree - distinguish absent minimum from explicitly encoded DEFAULT 0

Aperta
#2,428 1 commento 0 reazioni 0 assegnatari Vedi su GitHub

I maintainer di solito rispondono entro 2 giorni

Nessuno ha ancora preso questa issue.

Valutazione

Difficoltà
4/5
Tempo stimato
3-5 giorni
Idoneità per principianti
48/100
Tipo di issue
Bug
Chiarezza
Abbastanza chiara
Stato di attività
Attiva
Stack tecnologico
rust
Ambito
cryptography

Direzione di ricerca

Inizia con i test DER indipendenti di TestDefault e la gestione di #[asn1(default = "Default::default")] in der_derive, quindi confronta tale comportamento con GeneralSubtree e NameConstraints::from_der() di x509-cert. Determina la gestione prevista di un valore predefinito codificato esplicitamente e aggiungi una copertura di regressione che mostri il comportamento selezionato per entrambi gli esempi.

Scritto dal modello di indicizzazione a partire dal testo della issue.

Descrizione

Issue

During the development of an X.509 extension validator using x509-cert, I encountered the following behavior:

The current NameConstraints representation does not appear to distinguish an absent minimum from an explicitly encoded DEFAULT 0.

Initial analysis

x509-cert currently represents GeneralSubtree.minimum as:

#[asn1(
    context_specific = "0",
    tag_mode = "IMPLICIT",
    default = "Default::default"
)]
pub minimum: u32,

This may create a problem for strict validation of nameConstraints.

GeneralSubtree is defined by RFC 5280 as:

GeneralSubtree ::= SEQUENCE {
     base                    GeneralName,
     minimum         [0]     BaseDistance DEFAULT 0,
     maximum         [1]     BaseDistance OPTIONAL }

For the RFC 5280 profile, minimum must be zero and maximum must be absent. Some profiles/specifications, such as the CA/B Forum Baseline Requirements, state the corresponding encoding requirement more directly: minimum MUST NOT be present and maximum MUST NOT be present, as specified in section 7.1.2.10.8:

https://github.com/cabforum/servercert/blob/main/docs/BR.md#712108-ca-certificate-name-constraints

The issue is that an explicitly encoded minimum = 0 currently appears to be accepted and normalized to the same Rust value as an omitted minimum.

NameConstraints examples

The following two cases both pass:

#[cfg(test)]
use x509_cert::{der::Decode, ext::pkix::constraints::name::NameConstraints};

#[test]
fn name_constraints_omitted_minimum() {
    // NameConstraints ::= SEQUENCE {
    //     permittedSubtrees [0] IMPLICIT GeneralSubtrees OPTIONAL
    // }
    //
    // GeneralSubtree ::= SEQUENCE {
    //     base     dNSName "test.test"
    //     minimum  omitted
    // }
    let der = [
        0x30, 0x0f, // SEQUENCE
        0xa0, 0x0d, //   [0] permittedSubtrees
        0x30, 0x0b, //     SEQUENCE (GeneralSubtree)
        0x82, 0x09, //       [2] dNSName
        b't', b'e', b's', b't', b'.', b't', b'e', b's', b't',
    ];

    let nc = NameConstraints::from_der(&der).unwrap();
    let subtree = &nc.permitted_subtrees.as_ref().unwrap()[0];

    assert_eq!(subtree.minimum, 0);
    assert_eq!(subtree.maximum, None);
}

#[test]
fn name_constraints_explicit_default_minimum() {
    // Same NameConstraints as above, except GeneralSubtree contains:
    //
    //     minimum [0] = 0
    //
    // explicitly.
    let der = [
        0x30, 0x12, // SEQUENCE
        0xa0, 0x10, //   [0] permittedSubtrees
        0x30, 0x0e, //     SEQUENCE (GeneralSubtree)
        0x82, 0x09, //       [2] dNSName
        b't', b'e', b's', b't', b'.', b't', b'e', b's', b't',
        0x80, 0x01, 0x00, // [0] minimum = 0
    ];

    let nc = NameConstraints::from_der(&der).unwrap();
    let subtree = &nc.permitted_subtrees.as_ref().unwrap()[0];

    assert_eq!(subtree.minimum, 0);
    assert_eq!(subtree.maximum, None);
}

Consequently, it seems that a downstream NameConstraints validator cannot currently distinguish minimum being absent from minimum being explicitly present with value 0.

Is there an intended way for downstream consumers to make this distinction?

Alternatively, since X.690 requires a component equal to its DEFAULT value to be omitted from DER encoding, should the second example instead be rejected by NameConstraints::from_der()?

X.690 reference

https://www.itu.int/myworkspace/t-rec/item?id=14472&lang=en&page=publication

11.5 Set and sequence components with default value
The encoding of a set value or sequence value shall not include an encoding for any component value which is equal to its default value.

Potential upstream cause

If the intended behavior is for NameConstraints::from_der() to reject the explicitly encoded DEFAULT 0, then this may be a potential issue upstream in der_derive, rather than something specific to the GeneralSubtree representation in x509-cert.

The same behavior can be reproduced independently of x509-cert:

use der::{Decode, Sequence};

#[derive(Clone, Debug, Eq, PartialEq, Sequence)]
struct TestDefault {
    #[asn1(
        context_specific = "0",
        tag_mode = "IMPLICIT",
        default = "Default::default"
    )]
    value: u32,
}

#[test]
fn der_accepts_omitted_default_value() {
    let der = [
        0x30, 0x00, // SEQUENCE, value omitted
    ];

    let value = TestDefault::from_der(&der).unwrap();
    assert_eq!(value.value, 0);
}

#[test]
fn der_accepts_non_default_value() {
    let der = [
        0x30, 0x03,
        0x80, 0x01, 0x01, // [0] value = 1
    ];

    let value = TestDefault::from_der(&der).unwrap();
    assert_eq!(value.value, 1);
}

// FAILED
#[test]
fn der_rejects_explicit_default_value() {
    // TestDefault ::= SEQUENCE {
    //     value [0] INTEGER DEFAULT 0
    // }
    //
    // Under X.690 §11.5, explicitly encoding value
    // = 0 does not appear to be a valid DER
    // encoding because the component equals its
    // DEFAULT value.
    let der = [
        0x30, 0x03,       // SEQUENCE
        0x80, 0x01, 0x00, // [0] IMPLICIT INTEGER 0
    ];

    assert!(TestDefault::from_der(&der).is_err());
}

The first two tests pass, while der_rejects_explicit_default_value fails because TestDefault::from_der(&der) returns Ok.

This suggests the behavior may originate in the handling of #[asn1(default = "...")] rather than in the x509-cert GeneralSubtree representation itself.

If Decode::from_der() is intended to enforce DER canonicality, should #[asn1(default = "...")] reject a present component when its decoded value equals the declared default?

Thank you for your attention.

Lingua principale
Rust
Stelle
338
Fork
188
Merge medio
4g 6h
PR unite (30g)
15

Preparare l'ambiente

Non abbiamo ancora controllato i file di configurazione di questo progetto. Parti dal suo README e consulta la nostra guida al primo contributo per i passaggi generali.

Come iniziare

  1. Leggi tutta la issue e poi la guida ai contributi del progetto.
  2. Commenta sulla issue per dire che te ne occupi tu — evita che due persone facciano lo stesso lavoro.
  3. Fai un fork del repository e lavora su un branch.
  4. Apri una pull request che faccia riferimento al numero della issue.

Altre issue di RustCrypto/formats

Tutte le issue di RustCrypto/formats

Issue simili

Altre issue su Rust

Ricevi le nuove issue nella tua casella

Un breve riepilogo di issue GitHub adatte ai principianti.