@@ -199,6 +199,9 @@ sub new {
199199 my $oaep_mgf_alg = exists ($params -> {' oaep_mgf_alg' }) ? $params -> {' oaep_mgf_alg' } : ' http://www.w3.org/2009/xmlenc11#mgf1sha1' ;
200200 $self -> {' oaep_mgf_alg' } = $self -> _setOAEPAlgorithm($oaep_mgf_alg );
201201
202+ my $oaep_digest = exists ($params -> {' oaep_digest' }) ? $params -> {' oaep_digest' } : $oaep_mgf_alg ;
203+ $self -> {' oaep_digest' } = $self -> _setOAEPDigest($oaep_digest );
204+
202205 $self -> {' oaep_params' } = exists ($params -> {' oaep_params' }) ? $params -> {' oaep_params' } : ' ' ;
203206
204207 return $self ;
@@ -233,6 +236,7 @@ sub decrypt {
233236 my $xpc = XML::LibXML::XPathContext-> new($doc );
234237 $xpc -> registerNs(' dsig' , ' http://www.w3.org/2000/09/xmldsig#' );
235238 $xpc -> registerNs(' xenc' , ' http://www.w3.org/2001/04/xmlenc#' );
239+ $xpc -> registerNs(' xenc11' , ' http://www.w3.org/2009/xmlenc11#' );
236240 $xpc -> registerNs(' saml' , ' urn:oasis:names:tc:SAML:2.0:assertion' );
237241
238242 my $data ;
@@ -383,6 +387,8 @@ sub _setOAEPAlgorithm {
383387 my $self = shift ;
384388 my $method = shift ;
385389
390+ return if ! defined $method ;
391+
386392 my %methods = (
387393 ' mgf1sha1' => ' http://www.w3.org/2009/xmlenc11#mgf1sha1' ,
388394 ' mgf1sha224' => ' http://www.w3.org/2009/xmlenc11#mgf1sha224' ,
@@ -409,6 +415,43 @@ sub _getOAEPAlgorithm {
409415 return exists ($methods {$method }) ? $methods {$method } : $methods {' http://www.w3.org/2009/xmlenc11#mgf1sha1' };
410416}
411417
418+ sub _setOAEPDigest {
419+ my $self = shift ;
420+ my $method = shift ;
421+
422+ return if ! defined $method ;
423+
424+ my %methods = (
425+ ' sha1' => ' http://www.w3.org/2000/09/xmldsig#sha1' ,
426+ ' sha224' => ' http://www.w3.org/2001/04/xmldsig-more#sha224' ,
427+ ' sha256' => ' http://www.w3.org/2001/04/xmlenc#sha256' ,
428+ ' sha384' => ' http://www.w3.org/2001/04/xmldsig-more#sha384' ,
429+ ' sha512' => ' http://www.w3.org/2001/04/xmlenc#sha512' ,
430+ ' mgf1sha1' => ' http://www.w3.org/2000/09/xmldsig#sha1' ,
431+ ' mgf1sha224' => ' http://www.w3.org/2001/04/xmldsig-more#sha224' ,
432+ ' mgf1sha256' => ' http://www.w3.org/2001/04/xmlenc#sha256' ,
433+ ' mgf1sha384' => ' http://www.w3.org/2001/04/xmldsig-more#sha384' ,
434+ ' mgf1sha512' => ' http://www.w3.org/2001/04/xmlenc#sha512' ,
435+ );
436+
437+ return exists ($methods {$method }) ? $methods {$method } : $methods {' http://www.w3.org/2001/04/xmlenc#sha256' };
438+ }
439+
440+ sub _getParamsAlgorithm {
441+ my $self = shift ;
442+ my $method = shift ;
443+
444+ my %methods = (
445+ ' http://www.w3.org/2000/09/xmldsig#sha1' => ' SHA1' ,
446+ ' http://www.w3.org/2001/04/xmldsig-more#sha224' => ' SHA224' ,
447+ ' http://www.w3.org/2001/04/xmlenc#sha256' => ' SHA256' ,
448+ ' http://www.w3.org/2001/04/xmldsig-more#sha384' => ' SHA384' ,
449+ ' http://www.w3.org/2001/04/xmlenc#sha512' => ' SHA512' ,
450+ );
451+
452+ return exists ($methods {$method }) ? $methods {$method } : $methods {' http://www.w3.org/2009/xmlenc11#mgf1sha1' };
453+ }
454+
412455sub _getKeyEncryptionMethod {
413456 my $self = shift ;
414457 my $xpc = shift ;
@@ -422,19 +465,54 @@ sub _getKeyEncryptionMethod {
422465 $id =~ s / #// g ;
423466
424467 my $keyinfo = $xpc -> find(' //*[@Id=\' ' . $id . ' \' ]' , $context );
468+ $keyinfo -> [0]-> setNamespace(' http://www.w3.org/2000/09/xmldsig#' , ' dsig' , 0);
469+ $keyinfo -> [0]-> setNamespace(' http://www.w3.org/2001/04/xmlenc#' , ' xenc' , 0);
470+ $keyinfo -> [0]-> setNamespace(' http://www.w3.org/2009/xmlenc11#' , ' xenc11' , 0);
425471 if (! $keyinfo ) {
426472 die " Unable to find EncryptedKey" ;
427473 }
428- $method {Algorithm } = $keyinfo -> [0]-> findvalue(' //xenc:EncryptedKey/xenc:EncryptionMethod/@Algorithm' , $context );
429- $method {KeySize } = $keyinfo -> [0]-> findvalue(' //xenc:EncryptedKey/xenc:EncryptionMethod/xenc:KeySize' , $context );
430- $method {OAEPparams } = $keyinfo -> [0]-> findvalue(' //xenc:EncryptedKey/xenc:EncryptionMethod/xenc:OAEPparams' , $context );
431- $method {MGF } = $keyinfo -> [0]-> findvalue(' //xenc:EncryptedKey/xenc:EncryptionMethod/xenc:MGF/@Algorithm' , $context );
474+ $method {Algorithm } = $keyinfo -> [0]-> findvalue(
475+ ' //xenc:EncryptedKey/xenc:EncryptionMethod/@Algorithm' ,
476+ $context );
477+ $method {KeySize } = $keyinfo -> [0]-> findvalue(
478+ ' //xenc:EncryptedKey/xenc:EncryptionMethod/xenc:KeySize' ,
479+ $context );
480+ $method {OAEPparams } = $keyinfo -> [0]-> findvalue('
481+ //xenc:EncryptedKey/xenc:EncryptionMethod/xenc:OAEPparams' ,
482+ $context );
483+
484+ if ($method {Algorithm } eq ' http://www.w3.org/2009/xmlenc11#rsa-oaep' ) {
485+ $method {MGF } = $keyinfo -> [0]-> findvalue(
486+ ' //xenc:EncryptedKey/xenc:EncryptionMethod/xmlenc11:MGF/@Algorithm'
487+ , $context );
488+ }
489+ if ($method {Algorithm } eq ' http://www.w3.org/2001/04/xmlenc#rsa-oaep-mgf1p' ) {
490+ $method {MGF } = undef ;
491+ }
492+
493+ $method {oaep_digest } = $keyinfo -> [0]-> findvalue(
494+ ' xenc:EncryptedKey/xenc:EncryptionMethod/dsig:DigestMethod/@Algorithm' ,
495+ $context ) || ' http://www.w3.org/2000/09/xmldsig#sha1' ;
432496 return \%method ;
433497 }
434- $method {Algorithm } = $xpc -> findvalue(' dsig:KeyInfo/xenc:EncryptedKey/xenc:EncryptionMethod/@Algorithm' , $context );
435- $method {KeySize } = $xpc -> findvalue(' dsig:KeyInfo/xenc:EncryptedKey/xenc:EncryptionMethod/xenc:KeySize' , $context );
436- $method {OAEPparams } = $xpc -> findvalue(' dsig:KeyInfo/xenc:EncryptedKey/xenc:EncryptionMethod/xenc:OAEPparams' , $context );
437- $method {MGF } = $xpc -> findvalue(' dsig:KeyInfo/xenc:EncryptedKey/xenc:EncryptionMethod/xenc:MGF/@Algorithm' , $context );
498+ $method {Algorithm } = $xpc -> findvalue(
499+ ' dsig:KeyInfo/xenc:EncryptedKey/xenc:EncryptionMethod/@Algorithm' ,
500+ $context );
501+ $method {KeySize } = $xpc -> findvalue(
502+ ' dsig:KeyInfo/xenc:EncryptedKey/xenc:EncryptionMethod/xenc:KeySize' ,
503+ $context );
504+ $method {OAEPparams } = $xpc -> findvalue(
505+ ' dsig:KeyInfo/xenc:EncryptedKey/xenc:EncryptionMethod/xenc:OAEPparams' ,
506+ $context );
507+ if ($method {Algorithm } eq ' http://www.w3.org/2009/xmlenc11#rsa-oaep' ) {
508+ $method {MGF } = $xpc -> findvalue(
509+ ' dsig:KeyInfo/xenc:EncryptedKey/xenc:EncryptionMethod/xenc11:MGF/@Algorithm' ,
510+ $context );
511+ }
512+ if ($method {Algorithm } eq ' http://www.w3.org/2001/04/xmlenc#rsa-oaep-mgf1p' ) {
513+ $method {MGF } = undef ;
514+ }
515+ $method {oaep_digest } = $xpc -> findvalue(' dsig:KeyInfo/xenc:EncryptedKey/xenc:EncryptionMethod/dsig:DigestMethod/@Algorithm' , $context ) || ' http://www.w3.org/2000/09/xmldsig#sha1' ;
438516 return \%method ;
439517}
440518
@@ -534,10 +612,20 @@ sub _DecryptKey {
534612 return $self -> {key_obj }-> decrypt($encryptedkey , ' v1.5' );
535613 }
536614 elsif ($keymethod -> {Algorithm } eq ' http://www.w3.org/2001/04/xmlenc#rsa-oaep-mgf1p' ) {
537- return $self -> {key_obj }-> decrypt($encryptedkey , ' oaep' , ' SHA1' , decode_base64($keymethod -> {OAEPparams }));
615+ my $oaep_params = defined $keymethod -> {OAEPparams } ?
616+ decode_base64(_trim($keymethod -> {OAEPparams }) ) : undef ;
617+ my $params_hash = defined $keymethod -> {oaep_digest } ?
618+ $self -> _getParamsAlgorithm($keymethod -> {oaep_digest }) : ' SHA1' ;
619+
620+ return $self -> {key_obj }-> decrypt($encryptedkey , ' oaep' , ' SHA1' , $params_hash , $oaep_params );
538621 }
539622 elsif ($keymethod -> {Algorithm } eq ' http://www.w3.org/2009/xmlenc11#rsa-oaep' ) {
540- return $self -> {key_obj }-> decrypt($encryptedkey , ' oaep' , $self -> _getOAEPAlgorithm($keymethod -> {MGF }), decode_base64($keymethod -> {OAEPparams }));
623+ my $oaep_params = defined $keymethod -> {OAEPparams } ?
624+ decode_base64(_trim($keymethod -> {OAEPparams }) ) : ' ' ;
625+ my $mgf_hash = defined $keymethod -> {MGF } ? $self -> _getOAEPAlgorithm($keymethod -> {MGF }) : undef ;
626+ my $params_hash = defined $keymethod -> {oaep_digest } ? $self -> _getParamsAlgorithm($keymethod -> {oaep_digest }) : $mgf_hash ;
627+
628+ return $self -> {key_obj }-> decrypt($encryptedkey , ' oaep' , $mgf_hash , $params_hash , $oaep_params );
541629 } else {
542630 die " Unsupported Key Encryption Method" ;
543631 }
@@ -557,10 +645,12 @@ sub _EncryptKey {
557645 ${$key} = $rsa_pub -> encrypt(${$key} , ' v1.5' );
558646 }
559647 elsif ($keymethod eq ' http://www.w3.org/2001/04/xmlenc#rsa-oaep-mgf1p' ) {
560- ${$key} = $rsa_pub -> encrypt(${$key} , ' oaep' , ' SHA1' , $self -> {oaep_params });
648+ ${$key} = $rsa_pub -> encrypt(${$key} , ' oaep' , ' SHA1' , ' SHA1 ' , $self -> {oaep_params });
561649 }
562650 elsif ($keymethod eq ' http://www.w3.org/2009/xmlenc11#rsa-oaep' ) {
563- ${$key} = $rsa_pub -> encrypt(${$key} , ' oaep' , $self -> _getOAEPAlgorithm($self -> {oaep_mgf_alg }), $self -> {oaep_params });
651+ my $mgf_hash = defined $self -> {oaep_mgf_alg } ? $self -> _getOAEPAlgorithm($self -> {oaep_mgf_alg }) : undef ;
652+ my $params_hash = defined $self -> {oaep_digest } & $self -> {oaep_digest } ne ' ' ? $self -> _getParamsAlgorithm($self -> {oaep_digest }) : $mgf_hash ;
653+ ${$key} = $rsa_pub -> encrypt(${$key} , ' oaep' , $mgf_hash , $params_hash , $self -> {oaep_params });
564654 } else {
565655 die " Unsupported Key Encryption Method" ;
566656 }
@@ -861,6 +951,7 @@ sub _create_encrypted_data_xml {
861951 my $doc = XML::LibXML::Document-> new();
862952
863953 my $xencns = ' http://www.w3.org/2001/04/xmlenc#' ;
954+ my $xenc11ns = ' http://www.w3.org/2009/xmlenc11#' ;
864955 my $dsigns = ' http://www.w3.org/2000/09/xmldsig#' ;
865956
866957 my $encdata = $self -> _create_node($doc , $xencns , $doc , ' xenc:EncryptedData' ,
@@ -914,12 +1005,24 @@ sub _create_encrypted_data_xml {
9141005 );
9151006 };
9161007
1008+ if ($self -> {key_transport } eq ' http://www.w3.org/2009/xmlenc11#rsa-oaep' ) {
1009+ my $digestmethod = $self -> _create_node(
1010+ $doc ,
1011+ $dsigns ,
1012+ $kencmethod ,
1013+ ' dsig:DigestMethod' ,
1014+ {
1015+ Algorithm => $self -> {oaep_digest },
1016+ }
1017+ );
1018+ };
1019+
9171020 if ($self -> {key_transport } eq ' http://www.w3.org/2009/xmlenc11#rsa-oaep' ) {
9181021 my $oaepmethod = $self -> _create_node(
9191022 $doc ,
920- $xencns ,
1023+ $xenc11ns ,
9211024 $kencmethod ,
922- ' xenc :MGF' ,
1025+ ' xenc11 :MGF' ,
9231026 {
9241027 Algorithm => $self -> {oaep_mgf_alg },
9251028 }
0 commit comments