SYNOPSIS

 use Crypt::X509;

 $decoded = Crypt::X509->new( cert => $cert );

 $subject_email = $decoded->subject_email;
 print "do not use after: ".gmtime($decoded->not_after)." GMT\n";

REQUIRES

Convert::ASN1

DESCRIPTION

Crypt::X509 parses X.509 certificates. Methods are provided for accessing most certificate elements.

It is based on the generic \s-1ASN\s0.1 module by Graham Barr, on the x509decode example by Norbert Klasen and contributions on the perl-ldap-dev-Mailinglist by Chriss Ridd.

CONSTRUCTOR

new ( \s-1OPTIONS\s0 )

Creates and returns a parsed X.509 certificate hash, containing the parsed contents. The data is organised as specified in \s-1RFC\s0 2459. By default only the first \s-1ASN\s0.1 Layer is decoded. Nested decoding is done automagically through the data access methods. A variable containing the \s-1DER\s0 formatted certificate to be parsed (eg. as stored in \*(C`usercertificate;binary\*(C' attribute in an LDAP-directory).

use Crypt::X509; use Data::Dumper;

$decoded= Crypt::X509->new(cert => $cert);

print Dumper($decoded);

METHODS

error

Returns the last error from parsing, \*(C`undef\*(C' when no error occured. This error is updated on deeper parsing with the data access methods.

$decoded= Crypt::X509->new(cert => $cert); if ($decoded->error) { warn "Error on parsing Certificate:".$decoded->error; }

DATA ACCESS METHODS

You can access all parsed data directly from the returned hash. For convenience the following methods have been implemented to give quick access to the most-used certificate attributes.

version

Returns the certificate's version as an integer. \s-1NOTE\s0 that version is defined as an Integer where 0 = v1, 1 = v2, and 2 = v3.

version_string

Returns the certificate's version as a string value.

serial

returns the serial number (integer or Math::BigInt Object, that gets automagic evaluated in scalar context) from the certificate

$decoded= Crypt::X509->new(cert => $cert); print "Certificate has serial number:".$decoded->serial."\n";

not_before

returns the GMT-timestamp of the certificate's beginning date of validity. If the Certificate holds this Entry in utcTime, it is guaranteed by the \s-1RFC\s0 to been correct.

As utcTime is limited to 32-bit values (like unix-timestamps) newer certificates hold the timesamps as \*(L"generalTime\*(R"-entries. The contents of \*(L"generalTime\*(R"-entries are not well defined in the \s-1RFC\s0 and are returned by this module unmodified, if no utcTime-entry is found.

$decoded= Crypt::X509->new(cert => $cert); if ($decoded->notBefore < time()) { warn "Certificate: not yet valid!"; }

not_after

returns the GMT-timestamp of the certificate's ending date of validity. If the Certificate holds this Entry in utcTime, it is guaranteed by the \s-1RFC\s0 to been correct.

As utcTime is limited to 32-bit values (like unix-timestamps) newer certificates hold the timesamps as \*(L"generalTime\*(R"-entries. The contents of \*(L"generalTime\*(R"-entries are not well defined in the \s-1RFC\s0 and are returned by this module unmodified, if no utcTime-entry is found.

$decoded= Crypt::X509->new(cert => $cert); print "Certificate expires on ".gmtime($decoded->not_after)." GMT\n";

signature

Return's the certificate's signature in binary \s-1DER\s0 format.

pubkey

Returns the certificate's public key in binary \s-1DER\s0 format.

pubkey_size

Returns the certificate's public key size.

pubkey_algorithm

Returns the algorithm as \s-1OID\s0 string which the public key was created with.

PubKeyAlg

returns the subject public key encryption algorithm (e.g. '\s-1RSA\s0') as string.

$decoded= Crypt::X509->new(cert => $cert); print "Certificate public key is encrypted with:".$decoded->PubKeyAlg."\n";

Example Output: Certificate public key is encrypted with: RSA

pubkey_components

If this certificate contains an \s-1RSA\s0 key, this function returns a hashref { modulus => $m, exponent => $e) from that key; each value in the hash will be an integer scalar or a Math::BigInt object.

For other pubkey types, it returns undef (implementations welcome!).

sig_algorithm

Returns the certificate's signature algorithm as \s-1OID\s0 string

$decoded= Crypt::X509->new(cert => $cert); print "Certificate signature is encrypted with:".$decoded->sig_algorithm."\n";>

Example Output: Certificate signature is encrypted with: 1.2.840.113549.1.1.5

SigEncAlg

returns the signature encryption algorithm (e.g. '\s-1RSA\s0') as string.

$decoded= Crypt::X509->new(cert => $cert); print "Certificate signature is encrypted with:".$decoded->SigEncAlg."\n";

Example Output: Certificate signature is encrypted with: RSA

SigHashAlg

returns the signature hashing algorithm (e.g. '\s-1SHA1\s0') as string.

$decoded= Crypt::X509->new(cert => $cert); print "Certificate signature is hashed with:".$decoded->SigHashAlg."\n";

Example Output: Certificate signature is encrypted with: SHA1

Subject

returns a pointer to an array of strings containing subject nameparts of the certificate. Attributenames for the most common Attributes are translated from the OID-Numbers, unknown numbers are output verbatim.

$decoded= Convert::ASN1::X509->new($cert); print "DN for this Certificate is:".join(',',@{$decoded->Subject})."\n";

subject_country

Returns the string value for subject's country (= the value with the \s-1OID\s0 2.5.4.6 or in \s-1DN\s0 Syntax everything after \*(C`C=\*(C'). Only the first entry is returned. \*(C`undef\*(C' if subject contains no country attribute.

subject_locality

Returns the string value for subject's locality (= the value with the \s-1OID\s0 2.5.4.7 or in \s-1DN\s0 Syntax everything after \*(C`l=\*(C'). Only the first entry is returned. \*(C`undef\*(C' if subject contains no locality attribute.

subject_state

Returns the string value for subject's state or province (= the value with the \s-1OID\s0 2.5.4.8 or in \s-1DN\s0 Syntax everything after \*(C`S=\*(C'). Only the first entry is returned. \*(C`undef\*(C' if subject contains no state attribute.

subject_org

Returns the string value for subject's organization (= the value with the \s-1OID\s0 2.5.4.10 or in \s-1DN\s0 Syntax everything after \*(C`O=\*(C'). Only the first entry is returned. \*(C`undef\*(C' if subject contains no organization attribute.

subject_ou

Returns the string value for subject's organizational unit (= the value with the \s-1OID\s0 2.5.4.11 or in \s-1DN\s0 Syntax everything after \*(C`OU=\*(C'). Only the first entry is returned. \*(C`undef\*(C' if subject contains no organization attribute.

subject_cn

Returns the string value for subject's common name (= the value with the \s-1OID\s0 2.5.4.3 or in \s-1DN\s0 Syntax everything after \*(C`CN=\*(C'). Only the first entry is returned. \*(C`undef\*(C' if subject contains no common name attribute.

subject_email

Returns the string value for subject's email address (= the value with the \s-1OID\s0 1.2.840.113549.1.9.1 or in \s-1DN\s0 Syntax everything after \*(C`E=\*(C'). Only the first entry is returned. \*(C`undef\*(C' if subject contains no email attribute.

Issuer

returns a pointer to an array of strings building the \s-1DN\s0 of the certificate issuer (= the \s-1DN\s0 of the \s-1CA\s0). Attributenames for the most common Attributes are translated from the OID-Numbers, unknown numbers are output verbatim.

$decoded= Crypt::X509->new($cert); print "Certificate was issued by:".join(',',@{$decoded->Issuer})."\n";

issuer_cn

Returns the string value for issuer's common name (= the value with the \s-1OID\s0 2.5.4.3 or in \s-1DN\s0 Syntax everything after \*(C`CN=\*(C'). Only the first entry is returned. \*(C`undef\*(C' if issuer contains no common name attribute.

issuer_country

Returns the string value for issuer's country (= the value with the \s-1OID\s0 2.5.4.6 or in \s-1DN\s0 Syntax everything after \*(C`C=\*(C'). Only the first entry is returned. \*(C`undef\*(C' if issuer contains no country attribute.

issuer_state

Returns the string value for issuer's state or province (= the value with the \s-1OID\s0 2.5.4.8 or in \s-1DN\s0 Syntax everything after \*(C`S=\*(C'). Only the first entry is returned. \*(C`undef\*(C' if issuer contains no state attribute.

issuer_locality

Returns the string value for issuer's locality (= the value with the \s-1OID\s0 2.5.4.7 or in \s-1DN\s0 Syntax everything after \*(C`L=\*(C'). Only the first entry is returned. \*(C`undef\*(C' if issuer contains no locality attribute.

issuer_org

Returns the string value for issuer's organization (= the value with the \s-1OID\s0 2.5.4.10 or in \s-1DN\s0 Syntax everything after \*(C`O=\*(C'). Only the first entry is returned. \*(C`undef\*(C' if issuer contains no organization attribute.

issuer_email

Returns the string value for issuer's email address (= the value with the \s-1OID\s0 1.2.840.113549.1.9.1 or in \s-1DN\s0 Syntax everything after \*(C`E=\*(C'). Only the first entry is returned. \*(C`undef\*(C' if issuer contains no email attribute.

KeyUsage

returns a pointer to an array of strings describing the valid Usages for this certificate. \*(C`undef\*(C' is returned, when the extension is not set in the certificate.

If the extension is marked critical, this is also reported.

$decoded= Crypt::X509->new(cert => $cert); print "Allowed usages for this Certificate are:\n".join("\n",@{$decoded->KeyUsage})."\n";

Example Output: Allowed usages for this Certificate are: critical digitalSignature keyEncipherment dataEncipherment

ExtKeyUsage

returns a pointer to an array of ExtKeyUsage strings (or OIDs for unknown OIDs) or \*(C`undef\*(C' if the extension is not filled. OIDs of the following ExtKeyUsages are known: serverAuth, clientAuth, codeSigning, emailProtection, timeStamping, OCSPSigning

If the extension is marked critical, this is also reported.

$decoded= Crypt::X509->new($cert); print "ExtKeyUsage extension of this Certificates is: ", join(", ", @{$decoded->ExtKeyUsage}), "\n";

Example Output: ExtKeyUsage extension of this Certificates is: critical, serverAuth

SubjectAltName

returns a pointer to an array of strings containing alternative Subjectnames or \*(C`undef\*(C' if the extension is not filled. Usually this Extension holds the e-Mail address for person-certificates or DNS-Names for server certificates.

It also pre-pends the field type (ie rfc822Name) to the returned value.

$decoded= Crypt::X509->new($cert); print "E-Mail or Hostnames in this Certificates is/are:", join(", ", @{$decoded->SubjectAltName}), "\n";

Example Output: E-Mail or Hostnames in this Certificates is/are: [email protected]

authorityCertIssuer

returns a pointer to an array of strings building the \s-1DN\s0 of the Authority Cert Issuer. Attributenames for the most common Attributes are translated from the OID-Numbers, unknown numbers are output verbatim. undef if the extension is not set in the certificate.

$decoded= Crypt::X509->new($cert); print "Certificate was authorised by:".join(',',@{$decoded->authorityCertIssuer})."\n";

authority_serial

Returns the authority's certificate serial number.

key_identifier

Returns the authority key identifier or undef if it is a rooted cert

authority_cn

Returns the authority's ca.

authority_country

Returns the authority's country.

authority_state

Returns the authority's state.

authority_locality

Returns the authority's locality.

authority_org

Returns the authority's organization.

authority_email

Returns the authority's email.

CRLDistributionPoints

Returns the \s-1CRL\s0 distribution points as an array of strings (with one value usually)

CRLDistributionPoints2

Returns the \s-1CRL\s0 distribution points as an array of hashes (allowing for some variations)

CertificatePolicies

Returns the CertificatePolicies as an array of strings

EntrustVersionInfo

Returns the EntrustVersion as a string

print "Entrust Version: ", $decoded->EntrustVersion, "\n";

Example Output: Entrust Version: V7.0

SubjectDirectoryAttributes

Returns the SubjectDirectoryAttributes as an array of key = value pairs, to include a data type

print "Subject Directory Attributes: ", join( ', ' , @{ $decoded->SubjectDirectoryAttributes } ), "\n";

Example Output: Subject Directory Attributes: 1.2.840.113533.7.68.29 = 7 (integer)

BasicConstraints

Returns the BasicConstraints as an array and the criticallity pre-pended.

subject_keyidentifier

Returns the subject key identifier from the extensions.

SubjectInfoAccess

Returns the SubjectInfoAccess as an array of hashes with key=value pairs.

print "Subject Info Access: "; if ( defined $decoded->SubjectInfoAccess ) { my %SIA = $decoded->SubjectInfoAccess; for my $key ( keys %SIA ) { print "\n\t$key: \n\t"; print join( "\n\t" , @{ $SIA{$key} } ), "\n"; } } else { print "\n" }

Example Output: Subject Info Access: 1.3.6.1.5.5.7.48.5: uniformResourceIdentifier = http://pki.treas.gov/root_sia.p7c uniformResourceIdentifier = ldap://ldap.treas.gov/ou=US%20Treasury%20Root%20CA,ou=Certification%20Authorities,ou=Department%20of%20the%20Treasury,o=U.S.%20Government,c=US?cACertificate;binary,crossCertificatePair;binary

PGPExtension

Returns the creation timestamp of the corresponding OpenPGP key. (see http://www.imc.org/ietf-openpgp/mail-archive/msg05320.html)

print "PGPExtension: "; if ( defined $decoded->PGPExtension ) { my $creationtime = $decoded->PGPExtension; printf "\n\tcorresponding OpenPGP Creation Time: ", $creationtime, "\n"; }

Example Output: PGPExtension: whatever

RELATED TO Crypt::X509…

See the examples of \*(C`Convert::ASN1\*(C' and the <[email protected]> Mailing List. An example on how to load certificates can be found in t\Crypt-X509.t.

ACKNOWLEDGEMENTS

This module is based on the x509decode script, which was contributed to Convert::ASN1 in 2002 by Norbert Klasen.

AUTHORS

Mike Jackson <[email protected]>, Alexander Jung <[email protected]>, Duncan Segrest <[email protected]>

COPYRIGHT

Copyright (c) 2005 Mike Jackson <[email protected]>. Copyright (c) 2001-2002 Norbert Klasen, \s-1DAASI\s0 International GmbH.

All rights reserved. This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself.