I've never used cloud SDK's before so no terraform files. To make this work I had to use the Go 1.11 runtime as the go 1.13 runtime did not have the correct environment variables set. I also had to use the key with PKCS#1 v1.5 padding the PSS Padding did not work.
90 lines
1.7 KiB
Go
90 lines
1.7 KiB
Go
package signer
|
|
|
|
import (
|
|
"context"
|
|
"crypto"
|
|
"crypto/x509"
|
|
"encoding/pem"
|
|
"fmt"
|
|
"io"
|
|
|
|
kms "cloud.google.com/go/kms/apiv1"
|
|
kmspb "google.golang.org/genproto/googleapis/cloud/kms/v1"
|
|
)
|
|
|
|
// KMSSigner a GCP asymetric crypto signer
|
|
type GCPSigner struct {
|
|
crypto.Signer
|
|
ctx context.Context
|
|
client *kms.KeyManagementClient
|
|
key string
|
|
}
|
|
|
|
// NewGCPSSigner return a new instsance of NewGCPSSigner
|
|
func NewGCPSSigner(key string) *GCPSigner {
|
|
ctx := context.Background()
|
|
c, err := kms.NewKeyManagementClient(ctx)
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
|
|
return &GCPSigner{
|
|
ctx: ctx,
|
|
client: c,
|
|
key: key,
|
|
}
|
|
}
|
|
|
|
// Public returns the public key from KMS
|
|
func (s *GCPSigner) Public() crypto.PublicKey {
|
|
|
|
response, err := s.client.GetPublicKey(s.ctx, &kmspb.GetPublicKeyRequest{
|
|
Name: s.key,
|
|
})
|
|
if err != nil {
|
|
fmt.Printf(err.Error())
|
|
return nil
|
|
}
|
|
|
|
pubPem := response.GetPem()
|
|
// pubAlg := response.GetAlgorithm()
|
|
pemBlock, _ := pem.Decode([]byte(pubPem))
|
|
|
|
publicKey, err := x509.ParsePKIXPublicKey(pemBlock.Bytes)
|
|
if err != nil {
|
|
fmt.Printf(err.Error())
|
|
return nil
|
|
}
|
|
|
|
return publicKey
|
|
}
|
|
|
|
// Sign a digest with the private key in KMS
|
|
func (s *GCPSigner) Sign(rand io.Reader, digest []byte, opts crypto.SignerOpts) ([]byte, error) {
|
|
var dig *kmspb.Digest = &kmspb.Digest{}
|
|
switch opts {
|
|
case crypto.SHA256:
|
|
dig.Digest = &kmspb.Digest_Sha256{
|
|
Sha256: digest,
|
|
}
|
|
case crypto.SHA384:
|
|
dig.Digest = &kmspb.Digest_Sha384{
|
|
Sha384: digest,
|
|
}
|
|
case crypto.SHA512:
|
|
dig.Digest = &kmspb.Digest_Sha512{
|
|
Sha512: digest,
|
|
}
|
|
}
|
|
|
|
response, err := s.client.AsymmetricSign(s.ctx, &kmspb.AsymmetricSignRequest{
|
|
Name: s.key,
|
|
Digest: dig,
|
|
})
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
return response.GetSignature(), nil
|
|
}
|