/
csrsigner.go
44 lines (37 loc) · 1.21 KB
/
csrsigner.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
package scepserver
import (
"crypto/subtle"
"crypto/x509"
"errors"
"github.com/inverse-inc/scep/scep"
)
// CSRSigner is a handler for CSR signing by the CA/RA
//
// SignCSR should take the CSR in the CSRReqMessage and return a
// Certificate signed by the CA.
type CSRSigner interface {
SignCSR(*scep.CSRReqMessage) (*x509.Certificate, error)
}
// CSRSignerFunc is an adapter for CSR signing by the CA/RA
type CSRSignerFunc func(*scep.CSRReqMessage) (*x509.Certificate, error)
// SignCSR calls f(m)
func (f CSRSignerFunc) SignCSR(m *scep.CSRReqMessage) (*x509.Certificate, error) {
return f(m)
}
// NopCSRSigner does nothing
func NopCSRSigner() CSRSignerFunc {
return func(m *scep.CSRReqMessage) (*x509.Certificate, error) {
return nil, nil
}
}
// ChallengeMiddleware wraps next in a CSRSigner that validates the challenge from the CSR
func ChallengeMiddleware(challenge string, next CSRSigner) CSRSignerFunc {
challengeBytes := []byte(challenge)
return func(m *scep.CSRReqMessage) (*x509.Certificate, error) {
// TODO: compare challenge only for PKCSReq?
if subtle.ConstantTimeCompare(challengeBytes, []byte(m.ChallengePassword)) != 1 {
return nil, errors.New("invalid challenge")
}
return next.SignCSR(m)
}
}