@@ -9,7 +9,7 @@ package XML::Enc;
9
9
use Carp;
10
10
use Crypt::AuthEnc::GCM 0.062;
11
11
use Crypt::Mode::CBC;
12
- use Crypt::PK::RSA;
12
+ use Crypt::PK::RSA 0.081 ;
13
13
use Crypt::PRNG qw( random_bytes ) ;
14
14
use MIME::Base64 qw/ decode_base64 encode_base64/ ;
15
15
use XML::LibXML;
@@ -107,8 +107,10 @@ sub _assert_encryption_digest {
107
107
state $ENC_DIGEST = {
108
108
' http://www.w3.org/2000/09/xmldsig#sha1' => ' SHA1' ,
109
109
' http://www.w3.org/2001/04/xmlenc#sha256' => ' SHA256' ,
110
+ ' http://www.w3.org/2001/04/xmldsig-more#sha224' => ' SHA224' ,
111
+ ' http://www.w3.org/2001/04/xmldsig-more#sha384' => ' SHA384' ,
112
+ ' http://www.w3.org/2001/04/xmlenc#sha512' => ' SHA512' ,
110
113
};
111
-
112
114
die " Unsupported encryption digest algo $algo " unless $ENC_DIGEST -> { $algo };
113
115
return $ENC_DIGEST -> { $algo };
114
116
}
@@ -196,6 +198,37 @@ Used in encryption. Optional. Default method: mgf1sha1
196
198
197
199
=back
198
200
201
+ =item B<oaep_params >
202
+
203
+ Specify the OAEPparams value to use as part of the mask generation function (MGF).
204
+ It is optional but can be specified for rsa-oaep and rsa-oaep-mgf1p EncryptionMethods.
205
+
206
+ It is base64 encoded and stored in the XML as OAEPparams.
207
+
208
+ If specified you MAY specify the oaep_label_hash that should be used. You should note
209
+ that not all implementations support an oaep_label_hash that differs from that of the
210
+ MGF specified in the xenc11:MGF element or the default MGF1 with SHA1.
211
+
212
+ The oaep_label_hash is stored in the DigestMethod child element of the EncryptionMethod.
213
+
214
+ =item B<oaep_label_hash >
215
+
216
+ Specify the Hash Algorithm to use for the rsa-oaep label as specified by oaep_params.
217
+
218
+ The default is sha1. Supported algorithms are:
219
+
220
+ =over
221
+
222
+ =item * L<sha1|http://www.w3.org/2000/09/xmldsig#sha1>
223
+
224
+ =item * L<sha224|http://www.w3.org/2001/04/xmldsig-more#sha224>
225
+
226
+ =item * L<sha256|http://www.w3.org/2001/04/xmlenc#sha256>
227
+
228
+ =item * L<sha384|http://www.w3.org/2001/04/xmldsig-more#sha384>
229
+
230
+ =item * L<sha512|http://www.w3.org/2001/04/xmlenc#sha512>
231
+
199
232
=back
200
233
201
234
=cut
@@ -225,8 +258,12 @@ sub new {
225
258
my $key_method = exists ($params -> {' key_transport' }) ? $params -> {' key_transport' } : ' rsa-oaep-mgf1p ' ;
226
259
$self -> {' key_transport' } = $self -> _setKeyEncryptionMethod($key_method );
227
260
228
- my $oaep_mgf_alg = exists ($params -> {' oaep_mgf_alg' }) ? $params -> {' oaep_mgf_alg' } : ' http://www.w3.org/2009/xmlenc11#mgf1sha1' ;
229
- $self -> {' oaep_mgf_alg' } = $self -> _setOAEPAlgorithm($oaep_mgf_alg );
261
+ if (exists $params -> {' oaep_mgf_alg' }) {
262
+ $self -> {' oaep_mgf_alg' } = $self -> _setOAEPAlgorithm($params -> {' oaep_mgf_alg' });
263
+ }
264
+ if (exists $params -> {' oaep_label_hash' } ) {
265
+ $self -> {' oaep_label_hash' } = $self -> _setOAEPDigest($params -> {' oaep_label_hash' });
266
+ }
230
267
231
268
$self -> {' oaep_params' } = exists ($params -> {' oaep_params' }) ? $params -> {' oaep_params' } : ' ' ;
232
269
@@ -576,6 +613,36 @@ sub _getOAEPAlgorithm {
576
613
return $OAEPAlgorithm -> {$method } // ' SHA1' ;
577
614
}
578
615
616
+ sub _setOAEPDigest {
617
+ my $self = shift ;
618
+ my $method = shift ;
619
+
620
+ state $OAEPDigest = {
621
+ ' sha1' => ' http://www.w3.org/2000/09/xmldsig#sha1' ,
622
+ ' sha224' => ' http://www.w3.org/2001/04/xmldsig-more#sha224' ,
623
+ ' sha256' => ' http://www.w3.org/2001/04/xmlenc#sha256' ,
624
+ ' sha384' => ' http://www.w3.org/2001/04/xmldsig-more#sha384' ,
625
+ ' sha512' => ' http://www.w3.org/2001/04/xmlenc#sha512' ,
626
+ };
627
+
628
+ return $OAEPDigest -> {$method } // $OAEPDigest -> {' sha256' };
629
+ }
630
+
631
+ sub _getParamsAlgorithm {
632
+ my $self = shift ;
633
+ my $method = shift ;
634
+
635
+ state $ParamsAlgorithm = {
636
+ ' http://www.w3.org/2000/09/xmldsig#sha1' => ' SHA1' ,
637
+ ' http://www.w3.org/2001/04/xmldsig-more#sha224' => ' SHA224' ,
638
+ ' http://www.w3.org/2001/04/xmlenc#sha256' => ' SHA256' ,
639
+ ' http://www.w3.org/2001/04/xmldsig-more#sha384' => ' SHA384' ,
640
+ ' http://www.w3.org/2001/04/xmlenc#sha512' => ' SHA512' ,
641
+ };
642
+
643
+ return $ParamsAlgorithm -> {$method } // $ParamsAlgorithm -> {' http://www.w3.org/2000/09/xmldsig#sha1' };
644
+ }
645
+
579
646
sub _setKeyEncryptionMethod {
580
647
my $self = shift ;
581
648
my $method = shift ;
@@ -681,23 +748,45 @@ sub _decrypt_key {
681
748
if ($algo eq ' http://www.w3.org/2001/04/xmlenc#rsa-oaep-mgf1p' ) {
682
749
return _decrypt(
683
750
sub {
684
- $self -> {key_obj }-> decrypt(
685
- $key , ' oaep' ,
686
- $digest_name // ' SHA1' ,
687
- $oaep // ' '
688
- );
751
+ if ($CryptX::VERSION le 0.081) {
752
+ # print "Caller: _decrypt_key rsa-oaep-mgf1p\n";
753
+ $self -> {key_obj }-> decrypt(
754
+ $key , ' oaep' ,
755
+ # $self->_getOAEPAlgorithm($mgf),
756
+ $digest_name // ' SHA1' ,
757
+ $oaep // ' ' ,
758
+ );
759
+ } else {
760
+ # print "Caller: _decrypt_key rsa-oaep-mgf1p\n";
761
+ # print "digest_name: ", $digest_name, "\n";
762
+ $self -> {key_obj }-> decrypt(
763
+ $key , ' oaep' ,
764
+ $mgf // ' SHA1' ,
765
+ $oaep // ' ' ,
766
+ $digest_name // ' SHA1' ,
767
+ );
768
+ }
689
769
}
690
770
);
691
771
}
692
772
693
773
if ($algo eq ' http://www.w3.org/2009/xmlenc11#rsa-oaep' ) {
694
774
return _decrypt(
695
775
sub {
696
- $self -> {key_obj }-> decrypt(
697
- $key , ' oaep' ,
698
- $self -> _getOAEPAlgorithm($mgf ),
699
- $oaep // ' ' ,
700
- );
776
+ if ($CryptX::VERSION le 0.081) {
777
+ $self -> {key_obj }-> decrypt(
778
+ $key , ' oaep' ,
779
+ $self -> _getOAEPAlgorithm($mgf ),
780
+ $oaep // ' ' ,
781
+ );
782
+ } else {
783
+ $self -> {key_obj }-> decrypt(
784
+ $key , ' oaep' ,
785
+ $self -> _getOAEPAlgorithm($mgf ),
786
+ $oaep // ' ' ,
787
+ $digest_name // ' ' ,
788
+ );
789
+ }
701
790
}
702
791
);
703
792
}
@@ -712,14 +801,29 @@ sub _EncryptKey {
712
801
713
802
my $rsa_pub = $self -> {cert_obj };
714
803
804
+ # FIXME: this could use some refactoring and some simplfication
715
805
if ($keymethod eq ' http://www.w3.org/2001/04/xmlenc#rsa-1_5' ) {
716
806
${$key} = $rsa_pub -> encrypt(${$key} , ' v1.5' );
717
807
}
718
808
elsif ($keymethod eq ' http://www.w3.org/2001/04/xmlenc#rsa-oaep-mgf1p' ) {
719
- ${$key} = $rsa_pub -> encrypt(${$key} , ' oaep' , ' SHA1' , $self -> {oaep_params });
809
+ if ($CryptX::VERSION le 0.081) {
810
+ ${$key} = $rsa_pub -> encrypt(${$key} , ' oaep' , ' SHA1' , $self -> {oaep_params });
811
+ } else {
812
+ my $oaep_label_hash = (defined $self -> {oaep_label_hash } && $self -> {oaep_label_hash } ne ' ' ) ?
813
+ $self -> _getParamsAlgorithm($self -> {oaep_label_hash }) : ' SHA1' ;
814
+ ${$key} = $rsa_pub -> encrypt(${$key} , ' oaep' , ' SHA1' , $self -> {oaep_params }, $oaep_label_hash );
815
+ }
720
816
}
721
817
elsif ($keymethod eq ' http://www.w3.org/2009/xmlenc11#rsa-oaep' ) {
722
- ${$key} = $rsa_pub -> encrypt(${$key} , ' oaep' , $self -> _getOAEPAlgorithm($self -> {oaep_mgf_alg }), $self -> {oaep_params });
818
+ my $mgf_hash = defined $self -> {oaep_mgf_alg } ?
819
+ $self -> _getOAEPAlgorithm($self -> {oaep_mgf_alg }) : undef ;
820
+ if ($CryptX::VERSION le 0.081) {
821
+ ${$key} = $rsa_pub -> encrypt(${$key} , ' oaep' , $mgf_hash , $self -> {oaep_params });
822
+ } else {
823
+ my $oaep_label_hash = (defined $self -> {oaep_label_hash } && $self -> {oaep_label_hash } ne ' ' ) ?
824
+ $self -> _getParamsAlgorithm($self -> {oaep_label_hash }) : $mgf_hash ;
825
+ ${$key} = $rsa_pub -> encrypt(${$key} , ' oaep' , $mgf_hash , $self -> {oaep_params }, $oaep_label_hash );
826
+ }
723
827
} else {
724
828
die " Unsupported algorithm for key encyption $keymethod }" ;
725
829
}
@@ -1030,6 +1134,20 @@ sub _create_encrypted_data_xml {
1030
1134
}
1031
1135
);
1032
1136
1137
+ if ($self -> {key_transport } eq ' http://www.w3.org/2009/xmlenc11#rsa-oaep' ||
1138
+ $self -> {key_transport } eq ' http://www.w3.org/2001/04/xmlenc#rsa-oaep-mgf1p' &&
1139
+ $self -> {oaep_label_hash }) {
1140
+ my $digestmethod = $self -> _create_node(
1141
+ $doc ,
1142
+ $dsigns ,
1143
+ $kencmethod ,
1144
+ ' dsig:DigestMethod' ,
1145
+ {
1146
+ Algorithm => $self -> {oaep_label_hash },
1147
+ }
1148
+ );
1149
+ };
1150
+
1033
1151
if ($self -> {' oaep_params' } ne ' ' ) {
1034
1152
my $oaep_params = $self -> _create_node(
1035
1153
$doc ,
@@ -1039,7 +1157,8 @@ sub _create_encrypted_data_xml {
1039
1157
);
1040
1158
};
1041
1159
1042
- if ($self -> {key_transport } eq ' http://www.w3.org/2009/xmlenc11#rsa-oaep' ) {
1160
+ if ($self -> {key_transport } eq ' http://www.w3.org/2009/xmlenc11#rsa-oaep' &&
1161
+ $self -> {oaep_mgf_alg }) {
1043
1162
my $oaepmethod = $self -> _create_node(
1044
1163
$doc ,
1045
1164
$xenc11ns ,
0 commit comments