From 8657895178ceb5039c725d5a238ebc52f7e5ebea Mon Sep 17 00:00:00 2001 From: Michael Vogt Date: Fri, 20 Dec 2024 12:02:17 +0100 Subject: [PATCH] crypt: provide a non-cgo fallback for crypt() This commit add a trivial openssl based fallback version of crypt() that works when the library is build without cgo (e.g. when doing a cross build). --- pkg/crypt/crypt.go | 1 + pkg/crypt/crypt_impl_non_cgo.go | 34 +++++++++++++++++++++++++++++++++ pkg/crypt/crypt_test.go | 24 +++++++++++++++++++++++ 3 files changed, 59 insertions(+) create mode 100644 pkg/crypt/crypt_impl_non_cgo.go diff --git a/pkg/crypt/crypt.go b/pkg/crypt/crypt.go index eede15e010..b09c8fd6e1 100644 --- a/pkg/crypt/crypt.go +++ b/pkg/crypt/crypt.go @@ -18,6 +18,7 @@ func CryptSHA512(phrase string) (string, error) { return "", nil } + // Note: update "crypt_impl_non_cgo.go" if new hash types get added hashSettings := "$6$" + salt return crypt(phrase, hashSettings) } diff --git a/pkg/crypt/crypt_impl_non_cgo.go b/pkg/crypt/crypt_impl_non_cgo.go new file mode 100644 index 0000000000..21989e7565 --- /dev/null +++ b/pkg/crypt/crypt_impl_non_cgo.go @@ -0,0 +1,34 @@ +//go:build !cgo + +// +// fallback implementation of "crypt" for cross building + +package crypt + +import ( + "bytes" + "fmt" + "os/exec" + "strings" +) + +func crypt(pass, salt string) (string, error) { + // we could extract the "hash-type" here and pass it to + // openssl instead of hardcoding -6 but lets do that once we + // actually move away from sha512crypt + if !strings.HasPrefix(salt, "$6$") { + return "", fmt.Errorf("only crypt type SHA512 supported, got %q", salt) + } + cmd := exec.Command( + "openssl", "passwd", "-6", + // strip the $6$ + "-salt", salt[3:], + "-stdin", + ) + cmd.Stdin = bytes.NewBufferString(pass) + output, err := cmd.CombinedOutput() + if err != nil { + return "", fmt.Errorf("cannot generate password: %v, output:%s\n", err, string(output)) + } + return strings.TrimSpace(string(output)), nil +} diff --git a/pkg/crypt/crypt_test.go b/pkg/crypt/crypt_test.go index 4665b008cc..38bbe80e0a 100644 --- a/pkg/crypt/crypt_test.go +++ b/pkg/crypt/crypt_test.go @@ -62,3 +62,27 @@ func TestGenSalt(t *testing.T) { retSaltSecond, _ := genSalt(length) assert.NotEqual(t, retSaltFirst, retSaltSecond) } + +func TestCryptItself(t *testing.T) { + for _, tc := range []struct { + pass, salt string + expected string + }{ + // test vectors from upstream glibc, e.g. + // https://github.com/lattera/glibc/blob/master/crypt/sha512c-test.c#L12 + { + "Hello world!", + "$6$saltstring", + "$6$saltstring$svn8UoSVapNtMuq1ukKS4tPQd8iKwSMHWjl/O817G3uBnIFNjnQJuesI68u4OTLiBFdcbYEdFCoEOfaS35inz1", + }, + { + "Hello world!", + "$6$rounds=10000$saltstringsaltstring", + "$6$rounds=10000$saltstringsaltst$OW1/O6BYHV6BcXZu8QVeXbDWra3Oeqh0sbHbbMCVNSnCM/UrjmM0Dp8vOuZeHBy/YTBmSK6H9qs/y3RnOaw5v.", + }, + } { + cryptedPass, err := crypt(tc.pass, tc.salt) + assert.NoError(t, err) + assert.Equal(t, tc.expected, cryptedPass) + } +}