NAME

App::CamelPKI::CertTemplate - A certificate template for Camel-PKI (abstract class - not instanciable).

SYNOPSIS

package App::CamelPKI::CertTemplate::Foo;

use base "App::CamelPKI::CertTemplate";
use Crypt::OpenSSL::CA;

sub list_keys { qw(name uid) }

sub prepare_certificate {
    my ($class, $cacert, $cert, %opts) = @_;
    $class->copy_from_ca_cert($cacert, $cert);
    $cert->set_notBefore($opts{time});
    $cert->set_notAfter($cacert->get_notAfter());
    $cert->set_subject_DN
        (Crypt::OpenSSL::CA::X509_NAME->new_utf8
         ("2.5.4.11" => "Internet widgets",
          CN => $opts{name}, x500UniqueIdentifier => $opts{uid}));
    # ...
}

# Only one certificate must be valid for a given UID:
sub test_certificate_conflict {
    my ($class, $db, %opts) = @_;
    return $db->search(uid => $opts{uid});
}

# Sample coherency enforcement: no duplicate names, no duplicate
# UIDs.
sub test_issued_certs_coherent {
    my ($class, $db, @opts_array) = @_;
    $class->test_no_duplicates(["uid"], @opts_array);
    $class->test_no_duplicates(["name"], @opts_array);
}

DESCRIPTION

A certificate template is a certificate "with holes": it fix the rules used to generate certificates (see App::CamelPKI::CA).

Each subclasses of App::CamelPKI::CertTemplate represent a certificate template, to be (mainly) used as classes; no object is created as instance of App::CamelPKI::CertTemplate or one of its subclasses. Moreover, App::CamelPKI::CertTemplate is an abstract class; only its subclasses must be used as templates.

CAPABILITY DISCIPLINE

Classes inherited from App::CamelPKI::CertTemplate do not encapsulate any state; they are therefore neutral from a security point of view and don't carry any privileges. On the other hand, an App::CamelPKI::CertTemplate may be used to restrict the rights of an App::CamelPKI::CA instance; see "facet_certtemplate" in App::CamelPKI::CA.

METHODS TO OVERLOAD

Barring an explicit contrary statement, every class that inherits from App::CamelPKI::CertTemplate must define the following methods:

prepare_certificate($cacertobj, $eecertobj, $key1 => $val1, ...)

Prepares a certificate for "sign" in App::CamelPKI::CA, using $key1 => $val1, ... to fill out the variable fields. Keys ($key1, etc.) are always among those listed by "list_keys". Values are character strings or references to lists of character strings for templates allowing multi-valued fields (not implemented yet).

The method is called in a scalar context; it shall modify $eecertobj, an instance of "Crypt::OpenSSL::CA::X509" in Crypt::OpenSSL::CA initially empty, by calling mutator methods on it, until $eecertobj is ready to be signed by the CA. To perform this task, prepare_certificate may use $cacertobj, an instance of App::CamelPKI::Certificate (not Crypt::OpenSSL:CA::X509) which represents the CA certificate, and/or the key-value data passed in parameters.

Keys names ($key1, ...) are mostly chosen freely by the certificate template implementor, except for a short number that are "well known" and always provided by App::CamelPKI::CA:

time => $zulutime

The date and time to be considered as the current time, in "Zulu" format. Typically, the certificate validity period start at $zulutime.

list_keys()

Called in list context, returns the valid nominative informations keys list to be passed to "prepare_certificate" and "test_certificate_conflict".

The CA will not give any key to this methods unless these keys are present in the return value of list_keys(), excepted time which will be passed even if the template do not mention it.

The base class implementation returns the empty list, which is only appropriate for Camel-PKI internal certificates.

signature_hash

Returns the cryptographic algorithm to use for certificates signing, under the form of a name ("md5" or "sha1", for example).

The base class implementation returns "sha256", as "md5" and "sha1" are now not recommanded because of progress done on their cryptanalysis (http://www.win.tue.nl/~bdeweger/CollidingCertificates/).

test_certificate_conflict($db, $key1 => $val1, ...)

FIXME-TR: ouch, du pour une sommeillant comme moi - � faire la t�te fraiche Doit se terminer avec succès si et seulement si le gabarit de certificat considère qu'il est légitime d'ajouter à la base $db (une instance de App::CamelPKI::CADB) un certificat avec les options nominatives $key1 => $val1, ... tel que "prepare_certificate" le créerait, et lancer une exception dans le cas contraire. Plus précisément, certificate_test_conflict est appelé en contexte liste et doit

  • return an empty list if the certificate creation is unconditionnaly valid, due the to actual $db status;

  • or must return a certificates list (in the form of App::CamelPKI::Certificates instances) if certificate_test_conflict thinks to be conflict with the new putative certificate. The calling CA then decides its have to cancel the transaction, revoke certificates, or bypass the restriction (see "Coherence" in App::CamelPKI::CA);

  • or must throw an exception if there is no means to consider such a certificate compliant in terms of the certificate policy.

FIXME-TR: creuv�... Noter que le principe de moindre privilège s'applique à test_certificate_conflict, et que la version de $db qu'il récupère est en réalité une facette de la véritable base de données de CA, en lecture seule et dont le contenu est de surcroît filtré sur la base d'un need-to-know: typiquement, test_certificate_conflict ne pourra voir que les certificats qu'il a lui-même fabriqués par le passé.

The base class implementation is always happy, and always returns the empty list.

test_issued_certs_coherent( \%data1, \%data2, ... )

TODO-TR: stoppedhere Doit se terminer avec succès si et seulement si le gabarit de certificat considère qu'il est légitime d'émettre en une seule transaction les certificats dont les données nominatives figurent en argument. test_issued_certs_coherent doit se terminer normalement s'il estime que les certificats qui seraient créés en appelant prepare_certificate(%data1), prepare_certificate(%data2), etc sont cohérents les uns avec les autres, et lever une exception dans le cas contraire. L'AC prend cette information en compte comme il est décrit dans "Cohérence" in App::CamelPKI::CA.

The base class implementation is always happy, and always ends with success.

METHODS PROVIDED BY THE BASE CLASS

Dans sa tâche d'implémenter les "MÉTHODES À SURCHARGER", le programmeur est aidé par les méthodes suivantes, dont il bénéficie par voie d'héritage:

normalize_opts($template, $key1 => $val1, ...)

Lorsqu'on invoque cette méthode (indifféremment de classe ou d'instance) en contexte liste, elle renvoie la liste associative passée en paramètre ($key1 => $val1, ...) après l'avoir «nettoyée» de la façon suivante :

  • les clefs ($key1, $key2, ...) qui ne valident pas l'expression rationnelle qr/^[a-z0-9_]+$/i provoquent une exception; celles qui ne font pas partie de la liste des clefs reconnues par $template (d'après "list_keys" in App::CamelPKI::CertTemplate) sont supprimées.

  • les valeurs ($val1, $val2, ...) doivent être soit des chaînes de caractères soit des références sur des tableaux de chaînes de caractères, et ne pas contenir undef. Toutes les valeurs sont chaînifiées, et si une même clef apparaît plusieurs fois dans la liste d'arguments de normalize_opts seule sa dernière occurence est prise en compte.

La valeur de retour est une liste associative dont toutes les valeurs sont soit des vraies chaînes, soit des références vers des tableaux de vraies chaînes (pas undef, pas d'objet chaînifiable).

Cette méthode est également utilisée directement par App::CamelPKI::CA pour préparer les arguments avant d'infoquer "test_certificate_conflict" et "test_issued_certs_coherent"; dans ce cas, pour des raisons de sécurité, cette méthode doit être invoquée explicitement dans la classe de base à l'aide de l'idiome suivant :

my %opts = $template->App::CamelPKI::CertTemplate::normalize_opts(@opts);

sans quoi le gabarit de certificat aurait le droit de modifier l'implémentation de cette méthode à sa guise.

copy_from_ca_cert($cacertobj, $eecertobj, %options)

Copie automatiquement de $cacertobj dans $eecertobj les champs qui sont nécessaires à la validation du nouveau certificat $eecertobj au sens de RFC3280. Les copies suivantes sont faites inconditionnellement:

  • l'issuer de $cacertobj est copié en tant que subject de $eecertobj;

  • si le certificat $cacertobj possède un subjectKeyIdentifier, alors celui-ci sera inscrit en tant que keyid dans l'authorityKeyIdentifier de $eecertobj.

Les options nommées suivantes permettent d'altérer le comportement de cette méthode :

-authoritykeyid_issuer => 1

Copie également l'issuer et le numéro de série du certificat d'AC sous la forme des champs de même nom dans l'extension authorityKeyIdentifier de $eecertobj. Noter que cette pratique est décommandée par le X509 style guide.

test_no_duplicates(\@keys, \%hash1, \%hash2, ...)

An usefull primitive to implement "test_issued_certs_coherent": test there is no two certificates with the same keys in the @keys subset, among \%hash1, \%hash2, ... tables. test_no_duplicates triggers an exception if it's the case.

Order of multi-valuated fields is not relevant, so that the following call fails:

App::CamelPKI::CertTemplate->test_no_duplicates
   ([qw(foo bar)], { foo => [ 1, 2 ], bar => "bo", quux => 42 },
                   { foo => [ 2, 1 ], bar => "bo", quux => "Bah." });

On the other end, the cardinal is important, so that the following call succeeds:

App::CamelPKI::CertTemplate->test_no_duplicates
   ([qw(foo baz)], { foo => [ 1, 1 ] }, { foo => [ 1 ] });

1 POD Error

The following errors were encountered while parsing the POD:

Around line 141:

Non-ASCII character seen before =encoding in '�'. Assuming UTF-8