| App-CamelPKI documentation | view source | Contained in the App-CamelPKI distribution. |
App::CamelPKI::CertTemplate - A certificate template for Camel-PKI (abstract class - not instanciable).
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);
}
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.
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.
Barring an explicit contrary statement, every class that inherits from App::CamelPKI::CertTemplate must define the following methods:
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:
The date and time to be considered as the current time, in "Zulu" format. Typically, the certificate validity period start at $zulutime.
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.
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/).
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
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.
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.
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:
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 :
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.
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:
issuer de $cacertobj est copié en tant que subject de
$eecertobj; 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 :
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.
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 ] });
| App-CamelPKI documentation | view source | Contained in the App-CamelPKI distribution. |