App-CamelPKI
view release on metacpan - search on metacpan
view release on metacpan or search on metacpan
lib/App/CamelPKI/CA.pm view on Meta::CPAN
sub certificate {
my ($self) = @_;
$self->{certificate} ||= App::CamelPKI::Certificate->load
($self->_certificate_path);
}
=head2 issue($certtemplate, $pubkey, $key1 => $val1, ...)
Issue on to many new certificates. $pubkey is a public key, in the
form of an L<App::CamelPKI::PublicKey> object. $certtemplate is the name
of a subclass of L<App::CamelPKI::CertTemplate>; $key1 => $val1, ... are
nominatives parameters to pass to $certtemplate for him to generate
associated certificates (see details in
L<App::CamelPKI::CertTemplate/prepare_certificate> and
L<App::CamelPKI::CertTemplate/list_keys>).
Internally, I<sign> control arguments, and the calls
$certtemplate->test_certificate_conflict($db, $key1 => $val1, ...)
to verify if the certificate to create is compliant to the existing
certificates. If it's ok, I<sign> invokes
$certtemplate->prepare_certificate($cacert, $newcert, $key1 => $val1, ...)
At last, I<sign> fix the serial number, conforming to the current CA status,
and records the certificate in database. The certificate may then be retrieved
using L</commit>.
=cut
sub issue {
my ($self, $template, $pubkey, @opts) = @_;
# Note the explicit class call: so the template has no authority
# to overload this method at will.
my %dbopts = $template->App::CamelPKI::CertTemplate::normalize_opts(@opts);
delete $dbopts{time}; # Sémantique réservée
$dbopts{template} = $template;
my %templateopts = %dbopts;
$templateopts{time} = App::CamelPKI::Time->now->zulu;
foreach my $conflictcert
($template->test_certificate_conflict
($self->database_facet($template), %templateopts)) {
# FIXME: should be more flexible (refuse the operation
# instead of revoking conflicting certificates, or give the
# "superseded" reason in the CRL...)
$self->revoke($template, $conflictcert) unless
grep {$conflictcert->equals($_->{cert})} @{$self->{signed}};
}
my $cert = Crypt::OpenSSL::CA::X509->new
($pubkey->as_crypt_openssl_ca_publickey);
$template->prepare_certificate
($self->certificate, $cert, %templateopts);
$cert->set_serial(sprintf("0x%x",
$self->{db}->next_serial("certificate")));
$cert = App::CamelPKI::Certificate->parse
($cert->sign($self->_private_key,
$template->signature_hash));
push @{$self->{signed}}, { cert => $cert, opts => \%dbopts };
return;
}
=head2 revoke($certtemplate, $certificate, %options)
Marks $certificate, an object of the L<App::CamelPKI::Certificate> class,
which has been certified via the $certtemplate template, as revoked.
It's prohibited to revoke a certificate that has just been certified
in the current transaction (see L</Coherence>); If this situation
is detected, triggers an exception. In the same way, the template
may cause additional revocations following the revocation of
$certificate (see L<App::CamelPKI::CertTemplate/test_cascaded_revocation>).
This method is delegated to L<App::CamelPKI::CADB/revoke>, and recognized named
options are documented at this section.
=cut
sub revoke {
throw App::CamelPKI::Error::Internal("WRONG_NUMBER_ARGS")
unless (@_ % 2);
my ($self, $template, $cert, %options) = @_;
throw App::CamelPKI::Error::Internal("INCORRECT_ARGS")
if (! defined $cert);
throw App::CamelPKI::Error::Privilege
("Attempt to revoke a certificate foreign to this template",
-certificate => $cert,
-template => $template)
unless $self->database_facet($template)
->search(-certificate => $cert,
-revoked => undef)->count;
$self->{db}->revoke($cert, %options);
}
=head2 commit()
Records all writes in database, and returns the certificate list issued
with L</sign> scince the creation of the object or scince the previous
call to I<commit>. Certificates are returned in the form of a list of
L<App::CamelPKI::Certificate> objects, in the same order as the corresponding
call to L</sign>.
=cut
sub commit {
my ($self) = @_;
my @signed = @{delete($self->{signed}) || []};
my $checks = {};
push @{$checks->{$_->{opts}->{template}}}, $_ foreach @signed;
$_->test_issued_certs_coherent(@{$checks->{$_}}) foreach
(keys %$checks);
my @retval;
foreach my $signed (@signed) {
$self->{db}->add($signed->{cert}, %{$signed->{opts}});
view all matches for this distributionview release on metacpan - search on metacpan
( run in 0.498 second using v1.00-cache-2.02-grep-82fe00e-cpan-dad7e4baca0 )