-
Notifications
You must be signed in to change notification settings - Fork 7
/
store.go
133 lines (117 loc) · 3.73 KB
/
store.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
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
package crypto
import (
"crypto/x509"
"encoding/pem"
"fmt"
"os"
"path/filepath"
"strings"
"github.com/aws/aws-sdk-go-v2/service/acmpca"
"github.com/coinbase/baseca/internal/types"
)
func WriteKeyToFile(service string, privateKey types.AsymmetricKey) error {
var pemBlock *pem.Block
directoryPath := filepath.Join(types.SubordinatePath, service)
filePath := filepath.Join(directoryPath, _subordinatePrivateKey)
if !strings.HasPrefix(filePath, types.SubordinatePath) {
return fmt.Errorf("unsafe file input, write private key")
}
switch k := privateKey.KeyPair().(type) {
case *RSA:
pkBytes := x509.MarshalPKCS1PrivateKey(k.PrivateKey)
pemBlock = &pem.Block{
Type: "RSA PRIVATE KEY",
Bytes: pkBytes,
}
case *ECDSA:
pkBytes, err := x509.MarshalECPrivateKey(k.PrivateKey)
if err != nil {
return err
}
pemBlock = &pem.Block{
Type: "EC PRIVATE KEY",
Bytes: pkBytes,
}
default:
return fmt.Errorf("private key format not supported")
}
if err := os.WriteFile(filePath, pem.EncodeToMemory(pemBlock), os.ModePerm); err != nil {
return err
}
return nil
}
func WriteSubordinateCaParameters(service string, caCertificate *x509.Certificate, ca types.CertificateParameters, pca *acmpca.GetCertificateAuthorityCertificateOutput) error {
var err error
directoryPath := filepath.Join(types.SubordinatePath, service)
// Subordinate CA
filePath := filepath.Join(directoryPath, _subordinateCertificate)
pemBlock := encodeCertificateFromx509(caCertificate)
if err := os.WriteFile(filePath, *pemBlock, os.ModePerm); err != nil {
return err
}
if !ca.RootCa {
filePath = filepath.Join(directoryPath, _intermediateCertificate)
pemBlock, err = encodeCertificateFromString(pca.Certificate)
if err != nil {
return fmt.Errorf("error encoding intermediate ca")
}
if err := os.WriteFile(filePath, *pemBlock, os.ModePerm); err != nil {
return fmt.Errorf("error writing intermediate ca to filesystem")
}
filePath = filepath.Join(directoryPath, _rootCertificate)
pemBlock, err = encodeCertificateFromString(pca.CertificateChain)
if err != nil {
return fmt.Errorf("error encoding root ca")
}
if err := os.WriteFile(filePath, *pemBlock, os.ModePerm); err != nil {
return fmt.Errorf("error writing root ca to filesystem")
}
} else {
filePath = filepath.Join(directoryPath, _rootCertificate)
pemBlock, err = encodeCertificateFromString(pca.Certificate)
if err != nil {
return fmt.Errorf("error encoding root ca")
}
if err := os.WriteFile(filePath, *pemBlock, os.ModePerm); err != nil {
return fmt.Errorf("error writing root ca to filesystem")
}
}
// Certificate Authority Serial Number
ca_serial_number := fmt.Sprintf("%x", caCertificate.SerialNumber)
filePath = filepath.Join(directoryPath, _subordinateSerialNumber)
err = writeFileToSystem(filePath, []byte(ca_serial_number))
if err != nil {
return fmt.Errorf("error writing serial number to filesystem")
}
// Intermediate ACM Private CA ARN
filePath = filepath.Join(directoryPath, _certificateAuthorityArn)
err = writeFileToSystem(filePath, []byte(ca.CaArn))
if err != nil {
return fmt.Errorf("error writing ca arn to filesystem")
}
return nil
}
func encodeCertificateFromString(certificate *string) (*[]byte, error) {
c := []byte(*certificate)
block, _ := pem.Decode(c)
x509Certificate, err := x509.ParseCertificate(block.Bytes)
if err != nil {
return nil, fmt.Errorf("invalid x509 certificate format")
}
pemBlock := pem.EncodeToMemory(
&pem.Block{
Type: "CERTIFICATE",
Bytes: x509Certificate.Raw,
},
)
return &pemBlock, nil
}
func encodeCertificateFromx509(certificate *x509.Certificate) *[]byte {
pemBlock := pem.EncodeToMemory(
&pem.Block{
Type: "CERTIFICATE",
Bytes: certificate.Raw,
},
)
return &pemBlock
}