Merge branch 'v2.0'

This commit is contained in:
Xavier Guimard 2019-06-28 14:35:30 +02:00
commit 8b7ce08587
5 changed files with 54 additions and 31 deletions

7
debian/NEWS vendored
View File

@ -1,3 +1,10 @@
lemonldap-ng (2.0.5-1) unstable; urgency=medium
This version adds some improvements in cryptographic functions. To take
advantage of them, you must change the encryption key of LemonLDAP::NG.
-- Xavier Guimard <yadd@debian.org> Thu, 27 Jun 2019 23:19:09 +0200
lemonldap-ng (2.0.0-1) unstable; urgency=medium lemonldap-ng (2.0.0-1) unstable; urgency=medium
2.0 is a major release, many things have been changed. You must read 2.0 is a major release, many things have been changed. You must read

4
debian/control vendored
View File

@ -211,7 +211,8 @@ Recommends: libapache-session-browseable-perl,
libdbi-perl, libdbi-perl,
libhttp-parser-xs-perl, libhttp-parser-xs-perl,
libjson-xs-perl, libjson-xs-perl,
liblwp-protocol-https-perl liblwp-protocol-https-perl,
libstring-random-perl
Suggests: libconvert-base32-perl, Suggests: libconvert-base32-perl,
libnet-ldap-perl, libnet-ldap-perl,
libsoap-lite-perl, libsoap-lite-perl,
@ -277,7 +278,6 @@ Recommends: libcrypt-openssl-bignum-perl,
libgd-securityimage-perl, libgd-securityimage-perl,
libmime-tools-perl, libmime-tools-perl,
libnet-ldap-perl, libnet-ldap-perl,
libstring-random-perl,
libunicode-string-perl libunicode-string-perl
Suggests: libcrypt-u2f-server-perl, Suggests: libcrypt-u2f-server-perl,
libdbi-perl, libdbi-perl,

View File

@ -11,26 +11,31 @@ package Lemonldap::NG::Common::Crypto;
use strict; use strict;
use Crypt::Rijndael; use Crypt::Rijndael;
use MIME::Base64; use MIME::Base64;
use Digest::MD5 qw(md5); use Digest::SHA;
use String::Random;
use bytes; use bytes;
our $VERSION = '2.1.0'; our $VERSION = '2.0.0';
my ( $newIv, $randG ); my ( $newIv, $randG, $hash );
$hash = \&Digest::SHA::sha256;
use constant HMAC_LENGTH => 32;
use constant IV_LENGTH => 16;
BEGIN { BEGIN {
eval { require Crypt::URandom; Crypt::URandom::urandom(16) }; eval { require Crypt::URandom; Crypt::URandom::urandom(IV_LENGTH) };
if ($@) { if ($@) {
$newIv = sub { return md5( rand() . time . {} ) }; $newIv = sub {
$randG = sub { return bytes::substr( Digest::SHA::sha1( rand() . time . {} ),
my $a = 256; 0, IV_LENGTH );
$a = unpack( "C", Crypt::URandom::urandom(1) ) while ( $a > $_[0] );
return $a;
}; };
$randG = sub { return int( rand( $_[0] ) ) };
} }
else { else {
$newIv = sub { return Crypt::URandom::urandom(16) }; $newIv = sub { return Crypt::URandom::urandom(IV_LENGTH) };
$randG = sub { return int( rand( $_[0] ) ) }; $randG = sub {
return
int( unpack( "C", Crypt::URandom::urandom(1) ) * $_[0] / 256 );
};
} }
} }
@ -61,9 +66,9 @@ sub new {
sub _getCipher { sub _getCipher {
my ( $self, $key, $iv ) = @_; my ( $self, $key, $iv ) = @_;
$key ||= ""; $key ||= "";
my $cipher = $self->{ciphers}->{$key} ||=
Crypt::Rijndael->new( md5( $self->{key}, $key ), $self->{mode} ); Crypt::Rijndael->new( $hash->( $self->{key}, $key ), $self->{mode} );
return $cipher; return $self->{ciphers}->{$key};
} }
## @method string encrypt(string data) ## @method string encrypt(string data)
@ -77,8 +82,11 @@ sub encrypt {
my $l = bytes::length($data) % 16; my $l = bytes::length($data) % 16;
$data .= "\0" x ( 16 - $l ) unless ( $l == 0 ); $data .= "\0" x ( 16 - $l ) unless ( $l == 0 );
my $iv = $low ? md5( rand() . time . {} ) : $newIv->(); my $iv =
my $hmac = md5($data); $low
? bytes::substr( Digest::SHA::sha1( rand() . time . {} ), 0, IV_LENGTH )
: $newIv->();
my $hmac = $hash->($data);
eval { eval {
$data = $data =
encode_base64( encode_base64(
@ -108,17 +116,17 @@ sub decrypt {
$data =~ s/%0A/\n/ig; $data =~ s/%0A/\n/ig;
$data = decode_base64($data); $data = decode_base64($data);
my $iv; my $iv;
$iv = bytes::substr( $data, 0, 16 ); $iv = bytes::substr( $data, 0, IV_LENGTH );
$data = bytes::substr( $data, 16 ); $data = bytes::substr( $data, IV_LENGTH );
eval { $data = $self->_getCipher->set_iv($iv)->decrypt($data); }; eval { $data = $self->_getCipher->set_iv($iv)->decrypt($data); };
if ($@) { if ($@) {
$msg = "Crypt::Rijndael error : $@"; $msg = "Crypt::Rijndael error : $@";
return undef; return undef;
} }
my $hmac = bytes::substr( $data, 0, 16 ); my $hmac = bytes::substr( $data, 0, HMAC_LENGTH );
$data = bytes::substr( $data, 16 ); $data = bytes::substr( $data, HMAC_LENGTH );
if ( md5($data) ne $hmac ) { if ( $hash->($data) ne $hmac ) {
$msg = "Bad MAC"; $msg = "Bad MAC";
return undef; return undef;
} }
@ -183,8 +191,8 @@ sub _cryptHex {
} }
$data = pack "H*", $data; $data = pack "H*", $data;
if ( $sub eq 'decrypt' ) { if ( $sub eq 'decrypt' ) {
$iv = bytes::substr( $data, 0, 16 ); $iv = bytes::substr( $data, 0, IV_LENGTH );
$data = bytes::substr( $data, 16 ); $data = bytes::substr( $data, IV_LENGTH );
} }
eval { $data = $self->_getCipher($key)->set_iv($iv)->$sub($data); }; eval { $data = $self->_getCipher($key)->set_iv($iv)->$sub($data); };
if ($@) { if ($@) {
@ -200,6 +208,10 @@ sub _cryptHex {
} }
sub srandom { sub srandom {
eval { require String::Random };
if ($@) {
die 'Missing recommended dependency to String::Random';
}
return String::Random->new( rand_gen => $randG ); return String::Random->new( rand_gen => $randG );
} }

View File

@ -12,7 +12,7 @@ use strict;
use Convert::PEM; use Convert::PEM;
use Crypt::OpenSSL::RSA; use Crypt::OpenSSL::RSA;
use Lemonldap::NG::Common::Conf; use Lemonldap::NG::Common::Conf;
use String::Random qw(random_string); use Lemonldap::NG::Common::Crypto;
my $debug = 0; my $debug = 0;
@ -28,9 +28,10 @@ print "Configuration loaded\n" if $debug;
#============================================================================= #=============================================================================
# Generate new key # Generate new key
#============================================================================= #=============================================================================
my $rsa = Crypt::OpenSSL::RSA->generate_key(2048); my $rsa = Crypt::OpenSSL::RSA->generate_key(2048);
my $key_id = random_string("ssssssssss"); my $key_id =
my $keys = { Lemonldap::NG::Common::Crypto::srandom()->randpattern("ssssssssss");
my $keys = {
'private' => $rsa->get_private_key_string(), 'private' => $rsa->get_private_key_string(),
'public' => $rsa->get_public_key_x509_string(), 'public' => $rsa->get_public_key_x509_string(),
'id' => $key_id, 'id' => $key_id,

View File

@ -532,6 +532,7 @@ t/61-GrantSession.t
t/61-Session-ActivityTimeout.t t/61-Session-ActivityTimeout.t
t/61-Session-Timeout.t t/61-Session-Timeout.t
t/62-SingleSession.t t/62-SingleSession.t
t/62-UpgradeSession.t
t/63-History.t t/63-History.t
t/64-StayConnected.t t/64-StayConnected.t
t/65-AutoSignin.t t/65-AutoSignin.t
@ -552,7 +553,8 @@ t/68-Impersonation.t
t/69-FavApps.t t/69-FavApps.t
t/70-2F-TOTP-8.t t/70-2F-TOTP-8.t
t/70-2F-TOTP-with-History.t t/70-2F-TOTP-with-History.t
t/70-2F-TOTP-with-TTL-and-msg.t t/70-2F-TOTP-with-TTL-and-JSON.t
t/70-2F-TOTP-with-TTL-and-XML.t
t/70-2F-TOTP-with-TTL.t t/70-2F-TOTP-with-TTL.t
t/71-2F-U2F-with-History.t t/71-2F-U2F-with-History.t
t/71-2F-U2F-with-TTL-and-msg.t t/71-2F-U2F-with-TTL-and-msg.t
@ -571,6 +573,7 @@ t/76-2F-Ext-with-GrantSession.t
t/76-2F-Ext-with-History.t t/76-2F-Ext-with-History.t
t/77-2F-Mail-with-global-storage.t t/77-2F-Mail-with-global-storage.t
t/77-2F-Mail.t t/77-2F-Mail.t
t/78-2F-Upgrade.t
t/90-Translations.t t/90-Translations.t
t/99-pod.t t/99-pod.t
t/gpghome/key.asc t/gpghome/key.asc