diff --git a/README b/README index 706cf92..47ac887 100644 --- a/README +++ b/README @@ -134,6 +134,10 @@ METHODS * sha512 + key_name + Specify a key name to add to the KeyName element. If it is not + specified then no KeyName element is added to the KeyInfo + decrypt( ... ) Main decryption function. diff --git a/lib/XML/Enc.pm b/lib/XML/Enc.pm index 4aebe33..d5616a5 100644 --- a/lib/XML/Enc.pm +++ b/lib/XML/Enc.pm @@ -231,6 +231,13 @@ The default is sha1. Supported algorithms are: =back +=item B + +Specify a key name to add to the KeyName element. If it is not specified then no +KeyName element is added to the KeyInfo + +=back + =cut sub new { @@ -267,6 +274,8 @@ sub new { $self->{'oaep_params'} = exists($params->{'oaep_params'}) ? $params->{'oaep_params'} : ''; + $self->{'key_name'} = $params->{'key_name'} if exists($params->{'key_name'}); + return $self; } @@ -539,6 +548,11 @@ sub encrypt { my $base64_key = encode_base64($key); my $base64_data = encode_base64($encrypteddata); + # Insert KeyName into the XML + if (defined $self->{key_name} and $self->{key_name} ne '') { + $encrypted = $self->_setKeyName($encrypted, $xpc, $self->{key_name}); + } + # Insert OAEPparams into the XML if ($self->{oaep_params} ne '') { $encrypted = $self->_setOAEPparams($encrypted, $xpc, encode_base64($self->{oaep_params})); @@ -570,6 +584,19 @@ sub _setEncryptionMethod { return exists($methods{$method}) ? $methods{$method} : $methods{'aes256-cbc'}; } +sub _setKeyName { + my $self = shift; + my $context = shift; + my $xpc = shift; + my $keyname = shift; + + my $node = $xpc->findnodes('//xenc:EncryptedKey/dsig:KeyInfo/dsig:KeyName', $context); + + $node->[0]->removeChildNodes(); + $node->[0]->appendText(defined $keyname ? $keyname : 'key_name'); + return $context; +} + sub _setOAEPparams { my $self = shift; my $context = shift; @@ -1177,12 +1204,14 @@ sub _create_encrypted_data_xml { 'dsig:KeyInfo', ); - my $keyname = $self->_create_node( + if (defined $self->{key_name}) { + my $keyname = $self->_create_node( $doc, $dsigns, $keyinfo2, 'dsig:KeyName', ); + }; my $keycipherdata = $self->_create_node( $doc, diff --git a/t/06-test-encryption-methods.t b/t/06-test-encryption-methods.t index 2dd3b48..017aff3 100644 --- a/t/06-test-encryption-methods.t +++ b/t/06-test-encryption-methods.t @@ -13,6 +13,7 @@ my $xml = <<'XML'; XML +my $key_name = 'mykey'; my @key_methods = qw/rsa-1_5 rsa-oaep-mgf1p/; my @data_methods = qw/aes128-cbc aes192-cbc aes256-cbc tripledes-cbc aes128-gcm aes192-gcm aes256-gcm/; my @oaep_mgf_algs = qw/rsa-oaep-mgf1p mgf1sha1 mgf1sha224 mgf1sha256 mgf1sha384 mgf1sha512/; @@ -28,6 +29,7 @@ foreach my $km (@key_methods) { { key => 't/sign-private.pem', cert => 't/sign-certonly.pem', + key_name => $key_name, data_enc_method => $dm, key_transport => $km, no_xml_declaration => 1 @@ -42,17 +44,16 @@ foreach my $km (@key_methods) { SKIP: { skip "xmlsec1 not installed", 2 unless $xmlsec->{installed}; skip "xmlsec version 1.2.27 minimum for GCM", 2 if ! $xmlsec->{aes_gcm}; - ok( open XML, '>', 'tmp.xml' ); + ok( open XML, '>', "enc-xml-$km-$dm.xml" ); print XML $encrypted; close XML; - my $verify_response = `xmlsec1 --decrypt $lax_key_search --privkey-pem t/sign-private.pem tmp.xml 2>&1`; + my $verify_response = `xmlsec1 --decrypt $lax_key_search --privkey-pem:$key_name t/sign-private.pem,t/sign-certonly.pem enc-xml-$km-$dm.xml 2>&1`; like($verify_response, qr/XML-SIG_1/, "Successfully decrypted with xmlsec1" ) or warn "calling xmlsec1 failed: '$verify_response'\n"; - unlink 'tmp.xml'; + unlink "enc-xml-$km-$dm.xml"; } } } - foreach my $om (@oaep_mgf_algs) { foreach my $omdig (@oaep_label_hashes) { SKIP: { @@ -67,6 +68,7 @@ foreach my $om (@oaep_mgf_algs) { { key => 't/sign-private.pem', cert => 't/sign-certonly.pem', + key_name => $key_name, data_enc_method => $dm, key_transport => $km, oaep_mgf_alg => $om, @@ -82,13 +84,14 @@ foreach my $om (@oaep_mgf_algs) { SKIP: { skip "xmlsec1 not installed", 2 unless $xmlsec->{installed}; skip "xmlsec version 1.2.27 minimum for GCM", 2 if ! $xmlsec->{aes_gcm}; - ok( open XML, '>', "$km-$om-$omdig-$dm-tmp.xml" ); + skip "xmlsec version 1.3.00 minimum for rsa-oeap", 2 if ! $xmlsec->{rsa_oaep}; + ok( open XML, '>', "enc-xml-$km-$om-$omdig-$dm.xml" ); print XML $encrypted; close XML; - my $verify_response = `xmlsec1 --decrypt $lax_key_search --privkey-pem t/sign-private.pem $km-$om-$omdig-$dm-tmp.xml 2>&1`; + my $verify_response = `xmlsec1 --decrypt $lax_key_search --privkey-pem:$key_name t/sign-private.pem,t/sign-certonly.pem enc-xml-$km-$om-$omdig-$dm.xml 2>&1`; ok( $verify_response =~ m/XML-SIG_1/, "Successfully decrypted with xmlsec1" ) or warn "calling xmlsec1 failed: '$verify_response'\n"; - unlink "$km-$om-$omdig-$dm-tmp.xml"; + unlink "enc-xml-$km-$om-$omdig-$dm.xml"; } ok($encrypter->decrypt($encrypted) =~ /XML-SIG_1/, "Successfully Decrypted with XML::Enc"); } diff --git a/t/lib/Test/XML/Enc/Util.pm b/t/lib/Test/XML/Enc/Util.pm index bdb1c31..e3d478a 100644 --- a/t/lib/Test/XML/Enc/Util.pm +++ b/t/lib/Test/XML/Enc/Util.pm @@ -54,6 +54,7 @@ sub get_xmlsec_features { ripemd160 => ($major >= 1 and $minor >= 3) ? 1 : 0, aes_gcm => ($major <= 1 and $minor <= 2 and $patch <= 27) ? 0 : 1, lax_key_search => ($major >= 1 and $minor >= 3) ? 1 : 0, + rsa_oaep => ($major >= 1 and $minor >= 3) ? 1 : 0, ); return \%xmlsec; }