@@ -167,6 +167,39 @@ Used in encryption. Optional. Default method: mgf1sha1
167167
168168=back
169169
170+ =item B<oaep_params >
171+
172+ Specify the OAEPparams value to use as part of the mask generation function (MGF).
173+ It is optional but can be specified for rsa-oaep and rsa-oaep-mgf1p EncryptionMethods.
174+
175+ It is base64 encoded and stored in the XML as OAEPparams.
176+
177+ If specified you MAY specify the oaep_label_hash that should be used. You should note
178+ that not all implementations support an oaep_label_hash that differs from that of the
179+ MGF specified in the xenc11:MGF element or the default MGF1 with SHA1.
180+
181+ The oaep_label_hash is stored in the DigestMethod child element of the EncryptionMethod.
182+
183+ =item B<oaep_label_hash >
184+
185+ Specify the Hash Algorithm to use for the rsa-oaep label as specified by oaep_params.
186+
187+ The default is sha1. Supported algorithms are:
188+
189+ =over
190+
191+ =item * L<sha1|http://www.w3.org/2000/09/xmldsig#sha1>
192+
193+ =item * L<sha224|http://www.w3.org/2001/04/xmldsig-more#sha224>
194+
195+ =item * L<sha256|http://www.w3.org/2001/04/xmlenc#sha256>
196+
197+ =item * L<sha384|http://www.w3.org/2001/04/xmldsig-more#sha384>
198+
199+ =item * L<sha512|http://www.w3.org/2001/04/xmlenc#sha512>
200+
201+ =back
202+
170203=back
171204
172205=cut
@@ -196,8 +229,12 @@ sub new {
196229 my $key_method = exists ($params -> {' key_transport' }) ? $params -> {' key_transport' } : ' rsa-oaep-mgf1p ' ;
197230 $self -> {' key_transport' } = $self -> _setKeyEncryptionMethod($key_method );
198231
199- my $oaep_mgf_alg = exists ($params -> {' oaep_mgf_alg' }) ? $params -> {' oaep_mgf_alg' } : ' http://www.w3.org/2009/xmlenc11#mgf1sha1' ;
200- $self -> {' oaep_mgf_alg' } = $self -> _setOAEPAlgorithm($oaep_mgf_alg );
232+ if (exists $params -> {' oaep_mgf_alg' }) {
233+ $self -> {' oaep_mgf_alg' } = $self -> _setOAEPAlgorithm($params -> {' oaep_mgf_alg' });
234+ }
235+ if (exists $params -> {' oaep_label_hash' } ) {
236+ $self -> {' oaep_label_hash' } = $self -> _setOAEPDigest($params -> {' oaep_label_hash' });
237+ }
201238
202239 $self -> {' oaep_params' } = exists ($params -> {' oaep_params' }) ? $params -> {' oaep_params' } : ' ' ;
203240
@@ -233,6 +270,7 @@ sub decrypt {
233270 my $xpc = XML::LibXML::XPathContext-> new($doc );
234271 $xpc -> registerNs(' dsig' , ' http://www.w3.org/2000/09/xmldsig#' );
235272 $xpc -> registerNs(' xenc' , ' http://www.w3.org/2001/04/xmlenc#' );
273+ $xpc -> registerNs(' xenc11' , ' http://www.w3.org/2009/xmlenc11#' );
236274 $xpc -> registerNs(' saml' , ' urn:oasis:names:tc:SAML:2.0:assertion' );
237275
238276 my $data ;
@@ -383,6 +421,8 @@ sub _setOAEPAlgorithm {
383421 my $self = shift ;
384422 my $method = shift ;
385423
424+ return if ! defined $method ;
425+
386426 my %methods = (
387427 ' mgf1sha1' => ' http://www.w3.org/2009/xmlenc11#mgf1sha1' ,
388428 ' mgf1sha224' => ' http://www.w3.org/2009/xmlenc11#mgf1sha224' ,
@@ -398,6 +438,8 @@ sub _getOAEPAlgorithm {
398438 my $self = shift ;
399439 my $method = shift ;
400440
441+ return if ! defined $method ;
442+
401443 my %methods = (
402444 ' http://www.w3.org/2009/xmlenc11#mgf1sha1' => ' SHA1' ,
403445 ' http://www.w3.org/2009/xmlenc11#mgf1sha224' => ' SHA224' ,
@@ -409,6 +451,40 @@ sub _getOAEPAlgorithm {
409451 return exists ($methods {$method }) ? $methods {$method } : $methods {' http://www.w3.org/2009/xmlenc11#mgf1sha1' };
410452}
411453
454+ sub _setOAEPDigest {
455+ my $self = shift ;
456+ my $method = shift ;
457+
458+ return if ! defined $method ;
459+
460+ my %methods = (
461+ ' sha1' => ' http://www.w3.org/2000/09/xmldsig#sha1' ,
462+ ' sha224' => ' http://www.w3.org/2001/04/xmldsig-more#sha224' ,
463+ ' sha256' => ' http://www.w3.org/2001/04/xmlenc#sha256' ,
464+ ' sha384' => ' http://www.w3.org/2001/04/xmldsig-more#sha384' ,
465+ ' sha512' => ' http://www.w3.org/2001/04/xmlenc#sha512' ,
466+ );
467+
468+ return exists ($methods {$method }) ? $methods {$method } : $methods {' http://www.w3.org/2001/04/xmlenc#sha256' };
469+ }
470+
471+ sub _getParamsAlgorithm {
472+ my $self = shift ;
473+ my $method = shift ;
474+
475+ return if ! defined $method ;
476+
477+ my %methods = (
478+ ' http://www.w3.org/2000/09/xmldsig#sha1' => ' SHA1' ,
479+ ' http://www.w3.org/2001/04/xmldsig-more#sha224' => ' SHA224' ,
480+ ' http://www.w3.org/2001/04/xmlenc#sha256' => ' SHA256' ,
481+ ' http://www.w3.org/2001/04/xmldsig-more#sha384' => ' SHA384' ,
482+ ' http://www.w3.org/2001/04/xmlenc#sha512' => ' SHA512' ,
483+ );
484+
485+ return exists ($methods {$method }) ? $methods {$method } : $methods {' http://www.w3.org/2009/xmlenc11#mgf1sha1' };
486+ }
487+
412488sub _getKeyEncryptionMethod {
413489 my $self = shift ;
414490 my $xpc = shift ;
@@ -422,19 +498,45 @@ sub _getKeyEncryptionMethod {
422498 $id =~ s / #// g ;
423499
424500 my $keyinfo = $xpc -> find(' //*[@Id=\' ' . $id . ' \' ]' , $context );
501+ $keyinfo -> [0]-> setNamespace(' http://www.w3.org/2000/09/xmldsig#' , ' dsig' , 0);
502+ $keyinfo -> [0]-> setNamespace(' http://www.w3.org/2001/04/xmlenc#' , ' xenc' , 0);
503+ $keyinfo -> [0]-> setNamespace(' http://www.w3.org/2009/xmlenc11#' , ' xenc11' , 0);
425504 if (! $keyinfo ) {
426505 die " Unable to find EncryptedKey" ;
427506 }
428507 $method {Algorithm } = $keyinfo -> [0]-> findvalue(' //xenc:EncryptedKey/xenc:EncryptionMethod/@Algorithm' , $context );
429508 $method {KeySize } = $keyinfo -> [0]-> findvalue(' //xenc:EncryptedKey/xenc:EncryptionMethod/xenc:KeySize' , $context );
430509 $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 );
510+
511+ if ($method {Algorithm } eq ' http://www.w3.org/2009/xmlenc11#rsa-oaep' ) {
512+ $method {MGF } = $keyinfo -> [0]-> findvalue(
513+ ' //xenc:EncryptedKey/xenc:EncryptionMethod/xmlenc11:MGF/@Algorithm'
514+ , $context );
515+ }
516+ if ($method {Algorithm } eq ' http://www.w3.org/2001/04/xmlenc#rsa-oaep-mgf1p' ) {
517+ $method {MGF } = undef ;
518+ }
519+
520+ $method {oaep_label_hash } = $keyinfo -> [0]-> findvalue(
521+ ' xenc:EncryptedKey/xenc:EncryptionMethod/dsig:DigestMethod/@Algorithm' ,
522+ $context ) || _setOAEPDigest(' sha1' );
432523 return \%method ;
433524 }
434525 $method {Algorithm } = $xpc -> findvalue(' dsig:KeyInfo/xenc:EncryptedKey/xenc:EncryptionMethod/@Algorithm' , $context );
435526 $method {KeySize } = $xpc -> findvalue(' dsig:KeyInfo/xenc:EncryptedKey/xenc:EncryptionMethod/xenc:KeySize' , $context );
436527 $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 );
528+ if ($method {Algorithm } eq ' http://www.w3.org/2009/xmlenc11#rsa-oaep' ) {
529+ $method {MGF } = $xpc -> findvalue(
530+ ' dsig:KeyInfo/xenc:EncryptedKey/xenc:EncryptionMethod/xenc11:MGF/@Algorithm' ,
531+ $context );
532+ }
533+ if ($method {Algorithm } eq ' http://www.w3.org/2001/04/xmlenc#rsa-oaep-mgf1p' ) {
534+ $method {MGF } = undef ;
535+ }
536+ $method {oaep_label_hash } = $xpc -> findvalue(
537+ ' dsig:KeyInfo/xenc:EncryptedKey/xenc:EncryptionMethod/dsig:DigestMethod/@Algorithm' ,
538+ $context ) || _setOAEPDigest(' sha1' );
539+
438540 return \%method ;
439541}
440542
@@ -534,10 +636,30 @@ sub _DecryptKey {
534636 return $self -> {key_obj }-> decrypt($encryptedkey , ' v1.5' );
535637 }
536638 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 }));
639+ my $oaep_params = defined $keymethod -> {OAEPparams } ?
640+ decode_base64(_trim($keymethod -> {OAEPparams }) ) : undef ;
641+ my $oaep_label_hash = defined $keymethod -> {oaep_label_hash } ?
642+ $self -> _getParamsAlgorithm($keymethod -> {oaep_label_hash }) : ' SHA1' ;
643+
644+ if ($CryptX::VERSION le 0.077) {
645+ return $self -> {key_obj }-> decrypt($encryptedkey , ' oaep' , ' SHA1' , $oaep_params );
646+ } else {
647+ return $self -> {key_obj }-> decrypt($encryptedkey , ' oaep' , ' SHA1' , $oaep_params , $oaep_label_hash );
648+ }
538649 }
539650 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 }));
651+ my $oaep_params = defined $keymethod -> {OAEPparams } ?
652+ decode_base64(_trim($keymethod -> {OAEPparams }) ) : ' ' ;
653+ my $mgf_hash = defined $keymethod -> {MGF } ? $self -> _getOAEPAlgorithm($keymethod -> {MGF }) : undef ;
654+ my $oaep_label_hash = defined $keymethod -> {oaep_label_hash } ?
655+ $self -> _getParamsAlgorithm($keymethod -> {oaep_label_hash }) :
656+ $mgf_hash ;
657+
658+ if ($CryptX::VERSION le 0.077) {
659+ return $self -> {key_obj }-> decrypt($encryptedkey , ' oaep' , $mgf_hash , $oaep_params );
660+ } else {
661+ return $self -> {key_obj }-> decrypt($encryptedkey , ' oaep' , $mgf_hash , $oaep_params , $oaep_label_hash );
662+ }
541663 } else {
542664 die " Unsupported Key Encryption Method" ;
543665 }
@@ -557,10 +679,24 @@ sub _EncryptKey {
557679 ${$key} = $rsa_pub -> encrypt(${$key} , ' v1.5' );
558680 }
559681 elsif ($keymethod eq ' http://www.w3.org/2001/04/xmlenc#rsa-oaep-mgf1p' ) {
560- ${$key} = $rsa_pub -> encrypt(${$key} , ' oaep' , ' SHA1' , $self -> {oaep_params });
682+ my $oaep_label_hash = (defined $self -> {oaep_label_hash } && $self -> {oaep_label_hash } ne ' ' ) ?
683+ $self -> _getParamsAlgorithm($self -> {oaep_label_hash }) : ' SHA1' ;
684+ if ($CryptX::VERSION le 0.077) {
685+ ${$key} = $rsa_pub -> encrypt(${$key} , ' oaep' , ' SHA1' , $self -> {oaep_params });
686+ } else {
687+ ${$key} = $rsa_pub -> encrypt(${$key} , ' oaep' , ' SHA1' , $self -> {oaep_params }, $oaep_label_hash );
688+ }
561689 }
562690 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 });
691+ my $mgf_hash = defined $self -> {oaep_mgf_alg } ?
692+ $self -> _getOAEPAlgorithm($self -> {oaep_mgf_alg }) : undef ;
693+ my $oaep_label_hash = (defined $self -> {oaep_label_hash } && $self -> {oaep_label_hash } ne ' ' ) ?
694+ $self -> _getParamsAlgorithm($self -> {oaep_label_hash }) : $mgf_hash ;
695+ if ($CryptX::VERSION le 0.077) {
696+ ${$key} = $rsa_pub -> encrypt(${$key} , ' oaep' , $mgf_hash , $self -> {oaep_params });
697+ } else {
698+ ${$key} = $rsa_pub -> encrypt(${$key} , ' oaep' , $mgf_hash , $self -> {oaep_params }, $oaep_label_hash );
699+ }
564700 } else {
565701 die " Unsupported Key Encryption Method" ;
566702 }
@@ -861,6 +997,7 @@ sub _create_encrypted_data_xml {
861997 my $doc = XML::LibXML::Document-> new();
862998
863999 my $xencns = ' http://www.w3.org/2001/04/xmlenc#' ;
1000+ my $xenc11ns = ' http://www.w3.org/2009/xmlenc11#' ;
8641001 my $dsigns = ' http://www.w3.org/2000/09/xmldsig#' ;
8651002
8661003 my $encdata = $self -> _create_node($doc , $xencns , $doc , ' xenc:EncryptedData' ,
@@ -914,12 +1051,27 @@ sub _create_encrypted_data_xml {
9141051 );
9151052 };
9161053
917- if ($self -> {key_transport } eq ' http://www.w3.org/2009/xmlenc11#rsa-oaep' ) {
1054+ if ($self -> {key_transport } eq ' http://www.w3.org/2009/xmlenc11#rsa-oaep' ||
1055+ $self -> {key_transport } eq ' http://www.w3.org/2001/04/xmlenc#rsa-oaep-mgf1p' &&
1056+ $self -> {oaep_label_hash }) {
1057+ my $digestmethod = $self -> _create_node(
1058+ $doc ,
1059+ $dsigns ,
1060+ $kencmethod ,
1061+ ' dsig:DigestMethod' ,
1062+ {
1063+ Algorithm => $self -> {oaep_label_hash },
1064+ }
1065+ );
1066+ };
1067+
1068+ if ($self -> {key_transport } eq ' http://www.w3.org/2009/xmlenc11#rsa-oaep' &&
1069+ $self -> {oaep_mgf_alg }) {
9181070 my $oaepmethod = $self -> _create_node(
9191071 $doc ,
920- $xencns ,
1072+ $xenc11ns ,
9211073 $kencmethod ,
922- ' xenc :MGF' ,
1074+ ' xenc11 :MGF' ,
9231075 {
9241076 Algorithm => $self -> {oaep_mgf_alg },
9251077 }
0 commit comments