-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathcertificate.go
134 lines (110 loc) · 3.24 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
// Copyright 2020 Canonical Ltd.
// Licensed under the AGPLv3, see LICENCE file for details.
package pki
import (
"crypto/rand"
"crypto/sha1"
"crypto/x509"
"crypto/x509/pkix"
"math/big"
"github.com/juju/errors"
"github.com/juju/utils/v2"
)
// CSRToCertificate copies all fields from a CertificateRequest into a new x509
// Certificate. No policy check is performed this is just a straight 1 to 1
// copy.
func CSRToCertificate(csr *x509.CertificateRequest) *x509.Certificate {
cert := &x509.Certificate{}
cert.Subject = csr.Subject
cert.Extensions = csr.Extensions
cert.ExtraExtensions = csr.ExtraExtensions
cert.DNSNames = csr.DNSNames
cert.EmailAddresses = csr.EmailAddresses
cert.IPAddresses = csr.IPAddresses
cert.URIs = csr.URIs
return cert
}
func assetTagCertificate(cert *x509.Certificate) error {
uuid, err := utils.NewUUID()
if err != nil {
return errors.Annotate(err, "failed to generate new certificate uuid")
}
serialNumber, err := newSerialNumber()
if err != nil {
return errors.Annotate(err,
"failed to generate new certificate serial number")
}
cert.SerialNumber = serialNumber
cert.Subject.SerialNumber = uuid.String()
return nil
}
func bigIntHash(n *big.Int) []byte {
h := sha1.New()
h.Write(n.Bytes())
return h.Sum(nil)
}
// MakeX509NameFromDefaults constructs a new x509 name from the merging of a
// default and request name. Fields not set in the request name
// will be copied from the default name.
func MakeX509NameFromDefaults(template, request *pkix.Name) pkix.Name {
rval := pkix.Name{}
if template == nil {
template = &pkix.Name{}
}
rval.Country = request.Country
if len(rval.Country) == 0 {
rval.Country = template.Country
}
rval.Organization = request.Organization
if len(rval.Organization) == 0 {
rval.Organization = template.Organization
}
rval.OrganizationalUnit = request.OrganizationalUnit
if len(rval.OrganizationalUnit) == 0 {
rval.OrganizationalUnit = template.OrganizationalUnit
}
rval.Locality = request.Locality
if len(rval.Locality) == 0 {
rval.Locality = template.Locality
}
rval.Province = request.Province
if len(rval.Province) == 0 {
rval.Province = template.Province
}
rval.StreetAddress = request.StreetAddress
if len(rval.StreetAddress) == 0 {
rval.StreetAddress = template.StreetAddress
}
rval.PostalCode = request.PostalCode
if len(rval.PostalCode) == 0 {
rval.PostalCode = template.PostalCode
}
rval.SerialNumber = request.SerialNumber
if rval.SerialNumber == "" {
rval.SerialNumber = template.SerialNumber
}
rval.CommonName = request.CommonName
if rval.CommonName == "" {
rval.CommonName = template.CommonName
}
rval.Names = request.Names
if len(rval.Names) == 0 {
rval.Names = template.Names
}
rval.ExtraNames = request.ExtraNames
if len(rval.ExtraNames) == 0 {
rval.ExtraNames = template.ExtraNames
}
return rval
}
// newSerialNumber returns a new random serial number suitable for use in a
// certificate.
func newSerialNumber() (*big.Int, error) {
// A serial number can be up to 20 octets in size.
// https://tools.ietf.org/html/rfc5280#section-4.1.2.2
n, err := rand.Int(rand.Reader, new(big.Int).Lsh(big.NewInt(1), 8*20))
if err != nil {
return nil, errors.Annotatef(err, "failed to generate serial number")
}
return n, nil
}