certificates/kms/apiv1/options.go
Herman Slatman 2d85d4c1c1 Add non-TLS server and improve crypto.Decrypter interface
A server without TLS was added to serve the SCEP endpoints. According
to the RFC, SCEP has to be served via HTTP. The `sscep` client, for
example, will stop any URL that does not start with `http://` from
being used, so serving SCEP seems to be the right way to do it.

This commit adds a second server for which no TLS configuration is
configured. A distinct field in the configuration, `insecureAddress`
was added to specify the address for the insecure server.

The SCEP endpoints will also still be served via HTTPS. Some clients
may be able to work with that.

This commit also improves how the crypto.Decrypter interface is
handled for the different types of KMSes supported by step. The
apiv1.Decrypter interface was added. Currently only SoftKMS
implements this interface, providing a crypto.Decrypter required
for SCEP operations.
2021-05-26 16:09:38 -07:00

126 lines
3.4 KiB
Go

package apiv1
import (
"crypto"
"crypto/x509"
"strings"
"github.com/pkg/errors"
)
// KeyManager is the interface implemented by all the KMS.
type KeyManager interface {
GetPublicKey(req *GetPublicKeyRequest) (crypto.PublicKey, error)
CreateKey(req *CreateKeyRequest) (*CreateKeyResponse, error)
CreateSigner(req *CreateSignerRequest) (crypto.Signer, error)
Close() error
}
type Decrypter interface {
CreateDecrypter(req *CreateDecrypterRequest) (crypto.Decrypter, error)
}
// CertificateManager is the interface implemented by the KMS that can load and
// store x509.Certificates.
type CertificateManager interface {
LoadCertificate(req *LoadCertificateRequest) (*x509.Certificate, error)
StoreCertificate(req *StoreCertificateRequest) error
}
// ErrNotImplemented is the type of error returned if an operation is not
// implemented.
type ErrNotImplemented struct {
Message string
}
func (e ErrNotImplemented) Error() string {
if e.Message != "" {
return e.Message
}
return "not implemented"
}
// ErrAlreadyExists is the type of error returned if a key already exists. This
// is currently only implmented on pkcs11.
type ErrAlreadyExists struct {
Message string
}
func (e ErrAlreadyExists) Error() string {
if e.Message != "" {
return e.Message
}
return "key already exists"
}
// Type represents the KMS type used.
type Type string
const (
// DefaultKMS is a KMS implementation using software.
DefaultKMS Type = ""
// SoftKMS is a KMS implementation using software.
SoftKMS Type = "softkms"
// CloudKMS is a KMS implementation using Google's Cloud KMS.
CloudKMS Type = "cloudkms"
// AmazonKMS is a KMS implementation using Amazon AWS KMS.
AmazonKMS Type = "awskms"
// PKCS11 is a KMS implementation using the PKCS11 standard.
PKCS11 Type = "pkcs11"
// YubiKey is a KMS implementation using a YubiKey PIV.
YubiKey Type = "yubikey"
// SSHAgentKMS is a KMS implementation using ssh-agent to access keys.
SSHAgentKMS Type = "sshagentkms"
)
// Options are the KMS options. They represent the kms object in the ca.json.
type Options struct {
// The type of the KMS to use.
Type string `json:"type"`
// Path to the credentials file used in CloudKMS and AmazonKMS.
CredentialsFile string `json:"credentialsFile"`
// URI is based on the PKCS #11 URI Scheme defined in
// https://tools.ietf.org/html/rfc7512 and represents the configuration used
// to connect to the KMS.
//
// Used by: pkcs11
URI string `json:"uri"`
// Pin used to access the PKCS11 module. It can be defined in the URI using
// the pin-value or pin-source properties.
Pin string `json:"pin"`
// ManagementKey used in YubiKeys. Default management key is the hexadecimal
// string 010203040506070801020304050607080102030405060708:
// []byte{
// 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
// 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
// 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
// }
ManagementKey string `json:"managementKey"`
// Region to use in AmazonKMS.
Region string `json:"region"`
// Profile to use in AmazonKMS.
Profile string `json:"profile"`
}
// Validate checks the fields in Options.
func (o *Options) Validate() error {
if o == nil {
return nil
}
switch Type(strings.ToLower(o.Type)) {
case DefaultKMS, SoftKMS: // Go crypto based kms.
case CloudKMS, AmazonKMS, SSHAgentKMS: // Cloud based kms.
case YubiKey, PKCS11: // Hardware based kms.
default:
return errors.Errorf("unsupported kms type %s", o.Type)
}
return nil
}