github.com/haraldrudell/parl@v0.4.176/parlca/parse.go (about)

     1  /*
     2  © 2022–present Harald Rudell <harald.rudell@gmail.com> (https://haraldrudell.github.io/haraldrudell/)
     3  ISC License
     4  */
     5  
     6  package parlca
     7  
     8  import (
     9  	"crypto/ecdsa"
    10  	"crypto/ed25519"
    11  	"crypto/rsa"
    12  	"crypto/x509"
    13  	"encoding/pem"
    14  
    15  	"github.com/haraldrudell/parl"
    16  	"github.com/haraldrudell/parl/perrors"
    17  )
    18  
    19  func ParsePEM(pemData []byte) (certificate parl.Certificate, privateKey parl.PrivateKey, publicKey parl.PublicKey, err error) {
    20  	block, _ := pem.Decode(pemData)
    21  	if block == nil {
    22  		err = perrors.NewPF("PEM block not found in input")
    23  		return
    24  	}
    25  	switch block.Type {
    26  	case pemPublicKeyType:
    27  		publicKey, err = ParsePkix(block.Bytes)
    28  		return
    29  	case pemPrivateKeyType:
    30  		privateKey, err = ParsePkcs8(block.Bytes)
    31  		return
    32  	case pemCertificateType:
    33  		if _, err = x509.ParseCertificate(block.Bytes); perrors.IsPF(&err, "x509.ParseCertificate %w", err) {
    34  			return
    35  		}
    36  		certificate = &Certificate{der: block.Bytes}
    37  		return
    38  	default:
    39  		err = perrors.ErrorfPF("Unknown pem block type: %q", block.Type)
    40  		return
    41  	}
    42  }
    43  
    44  func ParsePkcs8(privateKeyDer parl.PrivateKeyDer) (privateKey parl.PrivateKey, err error) {
    45  	var pub any
    46  	if pub, err = x509.ParsePKCS8PrivateKey(privateKeyDer); perrors.IsPF(&err, "x509.ParsePKCS8PrivateKey %w", err) {
    47  		return
    48  	}
    49  	if pk, ok := pub.(*rsa.PrivateKey); ok {
    50  		privateKey = &RsaPrivateKey{PrivateKey: *pk}
    51  	} else if pk, ok := pub.(*ecdsa.PrivateKey); ok {
    52  		privateKey = &EcdsaPrivateKey{PrivateKey: *pk}
    53  	} else if pk, ok := pub.(ed25519.PrivateKey); ok {
    54  		privateKey = &Ed25519PrivateKey{PrivateKey: pk}
    55  	} else {
    56  		err = perrors.ErrorfPF("Unknown private key type: %T", pub)
    57  	}
    58  	return
    59  }
    60  
    61  func ParsePkix(publicKeyDer parl.PublicKeyDer) (publicKey parl.PublicKey, err error) {
    62  	var pub any
    63  	if pub, err = x509.ParsePKIXPublicKey(publicKeyDer); perrors.IsPF(&err, "x509.ParsePKIXPublicKey %w", err) {
    64  		return
    65  	}
    66  	if pk, ok := pub.(*rsa.PublicKey); ok {
    67  		publicKey = &RsaPublicKey{PublicKey: *pk}
    68  	} else if pk, ok := pub.(*ecdsa.PublicKey); ok {
    69  		publicKey = &EcdsaPublicKey{PublicKey: *pk}
    70  	} else if pk, ok := pub.(ed25519.PublicKey); ok {
    71  		publicKey = &Ed25519PublicKey{PublicKey: pk}
    72  	} else {
    73  		err = perrors.ErrorfPF("Unknown public key type: %T", pub)
    74  	}
    75  	return
    76  }