|
|
@ -8,6 +8,7 @@ import (
|
|
|
|
"crypto/sha256"
|
|
|
|
"crypto/sha256"
|
|
|
|
"crypto/x509"
|
|
|
|
"crypto/x509"
|
|
|
|
"encoding/hex"
|
|
|
|
"encoding/hex"
|
|
|
|
|
|
|
|
"fmt"
|
|
|
|
"log"
|
|
|
|
"log"
|
|
|
|
"net/http"
|
|
|
|
"net/http"
|
|
|
|
"strings"
|
|
|
|
"strings"
|
|
|
@ -447,6 +448,7 @@ func (a *Authority) init() error {
|
|
|
|
return err
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
}
|
|
|
|
a.rootX509Certs = append(a.rootX509Certs, resp.RootCertificate)
|
|
|
|
a.rootX509Certs = append(a.rootX509Certs, resp.RootCertificate)
|
|
|
|
|
|
|
|
a.intermediateX509Certs = append(a.intermediateX509Certs, resp.IntermediateCertificates...)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
@ -695,14 +697,23 @@ func (a *Authority) init() error {
|
|
|
|
options := &scep.Options{
|
|
|
|
options := &scep.Options{
|
|
|
|
Roots: a.rootX509Certs,
|
|
|
|
Roots: a.rootX509Certs,
|
|
|
|
Intermediates: a.intermediateX509Certs,
|
|
|
|
Intermediates: a.intermediateX509Certs,
|
|
|
|
SignerCert: a.intermediateX509Certs[0],
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// intermediate certificates can be empty in RA mode
|
|
|
|
|
|
|
|
if len(a.intermediateX509Certs) > 0 {
|
|
|
|
|
|
|
|
options.SignerCert = a.intermediateX509Certs[0]
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// attempt to create the (default) SCEP signer if the intermediate
|
|
|
|
|
|
|
|
// key is configured.
|
|
|
|
|
|
|
|
if a.config.IntermediateKey != "" {
|
|
|
|
if options.Signer, err = a.keyManager.CreateSigner(&kmsapi.CreateSignerRequest{
|
|
|
|
if options.Signer, err = a.keyManager.CreateSigner(&kmsapi.CreateSignerRequest{
|
|
|
|
SigningKey: a.config.IntermediateKey,
|
|
|
|
SigningKey: a.config.IntermediateKey,
|
|
|
|
Password: a.password,
|
|
|
|
Password: a.password,
|
|
|
|
}); err != nil {
|
|
|
|
}); err != nil {
|
|
|
|
return err
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// TODO(hs): instead of creating the decrypter here, pass the
|
|
|
|
// TODO(hs): instead of creating the decrypter here, pass the
|
|
|
|
// intermediate key + chain down to the SCEP authority,
|
|
|
|
// intermediate key + chain down to the SCEP authority,
|
|
|
|
// and only instantiate it when required there. Is that possible?
|
|
|
|
// and only instantiate it when required there. Is that possible?
|
|
|
@ -711,8 +722,8 @@ func (a *Authority) init() error {
|
|
|
|
// decrypter password too? Right now it needs to be entered multiple
|
|
|
|
// decrypter password too? Right now it needs to be entered multiple
|
|
|
|
// times; I've observed it to be three times maximum, every time
|
|
|
|
// times; I've observed it to be three times maximum, every time
|
|
|
|
// the intermediate key is read.
|
|
|
|
// the intermediate key is read.
|
|
|
|
_, isRSA := options.Signer.Public().(*rsa.PublicKey)
|
|
|
|
_, isRSAKey := options.Signer.Public().(*rsa.PublicKey)
|
|
|
|
if km, ok := a.keyManager.(kmsapi.Decrypter); ok && isRSA {
|
|
|
|
if km, ok := a.keyManager.(kmsapi.Decrypter); ok && isRSAKey {
|
|
|
|
if decrypter, err := km.CreateDecrypter(&kmsapi.CreateDecrypterRequest{
|
|
|
|
if decrypter, err := km.CreateDecrypter(&kmsapi.CreateDecrypterRequest{
|
|
|
|
DecryptionKey: a.config.IntermediateKey,
|
|
|
|
DecryptionKey: a.config.IntermediateKey,
|
|
|
|
Password: a.password,
|
|
|
|
Password: a.password,
|
|
|
@ -723,6 +734,7 @@ func (a *Authority) init() error {
|
|
|
|
options.DecrypterCert = options.Intermediates[0]
|
|
|
|
options.DecrypterCert = options.Intermediates[0]
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
a.scepOptions = options
|
|
|
|
a.scepOptions = options
|
|
|
|
}
|
|
|
|
}
|
|
|
@ -811,6 +823,26 @@ func (a *Authority) init() error {
|
|
|
|
return nil
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
func (a *Authority) Mode() string {
|
|
|
|
|
|
|
|
if a.isRA() {
|
|
|
|
|
|
|
|
return fmt.Sprintf("RA (%s)", casapi.TypeOf(a.x509CAService).Name())
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return "CA" // TODO(hs): more info? I.e. KMS type?
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
func (a *Authority) isRA() bool {
|
|
|
|
|
|
|
|
if a.x509CAService == nil {
|
|
|
|
|
|
|
|
return false
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
switch casapi.TypeOf(a.x509CAService) {
|
|
|
|
|
|
|
|
case casapi.StepCAS, casapi.CloudCAS, casapi.VaultCAS, casapi.ExternalCAS:
|
|
|
|
|
|
|
|
return true
|
|
|
|
|
|
|
|
default:
|
|
|
|
|
|
|
|
return false
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// initLogf is used to log initialization information. The output
|
|
|
|
// initLogf is used to log initialization information. The output
|
|
|
|
// can be disabled by starting the CA with the `--quiet` flag.
|
|
|
|
// can be disabled by starting the CA with the `--quiet` flag.
|
|
|
|
func (a *Authority) initLogf(format string, v ...any) {
|
|
|
|
func (a *Authority) initLogf(format string, v ...any) {
|
|
|
|