本文へスキップ
ecdsa.com
rustls (via reqwest, ureq, hyper-rustls, tonic)Rust

エラーメッセージ

invalid peer certificate: UnknownIssuer

別の表記

  • InvalidCertificate(UnknownIssuer)

reqwest は、原因の連鎖の末尾に「error sending request for url (…): client error (Connect): invalid peer certificate: UnknownIssuer」と出力します。Debug 出力では InvalidCertificate(UnknownIssuer) と表示されます。ureq は「io: invalid peer certificate: UnknownIssuer」と出力します。rustls を基盤とするネイティブバイナリ(pnpm 12、多くの CLI)も同じテキストを表示します。

rustls (via reqwest, ureq, hyper-rustls, tonic) — rustls::Error::InvalidCertificate(CertificateError::UnknownIssuer)

このエラーの意味

rustls は、サーバーの証明書を、設定されたどのトラストアンカーにもチェーンでつなげられませんでした。UnknownIssuer は、パス構築のあらゆる失敗に対して rustls が返す唯一のコードで、プライベート CA やプロキシの CA、中間証明書の欠落、自己署名証明書のいずれでもこのコードになります。どのルートが信頼されるかは、クレートのビルド方法によって決まります。プラットフォーム検証器(OS のストア)、rustls-native-certs(起動時に読み込まれる OS のルート)、webpki-roots(コンパイル時に組み込まれる Mozilla のリスト)のいずれかです。

発生する理由

修正方法

  1. 1.

    クライアントにルートを追加する

    ClientBuilder::add_root_certificate は、完全な検証(名前、日付)を保ったまま、トラストアンカーを追加します。

    rust
    // Trust a private root for this client (in addition to the default roots)
    let pem = std::fs::read("corp-root-ca.pem")?;
    let client = reqwest::Client::builder()
        .add_root_certificate(reqwest::Certificate::from_pem(&pem)?)
        .build()?;
  2. 2.

    ルートを OS のストアにインストールする

    プラットフォーム検証器(reqwest 0.13 のデフォルト)では、オペレーティングシステムのストアにあるルートが信頼されます。Linux では update-ca-certificates を実行するだけで十分です。

    bash
    # reqwest 0.13 verifies with the platform verifier: install the root in the OS store
    sudo cp corp-root-ca.pem /usr/local/share/ca-certificates/corp-root-ca.crt
    sudo update-ca-certificates
  3. 3.

    組み込まれているルートの取得元を確認する

    cargo tree で、webpki-roots と rustls-native-certs のどちらが使われているかがわかります。OS のストアを適用する必要がある場合は、フィーチャーを切り替えてください。

    bash
    # Which root source is compiled into this binary? (a crate that is absent reports no match)
    cargo tree -e features -i rustls-platform-verifier   # OS verifier (reqwest 0.13 default)
    cargo tree -e features -i rustls-native-certs        # OS roots loaded at start-up
    cargo tree -e features -i webpki-roots               # Mozilla roots compiled in, OS store ignored
  4. 4.

    サーバー管理者:中間証明書を送信する

    ハンドシェイクに含まれる証明書が 1 つだけで、その発行者が中間 CA である場合は、サーバーの設定が不完全です。

    bash
    openssl s_client -connect api.example.com:443 -servername api.example.com -showcerts </dev/null 2>/dev/null \
      | grep -E '^ *[0-9]+ s:|^ *i:'

関連するエラー

署名エラーデータベースをすべて見る