@@ -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,41 @@ 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 {' 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 } :
486+ $methods {' http://www.w3.org/2000/09/xmldsig#sha1' };
487+ }
488+
412489sub _getKeyEncryptionMethod {
413490 my $self = shift ;
414491 my $xpc = shift ;
@@ -422,19 +499,45 @@ sub _getKeyEncryptionMethod {
422499 $id =~ s / #// g ;
423500
424501 my $keyinfo = $xpc -> find(' //*[@Id=\' ' . $id . ' \' ]' , $context );
502+ $keyinfo -> [0]-> setNamespace(' http://www.w3.org/2000/09/xmldsig#' , ' dsig' , 0);
503+ $keyinfo -> [0]-> setNamespace(' http://www.w3.org/2001/04/xmlenc#' , ' xenc' , 0);
504+ $keyinfo -> [0]-> setNamespace(' http://www.w3.org/2009/xmlenc11#' , ' xenc11' , 0);
425505 if (! $keyinfo ) {
426506 die " Unable to find EncryptedKey" ;
427507 }
428508 $method {Algorithm } = $keyinfo -> [0]-> findvalue(' //xenc:EncryptedKey/xenc:EncryptionMethod/@Algorithm' , $context );
429509 $method {KeySize } = $keyinfo -> [0]-> findvalue(' //xenc:EncryptedKey/xenc:EncryptionMethod/xenc:KeySize' , $context );
430510 $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 );
511+
512+ if ($method {Algorithm } eq ' http://www.w3.org/2009/xmlenc11#rsa-oaep' ) {
513+ $method {MGF } = $keyinfo -> [0]-> findvalue(
514+ ' //xenc:EncryptedKey/xenc:EncryptionMethod/xmlenc11:MGF/@Algorithm'
515+ , $context );
516+ }
517+ if ($method {Algorithm } eq ' http://www.w3.org/2001/04/xmlenc#rsa-oaep-mgf1p' ) {
518+ $method {MGF } = undef ;
519+ }
520+
521+ $method {oaep_label_hash } = $keyinfo -> [0]-> findvalue(
522+ ' xenc:EncryptedKey/xenc:EncryptionMethod/dsig:DigestMethod/@Algorithm' ,
523+ $context ) || _setOAEPDigest(' sha1' );
432524 return \%method ;
433525 }
434526 $method {Algorithm } = $xpc -> findvalue(' dsig:KeyInfo/xenc:EncryptedKey/xenc:EncryptionMethod/@Algorithm' , $context );
435527 $method {KeySize } = $xpc -> findvalue(' dsig:KeyInfo/xenc:EncryptedKey/xenc:EncryptionMethod/xenc:KeySize' , $context );
436528 $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 );
529+ if ($method {Algorithm } eq ' http://www.w3.org/2009/xmlenc11#rsa-oaep' ) {
530+ $method {MGF } = $xpc -> findvalue(
531+ ' dsig:KeyInfo/xenc:EncryptedKey/xenc:EncryptionMethod/xenc11:MGF/@Algorithm' ,
532+ $context );
533+ }
534+ if ($method {Algorithm } eq ' http://www.w3.org/2001/04/xmlenc#rsa-oaep-mgf1p' ) {
535+ $method {MGF } = undef ;
536+ }
537+ $method {oaep_label_hash } = $xpc -> findvalue(
538+ ' dsig:KeyInfo/xenc:EncryptedKey/xenc:EncryptionMethod/dsig:DigestMethod/@Algorithm' ,
539+ $context ) || _setOAEPDigest(' sha1' );
540+
438541 return \%method ;
439542}
440543
@@ -534,10 +637,30 @@ sub _DecryptKey {
534637 return $self -> {key_obj }-> decrypt($encryptedkey , ' v1.5' );
535638 }
536639 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 }));
640+ my $oaep_params = defined $keymethod -> {OAEPparams } ?
641+ decode_base64(_trim($keymethod -> {OAEPparams }) ) : undef ;
642+ my $oaep_label_hash = defined $keymethod -> {oaep_label_hash } ?
643+ $self -> _getParamsAlgorithm($keymethod -> {oaep_label_hash }) : ' SHA1' ;
644+
645+ if ($CryptX::VERSION le 0.077) {
646+ return $self -> {key_obj }-> decrypt($encryptedkey , ' oaep' , ' SHA1' , $oaep_params );
647+ } else {
648+ return $self -> {key_obj }-> decrypt($encryptedkey , ' oaep' , ' SHA1' , $oaep_params , $oaep_label_hash );
649+ }
538650 }
539651 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 }));
652+ my $oaep_params = defined $keymethod -> {OAEPparams } ?
653+ decode_base64(_trim($keymethod -> {OAEPparams }) ) : undef ;
654+ my $mgf_hash = defined $keymethod -> {MGF } ? $self -> _getOAEPAlgorithm($keymethod -> {MGF }) : undef ;
655+ my $oaep_label_hash = defined $keymethod -> {oaep_label_hash } ?
656+ $self -> _getParamsAlgorithm($keymethod -> {oaep_label_hash }) :
657+ $mgf_hash ;
658+
659+ if ($CryptX::VERSION le 0.077) {
660+ return $self -> {key_obj }-> decrypt($encryptedkey , ' oaep' , $mgf_hash , $oaep_params );
661+ } else {
662+ return $self -> {key_obj }-> decrypt($encryptedkey , ' oaep' , $mgf_hash , $oaep_params , $oaep_label_hash );
663+ }
541664 } else {
542665 die " Unsupported Key Encryption Method" ;
543666 }
@@ -557,10 +680,24 @@ sub _EncryptKey {
557680 ${$key} = $rsa_pub -> encrypt(${$key} , ' v1.5' );
558681 }
559682 elsif ($keymethod eq ' http://www.w3.org/2001/04/xmlenc#rsa-oaep-mgf1p' ) {
560- ${$key} = $rsa_pub -> encrypt(${$key} , ' oaep' , ' SHA1' , $self -> {oaep_params });
683+ my $oaep_label_hash = (defined $self -> {oaep_label_hash } && $self -> {oaep_label_hash } ne ' ' ) ?
684+ $self -> _getParamsAlgorithm($self -> {oaep_label_hash }) : ' SHA1' ;
685+ if ($CryptX::VERSION le 0.077) {
686+ ${$key} = $rsa_pub -> encrypt(${$key} , ' oaep' , ' SHA1' , $self -> {oaep_params });
687+ } else {
688+ ${$key} = $rsa_pub -> encrypt(${$key} , ' oaep' , ' SHA1' , $self -> {oaep_params }, $oaep_label_hash );
689+ }
561690 }
562691 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 });
692+ my $mgf_hash = defined $self -> {oaep_mgf_alg } ?
693+ $self -> _getOAEPAlgorithm($self -> {oaep_mgf_alg }) : undef ;
694+ my $oaep_label_hash = (defined $self -> {oaep_label_hash } && $self -> {oaep_label_hash } ne ' ' ) ?
695+ $self -> _getParamsAlgorithm($self -> {oaep_label_hash }) : $mgf_hash ;
696+ if ($CryptX::VERSION le 0.077) {
697+ ${$key} = $rsa_pub -> encrypt(${$key} , ' oaep' , $mgf_hash , $self -> {oaep_params });
698+ } else {
699+ ${$key} = $rsa_pub -> encrypt(${$key} , ' oaep' , $mgf_hash , $self -> {oaep_params }, $oaep_label_hash );
700+ }
564701 } else {
565702 die " Unsupported Key Encryption Method" ;
566703 }
@@ -861,6 +998,7 @@ sub _create_encrypted_data_xml {
861998 my $doc = XML::LibXML::Document-> new();
862999
8631000 my $xencns = ' http://www.w3.org/2001/04/xmlenc#' ;
1001+ my $xenc11ns = ' http://www.w3.org/2009/xmlenc11#' ;
8641002 my $dsigns = ' http://www.w3.org/2000/09/xmldsig#' ;
8651003
8661004 my $encdata = $self -> _create_node($doc , $xencns , $doc , ' xenc:EncryptedData' ,
@@ -914,12 +1052,27 @@ sub _create_encrypted_data_xml {
9141052 );
9151053 };
9161054
917- if ($self -> {key_transport } eq ' http://www.w3.org/2009/xmlenc11#rsa-oaep' ) {
1055+ if ($self -> {key_transport } eq ' http://www.w3.org/2009/xmlenc11#rsa-oaep' ||
1056+ $self -> {key_transport } eq ' http://www.w3.org/2001/04/xmlenc#rsa-oaep-mgf1p' &&
1057+ $self -> {oaep_label_hash }) {
1058+ my $digestmethod = $self -> _create_node(
1059+ $doc ,
1060+ $dsigns ,
1061+ $kencmethod ,
1062+ ' dsig:DigestMethod' ,
1063+ {
1064+ Algorithm => $self -> {oaep_label_hash },
1065+ }
1066+ );
1067+ };
1068+
1069+ if ($self -> {key_transport } eq ' http://www.w3.org/2009/xmlenc11#rsa-oaep' &&
1070+ $self -> {oaep_mgf_alg }) {
9181071 my $oaepmethod = $self -> _create_node(
9191072 $doc ,
920- $xencns ,
1073+ $xenc11ns ,
9211074 $kencmethod ,
922- ' xenc :MGF' ,
1075+ ' xenc11 :MGF' ,
9231076 {
9241077 Algorithm => $self -> {oaep_mgf_alg },
9251078 }
0 commit comments