Skip Menu |

This queue is for tickets about the Crypt-SMIME CPAN distribution.

Report information
The Basics
Id: 115490
Status: resolved
Priority: 0/
Queue: Crypt-SMIME

People
Owner: mikage [...] ymir.co.jp
Requestors: MIK [...] cpan.org
Cc:
AdminCc:

Bug Information
Severity: (no value)
Broken in: (no value)
Fixed in: (no value)



Subject: [PATCH] add setPrivateKeyPkcs12
Hello, please find enclosed patch that adds new function setPrivateKeyPkcs12 which loads private key + corresponding cert from PKCS12 file. The patch includes also test and documentation. Regards, Karel
Subject: setPrivateKeyPkcs12.diff
diff -ru Crypt-SMIME-0.16_original/SMIME.xs Crypt-SMIME-0.16/SMIME.xs --- Crypt-SMIME-0.16_original/SMIME.xs 2015-10-05 03:48:07.000000000 +0200 +++ Crypt-SMIME-0.16/SMIME.xs 2016-06-21 00:02:35.814664200 +0200 @@ -3,6 +3,7 @@ #if defined(HAVE_SYS_TIME_H) # include <sys/time.h> #endif +#include <openssl/rand.h> #include <openssl/crypto.h> #include <openssl/pem.h> #include <openssl/err.h> @@ -485,6 +486,43 @@ OUTPUT: RETVAL +SV* +setPrivateKeyPkcs12(Crypt_SMIME this, SV* pkcs12, char* password = "") + PROTOTYPE: $$$;$ + PREINIT: + BIO *bio; + PKCS12 *p12; + int success = 0; + CODE: + if (this->priv_cert) { + X509_free(this->priv_cert); + this->priv_cert = NULL; + } + if (this->priv_key) { + EVP_PKEY_free(this->priv_key); + this->priv_key = NULL; + } + + if (SvOK(pkcs12)) { + if (bio = BIO_new_mem_buf(SvPV_nolen(pkcs12), SvCUR(pkcs12))) { + if (p12 = d2i_PKCS12_bio(bio, NULL)) { + success = PKCS12_parse(p12, password, &this->priv_key, &this->priv_cert, NULL); + } + BIO_free(bio); + } + } + + if (!success || this->priv_key == NULL || this->priv_cert == NULL) { + OPENSSL_CROAK("Crypt::SMIME#setPrivateKeyPkcs12: failed"); + } + this->priv_key_is_tainted = SvTAINTED(ST(1)); + this->priv_cert_is_tainted = SvTAINTED(ST(1)); + + SvREFCNT_inc(ST(0)); + RETVAL = ST(0); + OUTPUT: + RETVAL + SV* setPublicKey(Crypt_SMIME this, SV* crt) CODE: diff -ru Crypt-SMIME-0.16_original/lib/SMIME.pm Crypt-SMIME-0.16/lib/SMIME.pm --- Crypt-SMIME-0.16_original/lib/SMIME.pm 2015-10-05 03:54:58.000000000 +0200 +++ Crypt-SMIME-0.16/lib/SMIME.pm 2016-06-21 00:05:45.721664200 +0200 @@ -273,6 +273,15 @@ if it fails to load the key. +=item setPrivateKeyPkcs12() + + $smime->setPrivateKeyPkcs12($key, $pkcs12); + $smime->setPrivateKeyPkcs12($key, $pkcs12, $password); + +Load a private key and its X.509 certificate from PKCS12 into the instance. +The private key will be used for signing and decryption. The method dies if +it fails to load PKCS12. + =item setPublicKey() $smime->setPublicKey($crt); diff -ru Crypt-SMIME-0.16_original/t/01-smime.t Crypt-SMIME-0.16/t/01-smime.t --- Crypt-SMIME-0.16_original/t/01-smime.t 2014-05-07 07:46:12.000000000 +0200 +++ Crypt-SMIME-0.16/t/01-smime.t 2016-06-21 00:23:21.628075000 +0200 @@ -8,7 +8,7 @@ use Test::Exception; use Config; -my (%key, %csr, %crt); +my (%key, %csr, %crt, %p12); do { my $OPENSSL = do { if (defined(my $prefix = ExtUtils::PkgConfig->variable('openssl', 'prefix'))) { @@ -49,10 +49,12 @@ (undef, $key{$i}) = tempfile(UNLINK => 1); (undef, $csr{$i}) = tempfile(UNLINK => 1); (undef, $crt{$i}) = tempfile(UNLINK => 1); + (undef, $p12{$i}) = tempfile(UNLINK => 1); system(qq{$OPENSSL genrsa -out $key{$i} >$DEVNULL 2>&1}) and die $!; system(qq{$OPENSSL req -new -key $key{$i} -out $csr{$i} -config $conf_file >$DEVNULL 2>&1}) and die $!; system(qq{$OPENSSL x509 -in $csr{$i} -out $crt{$i} -req -signkey $key{$i} -set_serial $i >$DEVNULL 2>&1}) and die $!; + system(qq{$OPENSSL pkcs12 -export -out $p12{$i} -inkey $key{$i} -in $crt{$i} -passout pass:Secret123 >$DEVNULL 2>&1}) and die $!; } }; @@ -72,6 +74,15 @@ return scalar <$fh>; } +sub p12 { + my $i = shift; + + local $/; + open my $fh, '<', $p12{$i} or die $!; + binmode $fh; + return scalar <$fh>; +} + my $plain = q{From: alice@example.org To: bob@example.org Subject: Crypt::SMIME test @@ -86,7 +97,7 @@ $verify =~ s/\r?\n|\r/\r\n/g; #----------------------- -plan tests => 24; +plan tests => 25; use_ok('Crypt::SMIME'); my $smime; @@ -128,4 +139,7 @@ $smime->setPrivateKey(key(2), crt(2)); ok($decrypted = $smime->decrypt($encrypted), 'decrypt (by recipient\'s key)'); +$smime->setPrivateKeyPkcs12(p12(2), 'Secret123'); +ok($decrypted = $smime->decrypt($encrypted), 'decrypt (by recipient\'s PKCS12 key)'); + 1;
Thank you for your patch. I merged it and released 0.17.