From d869544ce11556df1128e46474d2fa2a9ca80ce8 Mon Sep 17 00:00:00 2001 From: Aanisha Mishra Date: Thu, 4 Feb 2021 08:03:17 +0530 Subject: [PATCH] [Go][Client] Secret key content string in http signing support (#8570) * accept private key content string * sample update * Add comments to new methods * update samples with comments * Update modules/openapi-generator/src/main/resources/go/signing.mustache Co-authored-by: Jiri Kuncar * Update modules/openapi-generator/src/main/resources/go/signing.mustache Co-authored-by: Jiri Kuncar * Update signing.mustache * update sample comments * Update modules/openapi-generator/src/main/resources/go/signing.mustache Co-authored-by: Sebastien Rosset * Update modules/openapi-generator/src/main/resources/go/signing.mustache Co-authored-by: Sebastien Rosset * update empty checks for privateKey Co-authored-by: Vikrant Balyan Co-authored-by: Jiri Kuncar Co-authored-by: Sebastien Rosset --- .../src/main/resources/go/signing.mustache | 17 ++++++++++++++++- .../client/petstore/go/go-petstore/signing.go | 17 ++++++++++++++++- 2 files changed, 32 insertions(+), 2 deletions(-) diff --git a/modules/openapi-generator/src/main/resources/go/signing.mustache b/modules/openapi-generator/src/main/resources/go/signing.mustache index db486a16b20..22477a06f38 100644 --- a/modules/openapi-generator/src/main/resources/go/signing.mustache +++ b/modules/openapi-generator/src/main/resources/go/signing.mustache @@ -116,6 +116,11 @@ type HttpSignatureAuth struct { privateKey crypto.PrivateKey // The private key used to sign HTTP requests. } +// SetPrivateKey accepts a private key string and sets it. +func (h *HttpSignatureAuth) SetPrivateKey(privateKey string) error { + return h.parsePrivateKey([]byte(privateKey)) +} + // ContextWithValue validates the HttpSignatureAuth configuration parameters and returns a context // suitable for HTTP signature. An error is returned if the HttpSignatureAuth configuration parameters // are invalid. @@ -123,7 +128,7 @@ func (h *HttpSignatureAuth) ContextWithValue(ctx context.Context) (context.Conte if h.KeyId == "" { return nil, fmt.Errorf("Key ID must be specified") } - if h.PrivateKeyPath == "" { + if h.PrivateKeyPath == "" && h.privateKey == nil { return nil, fmt.Errorf("Private key path must be specified") } if _, ok := supportedSigningSchemes[h.SigningScheme]; !ok { @@ -168,7 +173,11 @@ func (h *HttpSignatureAuth) GetPublicKey() (crypto.PublicKey, error) { } // loadPrivateKey reads the private key from the file specified in the HttpSignatureAuth. +// The key is loaded only when privateKey is not already set. func (h *HttpSignatureAuth) loadPrivateKey() (err error) { + if h.privateKey != nil { + return nil + } var file *os.File file, err = os.Open(h.PrivateKeyPath) if err != nil { @@ -182,12 +191,18 @@ func (h *HttpSignatureAuth) loadPrivateKey() (err error) { if err != nil { return err } + return h.parsePrivateKey(priv) +} + +// parsePrivateKey decodes privateKey byte array to crypto.PrivateKey type. +func (h *HttpSignatureAuth) parsePrivateKey(priv []byte) error { pemBlock, _ := pem.Decode(priv) if pemBlock == nil { // No PEM data has been found. return fmt.Errorf("File '%s' does not contain PEM data", h.PrivateKeyPath) } var privKey []byte + var err error if x509.IsEncryptedPEMBlock(pemBlock) { // The PEM data is encrypted. privKey, err = x509.DecryptPEMBlock(pemBlock, []byte(h.Passphrase)) diff --git a/samples/openapi3/client/petstore/go/go-petstore/signing.go b/samples/openapi3/client/petstore/go/go-petstore/signing.go index f4be5ad9265..9dc2cf7570a 100644 --- a/samples/openapi3/client/petstore/go/go-petstore/signing.go +++ b/samples/openapi3/client/petstore/go/go-petstore/signing.go @@ -125,6 +125,11 @@ type HttpSignatureAuth struct { privateKey crypto.PrivateKey // The private key used to sign HTTP requests. } +// SetPrivateKey accepts a private key string and sets it. +func (h *HttpSignatureAuth) SetPrivateKey(privateKey string) error { + return h.parsePrivateKey([]byte(privateKey)) +} + // ContextWithValue validates the HttpSignatureAuth configuration parameters and returns a context // suitable for HTTP signature. An error is returned if the HttpSignatureAuth configuration parameters // are invalid. @@ -132,7 +137,7 @@ func (h *HttpSignatureAuth) ContextWithValue(ctx context.Context) (context.Conte if h.KeyId == "" { return nil, fmt.Errorf("Key ID must be specified") } - if h.PrivateKeyPath == "" { + if h.PrivateKeyPath == "" && h.privateKey == nil { return nil, fmt.Errorf("Private key path must be specified") } if _, ok := supportedSigningSchemes[h.SigningScheme]; !ok { @@ -177,7 +182,11 @@ func (h *HttpSignatureAuth) GetPublicKey() (crypto.PublicKey, error) { } // loadPrivateKey reads the private key from the file specified in the HttpSignatureAuth. +// The key is loaded only when privateKey is not already set. func (h *HttpSignatureAuth) loadPrivateKey() (err error) { + if h.privateKey != nil { + return nil + } var file *os.File file, err = os.Open(h.PrivateKeyPath) if err != nil { @@ -191,12 +200,18 @@ func (h *HttpSignatureAuth) loadPrivateKey() (err error) { if err != nil { return err } + return h.parsePrivateKey(priv) +} + +// parsePrivateKey decodes privateKey byte array to crypto.PrivateKey type. +func (h *HttpSignatureAuth) parsePrivateKey(priv []byte) error { pemBlock, _ := pem.Decode(priv) if pemBlock == nil { // No PEM data has been found. return fmt.Errorf("File '%s' does not contain PEM data", h.PrivateKeyPath) } var privKey []byte + var err error if x509.IsEncryptedPEMBlock(pemBlock) { // The PEM data is encrypted. privKey, err = x509.DecryptPEMBlock(pemBlock, []byte(h.Passphrase))