@@ -8,7 +8,7 @@ package XML::Enc;
88
99use Carp;
1010use XML::LibXML;
11- use Crypt::OpenSSL ::RSA;
11+ use Crypt::PK ::RSA;
1212use Crypt::Mode::CBC;
1313use Crypt::AuthEnc::GCM 0.062;
1414use MIME::Base64 qw/ decode_base64 encode_base64/ ;
@@ -143,6 +143,8 @@ Used in encryption. Optional. Default method: rsa-1_5
143143
144144=item * L<rsa-oaep-mgf1p|https://www.w3.org/TR/2002/REC-xmlenc-core-20021210/Overview.html#rsa-oaep-mgf1p>
145145
146+ =item * L<rsa-oaep (Experimental)| http://www.w3.org/2009/xmlenc11#rsa-oaep>
147+
146148=back
147149
148150=back
@@ -174,6 +176,9 @@ sub new {
174176 my $key_method = exists ($params -> {' key_transport' }) ? $params -> {' key_transport' } : ' rsa-oaep-mgf1p ' ;
175177 $self -> {' key_transport' } = $self -> _setKeyEncryptionMethod($key_method );
176178
179+ my $oaep_method = exists ($params -> {' oaep_method' }) ? $params -> {' oaep_method' } : ' http://www.w3.org/2009/xmlenc11#mgf1sha1' ;
180+ $self -> {' oaep_method' } = $self -> _setOAEPAlgorithm($oaep_method );
181+
177182 return $self ;
178183}
179184
@@ -334,6 +339,36 @@ sub _setEncryptionMethod {
334339 return exists ($methods {$method }) ? $methods {$method } : $methods {' aes256-cbc' };
335340}
336341
342+ sub _setOAEPAlgorithm {
343+ my $self = shift ;
344+ my $method = shift ;
345+
346+ my %methods = (
347+ ' mgf1sha1' => ' http://www.w3.org/2009/xmlenc11#mgf1sha1' ,
348+ ' mgf1sha224' => ' http://www.w3.org/2009/xmlenc11#mgf1sha224' ,
349+ ' mgf1sha256' => ' http://www.w3.org/2009/xmlenc11#mgf1sha256' ,
350+ ' mgf1sha384' => ' http://www.w3.org/2009/xmlenc11#mgf1sha384' ,
351+ ' mgf1sha512' => ' http://www.w3.org/2009/xmlenc11#mgf1sha512' ,
352+ );
353+
354+ return exists ($methods {$method }) ? $methods {$method } : $methods {' mgf1sha1' };
355+ }
356+
357+ sub _getOAEPAlgorithm {
358+ my $self = shift ;
359+ my $method = shift ;
360+
361+ my %methods = (
362+ ' http://www.w3.org/2009/xmlenc11#mgf1sha1' => ' SHA1' ,
363+ ' http://www.w3.org/2009/xmlenc11#mgf1sha224' => ' SHA224' ,
364+ ' http://www.w3.org/2009/xmlenc11#mgf1sha256' => ' SHA256' ,
365+ ' http://www.w3.org/2009/xmlenc11#mgf1sha384' => ' SHA384' ,
366+ ' http://www.w3.org/2009/xmlenc11#mgf1sha512' => ' SHA512' ,
367+ );
368+
369+ return exists ($methods {$method }) ? $methods {$method } : $methods {' http://www.w3.org/2009/xmlenc11#mgf1sha1' };
370+ }
371+
337372sub _getKeyEncryptionMethod {
338373 my $self = shift ;
339374 my $xpc = shift ;
@@ -353,11 +388,13 @@ sub _getKeyEncryptionMethod {
353388 $method {Algorithm } = $keyinfo -> [0]-> findvalue(' //xenc:EncryptedKey/xenc:EncryptionMethod/@Algorithm' , $context );
354389 $method {KeySize } = $keyinfo -> [0]-> findvalue(' //xenc:EncryptedKey/xenc:EncryptionMethod/xenc:KeySize' , $context );
355390 $method {OAEPparams } = $keyinfo -> [0]-> findvalue(' //xenc:EncryptedKey/xenc:EncryptionMethod/xenc:OAEPparams' , $context );
391+ $method {MGF } = $keyinfo -> [0]-> findvalue(' //xenc:EncryptedKey/xenc:EncryptionMethod/xenc:MGF/@Algorithm' , $context );
356392 return \%method ;
357393 }
358394 $method {Algorithm } = $xpc -> findvalue(' dsig:KeyInfo/xenc:EncryptedKey/xenc:EncryptionMethod/@Algorithm' , $context );
359395 $method {KeySize } = $xpc -> findvalue(' dsig:KeyInfo/xenc:EncryptedKey/xenc:EncryptionMethod/xenc:KeySize' , $context );
360396 $method {OAEPparams } = $xpc -> findvalue(' dsig:KeyInfo/xenc:EncryptedKey/xenc:EncryptionMethod/xenc:OAEPparams' , $context );
397+ $method {MGF } = $xpc -> findvalue(' dsig:KeyInfo/xenc:EncryptedKey/xenc:EncryptionMethod/xenc:MGF/@Algorithm' , $context );
361398 return \%method ;
362399}
363400
@@ -368,6 +405,7 @@ sub _setKeyEncryptionMethod {
368405 my %methods = (
369406 ' rsa-1_5' => ' http://www.w3.org/2001/04/xmlenc#rsa-1_5' ,
370407 ' rsa-oaep-mgf1p' => ' http://www.w3.org/2001/04/xmlenc#rsa-oaep-mgf1p' ,
408+ ' rsa-oaep' => ' http://www.w3.org/2009/xmlenc11#rsa-oaep' ,
371409 );
372410
373411 return exists ($methods {$method }) ? $methods {$method } : $methods {' rsa-oaep-mgf1p' };
@@ -453,10 +491,13 @@ sub _DecryptKey {
453491 my $encryptedkey = shift ;
454492
455493 if ($keymethod -> {Algorithm } eq ' http://www.w3.org/2001/04/xmlenc#rsa-1_5' ) {
456- $self -> {key_obj }-> use_pkcs1_padding ;
494+ return $self -> {key_obj }-> decrypt( $encryptedkey , ' v1.5 ' ) ;
457495 }
458496 elsif ($keymethod -> {Algorithm } eq ' http://www.w3.org/2001/04/xmlenc#rsa-oaep-mgf1p' ) {
459- $self -> {key_obj }-> use_pkcs1_oaep_padding;
497+ return $self -> {key_obj }-> decrypt($encryptedkey , ' oaep' , ' SHA1' , decode_base64($keymethod -> {OAEPparams }));
498+ }
499+ elsif ($keymethod -> {Algorithm } eq ' http://www.w3.org/2009/xmlenc11#rsa-oaep' ) {
500+ return $self -> {key_obj }-> decrypt($encryptedkey , ' oaep' , $self -> _getOAEPAlgorithm($keymethod -> {MGF }), decode_base64($keymethod -> {OAEPparams }));
460501 } else {
461502 die " Unsupported Key Encryption Method" ;
462503 }
@@ -470,18 +511,21 @@ sub _EncryptKey {
470511 my $keymethod = shift ;
471512 my $key = shift ;
472513
473- my $rsa_pub = Crypt::OpenSSL::RSA-> new_public_key($self -> {cert_obj }-> pubkey);
514+ my $rsa_pub = $self -> {cert_obj };
515+
474516 if ($keymethod eq ' http://www.w3.org/2001/04/xmlenc#rsa-1_5' ) {
475- $rsa_pub -> use_pkcs1_padding ;
517+ ${$key} = $ rsa_pub-> encrypt( ${$key} , ' v1.5 ' ) ;
476518 }
477519 elsif ($keymethod eq ' http://www.w3.org/2001/04/xmlenc#rsa-oaep-mgf1p' ) {
478- $rsa_pub -> use_pkcs1_oaep_padding;
520+ ${$key} = $rsa_pub -> encrypt(${$key} , ' oaep' , ' SHA1' );
521+ }
522+ elsif ($keymethod eq ' http://www.w3.org/2009/xmlenc11#rsa-oaep' ) {
523+ ${$key} = $rsa_pub -> encrypt(${$key} , ' oaep' , $self -> _getOAEPAlgorithm($self -> {oaep_method }));
479524 } else {
480525 die " Unsupported Key Encryption Method" ;
481526 }
482527
483528 print " Encrypted key: " , encode_base64(${$key} ) if $DEBUG ;
484- ${$key} = $rsa_pub -> encrypt(${$key} );
485529}
486530
487531sub _getEncryptedData {
@@ -662,37 +706,31 @@ sub _load_rsa_key {
662706 my ($key_text ) = @_ ;
663707
664708 eval {
665- require Crypt::OpenSSL ::RSA;
709+ require Crypt::PK ::RSA;
666710 };
667- confess " Crypt::OpenSSL ::RSA needs to be installed so that we can handle RSA keys." if $@ ;
711+ confess " Crypt::PK ::RSA needs to be installed so that we can handle RSA keys." if $@ ;
668712
669- my $rsaKey = Crypt::OpenSSL ::RSA-> new_private_key( $key_text );
713+ my $rsaKey = Crypt::PK ::RSA-> new(\ $key_text );
670714
671715 if ( $rsaKey ) {
672- $rsaKey -> use_pkcs1_padding();
673716 $self -> { key_obj } = $rsaKey ;
674717 $self -> { key_type } = ' rsa' ;
675718
676719 if (!$self -> { x509 }) {
677- my $bigNum = ( $rsaKey -> get_key_parameters() )[1];
678- my $bin = $bigNum -> to_bin();
679- my $exp = encode_base64( $bin , ' ' );
720+ my $keyhash = $rsaKey -> key2hash();
680721
681- $bigNum = ( $rsaKey -> get_key_parameters() )[0];
682- $bin = $bigNum -> to_bin();
683- my $mod = encode_base64( $bin , ' ' );
684722 $self -> {KeyInfo } = " <dsig:KeyInfo>
685723 <dsig:KeyValue>
686724 <dsig:RSAKeyValue>
687- <dsig:Modulus>$mod </dsig:Modulus>
688- <dsig:Exponent>$exp </dsig:Exponent>
725+ <dsig:Modulus>$keyhash ->{N} </dsig:Modulus>
726+ <dsig:Exponent>$keyhash ->{d} </dsig:Exponent>
689727 </dsig:RSAKeyValue>
690728 </dsig:KeyValue>
691729 </dsig:KeyInfo>" ;
692730 }
693731 }
694732 else {
695- confess " did not get a new Crypt::OpenSSL ::RSA object" ;
733+ confess " did not get a new Crypt::PK ::RSA object" ;
696734 }
697735}
698736
@@ -758,10 +796,10 @@ sub _load_cert_file {
758796 $text = <$CERT >;
759797 close $CERT ;
760798
761- my $cert = Crypt::OpenSSL::X509 -> new_from_string( $text );
799+ my $cert = Crypt::PK::RSA -> new(\ $text );
762800 if ( $cert ) {
763801 $self -> { cert_obj } = $cert ;
764- my $cert_text = $cert -> as_string ;
802+ my $cert_text = $cert -> export_key_pem( ' public_x509 ' ) ;
765803 $cert_text =~ s / -----[^-]*-----// gm ;
766804 $self -> {KeyInfo } = " <dsig:KeyInfo><dsig:X509Data><dsig:X509Certificate>\n " ._trim($cert_text )." \n </dsig:X509Certificate></dsig:X509Data></dsig:KeyInfo>" ;
767805 }
@@ -827,6 +865,18 @@ sub _create_encrypted_data_xml {
827865 }
828866 );
829867
868+ if ($self -> {key_transport } eq ' http://www.w3.org/2009/xmlenc11#rsa-oaep' ) {
869+ my $oaepmethod = $self -> _create_node(
870+ $doc ,
871+ $xencns ,
872+ $kencmethod ,
873+ ' xenc:MGF' ,
874+ {
875+ Algorithm => $self -> {oaep_method },
876+ }
877+ );
878+ };
879+
830880 my $keyinfo2 = $self -> _create_node(
831881 $doc ,
832882 $dsigns ,
0 commit comments