package  x509 
 
import  ( 
	"crypto/rsa"  
	"encoding/asn1"  
	"errors"  
	"math/big"  
) 
 
 
type  pkcs1PrivateKey struct  { 
	Version int  
	N       *big .Int  
	E       int  
	D       *big .Int  
	P       *big .Int  
	Q       *big .Int  
	 
	Dp   *big .Int  `asn1:"optional"`  
	Dq   *big .Int  `asn1:"optional"`  
	Qinv *big .Int  `asn1:"optional"`  
 
	AdditionalPrimes []pkcs1AdditionalRSAPrime  `asn1:"optional,omitempty"`  
} 
 
type  pkcs1AdditionalRSAPrime struct  { 
	Prime *big .Int  
 
	 
	Exp   *big .Int  
	Coeff *big .Int  
} 
 
 
type  pkcs1PublicKey struct  { 
	N *big .Int  
	E int  
} 
 
 
 
 
func  ParsePKCS1PrivateKey  (der  []byte ) (*rsa .PrivateKey , error ) { 
	var  priv  pkcs1PrivateKey  
	rest , err  := asn1 .Unmarshal (der , &priv ) 
	if  len (rest ) > 0  { 
		return  nil , asn1 .SyntaxError {Msg : "trailing data" } 
	} 
	if  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 , &pkcs8 {}); err  == nil  { 
			return  nil , errors .New ("x509: failed to parse private key (use ParsePKCS8PrivateKey instead for this key format)" ) 
		} 
		return  nil , err  
	} 
 
	if  priv .Version  > 1  { 
		return  nil , errors .New ("x509: unsupported private key version" ) 
	} 
 
	if  priv .N .Sign () <= 0  || priv .D .Sign () <= 0  || priv .P .Sign () <= 0  || priv .Q .Sign () <= 0  { 
		return  nil , errors .New ("x509: private key contains zero or negative value" ) 
	} 
 
	key  := new (rsa .PrivateKey ) 
	key .PublicKey  = rsa .PublicKey { 
		E : priv .E , 
		N : priv .N , 
	} 
 
	key .D  = priv .D  
	key .Primes  = make ([]*big .Int , 2 +len (priv .AdditionalPrimes )) 
	key .Primes [0 ] = priv .P  
	key .Primes [1 ] = priv .Q  
	for  i , a  := range  priv .AdditionalPrimes  { 
		if  a .Prime .Sign () <= 0  { 
			return  nil , errors .New ("x509: private key contains zero or negative prime" ) 
		} 
		key .Primes [i +2 ] = a .Prime  
		 
 
	} 
 
	err  = key .Validate () 
	if  err  != nil  { 
		return  nil , err  
	} 
	key .Precompute () 
 
	return  key , nil  
} 
 
 
 
 
 
 
func  MarshalPKCS1PrivateKey  (key  *rsa .PrivateKey ) []byte  { 
	key .Precompute () 
 
	version  := 0  
	if  len (key .Primes ) > 2  { 
		version  = 1  
	} 
 
	priv  := pkcs1PrivateKey { 
		Version : version , 
		N :       key .N , 
		E :       key .PublicKey .E , 
		D :       key .D , 
		P :       key .Primes [0 ], 
		Q :       key .Primes [1 ], 
		Dp :      key .Precomputed .Dp , 
		Dq :      key .Precomputed .Dq , 
		Qinv :    key .Precomputed .Qinv , 
	} 
 
	priv .AdditionalPrimes  = make ([]pkcs1AdditionalRSAPrime , len (key .Precomputed .CRTValues )) 
	for  i , values  := range  key .Precomputed .CRTValues  { 
		priv .AdditionalPrimes [i ].Prime  = key .Primes [2 +i ] 
		priv .AdditionalPrimes [i ].Exp  = values .Exp  
		priv .AdditionalPrimes [i ].Coeff  = values .Coeff  
	} 
 
	b , _  := asn1 .Marshal (priv ) 
	return  b  
} 
 
 
 
 
func  ParsePKCS1PublicKey  (der  []byte ) (*rsa .PublicKey , error ) { 
	var  pub  pkcs1PublicKey  
	rest , err  := asn1 .Unmarshal (der , &pub ) 
	if  err  != nil  { 
		if  _ , err  := asn1 .Unmarshal (der , &publicKeyInfo {}); err  == nil  { 
			return  nil , errors .New ("x509: failed to parse public key (use ParsePKIXPublicKey instead for this key format)" ) 
		} 
		return  nil , err  
	} 
	if  len (rest ) > 0  { 
		return  nil , asn1 .SyntaxError {Msg : "trailing data" } 
	} 
 
	if  pub .N .Sign () <= 0  || pub .E  <= 0  { 
		return  nil , errors .New ("x509: public key contains zero or negative value" ) 
	} 
	if  pub .E  > 1 <<31 -1  { 
		return  nil , errors .New ("x509: public key contains large public exponent" ) 
	} 
 
	return  &rsa .PublicKey { 
		E : pub .E , 
		N : pub .N , 
	}, nil  
} 
 
 
 
 
func  MarshalPKCS1PublicKey  (key  *rsa .PublicKey ) []byte  { 
	derBytes , _  := asn1 .Marshal (pkcs1PublicKey { 
		N : key .N , 
		E : key .E , 
	}) 
	return  derBytes  
} 
  
The pages are generated with Golds   v0.6.7 . (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 @Go100and1  (reachable from the left QR code) to get the latest news of Golds .