[Rt-commit] rt branch, 4.2.14-releng, updated. rt-4.2.14rc2-1-g96075fc
Shawn Moore
shawn at bestpractical.com
Wed Jul 12 10:23:31 EDT 2017
The branch, 4.2.14-releng has been updated
via 96075fc4169e164a81e527110722e16bcae0d40a (commit)
from 74e13acf775e116d6af21809fe9c999aa8ece263 (commit)
Summary of changes:
lib/RT/User.pm | 2 +-
lib/RT/Util.pm | 20 ++++++++++++++++----
2 files changed, 17 insertions(+), 5 deletions(-)
- Log -----------------------------------------------------------------
commit 96075fc4169e164a81e527110722e16bcae0d40a
Author: Shawn M Moore <shawn at bestpractical.com>
Date: Mon Jul 10 11:48:28 2017 -0400
Add a "binary" option to opt out of UTF8 encoding
The SHA256 branch of IsPassword generates binary values to compare,
which may lead to comparing two strings with a different number of
Unicode characters, even when both strings have 26 octets (since UTF8 is
a variable-length encoding). This triggers an error in constant_time_eq
which demands both strings are the same length.
When comparing binary values pass this flag to avoid treating the
inputs as UTF8.
diff --git a/lib/RT/User.pm b/lib/RT/User.pm
index 4e450b9..b969d24 100644
--- a/lib/RT/User.pm
+++ b/lib/RT/User.pm
@@ -1012,7 +1012,7 @@ sub IsPassword {
my $salt = substr($hash, 0, 4, "");
return 0 unless RT::Util::constant_time_eq(
substr(Digest::SHA::sha256($salt . Digest::MD5::md5(Encode::encode( "UTF-8", $value))), 0, 26),
- $hash
+ $hash, 1
);
} elsif (length $stored == 32) {
# Hex nonsalted-md5
diff --git a/lib/RT/Util.pm b/lib/RT/Util.pm
index 317a208..06cd046 100644
--- a/lib/RT/Util.pm
+++ b/lib/RT/Util.pm
@@ -166,6 +166,9 @@ The two string arguments B<MUST> be of equal length. If the lengths differ,
this function will call C<die()>, as proceeding with execution would create
a timing vulnerability. Length is defined by characters, not bytes.
+Strings that should be treated as binary octets rather than Unicode text
+should pass a true value for the binary flag.
+
This code has been tested to do what it claims. Do not change it without
thorough statistical timing analysis to validate the changes.
@@ -177,7 +180,7 @@ B<https://en.wikipedia.org/wiki/Timing_attack>
=cut
sub constant_time_eq {
- my ($a, $b) = @_;
+ my ($a, $b, $binary) = @_;
my $result = 0;
@@ -191,9 +194,18 @@ sub constant_time_eq {
my $a_char = substr($a, $i, 1);
my $b_char = substr($b, $i, 1);
- # encode() is set to die on malformed
- my @a_octets = unpack("C*", encode('UTF-8', $a_char, Encode::FB_CROAK));
- my @b_octets = unpack("C*", encode('UTF-8', $b_char, Encode::FB_CROAK));
+ my (@a_octets, @b_octets);
+
+ if ($binary) {
+ @a_octets = ord($a_char);
+ @b_octets = ord($b_char);
+ }
+ else {
+ # encode() is set to die on malformed
+ @a_octets = unpack("C*", encode('UTF-8', $a_char, Encode::FB_CROAK));
+ @b_octets = unpack("C*", encode('UTF-8', $b_char, Encode::FB_CROAK));
+ }
+
die $generic_error if (scalar @a_octets) != (scalar @b_octets);
for (my $j = 0; $j < scalar @a_octets; $j++) {
-----------------------------------------------------------------------
More information about the rt-commit
mailing list