Certificate Authority Certificates

La Public Key Inrastructure (infrastructure de clés publiques) est utilisés dans de nombreux cas de sécurité sur un système Linux. Pour qu'un certificat soit fiable, il doit être signé par un agent de confiance, qu'on appelle l'autorité de certificat (Certificate Authority) (CA). Les certificats chargés dans cette section sont issus de la liste du système de contrôle de Mozilla et elle est formatée dans une forme utilisée par OpenSSL-1.0.1c. Les certificats peuvent également être utilisés par d'autres applications, directement ou indirectement via openssl.

Ce paquet est connu pour se construire correctement sur une plateforme LFS-7.2.

Introduction à Certificate Authorities

Informations sur le paquet

Dépendances de Certificate Authority Certificates

Requises

OpenSSL-1.0.1c

Facultative

Wget-1.14

Notes utilisateur : http://wiki.linuxfromscratch.org/blfs/wiki/cacerts

Installation de Certificate Authority Certificates

Créez d'abord un script pour reformatter un certificat en forme dont a besoin openssl. En tant qu'utilisateur root :

cat > /bin/make-cert.pl << "EOF"
 #!/usr/bin/perl -w

# Utilisé pour générer des fichiers encodés en PEM à partir du certdata.txt de
# Mozilla. Lancez en tant que ./mkcrt.pl > certificate.crt
#
# Nous devons des parties de ce script à RedHat (mkcabundle.pl)
#
# Ce script modifié pour être utilisé avec un seul fichier de données
# (tempfile.cer) extrait de certdata.txt, récupéré dans la dernière version 
# des sources de Mozilla NSS.
# mozilla/security/nss/lib/ckfw/builtins/certdata.txt
#
# Auteurs : DJ Lucas
#
# Version 20120211

my $certdata = './tempfile.cer';

open( IN, "cat $certdata|" )
    || die "could not open $certdata";

my $incert = 0;

while ( <IN> ) 
{
    if ( /^CKA_VALUE MULTILINE_OCTAL/ ) 
    {
        $incert = 1;
        open( OUT, "|openssl x509 -text -inform DER -fingerprint" )
            || die "could not pipe to openssl x509";
    } 
    
    elsif ( /^END/ && $incert ) 
    {
        close( OUT );
        $incert = 0;
        print "\n\n";
    } 
    
    elsif ($incert) 
    {
        my @bs = split( /\\/ );
        foreach my $b (@bs) 
        {
            chomp $b;
            printf( OUT "%c", oct($b) ) unless $b eq '';
        }
    }
}
EOF

chmod +x /bin/make-cert.pl

Le script suivant crée les certificats et un bouquet de tous les certificats. Il crée un répertoire ./certs et ./BLFS-ca-bundle-${VERSION}.crt. Créez de nouveau ce script en tant qu'utilisateur root :

cat > /bin/make-ca.sh << "EOF"
#!/bin/bash
# Début de make-ca.sh
# Script pour peupler le CApath d'OpenSSL à partir d'un bouquet de CAs au 
# format PEM 
#
# Le fichier certdata.txt doit exister dans le répertoire local
# On obtient le numéro de version à partir de la version des données.
#
# Auteurs: DJ Lucas
#
# Version 20120211

certdata="certdata.txt"

if [ ! -r $certdata ]; then
  echo "$certdata doit etre dans le répertoire local"
  exit 1
fi

REVISION=$(grep CVS_ID $certdata | cut -f4 -d'$')

if [ -z "${REVISION}" ]; then
  echo "$certfile n'a pas de 'Revision' dans CVS_ID"
  exit 1
fi

VERSION=$(echo $REVISION | cut -f2 -d" ")

TEMPDIR=$(mktemp -d)
TRUSTATTRIBUTES="CKA_TRUST_SERVER_AUTH"
BUNDLE="BLFS-ca-bundle-${VERSION}.crt"
CONVERTSCRIPT="/bin/make-cert.pl"
SSLDIR="/etc/ssl"

mkdir "${TEMPDIR}/certs"

# Récupérer une liste des lignes bizarres pour chaque certif
CERTBEGINLIST=$(grep -n "^# Certificate" "${certdata}" | cut -d ":" -f1)

# Récupérer une liste des lignes finales pour chaque certif
CERTENDLIST=`grep -n "^CKA_TRUST_STEP_UP_APPROVED" "${certdata}" | cut -d ":" -f 1`

# Démarrer une boucle
for certbegin in ${CERTBEGINLIST}; do
  for certend in ${CERTENDLIST}; do
    if test "${certend}" -gt "${certbegin}"; then
      break
    fi
  done

  # Envoi vers un fichier temp avec le nom des fichiers en tant que numéro du
  # début de ligne 
  sed -n "${certbegin},${certend}p" "${certdata}" > "${TEMPDIR}/certs/${certbegin}.tmp"
done

unset CERTBEGINLIST CERTDATA CERTENDLIST certebegin certend

mkdir -p certs
rm certs/*      # Pour etre sur que le répertoire est vide

for tempfile in ${TEMPDIR}/certs/*.tmp; do
  # S'assure que le certif est fiable...
  grep "CKA_TRUST_SERVER_AUTH" "${tempfile}" | \
    grep "TRUST_UNKNOWN|NOT_TRUSTED" > /dev/null

  if test "${?}" = "0"; then
    # Affiche une erreur significative et supprime le fichier
    cp "${tempfile}" tempfile.cer
    perl ${CONVERTSCRIPT} > tempfile.crt
    keyhash=$(openssl x509 -noout -in tempfile.crt -hash)
    echo "Le certificat ${keyhash} n'est pas de confiance ! Suppression..."
    rm -f tempfile.cer tempfile.crt "${tempfile}"
    continue
  fi

  # Si on exécute à ce moment de la boucle, le certif temporaire est fiable
  # Chercher les données du certif et génère pour lui un fichier de certif

  cp "${tempfile}" tempfile.cer
  perl ${CONVERTSCRIPT} > tempfile.crt
  keyhash=$(openssl x509 -noout -in tempfile.crt -hash)
  mv tempfile.crt "certs/${keyhash}.pem"
  rm -f tempfile.cer "${tempfile}"
  echo "Cree ${keyhash}.pem"
done

# Supprime les fichiers blacklistés (mis sur liste noire)
# MD5 Collision Proof of Concept CA
if test -f certs/8f111d69.pem; then
  echo "Certificate 8f111d69 is not trusted!  Removing..."
  rm -f certs/8f111d69.pem
fi

# Enfin, génère le bouquet et nettoie.
cat certs/*.pem >  ${BUNDLE}
rm -r "${TEMPDIR}"
EOF

chmod +x /bin/make-ca.sh

Ajoutez un script bref pour supprimer les certificts expirés d'un répertoire. Créez de nouveau ce script en tant qu'utilisateur root :

cat > /bin/remove-expired-certs.sh << "EOF"
#!/bin/bash
# Début de /bin/remove-expired-certs.sh
#
# Version 20120211
 
# Garantie que la date soit bien analysée sur tous les systèmes
function mydate()
{
  local y=$( echo $1 | cut -d" " -f4 )
  local M=$( echo $1 | cut -d" " -f1 )
  local d=$( echo $1 | cut -d" " -f2 )
  local m
  
  if [ ${d} -lt 10 ]; then d="0${d}"; fi

  case $M in
    Jan) m="01";;
    Feb) m="02";;
    Mar) m="03";;
    Apr) m="04";;
    May) m="05";;
    Jun) m="06";;
    Jul) m="07";;
    Aug) m="08";;
    Sep) m="09";;
    Oct) m="10";;
    Nov) m="11";;
    Dec) m="12";;
  esac

  certdate="${y}${m}${d}"
}

OPENSSL=/usr/bin/openssl
DIR=/etc/ssl/certs

if [ $# -gt 0 ]; then
  DIR="$1"
fi

certs=$( find ${DIR} -type f -name "*.pem" -o -name "*.crt" )
today=$( date +%Y%m%d )

for cert in $certs; do
  notafter=$( $OPENSSL x509 -enddate -in "${cert}" -noout )
  date=$( echo ${notafter} |  sed 's/^notAfter=//' )
  mydate "$date"

  if [ ${certdate} -lt ${today} ]; then
     echo "${cert} expire le ${certdate}! Suppression..."
     rm -f "${cert}"
  fi
done
EOF

chmod +x /bin/remove-expired-certs.sh

Les commandes suivantes récupèreront les certificats et les convertit dans le bon format. Si vous le désirez, vous pouvez utiliser un navigateur Internet plutôt que wget mais le fichier devra être enregistré sous le nom certdata.txt. Ces commandes peuvent être répétées autant de fois que nécessaire pour mettre à jour les Certificats CA.

certhost='http://mxr.mozilla.org'                        &&
certdir='/mozilla/source/security/nss/lib/ckfw/builtins' &&
url="$certhost$certdir/certdata.txt?raw=1"               &&

wget --output-document certdata.txt $url &&
unset certhost certdir url               &&
make-ca.sh                               &&
remove-expired-certs.sh certs

Maintenant, en tant qu'utilisateur root :

SSLDIR=/etc/ssl                                     &&
install -d ${SSLDIR}/certs                          &&
cp -v certs/*.pem ${SSLDIR}/certs                   &&
c_rehash                                            &&
install BLFS-ca-bundle*.crt ${SSLDIR}/ca-bundle.crt &&
unset SSLDIR

Enfin, nettoyez le répertoire courant :

rm -r certs BLFS-ca-bundle*

Contenu

Programmes installés: make-ca.sh, make-cert.pl et remove-expired-certs.sh
Bibliothèques installées: Aucune
Répertoires installés: /etc/ssl/certs

Descriptions courtes

make-ca.sh

est un script bash qui reformate le fichier certdata.txt pour que openssl l'utilise.

make-cert.pl

est un script perl qui convertit un certificat binaire unique (format .der) au format .pem.

remove-expired-certs.sh

est un script perl qui supprime les certificats expirés d'un répertoire. Le répertoire par défaut est /etc/ssl/certs.

Last updated on : 2012-09-04 20:28:12 +020