forked from TrueCloudLab/certificates
Remove x509 template from API
This commit is contained in:
parent
311c9d767b
commit
a6d50f2fa0
2 changed files with 56 additions and 56 deletions
|
@ -2,19 +2,14 @@ package api
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"crypto"
|
|
||||||
"crypto/sha1"
|
|
||||||
"crypto/x509"
|
"crypto/x509"
|
||||||
"encoding/base64"
|
"encoding/base64"
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"math/big"
|
|
||||||
"math/rand"
|
|
||||||
"net/http"
|
"net/http"
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
|
||||||
|
|
||||||
"github.com/smallstep/certificates/acme"
|
"github.com/smallstep/certificates/acme"
|
||||||
"github.com/smallstep/certificates/api"
|
"github.com/smallstep/certificates/api"
|
||||||
|
@ -252,53 +247,29 @@ func (h *Handler) PKIOperation(w http.ResponseWriter, r *http.Request, scepReque
|
||||||
|
|
||||||
ctx := r.Context()
|
ctx := r.Context()
|
||||||
|
|
||||||
msg, err := microscep.ParsePKIMessage(scepRequest.Message)
|
microMsg, err := microscep.ParsePKIMessage(scepRequest.Message)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
pkimsg := &scep.PKIMessage{
|
msg := &scep.PKIMessage{
|
||||||
TransactionID: msg.TransactionID,
|
TransactionID: microMsg.TransactionID,
|
||||||
MessageType: msg.MessageType,
|
MessageType: microMsg.MessageType,
|
||||||
SenderNonce: msg.SenderNonce,
|
SenderNonce: microMsg.SenderNonce,
|
||||||
Raw: msg.Raw,
|
Raw: microMsg.Raw,
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := h.Auth.DecryptPKIEnvelope(ctx, pkimsg); err != nil {
|
if err := h.Auth.DecryptPKIEnvelope(ctx, msg); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
if pkimsg.MessageType == microscep.PKCSReq {
|
if msg.MessageType == microscep.PKCSReq {
|
||||||
// TODO: CSR validation, like challenge password
|
// TODO: CSR validation, like challenge password
|
||||||
}
|
}
|
||||||
|
|
||||||
csr := pkimsg.CSRReqMessage.CSR
|
csr := msg.CSRReqMessage.CSR
|
||||||
subjectKeyID, err := createKeyIdentifier(csr.PublicKey)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
serial := big.NewInt(int64(rand.Int63())) // TODO: serial logic?
|
certRep, err := h.Auth.SignCSR(ctx, csr, msg)
|
||||||
|
|
||||||
days := 40
|
|
||||||
|
|
||||||
// TODO: use information from provisioner, like claims
|
|
||||||
template := &x509.Certificate{
|
|
||||||
SerialNumber: serial,
|
|
||||||
Subject: csr.Subject,
|
|
||||||
NotBefore: time.Now().Add(-600).UTC(),
|
|
||||||
NotAfter: time.Now().AddDate(0, 0, days).UTC(),
|
|
||||||
SubjectKeyId: subjectKeyID,
|
|
||||||
KeyUsage: x509.KeyUsageDigitalSignature,
|
|
||||||
ExtKeyUsage: []x509.ExtKeyUsage{
|
|
||||||
x509.ExtKeyUsageClientAuth,
|
|
||||||
},
|
|
||||||
SignatureAlgorithm: csr.SignatureAlgorithm,
|
|
||||||
EmailAddresses: csr.EmailAddresses,
|
|
||||||
DNSNames: csr.DNSNames,
|
|
||||||
}
|
|
||||||
|
|
||||||
certRep, err := h.Auth.SignCSR(ctx, pkimsg, template)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -323,20 +294,6 @@ func certName(cert *x509.Certificate) string {
|
||||||
return string(cert.Signature)
|
return string(cert.Signature)
|
||||||
}
|
}
|
||||||
|
|
||||||
// createKeyIdentifier creates an identifier for public keys
|
|
||||||
// according to the first method in RFC5280 section 4.2.1.2.
|
|
||||||
func createKeyIdentifier(pub crypto.PublicKey) ([]byte, error) {
|
|
||||||
|
|
||||||
keyBytes, err := x509.MarshalPKIXPublicKey(pub)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
id := sha1.Sum(keyBytes)
|
|
||||||
|
|
||||||
return id[:], nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func formatCapabilities(caps []string) []byte {
|
func formatCapabilities(caps []string) []byte {
|
||||||
return []byte(strings.Join(caps, "\r\n"))
|
return []byte(strings.Join(caps, "\r\n"))
|
||||||
}
|
}
|
||||||
|
@ -354,6 +311,7 @@ func writeSCEPResponse(w http.ResponseWriter, response SCEPResponse) error {
|
||||||
|
|
||||||
var (
|
var (
|
||||||
// TODO: check the default capabilities; https://tools.ietf.org/html/rfc8894#section-3.5.2
|
// TODO: check the default capabilities; https://tools.ietf.org/html/rfc8894#section-3.5.2
|
||||||
|
// TODO: move capabilities to Authority or Provisioner, so that they can be configured?
|
||||||
defaultCapabilities = []string{
|
defaultCapabilities = []string{
|
||||||
"Renewal",
|
"Renewal",
|
||||||
"SHA-1",
|
"SHA-1",
|
||||||
|
|
|
@ -3,6 +3,8 @@ package scep
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"context"
|
"context"
|
||||||
|
"crypto"
|
||||||
|
"crypto/sha1"
|
||||||
"crypto/x509"
|
"crypto/x509"
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
@ -52,7 +54,7 @@ type Interface interface {
|
||||||
|
|
||||||
GetCACertificates() ([]*x509.Certificate, error)
|
GetCACertificates() ([]*x509.Certificate, error)
|
||||||
DecryptPKIEnvelope(ctx context.Context, msg *PKIMessage) error
|
DecryptPKIEnvelope(ctx context.Context, msg *PKIMessage) error
|
||||||
SignCSR(ctx context.Context, msg *PKIMessage, template *x509.Certificate) (*PKIMessage, error)
|
SignCSR(ctx context.Context, csr *x509.CertificateRequest, msg *PKIMessage) (*PKIMessage, error)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Authority is the layer that handles all SCEP interactions.
|
// Authority is the layer that handles all SCEP interactions.
|
||||||
|
@ -221,7 +223,8 @@ func (a *Authority) DecryptPKIEnvelope(ctx context.Context, msg *PKIMessage) err
|
||||||
// SignCSR creates an x509.Certificate based on a CSR template and Cert Authority credentials
|
// SignCSR creates an x509.Certificate based on a CSR template and Cert Authority credentials
|
||||||
// returns a new PKIMessage with CertRep data
|
// returns a new PKIMessage with CertRep data
|
||||||
//func (msg *PKIMessage) SignCSR(crtAuth *x509.Certificate, keyAuth *rsa.PrivateKey, template *x509.Certificate) (*PKIMessage, error) {
|
//func (msg *PKIMessage) SignCSR(crtAuth *x509.Certificate, keyAuth *rsa.PrivateKey, template *x509.Certificate) (*PKIMessage, error) {
|
||||||
func (a *Authority) SignCSR(ctx context.Context, msg *PKIMessage, template *x509.Certificate) (*PKIMessage, error) {
|
//func (a *Authority) SignCSR(ctx context.Context, msg *PKIMessage, template *x509.Certificate) (*PKIMessage, error) {
|
||||||
|
func (a *Authority) SignCSR(ctx context.Context, csr *x509.CertificateRequest, msg *PKIMessage) (*PKIMessage, error) {
|
||||||
|
|
||||||
// TODO: intermediate storage of the request? In SCEP it's possible to request a csr/certificate
|
// TODO: intermediate storage of the request? In SCEP it's possible to request a csr/certificate
|
||||||
// to be signed, which can be performed asynchronously / out-of-band. In that case a client can
|
// to be signed, which can be performed asynchronously / out-of-band. In that case a client can
|
||||||
|
@ -238,9 +241,32 @@ func (a *Authority) SignCSR(ctx context.Context, msg *PKIMessage, template *x509
|
||||||
if err := a.DecryptPKIEnvelope(ctx, msg); err != nil {
|
if err := a.DecryptPKIEnvelope(ctx, msg); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
csr = msg.CSRReqMessage.CSR
|
||||||
}
|
}
|
||||||
|
|
||||||
csr := msg.CSRReqMessage.CSR
|
// subjectKeyID, err := createKeyIdentifier(csr.PublicKey)
|
||||||
|
// if err != nil {
|
||||||
|
// return nil, err
|
||||||
|
// }
|
||||||
|
|
||||||
|
// serial := big.NewInt(int64(rand.Int63())) // TODO: serial logic?
|
||||||
|
// days := 40 // TODO: days
|
||||||
|
|
||||||
|
// // TODO: use information from provisioner, like claims
|
||||||
|
// template := &x509.Certificate{
|
||||||
|
// SerialNumber: serial,
|
||||||
|
// Subject: csr.Subject,
|
||||||
|
// NotBefore: time.Now().Add(-600).UTC(),
|
||||||
|
// NotAfter: time.Now().AddDate(0, 0, days).UTC(),
|
||||||
|
// SubjectKeyId: subjectKeyID,
|
||||||
|
// KeyUsage: x509.KeyUsageDigitalSignature,
|
||||||
|
// ExtKeyUsage: []x509.ExtKeyUsage{
|
||||||
|
// x509.ExtKeyUsageClientAuth,
|
||||||
|
// },
|
||||||
|
// SignatureAlgorithm: csr.SignatureAlgorithm,
|
||||||
|
// EmailAddresses: csr.EmailAddresses,
|
||||||
|
// DNSNames: csr.DNSNames,
|
||||||
|
// }
|
||||||
|
|
||||||
// Template data
|
// Template data
|
||||||
data := x509util.NewTemplateData()
|
data := x509util.NewTemplateData()
|
||||||
|
@ -278,6 +304,8 @@ func (a *Authority) SignCSR(ctx context.Context, msg *PKIMessage, template *x509
|
||||||
// fmt.Println(fmt.Sprintf("%T", cert))
|
// fmt.Println(fmt.Sprintf("%T", cert))
|
||||||
// fmt.Println(cert.Issuer)
|
// fmt.Println(cert.Issuer)
|
||||||
// fmt.Println(cert.Subject)
|
// fmt.Println(cert.Subject)
|
||||||
|
// fmt.Println(cert.SerialNumber)
|
||||||
|
// fmt.Println(string(cert.SubjectKeyId))
|
||||||
|
|
||||||
// create a degenerate cert structure
|
// create a degenerate cert structure
|
||||||
deg, err := DegenerateCertificates([]*x509.Certificate{cert})
|
deg, err := DegenerateCertificates([]*x509.Certificate{cert})
|
||||||
|
@ -365,6 +393,20 @@ func DegenerateCertificates(certs []*x509.Certificate) ([]byte, error) {
|
||||||
return degenerate, nil
|
return degenerate, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// createKeyIdentifier creates an identifier for public keys
|
||||||
|
// according to the first method in RFC5280 section 4.2.1.2.
|
||||||
|
func createKeyIdentifier(pub crypto.PublicKey) ([]byte, error) {
|
||||||
|
|
||||||
|
keyBytes, err := x509.MarshalPKIXPublicKey(pub)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
id := sha1.Sum(keyBytes)
|
||||||
|
|
||||||
|
return id[:], nil
|
||||||
|
}
|
||||||
|
|
||||||
// Interface guards
|
// Interface guards
|
||||||
var (
|
var (
|
||||||
_ Interface = (*Authority)(nil)
|
_ Interface = (*Authority)(nil)
|
||||||
|
|
Loading…
Reference in a new issue