From 3ade92f8d5d11aeac0c87878cb86b3bde6da3c81 Mon Sep 17 00:00:00 2001 From: Herman Slatman Date: Fri, 22 Sep 2023 11:10:22 +0200 Subject: [PATCH] Support both a decrypter key URI as well as PEM --- api/api.go | 3 +- api/models/scep.go | 3 +- authority/provisioner/scep.go | 66 +++++++++++++++++++++++++++-------- go.mod | 10 +++--- go.sum | 20 +++++------ 5 files changed, 71 insertions(+), 31 deletions(-) diff --git a/api/api.go b/api/api.go index ea0a1899..8b950c2a 100644 --- a/api/api.go +++ b/api/api.go @@ -246,7 +246,8 @@ func scepFromProvisioner(p *provisioner.SCEP) *models.SCEP { ExcludeIntermediate: p.ExcludeIntermediate, MinimumPublicKeyLength: p.MinimumPublicKeyLength, DecrypterCertificate: redacted, - DecrypterKey: redacted, + DecrypterKeyPEM: redacted, + DecrypterKeyURI: redacted, DecrypterKeyPassword: redacted, EncryptionAlgorithmIdentifier: p.EncryptionAlgorithmIdentifier, Options: p.Options, diff --git a/api/models/scep.go b/api/models/scep.go index a9cec1e0..5de7ecf5 100644 --- a/api/models/scep.go +++ b/api/models/scep.go @@ -26,7 +26,8 @@ type SCEP struct { ExcludeIntermediate bool `json:"excludeIntermediate,omitempty"` MinimumPublicKeyLength int `json:"minimumPublicKeyLength,omitempty"` DecrypterCertificate string `json:"decrypterCertificate"` - DecrypterKey string `json:"decrypterKey"` + DecrypterKeyPEM string `json:"decrypterKeyPEM"` + DecrypterKeyURI string `json:"decrypterKey"` DecrypterKeyPassword string `json:"decrypterKeyPassword"` EncryptionAlgorithmIdentifier int `json:"encryptionAlgorithmIdentifier,omitempty"` Options *provisioner.Options `json:"options,omitempty"` diff --git a/authority/provisioner/scep.go b/authority/provisioner/scep.go index 6f81a4d7..676bc338 100644 --- a/authority/provisioner/scep.go +++ b/authority/provisioner/scep.go @@ -14,6 +14,7 @@ import ( "github.com/pkg/errors" "go.step.sm/crypto/kms" + "go.step.sm/crypto/kms/apiv1" kmsapi "go.step.sm/crypto/kms/apiv1" "go.step.sm/crypto/kms/uri" "go.step.sm/linkedca" @@ -45,8 +46,9 @@ type SCEP struct { // TODO(hs): also support a separate signer configuration? DecrypterCertificate []byte `json:"decrypterCertificate"` - DecrypterKey string `json:"decrypterKey"` - DecrypterKeyPassword string `json:"decrypterKeyPassword"` + DecrypterKeyPEM []byte `json:"decrypterKeyPEM"` + DecrypterKeyURI string `json:"decrypterKey"` + DecrypterKeyPassword []byte `json:"decrypterKeyPassword"` // Numerical identifier for the ContentEncryptionAlgorithm as defined in github.com/mozilla-services/pkcs7 // at https://github.com/mozilla-services/pkcs7/blob/33d05740a3526e382af6395d3513e73d4e66d1cb/encrypt.go#L63 @@ -201,21 +203,57 @@ func (s *SCEP) Init(config Config) (err error) { s.GetOptions().GetWebhooks(), ) - if decryptionKey := s.DecrypterKey; decryptionKey != "" { - u, err := uri.Parse(s.DecrypterKey) + // parse the decrypter key PEM contents if available + if decryptionKeyPEM := s.DecrypterKeyPEM; len(decryptionKeyPEM) > 0 { + // try reading the PEM for validation + block, rest := pem.Decode(decryptionKeyPEM) + if len(rest) > 0 { + return errors.New("failed parsing decrypter key: trailing data") + } + if block == nil { + return errors.New("failed parsing decrypter key: no PEM block found") + } + opts := kms.Options{ + Type: apiv1.SoftKMS, + } + if s.keyManager, err = kms.New(context.Background(), opts); err != nil { + return fmt.Errorf("failed initializing kms: %w", err) + } + kmsDecrypter, ok := s.keyManager.(kmsapi.Decrypter) + if !ok { + return fmt.Errorf("%q is not a kmsapi.Decrypter", opts.Type) + } + if s.decrypter, err = kmsDecrypter.CreateDecrypter(&kmsapi.CreateDecrypterRequest{ + DecryptionKeyPEM: decryptionKeyPEM, + Password: s.DecrypterKeyPassword, + PasswordPrompter: kmsapi.NonInteractivePasswordPrompter, + }); err != nil { + return fmt.Errorf("failed creating decrypter: %w", err) + } + if s.signer, err = s.keyManager.CreateSigner(&kmsapi.CreateSignerRequest{ + SigningKeyPEM: decryptionKeyPEM, // TODO(hs): support distinct signer key in the future? + Password: s.DecrypterKeyPassword, + PasswordPrompter: kmsapi.NonInteractivePasswordPrompter, + }); err != nil { + return fmt.Errorf("failed creating signer: %w", err) + } + } + + if decryptionKeyURI := s.DecrypterKeyURI; len(decryptionKeyURI) > 0 { + u, err := uri.Parse(s.DecrypterKeyURI) if err != nil { return fmt.Errorf("failed parsing decrypter key: %w", err) } - var kmsType string + var kmsType apiv1.Type switch { case u.Scheme != "": - kmsType = u.Scheme + kmsType = kms.Type(u.Scheme) default: - kmsType = "softkms" + kmsType = apiv1.SoftKMS } opts := kms.Options{ - Type: kms.Type(kmsType), - URI: s.DecrypterKey, + Type: kmsType, + URI: s.DecrypterKeyURI, } if s.keyManager, err = kms.New(context.Background(), opts); err != nil { return fmt.Errorf("failed initializing kms: %w", err) @@ -225,18 +263,18 @@ func (s *SCEP) Init(config Config) (err error) { return fmt.Errorf("%q is not a kmsapi.Decrypter", opts.Type) } if kmsType != "softkms" { // TODO(hs): this should likely become more transparent? - decryptionKey = u.Opaque + decryptionKeyURI = u.Opaque } if s.decrypter, err = kmsDecrypter.CreateDecrypter(&kmsapi.CreateDecrypterRequest{ - DecryptionKey: decryptionKey, - Password: []byte(s.DecrypterKeyPassword), + DecryptionKey: decryptionKeyURI, + Password: s.DecrypterKeyPassword, PasswordPrompter: kmsapi.NonInteractivePasswordPrompter, }); err != nil { return fmt.Errorf("failed creating decrypter: %w", err) } if s.signer, err = s.keyManager.CreateSigner(&kmsapi.CreateSignerRequest{ - SigningKey: decryptionKey, // TODO(hs): support distinct signer key in the future? - Password: []byte(s.DecrypterKeyPassword), + SigningKey: decryptionKeyURI, // TODO(hs): support distinct signer key in the future? + Password: s.DecrypterKeyPassword, PasswordPrompter: kmsapi.NonInteractivePasswordPrompter, }); err != nil { return fmt.Errorf("failed creating signer: %w", err) diff --git a/go.mod b/go.mod index 1d91fef1..5010ec03 100644 --- a/go.mod +++ b/go.mod @@ -32,18 +32,18 @@ require ( go.mozilla.org/pkcs7 v0.0.0-20210826202110-33d05740a352 go.step.sm/cli-utils v0.8.0 go.step.sm/crypto v0.35.1 - go.step.sm/linkedca v0.20.1-0.20230904124610-b6e003ee7e36 + go.step.sm/linkedca v0.20.1-0.20230922085851-78fa28647893 golang.org/x/crypto v0.13.0 golang.org/x/exp v0.0.0-20230310171629-522b1b587ee0 golang.org/x/net v0.15.0 google.golang.org/api v0.141.0 - google.golang.org/grpc v1.58.1 + google.golang.org/grpc v1.58.2 google.golang.org/protobuf v1.31.0 gopkg.in/square/go-jose.v2 v2.6.0 ) require ( - cloud.google.com/go v0.110.6 // indirect + cloud.google.com/go v0.110.7 // indirect cloud.google.com/go/compute v1.23.0 // indirect cloud.google.com/go/compute/metadata v0.2.3 // indirect cloud.google.com/go/iam v1.1.1 // indirect @@ -135,9 +135,9 @@ require ( golang.org/x/text v0.13.0 // indirect golang.org/x/time v0.3.0 // indirect google.golang.org/appengine v1.6.7 // indirect - google.golang.org/genproto v0.0.0-20230803162519-f966b187b2e5 // indirect + google.golang.org/genproto v0.0.0-20230913181813-007df8e322eb // indirect google.golang.org/genproto/googleapis/api v0.0.0-20230803162519-f966b187b2e5 // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20230911183012-2d3300fd4832 // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20230920204549-e6e6cdab5c13 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect ) diff --git a/go.sum b/go.sum index 4bb2c876..b1abf28e 100644 --- a/go.sum +++ b/go.sum @@ -1,7 +1,7 @@ cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= -cloud.google.com/go v0.110.6 h1:8uYAkj3YHTP/1iwReuHPxLSbdcyc+dSBbzFMrVwDR6Q= -cloud.google.com/go v0.110.6/go.mod h1:+EYjdK8e5RME/VY/qLCAtuyALQ9q67dvuum8i+H5xsI= +cloud.google.com/go v0.110.7 h1:rJyC7nWRg2jWGZ4wSJ5nY65GTdYJkg0cd/uXb+ACI6o= +cloud.google.com/go v0.110.7/go.mod h1:+EYjdK8e5RME/VY/qLCAtuyALQ9q67dvuum8i+H5xsI= cloud.google.com/go/compute v1.23.0 h1:tP41Zoavr8ptEqaW6j+LQOnyBBhO7OkOMAGrgLopTwY= cloud.google.com/go/compute v1.23.0/go.mod h1:4tCnrn48xsqlwSAiLf1HXMQk8CONslYbdiEZc9FEIbM= cloud.google.com/go/compute/metadata v0.2.3 h1:mg4jlk7mCAj6xXp9UJ4fjI9VUI5rubuGBW5aJ7UnBMY= @@ -615,8 +615,8 @@ go.step.sm/cli-utils v0.8.0 h1:b/Tc1/m3YuQq+u3ghTFP7Dz5zUekZj6GUmd5pCvkEXQ= go.step.sm/cli-utils v0.8.0/go.mod h1:S77aISrC0pKuflqiDfxxJlUbiXcAanyJ4POOnzFSxD4= go.step.sm/crypto v0.35.1 h1:QAZZ7Q8xaM4TdungGSAYw/zxpyH4fMYTkfaXVV9H7pY= go.step.sm/crypto v0.35.1/go.mod h1:vn8Vkx/Mbqgoe7AG8btC0qZ995Udm3e+JySuDS1LCJA= -go.step.sm/linkedca v0.20.1-0.20230904124610-b6e003ee7e36 h1:F8CJdanbISusu7jX/ETOAVtPuLfcdTNl+wO22DB+y/8= -go.step.sm/linkedca v0.20.1-0.20230904124610-b6e003ee7e36/go.mod h1:QLWVNpZKKYukwVwQTfK22n5WmDs5c/xc4vakguT/THg= +go.step.sm/linkedca v0.20.1-0.20230922085851-78fa28647893 h1:PmvYAEYTBPXyWMZAYNrj9eiaj3Bj0qfDEnyiyQDsWcU= +go.step.sm/linkedca v0.20.1-0.20230922085851-78fa28647893/go.mod h1:Vaq4+Umtjh7DLFI1KuIxeo598vfBzgSYZUjgVJ7Syxw= go.uber.org/atomic v1.3.2/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= go.uber.org/atomic v1.5.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ= @@ -801,12 +801,12 @@ google.golang.org/genproto v0.0.0-20190425155659-357c62f0e4bb/go.mod h1:VzzqZJRn google.golang.org/genproto v0.0.0-20190530194941-fb225487d101/go.mod h1:z3L6/3dTEVtUr6QSP8miRzeRqwQOioJ9I66odjN4I7s= google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo= -google.golang.org/genproto v0.0.0-20230803162519-f966b187b2e5 h1:L6iMMGrtzgHsWofoFcihmDEMYeDR9KN/ThbPWGrh++g= -google.golang.org/genproto v0.0.0-20230803162519-f966b187b2e5/go.mod h1:oH/ZOT02u4kWEp7oYBGYFFkCdKS/uYR9Z7+0/xuuFp8= +google.golang.org/genproto v0.0.0-20230913181813-007df8e322eb h1:XFBgcDwm7irdHTbz4Zk2h7Mh+eis4nfJEFQFYzJzuIA= +google.golang.org/genproto v0.0.0-20230913181813-007df8e322eb/go.mod h1:yZTlhN0tQnXo3h00fuXNCxJdLdIdnVFVBaRJ5LWBbw4= google.golang.org/genproto/googleapis/api v0.0.0-20230803162519-f966b187b2e5 h1:nIgk/EEq3/YlnmVVXVnm14rC2oxgs1o0ong4sD/rd44= google.golang.org/genproto/googleapis/api v0.0.0-20230803162519-f966b187b2e5/go.mod h1:5DZzOUPCLYL3mNkQ0ms0F3EuUNZ7py1Bqeq6sxzI7/Q= -google.golang.org/genproto/googleapis/rpc v0.0.0-20230911183012-2d3300fd4832 h1:o4LtQxebKIJ4vkzyhtD2rfUNZ20Zf0ik5YVP5E7G7VE= -google.golang.org/genproto/googleapis/rpc v0.0.0-20230911183012-2d3300fd4832/go.mod h1:+Bk1OCOj40wS2hwAMA+aCW9ypzm63QTBBHp6lQ3p+9M= +google.golang.org/genproto/googleapis/rpc v0.0.0-20230920204549-e6e6cdab5c13 h1:N3bU/SQDCDyD6R528GJ/PwW9KjYcJA3dgyH+MovAkIM= +google.golang.org/genproto/googleapis/rpc v0.0.0-20230920204549-e6e6cdab5c13/go.mod h1:KSqppvjFjtoCI+KGd4PELB0qLNxdJHRGqRI09mB6pQA= google.golang.org/grpc v1.17.0/go.mod h1:6QZJwpn2B+Zp71q/5VxRsJ6NXXVCE5NRUHRo+f3cWCs= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= google.golang.org/grpc v1.20.0/go.mod h1:chYK+tFQF0nDUGJgXMSgLCQk3phJEuONr2DCgLDdAQM= @@ -819,8 +819,8 @@ google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQ google.golang.org/grpc v1.26.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= google.golang.org/grpc v1.33.2/go.mod h1:JMHMWHQWaTccqQQlmk3MJZS+GWXOdAesneDmEnv2fbc= -google.golang.org/grpc v1.58.1 h1:OL+Vz23DTtrrldqHK49FUOPHyY75rvFqJfXC84NYW58= -google.golang.org/grpc v1.58.1/go.mod h1:tgX3ZQDlNJGU96V6yHh1T/JeoBQ2TXdr43YbYSsCJk0= +google.golang.org/grpc v1.58.2 h1:SXUpjxeVF3FKrTYQI4f4KvbGD5u2xccdYdurwowix5I= +google.golang.org/grpc v1.58.2/go.mod h1:tgX3ZQDlNJGU96V6yHh1T/JeoBQ2TXdr43YbYSsCJk0= google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM=