-
Notifications
You must be signed in to change notification settings - Fork 2
/
sign_user_csr.go
98 lines (79 loc) · 2.57 KB
/
sign_user_csr.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
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
package req
import (
"crypto/rand"
"crypto/x509"
"crypto/x509/pkix"
"encoding/pem"
"errors"
"fmt"
"math/big"
"net/http"
"strings"
"time"
"github.com/dpb587/ssoca/certauth"
apierr "github.com/dpb587/ssoca/server/api/errors"
"github.com/dpb587/ssoca/server/service/req"
svc "github.com/dpb587/ssoca/service/openvpn"
svcapi "github.com/dpb587/ssoca/service/openvpn/api"
bosherr "github.com/cloudfoundry/bosh-utils/errors"
)
type SignUserCSR struct {
CertAuth certauth.Provider
Validity time.Duration
BaseProfile string
req.WithAuthenticationRequired
}
var _ req.RouteHandler = SignUserCSR{}
func (h SignUserCSR) Route() string {
return "sign-user-csr"
}
func (h SignUserCSR) Execute(request req.Request) error {
payload := svcapi.SignUserCSRRequest{}
err := request.ReadPayload(&payload)
if err != nil {
return err
}
response := svcapi.SignUserCSRResponse{}
csrPEM, _ := pem.Decode([]byte(payload.CSR))
if csrPEM == nil {
return apierr.NewError(errors.New("Decoding CSR"), http.StatusBadRequest, "Failed to decode certificate signing request")
}
csr, err := x509.ParseCertificateRequest(csrPEM.Bytes)
if err != nil {
return apierr.NewError(bosherr.WrapError(err, "Parsing CSR"), http.StatusBadRequest, "Failed to parse certificate signing request")
}
serialNumber, err := rand.Int(rand.Reader, new(big.Int).Lsh(big.NewInt(1), 128))
if err != nil {
return bosherr.WrapError(err, "Generating serial number")
}
now := time.Now()
template := x509.Certificate{
SerialNumber: serialNumber,
Subject: pkix.Name{
Country: []string{"US"},
Organization: []string{fmt.Sprintf("ssoca/%s", svc.Service{}.Version())},
CommonName: request.AuthToken.ID,
},
EmailAddresses: csr.EmailAddresses,
NotBefore: now.Add(-5 * time.Second).UTC(),
NotAfter: now.Add(h.Validity).UTC(),
KeyUsage: x509.KeyUsageKeyEncipherment | x509.KeyUsageDigitalSignature,
ExtKeyUsage: []x509.ExtKeyUsage{x509.ExtKeyUsageClientAuth},
BasicConstraintsValid: true,
}
certificatePEM, err := h.CertAuth.SignCertificate(&template, csr.PublicKey, request.LoggerContext)
if err != nil {
return bosherr.WrapError(err, "Signing certificate")
}
response.Certificate = strings.TrimSpace(string(certificatePEM))
caCertificate, err := h.CertAuth.GetCertificatePEM()
if err != nil {
return bosherr.WrapError(err, "Loading CA certificate")
}
response.Profile = fmt.Sprintf(
"%s\n<ca>\n%s\n</ca>\n",
strings.TrimSpace(h.BaseProfile),
strings.TrimSpace(caCertificate),
)
return request.WritePayload(response)
}