[Golang] enable unit test for ecdsa keys (#6593)

* Mustache template should use invokerPackage tag to generate import

* Enable unit tests for ECDSA keys

* fix unit test

Co-authored-by: Vikrant Balyan (vvb) <vvb@cisco.com>
This commit is contained in:
Sebastien Rosset 2020-06-10 00:47:13 -07:00 committed by GitHub
parent 4bbe3cdbc9
commit a4d679f9e5
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -11,6 +11,7 @@ import (
"context" "context"
"crypto" "crypto"
"crypto/ecdsa" "crypto/ecdsa"
"crypto/elliptic"
"crypto/rand" "crypto/rand"
"crypto/rsa" "crypto/rsa"
"crypto/x509" "crypto/x509"
@ -60,9 +61,9 @@ func writeTestRsaPemKey(t *testing.T, filePath string) {
type keyFormat int // The serialization format of the private key. type keyFormat int // The serialization format of the private key.
const ( const (
keyFormatPem keyFormat = iota // Private key is serialized in PEM format. keyFormatPem keyFormat = iota // Private key is serialized in PEM format.
keyFormatPkcs8Pem // Private key is serialized as PKCS#8 encoded in PEM format. keyFormatPkcs8Pem // Private key is serialized as PKCS#8 encoded in PEM format.
keyFormatPkcs8Der // Private key is serialized as PKCS#8 encoded in DER format. keyFormatPkcs8Der // Private key is serialized as PKCS#8 encoded in DER format.
) )
func writeRandomTestRsaPemKey(t *testing.T, filePath string, bits int, format keyFormat, passphrase string, alg *x509.PEMCipher) { func writeRandomTestRsaPemKey(t *testing.T, filePath string, bits int, format keyFormat, passphrase string, alg *x509.PEMCipher) {
@ -126,9 +127,6 @@ func writeRandomTestRsaPemKey(t *testing.T, filePath string, bits int, format ke
fmt.Printf("Wrote private key '%s'\n", filePath) fmt.Printf("Wrote private key '%s'\n", filePath)
} }
/*
Commented out because OpenAPITools is configured to use golang 1.8 at build time
x509.MarshalPKCS8PrivateKey is not present.
func writeRandomTestEcdsaPemKey(t *testing.T, filePath string) { func writeRandomTestEcdsaPemKey(t *testing.T, filePath string) {
key, err := ecdsa.GenerateKey(elliptic.P521(), rand.Reader) key, err := ecdsa.GenerateKey(elliptic.P521(), rand.Reader)
if err != nil { if err != nil {
@ -156,7 +154,6 @@ func writeRandomTestEcdsaPemKey(t *testing.T, filePath string) {
t.Fatalf("Error encoding ECDSA private key: %v", err) t.Fatalf("Error encoding ECDSA private key: %v", err)
} }
} }
*/
// TestHttpSignaturePrivateKeys creates private keys of various sizes, serialization format, // TestHttpSignaturePrivateKeys creates private keys of various sizes, serialization format,
// clear-text and password encrypted. // clear-text and password encrypted.
@ -196,11 +193,11 @@ func TestHttpSignaturePrivateKeys(t *testing.T) {
writeRandomTestRsaPemKey(t, privateKeyPath, bits, format, "", nil) writeRandomTestRsaPemKey(t, privateKeyPath, bits, format, "", nil)
authConfig := sw.HttpSignatureAuth{ authConfig := sw.HttpSignatureAuth{
KeyId: "my-key-id", KeyId: "my-key-id",
PrivateKeyPath: privateKeyPath, PrivateKeyPath: privateKeyPath,
Passphrase: "", Passphrase: "",
SigningScheme: "hs2019", SigningScheme: "hs2019",
SignedHeaders: []string{"Content-Type"}, SignedHeaders: []string{"Content-Type"},
} }
// Create a context with the HTTP signature configuration parameters. // Create a context with the HTTP signature configuration parameters.
@ -210,11 +207,11 @@ func TestHttpSignaturePrivateKeys(t *testing.T) {
} }
authConfig = sw.HttpSignatureAuth{ authConfig = sw.HttpSignatureAuth{
KeyId: "my-key-id", KeyId: "my-key-id",
PrivateKeyPath: privateKeyPath, PrivateKeyPath: privateKeyPath,
Passphrase: "my-secret-passphrase", Passphrase: "my-secret-passphrase",
SigningScheme: "hs2019", SigningScheme: "hs2019",
SignedHeaders: []string{"Content-Type"}, SignedHeaders: []string{"Content-Type"},
} }
switch format { switch format {
case keyFormatPem: case keyFormatPem:
@ -231,24 +228,21 @@ func TestHttpSignaturePrivateKeys(t *testing.T) {
} }
} }
/* {
Unfortunately, currently the build environment for OpenAPITools is using an old version privateKeyPath := "privatekey.pem"
of golang that does not support ECDSA keys. authConfig := sw.HttpSignatureAuth{
{ KeyId: "my-key-id",
privateKeyPath := "privatekey.pem" PrivateKeyPath: privateKeyPath,
authConfig := sw.HttpSignatureAuth{ SigningScheme: "hs2019",
KeyId: "my-key-id", SignedHeaders: []string{"Content-Type"},
SigningScheme: "hs2019",
SignedHeaders: []string{"Content-Type"},
}
// Generate test private key.
writeRandomTestEcdsaPemKey(t, privateKeyPath)
err := authConfig.LoadPrivateKey(privateKeyPath)
if err != nil {
t.Fatalf("Error loading private key '%s': %v", privateKeyPath, err)
}
} }
*/ // Generate test private key.
writeRandomTestEcdsaPemKey(t, privateKeyPath)
_, err := authConfig.ContextWithValue(context.Background())
if err != nil {
t.Fatalf("Error loading private key '%s': %v", privateKeyPath, err)
}
}
} }
func executeHttpSignatureAuth(t *testing.T, authConfig *sw.HttpSignatureAuth, expectSuccess bool) string { func executeHttpSignatureAuth(t *testing.T, authConfig *sw.HttpSignatureAuth, expectSuccess bool) string {
@ -380,7 +374,7 @@ var (
// signatureRe is a regular expression to capture the fields from the signature. // signatureRe is a regular expression to capture the fields from the signature.
signatureRe = regexp.MustCompile( signatureRe = regexp.MustCompile(
`Signature keyId="(?P<keyId>[^"]+)",algorithm="(?P<algorithm>[^"]+)"` + `Signature keyId="(?P<keyId>[^"]+)",algorithm="(?P<algorithm>[^"]+)"` +
`(,created=(?P<created>[0-9]+))?(,expires=(?P<expires>[0-9.]+))?,headers="(?P<headers>[^"]+)",signature="(?P<signature>[^"]+)"`) `(,created=(?P<created>[0-9]+))?(,expires=(?P<expires>[0-9.]+))?,headers="(?P<headers>[^"]+)",signature="(?P<signature>[^"]+)"`)
) )
// validateHttpAuthorizationSignature validates the HTTP signature in the HTTP request. // validateHttpAuthorizationSignature validates the HTTP signature in the HTTP request.
@ -396,10 +390,10 @@ func validateHttpAuthorizationSignature(t *testing.T, authConfig *sw.HttpSignatu
} }
result := make(map[string]string) result := make(map[string]string)
for i, name := range signatureRe.SubexpNames() { for i, name := range signatureRe.SubexpNames() {
if i != 0 && name != "" { if i != 0 && name != "" {
result[name] = match[i] result[name] = match[i]
} }
} }
b64signature := result["signature"] b64signature := result["signature"]
fmt.Printf("Algorithm: '%s' Headers: '%s' b64signature: '%s'\n", result["algorithm"], result["headers"], b64signature) fmt.Printf("Algorithm: '%s' Headers: '%s' b64signature: '%s'\n", result["algorithm"], result["headers"], b64signature)
var sb bytes.Buffer var sb bytes.Buffer
@ -418,14 +412,14 @@ func validateHttpAuthorizationSignature(t *testing.T, authConfig *sw.HttpSignatu
for _, h := range signedHeaders { for _, h := range signedHeaders {
var value string var value string
switch h { switch h {
case sw.HttpSignatureParameterRequestTarget: case sw.HttpSignatureParameterRequestTarget:
value = requestTarget value = requestTarget
case sw.HttpSignatureParameterCreated: case sw.HttpSignatureParameterCreated:
value = result["created"] value = result["created"]
case sw.HttpSignatureParameterExpires: case sw.HttpSignatureParameterExpires:
value = result["expires"] value = result["expires"]
default: default:
value = r.Request.Header.Get(h) value = r.Request.Header.Get(h)
} }
signedHeaderKvs = append(signedHeaderKvs, fmt.Sprintf("%s: %s", h, value)) signedHeaderKvs = append(signedHeaderKvs, fmt.Sprintf("%s: %s", h, value))
} }
@ -654,15 +648,14 @@ func TestInvalidHttpSignatureConfiguration(t *testing.T) {
var err error var err error
var authConfig sw.HttpSignatureAuth var authConfig sw.HttpSignatureAuth
authConfig = sw.HttpSignatureAuth{ authConfig = sw.HttpSignatureAuth{}
}
_, err = authConfig.ContextWithValue(context.Background()) _, err = authConfig.ContextWithValue(context.Background())
if err == nil || !strings.Contains(err.Error(), "Key ID must be specified") { if err == nil || !strings.Contains(err.Error(), "Key ID must be specified") {
t.Fatalf("Invalid configuration: %v", err) t.Fatalf("Invalid configuration: %v", err)
} }
authConfig = sw.HttpSignatureAuth{ authConfig = sw.HttpSignatureAuth{
KeyId: "my-key-id", KeyId: "my-key-id",
} }
_, err = authConfig.ContextWithValue(context.Background()) _, err = authConfig.ContextWithValue(context.Background())
if err == nil || !strings.Contains(err.Error(), "Private key path must be specified") { if err == nil || !strings.Contains(err.Error(), "Private key path must be specified") {
@ -670,8 +663,8 @@ func TestInvalidHttpSignatureConfiguration(t *testing.T) {
} }
authConfig = sw.HttpSignatureAuth{ authConfig = sw.HttpSignatureAuth{
KeyId: "my-key-id", KeyId: "my-key-id",
PrivateKeyPath: "test.pem", PrivateKeyPath: "test.pem",
} }
_, err = authConfig.ContextWithValue(context.Background()) _, err = authConfig.ContextWithValue(context.Background())
if err == nil || !strings.Contains(err.Error(), "Invalid signing scheme") { if err == nil || !strings.Contains(err.Error(), "Invalid signing scheme") {
@ -679,9 +672,9 @@ func TestInvalidHttpSignatureConfiguration(t *testing.T) {
} }
authConfig = sw.HttpSignatureAuth{ authConfig = sw.HttpSignatureAuth{
KeyId: "my-key-id", KeyId: "my-key-id",
PrivateKeyPath: "test.pem", PrivateKeyPath: "test.pem",
SigningScheme: "garbage", SigningScheme: "garbage",
} }
_, err = authConfig.ContextWithValue(context.Background()) _, err = authConfig.ContextWithValue(context.Background())
if err == nil || !strings.Contains(err.Error(), "Invalid signing scheme") { if err == nil || !strings.Contains(err.Error(), "Invalid signing scheme") {
@ -689,10 +682,10 @@ func TestInvalidHttpSignatureConfiguration(t *testing.T) {
} }
authConfig = sw.HttpSignatureAuth{ authConfig = sw.HttpSignatureAuth{
KeyId: "my-key-id", KeyId: "my-key-id",
PrivateKeyPath: "test.pem", PrivateKeyPath: "test.pem",
SigningScheme: sw.HttpSigningSchemeHs2019, SigningScheme: sw.HttpSigningSchemeHs2019,
SignedHeaders: []string{"foo", "bar", "foo"}, SignedHeaders: []string{"foo", "bar", "foo"},
} }
_, err = authConfig.ContextWithValue(context.Background()) _, err = authConfig.ContextWithValue(context.Background())
if err == nil || !strings.Contains(err.Error(), "cannot have duplicate names") { if err == nil || !strings.Contains(err.Error(), "cannot have duplicate names") {
@ -700,10 +693,10 @@ func TestInvalidHttpSignatureConfiguration(t *testing.T) {
} }
authConfig = sw.HttpSignatureAuth{ authConfig = sw.HttpSignatureAuth{
KeyId: "my-key-id", KeyId: "my-key-id",
PrivateKeyPath: "test.pem", PrivateKeyPath: "test.pem",
SigningScheme: sw.HttpSigningSchemeHs2019, SigningScheme: sw.HttpSigningSchemeHs2019,
SignedHeaders: []string{"foo", "bar", "Authorization"}, SignedHeaders: []string{"foo", "bar", "Authorization"},
} }
_, err = authConfig.ContextWithValue(context.Background()) _, err = authConfig.ContextWithValue(context.Background())
if err == nil || !strings.Contains(err.Error(), "Signed headers cannot include the 'Authorization' header") { if err == nil || !strings.Contains(err.Error(), "Signed headers cannot include the 'Authorization' header") {