Debe tener en cuenta RFC3280 section 6.1 y RFC5280 section 6.1. Ambos describen algoritmos para validar rutas de certificado. A pesar de que Win32 API se encarga de algunas cosas para usted, aún podría ser valioso saber sobre el proceso en general.
Además, aquí hay una (en mi opinión) referencia bastante confiable: Chromium certificate verification code.
En general, creo que su código no es incorrecto. Pero aquí hay algunas cosas que me gustaría mirar en/cambio, si yo fuera usted:
1. Separar Nombre común de validación
cromo valida nombre común del certificado por separado de la cadena. Aparentemente han notado algunos problemas con eso. Ver los comentarios de su razón de ser:
cert_verify_proc.win.cc:731 // Certificate name validation happens separately, later, using an internal
cert_verify_proc.win.cc:732 // routine that has better support for RFC 6125 name matching.
2. Uso CERT_CHAIN_REVOCATION_CHECK_CHAIN_EXCLUDE_ROOT
cromo también utiliza el indicador CERT_CHAIN_REVOCATION_CHECK_CHAIN_EXCLUDE_ROOT en lugar de CERT_CHAIN_REVOCATION_CHECK_CHAIN. De hecho, comencé a investigar esto antes de encontrar su código, y reforzaba mi creencia de que debería usar CERT_CHAIN_REVOCATION_CHECK_CHAIN_EXCLUDE_ROOT.
Aunque ambos RFC antes mencionados especifican que un delimitador de confianza autofirmado no se considera parte de una cadena, la documentación para CertGetCertificateChain (http://msdn.microsoft.com/en-us/library/windows/desktop/aa376078(v=vs.85).aspx) dice que crea una cadena de hasta, si es posible, un certificado raíz de confianza. Un certificado raíz confiable se define (en la misma página) como un certificado autofirmado de confianza.
Esto elimina la posibilidad de que * EXCLUDE_ROOT saltee la comprobación de revocación de un ancla de confianza no raíz (Win32 realmente requiere que los enlaces de confianza sean autofirmados, aunque no lo exija ningún RFC. Aunque esto no es oficialmente documentado).
Ahora, dado que un certificado de CA raíz no puede revocarse a sí mismo (no se pudo firmar/verificar la CRL), me parece que estos dos indicadores son idénticos.
Hice algunos googleando y tropecé con esta publicación en el foro: http://social.msdn.microsoft.com/Forums/windowsdesktop/en-US/9f95882a-1a68-477a-80ee-0a7e3c7ae5cf/x509revocationflag-question?forum=windowssecurity. Un miembro de .NET Product Group (supuestamente) afirma que las banderas en la práctica actúan de la misma manera, si la raíz está autofirmada (en teoría, el indicador ENTIRE_CHAIN verificaría la revocación del certificado raíz si incluía una extensión CDP, pero no puede suceder).
También recomienda utilizar el indicador * EXCLUDE_ROOT, porque el otro indicador podría causar una solicitud de red innecesaria, si la CA raíz con firma automática incluye la extensión CDP.
Desafortunadamente:
- no puedo encontrar ninguna explicación documentada oficialmente en las diferencias entre las dos banderas.
- Aunque es probable que la discusión vinculada se aplique a los mismos indicadores de API Win32 bajo el capó de .NET, no está garantizada.
Para estar completamente seguro de que es aceptable utilizar CERT_CHAIN_REVOCATION_CHECK_CHAIN_EXCLUDE_ROOT, busqué en Google un poco más y encontré el código de verificación del certificado SSL cromo he vinculado en la parte superior de mi respuesta.
Como un beneficio adicional, el archivo cert_verify_proc_win.cc cromo contiene las siguientes pistas acerca de IE código de verificación:
618: // IE passes a non-NULL pTime argument that specifies the current system
619: // time. IE passes CERT_CHAIN_REVOCATION_CHECK_CHAIN_EXCLUDE_ROOT as the
620: // chain_flags argument.
No estoy seguro de cómo habían saben esto, pero en este momento me sentiría cómodo usando CERT_CHAIN_REVOCATION_CHECK_EXCLUDE_ROOT.
3. Certificado Aceptado diferentes usos
me di cromo también especifica 3 usos de certificados en vez de 1:
szOID_PKIX_KP_SERVER_AUTH,
szOID_SERVER_GATED_CRYPTO,
szOID_SGC_NETSCAPE
De lo que he entendido a través de Google, los otros usos pueden ser requeridos por web más antiguo navegadores, de lo contrario, pueden no establecer una conexión segura.
Si Chromium considera adecuado incluir estos usos, lo seguiría.
Tenga en cuenta que si cambia su código, también debe establecer params.RequestedUsage.dwType a USAGE_MATCH_TYPE_OR en lugar de USAGE_MATCH_TYPE_AND.
-
No puedo pensar en cualquier otro comentario por el momento.Pero si yo fuera tú, verificaría la fuente Chromium (y tal vez también Firefox), solo para asegurarme de que no me he perdido nada.
No mencionaste para qué estás utilizando esto, pero sí, en general, debes aprobar CERT_CHAIN_REVOCATION_CHECK_CHAIN_EXCLUDE_ROOT si estás utilizando esto en un escenario HTTPS típico. – EricLaw
Principalmente quiero usar esto para verificar los certificados SSL del servidor LDAP (como, dentro de una función VERIFYSERVERCERT). También estoy pensando en usarlo para verificar certificados de servidor HTTPS en una aplicación cliente/servidor donde los clientes pueden especificar su propio certificado SSL para el servidor. – briangreenery
¿Es más común usar CERT_CHAIN_REVOCATION_CHECK_CHAIN_EXCLUDE_ROOT en lugar de CERT_CHAIN_REVOCATION_CHECK_CHAIN? ¿Por qué no verificaría el certificado raíz para las revocaciones? – briangreenery