@@ -231,52 +231,93 @@ func ParseCertificate(pemData []byte) (*x509.Certificate, error) {
231231 return nil , errors .New ("error parsing certificate: no certificate found" )
232232}
233233
234- // ParseCertificateBundle extracts all the certificates in the given data.
235- func ParseCertificateBundle (pemData []byte ) ([]* x509.Certificate , error ) {
236- var block * pem.Block
237- var certs []* x509.Certificate
238- for len (pemData ) > 0 {
239- block , pemData = pem .Decode (pemData )
240- if block == nil {
241- return nil , errors .New ("error decoding pem block" )
234+ // ParseCertificateBundle returns a list of *x509.Certificate parsed from
235+ // the given bytes.
236+ //
237+ // - supports PEM and DER certificate formats
238+ // - If a DER-formatted file is given only one certificate will be returned.
239+ func ParseCertificateBundle (data []byte ) ([]* x509.Certificate , error ) {
240+ var err error
241+
242+ // PEM format
243+ if bytes .Contains (data , PEMBlockHeader ) {
244+ var block * pem.Block
245+ var bundle []* x509.Certificate
246+ for len (data ) > 0 {
247+ block , data = pem .Decode (data )
248+ if block == nil {
249+ break
250+ }
251+ if block .Type != "CERTIFICATE" || len (block .Headers ) != 0 {
252+ continue
253+ }
254+ var crt * x509.Certificate
255+ crt , err = x509 .ParseCertificate (block .Bytes )
256+ if err != nil {
257+ return nil , & InvalidPEMError {
258+ Err : err ,
259+ Type : PEMTypeCertificate ,
260+ }
261+ }
262+ bundle = append (bundle , crt )
242263 }
243- if block .Type != "CERTIFICATE" || len (block .Headers ) != 0 {
244- continue
264+ if len (bundle ) == 0 {
265+ return nil , & InvalidPEMError {
266+ Type : PEMTypeCertificate ,
267+ }
245268 }
269+ return bundle , nil
270+ }
246271
247- cert , err := x509 .ParseCertificate (block .Bytes )
248- if err != nil {
249- return nil , errors .Wrap (err , "error parsing certificate" )
272+ // DER format (binary)
273+ crt , err := x509 .ParseCertificate (data )
274+ if err != nil {
275+ return nil , & InvalidPEMError {
276+ Message : fmt .Sprintf ("error parsing certificate as DER format: %v" , err ),
277+ Type : PEMTypeCertificate ,
250278 }
251- certs = append (certs , cert )
252- }
253- if len (certs ) == 0 {
254- return nil , errors .New ("error parsing certificate: no certificate found" )
255279 }
256- return certs , nil
280+ return [] * x509. Certificate { crt } , nil
257281}
258282
259- // ParseCertificateRequest extracts the first certificate from the given pem.
260- func ParseCertificateRequest (pemData []byte ) (* x509.CertificateRequest , error ) {
261- var block * pem.Block
262- for len (pemData ) > 0 {
263- block , pemData = pem .Decode (pemData )
264- if block == nil {
265- return nil , errors .New ("error decoding pem block" )
266- }
267- if (block .Type != "CERTIFICATE REQUEST" && block .Type != "NEW CERTIFICATE REQUEST" ) ||
268- len (block .Headers ) != 0 {
269- continue
270- }
283+ // ParseCertificateRequest extracts the first *x509.CertificateRequest
284+ // from the given data.
285+ //
286+ // - supports PEM and DER certificate formats
287+ // - If a DER-formatted file is given only one certificate will be returned.
288+ func ParseCertificateRequest (data []byte ) (* x509.CertificateRequest , error ) {
289+ // PEM format
290+ if bytes .Contains (data , PEMBlockHeader ) {
291+ var block * pem.Block
292+ for len (data ) > 0 {
293+ block , data = pem .Decode (data )
294+ if block == nil {
295+ break
296+ }
297+ if ! strings .HasSuffix (block .Type , "CERTIFICATE REQUEST" ) {
298+ continue
299+ }
300+ csr , err := x509 .ParseCertificateRequest (block .Bytes )
301+ if err != nil {
302+ return nil , & InvalidPEMError {
303+ Type : PEMTypeCertificateRequest ,
304+ Err : err ,
305+ }
306+ }
271307
272- csr , err := x509 .ParseCertificateRequest (block .Bytes )
273- if err != nil {
274- return nil , errors .Wrap (err , "error parsing certificate request" )
308+ return csr , nil
275309 }
276- return csr , nil
277310 }
278311
279- return nil , errors .New ("error parsing certificate request: no certificate found" )
312+ // DER format (binary)
313+ csr , err := x509 .ParseCertificateRequest (data )
314+ if err != nil {
315+ return nil , & InvalidPEMError {
316+ Message : fmt .Sprintf ("error parsing certificate request as DER format: %v" , err ),
317+ Type : PEMTypeCertificateRequest ,
318+ }
319+ }
320+ return csr , nil
280321}
281322
282323// PEMType represents a PEM block type. (e.g., CERTIFICATE, CERTIFICATE REQUEST, etc.)
@@ -318,14 +359,10 @@ func (e *InvalidPEMError) Error() string {
318359 case e .Err != nil :
319360 return fmt .Sprintf ("error decoding PEM data: %v" , e .Err )
320361 default :
321- var prefix = "input"
322- if e .File != "" {
323- prefix = fmt .Sprintf ("file %s" , e .File )
324- }
325362 if e .Type == PEMTypeUndefined {
326- return fmt . Sprintf ( "%s does not contain valid PEM encoded data", prefix )
363+ return " does not contain valid PEM encoded data"
327364 }
328- return fmt .Sprintf ("%s does not contain a valid PEM encoded %s" , prefix , e .Type )
365+ return fmt .Sprintf ("does not contain a valid PEM encoded %s" , e .Type )
329366 }
330367}
331368
@@ -355,83 +392,40 @@ func ReadCertificate(filename string, opts ...Options) (*x509.Certificate, error
355392 }
356393}
357394
358- // ReadCertificateBundle returns a list of *x509.Certificate from the given
359- // filename. It supports certificates formats PEM and DER. If a DER-formatted
360- // file is given only one certificate will be returned.
395+ // ReadCertificateBundle reads the given filename and returns a list of
396+ // *x509.Certificate.
397+ //
398+ // - supports PEM and DER certificate formats
399+ // - If a DER-formatted file is given only one certificate will be returned.
361400func ReadCertificateBundle (filename string ) ([]* x509.Certificate , error ) {
362401 b , err := utils .ReadFile (filename )
363402 if err != nil {
364403 return nil , err
365404 }
366405
367- // PEM format
368- if bytes .Contains (b , PEMBlockHeader ) {
369- var block * pem.Block
370- var bundle []* x509.Certificate
371- for len (b ) > 0 {
372- block , b = pem .Decode (b )
373- if block == nil {
374- break
375- }
376- if block .Type != "CERTIFICATE" {
377- continue
378- }
379- var crt * x509.Certificate
380- crt , err = x509 .ParseCertificate (block .Bytes )
381- if err != nil {
382- return nil , errors .Wrapf (err , "error parsing %s" , filename )
383- }
384- bundle = append (bundle , crt )
385- }
386- if len (bundle ) == 0 {
387- return nil , & InvalidPEMError {File : filename , Type : PEMTypeCertificate }
388- }
389- return bundle , nil
390- }
391-
392- // DER format (binary)
393- crt , err := x509 .ParseCertificate (b )
406+ bundle , err := ParseCertificateBundle (b )
394407 if err != nil {
395- return nil , errors . Wrapf ( err , "error parsing %s" , filename )
408+ return nil , fmt . Errorf ( "error parsing %s: %w " , filename , err )
396409 }
397- return [] * x509. Certificate { crt } , nil
410+ return bundle , nil
398411}
399412
400- // ReadCertificateRequest returns a *x509.CertificateRequest from the given
401- // filename. It supports certificates formats PEM and DER.
413+ // ReadCertificateRequest reads the given filename and returns a
414+ // *x509.CertificateRequest.
415+ //
416+ // - supports PEM and DER Certificate formats.
417+ // - supports reading from STDIN with filename `-`.
402418func ReadCertificateRequest (filename string ) (* x509.CertificateRequest , error ) {
403419 b , err := utils .ReadFile (filename )
404420 if err != nil {
405421 return nil , err
406422 }
407423
408- // PEM format
409- if bytes .Contains (b , PEMBlockHeader ) {
410- var block * pem.Block
411- for len (b ) > 0 {
412- block , b = pem .Decode (b )
413- if block == nil {
414- break
415- }
416- if ! strings .HasSuffix (block .Type , "CERTIFICATE REQUEST" ) {
417- continue
418- }
419- csr , err := x509 .ParseCertificateRequest (block .Bytes )
420- if err != nil {
421- return nil , & InvalidPEMError {
422- File : filename , Type : PEMTypeCertificateRequest ,
423- Message : fmt .Sprintf ("error parsing %s: CSR PEM block is invalid: %v" , filename , err ),
424- Err : err ,
425- }
426- }
427-
428- return csr , nil
429- }
424+ cr , err := ParseCertificateRequest (b )
425+ if err != nil {
426+ return nil , fmt .Errorf ("error parsing %s: %w" , filename , err )
430427 }
431-
432- // DER format (binary)
433- csr , err := x509 .ParseCertificateRequest (b )
434- return csr , errors .Wrapf (err , "error parsing %s" , filename )
428+ return cr , nil
435429}
436430
437431// Parse returns the key or certificate PEM-encoded in the given bytes.
0 commit comments