pem-rfc7468: a lone CR before -----BEGIN is refused as Error::Preamble, so a CR-terminated multi-certificate PEM fails load_pem_chain (RFC 7468 eol = CRLF / CR / LF)
Maintainer thường phản hồi trong vòng 1 ngày
Đánh giá
- Độ khó
- 2/5
- Thời gian dự kiến
- 1-3 giờ
- Mức phù hợp với người mới
- 77/100
Hướng nghiên cứu
Bắt đầu với strip_preamble của pem-rfc7468 trong src/grammar.rs và so sánh cách xử lý ranh giới của nó với các helper eol có xử lý CR ở đó. Thêm hoặc điều chỉnh một trường hợp hồi quy cho hai chứng chỉ PEM được phân tách bằng các ký tự xuống dòng CR đơn, sử dụng cách tái hiện được mô tả trong issue. Hoàn tất khi chuỗi chứng chỉ tải được cả hai chứng chỉ và giải mã trực tiếp chấp nhận thông điệp thứ hai sau một CR đơn.
Do mô hình lập chỉ mục viết ra từ nội dung của issue.
Mô tả
Hi,
Details, the source lines, and a self-contained reproduction are below.
Versions pinned
| Thing | Pin |
|---|---|
| pem-rfc7468 | 1.0.0, the newest release (2026-10-20), .crate sha256 a6305423e0e7738146434843d1694d621cce767262b2a86910beab705e4493d9 |
| x509-cert | 0.3.0, the newest release, 105ef4642d9cb137ef83d623d0e4bf08b8adf69e9918ca904a174adb6d3d038b, feature pem; over der 0.8.2 and base64ct 1.8.3 |
| the input | two v3 certificates assembled in harness/src/main.rs octet by octet, base64 and PEM written there too, in RFC 7468's strict form (64-character lines) |
| toolchain | rustc 1.98.0 (the repository's rust-toolchain.toml) |
The checksums are the ones in harness/Cargo.lock.
The rule
RFC 7468 §2: "Data before the encapsulation boundaries are permitted, and
parsers MUST NOT malfunction when processing such data. Furthermore, parsers
SHOULD ignore whitespace and other non-base64 characters and MUST handle
different newline conventions." "Files MAY contain multiple textual encoding instances. This
is used, for example, when a file contains several certificates."
§3's grammar: eol = CRLF / CR / LF, and the strict form every
generator SHOULD emit is stricttextualmsg = preeb eol strictbase64text posteb eol, so a lone CR is a conforming line end in every
figure, and two strict messages written one after the other put the second
-----BEGIN straight after the first's eol. The lax grammar names CR
before the boundary outright: laxtextualmsg = *W preeb, with
W = WSP / CR / LF / %x0B / %x0C.
What the code does
strip_preamble returns the input at once when it starts with
-----BEGIN ; otherwise it walks the bytes and stops only at an LF that the
boundary follows (src/grammar.rs:[email protected], at :71-73).
There is no arm for CR, though the file defines CHAR_CR
(src/grammar.rs:[email protected]) and the two eol helpers below it
accept a lone CR (src/grammar.rs:[email protected],
src/grammar.rs:[email protected]). With no LF at all, it ends at
Err(Error::Preamble) (:80), whose message reads "PEM preamble contains
invalid data (NUL byte)" (src/error.rs:[email protected]) — no NUL is
present. Every decode goes through it
(src/decoder.rs:[email protected]).
The base64 body is not the fault: base64ct trims a lone CR as a line end
(src/decoder.rs:[email protected], :517-519), which is why one
certificate decodes with any line end.
Certificate::load_pem_chain strips the input's trailing CR and LF octets,
then cuts it after each -----END CERTIFICATE----- and hands each piece to
from_pem (src/certificate.rs:[email protected], at :395-408 and
:410-420). The second piece therefore starts with the first message's last
eol: \n-----BEGIN and \r\n-----BEGIN pass strip_preamble; \r-----BEGIN
does not.
What repro.sh shows
| Key | LF | CRLF | lone CR | RFC 7468 |
|---|---|---|---|---|
load_pem_chain.one.* (control) |
Ok(1) |
Ok(1) |
Ok(1) |
read |
load_pem_chain.two.* |
Ok(2), same octets |
Ok(2), same octets |
Err |
read both |
decode_vec.after-eol.*: the second message after the first's eol |
Ok(CERTIFICATE) |
Ok(CERTIFICATE) |
Err(Preamble) |
read |
decode_vec.after-text.*: after a line of text, chain + eol |
Ok(CERTIFICATE) |
Ok(CERTIFICATE) |
Err(Preamble) |
read ("MUST NOT malfunction") |
same-octets says each decoded certificate re-encodes to the DER the
harness wrote. The info.* lines print x509-cert's error for the refused
chain; they are not part of the claim.
Severity, and what this does not claim
Conformance. Lone-CR line ends are rare (classic Mac OS text), and a single
certificate is read. The failure is a refusal, not an acceptance, so no
security property is claimed. decode_vec shows the Error::Preamble directly; through
load_pem_chain the run checks only that the chain is refused, and prints
the error.
Affected versions
pem-rfc7468 1.0.0 (newest), through x509-cert 0.3.0 (newest). Earlier
releases were not run. The ask: accept a
lone CR before the pre-encapsulation boundary, as the grammar's eol does.
The path
flowchart TD
in["cert 1 + cert 2, every eol = CR<br/>(RFC 7468 3: eol = CRLF / CR / LF)"]
in --> chain["Certificate::load_pem_chain<br/>certificate.rs:380-424"]
chain --> cut["cut after each -----END CERTIFICATE-----<br/>certificate.rs:410-420"]
cut --> p1["piece 1: -----BEGIN ... END-----"]
cut --> p2["piece 2: CR -----BEGIN ... END-----"]
p1 --> sp1["strip_preamble: starts with -----BEGIN<br/>grammar.rs:62-64"]
sp1 --> ok1["Certificate 1 decoded<br/>(base64ct trims a lone CR)"]
p2 --> sp2["strip_preamble: stops only at LF + -----BEGIN<br/>grammar.rs:66-78"]
sp2 --> pre["no LF anywhere: Err(Preamble)<br/>grammar.rs:80"]
pre --> fail["load_pem_chain: Err, the whole chain lost"]
lf["LF or CRLF: piece 2 starts LF -----BEGIN<br/>Ok(2)"]
classDef bad fill:#fde,stroke:#b35
classDef good fill:#def,stroke:#37b
class fail bad
class lf good
Reproduction script (self-contained)
Save it as repro.sh and run bash repro.sh. It writes the files it needs into a new temporary directory and runs the check there; it exits 0 when every observation matches this report. 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-PEMRFC7468-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.10.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a6ef517f0926dd24a1582492c791b6a4818a4d94e789a334894aa15b0d12f55c"
[[package]]
name = "der"
version = "0.8.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a878c850e9e421b20262e9b41f9c860e4785fa07541c266b62ff9d1ef998a80a"
dependencies = [
"const-oid",
"der_derive",
"flagset",
"pem-rfc7468",
"zeroize",
]
[[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 = "pem-rfc7468"
version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a6305423e0e7738146434843d1694d621cce767262b2a86910beab705e4493d9"
dependencies = [
"base64ct",
]
[[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.8.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7ef958a98b9d5da290cfc78946e9f3e61e1e62a18db0d92cac0b83cc161491a9"
dependencies = [
"base64ct",
"der",
]
[[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-pemrfc7468-001"
version = "0.0.0"
dependencies = [
"pem-rfc7468",
"x509-cert",
]
[[package]]
name = "x509-cert"
version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "105ef4642d9cb137ef83d623d0e4bf08b8adf69e9918ca904a174adb6d3d038b"
dependencies = [
"const-oid",
"der",
"spki",
]
[[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-PEMRFC7468-001's harness: pem-rfc7468 1.0.0 directly and under
# x509-cert 0.3.0's load_pem_chain (the newest of each). The harness writes
# the PEM text itself, so neither crate under test produces its own input.
[package]
name = "up-pemrfc7468-001"
version = "0.0.0"
edition = "2021"
publish = false
[dependencies]
pem-rfc7468 = { version = "=1.0.0", features = ["alloc"] }
x509-cert = { version = "=0.3.0", default-features = false, features = ["pem"] }
[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-PEMRFC7468-001: two PEM certificates, one after the other, with every
//! line ended by LF, by CRLF and by a lone CR (RFC 7468 §3: `eol = CRLF / CR
//! / LF`), through pem-rfc7468 1.0.0 directly and through x509-cert 0.3.0's
//! `Certificate::load_pem_chain`. The certificates are assembled and the PEM
//! text written here, so neither crate produces its own input. Prints
//! `OBS key=value`.
use pem_rfc7468::decode_vec;
use x509_cert::der::Encode as _;
use x509_cert::Certificate;
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())
}
/// X.690 §8.19 contents octets of an OID whose arcs after the first two are
/// each below 2^14.
fn oid(arcs: &[u32]) -> Vec<u8> {
let mut out = vec![(arcs[0] * 40 + arcs[1]) as u8];
for &arc in &arcs[2..] {
if arc >= 0x80 {
out.push(0x80 | (arc >> 7) as u8);
}
out.push((arc & 0x7f) as u8);
}
tlv(0x06, &out)
}
/// A v3 certificate with serial `serial`; nothing in it is signed.
fn certificate(serial: u8) -> 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-pemrfc7468-001")]))]);
let validity = seq(&[tlv(0x17, b"250101000000Z"), tlv(0x17, b"350101000000Z")]);
let mut point = vec![0x00, 0x04];
point.extend([0x22; 64]);
let spki = seq(&[
seq(&[oid(&[1, 2, 840, 10045, 2, 1]), oid(&[1, 2, 840, 10045, 3, 1, 7])]),
tlv(0x03, &point),
]);
let tbs = seq(&[
tlv(0xa0, &tlv(0x02, &[0x02])),
tlv(0x02, &[serial]),
ecdsa_sha256.clone(),
name.clone(),
validity,
name,
spki,
]);
seq(&[tbs, ecdsa_sha256, tlv(0x03, &[0x00, 0x01, 0x02, 0x03])])
}
/// RFC 4648 §4 base64, written here.
fn base64(data: &[u8]) -> String {
const ALPHABET: &[u8; 64] = b"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
let mut out = String::new();
for chunk in data.chunks(3) {
let b = [chunk[0], *chunk.get(1).unwrap_or(&0), *chunk.get(2).unwrap_or(&0)];
let n = (u32::from(b[0]) << 16) | (u32::from(b[1]) << 8) | u32::from(b[2]);
for i in 0..4 {
if i <= chunk.len() {
out.push(ALPHABET[((n >> (18 - 6 * i)) & 0x3f) as usize] as char);
} else {
out.push('=');
}
}
}
out
}
/// RFC 7468 Figure 3 (strict): `preeb eol`, 64-character lines, `posteb eol`,
/// with `eol` the given line end.
fn pem(der: &[u8], eol: &str) -> String {
let text = base64(der);
let mut out = format!("-----BEGIN CERTIFICATE-----{eol}");
for line in text.as_bytes().chunks(64) {
out.push_str(std::str::from_utf8(line).expect("ascii"));
out.push_str(eol);
}
out.push_str(&format!("-----END CERTIFICATE-----{eol}"));
out
}
fn obs(key: &str, value: impl std::fmt::Display) {
println!("OBS {key}={value}");
}
fn main() {
let first = certificate(1);
let second = certificate(2);
for (name, eol) in [("LF", "\n"), ("CRLF", "\r\n"), ("CR", "\r")] {
let one = pem(&first, eol);
let two = format!("{one}{}", pem(&second, eol));
// x509-cert 0.3.0: one certificate, then the chain of two.
match Certificate::load_pem_chain(one.as_bytes()) {
Ok(certs) => obs(&format!("load_pem_chain.one.{name}"), format!("Ok({})", certs.len())),
Err(e) => {
obs(&format!("load_pem_chain.one.{name}"), "Err");
obs(&format!("info.load_pem_chain.one.{name}.error"), e);
}
}
match Certificate::load_pem_chain(two.as_bytes()) {
Ok(certs) => {
obs(&format!("load_pem_chain.two.{name}"), format!("Ok({})", certs.len()));
let same = certs.len() == 2
&& certs[0].to_der().map(|d| d == first).unwrap_or(false)
&& certs[1].to_der().map(|d| d == second).unwrap_or(false);
obs(&format!("load_pem_chain.two.{name}.same-octets"), same);
}
Err(e) => {
obs(&format!("load_pem_chain.two.{name}"), "Err");
obs(&format!("info.load_pem_chain.two.{name}.error"), e);
}
}
// pem-rfc7468 1.0.0: the second message as load_pem_chain hands it
// over (the first message's last eol in front), and with a line of
// explanatory text in front.
for (what, preamble) in [("after-eol", eol.to_owned()), ("after-text", format!("chain{eol}"))] {
let input = format!("{preamble}{}", pem(&second, eol));
let got = match decode_vec(input.as_bytes()) {
Ok((label, der)) if der == second => format!("Ok({label})"),
Ok((label, _)) => format!("Ok({label}, other octets)"),
Err(e) => format!("Err({e:?})"),
};
obs(&format!("decode_vec.{what}.{name}"), got);
}
}
}
__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-PEMRFC7468-001: pem-rfc7468 1.0.0 (the newest release) finds
# a pre-encapsulation boundary only at the start of its input or after an
# LF, so when every line ends in a lone CR (RFC 7468 §3: `eol = CRLF / CR /
# LF`) x509-cert 0.3.0's Certificate::load_pem_chain reads one certificate
# and refuses a chain of two it reads with LF or CRLF. A defensive check
# over certificates and PEM text the harness writes itself.
#
# ./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/ (pem-rfc7468 1.0.0, x509-cert 0.3.0)"
out=$(run_harness) || { note "the harness did not build or run"; exit 2; }
printf '%s\n' "$out" | sed 's/^/ /'
# The controls: LF and CRLF read the chain, and one certificate is read
# with every line end, so the base64 body with lone CRs is not the fault.
compare control "$out" <<'EXPECT'
load_pem_chain.one.LF=Ok(1)
load_pem_chain.one.CRLF=Ok(1)
load_pem_chain.one.CR=Ok(1)
load_pem_chain.two.LF=Ok(2)
load_pem_chain.two.LF.same-octets=true
load_pem_chain.two.CRLF=Ok(2)
load_pem_chain.two.CRLF.same-octets=true
decode_vec.after-eol.LF=Ok(CERTIFICATE)
decode_vec.after-eol.CRLF=Ok(CERTIFICATE)
decode_vec.after-text.LF=Ok(CERTIFICATE)
decode_vec.after-text.CRLF=Ok(CERTIFICATE)
EXPECT
compare claim "$out" <<'EXPECT'
load_pem_chain.two.CR=Err
decode_vec.after-eol.CR=Err(Preamble)
decode_vec.after-text.CR=Err(Preamble)
EXPECT
finish UP-PEMRFC7468-001
__REPRO_FILE_5__
chmod +x "$dir/repro.sh"
cd "$dir" && ./repro.sh
Recorded run
date: 2026-10-21T10:16:31Z
arch: Darwin arm64
tools: bash 5.3.20(1)-release; git version 2.56.0; docker client 29.9.0; shellcheck 0.11.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/ (pem-rfc7468 1.0.0, x509-cert 0.3.0)
OBS load_pem_chain.one.LF=Ok(1)
OBS load_pem_chain.two.LF=Ok(2)
OBS load_pem_chain.two.LF.same-octets=true
OBS decode_vec.after-eol.LF=Ok(CERTIFICATE)
OBS decode_vec.after-text.LF=Ok(CERTIFICATE)
OBS load_pem_chain.one.CRLF=Ok(1)
OBS load_pem_chain.two.CRLF=Ok(2)
OBS load_pem_chain.two.CRLF.same-octets=true
OBS decode_vec.after-eol.CRLF=Ok(CERTIFICATE)
OBS decode_vec.after-text.CRLF=Ok(CERTIFICATE)
OBS load_pem_chain.one.CR=Ok(1)
OBS load_pem_chain.two.CR=Err
OBS info.load_pem_chain.two.CR.error=PEM error: PEM preamble contains invalid data (NUL byte)
OBS decode_vec.after-eol.CR=Err(Preamble)
OBS decode_vec.after-text.CR=Err(Preamble)
ok control: load_pem_chain.one.LF Ok(1)
ok control: load_pem_chain.one.CRLF Ok(1)
ok control: load_pem_chain.one.CR Ok(1)
ok control: load_pem_chain.two.LF Ok(2)
ok control: load_pem_chain.two.LF.same-octets true
ok control: load_pem_chain.two.CRLF Ok(2)
ok control: load_pem_chain.two.CRLF.same-octets true
ok control: decode_vec.after-eol.LF Ok(CERTIFICATE)
ok control: decode_vec.after-eol.CRLF Ok(CERTIFICATE)
ok control: decode_vec.after-text.LF Ok(CERTIFICATE)
ok control: decode_vec.after-text.CRLF Ok(CERTIFICATE)
ok claim: load_pem_chain.two.CR Err
ok claim: decode_vec.after-eol.CR Err(Preamble)
ok claim: decode_vec.after-text.CR Err(Preamble)
repro: all checks held: UP-PEMRFC7468-001 is shown as the report states it
exit: 0
- Ngôn ngữ chính
- Rust
- Star
- 344
- Fork
- 196
- Merge trung bình
- 1 ngày 17 giờ
- Pull request đã merge (30 ngày)
- 24
Chuẩn bị môi trường
Dự án này không cung cấp dev container, Dockerfile hay hướng dẫn đóng góp, nên bạn cần tự thiết lập môi trường: hãy bắt đầu từ README và xem hướng dẫn đóng góp lần đầu của chúng tôi để biết các bước chung.
Bắt đầu từ đâu
- Đọc hết issue, rồi đọc hướng dẫn đóng góp của dự án.
- Bình luận trên issue rằng bạn sẽ nhận — tránh hai người làm cùng một việc.
- Fork repository và làm thay đổi trên một nhánh.
- Mở pull request có tham chiếu số hiệu của issue.
Issue khác của RustCrypto/formats
-
IssuingDistributionPoint has the wrong AssociatedOid (id-pe-subjectInfoAccess)Có thể đã có người làm @eyusd đã nhận 85 ngày trước. Đang mở
Độ khó 1/5 1-3 giờ Mức phù hợp với người mới 86/100
RustCrypto/formats#2389 · 1 bình luận ·
Maintainer thường phản hồi trong vòng 1 ngày
-
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 68/100
RustCrypto/formats#2366 ·
Maintainer thường phản hồi trong vòng 1 ngày
-
x509-cert 0.3.0 declares RFC 5914's TrustAnchorInfo v1 as 0, so it encodes v1 as INTEGER 0 and reads a written version 0 as v1Có thể đã có người làm @choksi2212 đã nhận 6 ngày trước. Đang mở
Độ khó 3/5 1-2 ngày Mức phù hợp với người mới 61/100
RustCrypto/formats#2487 · 2 bình luận ·
Maintainer thường phản hồi trong vòng 1 ngày
-
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 decodeCó thể làm lại được Pull request cho issue này đã bị đóng mà không được merge. Đang mở
Độ khó 4/5 3-5 ngày Mức phù hợp với người mới 45/100
RustCrypto/formats#2485 · 3 bình luận ·
Maintainer thường phản hồi trong vòng 1 ngày
-
mcf: `PasswordHash::push_base64` with empty input produces an invalid hashCó thể đã có người làm @choksi2212 đã nhận 4 ngày trước. Đang mở
Độ khó 4/5 3-5 ngày Mức phù hợp với người mới 45/100
RustCrypto/formats#2471 ·
Maintainer thường phản hồi trong vòng 1 ngày
Tất cả issue của RustCrypto/formats
Issue tương tự
-
ai_p2 bug comp-datalake
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 85/100
ClickHouse/ClickHouse#128306 · 1 bình luận ·
Maintainer thường phản hồi trong vòng 1 ngày
-
documentation
Độ khó 1/5 Dưới một giờ Mức phù hợp với người mới 85/100
Maintainer thường phản hồi trong vòng 1 ngày
-
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 70/100
Maintainer thường phản hồi trong vòng 1 ngày
-
bug triage
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 85/100
Maintainer thường phản hồi trong vòng 1 ngày
-
Remove the preset version numberĐang mởarea: ui enhancement good first issue
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 70/100
JavenKazebee/capture-room#166 ·
Maintainer thường phản hồi trong vòng 1 ngày