package  x509import  (	"crypto/ecdh" 	"crypto/ecdsa" 	"crypto/ed25519" 	"crypto/rsa" 	"crypto/x509/pkix" 	"encoding/asn1" 	"errors" 	"fmt" )type  pkcs8  struct  {	Version     int 	Algo        pkix .AlgorithmIdentifier 	PrivateKey  []byte 	}func  ParsePKCS8PrivateKey der  []byte ) (key  any , err  error ) {	var  privKey  pkcs8 	if  _ , err  := asn1 .Unmarshal (der , &privKey ); err  != nil  {		if  _ , err  := asn1 .Unmarshal (der , &ecPrivateKey {}); err  == nil  {			return  nil , errors .New ("x509: failed to parse private key (use ParseECPrivateKey instead for this key format)" )		}		if  _ , err  := asn1 .Unmarshal (der , &pkcs1PrivateKey {}); err  == nil  {			return  nil , errors .New ("x509: failed to parse private key (use ParsePKCS1PrivateKey instead for this key format)" )		}		return  nil , err 	}	switch  {	case  privKey .Algo .Algorithm .Equal (oidPublicKeyRSA ):		key , err  = ParsePKCS1PrivateKey (privKey .PrivateKey )		if  err  != nil  {			return  nil , errors .New ("x509: failed to parse RSA private key embedded in PKCS#8: "  + err .Error())		}		return  key , nil 	case  privKey .Algo .Algorithm .Equal (oidPublicKeyECDSA ):		bytes  := privKey .Algo .Parameters .FullBytes 		namedCurveOID  := new (asn1 .ObjectIdentifier )		if  _ , err  := asn1 .Unmarshal (bytes , namedCurveOID ); err  != nil  {			namedCurveOID  = nil 		}		key , err  = parseECPrivateKey (namedCurveOID , privKey .PrivateKey )		if  err  != nil  {			return  nil , errors .New ("x509: failed to parse EC private key embedded in PKCS#8: "  + err .Error())		}		return  key , nil 	case  privKey .Algo .Algorithm .Equal (oidPublicKeyEd25519 ):		if  l  := len (privKey .Algo .Parameters .FullBytes ); l  != 0  {			return  nil , errors .New ("x509: invalid Ed25519 private key parameters" )		}		var  curvePrivateKey  []byte 		if  _ , err  := asn1 .Unmarshal (privKey .PrivateKey , &curvePrivateKey ); err  != nil  {			return  nil , fmt .Errorf ("x509: invalid Ed25519 private key: %v" , err )		}		if  l  := len (curvePrivateKey ); l  != ed25519 .SeedSize  {			return  nil , fmt .Errorf ("x509: invalid Ed25519 private key length: %d" , l )		}		return  ed25519 .NewKeyFromSeed (curvePrivateKey ), nil 	case  privKey .Algo .Algorithm .Equal (oidPublicKeyX25519 ):		if  l  := len (privKey .Algo .Parameters .FullBytes ); l  != 0  {			return  nil , errors .New ("x509: invalid X25519 private key parameters" )		}		var  curvePrivateKey  []byte 		if  _ , err  := asn1 .Unmarshal (privKey .PrivateKey , &curvePrivateKey ); err  != nil  {			return  nil , fmt .Errorf ("x509: invalid X25519 private key: %v" , err )		}		return  ecdh .X25519 ().NewPrivateKey (curvePrivateKey )	default :		return  nil , fmt .Errorf ("x509: PKCS#8 wrapping contained private key with unknown algorithm: %v" , privKey .Algo .Algorithm )	}}func  MarshalPKCS8PrivateKey key  any ) ([]byte , error ) {	var  privKey  pkcs8 	switch  k := key .(type ) {	case  *rsa .PrivateKey :		privKey .Algo  = pkix .AlgorithmIdentifier {			Algorithm :  oidPublicKeyRSA ,			Parameters : asn1 .NullRawValue ,		}		privKey .PrivateKey  = MarshalPKCS1PrivateKey (k )	case  *ecdsa .PrivateKey :		oid , ok  := oidFromNamedCurve (k .Curve )		if  !ok  {			return  nil , errors .New ("x509: unknown curve while marshaling to PKCS#8" )		}		oidBytes , err  := asn1 .Marshal (oid )		if  err  != nil  {			return  nil , errors .New ("x509: failed to marshal curve OID: "  + err .Error())		}		privKey .Algo  = pkix .AlgorithmIdentifier {			Algorithm : oidPublicKeyECDSA ,			Parameters : asn1 .RawValue {				FullBytes : oidBytes ,			},		}		if  privKey .PrivateKey , err  = marshalECPrivateKeyWithOID (k , nil ); err  != nil  {			return  nil , errors .New ("x509: failed to marshal EC private key while building PKCS#8: "  + err .Error())		}	case  ed25519 .PrivateKey :		privKey .Algo  = pkix .AlgorithmIdentifier {			Algorithm : oidPublicKeyEd25519 ,		}		curvePrivateKey , err  := asn1 .Marshal (k .Seed ())		if  err  != nil  {			return  nil , fmt .Errorf ("x509: failed to marshal private key: %v" , err )		}		privKey .PrivateKey  = curvePrivateKey 	case  *ecdh .PrivateKey :		if  k .Curve () == ecdh .X25519 () {			privKey .Algo  = pkix .AlgorithmIdentifier {				Algorithm : oidPublicKeyX25519 ,			}			var  err  error 			if  privKey .PrivateKey , err  = asn1 .Marshal (k .Bytes ()); err  != nil  {				return  nil , fmt .Errorf ("x509: failed to marshal private key: %v" , err )			}		} else  {			oid , ok  := oidFromECDHCurve (k .Curve ())			if  !ok  {				return  nil , errors .New ("x509: unknown curve while marshaling to PKCS#8" )			}			oidBytes , err  := asn1 .Marshal (oid )			if  err  != nil  {				return  nil , errors .New ("x509: failed to marshal curve OID: "  + err .Error())			}			privKey .Algo  = pkix .AlgorithmIdentifier {				Algorithm : oidPublicKeyECDSA ,				Parameters : asn1 .RawValue {					FullBytes : oidBytes ,				},			}			if  privKey .PrivateKey , err  = marshalECDHPrivateKey (k ); err  != nil  {				return  nil , errors .New ("x509: failed to marshal EC private key while building PKCS#8: "  + err .Error())			}		}	default :		return  nil , fmt .Errorf ("x509: unknown key type while marshaling PKCS#8: %T" , key )	}	return  asn1 .Marshal (privKey )} The pages are generated with Golds v0.7.6 . (GOOS=linux GOARCH=amd64)
Golds  is a Go 101  project developed by Tapir Liu .
PR and bug reports are welcome and can be submitted to the issue list .
Please follow @zigo_101  (reachable from the left QR code) to get the latest news of Golds .