You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
smallstep-certificates/authority/provisioner/scep.go

117 lines
2.6 KiB
Go

package provisioner
import (
"crypto/rsa"
"crypto/x509"
"encoding/pem"
"fmt"
"io/ioutil"
"github.com/pkg/errors"
)
// SCEP is the SCEP provisioner type, an entity that can authorize the
// SCEP provisioning flow
type SCEP struct {
*base
Type string `json:"type"`
Name string `json:"name"`
// ForceCN bool `json:"forceCN,omitempty"`
// Claims *Claims `json:"claims,omitempty"`
// Options *Options `json:"options,omitempty"`
// claimer *Claimer
IntermediateCert string
SigningKey string
CACertificates []*x509.Certificate
}
// GetID returns the provisioner unique identifier.
func (s SCEP) GetID() string {
return "scep/" + s.Name
}
// GetName returns the name of the provisioner.
func (s *SCEP) GetName() string {
return s.Name
}
// GetType returns the type of provisioner.
func (s *SCEP) GetType() Type {
return TypeSCEP
}
// GetEncryptedKey returns the base provisioner encrypted key if it's defined.
func (s *SCEP) GetEncryptedKey() (string, string, bool) {
return "", "", false
}
// GetTokenID returns the identifier of the token.
func (s *SCEP) GetTokenID(ott string) (string, error) {
return "", errors.New("scep provisioner does not implement GetTokenID")
}
// GetCACertificates returns the CA certificate chain
// TODO: this should come from the authority instead?
func (s *SCEP) GetCACertificates() []*x509.Certificate {
pemtxt, _ := ioutil.ReadFile(s.IntermediateCert) // TODO: move reading key to init? That's probably safer.
block, _ := pem.Decode([]byte(pemtxt))
cert, err := x509.ParseCertificate(block.Bytes)
if err != nil {
fmt.Println(err)
}
// TODO: return chain? I'm not sure if the client understands it correctly
return []*x509.Certificate{cert}
}
func (s *SCEP) GetSigningKey() *rsa.PrivateKey {
keyBytes, err := ioutil.ReadFile(s.SigningKey)
if err != nil {
return nil
}
block, _ := pem.Decode([]byte(keyBytes))
if block == nil {
return nil
}
key, err := x509.ParsePKCS1PrivateKey(block.Bytes)
if err != nil {
fmt.Println(err)
return nil
}
return key
}
// Init initializes and validates the fields of a JWK type.
func (s *SCEP) Init(config Config) (err error) {
switch {
case s.Type == "":
return errors.New("provisioner type cannot be empty")
case s.Name == "":
return errors.New("provisioner name cannot be empty")
}
// // Update claims with global ones
// if p.claimer, err = NewClaimer(p.Claims, config.Claims); err != nil {
// return err
// }
s.IntermediateCert = config.IntermediateCert
s.SigningKey = config.SigningKey
s.CACertificates = config.CACertificates
return err
}
// Interface guards
var (
_ Interface = (*SCEP)(nil)
//_ scep.Provisioner = (*SCEP)(nil)
)