Skip to content

Commit

Permalink
Added a test, and perl directory layout
Browse files Browse the repository at this point in the history
  • Loading branch information
M. Nunberg committed Feb 26, 2011
1 parent b55da05 commit 46156cc
Show file tree
Hide file tree
Showing 7 changed files with 244 additions and 71 deletions.
5 changes: 5 additions & 0 deletions Changes
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
Revision history for Crypt-OpenSSL-Cloner

0.01 Date/time
First version, released on an unsuspecting world.

6 changes: 6 additions & 0 deletions MANIFEST
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
Changes
MANIFEST
Makefile.PL
lib/Crypt/OpenSSL/Cloner.pm
lib/Crypt/OpenSSL/Cloner/x509asn1.pm
t/00_clone.t
19 changes: 19 additions & 0 deletions Makefile.PL
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
use strict;
use warnings;
use ExtUtils::MakeMaker;

WriteMakefile(
NAME => 'Crypt::OpenSSL::Cloner',
AUTHOR => q{M. Nunberg <mnunberg@haskalah.org>},
VERSION_FROM => 'lib/Crypt/OpenSSL/Cloner.pm',
ABSTRACT_FROM => 'lib/Crypt/OpenSSL/Cloner.pm',
($ExtUtils::MakeMaker::VERSION >= 6.3002
? ('LICENSE'=> 'perl')
: ()),
PL_FILES => {},
PREREQ_PM => {
'Test::More' => 0,
},
dist => { COMPRESS => 'gzip -9f', SUFFIX => 'gz', },
clean => { FILES => 'Crypt-OpenSSL-Cloner-*' },
);
55 changes: 55 additions & 0 deletions README
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
Crypt-OpenSSL-Cloner

The README is used to introduce the module and provide instructions on
how to install the module, any machine dependencies it may have (for
example C compilers and installed libraries) and any other information
that should be provided before the module is installed.

A README file is required for CPAN modules since CPAN extracts the README
file from a module distribution so that people browsing the archive
can use it to get an idea of the module's uses. It is usually a good idea
to provide version information here so that people can decide whether
fixes for the module are worth downloading.


INSTALLATION

To install this module, run the following commands:

perl Makefile.PL
make
make test
make install

SUPPORT AND DOCUMENTATION

After installing, you can find documentation for this module with the
perldoc command.

perldoc Crypt::OpenSSL::Cloner

You can also look for information at:

RT, CPAN's request tracker
http://rt.cpan.org/NoAuth/Bugs.html?Dist=Crypt-OpenSSL-Cloner

AnnoCPAN, Annotated CPAN documentation
http://annocpan.org/dist/Crypt-OpenSSL-Cloner

CPAN Ratings
http://cpanratings.perl.org/d/Crypt-OpenSSL-Cloner

Search CPAN
http://search.cpan.org/dist/Crypt-OpenSSL-Cloner/


LICENSE AND COPYRIGHT

Copyright (C) 2011 M. Nunberg

This program is free software; you can redistribute it and/or modify it
under the terms of either: the GNU General Public License as published
by the Free Software Foundation; or the Artistic License.

See http://dev.perl.org/licenses/ for more information.

12 changes: 12 additions & 0 deletions ignore.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
blib*
Makefile
Makefile.old
Build
Build.bat
_build*
pm_to_blib*
*.tar.gz
.lwpcookies
cover_db
pod2htm*.tmp
Crypt-OpenSSL-Cloner-*
110 changes: 39 additions & 71 deletions lib/Crypt/OpenSSL/Cloner.pm
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,9 @@ use Convert::ASN1;
use Crypt::OpenSSL::Cloner::x509asn1;

our $PREFERRED_ALG = "sha1";
our $PREFERRED_KEYLENGTH = 1024;
our $CA_BASENAME = "CA";
our $VERSION = 0.01;

my $ASN = Convert::ASN1->new();
$ASN->prepare($Crypt::OpenSSL::Cloner::x509asn1::ASN_DEF,
Expand Down Expand Up @@ -67,7 +69,7 @@ sub load_ca {

sub _gen_new_ca {
my ($self,$dn_hash) = @_;
my $rsa = Crypt::OpenSSL::RSA->generate_key(1024);
my $rsa = Crypt::OpenSSL::RSA->generate_key($PREFERRED_KEYLENGTH);
my $privkey = Crypt::OpenSSL::CA::PrivateKey->parse(
$rsa->get_private_key_string
);
Expand All @@ -91,7 +93,7 @@ sub _gen_new_ca {
# "digitalSignature, nonRepudiation,".
# "keyEncipherment, dataEncipherment, keyAgreement,".
# "keyCertSign, cRLSign");
my $crt_text = $ca->sign($privkey, "sha1");
my $crt_text = $ca->sign($privkey, $PREFERRED_ALG);
return [$ca,$privkey,$crt_text,$rsa->get_private_key_string];
}

Expand Down Expand Up @@ -215,84 +217,18 @@ sub clone_cert {
}
}
$new_cert->set_extension("subjectAltName", $alt_name_string) if $alt_name_string;
my $new_pem = $new_cert->sign($self->{PRIVKEY_OBJ}, "sha1");
my $new_pem = $new_cert->sign($self->{PRIVKEY_OBJ}, $PREFERRED_ALG);
return ($new_pem, $keystr);
}


if (!caller) {
#my $TEST_CERT = <<PEM;
#-----BEGIN CERTIFICATE-----
#MIIFVTCCBD2gAwIBAgIHBGX+dPs18DANBgkqhkiG9w0BAQUFADCByjELMAkGA1UE
#BhMCVVMxEDAOBgNVBAgTB0FyaXpvbmExEzARBgNVBAcTClNjb3R0c2RhbGUxGjAY
#BgNVBAoTEUdvRGFkZHkuY29tLCBJbmMuMTMwMQYDVQQLEypodHRwOi8vY2VydGlm
#aWNhdGVzLmdvZGFkZHkuY29tL3JlcG9zaXRvcnkxMDAuBgNVBAMTJ0dvIERhZGR5
#IFNlY3VyZSBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTERMA8GA1UEBRMIMDc5Njky
#ODcwHhcNMDkxMjExMDUwMjM2WhcNMTQxMjExMDUwMjM2WjBRMRUwEwYDVQQKEwwq
#LmdpdGh1Yi5jb20xITAfBgNVBAsTGERvbWFpbiBDb250cm9sIFZhbGlkYXRlZDEV
#MBMGA1UEAxMMKi5naXRodWIuY29tMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIB
#CgKCAQEA7dOJw11wcgnzM08acnTZtlqVULtoYZ/3+x8Z4doEMa8VfBp/+XOvHeVD
#K1YJAEVpSujEW9/Cd1JRGVvRK9k5ZTagMhkcQXP7MrI9n5jsglsLN2Q5LLcQg3LN
#8OokS/rZlC7DhRU5qTr2iNr0J4mmlU+EojdOfCV4OsmDbQIXlXh9R6hVg+4TyBka
#szzxX/47AuGF+xFmqwldn0xD8MckXilyKM7UdWhPJHIprjko/N+NT02Dc3QMbxGb
#p91i3v/i6xfm/wy/wC0xO9ZZovLdh0pIe20zERRNNJ8yOPbIGZ3xtj3FRu9RC4rG
#M+1IYcQdFxu9fLZn6TnPpVKACvTqzQIDAQABo4IBtjCCAbIwDwYDVR0TAQH/BAUw
#AwEBADAdBgNVHSUEFjAUBggrBgEFBQcDAQYIKwYBBQUHAwIwDgYDVR0PAQH/BAQD
#AgWgMDMGA1UdHwQsMCowKKAmoCSGImh0dHA6Ly9jcmwuZ29kYWRkeS5jb20vZ2Rz
#MS0xMS5jcmwwUwYDVR0gBEwwSjBIBgtghkgBhv1tAQcXATA5MDcGCCsGAQUFBwIB
#FitodHRwOi8vY2VydGlmaWNhdGVzLmdvZGFkZHkuY29tL3JlcG9zaXRvcnkvMIGA
#BggrBgEFBQcBAQR0MHIwJAYIKwYBBQUHMAGGGGh0dHA6Ly9vY3NwLmdvZGFkZHku
#Y29tLzBKBggrBgEFBQcwAoY+aHR0cDovL2NlcnRpZmljYXRlcy5nb2RhZGR5LmNv
#bS9yZXBvc2l0b3J5L2dkX2ludGVybWVkaWF0ZS5jcnQwHwYDVR0jBBgwFoAU/axh
#MpNsRdbi7oVfmrrndplozOcwIwYDVR0RBBwwGoIMKi5naXRodWIuY29tggpnaXRo
#dWIuY29tMB0GA1UdDgQWBBSH0Y8ZbuSHb1OMd5EHUN+jv1VHIDANBgkqhkiG9w0B
#AQUFAAOCAQEAwIe/Bbuk1/r38aqb5wlXjoW6tAmLpzLRkKorDOcDUJLtN6a9XqAk
#cgMai7NCI1YV+A4IjEENj53mV2xWLpniqLDHI5y2NbQuL2deu1jQSSNz7xE/nZCk
#WGt8OEtm6YI2bUsq5EXy078avRbigBko1bqtFuG0s5+nFrKCjhQVIk+GX7cwiyr4
#XJ49FxETvePrxNYr7x7n/Jju59KXTw3juPET+bAwNlRXmScjrMylMNUMr3sFcyLz
#DciaVnnextu6+L0w1+5KNVbMKndRwgg/cRldBL4AgmtouTC3mlDGGG3U6eV75cdH
#D03DXDfrYYjxmWjTRdO2GdbYnt1ToEgxyA==
#-----END CERTIFICATE-----
#PEM

#GOOGLE:
my $TEST_CERT = <<PEM;
-----BEGIN CERTIFICATE-----
MIIDIjCCAougAwIBAgIQHxn23jXdY6FCkYrVLMCrEjANBgkqhkiG9w0BAQUFADBM
MQswCQYDVQQGEwJaQTElMCMGA1UEChMcVGhhd3RlIENvbnN1bHRpbmcgKFB0eSkg
THRkLjEWMBQGA1UEAxMNVGhhd3RlIFNHQyBDQTAeFw0wOTEyMTgwMDAwMDBaFw0x
MTEyMTgyMzU5NTlaMGkxCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpDYWxpZm9ybmlh
MRYwFAYDVQQHFA1Nb3VudGFpbiBWaWV3MRMwEQYDVQQKFApHb29nbGUgSW5jMRgw
FgYDVQQDFA9tYWlsLmdvb2dsZS5jb20wgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJ
AoGBANknyBHye+RFyUa2Y3WDsXd+F0GJgDjxRSegPNnoqABL2QfQut7t9CymrNwn
E+wMwaaZF0LmjSfSgRSwS4L6ssXQuyBZYiijlrVh9nbBbUbS/brGDz3RyXeaWDP2
BnYyrVFfKV9u+BKLrebFCDmzQ0OpW5Ed1+PPUd91WY6NgKtTAgMBAAGjgecwgeQw
DAYDVR0TAQH/BAIwADA2BgNVHR8ELzAtMCugKaAnhiVodHRwOi8vY3JsLnRoYXd0
ZS5jb20vVGhhd3RlU0dDQ0EuY3JsMCgGA1UdJQQhMB8GCCsGAQUFBwMBBggrBgEF
BQcDAgYJYIZIAYb4QgQBMHIGCCsGAQUFBwEBBGYwZDAiBggrBgEFBQcwAYYWaHR0
cDovL29jc3AudGhhd3RlLmNvbTA+BggrBgEFBQcwAoYyaHR0cDovL3d3dy50aGF3
dGUuY29tL3JlcG9zaXRvcnkvVGhhd3RlX1NHQ19DQS5jcnQwDQYJKoZIhvcNAQEF
BQADgYEAicju7fexy+yRP2drx57Tcqo+BElR1CiHNZ1nhPmS9QSZaudDA8jy25IP
VWvjEgaq13Hro0Hg32ZNVK53qcXwjWtnCAReojvNwj6/x1Ciq5B6D7E6eiYDSfXJ
8/a2vR5IbgY89nq+wuHaA6vspH6vNR848xO3z1PQ7BrIjnYQ1A0=
-----END CERTIFICATE-----
PEM
use Carp qw(confess);
$SIG{__DIE__} = sub { confess $_[0] };

my $CA = __PACKAGE__->new();
my ($pem, $privkey) = $CA->clone_cert($TEST_CERT);
write_file($CA->{PATH} . "/dummy.pem", \$pem);
write_file($CA->{PATH} . "/dummy.key", \$privkey);
}

1;

__END__
=head1 NAME
Crypt::OpenSSL::Cloner - Clone an existing certificate.
Crypt::OpenSSL::Cloner - Clone an existing certificate and sign it with your own
CA
=head1 SYNOPSIS
Expand Down Expand Up @@ -339,3 +275,35 @@ synopsis)
Clones an existing certificate. It takes one argument, which is a PEM blob.
It returns a pair of ($new_pem,$new_rsa_key). You are free to save it, if you
wish.
=head2 PACKAGE/CONFIGURATION VARIABLES
There are some package variables which control some trivial aspects of this module
=over
=item PREFERRED_ALG
The preferred algorithm to use for creating new private keys. An appropriate
value is one accepted by the L<Crypt::OpenSSL::CA>::X509->sign method.
=item PREFERRED_KEYLENGTH
Keylength to use for private keys. As always, this must be a power of two
=item CA_BASENAME
What the CA files will be called within the CA directory. They will live there
in the format of $CA_BASENAME.pem and $CA_BASENAME.key
=back
=head1 LICENSE & COPYRIGHT
Copyright 2011 M. Nunberg
All rights are reserved. Crypt::OpenSSL::Cloner is free software;
you may redistribute it and/or modify it under the same terms as Perl itself.
This product includes software developed by the OpenSSL Project
for use in the OpenSSL Toolkit. (http://www.openssl.org/)
108 changes: 108 additions & 0 deletions t/00_clone.t
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
#!/opt/local/bin/perl
use strict;
use warnings;

use Test::More;
use File::Temp qw(tempdir);

BEGIN {
use_ok("Crypt::OpenSSL::Cloner", "use our module");
}

my $tmpdir = tempdir(CLEANUP => 1);
my $CA;
my @CERTS;
my $DN_HREF = {
C => US => O => FooOrg => OU => BigUnit => CN => "Foo big unit trust"
};

$CA = Crypt::OpenSSL::Cloner->new(path => $tmpdir, dn => $DN_HREF);

isa_ok($CA, "Crypt::OpenSSL::Cloner", "new CA with directory");
my $dn_text = $CA->{CA_OBJ}->get_issuer_DN->to_string();
undef $CA;

ok(-f $tmpdir . "/" . $Crypt::OpenSSL::Cloner::CA_BASENAME . ".key",
"checked for key file");
ok(-f $tmpdir . "/" . $Crypt::OpenSSL::Cloner::CA_BASENAME . ".pem",
"checked for PEM encoded cert");

$CA = Crypt::OpenSSL::Cloner->new(path => $tmpdir);
isa_ok($CA, "Crypt::OpenSSL::Cloner", "load from existing directory");
is($CA->{CA_OBJ}->get_issuer_DN->to_string, $dn_text,
"same certificate data(sort of)");

my @pems;
my @pkeys;
foreach my $cert (@CERTS) {
my ($pem,$privkey) = $CA->clone_cert($cert);
push @pems, $pem;
push @pkeys, $privkey;
}
my $certcount = @CERTS;
my $pem_count = (grep $_, @pems);
my $key_count = (grep $_, @pkeys);
ok($pem_count == $key_count &&
$key_count == $certcount,
"Got $key_count keys, $pem_count certificates/
$certcount input");
done_testing();


BEGIN {
push @CERTS, <<PEM;
-----BEGIN CERTIFICATE-----
MIIFVTCCBD2gAwIBAgIHBGX+dPs18DANBgkqhkiG9w0BAQUFADCByjELMAkGA1UE
BhMCVVMxEDAOBgNVBAgTB0FyaXpvbmExEzARBgNVBAcTClNjb3R0c2RhbGUxGjAY
BgNVBAoTEUdvRGFkZHkuY29tLCBJbmMuMTMwMQYDVQQLEypodHRwOi8vY2VydGlm
aWNhdGVzLmdvZGFkZHkuY29tL3JlcG9zaXRvcnkxMDAuBgNVBAMTJ0dvIERhZGR5
IFNlY3VyZSBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTERMA8GA1UEBRMIMDc5Njky
ODcwHhcNMDkxMjExMDUwMjM2WhcNMTQxMjExMDUwMjM2WjBRMRUwEwYDVQQKEwwq
LmdpdGh1Yi5jb20xITAfBgNVBAsTGERvbWFpbiBDb250cm9sIFZhbGlkYXRlZDEV
MBMGA1UEAxMMKi5naXRodWIuY29tMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIB
CgKCAQEA7dOJw11wcgnzM08acnTZtlqVULtoYZ/3+x8Z4doEMa8VfBp/+XOvHeVD
K1YJAEVpSujEW9/Cd1JRGVvRK9k5ZTagMhkcQXP7MrI9n5jsglsLN2Q5LLcQg3LN
8OokS/rZlC7DhRU5qTr2iNr0J4mmlU+EojdOfCV4OsmDbQIXlXh9R6hVg+4TyBka
szzxX/47AuGF+xFmqwldn0xD8MckXilyKM7UdWhPJHIprjko/N+NT02Dc3QMbxGb
p91i3v/i6xfm/wy/wC0xO9ZZovLdh0pIe20zERRNNJ8yOPbIGZ3xtj3FRu9RC4rG
M+1IYcQdFxu9fLZn6TnPpVKACvTqzQIDAQABo4IBtjCCAbIwDwYDVR0TAQH/BAUw
AwEBADAdBgNVHSUEFjAUBggrBgEFBQcDAQYIKwYBBQUHAwIwDgYDVR0PAQH/BAQD
AgWgMDMGA1UdHwQsMCowKKAmoCSGImh0dHA6Ly9jcmwuZ29kYWRkeS5jb20vZ2Rz
MS0xMS5jcmwwUwYDVR0gBEwwSjBIBgtghkgBhv1tAQcXATA5MDcGCCsGAQUFBwIB
FitodHRwOi8vY2VydGlmaWNhdGVzLmdvZGFkZHkuY29tL3JlcG9zaXRvcnkvMIGA
BggrBgEFBQcBAQR0MHIwJAYIKwYBBQUHMAGGGGh0dHA6Ly9vY3NwLmdvZGFkZHku
Y29tLzBKBggrBgEFBQcwAoY+aHR0cDovL2NlcnRpZmljYXRlcy5nb2RhZGR5LmNv
bS9yZXBvc2l0b3J5L2dkX2ludGVybWVkaWF0ZS5jcnQwHwYDVR0jBBgwFoAU/axh
MpNsRdbi7oVfmrrndplozOcwIwYDVR0RBBwwGoIMKi5naXRodWIuY29tggpnaXRo
dWIuY29tMB0GA1UdDgQWBBSH0Y8ZbuSHb1OMd5EHUN+jv1VHIDANBgkqhkiG9w0B
AQUFAAOCAQEAwIe/Bbuk1/r38aqb5wlXjoW6tAmLpzLRkKorDOcDUJLtN6a9XqAk
cgMai7NCI1YV+A4IjEENj53mV2xWLpniqLDHI5y2NbQuL2deu1jQSSNz7xE/nZCk
WGt8OEtm6YI2bUsq5EXy078avRbigBko1bqtFuG0s5+nFrKCjhQVIk+GX7cwiyr4
XJ49FxETvePrxNYr7x7n/Jju59KXTw3juPET+bAwNlRXmScjrMylMNUMr3sFcyLz
DciaVnnextu6+L0w1+5KNVbMKndRwgg/cRldBL4AgmtouTC3mlDGGG3U6eV75cdH
D03DXDfrYYjxmWjTRdO2GdbYnt1ToEgxyA==
-----END CERTIFICATE-----
PEM

push @CERTS, <<PEM;
-----BEGIN CERTIFICATE-----
MIIDIjCCAougAwIBAgIQHxn23jXdY6FCkYrVLMCrEjANBgkqhkiG9w0BAQUFADBM
MQswCQYDVQQGEwJaQTElMCMGA1UEChMcVGhhd3RlIENvbnN1bHRpbmcgKFB0eSkg
THRkLjEWMBQGA1UEAxMNVGhhd3RlIFNHQyBDQTAeFw0wOTEyMTgwMDAwMDBaFw0x
MTEyMTgyMzU5NTlaMGkxCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpDYWxpZm9ybmlh
MRYwFAYDVQQHFA1Nb3VudGFpbiBWaWV3MRMwEQYDVQQKFApHb29nbGUgSW5jMRgw
FgYDVQQDFA9tYWlsLmdvb2dsZS5jb20wgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJ
AoGBANknyBHye+RFyUa2Y3WDsXd+F0GJgDjxRSegPNnoqABL2QfQut7t9CymrNwn
E+wMwaaZF0LmjSfSgRSwS4L6ssXQuyBZYiijlrVh9nbBbUbS/brGDz3RyXeaWDP2
BnYyrVFfKV9u+BKLrebFCDmzQ0OpW5Ed1+PPUd91WY6NgKtTAgMBAAGjgecwgeQw
DAYDVR0TAQH/BAIwADA2BgNVHR8ELzAtMCugKaAnhiVodHRwOi8vY3JsLnRoYXd0
ZS5jb20vVGhhd3RlU0dDQ0EuY3JsMCgGA1UdJQQhMB8GCCsGAQUFBwMBBggrBgEF
BQcDAgYJYIZIAYb4QgQBMHIGCCsGAQUFBwEBBGYwZDAiBggrBgEFBQcwAYYWaHR0
cDovL29jc3AudGhhd3RlLmNvbTA+BggrBgEFBQcwAoYyaHR0cDovL3d3dy50aGF3
dGUuY29tL3JlcG9zaXRvcnkvVGhhd3RlX1NHQ19DQS5jcnQwDQYJKoZIhvcNAQEF
BQADgYEAicju7fexy+yRP2drx57Tcqo+BElR1CiHNZ1nhPmS9QSZaudDA8jy25IP
VWvjEgaq13Hro0Hg32ZNVK53qcXwjWtnCAReojvNwj6/x1Ciq5B6D7E6eiYDSfXJ
8/a2vR5IbgY89nq+wuHaA6vspH6vNR848xO3z1PQ7BrIjnYQ1A0=
-----END CERTIFICATE-----
PEM
}

0 comments on commit 46156cc

Please sign in to comment.