/
extension.go
73 lines (65 loc) · 1.9 KB
/
extension.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
package provisioner
import (
"crypto/x509"
"crypto/x509/pkix"
"encoding/asn1"
)
var (
// StepOIDRoot is the root OID for smallstep.
StepOIDRoot = asn1.ObjectIdentifier{1, 3, 6, 1, 4, 1, 37476, 9000, 64}
// StepOIDProvisioner is the OID for the provisioner extension.
StepOIDProvisioner = append(asn1.ObjectIdentifier(nil), append(StepOIDRoot, 1)...)
)
// Extension is the Go representation of the provisioner extension.
type Extension struct {
Type Type
Name string
CredentialID string
KeyValuePairs []string
}
type extensionASN1 struct {
Type int
Name []byte
CredentialID []byte
KeyValuePairs []string `asn1:"optional,omitempty"`
}
// Marshal marshals the extension using encoding/asn1.
func (e *Extension) Marshal() ([]byte, error) {
return asn1.Marshal(extensionASN1{
Type: int(e.Type),
Name: []byte(e.Name),
CredentialID: []byte(e.CredentialID),
KeyValuePairs: e.KeyValuePairs,
})
}
// ToExtension returns the pkix.Extension representation of the provisioner
// extension.
func (e *Extension) ToExtension() (pkix.Extension, error) {
b, err := e.Marshal()
if err != nil {
return pkix.Extension{}, err
}
return pkix.Extension{
Id: StepOIDProvisioner,
Value: b,
}, nil
}
// GetProvisionerExtension goes through all the certificate extensions and
// returns the provisioner extension (1.3.6.1.4.1.37476.9000.64.1).
func GetProvisionerExtension(cert *x509.Certificate) (*Extension, bool) {
for _, e := range cert.Extensions {
if e.Id.Equal(StepOIDProvisioner) {
var provisioner extensionASN1
if _, err := asn1.Unmarshal(e.Value, &provisioner); err != nil {
return nil, false
}
return &Extension{
Type: Type(provisioner.Type),
Name: string(provisioner.Name),
CredentialID: string(provisioner.CredentialID),
KeyValuePairs: provisioner.KeyValuePairs,
}, true
}
}
return nil, false
}