Message d’erreur
invalid peer certificate: UnknownIssuer
Également affiché sous la forme
- InvalidCertificate(UnknownIssuer)
reqwest l’affiche à la fin de sa chaîne de causes : « error sending request for url (…): client error (Connect): invalid peer certificate: UnknownIssuer » ; la sortie Debug montre InvalidCertificate(UnknownIssuer). ureq affiche « io: invalid peer certificate: UnknownIssuer ». Les binaires natifs fondés sur rustls (pnpm 12, de nombreux outils CLI) affichent le même texte.
rustls (via reqwest, ureq, hyper-rustls, tonic) — rustls::Error::InvalidCertificate(CertificateError::UnknownIssuer)
Ce que cela signifie
rustls n’a pu rattacher le certificat du serveur à aucune des ancres de confiance avec lesquelles il a été configuré. UnknownIssuer est le code unique de rustls pour tout échec de construction du chemin : une AC privée ou de proxy, un certificat intermédiaire manquant ou un certificat auto-signé. Les racines considérées comme approuvées dépendent de la façon dont la crate a été compilée : le vérificateur de la plateforme (magasin du système d’exploitation), rustls-native-certs (racines du système chargées au démarrage) ou webpki-roots (liste de Mozilla intégrée à la compilation).
Pourquoi cela se produit
Une AC d’entreprise ou privée
fréquenteLa chaîne du serveur se termine par une racine qui ne figure pas parmi les ancres configurées, ce qui est typique des services internes et des proxys d’inspection TLS.
Le client ne fait confiance qu’aux racines publiques intégrées à la compilation
fréquenteLes crates compilées avec webpki-roots ignorent complètement le magasin du système d’exploitation : une racine installée par le service informatique ne s’applique donc jamais. Le vérificateur de la plateforme, utilisé par défaut par reqwest 0.13, s’appuie bien sur le magasin du système d’exploitation (comme l’a confirmé la reproduction après update-ca-certificates).
Le serveur omet son certificat intermédiaire
occasionnellerustls ne récupère pas les certificats intermédiaires manquants ; un serveur qui n’envoie que son certificat feuille échoue avec UnknownIssuer, même si la racine est approuvée.
Un certificat serveur auto-signé
occasionnellerustls signale aussi les certificats auto-signés comme UnknownIssuer ; faites confiance à ce certificat en tant que racine pour ce client, ou remplacez-le.
Comment corriger l’erreur
- 1.
Ajouter la racine au client
ClientBuilder::add_root_certificate ajoute une ancre tout en conservant une vérification complète (noms, dates).
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.
Installer la racine dans le magasin du système d’exploitation
Avec le vérificateur de la plateforme (par défaut dans reqwest 0.13), les racines du magasin du système d’exploitation sont approuvées ; sous Linux, update-ca-certificates suffit.
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.
Vérifier quelle source de racines est compilée
cargo tree indique si webpki-roots ou rustls-native-certs est utilisé ; modifiez les fonctionnalités (features) activées si le magasin du système d’exploitation doit s’appliquer.
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.
Propriétaires de serveurs : envoyer le certificat intermédiaire
Un seul certificat dans le handshake, dont l’émetteur est une AC intermédiaire, signifie que la configuration du serveur est incomplète.
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:'
Erreurs associées
invalid peer certificate: certificate expired: verification timerustls 0.23 (via reqwest, ureq, hyper-rustls)invalid peer certificate: certificate not valid for name "api.example.com"; cer…rustls 0.23 (via reqwest, ureq, hyper-rustls)Error: ERR_PNPM_RESOLVING_NPM_RESOLVER_NETWORK_ERRORpnpm 12 (native binary, rustls)x509: certificate signed by unknown authorityGo crypto/x509