Hacktoberfest 2026:メンテナが10月に向けて印を付けた、オープンで初心者向けの issue。 Hacktoberfest の issue を見る

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)

オープン 初心者向け
#2,486 コメント 1 件 リアクション 0 件 担当者 0 名 GitHub で見る

メンテナーはふだん 1 日以内に返信

@choksi2212 がすでに取り組んでいます。

2026年10月24日 から。

  • #2488 @choksi2212 による — オープン

評価

難易度
2/5
見積もり時間
1〜3時間
初心者へのやさしさ
77/100
issue の種類
バグ
明瞭さ
明確に書かれている
活発さ
活発
技術スタック
rust
領域
backend, security

調査の方向性

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 を読み、一般的な手順ははじめてのコントリビューションガイドを参照してください。

はじめの一歩

  1. issue を最後まで読み、次にプロジェクトのコントリビューションガイドを読みます。
  2. 着手することを issue にコメントします — 二人が同じ作業をするのを防げます。
  3. リポジトリをフォークし、ブランチを切って変更します。
  4. issue 番号を参照したプルリクエストを送ります。

RustCrypto/formats のほかの issue

RustCrypto/formats の issue をすべて見る

似ている issue

Rust の issue をもっと見る

新しい issue をメールで受け取る

初心者向けの GitHub issue を短くまとめたダイジェスト。