Skip to content

Commit

Permalink
Merge branch 'release/0.54'
Browse files Browse the repository at this point in the history
  • Loading branch information
Scott Hardin committed Apr 26, 2021
2 parents 76fca29 + fe1763b commit 3e5b4c5
Show file tree
Hide file tree
Showing 4 changed files with 124 additions and 72 deletions.
2 changes: 1 addition & 1 deletion META.yml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
--- #YAML:1.0
name: Crypt-X509
version: 0.53
version: '0.54';
abstract: Parse a X.509 certificate
author:
- Mike Jackson, Alexander Jung, Duncan Segrest, Oliver Welter
Expand Down
27 changes: 16 additions & 11 deletions build.mkd
Original file line number Diff line number Diff line change
Expand Up @@ -6,23 +6,28 @@ Note: Replace '0.10' in the examples below with the current version.

* Start release branch

# Set the connver to the new version number
connver=0.10
git flow release start $connver develop
# Set the modver to the new version number
modver=0.10
git flow release start $modver develop

* Bump version number in lib/Connector.pm
* Make any last-minute fixes

perl -i -pe "s{^version: .+}{version: '$connver';};" \
META.yml
git add META.yml
git commit -m "bump version to $connver"
* Run unit tests

* Make any last-minute fixes
perl Makefile.PL
make test

* Bump version number in lib/Crypt/X509.pm

perl -i -pe "s{^our \\\$VERSION.+}{our \\\$VERSION = '$modver';};" lib/Crypt/X509.pm
perl -i -pe "s{^version: .+}{version: '$modver';};" META.yml
git add lib/Crypt/X509.pm META.yml
git commit -m "bump version to $modver"

* Finalize release (write the version number in the TAG\_MSG)

git flow release finish "$connver"
git push origin develop master "$connver"
git flow release finish "$modver"
git push origin develop master "$modver"

* Build tarball

Expand Down
156 changes: 98 additions & 58 deletions lib/Crypt/X509.pm
Original file line number Diff line number Diff line change
Expand Up @@ -8,37 +8,57 @@ our @ISA = qw(Exporter);
our %EXPORT_TAGS = ( 'all' => [qw()] );
our @EXPORT_OK = ( @{ $EXPORT_TAGS{'all'} } );
#our @EXPORT = qw(error new not_before not_after serial);
our $VERSION = '0.53';
our $VERSION = '0.54';
my $parser = undef;
my $asn = undef;
my $error = undef;
our %oid2enchash = (
'1.2.840.113549.1.1.1' => { 'enc' => 'RSA' },
'1.2.840.113549.1.1.2' => { 'enc' => 'RSA', 'hash' => 'MD2' },
'1.2.840.113549.1.1.3' => { 'enc' => 'RSA', 'hash' => 'MD4' },
'1.2.840.113549.1.1.4' => { 'enc' => 'RSA', 'hash' => 'MD5' },
'1.2.840.113549.1.1.5' => { 'enc' => 'RSA', 'hash' => 'SHA1' },
'1.2.840.113549.1.1.6' => { 'enc' => 'OAEP' },
'1.2.840.113549.1.1.11' => { 'enc' => 'RSA', 'hash' => 'SHA256' },
'1.2.840.113549.1.1.12' => { 'enc' => 'RSA', 'hash' => 'SHA384' },
'1.2.840.113549.1.1.13' => { 'enc' => 'RSA', 'hash' => 'SHA512' },
'1.2.840.113549.1.1.14' => { 'enc' => 'RSA', 'hash' => 'SHA224' }
'1.2.840.113549.1.1.1' => { 'enc' => 'RSA' },
'1.2.840.113549.1.1.2' => { 'enc' => 'RSA', 'hash' => 'MD2' },
'1.2.840.113549.1.1.3' => { 'enc' => 'RSA', 'hash' => 'MD4' },
'1.2.840.113549.1.1.4' => { 'enc' => 'RSA', 'hash' => 'MD5' },
'1.2.840.113549.1.1.5' => { 'enc' => 'RSA', 'hash' => 'SHA1' },
'1.2.840.113549.1.1.6' => { 'enc' => 'OAEP' },
'1.2.840.113549.1.1.11' => { 'enc' => 'RSA', 'hash' => 'SHA256' },
'1.2.840.113549.1.1.12' => { 'enc' => 'RSA', 'hash' => 'SHA384' },
'1.2.840.113549.1.1.13' => { 'enc' => 'RSA', 'hash' => 'SHA512' },
'1.2.840.113549.1.1.14' => { 'enc' => 'RSA', 'hash' => 'SHA224' },
'1.2.840.10045.2.1' => { 'enc' => 'EC' },
);

our %oid2attr = (
"2.5.4.3" => "CN",
"2.5.4.4" => "SN",
"2.5.4.42" => "GN",
"2.5.4.5" => "serialNumber",
"2.5.4.6" => "C",
"2.5.4.7" => "L",
"2.5.4.8" => "ST",
"2.5.4.10" => "O",
"2.5.4.11" => "OU",
"1.2.840.113549.1.9.1" => "E",
"0.9.2342.19200300.100.1.1" => "UID",
"0.9.2342.19200300.100.1.25" => "DC",
"0.2.262.1.10.7.20" => "nameDistinguisher"
"2.5.4.3" => "CN",
"2.5.4.4" => "SN",
"2.5.4.42" => "GN",
"2.5.4.5" => "serialNumber",
"2.5.4.6" => "C",
"2.5.4.7" => "L",
"2.5.4.8" => "ST",
'2.5.4.9' => 'streetAddress',
"2.5.4.10" => "O",
"2.5.4.11" => "OU",
"1.2.840.113549.1.9.1" => "emailAddress",
'1.2.840.113549.1.9.2' => 'unstructuredName',
"0.9.2342.19200300.100.1.1" => "UID",
"0.9.2342.19200300.100.1.25" => "DC",
"0.2.262.1.10.7.20" => "nameDistinguisher",
'2.5.4.12' => 'title',
'2.5.4.13' => 'description',
'2.5.4.14' => 'searchGuide',
'2.5.4.15' => 'businessCategory',
'2.5.4.16' => 'postalAddress',
'2.5.4.17' => 'postalCode',
'2.5.4.18' => 'postOfficeBox',
'2.5.4.19' => 'physicalDeliveryOfficeName',
'2.5.4.20' => 'telephoneNumber',
'2.5.4.23' => 'facsimileTelephoneNumber',
'2.5.4.41' => 'name',
'2.5.4.43' => 'initials',
'2.5.4.44' => 'generationQualifier',
'2.5.4.45' => 'uniqueIdentifier',
'2.5.4.46' => 'dnQualifier',
'2.5.4.51' => 'houseIdentifier',
'2.5.4.65' => 'pseudonym',
);

=head1 NAME
Expand Down Expand Up @@ -394,6 +414,26 @@ sub Subject {
return $subjdn;
}


sub SubjectRaw {

my $self = shift;
my @subject;
foreach my $rdn (@{$self->{'tbsCertificate'}->{'subject'}->{'rdnSequence'}}) {
my @sequence = map {
$_->{format} = (keys %{$_->{value}})[0];
$_->{value} = (values %{$_->{value}})[0];
$_;
} @{$rdn};
if (scalar @sequence > 1) {
push @subject, \@sequence;
} else {
push @subject, $sequence[0];
}
}
return \@subject;
}

sub _subject_part {
my $self = shift;
my $oid = shift;
Expand Down Expand Up @@ -490,7 +530,7 @@ sub subject_cn {
=head2 subject_email
Returns the string value for subject's email address (= the value with the
OID 1.2.840.113549.1.9.1 or in DN Syntax everything after C<E=>).
OID 1.2.840.113549.1.9.1 or in DN Syntax everything after C<emailAddress=>).
Only the first entry is returned. C<undef> if subject contains no email attribute.
=cut back
Expand Down Expand Up @@ -656,7 +696,7 @@ sub KeyUsage {
; # no extensions in certificate
foreach $ext ( @{$exts} ) {
if ( $ext->{'extnID'} eq '2.5.29.15' ) { #OID for keyusage
my $parsKeyU = _init('KeyUsage'); # get a parser for this
my $parsKeyU = _init('KeyUsage'); # get a parser for this
my $keyusage = $parsKeyU->decode( $ext->{'extnValue'} ); # decode the value
if ( $parsKeyU->error ) {
$self->{"_error"} = $parsKeyU->error;
Expand Down Expand Up @@ -695,12 +735,12 @@ If the extension is marked critical, this is also reported.
=cut back
our %oid2extkeyusage = (
'1.3.6.1.5.5.7.3.1' => 'serverAuth',
'1.3.6.1.5.5.7.3.2' => 'clientAuth',
'1.3.6.1.5.5.7.3.3' => 'codeSigning',
'1.3.6.1.5.5.7.3.4' => 'emailProtection',
'1.3.6.1.5.5.7.3.8' => 'timeStamping',
'1.3.6.1.5.5.7.3.9' => 'OCSPSigning',
'1.3.6.1.5.5.7.3.1' => 'serverAuth',
'1.3.6.1.5.5.7.3.2' => 'clientAuth',
'1.3.6.1.5.5.7.3.3' => 'codeSigning',
'1.3.6.1.5.5.7.3.4' => 'emailProtection',
'1.3.6.1.5.5.7.3.8' => 'timeStamping',
'1.3.6.1.5.5.7.3.9' => 'OCSPSigning',
);

sub ExtKeyUsage {
Expand All @@ -712,7 +752,7 @@ sub ExtKeyUsage {
foreach $ext ( @{$exts} ) {
if ( $ext->{'extnID'} eq '2.5.29.37' ) { #OID for ExtKeyUsage
return $ext->{'oids'} if defined $ext->{'oids'};
my $parsExtKeyUsage = _init('ExtKeyUsageSyntax'); # get a parser for this
my $parsExtKeyUsage = _init('ExtKeyUsageSyntax'); # get a parser for this
my $oids = $parsExtKeyUsage->decode( $ext->{'extnValue'} ); # decode the value
if ( $parsExtKeyUsage->error ) {
$self->{"_error"} = $parsExtKeyUsage->error;
Expand Down Expand Up @@ -749,7 +789,7 @@ sub SubjectAltName {
; # no extensions in certificate
foreach $ext ( @{$exts} ) {
if ( $ext->{'extnID'} eq '2.5.29.17' ) { #OID for SubjectAltName
my $parsSubjAlt = _init('SubjectAltName'); # get a parser for this
my $parsSubjAlt = _init('SubjectAltName'); # get a parser for this
my $altnames = $parsSubjAlt->decode( $ext->{'extnValue'} ); # decode the value
if ( $parsSubjAlt->error ) {
$self->{"_error"} = $parsSubjAlt->error;
Expand Down Expand Up @@ -1037,23 +1077,23 @@ sub CRLDistributionPoints2 {
if ( $extension->{'extnID'} eq '2.5.29.31' ) { # OID for ARRAY of cRLDistributionPoints
my $parser = _init('cRLDistributionPoints'); # get a parser for CDPs
my $points = $parser->decode( $extension->{'extnValue'} ); # decode the values (returns an array)
for my $each_dp ( @{$points} ) { # this loops through multiple "distributionPoint" values
for my $each_dp ( @{$points} ) { # this loops through multiple "distributionPoint" values
$dp_cnt++;
for my $each_fullName ( @{ $each_dp->{'distributionPoint'}->{'fullName'} } )
{ # this loops through multiple "fullName" values
{ # this loops through multiple "fullName" values
if ( exists $each_fullName->{directoryName} ) {

# found a rdnSequence
my $rdn = join ',', reverse @{ my_CRL_rdn( $each_fullName->{directoryName}->{rdnSequence} ) };
push @{ $CDPs{$dp_cnt} }, "Directory Address: $rdn";
# found a rdnSequence
my $rdn = join ',', reverse @{ my_CRL_rdn( $each_fullName->{directoryName}->{rdnSequence} ) };
push @{ $CDPs{$dp_cnt} }, "Directory Address: $rdn";
} elsif ( exists $each_fullName->{uniformResourceIdentifier} ) {

# found a URI
push @{ $CDPs{$dp_cnt} }, "URL: " . $each_fullName->{uniformResourceIdentifier};
# found a URI
push @{ $CDPs{$dp_cnt} }, "URL: " . $each_fullName->{uniformResourceIdentifier};
} else {

# found some other type of CDP value
# return undef;
# found some other type of CDP value
# return undef;
}
}
}
Expand Down Expand Up @@ -1164,7 +1204,7 @@ sub SubjectDirectoryAttributes {
for my $type ( @{$subject_dir_attrs} ) {
for my $value ( @{ $type->{'values'} } ) {
for my $key ( keys %{$value} ) {
push @{$attributes}, $type->{'type'} . " = " . $value->{$key} . " ($key)";
push @{$attributes}, $type->{'type'} . " = " . $value->{$key} . " ($key)";
}
}
}
Expand All @@ -1191,7 +1231,7 @@ sub BasicConstraints {
for $extension ( @{$extensions} ) {
if ( $extension->{'extnID'} eq '2.5.29.19' ) { # OID for BasicConstraints
if ( $extension->{'critical'} ) { push @{$constraints}, "critical"; } # mark this as critical as appropriate
my $parser = _init('BasicConstraints'); # get a parser for this
my $parser = _init('BasicConstraints'); # get a parser for this
my $basic_constraints = $parser->decode( $extension->{'extnValue'} ); # decode the value
for my $key ( keys %{$basic_constraints} ) {
push @{$constraints}, "$key = " . $basic_constraints->{$key};
Expand Down Expand Up @@ -1310,14 +1350,14 @@ sub PGPExtension {
if ( $extension->{'extnID'} eq '1.3.6.1.4.1.3401.8.1.1' ) { # OID for PGPExtension
my $parser = _init('PGPExtension'); # get a parser for this
my $pgpextension = $parser->decode( $extension->{'extnValue'} ); # decode the value
if ($pgpextension->{version} != 0) {
$self->{"_error"} = sprintf("got PGPExtension version %d. We only know how to deal with v1 (0)", $pgpextension->{version});
} else {
foreach my $timetype ('generalTime', 'utcTime') {
return $pgpextension->{keyCreation}->{$timetype}
if exists $pgpextension->{keyCreation}->{$timetype};
}
}
if ($pgpextension->{version} != 0) {
$self->{"_error"} = sprintf("got PGPExtension version %d. We only know how to deal with v1 (0)", $pgpextension->{version});
} else {
foreach my $timetype ('generalTime', 'utcTime') {
return $pgpextension->{keyCreation}->{$timetype}
if exists $pgpextension->{keyCreation}->{$timetype};
}
}
}
}
return undef;
Expand Down Expand Up @@ -1542,14 +1582,14 @@ SubjectAltName ::= GeneralNames
GeneralNames ::= SEQUENCE OF GeneralName
GeneralName ::= CHOICE {
otherName [0] AnotherName,
rfc822Name [1] IA5String,
dNSName [2] IA5String,
otherName [0] AnotherName,
rfc822Name [1] IA5String,
dNSName [2] IA5String,
x400Address [3] ANY, --ORAddress,
directoryName [4] Name,
ediPartyName [5] EDIPartyName,
uniformResourceIdentifier [6] IA5String,
iPAddress [7] OCTET STRING,
iPAddress [7] OCTET STRING,
registeredID [8] OBJECT IDENTIFIER }
EntrustVersionInfo ::= SEQUENCE {
Expand Down Expand Up @@ -1588,7 +1628,7 @@ SubjectDirectoryAttributes ::= SEQUENCE OF Attribute
-- id-ce-basicConstraints OBJECT IDENTIFIER ::= { id-ce 19 }
BasicConstraints ::= SEQUENCE {
cA BOOLEAN OPTIONAL, --DEFAULT FALSE,
cA BOOLEAN OPTIONAL, --DEFAULT FALSE,
pathLenConstraint INTEGER OPTIONAL }
Expand Down
11 changes: 9 additions & 2 deletions t/Crypt-X509.t
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Before `make install' is performed this script should be runnable with
# `make test'. After `make install' it should work as `perl Crypt-X509.t'
use Test::More tests => 70;
use Test::More tests => 71;
use Math::BigInt;
BEGIN { use_ok('Crypt::X509') }

Expand All @@ -21,12 +21,18 @@ is( join( ':', @{ $decoded2->ExtKeyUsage } ), "clientAuth:emailProtection", 'Ext
# this has also to work twice
is( join( ':', @{ $decoded2->KeyUsage } ), "critical:digitalSignature:keyEncipherment:dataEncipherment", 'Keyusagecheck again' );
is( join( ':', @{ $decoded2->ExtKeyUsage } ), "clientAuth:emailProtection", 'Extkeyusagecheck again' );
is( join( ',', @{ $decoded2->Subject } ), "E=alexander.jung\@allianz.de,C=DE,O=Allianz Group,CN=Alexander Jung", 'Subject parsed' );
is( join( ',', @{ $decoded2->Subject } ), "emailAddress=alexander.jung\@allianz.de,C=DE,O=Allianz Group,CN=Alexander Jung", 'Subject parsed' );
is( $decoded2->subject_country, "DE", "Subject_country" );
is( $decoded2->subject_state, undef, "Subject_state" );
is( $decoded2->subject_org, "Allianz Group", "Subject_org" );
is( $decoded2->subject_ou, undef, "Subject_ou" );
is( $decoded2->subject_email, "alexander.jung\@allianz.de", "Subject_email" );
is_deeply( $decoded2->SubjectRaw, [
{'type' => '1.2.840.113549.1.9.1','value' => '[email protected]','format' => 'ia5String'},
{'type' => '2.5.4.6','value' => 'DE','format' => 'printableString'},
{'type' => '2.5.4.10','value' => 'Allianz Group','format' => 'printableString'},
{'type' => '2.5.4.3','value' => 'Alexander Jung','format' => 'printableString'}
]);
is( join( ',', @{ $decoded2->Issuer } ), "C=DE,O=Allianz Group,CN=Allianz Dresdner CA", "Issuer Parsed");
is( $decoded2->issuer_cn, "Allianz Dresdner CA", "Issuer_cn" );
is( $decoded2->issuer_country, "DE", "Isssuer_country" );
Expand All @@ -41,6 +47,7 @@ is( length( $decoded2->signature ), 256, "Signature Length" )
is( join( ',', @{ $decoded2->SubjectAltName } ), "rfc822Name=alexander.jung\@allianz.de", 'SubjectAltName parsed' );
is_deeply( $decoded2->DecodedSubjectAltNames, [[{rfc822Name => '[email protected]'}]], 'DecodedSubjectAltName parsed' );


$cert = loadcert('t/aj2.cer');
$decoded3 = Crypt::X509->new( cert => $cert );
is( $decoded3->error, undef, 'decode successful' );
Expand Down

0 comments on commit 3e5b4c5

Please sign in to comment.