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)
メンテナーはふだん 1 日以内に返信
評価
- 難易度
- 2/5
- 見積もり時間
- 1〜3時間
- 初心者へのやさしさ
- 77/100
調査の方向性
src/grammar.rs の pem-rfc7468 にある strip_preamble から始め、そこでの CR に対応した eol ヘルパーと境界の処理を比較してください。issue に記載された再現手順を使い、単独の CR 改行で区切られた 2 つの PEM 証明書の回帰テストを追加または調整してください。証明書チェーンが両方の証明書を読み込み、直接デコードで単独の CR の後の 2 つ目のメッセージを受け付ければ完了です。
索引モデルが issue の本文から書いたものです。
説明
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
- 主要言語
- Rust
- スター
- 344
- フォーク
- 196
- 平均マージ
- 1日 17時間
- マージ済み PR(30日)
- 24
環境構築
このプロジェクトには開発コンテナ、Dockerfile、コントリビューションガイドがありません。まず README を読み、一般的な手順ははじめてのコントリビューションガイドを参照してください。
はじめの一歩
- issue を最後まで読み、次にプロジェクトのコントリビューションガイドを読みます。
- 着手することを issue にコメントします — 二人が同じ作業をするのを防げます。
- リポジトリをフォークし、ブランチを切って変更します。
- issue 番号を参照したプルリクエストを送ります。
RustCrypto/formats のほかの issue
-
IssuingDistributionPoint has the wrong AssociatedOid (id-pe-subjectInfoAccess)対応中かも @eyusd が 84 日前に担当しました。 オープン
難易度 1/5 1〜3時間 初心者へのやさしさ 86/100
RustCrypto/formats#2389 · コメント 1 件 ·
メンテナーはふだん 1 日以内に返信
-
難易度 2/5 1〜3時間 初心者へのやさしさ 68/100
RustCrypto/formats#2366 ·
メンテナーはふだん 1 日以内に返信
-
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 v1対応中かも @choksi2212 が 6 日前に担当しました。 オープン
難易度 3/5 1〜2日 初心者へのやさしさ 61/100
RustCrypto/formats#2487 · コメント 2 件 ·
メンテナーはふだん 1 日以内に返信
-
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再び着手できるかも このイシューのプルリクエストはマージされずにクローズされました。 オープン
難易度 4/5 3〜5日 初心者へのやさしさ 45/100
RustCrypto/formats#2485 · コメント 3 件 ·
メンテナーはふだん 1 日以内に返信
-
mcf: `PasswordHash::push_base64` with empty input produces an invalid hash対応中かも @choksi2212 が 4 日前に担当しました。 オープン
難易度 4/5 3〜5日 初心者へのやさしさ 45/100
RustCrypto/formats#2471 ·
メンテナーはふだん 1 日以内に返信
RustCrypto/formats の issue をすべて見る
似ている issue
-
good first issue help wanted r-docs
難易度 2/5 1〜3時間 初心者へのやさしさ 72/100
servo/rust-smallvec#824 ·
メンテナーはふだん 1 日以内に返信
-
難易度 2/5 1〜3時間 初心者へのやさしさ 83/100
メンテナーはふだん 1 日以内に返信
-
priority middle
難易度 1/5 1時間未満 初心者へのやさしさ 62/100
KATO-Hiro/AtCoderClans#12940 ·
メンテナーはふだん 1 日以内に返信
-
bug
難易度 2/5 1〜3時間 初心者へのやさしさ 83/100
メンテナーはふだん 1 日以内に返信
-
o8 next debug build aborts on Glass to Dark appearance switch (nil identifier messaged before check)オープンbug
難易度 2/5 1〜3時間 初心者へのやさしさ 78/100
hurttlocker/o8#5112 ·