-
Notifications
You must be signed in to change notification settings - Fork 0
/
generateIdentityCertificate.go
99 lines (86 loc) · 2.53 KB
/
generateIdentityCertificate.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
package generateCertificate
import (
"context"
"crypto/ecdsa"
"crypto/rand"
"crypto/x509"
"crypto/x509/pkix"
"encoding/asn1"
"encoding/pem"
"fmt"
ocfSigner "github.com/plgd-dev/device/v2/pkg/security/signer"
)
type basicConstraints struct {
CA bool
}
func NewIdentityCSRTemplate(deviceID string) (*x509.CertificateRequest, error) {
subj := pkix.Name{
CommonName: fmt.Sprintf("uuid:%v", deviceID),
}
val, err := asn1.Marshal([]asn1.ObjectIdentifier{{1, 3, 6, 1, 5, 5, 7, 3, 1}, {1, 3, 6, 1, 5, 5, 7, 3, 2}, {1, 3, 6, 1, 4, 1, 44924, 1, 6}})
if err != nil {
return nil, err
}
bcVal, err := asn1.Marshal(basicConstraints{false})
if err != nil {
return nil, err
}
kuVal, err := asn1.Marshal(asn1.BitString{Bytes: []byte{1<<3 | 1<<7}, BitLength: 7}) // x509.KeyUsageDigitalSignature | x509.KeyUsageKeyAgreement
if err != nil {
return nil, err
}
template := x509.CertificateRequest{
Subject: subj,
ExtraExtensions: []pkix.Extension{
{
Id: asn1.ObjectIdentifier{2, 5, 29, 19}, // basic constraints
Value: bcVal,
Critical: false,
},
{
Id: asn1.ObjectIdentifier{2, 5, 29, 15}, // key usage
Value: kuVal,
Critical: false,
},
{
Id: asn1.ObjectIdentifier{2, 5, 29, 37}, // EKU
Value: val,
Critical: false,
},
},
}
return &template, nil
}
// GenerateIdentityCSR creates identity CSR according to configuration.
func GenerateIdentityCSR(cfg Configuration, deviceID string, privateKey *ecdsa.PrivateKey) ([]byte, error) {
template, err := NewIdentityCSRTemplate(deviceID)
if err != nil {
return nil, err
}
signatureAlgorithm, err := cfg.ToSignatureAlgorithm()
if err != nil {
return nil, err
}
subj := cfg.ToPkixName()
subj.CommonName = template.Subject.CommonName
template.Subject = subj
template.SignatureAlgorithm = signatureAlgorithm
csrDER, err := x509.CreateCertificateRequest(rand.Reader, template, privateKey)
if err != nil {
return nil, err
}
return pem.EncodeToMemory(&pem.Block{Type: "CERTIFICATE REQUEST", Bytes: csrDER}), nil
}
func GenerateIdentityCert(cfg Configuration, deviceID string, privateKey *ecdsa.PrivateKey, signerCA []*x509.Certificate, signerCAKey *ecdsa.PrivateKey) ([]byte, error) {
csr, err := GenerateIdentityCSR(cfg, deviceID, privateKey)
if err != nil {
return nil, err
}
notBefore, err := cfg.ToValidFrom()
if err != nil {
return nil, err
}
notAfter := notBefore.Add(cfg.ValidFor)
s := ocfSigner.NewOCFIdentityCertificate(signerCA, signerCAKey, notBefore, notAfter)
return s.Sign(context.Background(), csr)
}