diff --git a/authentication.go b/authentication.go index f8ead404..b515adf6 100644 --- a/authentication.go +++ b/authentication.go @@ -7,9 +7,7 @@ import ( "crypto/sha1" "crypto/sha256" "encoding/base64" - "errors" "io" - "math/big" ) // GenerateDigestSignature will generate a signature of the given data protocol 1.3 @@ -24,7 +22,7 @@ func GenerateDigestSignature(priv *rsa.PrivateKey, string_to_sign string) (sig [ // GenerateSignature will generate a signature ( sign ) the given data func GenerateSignature(priv *rsa.PrivateKey, data string) (enc []byte, err error) { - sig, err := privateEncrypt(priv, []byte(data)) + sig, err := rsa.SignPKCS1v15(rand.Reader, priv, 0, []byte(data)) if err != nil { return nil, err } @@ -32,68 +30,6 @@ func GenerateSignature(priv *rsa.PrivateKey, data string) (enc []byte, err error return sig, nil } -// privateEncrypt implements OpenSSL's RSA_private_encrypt function -func privateEncrypt(key *rsa.PrivateKey, data []byte) (enc []byte, err error) { - k := (key.N.BitLen() + 7) / 8 - tLen := len(data) - - // rfc2313, section 8: - // The length of the data D shall not be more than k-11 octets - if tLen > k-11 { - err = errors.New("Data too long") - return - } - em := make([]byte, k) - em[1] = 1 - for i := 2; i < k-tLen-1; i++ { - em[i] = 0xff - } - copy(em[k-tLen:k], data) - c := new(big.Int).SetBytes(em) - if c.Cmp(key.N) > 0 { - err = nil - return - } - var m *big.Int - var ir *big.Int - if key.Precomputed.Dp == nil { - m = new(big.Int).Exp(c, key.D, key.N) - } else { - // We have the precalculated values needed for the CRT. - m = new(big.Int).Exp(c, key.Precomputed.Dp, key.Primes[0]) - m2 := new(big.Int).Exp(c, key.Precomputed.Dq, key.Primes[1]) - m.Sub(m, m2) - if m.Sign() < 0 { - m.Add(m, key.Primes[0]) - } - m.Mul(m, key.Precomputed.Qinv) - m.Mod(m, key.Primes[0]) - m.Mul(m, key.Primes[1]) - m.Add(m, m2) - - for i, values := range key.Precomputed.CRTValues { - prime := key.Primes[2+i] - m2.Exp(c, values.Exp, prime) - m2.Sub(m2, m) - m2.Mul(m2, values.Coeff) - m2.Mod(m2, prime) - if m2.Sign() < 0 { - m2.Add(m2, prime) - } - m2.Mul(m2, values.R) - m.Add(m, m2) - } - } - - if ir != nil { - // Unblind. - m.Mul(m, ir) - m.Mod(m, key.N) - } - enc = m.Bytes() - return -} - // HashStr returns the base64 encoded SHA1 sum of the toHash string func HashStr(toHash string) string { h := sha1.New() diff --git a/authentication_test.go b/authentication_test.go index c5055864..eaa66b5a 100644 --- a/authentication_test.go +++ b/authentication_test.go @@ -1,13 +1,24 @@ package chef import ( + "crypto/rsa" + "encoding/base64" "testing" + + "github.com/stretchr/testify/assert" ) +type privateKey struct { + name string + key *rsa.PrivateKey +} + const ( teststr = "Hash this string" testsha1 = "hdBcDGYOo5/Q4k2DojVVP1ANs3U=" testsha256 = "HKxj85/WjYxTHye4B2EPs9UPD8PxhplXZ/tjFucgCj4=" + signature10 = "Z6mh9AcCOylVV4mR2MdgQ+FxriOjFipbcowQkDNIOT9o2pVxdzqC4mstZfF430wAEd+HLPXldJafQINmWpHzG2tDd+ms3WQBIq2/kCLmSljP7DHulOsJVeznXtcOwlg6KP4xTK4CYZoh8YuqW3VbdXyGwgx8iOKYac7EBFoKHxu2B4ggDq6NhDvYTA7eNLdXhaotEh6oNkiTByWndUki0boz82R6jMBtMw0ww4ENhZ6Mt3KeC95cFpv5dhmLXWGYVCbCnhWHsUuQlW5Ii1897muSWa+nlQBK6EBiqL8GD/3X8hHta9YLt8zM7W0hqo4NmFKie6mCaaX51Z6ExzUEgw==" + signature13 = "EuuCVnnbDBah5WiTy9cM1OwhPp+rEQl6L60E9dpYCEcvCMdvs5G6fVuW9wyo7wHlLETMmbltNccdmlByACWKobFi98oH/aYTz6Z7qRxiAJX8Z/b6C6K1c5mxKeJguOt86SGKd6aqQ4O20bXncKJ6u9HxfALphYHIJHegXC414bGbnWbDowI9ZQpNWZ/10bqyoOIiGAOJbzmU2jn6+2eey78sTbKYmddNJzaVzJAq7dtHvGG0yE1h0Y3lCN3mWP9rVu2tVClXKhpOJ1CQGY7t3gVrBtVVvgdQNBW5rhGWDD6BkwRigGiwBczSVk8a1oTiAMRHPXurrEr+c7ArItrUvA==" privateKeyG = ` -----BEGIN RSA PRIVATE KEY----- MIIEpAIBAAKCAQEAx12nDxxOwSPHRSJEDz67a0folBqElzlu2oGMiUTS+dqtj3FU @@ -36,32 +47,77 @@ rlXw1QKBgQDBOyUJKQOgDE2u9EHybhCIbfowyIE22qn9a3WjQgfxFJ+aAL9Bg124 fJIEzz43fJ91fe5lTOgyMF5TtU5ClAOPGtlWnXU0e5j3L4LjbcqzEbeyxvP3sn1z dYkX7NdNQ5E6tcJZuJCGq0HxIAQeKPf3x9DRKzMnLply6BEzyuAC4g== -----END RSA PRIVATE KEY----- +` + privateKey8 = ` +-----BEGIN PRIVATE KEY----- +MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQDHXacPHE7BI8dF +IkQPPrtrR+iUGoSXOW7agYyJRNL52q2PcVSHmUlzUyNymtFXFwNXCGxJKj33jxcS +STf0h1uVQIuiG5yo0zM6chx1mfzNuU3sKelbTdTBEzSJZfUe7Aeca+bo8p6ooaqm +XIhdg7SqUNYLML5VrEVPA5STfUx84clCfjJ9Ot+4TuHcVMSUsG7TrlIWnd08gIgS +ZYKX0Np2fFudnwBLFhD3EbuGZl24OCM1bmXfHr8QWSnKb7/8PoBtYNxUnWi8Kwkv +cJ8f81kLd6R4n9oR4vE/+9oJIfVVgLlWxgrlCDtIhro22Hf5FnPWFg6gEm6UTPCW +POfChlhFAgMBAAECggEAM9CiX6oCye3Ll6s9Nx0dxtcsmnl95nPV3NJ4vSB3GNr9 +6t8QkiGD1oZQGzQjnlfr1U3qHuXsrw+wdl8zPMmFQvhAkkRM5g/mK5WG0gXQj4NO +vkdyT/mdhwS/zcoC+CNuIvhkTjzogXlrCcvY4T0e0nkp+ESV41xfsxaCIgcZvwbW +MKq7+0fQYjxnhw2BStcxtzMbB9s3/lZzTOgO2l7RN5z8V3QMsXBGIC6F5qQ+OVVZ +vsAYwNfhPLMJd8ylLW6XaOTqcYWTvu5CjMU9BRrAJGn6ZVLip5yCr9ap9NllsGVb +YvXz+Slp++zEbyQns5ES2tvRKWhk0UcRzZDvQZuAoQKBgQDpz946sjdSi6vWAp7M +QEWYUoUfphL81k2lxIbk9yioXoBUnBeDnvhDLpFq0Ljt73Zt7ZNPU7KmWe2Pi+Rn +dES/zXJ/P+25ea0bQDKUftERvG5vECBiZRPXzBQAvizdNJPYCUrhHb0rAFp3BQAl +44s1b5FzjGG3WBqWypBFvilTOQKBgQDaSPa9SEoAHtAUI9JPjn/mr4ABO63xZ4ec +j63VRqJmgrjUmt7xPCVipSBwnXpDQfoohsmOURkC7QiwnGNDGQPigmC/yfk8Vd1z +XgdxJDnXYWaAIY3C0Nj8BPtJA/eQ6PRHJ2A3Ta65Fv/nk0nTsGH7JNA0YD4zlJKd +TJpE8gAxbQKBgGBVTuCsMPMHrQL+DWNmT8ZUqZjCmiwmN9PGxzVrSAsm9ITn0yBd +zTgQ5cU2vhr6gLcGHZ2fhInZn3F3V+HwG6tTAIvBUTcMFPCXYL+iCI3gLzf/Uvh3 +YNeWs98ie+WgFhH6silSUXB4Ms2697akq+SWVT1gZ5pc6IecahjyIqCxAoGBANko +w4e1liEehmWy6XTKUIYATPltFPRXyftAmXDXb5NKM3UXifo2mv7TRj2i/VJSHfwZ +dAWIurhFdmK1gq7rAQlkKbpDxhd3WPOANSkjIAQc2ytXtj99JJE8p32RW8anavYq +vzblqpBqyDXrOwRFsoR2sEebA+auxVmGLueuVfDVAoGBAME7JQkpA6AMTa70QfJu +EIht+jDIgTbaqf1rdaNCB/EUn5oAv0GDXbh8kgTPPjd8n3V97mVM6DIwXlO1TkKU +A48a2VaddTR7mPcvguNtyrMRt7LG8/eyfXN1iRfs101DkTq1wlm4kIarQfEgBB4o +9/fH0NErMycumXLoETPK4ALi +-----END PRIVATE KEY----- ` ) var testblock = "Stuff and nonsense to encode " -func TestGenerateDigestSignature(t *testing.T) { - pk, _ := PrivateKeyFromString([]byte(privateKeyG)) - _, err := GenerateDigestSignature(pk, teststr) +func getPrivateKeys() ([]privateKey, error) { + pkcs1, err := PrivateKeyFromString([]byte(privateKeyG)) + if err != nil { + return nil, err + } + pkcs8, err := PrivateKeyFromString([]byte(privateKey8)) if err != nil { - t.Error("Error generating signature", err) + return nil, err } + return []privateKey{ + {"pkcs#1", pkcs1}, + {"pkcs#8", pkcs8}, + }, nil } -func TestGenerateSignature(t *testing.T) { - pk, _ := PrivateKeyFromString([]byte(privateKeyG)) - _, err := GenerateSignature(pk, teststr) - if err != nil { - t.Error("Error generating signature", err) +func TestGenerateDigestSignature(t *testing.T) { + pks, _ := getPrivateKeys() + for _, pk := range pks { + signed, err := GenerateDigestSignature(pk.key, teststr) + if err != nil { + t.Error("Error generating signature", pk.name, err) + } + assert.Equalf(t, signature13, base64.StdEncoding.EncodeToString(signed), + "Signature doesn't match. Version=%+v, KeyType=%+v", "1.0", pk.name) } } -func TestPrivateEncrypt(t *testing.T) { - pk, _ := PrivateKeyFromString([]byte(privateKeyG)) - _, err := privateEncrypt(pk, []byte(teststr)) - if err != nil { - t.Error("Error encrypting", err) +func TestGenerateSignature(t *testing.T) { + pks, _ := getPrivateKeys() + for _, pk := range pks { + signed, err := GenerateSignature(pk.key, teststr) + if err != nil { + t.Error("Error generating signature", pk.name, err) + } + assert.Equalf(t, signature10, base64.StdEncoding.EncodeToString(signed), + "Signature doesn't match. Version=%+v, KeyType=%+v", "1.3", pk.name) } }