Creación de una Autoridad Certificadora

Para crear una autoridad certificadora es necesario crear una estructura de directorios, un certificado público y una llave privada. El proceso es simple, pero lo podemos simplificar aun más si instalamos openssl-perl y utilizamos el script CA.pl que encontraremos en el directorio $SSL/misc/ .

Ejecutamos:

 
mkdir /tmp/ssl 
cd /tmp/ssl
/ruta/CA.pl -newca 
            

Ahora deberemos tener un directorio llamado demoCA que contiene un fichero llamado cacert.pem, que a su vez contiene el certificado público, el índice, el número de serie y los directorios:

  • certs un directorio para contener certificados

  • crl un directorio para contener certificados revocados

  • index.txt un fichero con el índice de certificados firmados

  • newcerts un directorio para contener los nuevos certificados emitidos

  • private un directorio que contiene el fichero cakey.pem, la llave privada

  • serial un fichero que contiene el número de serie de certificados firmados.

La clave que nos ha solicitado es la que tendremos que utilizar para abrir la llave privada cada vez que queramos firmar un nuevo certificado.

Si queremos realizar el proceso manualmente:

creamos la estructura de directorios:

 
mkdir demoCA
mkdir demoCA/certs
mkdir demoCA/crl
mkdir demoCA/newcerts
mkdir demoCA/private
echo -n ?01? >demoCA/serial";
touch demoCA/index.txt
openssl req -new -x509 \
        -keyout demoCA/private/cakey.pem \
        -out demoCA/cacert.pem \
        -days 365 
            

Es decir, para crear una autoridad certificadora basta crear la estructura de directorio, dos ficheros y una pareja de llave privada ? certificado público.

En la última orden realizamos solicitud de certificado autofirmado donde el certificado público es demoCA/cacert.pem y la llave privada es demoCA/private/cakey.pem. Como lo que pretendemos es convertirnos en una CA nuestro certificado tiene que ser autofirmado.

Confianza en una CA

OpenSSL utiliza el directorio $SSL/certs para contener los certificados de las CA en las que confía. No sólo basta copiar el fichero con el certificado en él, sino que tendremos que proporcionar a openssl una forma de localizarlo. La localización por el nombre de fichero no es adecuada ya que el nombre del fichero es completamente independiente del certificado que contiene y buscamos un nombre único para cada fichero de certificado. Un usuario no tiene el mismo concepto para un nombre de fichero que una aplicación De cada certificado podemos obtener un hash que lo puede identificar y es ese valor, el que vamos a utilizar para que OpenSSL sepa identificar el fichero que contiene el certificado. Lo más cómodo es utilizar un enlace simbólico entre el nombre de fichero que conoce el usuario y el nombre que espera encontrar OpenSSL.

Para averiguar el hash de un certificado para el enlace simbólico utilizamos:

 
$ openssl x509 -noout -hash -in mica.pem
def616ee 
              

Ahora tenemos que enlazar el certificado con el nombre hash:

ln -s mica.pem def616ee.0

Los dígitos de la extensión se utilizan para evitar posibles colisiones de nombres de hash con distintos certificados, cosa que estadísticamente es posible.

Cuando una aplicación encuentra un certificado remoto, comprueba si el certificado se encuentra en cert.pem, y si no, en un fichero con nombre igual al hash del certificado. Si se encuentra la validez se considera verificada.

Algunas aplicaciones como Sendmail permiten especificar los ubicación de los certificados de confianza durante la ejecución, sin embargo otras aplicaciones no, la ubicación se decide en el momento de la ejecución.

Para reconocer y verificar certificados, tiene que poner el fichero que contiene el certificado en el directorio indicado antes y crear el enlace simbólico con el hash obtenido.

Como vimos en el ejemplo anterior sería:

 
ln -s mica.pem def616ee.0 
              

El siguiente script se encarga de esto:

 
#!/bin/sh 
              

#http://www.madboa.com/geek/openssl/

 
#Paul Heinlein, heinlein(en)madboa.com
# usage: certlink.sh filename [filename ...]
for CERTFILE in $*; do
  # make sure file exists and is a valid cert
  test -f "$CERTFILE" || continue
  HASH=$(openssl x509 -noout -hash -in "$CERTFILE")
  test -n "$HASH" || continue
  # use lowest available iterator for symlink
  for ITER in 0 1 2 3 4 5 6 7 8 9; do
    test -f "${HASH}.${ITER}" && continue
    ln -s "$CERTFILE" "${HASH}.${ITER}"
    test -L "${HASH}.${ITER}" && break
  done
done