Extensiones de certificado personalizadas

Las extensiones personalizadas se agregan y eliminan en la página de Configuración del sistema EJBCA en la pestaña Extensiones de certificado personalizadas .

Descripción general

Se puede agregar una extensión simple que solo contenga un valor estático mediante la clase BasicCertificateExtension , ya implementada. Se pueden crear extensiones personalizadas más avanzadas implementando la interfaz org.cesecore.certificates.certificate.certextensions.CustomCertificateExtension y haciendo que la implementación esté disponible en la ruta de clases mediante ServiceLoader de Java. Para más información, consulte BasicCertificateExtension.java. Al implementar la interfaz de marcador y configurar los campos de propiedad y los valores predeterminados, EJBCA puede generar automáticamente una tabla de propiedades para la extensión.

Configuración de extensiones de certificado personalizadas

Las extensiones de certificado se configuran en la pestaña Extensiones de certificado personalizadas ( IU de CA → Configuración del sistema Extensiones de certificado personalizadas ). Solo los administradores con la regla de acceso '/system_functionality/edit_available_custom_certificate_extensions' pueden agregar y eliminar extensiones de certificado personalizadas.

Las siguientes propiedades están disponibles para cada extensión:

Propiedad

Descripción

Identificador de origen

El identificador único de objeto (OID) de la extensión. Valor obligatorio. También puede definirse como un OID comodín .

Nombre para mostrar

Nombre para mostrar de la extensión en la página Editar perfil de certificado. Valor obligatorio.

Clase de extensión

Nombre completo de la clase que implementa CertificateExtension. Valor obligatorio.

Crítico

Define si la extensión debe marcarse como crítica en el certificado.

Requerido

Habilitado por defecto, lo que hace que la extensión sea obligatoria en la solicitud. Desactivar "Obligatorio" permite que una solicitud contenga opcionalmente la extensión definida. De no ser así, se ignorará.

Propiedades

Las propiedades son inherentes a cada implementación de extensión.

Al agregar una nueva extensión de certificado personalizado, se especifican el OID y el nombre para mostrar y se crea una nueva extensión con los siguientes valores predeterminados:

  • Ruta de clase : org.cesecore.certificates.certificate.certextensions.BasicCertificateExtension

  • Crítico : Falso

  • Propiedades : Lista vacía de propiedades

Haga clic en la extensión recién creada para editar estos valores.

Una vez agregadas las extensiones, es posible seleccionarlas para un perfil de certificado en la página Editar perfil de certificado .

Usando la bandera Requerido

Cuando se selecciona una extensión como obligatoria (predeterminada) y se establece la propiedad de extensión dynamic=true , se debe proporcionar un valor. Puede ser un valor predeterminado, especificado en las propiedades de la extensión, o un valor especificado como Datos de Extensión de Certificado Personalizados (véase más adelante). En ocasiones, es necesario especificar una extensión como opcional para que el emisor (normalmente una RA) pueda decidir si se debe incluir o no. Al establecer Required=false, se puede excluir una extensión con un valor dinámico al no proporcionarla en la solicitud.

Definición de extensión de certificado y ASN.1

La definición de una extensión de certificado se encuentra en el RFC 5280. Específicamente, la codificación ASN.1 de las extensiones se encuentra en la sección 4.1 del RFC 5280 .

La sección especifica que el valor de extensión (extnValue) es una cadena de octetos que encapsula la secuencia de extensión real.

Extension ::= SEQUENCE {
extnID OBJECT IDENTIFIER,
critical BOOLEAN DEFAULT FALSE,
extnValue OCTET STRING
-- contains the DER encoding of an ASN.1 value
-- corresponding to the extension type identified
-- by extnID
}

Esta encapsulación la gestiona EJBCA para el tipo de valor que introduzca. Por ejemplo, si añade un valor de extensión DEROCTETSTRING, como se especifica a continuación, el ASN.1 real será una cadena de octetos encapsulada en otra cadena de octetos. Asimismo, los datos con codificación hexadecimal que introduzca como DEROBJECT corresponden a la "codificación DER de un valor ASN.1 correspondiente al tipo de extensión", como se especifica en el bloque ASN.1 anterior.

OCSP debe graparse

Ejemplo de configuración de extensión para la extensión de función OCSP Must Staple TLS:

  • Identificador de objeto: 1.3.6.1.5.5.7.1.24

  • Etiqueta: OCSP debe graparse

  • Clase de extensión: Extensión de certificado básico

  • Crítico: falso

  • Obligatorio: falso

  • Propiedades:

    • Dinámica: falsa

    • Codificación: DEROBJECT

    • Valor: 3003020105

O para fines ilustrativos, también puede establecer lo siguiente:

  • Propiedades:

    • Dinámica: verdadera

    • Codificación: DEROBJECT

    • Valor: (vacío)

Al marcar los datos de extensión de certificado personalizado en el perfil de entidad final, aparecerá un campo de ingreso de Datos de extensión de certificado al agregar o editar entidades finales.

Si este campo se deja vacío (y no se ha especificado ningún valor estático para la extensión), la generación de un certificado para la entidad final dará como resultado que no se agregue ninguna extensión al certificado emitido.

Al ingresar los siguientes datos en el campo de ingreso de Datos de extensión del certificado, se agregará la extensión OCSP Must Staple al certificado emitido:

1.3 . 6.1 . 5.5 . 7.1 . 24 .value= 3003020105

Contenido del certificado emitido (de dumpasn1 ...) :

OBJECT IDENTIFIER '1 3 6 1 5 5 7 1 24'
OCTET STRING, encapsulates {
SEQUENCE {
INTEGER 5
}
}

OID comodín

El OID de la extensión puede configurarse como un comodín, por ejemplo, *.1.2.3 . Esto hará que la configuración coincida con cualquier OID solicitado , coincidiendo con el patrón (terminando así en .1.2.3 ). Una vez encontrado el OID, el valor dinámico de la solicitud se utilizará en el certificado. Dado que el comodín en sí no es un OID válido, siempre debe haber un OID real que coincida con él en la solicitud (a menos que se borre la opción "Required" , en cuyo caso se ignora). Por lo tanto, las configuraciones de comodines no pueden recurrir al valor estático definido si la extensión no se encuentra en la solicitud.

Eliminar una extensión de certificado personalizada

Si se elimina una extensión de certificado personalizada, actualmente en uso en un perfil de certificado, de la lista de extensiones disponibles en Extensiones de Certificado Personalizadas , se mostrará una advertencia con los perfiles de certificado que la utilizan. La extensión no se eliminará del perfil de certificado, ya que aún se utiliza. Sin embargo, no se podrá utilizar ni formará parte de ningún certificado emitido después de la eliminación y se mostrará como OID (Ya no se utiliza. Desactive esta opción) en la página Editar Perfil de Certificado . Para eliminar una extensión en uso del perfil de certificado, bórrela manualmente de la lista de Extensiones de Certificado Personalizadas Usadas en la página Editar Perfil de Certificado .

Extensión del certificado básico

Para crear una extensión de certificado básica, configure la ruta de clase en 'org.cesecore.certificates.certificate.certextensions.BasicCertificateExtension' (configuración predeterminada) y especifique la codificación y el valor de las propiedades ( el valor es opcional si hay una propiedad 'dynamic=true').

La siguiente tabla enumera las codificaciones disponibles y cómo se interpreta su valor.

Codificación

Valor

DERBITSTRING

Una cadena que contiene los caracteres '0' y '1'. El valor introducido se codificará en una cadena de bits ASN.1 con el valor introducido. Por ejemplo, "10011011".

DERINTEGER

Una cadena que contiene solo dígitos decimales. El valor que introduzca se codificará en un entero ASN.1 con el valor introducido. Por ejemplo, "123".

DEROCTETSTRING

Una cadena que contiene una representación de datos hexadecimales. El valor que introduzca se codificará en una cadena de octetos ASN.1 con el valor introducido. Por ejemplo, "mi cadena".

DERBOOLEAN

La cadena es 'true' o 'false'. El valor que introduzca se codificará en un booleano ASN.1.

CADENA IMPRIMIBLE

Una cadena que contiene caracteres imprimibles válidos (az, 0-9). El valor que introduzca se codificará en una cadena imprimible ASN.1, con las limitaciones del conjunto de caracteres.

DERUTF8STRING

Una cadena en formato UTF-8. El valor que introduzca se codificará en una cadena ASN.1 UTF-8, con menos limitaciones de caracteres que una cadena imprimible.

DERIA5STRING

Una cadena IA5String ASN.1 que contiene caracteres de cadena imprimibles válidos (az, 0-9).

DERNULL

Valor vacío. Se codifica en un valor ASN.1 NULL, que en realidad es una etiqueta y, por lo tanto, se codifica en bytes ASN.1.

DESROBAR

El valor DER hexadecimal de las extensiones. Puede usarlo para crear una extensión con secuencias, etc. Los datos hexadecimales que introduzca corresponden a la "codificación DER de un valor ASN.1 correspondiente al tipo de extensión", como se especifica en la sección 4.1 de RFC5280 (véase más arriba).

CRUDO

El valor de la matriz de bytes de las extensiones, codificado en hexadecimal. Puede proporcionar cualquier dato codificado en hexadecimal para usarlo como bytes del valor de la extensión, incluso datos que infrinjan la norma RFC5280. No lo utilice a menos que tenga una razón heredada que requiera crear certificados con codificación no válida.

En 'src/java/certextensions.properties' se ofrecen ejemplos de extensiones de certificado que puede configurar con BasicCertificateExtension.

  • Políticas de aplicaciones de MS

  • Tipo de certificado de Netscape

  • Comentario de Netscape

  • URL de revocación de NetscapeCAR

  • URL de revocación de Netscape

  • ...

Si la propiedad dinámica se configura como verdadera , el valor de la extensión puede obtenerse de los datos de extensión proporcionados con la entidad final. Para obtener más información sobre cómo agregar datos de extensión mediante la Web de administración, consulte Datos de extensión de certificado personalizados .

Creación de una extensión personalizada a partir de un certificado existente

<p >Si tiene un certificado existente con una extensión específica que desea agregar en EJBCA, y la extensión aún no está presente como una opción en la interfaz de usuario de EJBCA, puede extraer la extensión del certificado existente y agregarla como una extensión personalizada.

Si tiene un certificado con restricciones de política, un volcado de OpenSSL puede verse así:

>openssl x509 -in cert.pem -text
...
X509v3 Policy Constraints:
Require Explicit Policy:0, Inhibit Policy Mapping:0
X509v3 Inhibit Any Policy:
0
...

Para agregar esta extensión de restricciones de políticas a EJBCA, haga lo siguiente.

  1. Extraiga los datos codificados DER reales:

    >openssl asn1parse -in cert.pem -i
    ...
    1555:d=5 hl=2 l= 3 prim: OBJECT :X509v3 Policy Constraints
    1560:d=5 hl=2 l= 8 prim: OCTET STRING [HEX DUMP]:3006800100810100
    1570:d=4 hl=2 l= 10 cons: SEQUENCE
    1572:d=5 hl=2 l= 3 prim: OBJECT :X509v3 Inhibit Any Policy
    1577:d=5 hl=2 l= 3 prim: OCTET STRING [HEX DUMP]:020100
    ...
  2. Luego, para agregar el valor 3006800100810100 como una extensión de certificado personalizado DEROBJECT:

    • Vaya a Configuración del sistemaExtensiones de certificado personalizadas y especifique lo siguiente:

      • OID = 2.5.29.36

      • Etiqueta =PolicyConstraints_Explicit0_Inhibit0 (cualquier etiqueta que considere apropiada y lógica para la configuración de su sistema).

      • Haga clic en Agregar .

    • Haga clic en Editar para la entrada recién creada y especifique lo siguiente:

      • Dinámico = falso

      • Codificación =DEROBJECT

      • Valor = 3006800100810100

    • Haga clic en Guardar .

A continuación, edite un perfil de certificado y seleccione "PolicyConstraints_Explicit0_Inhibit0 " en la lista " Extensiones de certificado personalizadas utilizadas" . Por último, emita el certificado y verifique que la extensión esté presente y sea la esperada.

Implementación de una extensión de certificado avanzada

Para crear una extensión avanzada, necesita crear una clase Java que implemente la interfaz CustomCertificateExtension. Recomendamos extender la clase StandardCertificateExtension. El método getValue es obligatorio y los datos de usuario actuales, la CA y el perfil del certificado se envían a la extensión para generar extensiones dinámicas.

Además de los valores estáticos definidos en Admin Web > Configuración del sistema > Extensiones de certificado personalizadas , también es posible obtener valores de los datos de extensión en el almacén de información extendida de la entidad final. Una buena opción es usar el oid de extensión como prefijo de la clave de la propiedad para asociar el valor con esta extensión.

A continuación se muestra un ejemplo de una extensión avanzada. Para añadir esta extensión a EJBCA, implemente la clase como parte del archivo ejbca.ear. Esta debería aparecer en la lista de Clases de Extensión al editar una extensión personalizada en Configuración del Sistema > Extensiones de Certificado Personalizadas . El archivo se encuentra automáticamente gracias a la implementación de la interfaz CustomCertificateExtension.

public class SomeAdvancedCertificateExtension extends StandardCertificateExtension implements CustomCertificateExtension {
private static String PROPERTY_SOMEPROPERTY = "someproperty";
public SomeAdvancedCertificateExtension() {
super.setDisplayName("SomeAdvancedCertificateExtension");
}
@Override
public Map< String , String[]> getAvailableProperties() {
Map< String , String[]> map = new HashMap<>();
map.put(PROPERTY_SOMEPROPERTY, new String[]{"a", "b", "c"});
return map;
}
/**
* The main method that should return a byte[] with the ASN.1 encoded data to be put
in the extension valud
* using the input data (optional) or defined properties (optional)
*
* @see
org.cesecore.certificates.certificate.certextensions.CertificateExtension#getValueEncoded
*/
@Override
public byte[] getValueEncoded(EndEntityInformation userData, CA ca, CertificateProfile
certProfile, PublicKey userPublicKey,
PublicKey caPublicKey, CertificateValidity val )
throws CertificateExtentionConfigurationException, CertificateExtensionException {
try {
// Optionally get dynamic values for this extension
//String dynamicValue = userData.getExtendedinformation().getExtensionData
(getOID() + ".someotherproperty");
String value = getProperties().getProperty("FOO");
DERPrintableString asn1value = new DERPrintableString(value);
return asn1value.toASN1Primitive().getEncoded();
} catch (IOException e) {
throw new CertificateExtensionException("Error constructing certificate
extension SomeAdvancedCertificateExtension.", e);
}
}
/**
* @deprecated use getValueEncoded instead.
*/
public ASN1Encodable getValue(EndEntityInformation userData, CA ca, CertificateProfile
certProfile, PublicKey userPublicKey, PublicKey caPublicKey, CertificateValidity val)
throws CertificateExtensionException, CertificateExtentionConfigurationException {
throw new UnsupportedOperationException("Use getValueEncoded instead");
}
}