use strict; use Test; use Crypt::OpenSSL::Random; use Crypt::OpenSSL::RSA; BEGIN { plan tests => 19 } sub _Test_Sign_And_Verify { my( $plaintext, $rsa, $rsa_pub ) = @_; my $sig = $rsa->sign($plaintext); ok( $rsa_pub->verify( $plaintext, $sig ) ); my $false_sig = unpack "H*", $sig; $false_sig =~ tr/[a-f]/[0a-d]/; ok(! $rsa_pub->verify( $plaintext, pack( "H*", $false_sig ) ) ); } # On platforms without a /dev/random, we need to manually seed. In # real life, the following would stink, but for testing purposes, it # suffices to seed with any old thing, even if it is not actually # random. We'll at least emulate seeding from Crypt::OpenSSL::Random, # which is what we would have to do in "real life", since the private # data used by the OpenSSL random library apparently does not span # across perl XS modules. Crypt::OpenSSL::Random::random_seed("Here are 20 bytes..."); Crypt::OpenSSL::RSA->import_random_seed(); ok( Crypt::OpenSSL::RSA->generate_key( 512 )->size() * 8 == 512 ); my $rsa = Crypt::OpenSSL::RSA->generate_key( 1024 ); ok( $rsa->size() * 8 == 1024 ); ok( $rsa->check_key() ); # check if NO_PADDING works $rsa->use_no_padding(); my ($ciphertext, $decoded_text); my $plaintext = "X" x $rsa->size; ok($ciphertext = $rsa->encrypt($plaintext)); ok($decoded_text = $rsa->decrypt($ciphertext)); ok ($decoded_text eq $plaintext); # check if OAEP_PADDING works my $plaintext_length = $rsa->size() - 42; $plaintext = pack("C$plaintext_length", (255,0,128,4, # Make sure these characters work map {int(rand 256)} (1..$plaintext_length-4))); $rsa->use_pkcs1_oaep_padding(); ok($ciphertext = $rsa->encrypt($plaintext)); ok($decoded_text = $rsa->decrypt($ciphertext)); ok ($decoded_text eq $plaintext); my $private_key_string = $rsa->get_private_key_string(); my $public_key_string = $rsa->get_public_key_string(); ok( $private_key_string and $public_key_string ); my $rsa_priv = Crypt::OpenSSL::RSA->new_private_key($private_key_string); $decoded_text = $rsa_priv->decrypt($ciphertext); ok( $decoded_text eq $plaintext ); my $rsa_pub = Crypt::OpenSSL::RSA->new_public_key( $public_key_string ); $ciphertext = $rsa_pub->encrypt($plaintext); $decoded_text = $rsa->decrypt($ciphertext); ok ($decoded_text eq $plaintext); $plaintext .= $plaintext x 5; # check signature algorithms $rsa->use_md5_hash(); $rsa_pub->use_md5_hash(); _Test_Sign_And_Verify( $plaintext, $rsa, $rsa_pub ); $rsa->use_sha1_hash(); $rsa_pub->use_sha1_hash(); _Test_Sign_And_Verify( $plaintext, $rsa, $rsa_pub ); $rsa->use_ripemd160_hash(); $rsa_pub->use_ripemd160_hash(); _Test_Sign_And_Verify( $plaintext, $rsa, $rsa_pub ); # check subclassing eval { Crypt::OpenSSL::RSA::Subpackage->generate_key( 256 ); }; ok( !$@ ); package Crypt::OpenSSL::RSA::Subpackage; use base qw( Crypt::OpenSSL::RSA );