-
Notifications
You must be signed in to change notification settings - Fork 43
/
certificate.go
141 lines (125 loc) · 4.13 KB
/
certificate.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
134
135
136
137
138
139
140
141
package models
import (
"bytes"
"crypto/sha1"
"crypto/tls"
"crypto/x509"
"encoding/hex"
"encoding/pem"
"fmt"
"net"
"net/url"
"reflect"
"strings"
"time"
"github.com/baetyl/baetyl-go/v2/errors"
specV1 "github.com/baetyl/baetyl-go/v2/spec/v1"
"github.com/jinzhu/copier"
)
// AltNames contains the domain names and IP addresses that will be added
// to the API Server's x509 certificate SubAltNames field. The values will
// be passed directly to the x509.Certificate object.
type AltNames struct {
DNSNames []string `json:"dnsNames,omitempty"`
IPs []net.IP `json:"ips,omitempty"`
Emails []string `json:"emails,omitempty"`
URIs []*url.URL `json:"uris,omitempty"`
}
// PEMCredential holds a certificate, private key pem data
type PEMCredential struct {
CertPEM []byte
KeyPEM []byte
CertId string
}
// CertStorage contains certName and keyName which can be used to
// storage certificate and private key pem data to secret.
type CertStorage struct {
CertName string
KeyName string
}
// Certificate Certificate
type Certificate struct {
Name string `json:"name,omitempty" validate:"omitempty,resourceName"`
Namespace string `json:"namespace,omitempty"`
SignatureAlgorithm string `json:"signatureAlgorithm,omitempty"`
EffectiveTime string `json:"effectiveTime,omitempty"`
ExpiredTime string `json:"expiredTime,omitempty"`
SerialNumber string `json:"serialNumber,omitempty"`
Issuer string `json:"issuer,omitempty"`
FingerPrint string `json:"fingerPrint,omitempty"`
Data CertificateDataItem `json:"data,omitempty"`
CreationTimestamp time.Time `json:"createTime,omitempty"`
UpdateTimestamp time.Time `json:"updateTime,omitempty"`
Description string `json:"description"`
Version string `json:"version,omitempty"`
}
type CertificateDataItem struct {
Key string `json:"key,omitempty"`
Certificate string `json:"certificate,omitempty"`
}
// CertificateList Certificate List
type CertificateList struct {
Total int `json:"total"`
ListOptions *ListOptions `json:"listOptions"`
Items []Certificate `json:"items"`
}
func (r *Certificate) Equal(target *Certificate) bool {
return reflect.DeepEqual(r.Data, target.Data) &&
reflect.DeepEqual(r.Description, target.Description)
}
func (r *Certificate) ToSecret() *specV1.Secret {
res := &specV1.Secret{
Labels: map[string]string{
specV1.SecretLabel: specV1.SecretCertificate,
},
}
err := copier.Copy(res, r)
if err != nil {
panic(fmt.Sprintf("copier exception: %s", err.Error()))
}
res.Data = map[string][]byte{
"key": []byte(r.Data.Key),
"certificate": []byte(r.Data.Certificate),
"signatureAlgorithm": []byte(r.SignatureAlgorithm),
"effectiveTime": []byte(r.EffectiveTime),
"expiredTime": []byte(r.ExpiredTime),
"serialNumber": []byte(r.SerialNumber),
"issuer": []byte(r.Issuer),
"fingerPrint": []byte(r.FingerPrint),
}
return res
}
func (r *Certificate) ParseCertInfo() error {
_, err := tls.X509KeyPair([]byte(r.Data.Certificate), []byte(r.Data.Key))
if err != nil {
return err
}
var block *pem.Block
rest := []byte(r.Data.Certificate)
block, rest = pem.Decode(rest)
if block == nil {
return errors.New("failed to find cert that matched private key")
}
cert, err := x509.ParseCertificate(block.Bytes)
if err != nil {
return errors.Errorf("failed to parse certificate, err: %s", err)
}
r.FingerPrint = fingerprint(block.Bytes)
r.Issuer = cert.Issuer.CommonName
r.ExpiredTime = cert.NotAfter.String()
r.EffectiveTime = cert.NotBefore.String()
r.SerialNumber = cert.SerialNumber.String()
r.SignatureAlgorithm = cert.SignatureAlgorithm.String()
return nil
}
func fingerprint(data []byte) string {
digest := sha1.Sum(data)
buf := &bytes.Buffer{}
for i := 0; i < len(digest); i++ {
if buf.Len() > 0 {
buf.WriteString(":")
}
buf.WriteString(strings.ToUpper(hex.EncodeToString(digest[i : i+1])))
}
return buf.String()
}