diff --git a/go/config/pfcrypt/init.go b/go/config/pfcrypt/init.go index f53571ad183..1c403feb0ee 100644 --- a/go/config/pfcrypt/init.go +++ b/go/config/pfcrypt/init.go @@ -8,9 +8,10 @@ import ( ) var systemInitKey []byte +var dervivedKey []byte func setupSystemInitKey(envName, fileName string) error { - val := os.Getenv("PF_SYSTEM_INIT_KEY_FILE") + val := os.Getenv(envName) if val != "" { systemInitKey = []byte(val) return nil @@ -26,7 +27,9 @@ func setupSystemInitKey(envName, fileName string) error { } func init() { - if err := setupSystemInitKey("PF_SYSTEM_INIT_KEY_FILE", file_paths.SYSTEM_INIT_KEY_FILE); err != nil { - panic("The PF_SYSTEM_INIT_KEY_FILE environment is not" + err.Error()) + if err := setupSystemInitKey("PF_SYSTEM_INIT_KEY", file_paths.SYSTEM_INIT_KEY_FILE); err != nil { + panic("Unable to setup the PF_SYSTEM_INIT secret" + err.Error()) } + + dervivedKey = makeDerivedKey() } diff --git a/go/config/pfcrypt/pfcrypt.go b/go/config/pfcrypt/pfcrypt.go index 18a35efd75f..fab034fc5d0 100644 --- a/go/config/pfcrypt/pfcrypt.go +++ b/go/config/pfcrypt/pfcrypt.go @@ -35,8 +35,7 @@ func encodeParts(inputs ...part) string { } func PfEncrypt(data []byte) (string, error) { - key := derivedKey() - aesCypher, err := aes.NewCipher(key) + aesCypher, err := aes.NewCipher(dervivedKey) ad := []byte{} if err != nil { return "", fmt.Errorf("PfEncrypt NewCipher: %w", err) @@ -134,8 +133,7 @@ func PfDecrypt(data string) ([]byte, error) { return nil, fmt.Errorf("Associated Data Not Found") } - key := derivedKey() - aesCypher, err := aes.NewCipher(key) + aesCypher, err := aes.NewCipher(dervivedKey) if err != nil { return nil, fmt.Errorf("PfDerypt NewCipher: %w", err) } @@ -156,6 +154,6 @@ func PfDecrypt(data string) ([]byte, error) { return output, nil } -func derivedKey() []byte { +func makeDerivedKey() []byte { return pbkdf2.Key(systemInitKey, []byte("packetfence"), ITERATION_COUNT, LEN, sha256.New) } diff --git a/lib/pf/config/crypt.pm b/lib/pf/config/crypt.pm index fe7a833cdcb..09c372ace95 100644 --- a/lib/pf/config/crypt.pm +++ b/lib/pf/config/crypt.pm @@ -20,13 +20,17 @@ use MIME::Base64; use pf::file_paths qw($system_init_key_file); our $PREFIX = 'PF_ENC['; -my $ITERATION_COUNT = 5000; -my $HASH_TYPE = 'SHA256'; -my $LEN = 32; -my $SYSTEM_INIT_KEY; +our $ITERATION_COUNT = 5000; +our $HASH_TYPE = 'SHA256'; +our $LEN = 32; +our $SYSTEM_INIT_KEY = ''; +our $DERIVED_KEY; BEGIN { - my $val = $ENV{PF_SYSTEM_INIT_KEY_FILE}; + $ITERATION_COUNT = 5000; + $HASH_TYPE = 'SHA256'; + $LEN = 32; + my $val = $ENV{PF_SYSTEM_INIT_KEY}; if ($val) { $SYSTEM_INIT_KEY = $val; } else { @@ -41,6 +45,14 @@ sub derived_key { return pbkdf2($SYSTEM_INIT_KEY, 'packetfence', $ITERATION_COUNT, $HASH_TYPE, $LEN); } +BEGIN { + if ($SYSTEM_INIT_KEY eq '') { + die "system init key"; + } + + $DERIVED_KEY = derived_key(); +} + sub encode_tags { if (@_ % 2) { die "odd number of passed"; @@ -69,17 +81,15 @@ sub decode_tags { sub pf_encrypt { my ($text) = @_; my $iv = random_bytes(12); - my $derived_key = derived_key(); my $ad = ''; - my ($ciphertext, $tag) = gcm_encrypt_authenticate('AES', $derived_key, $iv, $ad, $text); + my ($ciphertext, $tag) = gcm_encrypt_authenticate('AES', $DERIVED_KEY, $iv, $ad, $text); return 'PF_ENC[' . encode_tags(data => $ciphertext, tag => $tag, iv => $iv, ad => $ad) . ']'; } sub pf_decrypt { my ($data) = @_; my $tags = decode_tags($data); - my $derived_key = derived_key(); - return gcm_decrypt_verify('AES', $derived_key, $tags->{iv}, $tags->{ad}, $tags->{data}, $tags->{tag}); + return gcm_decrypt_verify('AES', $DERIVED_KEY, $tags->{iv}, $tags->{ad}, $tags->{data}, $tags->{tag}); } =head1 AUTHOR diff --git a/t/unittest/config/crypt/object.t b/t/unittest/config/crypt/object.t index ed041a11a2b..6a126aa65e8 100755 --- a/t/unittest/config/crypt/object.t +++ b/t/unittest/config/crypt/object.t @@ -22,7 +22,7 @@ BEGIN { use Test::More tests => 4; use pf::config::crypt::object; -use pf::Sereal qw($DECODER $ENCODER); +use pf::Sereal qw($DECODER $ENCODER_FREEZER); use Sereal::Encoder qw(sereal_encode_with_object); use Sereal::Decoder qw(sereal_decode_with_object); @@ -37,7 +37,7 @@ my $frozen = $object->FREEZE(undef); my $thawed = $object->THAW(undef, $frozen); is($secret, $thawed, "Data frozen and thawed"); -my $data = sereal_encode_with_object($ENCODER, $object); +my $data = sereal_encode_with_object($ENCODER_FREEZER, $object); $thawed = sereal_decode_with_object($DECODER, $data); is($secret, $thawed, "Data frozen and thawed");