Mensagem de erro
verify error:num=21:unable to verify the first certificate
Também aparece como
- Verify return code: 21 (unable to verify the first certificate)
O openssl s_client imprime o erro como “verify error:num=21:…” e “Verify return code: 21 (…)”. O Node.js informa a mesma condição como UNABLE_TO_VERIFY_LEAF_SIGNATURE (“unable to verify the first certificate”).
OpenSSL CLI (openssl s_client) — X509_V_ERR_UNABLE_TO_VERIFY_LEAF_SIGNATURE
O que significa
Erro 21 do OpenSSL (X509_V_ERR_UNABLE_TO_VERIFY_LEAF_SIGNATURE): a cadeia é formada por um único certificado, o do próprio servidor, e o emissor dele não foi encontrado, então nem a assinatura do certificado folha pode ser verificada. O s_client costuma imprimir o erro 20 para a profundidade 0 logo antes. A solução quase sempre está no servidor: ele precisa enviar o certificado intermediário.
Por que acontece
O servidor está configurado só com o certificado folha
comumcert.pem em vez de fullchain.pem, um certificado colado em um balanceador de carga sem a cadeia ou uma entrada de keystore Java importada sem a CA emissora.
A cadeia está configurada, mas não é enviada
ocasionalAlguns servidores precisam da cadeia em uma diretiva ou campo separado (SSLCertificateChainFile em versões antigas do Apache, a caixa da cadeia em um balanceador de carga na nuvem); um bundle no lugar errado é ignorado silenciosamente.
O servidor envia um intermediário que não emitiu o certificado folha
ocasionalDepois que uma CA troca de intermediários, um arquivo de cadeia antigo envia um certificado que não é o emissor do certificado folha; o OpenSSL então não consegue usá-lo.
Como corrigir
- 1.
Verificar o que o servidor envia
Um único certificado cujo emissor (i:) é uma CA intermediária confirma o problema.
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:' - 2.
Servir certificado folha + intermediários
Concatene, na ordem, o certificado folha e os intermediários emissores e configure o servidor com esse arquivo; imprima o bundle para conferir a ordem.
bash # Build the file the server should use: leaf, then intermediates (issuer of each previous one) cat server.pem intermediate.pem > fullchain.pem openssl crl2pkcs7 -nocrl -certfile fullchain.pem | openssl pkcs7 -print_certs -noout # check the order - 3.
Encontrar o intermediário correto
A extensão Authority Information Access do certificado folha indica a URL do certificado do emissor; baixe-o, converta para PEM se necessário e adicione-o ao arquivo de cadeia.
bash # Where to download the missing intermediate: the leaf's Authority Information Access URL openssl x509 -in server.pem -noout -ext authorityInfoAccess curl -sS -o intermediate.der http://ca.example.com/issuing-ca.crt openssl x509 -inform der -in intermediate.der -out intermediate.pem