Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -171,12 +171,12 @@ this (never documented) behavior is no longer the case.
-----BEGIN RSA PRIVATE KEY------
-----END RSA PRIVATE KEY------

2 optional parameters can be passed for passphase protected private key
2 optional parameters can be passed for passphrase protected private key
string:

- passphase
- passphrase

The passphase which protects the private key.
The passphrase which protects the private key.

- cipher name

Expand Down
6 changes: 3 additions & 3 deletions RSA.pm
Original file line number Diff line number Diff line change
Expand Up @@ -289,14 +289,14 @@ header and footer lines:
-----BEGIN RSA PRIVATE KEY------
-----END RSA PRIVATE KEY------

2 optional parameters can be passed for passphase protected private key
2 optional parameters can be passed for passphrase protected private key
string:

=over

=item passphase
=item passphrase

The passphase which protects the private key.
The passphrase which protects the private key.

=item cipher name

Expand Down
50 changes: 25 additions & 25 deletions RSA.xs
Original file line number Diff line number Diff line change
Expand Up @@ -368,24 +368,24 @@ SV* extractBioString(BIO* p_stringBio)

EVP_PKEY* _load_rsa_key(SV* p_keyStringSv,
EVP_PKEY*(*p_loader)(BIO *, EVP_PKEY**, pem_password_cb*, void*),
SV* p_passphaseSv)
SV* p_passphraseSv)
{
STRLEN keyStringLength;
char* keyString;
UNSIGNED_CHAR *passphase = NULL;
UNSIGNED_CHAR *passphrase = NULL;

EVP_PKEY* rsa;
BIO* stringBIO;

keyString = SvPV(p_keyStringSv, keyStringLength);

if (SvPOK(p_passphaseSv)) {
passphase = (UNSIGNED_CHAR *)SvPV_nolen(p_passphaseSv);
if (SvPOK(p_passphraseSv)) {
passphrase = (UNSIGNED_CHAR *)SvPV_nolen(p_passphraseSv);
}

CHECK_OPEN_SSL(stringBIO = BIO_new_mem_buf(keyString, keyStringLength));

rsa = p_loader(stringBIO, NULL, NULL, passphase);
rsa = p_loader(stringBIO, NULL, NULL, passphrase);

CHECK_OPEN_SSL(BIO_set_close(stringBIO, BIO_CLOSE) == 1);
BIO_free(stringBIO);
Expand Down Expand Up @@ -531,13 +531,13 @@ BOOT:
#endif

SV*
_new_private_key_pem(proto, key_string_SV, passphase_SV=&PL_sv_undef)
_new_private_key_pem(proto, key_string_SV, passphrase_SV=&PL_sv_undef)
SV* proto;
SV* key_string_SV;
SV* passphase_SV;
SV* passphrase_SV;
CODE:
RETVAL = make_rsa_obj(
proto, _load_rsa_key(key_string_SV, PEM_read_bio_PrivateKey, passphase_SV));
proto, _load_rsa_key(key_string_SV, PEM_read_bio_PrivateKey, passphrase_SV));
OUTPUT:
RETVAL

Expand Down Expand Up @@ -670,26 +670,26 @@ DESTROY(p_rsa)
Safefree(p_rsa);

SV*
get_private_key_string(p_rsa, passphase_SV=&PL_sv_undef, cipher_name_SV=&PL_sv_undef)
get_private_key_string(p_rsa, passphrase_SV=&PL_sv_undef, cipher_name_SV=&PL_sv_undef)
rsaData* p_rsa;
SV* passphase_SV;
SV* passphrase_SV;
SV* cipher_name_SV;
PREINIT:
BIO* stringBIO;
char* passphase = NULL;
STRLEN passphaseLength = 0;
char* passphrase = NULL;
STRLEN passphraseLength = 0;
char* cipher_name;
const EVP_CIPHER* enc = NULL;
CODE:
if (!_is_private(p_rsa))
{
croak("Public keys cannot export private key strings");
}
if (SvPOK(cipher_name_SV) && !SvPOK(passphase_SV)) {
if (SvPOK(cipher_name_SV) && !SvPOK(passphrase_SV)) {
croak("Passphrase is required for cipher");
}
if (SvPOK(passphase_SV)) {
passphase = SvPV(passphase_SV, passphaseLength);
if (SvPOK(passphrase_SV)) {
passphrase = SvPV(passphrase_SV, passphraseLength);
if (SvPOK(cipher_name_SV)) {
cipher_name = SvPV_nolen(cipher_name_SV);
}
Expand All @@ -704,29 +704,29 @@ get_private_key_string(p_rsa, passphase_SV=&PL_sv_undef, cipher_name_SV=&PL_sv_u

CHECK_OPEN_SSL(stringBIO = BIO_new(BIO_s_mem()));
CHECK_OPEN_SSL_BIO(PEM_write_bio_PrivateKey_traditional(
stringBIO, p_rsa->rsa, enc, (unsigned char* ) passphase, passphaseLength, NULL, NULL), stringBIO);
stringBIO, p_rsa->rsa, enc, (unsigned char* ) passphrase, passphraseLength, NULL, NULL), stringBIO);
RETVAL = extractBioString(stringBIO);

OUTPUT:
RETVAL

SV*
get_private_key_pkcs8_string(p_rsa, passphase_SV=&PL_sv_undef, cipher_name_SV=&PL_sv_undef)
get_private_key_pkcs8_string(p_rsa, passphrase_SV=&PL_sv_undef, cipher_name_SV=&PL_sv_undef)
rsaData* p_rsa;
SV* passphase_SV;
SV* passphrase_SV;
SV* cipher_name_SV;
PREINIT:
BIO* stringBIO;
char* passphase = NULL;
STRLEN passphaseLength = 0;
char* passphrase = NULL;
STRLEN passphraseLength = 0;
char* cipher_name;
const EVP_CIPHER* enc = NULL;
CODE:
if (SvPOK(cipher_name_SV) && !SvPOK(passphase_SV)) {
if (SvPOK(cipher_name_SV) && !SvPOK(passphrase_SV)) {
croak("Passphrase is required for cipher");
}
if (SvPOK(passphase_SV)) {
passphase = SvPV(passphase_SV, passphaseLength);
if (SvPOK(passphrase_SV)) {
passphrase = SvPV(passphrase_SV, passphraseLength);
if (SvPOK(cipher_name_SV)) {
cipher_name = SvPV_nolen(cipher_name_SV);
}
Expand All @@ -742,10 +742,10 @@ get_private_key_pkcs8_string(p_rsa, passphase_SV=&PL_sv_undef, cipher_name_SV=&P
CHECK_OPEN_SSL(stringBIO = BIO_new(BIO_s_mem()));
#if OPENSSL_VERSION_NUMBER >= 0x30000000L
CHECK_OPEN_SSL_BIO(PEM_write_bio_PrivateKey(
stringBIO, p_rsa->rsa, enc, (unsigned char*) passphase, passphaseLength, NULL, NULL), stringBIO);
stringBIO, p_rsa->rsa, enc, (unsigned char*) passphrase, passphraseLength, NULL, NULL), stringBIO);
#else
CHECK_OPEN_SSL_BIO(_write_pkcs8_pem(
stringBIO, p_rsa->rsa, enc, (unsigned char*) passphase, passphaseLength), stringBIO);
stringBIO, p_rsa->rsa, enc, (unsigned char*) passphrase, passphraseLength), stringBIO);
#endif
RETVAL = extractBioString(stringBIO);

Expand Down
18 changes: 9 additions & 9 deletions t/format.t
Original file line number Diff line number Diff line change
Expand Up @@ -88,23 +88,23 @@ is( $public_key->get_public_key_pkcs1_string(), $PUBLIC_KEY_PKCS1_STRING, "get_p
is( $private_key->get_public_key_pkcs1_string(), $private_key->get_public_key_string(), "pkcs1 alias matches get_public_key_string on private key" );
ok( $public_key = Crypt::OpenSSL::RSA->new_public_key($private_key->get_public_key_pkcs1_string()), "new_public_key accepts output of get_public_key_pkcs1_string" );

my $passphase = '123456';
ok( $private_key = Crypt::OpenSSL::RSA->new_private_key( $ENCRYPT_PRIVATE_KEY_STRING, $passphase ), "load encrypted private key" );
my $passphrase = '123456';
ok( $private_key = Crypt::OpenSSL::RSA->new_private_key( $ENCRYPT_PRIVATE_KEY_STRING, $passphrase ), "load encrypted private key" );
is( $private_key->get_private_key_string(), $DECRYPT_PRIVATE_KEY_STRING, "encrypted key decrypts to expected private key" );
ok( $private_key = Crypt::OpenSSL::RSA->new_private_key($DECRYPT_PRIVATE_KEY_STRING), "load decrypted private key" );
ok( $private_key2 = Crypt::OpenSSL::RSA->new_private_key( $private_key->get_private_key_string($passphase), $passphase ), "re-encrypt and reload with passphrase" );
ok( $private_key2 = Crypt::OpenSSL::RSA->new_private_key( $private_key->get_private_key_string($passphrase), $passphrase ), "re-encrypt and reload with passphrase" );
is( $private_key2->get_private_key_string(), $DECRYPT_PRIVATE_KEY_STRING, "re-encrypted key round-trips" );
ok( $private_key2 = Crypt::OpenSSL::RSA->new_private_key( $private_key->get_private_key_string( $passphase, 'des3' ), $passphase ), "encrypt with des3 and reload" );
ok( $private_key2 = Crypt::OpenSSL::RSA->new_private_key( $private_key->get_private_key_string( $passphrase, 'des3' ), $passphrase ), "encrypt with des3 and reload" );
is( $private_key2->get_private_key_string(), $DECRYPT_PRIVATE_KEY_STRING, "des3-encrypted key round-trips" );
ok( $private_key2 = Crypt::OpenSSL::RSA->new_private_key( $private_key->get_private_key_string( $passphase, 'aes-128-cbc' ), $passphase ), "encrypt with aes-128-cbc and reload" );
ok( $private_key2 = Crypt::OpenSSL::RSA->new_private_key( $private_key->get_private_key_string( $passphrase, 'aes-128-cbc' ), $passphrase ), "encrypt with aes-128-cbc and reload" );
is( $private_key2->get_private_key_string(), $DECRYPT_PRIVATE_KEY_STRING, "aes-128-cbc-encrypted key round-trips" );

# --- Additional cipher algorithms ---

ok( $private_key2 = Crypt::OpenSSL::RSA->new_private_key( $private_key->get_private_key_string( $passphase, 'aes-256-cbc' ), $passphase ), "encrypt with aes-256-cbc and reload" );
ok( $private_key2 = Crypt::OpenSSL::RSA->new_private_key( $private_key->get_private_key_string( $passphrase, 'aes-256-cbc' ), $passphrase ), "encrypt with aes-256-cbc and reload" );
is( $private_key2->get_private_key_string(), $DECRYPT_PRIVATE_KEY_STRING, "aes-256-cbc-encrypted key round-trips" );

ok( $private_key2 = Crypt::OpenSSL::RSA->new_private_key( $private_key->get_private_key_string( $passphase, 'aes-192-cbc' ), $passphase ), "encrypt with aes-192-cbc and reload" );
ok( $private_key2 = Crypt::OpenSSL::RSA->new_private_key( $private_key->get_private_key_string( $passphrase, 'aes-192-cbc' ), $passphrase ), "encrypt with aes-192-cbc and reload" );
is( $private_key2->get_private_key_string(), $DECRYPT_PRIVATE_KEY_STRING, "aes-192-cbc-encrypted key round-trips" );

# --- Passphrase with special characters ---
Expand All @@ -120,7 +120,7 @@ like($@, qr/Passphrase is required for cipher/, "get_private_key_string croaks w

# --- Error: unsupported cipher name ---

eval { $private_key->get_private_key_string($passphase, 'bogus-cipher-xyz') };
eval { $private_key->get_private_key_string($passphrase, 'bogus-cipher-xyz') };
like($@, qr/Unsupported cipher/, "get_private_key_string croaks on unsupported cipher");

# --- Error: export private key from public-only key ---
Expand All @@ -132,7 +132,7 @@ like($@, qr/Public keys cannot export private key strings/,

# --- Error: wrong passphrase on re-import ---

my $encrypted_pem = $private_key->get_private_key_string($passphase, 'aes-128-cbc');
my $encrypted_pem = $private_key->get_private_key_string($passphrase, 'aes-128-cbc');
eval { Crypt::OpenSSL::RSA->new_private_key($encrypted_pem, 'wrong_passphrase') };
ok($@, "new_private_key croaks on wrong passphrase");

Expand Down
Loading