/
reg.go
95 lines (83 loc) · 2.49 KB
/
reg.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
package reg
import (
"context"
stdlibx509 "crypto/x509"
"encoding/pem"
"fmt"
"io/ioutil"
"log"
"os"
"path"
"time"
"github.com/autonomy/talos/src/initramfs/cmd/trustd/proto"
"github.com/autonomy/talos/src/initramfs/pkg/crypto/x509"
"github.com/autonomy/talos/src/initramfs/pkg/userdata"
"google.golang.org/grpc"
)
// Registrator is the concrete type that implements the factory.Registrator and
// proto.TrustdServer interfaces.
type Registrator struct {
Data *userdata.OSSecurity
}
// Register implements the factory.Registrator interface.
func (r *Registrator) Register(s *grpc.Server) {
proto.RegisterTrustdServer(s, r)
}
// Certificate implements the proto.TrustdServer interface.
func (r *Registrator) Certificate(ctx context.Context, in *proto.CertificateRequest) (resp *proto.CertificateResponse, err error) {
// TODO: Verify that the request is coming from the IP addresss declared in
// the CSR.
signed, err := GenerateCertificateFromCSR(r.Data.CA.Crt, r.Data.CA.Key, in.Csr)
if err != nil {
return
}
resp = &proto.CertificateResponse{
Bytes: signed.X509CertificatePEM,
}
return resp, nil
}
// WriteFile implements the proto.TrustdServer interface.
func (r *Registrator) WriteFile(ctx context.Context, in *proto.WriteFileRequest) (resp *proto.WriteFileResponse, err error) {
if err = os.MkdirAll(path.Dir(in.Path), os.ModeDir); err != nil {
return
}
if err = ioutil.WriteFile(in.Path, in.Data, os.FileMode(in.Perm)); err != nil {
return
}
log.Printf("wrote file to disk: %s", in.Path)
resp = &proto.WriteFileResponse{}
return resp, nil
}
// GenerateCertificateFromCSR creates a signed certificate using the provided
// certificate, key, and CSR.
func GenerateCertificateFromCSR(crt, key, csr []byte) (signed *x509.Certificate, err error) {
caPemBlock, _ := pem.Decode(crt)
if caPemBlock == nil {
return nil, fmt.Errorf("decode PEM: %v", err)
}
caCrt, err := stdlibx509.ParseCertificate(caPemBlock.Bytes)
if err != nil {
return
}
keyPemBlock, _ := pem.Decode(key)
if keyPemBlock == nil {
return nil, fmt.Errorf("decode PEM: %v", err)
}
caKey, err := stdlibx509.ParseECPrivateKey(keyPemBlock.Bytes)
if err != nil {
return
}
csrPemBlock, _ := pem.Decode(csr)
if csrPemBlock == nil {
return
}
request, err := stdlibx509.ParseCertificateRequest(csrPemBlock.Bytes)
if err != nil {
return
}
signed, err = x509.NewCertificateFromCSR(caCrt, caKey, request, x509.NotAfter(time.Now().Add(time.Duration(8760)*time.Hour)))
if err != nil {
return
}
return signed, nil
}