¿Cómo puedo verificar / leer una CSR de renovación SSL de IIS7 con OpenSSL?

10

Tengo el privilegio de manejar ~ 5 CSR SSL por semana, verificando su validez antes de pasarlas a nuestra CA para la acción. Utilizo OpenSSL en una máquina Ubuntu para verificar que sean válidos, probando cosas como el nombre correcto de OU, un CN sensible, tamaño de clave> = 2048 bits, etc., ya que nuestras solicitudes a veces son incorrectas.

El otro día recibí una solicitud de renovación de una máquina IIS7. No puedo entender cómo leer esto, usando OpenSSL. Es válido, ya que mi CA lo ha aceptado ...

'file (1)' dice que es un "Texto de solicitud de firma de certificado de seguridad RFC1421", que es lo que dice para ~ 50% de las CSR que tengo aquí (el resto son "solicitud de certificado PEM").

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

openssl req, que lee CSR (PKCS # 10) no lo comprende ...

$ 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 artículo de Andreas Klein en los blogs de MSDN sugiere que los CSR de renovación de IIS7 son un contenedor PKCS # 7, con un CSR y una firma basada en el certificado actual ... pero aún no puedo leerlo.

$ 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

Puedo usar 'openssl base64' para decodificar el archivo, y en el archivo binario resultante puedo ver cadenas que se parecen a la CSR, y algunas referencias de CA que deben haber venido de una firma basada en el certificado anterior. Entonces, la idea del contenedor (CSR, firma) suena plausible.

¡Pero todavía no puedo encontrar una manera de leer la CSR que está ahí! He intentado muchas cosas, no enumeraré los detalles aquí, pero aquí están los puntos más altos de las variaciones que he probado: pkcs12 pkcs7 PEM DER req x509 verificar ...

Lamentablemente, no puedo publicar la CSR en sí. ¿Alguien puede ayudarme a encontrar una manera de leer / verificar este archivo?

Jim Cheetham
fuente
¿Por casualidad la solicitud contiene atributos que buscan un Nombre alternativo de sujeto?
Shane Madden
Lo dudo, es para un servidor interno con un solo nombre. Por supuesto, los certificados que recibimos generalmente tienen un campo SAN con 'www'. insertado a la fuerza, pero vivimos con eso!
Jim Cheetham
certutil de una máquina Windows leerá este cert, y lo describe como un mensaje PKCS7, con una Solicitud de certificado PKCS10 (que contiene el certificado x509 de la antigua CA) y una cadena de cert, que contiene otro certificado x509). 'certutil -split' divide estas partes, y Blob0_1.p10 es el CSR que espero encontrar, en formato DER. Así que me estoy acercando ... y sí, hay un campo SAN en la solicitud, que probablemente sea el resultado de la inserción forzada de 'www'. cuando obtuvimos el certificado original el año pasado ...
Jim Cheetham
1
openssl asn1parsepuedo leer la solicitud, y desde allí puedo extraer la CSR normal. Todavía no puedo responder (lo resolví demasiado rápido), así que actualizaré la pregunta con la solución y luego la arreglaré mañana :-)
Jim Cheetham
Bonito, buen hallazgo!
Shane Madden

Respuestas:

8

La estructura de esta solicitud de renovación de IIS7 es realmente bastante elegante. Parece partir de la premisa de que, dado que se trata de una solicitud para renovar un certificado actual , debe demostrar que la solicitud proviene del host correcto, es decir, el host que realmente utiliza el certificado actual y ∴ es propietario del privado asociado llave. En el mundo de Internet, usted demuestra que puede solicitar renovaciones para un certificado autenticándose en su CA como usuario original, en lugar de crear una CSR firmada.

Para demostrar el derecho a emitir una solicitud de renovación, IIS7 crea una CSR normal (objeto PKCS # 10), luego la firma y proporciona el certificado de la clave que la firmó.

  • IIS7 renovación CSR
    • Datos PKCS # 7
      • Datos PKCS # 10 (la CSR ordinaria)
    • Certificado de servidor normal
    • Emisión de datos de CA
    • Firma RSA (supongo)

Use openssl asn1parse -in iis7rcsr -ipara ver la estructura del archivo y compárelo con las CSR normales. Debería ver una OCTET STRING cerca del comienzo, en un objeto etiquetado ": pkcs7-data", que es lo que necesita extraer para obtener la 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 obtener el CSR PKCS # 10 real de aquí, necesitamos ese número de desplazamiento, "58" en este ejemplo. Entonces podemos usar ese desplazamiento para extraer la versión binaria de ese objeto:

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

A continuación, podemos leer ese archivo de salida 'thecsr' con openssl req, recordando especificar el 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
...

Puedo resumir todo esto en una línea de comandos sin archivos temporales (pero lamentablemente 2 lecturas del certificado original), siempre que pueda usar Linux /proc/self/fd/para engañar a openssl (hará trucos nativos con descriptores de archivo para el manejo de contraseñas, pero salida no 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):
...

Esta larga línea de comando es directamente equivalente a la simple openssl req -in non-iis7rcsr -noout -textque normalmente uso :-)

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

Gracias Jim por esta excelente información que fue de gran ayuda, tuve exactamente el mismo problema al intentar renovar un certificado de servidor w2008 / IIS7.

Yo agregaría solo una cosa. Puede extraer el CSR en formato P10 directamente con el siguiente comando: certutil -split iis7rcsr (iis7rcsr es el .csr que obtiene a través del administrador IIS). El csr se extraerá en un archivo llamado blob0_1.p10 Está en formato binario (DER), es posible que deba codificarlo en base64 con el siguiente comando: certutil -encode blob0_1.p10 finalcsr.csr

Sin embargo, hay un último problema. Luego descubrí, volcando el contenido .csr con openssl, que el proceso de renovación forzó automáticamente el uso de la clave de 1024 bits (a pesar de que la clave privada original creada en el servidor para el certificado del servidor tenía una longitud de 2048 bits). Parece que no puede forzar el uso de claves de 2048 bits utilizando el proceso de renovación de IIS7.

La única buena opción parece ser crear una nueva clave / certificado y no usar el proceso de renovación.

Florent Vélu
fuente