1 package tls
2
3 import (
4 "bytes"
5 "crypto/ecdsa"
6 "crypto/rsa"
7 "crypto/x509"
8 "encoding/pem"
9 "errors"
10 "fmt"
11 "reflect"
12 )
13
14
15
16
17
18 func EncodeCertificatesPEM(crts ...*x509.Certificate) string {
19 buf := bytes.Buffer{}
20 for _, c := range crts {
21 encode(&buf, &pem.Block{Type: "CERTIFICATE", Bytes: c.Raw})
22 }
23 return buf.String()
24 }
25
26
27 func EncodePrivateKeyPEM(k *ecdsa.PrivateKey) ([]byte, error) {
28 der, err := x509.MarshalECPrivateKey(k)
29 if err != nil {
30 return nil, err
31 }
32
33 return pem.EncodeToMemory(&pem.Block{Type: "EC PRIVATE KEY", Bytes: der}), nil
34 }
35
36
37 func EncodePrivateKeyP8(k *ecdsa.PrivateKey) []byte {
38 p8, err := x509.MarshalPKCS8PrivateKey(k)
39 if err != nil {
40 panic("ECDSA keys must be encodeable as PKCS8")
41 }
42 return p8
43 }
44
45 func encode(buf *bytes.Buffer, blk *pem.Block) {
46 if err := pem.Encode(buf, blk); err != nil {
47 panic("encoding to memory must not fail")
48 }
49 }
50
51
52
53
54 func DecodePEMKey(txt string) (GenericPrivateKey, error) {
55 block, _ := pem.Decode([]byte(txt))
56 if block == nil {
57 return nil, errors.New("not PEM-encoded")
58 }
59 switch block.Type {
60 case "EC PRIVATE KEY":
61 k, err := x509.ParseECPrivateKey(block.Bytes)
62 if err != nil {
63 return nil, err
64 }
65 return privateKeyEC{k}, nil
66 case "RSA PRIVATE KEY":
67 k, err := x509.ParsePKCS1PrivateKey(block.Bytes)
68 if err != nil {
69 return nil, err
70 }
71 return privateKeyRSA{k}, nil
72 case "PRIVATE KEY":
73 k, err := x509.ParsePKCS8PrivateKey(block.Bytes)
74 if err != nil {
75 return nil, err
76 }
77 if ec, ok := k.(*ecdsa.PrivateKey); ok {
78 return privateKeyEC{ec}, nil
79 }
80 if rsa, ok := k.(*rsa.PrivateKey); ok {
81 return privateKeyRSA{rsa}, nil
82 }
83 return nil, fmt.Errorf(
84 "unsupported PKCS#8 encoded private key type: '%s', linkerd2 only supports ECDSA and RSA private keys",
85 reflect.TypeOf(k))
86 default:
87 return nil, fmt.Errorf("unsupported block type: '%s'", block.Type)
88 }
89 }
90
91
92 func DecodePEMCertificates(txt string) (certs []*x509.Certificate, err error) {
93 buf := []byte(txt)
94 for len(buf) > 0 {
95 var c *x509.Certificate
96 c, buf, err = decodeCertificatePEM(buf)
97 if err != nil {
98 return
99 }
100 if c == nil {
101 continue
102 }
103 certs = append(certs, c)
104 }
105 return
106 }
107
108
109 func CertificatesToPool(certs []*x509.Certificate) *x509.CertPool {
110 pool := x509.NewCertPool()
111 for _, c := range certs {
112 pool.AddCert(c)
113 }
114 return pool
115 }
116
117
118 func DecodePEMCertPool(txt string) (*x509.CertPool, error) {
119 certs, err := DecodePEMCertificates(txt)
120 if err != nil {
121 return nil, err
122 }
123 if len(certs) == 0 {
124 return nil, errors.New("no certificates found")
125 }
126
127 return CertificatesToPool(certs), nil
128 }
129
130 func decodeCertificatePEM(crtb []byte) (*x509.Certificate, []byte, error) {
131 block, crtb := pem.Decode(crtb)
132 if block == nil {
133 return nil, crtb, errors.New("not a PEM certificate")
134 }
135 if block.Type != "CERTIFICATE" {
136 return nil, nil, nil
137 }
138 c, err := x509.ParseCertificate(block.Bytes)
139 return c, crtb, err
140 }
141
View as plain text