245 lines
9.7 KiB
Perl
245 lines
9.7 KiB
Perl
|
# rebuild:
|
||
|
# rm -f src/liballinone.a && touch CryptX.xs && make && perl -Mblib t/wycheproof.t
|
||
|
|
||
|
use strict;
|
||
|
use warnings;
|
||
|
|
||
|
use Test::More;
|
||
|
|
||
|
plan skip_all => "No JSON::* module installed" unless eval { require JSON::PP } || eval { require JSON::XS } || eval { require Cpanel::JSON::XS };
|
||
|
plan tests => 1298;
|
||
|
|
||
|
use CryptX;
|
||
|
use Crypt::Misc 'read_rawfile';
|
||
|
use Crypt::Digest 'digest_data';
|
||
|
|
||
|
if (1) {
|
||
|
use Crypt::AuthEnc::GCM qw(gcm_encrypt_authenticate gcm_decrypt_verify);
|
||
|
|
||
|
my $tests = CryptX::_decode_json read_rawfile 't/wycheproof/aes_gcm_test.json';
|
||
|
for my $g (@{$tests->{testGroups}}) {
|
||
|
my $type = $g->{type};
|
||
|
for my $t (@{$g->{tests}}) {
|
||
|
my $tcId = $t->{tcId}; # 1
|
||
|
my $comment = $t->{comment}; # ""
|
||
|
my $result = $t->{result}; # "valid"
|
||
|
my $aad = pack "H*", $t->{aad}; # "6578616d706c65"
|
||
|
my $ct = pack "H*", $t->{ct}; # "5d349ead175ef6b1def6fd"
|
||
|
my $iv = pack "H*", $t->{iv}; # "752abad3e0afb5f434dc4310"
|
||
|
my $key = pack "H*", $t->{key}; # "ee8e1ed9ff2540ae8f2ba9f50bc2f27c"
|
||
|
my $msg = pack "H*", $t->{msg}; # "48656c6c6f20776f726c64"
|
||
|
my $tag = pack "H*", $t->{tag}; # "4fbcdeb7e4793f4a1d7e4faa70100af1"
|
||
|
# do the test
|
||
|
my ($ct2, $tag2) = eval { gcm_encrypt_authenticate('AES', $key, $iv, $aad, $msg) };
|
||
|
my $pt2 = eval { gcm_decrypt_verify('AES', $key, $iv, $aad, $ct, $tag) };
|
||
|
my $testname = "type=$type tcId=$tcId comment='$comment' expected-result=$result";
|
||
|
if ($result eq 'valid') {
|
||
|
is(unpack("H*", $ct2), $t->{ct}, "$testname CT-v");
|
||
|
is(unpack("H*", $tag2), $t->{tag}, "$testname TAG-v");
|
||
|
is(unpack("H*", $pt2), $t->{msg}, "$testname PT-v");
|
||
|
}
|
||
|
elsif ($result eq 'invalid') {
|
||
|
#isnt(unpack("H*", $ct2), $t->{ct}, "$testname CT-i");
|
||
|
#isnt(unpack("H*", $tag2), $t->{tag}, "$testname TAG-i");
|
||
|
is($pt2, undef, "$testname PT-i");
|
||
|
}
|
||
|
else {
|
||
|
ok(0, "UNEXPECTED result=$result");
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if (1) {
|
||
|
use Crypt::PK::RSA;
|
||
|
|
||
|
my $tests = CryptX::_decode_json read_rawfile 't/wycheproof/rsa_signature_test.json';
|
||
|
for my $g (@{$tests->{testGroups}}) {
|
||
|
my $type = $g->{type};
|
||
|
my $keyDer = pack "H*", $g->{keyDer};
|
||
|
my $keyPem = $g->{keyPem};
|
||
|
my $sha = $g->{sha};
|
||
|
$sha =~ s/-//g; # SHA-1 >> SHA1
|
||
|
ok(Crypt::PK::RSA->new( \$keyDer ), "Crypt::PK::RSA->new + DER type: $type/$sha");
|
||
|
ok(Crypt::PK::RSA->new( \$keyPem ), "Crypt::PK::RSA->new + PEM type: $type/$sha");
|
||
|
for my $t (@{$g->{tests}}) {
|
||
|
my $tcId = $t->{tcId};
|
||
|
my $comment = $t->{comment};
|
||
|
my $result = $t->{result};
|
||
|
my $message = pack "H*", $t->{message};
|
||
|
my $sig = pack "H*", $t->{sig};
|
||
|
# do the test
|
||
|
my $testname = "type=$type/$sha tcId=$tcId comment='$comment' expected-result=$result";
|
||
|
my $pk = Crypt::PK::RSA->new( \$keyPem );
|
||
|
my $valid = $pk->verify_message($sig, $message, $sha,"v1.5");
|
||
|
if ($result eq 'valid' || $result eq 'acceptable') {
|
||
|
ok($valid, $testname);
|
||
|
}
|
||
|
elsif ($result eq 'invalid') {
|
||
|
ok(!$valid, $testname);
|
||
|
}
|
||
|
else {
|
||
|
ok(0, "UNEXPECTED result=$result");
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if (1) {
|
||
|
use Crypt::PK::DSA;
|
||
|
|
||
|
my $tests = CryptX::_decode_json read_rawfile 't/wycheproof/dsa_test.json';
|
||
|
for my $g (@{$tests->{testGroups}}) {
|
||
|
my $type = $g->{type}; # "DSAVer"
|
||
|
my $keyDer = pack "H*", $g->{keyDer};
|
||
|
my $keyPem = $g->{keyPem};
|
||
|
my $sha = $g->{sha}; # "SHA-1"
|
||
|
$sha =~ s/-//g; # SHA-1 >> SHA1
|
||
|
ok(Crypt::PK::DSA->new( \$keyDer ), "Crypt::PK::DSA->new + DER type=$type/$sha");
|
||
|
ok(Crypt::PK::DSA->new( \$keyPem ), "Crypt::PK::DSA->new + PEM type=$type/$sha");
|
||
|
for my $t (@{$g->{tests}}) {
|
||
|
my $tcId = $t->{tcId};
|
||
|
my $comment = $t->{comment};
|
||
|
my $result = $t->{result};
|
||
|
my $message = pack "H*", $t->{message};
|
||
|
my $sig = pack "H*", $t->{sig};
|
||
|
# skip unsupported tests:
|
||
|
next if $tcId==12 && $result eq 'acceptable' && $comment eq "Legacy:ASN encoding of s misses leading 0";
|
||
|
next if $tcId==13 && $result eq 'acceptable' && $comment eq "BER:long form encoding of length";
|
||
|
next if $tcId==14 && $result eq 'acceptable' && $comment eq "BER:long form encoding of length";
|
||
|
next if $tcId==15 && $result eq 'acceptable' && $comment eq "BER:long form encoding of length";
|
||
|
next if $tcId==16 && $result eq 'acceptable' && $comment eq "BER:length contains leading 0";
|
||
|
next if $tcId==17 && $result eq 'acceptable' && $comment eq "BER:length contains leading 0";
|
||
|
next if $tcId==18 && $result eq 'acceptable' && $comment eq "BER:length contains leading 0";
|
||
|
next if $tcId==19 && $result eq 'acceptable' && $comment eq "BER:indefinite length";
|
||
|
next if $tcId==20 && $result eq 'acceptable' && $comment eq "BER:prepending 0's to integer";
|
||
|
next if $tcId==21 && $result eq 'acceptable' && $comment eq "BER:prepending 0's to integer";
|
||
|
# do the test
|
||
|
my $testname = "type=$type/$sha tcId=$tcId comment='$comment' expected-result=$result";
|
||
|
my $pk = Crypt::PK::DSA->new( \$keyPem );
|
||
|
my $hash = digest_data($sha, $message);
|
||
|
my $valid_h = $pk->verify_hash($sig, $hash);
|
||
|
my $valid = $pk->verify_message($sig, $message, $sha);
|
||
|
if ($result eq 'valid' || $result eq 'acceptable') {
|
||
|
ok($valid, $testname);
|
||
|
}
|
||
|
elsif ($result eq 'invalid') {
|
||
|
ok(!$valid, $testname);
|
||
|
}
|
||
|
else {
|
||
|
ok(0, "UNEXPECTED result=$result");
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if (1) {
|
||
|
use Crypt::PK::ECC;
|
||
|
|
||
|
my $tests = CryptX::_decode_json read_rawfile 't/wycheproof/ecdsa_test.json';
|
||
|
for my $g (@{$tests->{testGroups}}) {
|
||
|
my $type = $g->{type};
|
||
|
my $keyDer = pack "H*", $g->{keyDer};
|
||
|
my $keyPem = $g->{keyPem};
|
||
|
my $sha = $g->{sha};
|
||
|
$sha =~ s/-//g; # SHA-1 >> SHA1
|
||
|
ok(Crypt::PK::ECC->new( \$keyDer ), "Crypt::PK::ECC->new + DER type=$type/$sha");
|
||
|
ok(Crypt::PK::ECC->new( \$keyPem ), "Crypt::PK::ECC->new + PEM type=$type/$sha");
|
||
|
for my $t (@{$g->{tests}}) {
|
||
|
my $tcId = $t->{tcId};
|
||
|
my $comment = $t->{comment};
|
||
|
my $result = $t->{result};
|
||
|
my $message = pack "H*", $t->{message};
|
||
|
my $sig = pack "H*", $t->{sig};
|
||
|
# skip unsupported tests:
|
||
|
next if $tcId==9 && $result eq 'acceptable' && $comment eq "BER:long form encoding of length";
|
||
|
next if $tcId==10 && $result eq 'acceptable' && $comment eq "BER:long form encoding of length";
|
||
|
next if $tcId==12 && $result eq 'acceptable' && $comment eq "BER:length contains leading 0";
|
||
|
next if $tcId==13 && $result eq 'acceptable' && $comment eq "BER:length contains leading 0";
|
||
|
next if $tcId==14 && $result eq 'acceptable' && $comment eq "BER:indefinite length";
|
||
|
next if $tcId==15 && $result eq 'acceptable' && $comment eq "BER:prepending 0's to integer";
|
||
|
next if $tcId==16 && $result eq 'acceptable' && $comment eq "BER:prepending 0's to integer";
|
||
|
# do the test
|
||
|
my $testname = "type=$type/$sha tcId=$tcId comment='$comment' expected-result=$result";
|
||
|
my $pk = Crypt::PK::ECC->new( \$keyPem );
|
||
|
my $valid = $pk->verify_message($sig, $message, $sha);
|
||
|
if ($result eq 'valid' || $result eq 'acceptable') {
|
||
|
ok($valid, "$testname verify_message=$valid");
|
||
|
}
|
||
|
elsif ($result eq 'invalid') {
|
||
|
ok(!$valid, "$testname verify_message=$valid");
|
||
|
}
|
||
|
else {
|
||
|
ok(0, "UNEXPECTED result=$result");
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if (1) {
|
||
|
use Crypt::PK::ECC;
|
||
|
|
||
|
my $tests = CryptX::_decode_json read_rawfile 't/wycheproof/ecdsa_webcrypto_test.json';
|
||
|
for my $g (@{$tests->{testGroups}}) {
|
||
|
my $type = $g->{type};
|
||
|
my $keyDer = pack "H*", $g->{keyDer};
|
||
|
my $keyPem = $g->{keyPem};
|
||
|
my $sha = $g->{sha};
|
||
|
my $jwk = $g->{jwk};
|
||
|
$sha =~ s/-//g; # SHA-1 >> SHA1
|
||
|
ok(Crypt::PK::ECC->new( \$keyDer ), "Crypt::PK::ECC->new + DER type=$type/$sha");
|
||
|
ok(Crypt::PK::ECC->new( \$keyPem ), "Crypt::PK::ECC->new + PEM type=$type/$sha");
|
||
|
ok(Crypt::PK::ECC->new( $jwk ), "Crypt::PK::ECC->new + JWK type=$type/$sha");
|
||
|
for my $t (@{$g->{tests}}) {
|
||
|
my $tcId = $t->{tcId};
|
||
|
my $comment = $t->{comment};
|
||
|
my $result = $t->{result};
|
||
|
my $message = pack "H*", $t->{message};
|
||
|
my $sig = pack "H*", $t->{sig};
|
||
|
# do the test
|
||
|
my $testname = "type=$type/$sha tcId=$tcId comment='$comment' expected-result=$result";
|
||
|
my $pk = Crypt::PK::ECC->new( \$keyPem );
|
||
|
my $valid = $pk->verify_message_rfc7518($sig, $message, $sha);
|
||
|
if ($result eq 'valid' || $result eq 'acceptable') {
|
||
|
ok($valid, "$testname verify_message=$valid");
|
||
|
}
|
||
|
elsif ($result eq 'invalid') {
|
||
|
ok(!$valid, "$testname verify_message=$valid");
|
||
|
}
|
||
|
else {
|
||
|
ok(0, "UNEXPECTED result=$result");
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if (1) {
|
||
|
use Crypt::PK::ECC;
|
||
|
|
||
|
my $tests = CryptX::_decode_json read_rawfile 't/wycheproof/ecdh_webcrypto_test.json';
|
||
|
for my $g (@{$tests->{testGroups}}) {
|
||
|
my $type = $g->{type};
|
||
|
for my $t (@{$g->{tests}}) {
|
||
|
my $tcId = $t->{tcId};
|
||
|
my $comment = $t->{comment};
|
||
|
my $name = $t->{name};
|
||
|
my $result = $t->{result};
|
||
|
my $shared = pack "H*", $t->{shared};
|
||
|
# do the test
|
||
|
my $testname = "type=$type/$name tcId=$tcId comment='$comment' expected-result=$result";
|
||
|
my $pub = Crypt::PK::ECC->new( $t->{public} );
|
||
|
my $pri = Crypt::PK::ECC->new( $t->{private} );
|
||
|
my $shared_hex = unpack "H*", $pri->shared_secret($pub);
|
||
|
if ($result eq 'valid' || $result eq 'acceptable') {
|
||
|
is($shared_hex, $t->{shared}, $testname);
|
||
|
}
|
||
|
elsif ($result eq 'invalid') {
|
||
|
isnt($shared_hex, $t->{shared}, $testname);
|
||
|
}
|
||
|
else {
|
||
|
ok(0, "UNEXPECTED result=$result");
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|