Merge branch 'v2.0'
This commit is contained in:
commit
8b7ce08587
7
debian/NEWS
vendored
7
debian/NEWS
vendored
|
@ -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
4
debian/control
vendored
|
@ -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,
|
||||||
|
|
|
@ -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 );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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,
|
||||||
|
|
|
@ -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
|
||||||
|
|
Loading…
Reference in New Issue
Block a user