Skip Menu |

This queue is for tickets about the URL-Encode CPAN distribution.

Report information
The Basics
Id: 106539
Status: rejected
Priority: 0/
Queue: URL-Encode

People
Owner: Nobody in particular
Requestors: jleu [...] mindspring.com
Cc:
AdminCc:

Bug Information
Severity: Normal
Broken in: 0.03
Fixed in: (no value)



Subject: URL::Encode is not utf8 binary 'clean'
Encoding binary data via url_encode_utf8 and then decoding via url_decode_utf8 does not yield identical data (very subtly different) I will concede this is a non-typical usage of URL::Encode but I thought you would appreciate the knowledge that there is some subtle issue with url_encode_utf8/url_decode_utf8 The script I attached has 3 test: test 1: - creates a binary string using Crypt::OpenSSL::RSA to encrypt a string. - use hex_encode/hex_decode - decrypt string: success test 2: - use original binary string - use url_encode_utf8 / url_decode_utf8 - decrypt string: failure test 3: - use decoded string from test 2 - encode decode again, but using hex_encode / hex_decode - decrypt string: success
Subject: gen.pl
#!/usr/bin/env perl use strict; use Crypt::OpenSSL::RSA; use URL::Encode qw(:all); my $rsa = Crypt::OpenSSL::RSA->generate_key(1024); my $private_string = $rsa->get_private_key_string(); my $public_string = $rsa->get_public_key_x509_string(); my $rsa_priv = Crypt::OpenSSL::RSA->new_private_key($private_string); my $rsa_pub = Crypt::OpenSSL::RSA->new_public_key($public_string); $rsa_priv->use_pkcs1_padding(); $rsa_pub->use_pkcs1_padding(); my $plaintext0 = 'a' x 117; my $encrypted = $rsa_pub->encrypt($plaintext0); my $encoded1 = hex_encode($encrypted); my $decoded1 = hex_decode($encoded1); if ($encrypted ne $decoded1) { die "Encode1/decode1 failed\n"; } my $plaintext1; eval { $plaintext1 = $rsa_priv->decrypt($decoded1); }; if ($plaintext0 eq $plaintext1) { print "\nEncrypted,encoded1/decoded1,decryped correctly\n\n"; } else { print "\nEncrypted,encoded1/decoded1,decryped failed\n\n"; } my $encoded2 = url_encode_utf8($encrypted); my $decoded2 = url_decode_utf8($encoded2); if ($encrypted ne $decoded2) { die "Encode2/decode2 failed\n"; } my $plaintext2; eval { $plaintext2 = $rsa_priv->decrypt($decoded2); }; if ($plaintext0 eq $plaintext2) { print "\nEncrypted,encoded2/decoded2,decryped correctly\n\n"; } else { print "\nEncrypted,encoded2/decoded2,decryped failed\n\n"; } my $encoded3 = hex_encode($decoded2); my $decoded3 = hex_decode($encoded3); my $plaintext3; eval { $plaintext3 = $rsa_priv->decrypt($decoded3); }; if ($plaintext0 eq $plaintext3) { print "\nEncrypted,encoded3/decoded3,decryped correctly\n\n"; } else { print "\nEncrypted,encoded3/decoded3,decryped failed\n\n"; } sub hex_encode { my $input = shift; my @bytes; foreach my $i (0 .. (length($input) - 1)) { my $byte = sprintf('%02x', ord(substr($input, $i, 1))); push(@bytes, $byte); } my $output = join(qw{}, @bytes); return $output; } sub hex_decode { my $input = shift; my @hex = ($input =~ /(..)/g); my @dec = map({ hex($_) } @hex); my @bytes = map({ pack('C', $_) } @dec); my $output = join(q{},@bytes); return $output; }
On 2015-08-19 13:48:50, jleu@mindspring.com wrote: Show quoted text
> Encoding binary data via url_encode_utf8 and then decoding via > url_decode_utf8 does not yield identical data (very subtly different) > > I will concede this is a non-typical usage of URL::Encode > but I thought you would appreciate the knowledge that there is > some subtle issue with url_encode_utf8/url_decode_utf8 > > > The script I attached has 3 test: > > test 1: > - creates a binary string using Crypt::OpenSSL::RSA to encrypt a > string. > - use hex_encode/hex_decode > - decrypt string: success > > test 2: > - use original binary string > - use url_encode_utf8 / url_decode_utf8 > - decrypt string: failure > > test 3: > - use decoded string from test 2 > - encode decode again, but using hex_encode / hex_decode > - decrypt string: success
The problem is not in URL::Encode, but in Crypt::OpenSSL::RSA. The latter behaves differently if the encrypted data has the utf8 flag set, but it should not. Usually perl code should do the same regardless if a variable has the utf8 flag set or not, and the following test script should pass (but it does not): #!/usr/bin/perl use strict; use Crypt::OpenSSL::RSA; use Test::More; my $rsa = Crypt::OpenSSL::RSA->generate_key(1024); my $private_string = $rsa->get_private_key_string(); my $public_string = $rsa->get_public_key_x509_string(); my $rsa_priv = Crypt::OpenSSL::RSA->new_private_key($private_string); my $rsa_pub = Crypt::OpenSSL::RSA->new_public_key($public_string); $rsa_priv->use_pkcs1_padding(); $rsa_pub->use_pkcs1_padding(); my $plaintext0 = 'a' x 117; my $encrypted_noutf8flag = $rsa_pub->encrypt($plaintext0); my $encrypted_utf8flag = $encrypted_noutf8flag; utf8::upgrade $encrypted_utf8flag; is $encrypted_utf8flag, $encrypted_noutf8flag; is $rsa_priv->decrypt($encrypted_noutf8flag), $plaintext0; is $rsa_priv->decrypt($encrypted_utf8flag), $plaintext0; done_testing; __END__ You have the following options: * Don't use url_encode_utf8 and url_decode_utf8, but stick to url_encode and url-decode instead. Encrypted data can only contain octets in the range 0..255, so using utf8 here is not necessary at all. * utf8-downgrade the encrypted data, that is, do something like utf8::downgrade $encrypted before feeding the result to the decrypt method. I propose to reject this ticket.
From: jleu [...] mindspring.com
On Sat Aug 29 18:34:31 2015, SREZIC wrote: Show quoted text
> On 2015-08-19 13:48:50, jleu@mindspring.com wrote:
> > Encoding binary data via url_encode_utf8 and then decoding via > > url_decode_utf8 does not yield identical data (very subtly different) > > > > I will concede this is a non-typical usage of URL::Encode > > but I thought you would appreciate the knowledge that there is > > some subtle issue with url_encode_utf8/url_decode_utf8 > > > > > > The script I attached has 3 test: > > > > test 1: > > - creates a binary string using Crypt::OpenSSL::RSA to encrypt a > > string. > > - use hex_encode/hex_decode > > - decrypt string: success > > > > test 2: > > - use original binary string > > - use url_encode_utf8 / url_decode_utf8 > > - decrypt string: failure > > > > test 3: > > - use decoded string from test 2 > > - encode decode again, but using hex_encode / hex_decode > > - decrypt string: success
> > The problem is not in URL::Encode, but in Crypt::OpenSSL::RSA. The > latter behaves differently if the encrypted data has the utf8 flag > set, but it should not. Usually perl code should do the same > regardless if a variable has the utf8 flag set or not, and the > following test script should pass (but it does not): > > #!/usr/bin/perl > > use strict; > use Crypt::OpenSSL::RSA; > use Test::More; > > my $rsa = Crypt::OpenSSL::RSA->generate_key(1024); > my $private_string = $rsa->get_private_key_string(); > my $public_string = $rsa->get_public_key_x509_string(); > my $rsa_priv = Crypt::OpenSSL::RSA->new_private_key($private_string); > my $rsa_pub = Crypt::OpenSSL::RSA->new_public_key($public_string); > $rsa_priv->use_pkcs1_padding(); > $rsa_pub->use_pkcs1_padding(); > > my $plaintext0 = 'a' x 117; > my $encrypted_noutf8flag = $rsa_pub->encrypt($plaintext0); > my $encrypted_utf8flag = $encrypted_noutf8flag; utf8::upgrade > $encrypted_utf8flag; > > is $encrypted_utf8flag, $encrypted_noutf8flag; > > is $rsa_priv->decrypt($encrypted_noutf8flag), $plaintext0; > is $rsa_priv->decrypt($encrypted_utf8flag), $plaintext0; > > done_testing; > > __END__ > > You have the following options: > > * Don't use url_encode_utf8 and url_decode_utf8, but stick to > url_encode and url-decode instead. Encrypted data can only contain > octets in the range 0..255, so using utf8 here is not necessary at > all. > > * utf8-downgrade the encrypted data, that is, do something like > > utf8::downgrade $encrypted > > before feeding the result to the decrypt method. > > I propose to reject this ticket.
Thank you for finding the subtly I was missing. I agree, this 'bug' can be rejected and issue closed. Thank you again!
Ticket is rejected, as explained by SREZIC. -- chansen