diff --git a/.phive/phars.xml b/.phive/phars.xml index 3a2518b..ade4305 100644 --- a/.phive/phars.xml +++ b/.phive/phars.xml @@ -1,8 +1,8 @@ - + - - + + diff --git a/docs/CHANGELOG.md b/docs/CHANGELOG.md index dd50aa4..27e079e 100644 --- a/docs/CHANGELOG.md +++ b/docs/CHANGELOG.md @@ -11,6 +11,15 @@ versión, aunque sí su incorporación en la rama principal de trabajo. Generalm ## Listado de cambios +### Versión 1.2.1 2023-05-24 + +PHPStan detectó un uso inapropiado de conversión de objeto a cadena de caracteres. +Esta conversión es innecesaria, por lo que se eliminó. + +Se agregó información básica de cómo verificar un certificado emitido por el SAT usando OCSP. + +Se actualizaron las herramientas de desarrollo. + ### Versión 1.2.0 2023-02-24 Se agrega la funcionalidad para exportar (`PfxExporter`) y leer (`PfxReader`) una credencial con formato PKCS#12 (PFX). diff --git a/docs/VerificacionCertificadosSAT.md b/docs/VerificacionCertificadosSAT.md index 159c54b..b33294b 100644 --- a/docs/VerificacionCertificadosSAT.md +++ b/docs/VerificacionCertificadosSAT.md @@ -9,42 +9,36 @@ Al no tener un servicio público de verificación, el SAT comparte sus certifica Para ello necesitaremos de `openssl`. El procedimiento general consiste en: 1. Descargar los certificados raíz de producción -1. Convertir los certificados DER en PEM -1. Adaptar la carpeta para reconocerla como un directorio de Certificate Authority (CA) -1. Comparar el certificado PEM contra los certificados raíz. +2. Convertir los certificados DER en PEM +3. Adaptar la carpeta para reconocerla como un directorio de Certificate Authority (CA) +4. Comparar el certificado PEM contra los certificados raíz. Lo mejor sería que el SAT tuviera un servicio público de consulta de certificados, incluso saber si un certificado ha sido revocado, el problema es que sí tienen el servicio, pero está restringido a agencias gubernamentales -## Verificación de certificado +## Verificación local de certificado Con el siguiente comando se hace la verificación de un certificado ```shell -openssl verify -no_check_time -CApath sat_ca_prod - mi_certificado.pem +openssl verify -no_check_time -CApath sat_ca_prod mi_certificado.pem ``` Donde: - `-no_check_time`: No verificar que los certificados raíz sean válidos en el tiempo. - `-CAPath sat_ca_prod`: Lugar en donde están los certificados raíz ya procesados. -- `- mi_certificado.pem`: Certificado en formato PEM a validar +- `mi_certificado.pem`: Certificado en formato PEM a validar ## Creación de la carpeta de certificados raíz Una vez que tengas los archivos raíz descomprimidos puedes ejecutar estos comandos para que la carpeta sea -usable para el comando `openssl verify`. +usable para el comando `openssl verify` o `openssl ocsp`. * Exportar en formato PEM los certificados que no están como tal: -Para cada archivo `.cer` en el directorio `sat_ca_prod` ejecuta `openssl` para exportar de formato PEM a DER. - -```shell -find sat_ca_prod/ -type f -maxdepth 0 -name "*.cer" -exec \ - openssl x509 -inform DER -outform PEM -in "{}" -out "{}.pem" \ -\; -``` +Para cada archivo `.cer` o `.crt` en el directorio `sat_ca_prod` ejecuta `openssl` para exportar de formato DER a PEM. * Crear enlaces simbólicos a los archivos por el número de hash @@ -55,7 +49,7 @@ los archivos por número de hash, si no están así entonces no se tomarán en c openssl rehash sat_ca_prod ``` -## Script para crear toda la estructura de producción y pruebas +### Script para crear toda la estructura de producción y pruebas El siguiente script básico de bash ejecuta todos los comandos que se requieren para descargar, exportar y poder utilizar como `CApath` los certificados raíz ofrecidos por el SAT: @@ -63,28 +57,112 @@ utilizar como `CApath` los certificados raíz ofrecidos por el SAT: ```bash #!/bin/bash -e -CA_PROD_SOURCE="https://omawww.sat.gob.mx/tramitesyservicios/Paginas/documentos/Cert_Prod.zip" +CA_PROD_SOURCE="http://omawww.sat.gob.mx/tramitesyservicios/Paginas/documentos/Cert_Prod.zip" CA_PROD_DEST="ca_production" -CA_TEST_SOURCE="https://omawww.sat.gob.mx/tramitesyservicios/Paginas/documentos/Certificados_P.zip" +CA_TEST_SOURCE="http://omawww.sat.gob.mx/tramitesyservicios/Paginas/documentos/Certificados_P.zip" CA_TEST_DEST="ca_testing" -function extract() { +function extract_certificates() { local url="$1" local source="$(basename "$url")" + local extractto="${source%.*}" local ca_folder="$2" rm -f "$source" wget "$url" -O "$source" - rm -rf $ca_folder - mkdir -p "$ca_folder" - unzip "$source" -d "$ca_folder" - find . -type f -name "*.cer" -exec openssl x509 -inform DER -outform PEM -in "{}" -out "{}.pem" \; - find "$ca_folder" -type d -exec openssl rehash "{}" \; + rm -rf "$ca_folder" "$extractto" + mkdir -p "$ca_folder" "$extractto" + unzip "$source" -d "$extractto" + + find "$extractto" -type f \( -name "*.cer" -o -name "*.crt" \) | while read certificate; do + rename_or_convert_certificate "$certificate" "$ca_folder" + done + rm -rf "$extractto" + + openssl rehash "$ca_folder" +} + +function rename_or_convert_certificate { + local source="$1" + local sourcebasename="$(basename "$source")" + local destination="$2/${sourcebasename%.*}.pem" + if [ "text/plain" == "$(file "$source" -b --mime-type)" ]; then + echo "Copy $source -> $destination" + cp "$source" "$destination" + return; + fi + echo "Convert $source -> $destination" + openssl x509 -inform DER -outform PEM -in "$source" -out "$destination" } -extract "$CA_PROD_SOURCE" "$CA_PROD_DEST" -extract "$CA_TEST_SOURCE" "$CA_TEST_DEST" +extract_certificates "$CA_PROD_SOURCE" "$CA_PROD_DEST" +extract_certificates "$CA_TEST_SOURCE" "$CA_TEST_DEST" +``` + +## Verificación a través de OCSP + +A pesar de que el SAT anuncia que su servicio OCSP es privado, en realidad sí se encuentra públicamente disponible. + +El siguiente comando sirve para verificar un certificado (FIEL o CSD) emitido por el SAT. + +```shell +OPENSSL_CONF=/etc/ssl/openssl_custom.cnf \ + openssl ocsp -issuer ca_production/AC4_SAT.cer.pem -cert certificate.cer \ + -text -CApath ca_production -url https://cfdi.sat.gob.mx/edofiel +``` + +Y entrega una respuesta como: + +```text +Response verify OK +certificate.cer: revoked + This Update: May 23 14:44:07 2023 GMT + Next Update: May 23 14:45:07 2023 GMT + Reason: unspecified + Revocation Time: May 18 19:02:47 2023 GMT +``` + +### `OPENSSL_CONF=/etc/ssl/openssl_custom.cnf` + +El sitio del SAT no tiene la seguridad adecuada y las nuevas versiones de OpenSSL 3.x no permiten hacer la consulta. + +En 2023-05-23 se encontró que utilizaba `TLSv1.2, Cipher is DHE-RSA-AES256-GCM-SHA384 ... Server Temp Key: DH, 1024 bits` +y no es considerado seguro en el nivel 2 de OpenSSL: +*RSA, DSA and DH keys shorter than 2048 bits and ECC keys shorter than 224 bits are prohibited*. + +Por lo que hay que degradar la configuración a `SECLEVEL=1`, generalmente agregando la siguiente información: + +```ini +[openssl_init] +ssl_conf = ssl_sect + +[ssl_sect] +system_default = system_default_sect + +[system_default_sect] +CipherString = DEFAULT@SECLEVEL=1 +``` + +### `-issuer ca_production/AC4_SAT.cer.pem` + +El certificado padre del SAT, si se está usando el certificado incorrecto el comando fallará y +mostrará un mensaje de error como este: + +```text +Responder Error: trylater (3) ``` +### `-cert certificate.cer` + +El certificado que se desea revisar, no es necesario convertirlo a formato PEM. + +### `-url https://cfdi.sat.gob.mx/edofiel` + +Dirección del servicio OSCP del SAT. + +### `-CApath ca_production` + +Dirección donde están los certificados de confianza del SAT. + ## Verificación de certificados a través de la página del Gobierno de Colima El Gobierno de Colima expone una API JSON en que sirve para el propósito diff --git a/src/Internal/DataArrayTrait.php b/src/Internal/DataArrayTrait.php index ee6e985..6ed6f62 100644 --- a/src/Internal/DataArrayTrait.php +++ b/src/Internal/DataArrayTrait.php @@ -54,7 +54,7 @@ protected function extractArrayStrings(string $key): array { $array = []; foreach ($this->extractArray($key) as $name => $value) { - if (is_scalar($value) || is_object($value)) { + if (is_scalar($value)) { $array[$name] = strval($value); } }