Como posso verificar / ler um CSR de renovação do IIS7 SSL com OpenSSL

10

Tenho o privilégio de manipular ~ 5 CSRs SSL por semana, verificando sua validade antes de transmiti-los à nossa CA para ação. Uso o OpenSSL em uma máquina Ubuntu para verificar se eles são válidos, testando coisas como o nome correto da UO, uma CN sensata, tamanho da chave> = 2048 bits e assim por diante, pois nossos pedidos às vezes são incorretos.

Outro dia, recebi uma solicitação de renovação de uma máquina IIS7. Não consigo descobrir como ler isso, usando o OpenSSL. É válido, pois minha CA o aceitou ...

'file (1)' diz que é um "texto de solicitação de assinatura de certificado de segurança RFC1421", que é o que diz para ~ 50% dos CSRs que tenho aqui (o restante é "solicitação de certificado PEM").

$ head iis7rcsr
-----BEGIN NEW CERTIFICATE REQUEST-----
MIIQsQYJKoZIhvcNAQcCoIIQojCCEJ4CAQExCzAJBgUrDgMCGgUAMIIJegYJKoZI
hvcNAQcBoIIJawSCCWcwggljMIIIzAIBADCB2zELMAkGA1UEBhMCTloxDTALBgNV
BBEMBDkwNTQxDjAMBgNVBAgMBU90YWdvMRAwDgYDVQQHDAdEdW5lZGluMRwwGgYD
...
...

openssl req, que lê CSRs (PKCS # 10) não consegue compreendê-lo ...

$ openssl req -in iis7rcsr -text
unable to load X509 request
5156:error:0D0680A8:asn1 encoding routines:ASN1_CHECK_TLEN:wrong tag:tasn_dec.c:1316:
5156:error:0D07803A:asn1 encoding routines:ASN1_ITEM_EX_D2I:nested asn1 error:tasn_dec.c:380:Type=X509_REQ_INFO
5156:error:0D08303A:asn1 encoding routines:ASN1_TEMPLATE_NOEXP_D2I:nested asn1 error:tasn_dec.c:748:Field=req_info, Type=X509_REQ
5156:error:0906700D:PEM routines:PEM_ASN1_read_bio:ASN1 lib:pem_oth.c:83:

Este artigo de Andreas Klein nos blogs do MSDN sugere que os CSRs de renovação do IIS7 são um contêiner PKCS # 7, com um CSR e uma assinatura com base no certificado atual ... mas ainda não consigo lê-lo.

$ openssl pkcs7 -in iis7rcsr -text
unable to load PKCS7 object
6581:error:0906D06C:PEM routines:PEM_read_bio:no start line:pem_lib.c:650:Expecting: PKCS7

Posso usar 'openssl base64' para decodificar o arquivo e, no arquivo binário resultante, vejo sequências que se parecem com o CSR e algumas referências de CA que devem ter vindo de uma assinatura baseada no certificado antigo. Portanto, a idéia de contêiner (CSR, assinatura) parece plausível.

Mas ainda não consigo encontrar uma maneira de ler o RSE! Eu tentei muitas coisas, não vou listar os detalhes aqui, mas aqui estão os pontos altos das variações que eu tentei: pkcs12 pkcs7 PEM DER req x509

Infelizmente, não posso postar o próprio CSR aqui. Alguém pode me ajudar a descobrir uma maneira de ler / verificar este arquivo?

Jim Cheetham
fonte
Por acaso, a solicitação contém atributos que procuram um Nome Alternativo para o Assunto?
Shane Madden
Duvido - é para um servidor interno com um único nome. É claro que os certificados que recebemos geralmente têm um campo SAN com 'www'. inserido à força, mas convivemos com isso!
Jim Cheetham
O certutil de uma máquina Windows lerá esse certificado e descreve como uma mensagem PKCS7, com uma Solicitação de certificado PKCS10 (contendo um certificado x509 da antiga CA) e uma cadeia de certificados contendo outro certificado x509. 'certutil -split' quebra essas partes e Blob0_1.p10 é o CSR que espero encontrar, no formato DER. Então, estou chegando mais perto ... e sim, há um campo SAN na solicitação, que provavelmente é o resultado da inserção forçada de 'www'. quando obtivemos o certificado original no ano passado ...
Jim Cheetham
1
openssl asn1parsepode ler a solicitação e a partir daí posso extrair o CSR normal. Eu não posso auto-resposta ainda (resolvido muito rapidamente), então eu vou atualizar a questão com a solução, e depois corrigi-lo amanhã :-)
Jim Cheetham
Bom, bom achado!
Shane Madden

Respostas:

8

A estrutura dessa solicitação de renovação do IIS7 é realmente bastante elegante. Parece partir da premissa de que, como se trata de uma solicitação para renovar um certificado atual , é necessário provar que a solicitação é proveniente do host correto - ou seja, o host que está realmente usando o certificado atual e é o proprietário privado associado chave. No mundo da Internet, você prova que tem permissão para solicitar renovações para um certificado, autenticando sua CA como usuário original, em vez de criar um CSR assinado.

Para provar o direito de emitir uma solicitação de renovação, o IIS7 cria um CSR normal (objeto PKCS # 10), assina e fornece o certificado da chave que o assinou.

  • CS7 de renovação do IIS7
    • PKCS # 7 Data
      • Dados PKCS # 10 (o CSR comum)
    • Certificado de servidor normal
    • Emitindo dados da CA
    • Assinatura RSA (presumo)

Use openssl asn1parse -in iis7rcsr -ipara ver a estrutura do arquivo e compare-a com os CSRs normais. Você deve ver um OCTET STRING próximo ao início, em um objeto chamado ": pkcs7-data", que é o que você precisa extrair para obter o CSR.

$ openssl asn1parse -in iis7rcsr -i
0:d=0  hl=4 l=4273 cons: SEQUENCE          
4:d=1  hl=2 l=   9 prim:  OBJECT            :pkcs7-signedData
15:d=1  hl=4 l=4258 cons:  cont [ 0 ]        
19:d=2  hl=4 l=4254 cons:   SEQUENCE          
23:d=3  hl=2 l=   1 prim:    INTEGER           :01
26:d=3  hl=2 l=  11 cons:    SET               
28:d=4  hl=2 l=   9 cons:     SEQUENCE          
30:d=5  hl=2 l=   5 prim:      OBJECT            :sha1
37:d=5  hl=2 l=   0 prim:      NULL              
39:d=3  hl=4 l=2426 cons:    SEQUENCE          
43:d=4  hl=2 l=   9 prim:     OBJECT            :pkcs7-data
54:d=4  hl=4 l=2411 cons:     cont [ 0 ]        
58:d=5  hl=4 l=2407 prim:      OCTET STRING      [HEX DUMP]:3082096330820...

Para obter o CSR PKCS # 10 real daqui, precisamos do número de deslocamento "58" neste exemplo. Em seguida, podemos usar esse deslocamento para extrair a versão binária desse objeto:

$ openssl asn1parse -in iis7rcsr -strparse 58 -out thecsr -noout

Em seguida, podemos ler o arquivo de saída 'thecsr' openssl req, lembrando-se de especificar o formato de entrada DER.

$ openssl req -in thecsr -inform DER -text -noout
Certificate Request:
Data:
    Version: 0 (0x0)
    Subject: (normal CSR Subject: line, censored)
    Subject Public Key Info:
        Public Key Algorithm: rsaEncryption
...

Eu posso agrupar tudo isso em uma linha de comando sem arquivos temporários (mas infelizmente 2 leituras do certificado original), desde que eu possa usar o Linux /proc/self/fd/para enganar o openssl (ele fará truques nativos com descritores de arquivo para manipulação de senhas, mas saída não normal).

$ openssl asn1parse -in iis7rcsr -strparse $(openssl asn1parse -in iis7rcsr | grep -A2 ':pkcs7-data'|tail -1|cut -d: -f1) -out /dev/stdout -noout | openssl req -inform DER -noout -text

Certificate Request:
Data:
    Version: 0 (0x0)
    Subject: (Subject: line censored again)
    Subject Public Key Info:
        Public Key Algorithm: rsaEncryption
        RSA Public Key: (1024 bit)
            Modulus (1024 bit):
...

Essa longa linha de comando é diretamente equivalente à simples openssl req -in non-iis7rcsr -noout -textque eu normalmente uso :-)

Jim Cheetham
fonte
É CMC tools.ietf.org/html/rfc5272#section-3.2
Daniel Fisher lennybacon
2

Obrigado Jim por essas excelentes informações que foram muito úteis, tive exatamente o mesmo problema ao tentar renovar um certificado de servidor w2008 / IIS7.

Eu acrescentaria apenas uma coisa. Você pode extrair o CSR no formato P10 diretamente com o seguinte comando: certutil -split iis7rcsr (iis7rcsr é o .csr obtido pelo gerenciador do IIS). O csr será então extraído em um arquivo chamado blob0_1.p10 É no formato binário (DER), talvez seja necessário codificá-lo na base64 com o seguinte comando: certutil -encode blob0_1.p10 finalcsr.csr

Há um último problema, no entanto. Descobri, ao despejar o conteúdo .csr no openssl, que o processo de renovação automaticamente forçou o uso da chave de 1024 bits (mesmo que a chave privada original criada no servidor para o certificado do servidor tivesse 2048 bits). Parece que você não pode forçar o uso de chaves de 2048 bits usando o processo de renovação do IIS7.

A única boa opção parece ser criar uma nova chave / certificado e não usar o processo de renovação.

Florent Vélu
fonte