@@ -191,33 +191,55 @@ func (c Certificate) collectStats(report *statsReportCollector) error {
191
191
192
192
// CertificateFromPEM creates a fresh certificate based on a string containing
193
193
// pem blocks fort the private key and x509 certificate.
194
- func CertificateFromPEM (pems string ) (* Certificate , error ) {
195
- // decode & parse the certificate
196
- block , more := pem .Decode ([]byte (pems ))
197
- if block == nil || block .Type != "CERTIFICATE" {
198
- return nil , errCertificatePEMFormatError
199
- }
200
- certBytes := make ([]byte , base64 .StdEncoding .DecodedLen (len (block .Bytes )))
201
- n , err := base64 .StdEncoding .Decode (certBytes , block .Bytes )
202
- if err != nil {
203
- return nil , fmt .Errorf ("failed to decode ceritifcate: %w" , err )
204
- }
205
- cert , err := x509 .ParseCertificate (certBytes [:n ])
206
- if err != nil {
207
- return nil , fmt .Errorf ("failed parsing ceritifcate: %w" , err )
208
- }
209
- // decode & parse the private key
210
- block , _ = pem .Decode (more )
211
- if block == nil || block .Type != "PRIVATE KEY" {
212
- return nil , errCertificatePEMFormatError
194
+ func CertificateFromPEM (pems string ) (* Certificate , error ) { //nolint: cyclop
195
+ var cert * x509.Certificate
196
+ var privateKey crypto.PrivateKey
197
+
198
+ var block * pem.Block
199
+ more := []byte (pems )
200
+ for {
201
+ var err error
202
+ block , more = pem .Decode (more )
203
+ if block == nil {
204
+ break
205
+ }
206
+
207
+ // decode & parse the certificate
208
+ switch block .Type {
209
+ case "CERTIFICATE" :
210
+ if cert != nil {
211
+ return nil , errCertificatePEMMultipleCert
212
+ }
213
+ cert , err = x509 .ParseCertificate (block .Bytes )
214
+ // If parsing failed using block.Bytes, then parse the bytes as base64 and try again
215
+ if err != nil {
216
+ var n int
217
+ certBytes := make ([]byte , base64 .StdEncoding .DecodedLen (len (block .Bytes )))
218
+ n , err = base64 .StdEncoding .Decode (certBytes , block .Bytes )
219
+ if err == nil {
220
+ cert , err = x509 .ParseCertificate (certBytes [:n ])
221
+ }
222
+ }
223
+ case "PRIVATE KEY" :
224
+ if privateKey != nil {
225
+ return nil , errCertificatePEMMultiplePriv
226
+ }
227
+ privateKey , err = x509 .ParsePKCS8PrivateKey (block .Bytes )
228
+ }
229
+
230
+ // Report errors from parsing either the private key or the certificate
231
+ if err != nil {
232
+ return nil , fmt .Errorf ("failed to decode %s: %w" , block .Type , err )
233
+ }
213
234
}
214
- privateKey , err := x509 . ParsePKCS8PrivateKey ( block . Bytes )
215
- if err ! = nil {
216
- return nil , fmt . Errorf ( "unable to parse private key: %w" , err )
235
+
236
+ if cert == nil || privateKey = = nil {
237
+ return nil , errCertificatePEMMissing
217
238
}
218
- x := CertificateFromX509 (privateKey , cert )
219
239
220
- return & x , nil
240
+ ret := CertificateFromX509 (privateKey , cert )
241
+
242
+ return & ret , nil
221
243
}
222
244
223
245
// PEM returns the certificate encoded as two pem block: once for the X509
0 commit comments