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

x509-cert/const-oid: a 100-character OID (RFC 5280 Appendix B) needs 40 octets, so a certificate carrying one as a non-critical extension id does not decode

Aperta
#2,485 3 commenti 0 reazioni 0 assegnatari Vedi su GitHub

I maintainer di solito rispondono entro 1 giorno

Nessuno ha ancora preso questa issue.

  • #2497 di @choksi2212 — chiusa senza merge

Valutazione

Difficoltà
4/5
Tempo stimato
3-5 giorni
Idoneità per principianti
45/100
Tipo di issue
Bug
Chiarezza
Specificata chiaramente
Stato di attività
Attiva
Stack tecnologico
rust
Ambito
backend, security

Direzione di ricerca

Start with const-oid’s DEFAULT_MAX_SIZE and parsing in src/lib.rs and src/encoder.rs, then trace DER OID decoding in der/src/asn1/oid.rs and Extension::extn_id in x509-cert’s src/ext.rs. Reproduce the 40-octet case and compare it with the 39-octet control. Done when certificates with the Appendix B sized non-critical extension OID decode successfully and the existing controls still pass.

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

Descrizione

Hi,

RFC 5280 Appendix B requires support for OIDs whose dotted-decimal form is up to 100 characters, with up to 20 arcs, each below 2^28. ObjectIdentifier's default capacity is 39 octets. A 100-character OID that stays within those limits can need 40, and then it doesn't fit. When that OID is the id of a non-critical extension, Certificate::from_der refuses the whole certificate, although RFC 5280 §4.2 says a non-critical extension a relying party doesn't recognise MAY be ignored.

The OID used is 1.3 followed by nine arcs of 268435455 (2^28 − 1, the largest Appendix B mandates) and then 123456: 12 arcs, 100 characters, 40 contents octets (1 + 9 × 4 + 3). The control swaps the last arc for 16383 (99 characters, 39 octets) and decodes fine. The three test certificates differ only in that extension id, and both controls re-encode to the exact octets they were decoded from, so the DER is canonical and the 40th octet is what fails.

What the reproduction shows

const-oid 0.10.2 + x509-cert 0.3.0 const-oid 0.9.6 + x509-cert 0.2.5
OID, 100 chars / 40 octets new and from_bytes: Err(Length) from_bytes: Err(NotEnoughArcs)
OID, 99 chars / 39 octets (control) Ok Ok
certificate, extension id 1.3.6.1.4.1.99999.1 (control) Ok, re-encodes identically Ok, re-encodes identically
certificate, extension id = the 99-char OID (control) Ok, re-encodes identically Ok, re-encodes identically
certificate, extension id = the 100-char OID Err: incorrect length for OBJECT IDENTIFIER at DER byte 214 Err: incorrect length for OBJECT IDENTIFIER at DER byte 212

Where it comes from

  • const-oid 0.10.2: DEFAULT_MAX_SIZE is 39 (src/lib.rs:48, src/lib.rs:66). The string parser refuses an arc that would end past it (src/encoder.rs:96-102), and from_bytes does the same after checking the arcs (src/lib.rs:121-132 into src/lib.rs:234-254, Error::Length at :240-241).
  • der 0.8.2 decodes an OBJECT IDENTIFIER into a buffer of that capacity and fails when the contents are longer (src/asn1/oid.rs:12-28).
  • x509-cert 0.3.0 and 0.2.5 type Extension::extn_id as the default ObjectIdentifier (src/ext.rs:29-36), and the extensions are a field of the TBS certificate (src/certificate.rs:163-164 in 0.3.0), so one extension id that doesn't fit fails the decode, critical or not.
  • On 0.9.6, from_bytes reports an input that is too long as Error::NotEnoughArcs (src/lib.rs:143-147), which names the wrong problem.
flowchart TD
  cert["Certificate DER, extension id = 1.3 + 9 x 268435455 + 123456<br/>100 characters, 40 octets (RFC 5280 App. B: must be supported)"]
  cert --> a["x509-cert 0.3.0 Certificate::from_der"]
  cert --> b["x509-cert 0.2.5 Certificate::from_der"]
  a --> ext3["Extension.extn_id: ObjectIdentifier<br/>ext.rs:29-36"]
  b --> ext2["Extension.extn_id: ObjectIdentifier<br/>ext.rs:29-36"]
  ext3 --> d8["der 0.8.2 decode_value: buf [u8; 39]<br/>oid.rs:12-28 -> length error"]
  ext2 --> d7["der 0.7.10 decode_value: buf [u8; 39]<br/>oid.rs:12-23 -> length error"]
  d8 --> cap10["const-oid 0.10.2 DEFAULT_MAX_SIZE = 39<br/>lib.rs:48, 66"]
  d7 --> cap9["const-oid 0.9.6 MAX_SIZE = 39<br/>lib.rs:92"]
  cap10 --> fail["Err: the whole certificate is unreadable<br/>(RFC 5280 4.2: a non-critical extension MAY be ignored)"]
  cap9 --> fail
  ctl["control: the same certificate with 39 octets<br/>Ok, re-encodes identically"]
  classDef bad fill:#fde,stroke:#b35
  classDef good fill:#def,stroke:#37b
  class fail bad
  class ctl good

This is related to #1984 but isn't the same thing: that asked for arcs beyond 2^32, which Appendix B doesn't require. This OID is inside Appendix B's limits and is one octet over the default capacity.

What would help, if you agree it's worth fixing: a default capacity that holds every OID Appendix B mandates, or an x509-cert decode path that accepts a larger MAX_SIZE, which const-oid's const parameter already makes possible. I'm happy to send a PR for whichever you prefer.

Reproduction script (self-contained; needs bash, rustup and network access for cargo to fetch the pinned crates)

Save it as repro.sh and run bash repro.sh. It writes a small Cargo project (locked by its own Cargo.lock) into a new temporary directory, builds it with Rust 1.98.0, and compares each observation with the table above. It exits 0 when everything matches. The script is yours to use under Apache-2.0 OR MIT.

#!/usr/bin/env bash
# SPDX-FileCopyrightText: Protoworks Group (Pty) Ltd
# SPDX-License-Identifier: Apache-2.0 OR MIT
#
# Self-contained reproduction (UP-CONSTOID-001). It writes the files below into a new
# temporary directory and runs repro.sh there; nothing outside that
# directory is written. Run it with: bash this-file.sh
set -euo pipefail
dir=$(mktemp -d "${TMPDIR:-/tmp}/repro.XXXXXX")
echo "files written to $dir"
cat >"$dir/rust-toolchain.toml" <<'__REPRO_FILE_1__'
[toolchain]
channel = "1.98.0"
__REPRO_FILE_1__
mkdir -p "$dir/harness"
cat >"$dir/harness/Cargo.lock" <<'__REPRO_FILE_2__'
# This file is automatically @generated by Cargo.
# It is not intended for manual editing.
version = 4

[[package]]
name = "base64ct"
version = "1.8.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2af50177e190e07a26ab74f8b1efbfe2ef87da2116221318cb1c2e82baf7de06"

[[package]]
name = "const-oid"
version = "0.9.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c2459377285ad874054d797f3ccebf984978aa39129f6eafde5cdc8315b612f8"

[[package]]
name = "const-oid"
version = "0.10.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a6ef517f0926dd24a1582492c791b6a4818a4d94e789a334894aa15b0d12f55c"

[[package]]
name = "der"
version = "0.7.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e7c1832837b905bbfb5101e07cc24c8deddf52f93225eee6ead5f4d63d53ddcb"
dependencies = [
 "const-oid 0.9.6",
 "der_derive 0.7.3",
 "flagset",
 "zeroize",
]

[[package]]
name = "der"
version = "0.8.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a878c850e9e421b20262e9b41f9c860e4785fa07541c266b62ff9d1ef998a80a"
dependencies = [
 "const-oid 0.10.2",
 "der_derive 0.8.0",
 "flagset",
 "zeroize",
]

[[package]]
name = "der_derive"
version = "0.7.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8034092389675178f570469e6c3b0465d3d30b4505c294a6550db47f3c17ad18"
dependencies = [
 "proc-macro2",
 "quote",
 "syn",
]

[[package]]
name = "der_derive"
version = "0.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "59600e2c2d636fde9b65e99cc6445ac770c63d3628195ff39932b8d6d7409903"
dependencies = [
 "proc-macro2",
 "quote",
 "syn",
]

[[package]]
name = "flagset"
version = "0.4.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b7ac824320a75a52197e8f2d787f6a38b6718bb6897a35142d749af3c0e8f4fe"

[[package]]
name = "proc-macro2"
version = "1.0.107"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "985e7ec9bb745e6ce6535b544d84d6cd6f7ad8bd711c398938ae983b91a766d9"
dependencies = [
 "unicode-ident",
]

[[package]]
name = "quote"
version = "1.0.47"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1fbf4db142a473a8d80c26bbf18454ed458bf8d26c8219c331daecfdbd079001"
dependencies = [
 "proc-macro2",
]

[[package]]
name = "spki"
version = "0.7.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d91ed6c858b01f942cd56b37a94b3e0a1798290327d1236e4d9cf4eaca44d29d"
dependencies = [
 "base64ct",
 "der 0.7.10",
]

[[package]]
name = "spki"
version = "0.8.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7ef958a98b9d5da290cfc78946e9f3e61e1e62a18db0d92cac0b83cc161491a9"
dependencies = [
 "base64ct",
 "der 0.8.2",
]

[[package]]
name = "syn"
version = "2.0.119"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "872831b642d1a07999a962a351ed35b955ea2cfc8f3862091e2a240a84f17297"
dependencies = [
 "proc-macro2",
 "quote",
 "unicode-ident",
]

[[package]]
name = "unicode-ident"
version = "1.0.27"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a2c754d6c33795a1c324727428e5a7dedb5b06195f9890bdbcba760d3e246563"

[[package]]
name = "up-constoid-001"
version = "0.0.0"
dependencies = [
 "const-oid 0.10.2",
 "const-oid 0.9.6",
 "x509-cert 0.2.5",
 "x509-cert 0.3.0",
]

[[package]]
name = "x509-cert"
version = "0.2.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1301e935010a701ae5f8655edc0ad17c44bad3ac5ce8c39185f75453b720ae94"
dependencies = [
 "const-oid 0.9.6",
 "der 0.7.10",
 "spki 0.7.3",
]

[[package]]
name = "x509-cert"
version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "105ef4642d9cb137ef83d623d0e4bf08b8adf69e9918ca904a174adb6d3d038b"
dependencies = [
 "const-oid 0.10.2",
 "der 0.8.2",
 "spki 0.8.1",
]

[[package]]
name = "zeroize"
version = "1.9.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e13084392c5e4bc371903e2935a5eaeed24905a7511356b883835e18a78f6879"
__REPRO_FILE_2__
mkdir -p "$dir/harness"
cat >"$dir/harness/Cargo.toml" <<'__REPRO_FILE_3__'
# SPDX-FileCopyrightText: Protoworks Group (Pty) Ltd
# SPDX-License-Identifier: Apache-2.0 OR MIT
#

# UP-CONSTOID-001's harness: const-oid 0.10.2 under x509-cert 0.3.0 (the
# newest of each), and const-oid 0.9.6 under x509-cert 0.2.5 (the 0.2
# line).
[package]
name = "up-constoid-001"
version = "0.0.0"
edition = "2021"
publish = false

[dependencies]
const-oid = "=0.10.2"
x509-cert = { version = "=0.3.0", default-features = false }
const-oid-09 = { package = "const-oid", version = "=0.9.6" }
x509-cert-02 = { package = "x509-cert", version = "=0.2.5", default-features = false }

[workspace]
__REPRO_FILE_3__
mkdir -p "$dir/harness/src"
cat >"$dir/harness/src/main.rs" <<'__REPRO_FILE_4__'
// SPDX-FileCopyrightText: Protoworks Group (Pty) Ltd
// SPDX-License-Identifier: Apache-2.0 OR MIT
//

//! UP-CONSTOID-001: an OID whose dotted-decimal form is 100 characters, as
//! the id of a non-critical extension, through const-oid 0.10.2 / x509-cert
//! 0.3.0 and const-oid 0.9.6 / x509-cert 0.2.5. RFC 5280 Appendix B:
//! "Implementations MUST also support OIDs where the length of the dotted
//! decimal ... string representation can be up to 100 bytes (inclusive)."
//! The certificate is assembled here octet by octet, so nothing of either
//! crate builds it; the control decodes and re-encodes to the same octets.
//! Prints `OBS key=value`.

use x509_cert::der::{Decode as _, Encode as _};
use x509_cert_02::der::{Decode as _, Encode as _};

/// The dotted form: `1.3`, nine `.268435455` (2^28 - 1, the largest arc RFC
/// 5280 Appendix B mandates) and a last arc.
fn dotted(last: u32) -> String {
    let mut s = String::from("1.3");
    for _ in 0..9 {
        s.push_str(".268435455");
    }
    s.push_str(&format!(".{last}"));
    s
}

/// X.690 §8.19 contents octets, written here rather than by either crate.
fn oid_contents(dotted: &str) -> Vec<u8> {
    let arcs: Vec<u64> = dotted.split('.').map(|a| a.parse().expect("digits")).collect();
    let mut out = vec![(arcs[0] * 40 + arcs[1]) as u8];
    for &arc in &arcs[2..] {
        let mut groups = vec![(arc & 0x7f) as u8];
        let mut rest = arc >> 7;
        while rest > 0 {
            groups.push(0x80 | (rest & 0x7f) as u8);
            rest >>= 7;
        }
        groups.reverse();
        out.extend(groups);
    }
    out
}

fn tlv(tag: u8, value: &[u8]) -> Vec<u8> {
    let mut out = vec![tag];
    let n = value.len();
    if n < 0x80 {
        out.push(n as u8);
    } else if n <= 0xff {
        out.extend([0x81, n as u8]);
    } else {
        out.extend([0x82, (n >> 8) as u8, n as u8]);
    }
    out.extend_from_slice(value);
    out
}

fn seq(parts: &[Vec<u8>]) -> Vec<u8> {
    tlv(0x30, &parts.concat())
}

fn oid(dotted: &str) -> Vec<u8> {
    tlv(0x06, &oid_contents(dotted))
}

/// A v3 certificate with one non-critical extension whose id is `ext_id`.
fn certificate(ext_id: &str) -> Vec<u8> {
    let ecdsa_sha256 = seq(&[oid("1.2.840.10045.4.3.2")]);
    let name = seq(&[tlv(0x31, &seq(&[oid("2.5.4.3"), tlv(0x0c, b"up-constoid-001")]))]);
    let validity = seq(&[tlv(0x17, b"250101000000Z"), tlv(0x17, b"350101000000Z")]);
    let mut point = vec![0x00, 0x04];
    point.extend([0x11; 64]);
    let spki = seq(&[
        seq(&[oid("1.2.840.10045.2.1"), oid("1.2.840.10045.3.1.7")]),
        tlv(0x03, &point),
    ]);
    let extension = seq(&[oid(ext_id), tlv(0x04, &[0x05, 0x00])]);
    let tbs = seq(&[
        tlv(0xa0, &tlv(0x02, &[0x02])),
        tlv(0x02, &[0x01]),
        ecdsa_sha256.clone(),
        name.clone(),
        validity,
        name,
        spki,
        tlv(0xa3, &seq(&[extension])),
    ]);
    seq(&[tbs, ecdsa_sha256, tlv(0x03, &[0x00, 0x01, 0x02, 0x03])])
}

fn obs(key: &str, value: impl std::fmt::Display) {
    println!("OBS {key}={value}");
}

fn verdict<T, E: std::fmt::Debug>(r: &Result<T, E>) -> String {
    match r {
        Ok(_) => "Ok".to_owned(),
        Err(e) => format!("Err({e:?})"),
    }
}

/// Decode with both x509-cert lines; on Ok, say whether re-encoding gives
/// back the same octets (it proves the assembled DER is the canonical form).
fn decode_both(label: &str, der: &[u8]) {
    match x509_cert::Certificate::from_der(der) {
        Ok(cert) => {
            obs(&format!("{label}.x509-cert-0.3.0"), "Ok");
            obs(
                &format!("{label}.x509-cert-0.3.0.reencodes-identically"),
                cert.to_der().map(|d| d == der).unwrap_or(false),
            );
        }
        Err(e) => {
            obs(&format!("{label}.x509-cert-0.3.0"), "Err");
            obs(&format!("info.{label}.x509-cert-0.3.0.error"), e);
        }
    }
    match x509_cert_02::Certificate::from_der(der) {
        Ok(cert) => {
            obs(&format!("{label}.x509-cert-0.2.5"), "Ok");
            obs(
                &format!("{label}.x509-cert-0.2.5.reencodes-identically"),
                cert.to_der().map(|d| d == der).unwrap_or(false),
            );
        }
        Err(e) => {
            obs(&format!("{label}.x509-cert-0.2.5"), "Err");
            obs(&format!("info.{label}.x509-cert-0.2.5.error"), e);
        }
    }
}

fn main() {
    // 100 characters, 40 BER octets: the claim.
    let long = dotted(123456);
    // 99 characters, 39 BER octets: the largest the crates hold.
    let fits = dotted(16383);

    obs("oid100.chars", long.len());
    obs("oid100.ber-octets", oid_contents(&long).len());
    obs("oid99.chars", fits.len());
    obs("oid99.ber-octets", oid_contents(&fits).len());

    obs("const-oid-0.10.2.new(oid100)", verdict(&const_oid::ObjectIdentifier::new(&long)));
    obs(
        "const-oid-0.10.2.from_bytes(oid100)",
        verdict(&const_oid::ObjectIdentifier::from_bytes(&oid_contents(&long))),
    );
    obs("const-oid-0.10.2.new(oid99)", verdict(&const_oid::ObjectIdentifier::new(&fits)));
    obs(
        "const-oid-0.9.6.from_bytes(oid100)",
        verdict(&const_oid_09::ObjectIdentifier::from_bytes(&oid_contents(&long))),
    );
    obs(
        "const-oid-0.9.6.from_bytes(oid99)",
        verdict(&const_oid_09::ObjectIdentifier::from_bytes(&oid_contents(&fits))),
    );
    obs("info.const-oid-0.9.6.new(oid100)", verdict(&const_oid_09::ObjectIdentifier::new(&long)));
    obs("info.const-oid-0.9.6.new(oid99)", verdict(&const_oid_09::ObjectIdentifier::new(&fits)));

    decode_both("control", &certificate("1.3.6.1.4.1.99999.1"));
    decode_both("cert-oid99", &certificate(&fits));
    decode_both("cert-oid100", &certificate(&long));
}
__REPRO_FILE_4__
cat >"$dir/repro.sh" <<'__REPRO_FILE_5__'
#!/usr/bin/env bash
# SPDX-FileCopyrightText: Protoworks Group (Pty) Ltd
# SPDX-License-Identifier: Apache-2.0 OR MIT
#
set -euo pipefail

# repro.sh — UP-CONSTOID-001: an OID whose dotted-decimal form is 100
# characters (RFC 5280 Appendix B: "MUST also support OIDs where the length
# of the dotted decimal ... string representation can be up to 100 bytes")
# does not fit const-oid's ObjectIdentifier, in 0.10.2 (the newest, under
# x509-cert 0.3.0) or 0.9.6 (under x509-cert 0.2.5); as the id of a
# non-critical extension it makes the whole certificate undecodable. A
# defensive check over a certificate the harness assembles octet by octet.
#
#   ./repro.sh
#
# What it does: builds harness/ (locked by harness/Cargo.lock) with the
# toolchain rust-toolchain.toml pins, runs it, and compares each
# `OBS key=value` with EXPECT, the claim table of the report. Lines named
# info.* are printed for the reader and not checked.
#
# Network: cargo's fetch of the crates harness/Cargo.lock pins. Nothing else.
#
# Exit status: 0 when every check holds (the defect is shown); otherwise the
# number of checks that disagreed; 2 if the harness could not be built or run.
#
# Dependencies: bash, awk, cargo and rustup (1.98.0).

here=$(cd "$(dirname "$0")" && pwd)
cd "$here"

fail=0
note() { echo "repro: $*"; }
check() {  # check <label> <want> <got>
  if [[ "$2" == "$3" ]]; then
    printf '  ok   %-60s %s\n' "$1" "$3"
  else
    printf '  FAIL %-60s got %s, want %s\n' "$1" "$3" "$2"
    fail=$((fail + 1))
  fi
}

if ! command -v cargo >/dev/null 2>&1; then
  note "cargo is not installed; cannot run"
  exit 2
fi
target=$(mktemp -d "${TMPDIR:-/tmp}/up-ev.XXXXXX")
trap 'rm -rf "$target"' EXIT

# The toolchain is the one the repository's rust-toolchain.toml pins.
rustc_version=$(cd "$here/harness" && rustc --version)
note "toolchain: $rustc_version"
check "rustc is the pinned 1.98.0" "rustc 1.98.0" "$(cut -d' ' -f1-2 <<<"$rustc_version")"

run_harness() {  # run_harness -> the harness's stdout
  (cd "$here/harness" && CARGO_TARGET_DIR="$target" cargo run --locked --quiet --release)
}

compare() {  # compare <label> <harness output> ; reads key=value lines on stdin
  local label="$1" out="$2" key want got
  while IFS='=' read -r key want; do
    [[ -z "$key" || "$key" == \#* ]] && continue
    got=$(awk -v k="OBS ${key}=" 'index($0, k) == 1 { print substr($0, length(k) + 1); exit }' <<<"$out")
    [[ -n "$got" ]] || got="(not printed)"
    check "$label: $key" "$want" "$got"
  done
}

finish() {  # finish <id>
  echo
  if [[ "$fail" -eq 0 ]]; then
    note "all checks held: $1 is shown as the report states it"
    exit 0
  fi
  note "$fail checks disagreed with the claim"
  exit "$fail"
}

note "building and running harness/ (const-oid 0.10.2 + x509-cert 0.3.0, const-oid 0.9.6 + x509-cert 0.2.5)"
out=$(run_harness) || { note "the harness did not build or run"; exit 2; }
printf '%s\n' "$out" | sed 's/^/    /'

compare oid "$out" <<'EXPECT'
oid100.chars=100
oid100.ber-octets=40
oid99.chars=99
oid99.ber-octets=39
EXPECT

compare const-oid "$out" <<'EXPECT'
const-oid-0.10.2.new(oid100)=Err(Length)
const-oid-0.10.2.from_bytes(oid100)=Err(Length)
const-oid-0.10.2.new(oid99)=Ok
const-oid-0.9.6.from_bytes(oid100)=Err(NotEnoughArcs)
const-oid-0.9.6.from_bytes(oid99)=Ok
EXPECT

# The controls: the assembled certificate is canonical DER, and the
# extension id is the only thing that changes between the three.
compare control "$out" <<'EXPECT'
control.x509-cert-0.3.0=Ok
control.x509-cert-0.3.0.reencodes-identically=true
control.x509-cert-0.2.5=Ok
control.x509-cert-0.2.5.reencodes-identically=true
cert-oid99.x509-cert-0.3.0=Ok
cert-oid99.x509-cert-0.3.0.reencodes-identically=true
cert-oid99.x509-cert-0.2.5=Ok
cert-oid99.x509-cert-0.2.5.reencodes-identically=true
EXPECT

compare claim "$out" <<'EXPECT'
cert-oid100.x509-cert-0.3.0=Err
cert-oid100.x509-cert-0.2.5=Err
EXPECT

finish UP-CONSTOID-001
__REPRO_FILE_5__
chmod +x "$dir/repro.sh"
cd "$dir" && ./repro.sh
Recorded run (macOS arm64, rustc 1.98.0)
repro: toolchain: rustc 1.98.0 (88d9e12ae 2026-08-18)
  ok   rustc is the pinned 1.98.0                                   rustc 1.98.0
repro: building and running harness/ (const-oid 0.10.2 + x509-cert 0.3.0, const-oid 0.9.6 + x509-cert 0.2.5)
  ok   oid: oid100.chars                                            100
  ok   oid: oid100.ber-octets                                       40
  ok   oid: oid99.chars                                             99
  ok   oid: oid99.ber-octets                                        39
  ok   const-oid: const-oid-0.10.2.new(oid100)                      Err(Length)
  ok   const-oid: const-oid-0.10.2.from_bytes(oid100)               Err(Length)
  ok   const-oid: const-oid-0.10.2.new(oid99)                       Ok
  ok   const-oid: const-oid-0.9.6.from_bytes(oid100)                Err(NotEnoughArcs)
  ok   const-oid: const-oid-0.9.6.from_bytes(oid99)                 Ok
  ok   control: control.x509-cert-0.3.0                             Ok
  ok   control: control.x509-cert-0.3.0.reencodes-identically       true
  ok   control: control.x509-cert-0.2.5                             Ok
  ok   control: control.x509-cert-0.2.5.reencodes-identically       true
  ok   control: cert-oid99.x509-cert-0.3.0                          Ok
  ok   control: cert-oid99.x509-cert-0.3.0.reencodes-identically    true
  ok   control: cert-oid99.x509-cert-0.2.5                          Ok
  ok   control: cert-oid99.x509-cert-0.2.5.reencodes-identically    true
  ok   claim: cert-oid100.x509-cert-0.3.0                           Err
  ok   claim: cert-oid100.x509-cert-0.2.5                           Err

repro: all checks held: UP-CONSTOID-001 is shown as the report states it
Lingua principale
Rust
Stelle
344
Fork
196
Merge medio
1g 17h
PR unite (30g)
24

Preparare l'ambiente

Questo progetto non fornisce container di sviluppo, Dockerfile né guida per i contributori, quindi l'ambiente è a tuo carico: 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.