Code refactoring for bpa operator
[icn.git] / cmd / bpa-operator / vendor / k8s.io / client-go / util / cert / pem.go
1 /*
2 Copyright 2014 The Kubernetes Authors.
3
4 Licensed under the Apache License, Version 2.0 (the "License");
5 you may not use this file except in compliance with the License.
6 You may obtain a copy of the License at
7
8     http://www.apache.org/licenses/LICENSE-2.0
9
10 Unless required by applicable law or agreed to in writing, software
11 distributed under the License is distributed on an "AS IS" BASIS,
12 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 See the License for the specific language governing permissions and
14 limitations under the License.
15 */
16
17 package cert
18
19 import (
20         "crypto/ecdsa"
21         "crypto/rsa"
22         "crypto/x509"
23         "encoding/pem"
24         "errors"
25         "fmt"
26 )
27
28 const (
29         // ECPrivateKeyBlockType is a possible value for pem.Block.Type.
30         ECPrivateKeyBlockType = "EC PRIVATE KEY"
31         // RSAPrivateKeyBlockType is a possible value for pem.Block.Type.
32         RSAPrivateKeyBlockType = "RSA PRIVATE KEY"
33         // PrivateKeyBlockType is a possible value for pem.Block.Type.
34         PrivateKeyBlockType = "PRIVATE KEY"
35         // PublicKeyBlockType is a possible value for pem.Block.Type.
36         PublicKeyBlockType = "PUBLIC KEY"
37         // CertificateBlockType is a possible value for pem.Block.Type.
38         CertificateBlockType = "CERTIFICATE"
39         // CertificateRequestBlockType is a possible value for pem.Block.Type.
40         CertificateRequestBlockType = "CERTIFICATE REQUEST"
41 )
42
43 // EncodePublicKeyPEM returns PEM-encoded public data
44 func EncodePublicKeyPEM(key *rsa.PublicKey) ([]byte, error) {
45         der, err := x509.MarshalPKIXPublicKey(key)
46         if err != nil {
47                 return []byte{}, err
48         }
49         block := pem.Block{
50                 Type:  PublicKeyBlockType,
51                 Bytes: der,
52         }
53         return pem.EncodeToMemory(&block), nil
54 }
55
56 // EncodePrivateKeyPEM returns PEM-encoded private key data
57 func EncodePrivateKeyPEM(key *rsa.PrivateKey) []byte {
58         block := pem.Block{
59                 Type:  RSAPrivateKeyBlockType,
60                 Bytes: x509.MarshalPKCS1PrivateKey(key),
61         }
62         return pem.EncodeToMemory(&block)
63 }
64
65 // EncodeCertPEM returns PEM-endcoded certificate data
66 func EncodeCertPEM(cert *x509.Certificate) []byte {
67         block := pem.Block{
68                 Type:  CertificateBlockType,
69                 Bytes: cert.Raw,
70         }
71         return pem.EncodeToMemory(&block)
72 }
73
74 // ParsePrivateKeyPEM returns a private key parsed from a PEM block in the supplied data.
75 // Recognizes PEM blocks for "EC PRIVATE KEY", "RSA PRIVATE KEY", or "PRIVATE KEY"
76 func ParsePrivateKeyPEM(keyData []byte) (interface{}, error) {
77         var privateKeyPemBlock *pem.Block
78         for {
79                 privateKeyPemBlock, keyData = pem.Decode(keyData)
80                 if privateKeyPemBlock == nil {
81                         break
82                 }
83
84                 switch privateKeyPemBlock.Type {
85                 case ECPrivateKeyBlockType:
86                         // ECDSA Private Key in ASN.1 format
87                         if key, err := x509.ParseECPrivateKey(privateKeyPemBlock.Bytes); err == nil {
88                                 return key, nil
89                         }
90                 case RSAPrivateKeyBlockType:
91                         // RSA Private Key in PKCS#1 format
92                         if key, err := x509.ParsePKCS1PrivateKey(privateKeyPemBlock.Bytes); err == nil {
93                                 return key, nil
94                         }
95                 case PrivateKeyBlockType:
96                         // RSA or ECDSA Private Key in unencrypted PKCS#8 format
97                         if key, err := x509.ParsePKCS8PrivateKey(privateKeyPemBlock.Bytes); err == nil {
98                                 return key, nil
99                         }
100                 }
101
102                 // tolerate non-key PEM blocks for compatibility with things like "EC PARAMETERS" blocks
103                 // originally, only the first PEM block was parsed and expected to be a key block
104         }
105
106         // we read all the PEM blocks and didn't recognize one
107         return nil, fmt.Errorf("data does not contain a valid RSA or ECDSA private key")
108 }
109
110 // ParsePublicKeysPEM is a helper function for reading an array of rsa.PublicKey or ecdsa.PublicKey from a PEM-encoded byte array.
111 // Reads public keys from both public and private key files.
112 func ParsePublicKeysPEM(keyData []byte) ([]interface{}, error) {
113         var block *pem.Block
114         keys := []interface{}{}
115         for {
116                 // read the next block
117                 block, keyData = pem.Decode(keyData)
118                 if block == nil {
119                         break
120                 }
121
122                 // test block against parsing functions
123                 if privateKey, err := parseRSAPrivateKey(block.Bytes); err == nil {
124                         keys = append(keys, &privateKey.PublicKey)
125                         continue
126                 }
127                 if publicKey, err := parseRSAPublicKey(block.Bytes); err == nil {
128                         keys = append(keys, publicKey)
129                         continue
130                 }
131                 if privateKey, err := parseECPrivateKey(block.Bytes); err == nil {
132                         keys = append(keys, &privateKey.PublicKey)
133                         continue
134                 }
135                 if publicKey, err := parseECPublicKey(block.Bytes); err == nil {
136                         keys = append(keys, publicKey)
137                         continue
138                 }
139
140                 // tolerate non-key PEM blocks for backwards compatibility
141                 // originally, only the first PEM block was parsed and expected to be a key block
142         }
143
144         if len(keys) == 0 {
145                 return nil, fmt.Errorf("data does not contain any valid RSA or ECDSA public keys")
146         }
147         return keys, nil
148 }
149
150 // ParseCertsPEM returns the x509.Certificates contained in the given PEM-encoded byte array
151 // Returns an error if a certificate could not be parsed, or if the data does not contain any certificates
152 func ParseCertsPEM(pemCerts []byte) ([]*x509.Certificate, error) {
153         ok := false
154         certs := []*x509.Certificate{}
155         for len(pemCerts) > 0 {
156                 var block *pem.Block
157                 block, pemCerts = pem.Decode(pemCerts)
158                 if block == nil {
159                         break
160                 }
161                 // Only use PEM "CERTIFICATE" blocks without extra headers
162                 if block.Type != CertificateBlockType || len(block.Headers) != 0 {
163                         continue
164                 }
165
166                 cert, err := x509.ParseCertificate(block.Bytes)
167                 if err != nil {
168                         return certs, err
169                 }
170
171                 certs = append(certs, cert)
172                 ok = true
173         }
174
175         if !ok {
176                 return certs, errors.New("data does not contain any valid RSA or ECDSA certificates")
177         }
178         return certs, nil
179 }
180
181 // parseRSAPublicKey parses a single RSA public key from the provided data
182 func parseRSAPublicKey(data []byte) (*rsa.PublicKey, error) {
183         var err error
184
185         // Parse the key
186         var parsedKey interface{}
187         if parsedKey, err = x509.ParsePKIXPublicKey(data); err != nil {
188                 if cert, err := x509.ParseCertificate(data); err == nil {
189                         parsedKey = cert.PublicKey
190                 } else {
191                         return nil, err
192                 }
193         }
194
195         // Test if parsed key is an RSA Public Key
196         var pubKey *rsa.PublicKey
197         var ok bool
198         if pubKey, ok = parsedKey.(*rsa.PublicKey); !ok {
199                 return nil, fmt.Errorf("data doesn't contain valid RSA Public Key")
200         }
201
202         return pubKey, nil
203 }
204
205 // parseRSAPrivateKey parses a single RSA private key from the provided data
206 func parseRSAPrivateKey(data []byte) (*rsa.PrivateKey, error) {
207         var err error
208
209         // Parse the key
210         var parsedKey interface{}
211         if parsedKey, err = x509.ParsePKCS1PrivateKey(data); err != nil {
212                 if parsedKey, err = x509.ParsePKCS8PrivateKey(data); err != nil {
213                         return nil, err
214                 }
215         }
216
217         // Test if parsed key is an RSA Private Key
218         var privKey *rsa.PrivateKey
219         var ok bool
220         if privKey, ok = parsedKey.(*rsa.PrivateKey); !ok {
221                 return nil, fmt.Errorf("data doesn't contain valid RSA Private Key")
222         }
223
224         return privKey, nil
225 }
226
227 // parseECPublicKey parses a single ECDSA public key from the provided data
228 func parseECPublicKey(data []byte) (*ecdsa.PublicKey, error) {
229         var err error
230
231         // Parse the key
232         var parsedKey interface{}
233         if parsedKey, err = x509.ParsePKIXPublicKey(data); err != nil {
234                 if cert, err := x509.ParseCertificate(data); err == nil {
235                         parsedKey = cert.PublicKey
236                 } else {
237                         return nil, err
238                 }
239         }
240
241         // Test if parsed key is an ECDSA Public Key
242         var pubKey *ecdsa.PublicKey
243         var ok bool
244         if pubKey, ok = parsedKey.(*ecdsa.PublicKey); !ok {
245                 return nil, fmt.Errorf("data doesn't contain valid ECDSA Public Key")
246         }
247
248         return pubKey, nil
249 }
250
251 // parseECPrivateKey parses a single ECDSA private key from the provided data
252 func parseECPrivateKey(data []byte) (*ecdsa.PrivateKey, error) {
253         var err error
254
255         // Parse the key
256         var parsedKey interface{}
257         if parsedKey, err = x509.ParseECPrivateKey(data); err != nil {
258                 return nil, err
259         }
260
261         // Test if parsed key is an ECDSA Private Key
262         var privKey *ecdsa.PrivateKey
263         var ok bool
264         if privKey, ok = parsedKey.(*ecdsa.PrivateKey); !ok {
265                 return nil, fmt.Errorf("data doesn't contain valid ECDSA Private Key")
266         }
267
268         return privKey, nil
269 }