github.com/x04/go/src@v0.0.0-20200202162449-3d481ceb3525/crypto/x509/pkcs1.go (about)

     1  // Copyright 2011 The Go Authors. All rights reserved.
     2  // Use of this source code is governed by a BSD-style
     3  // license that can be found in the LICENSE file.
     4  
     5  package x509
     6  
     7  import (
     8  	"github.com/x04/go/src/crypto/rsa"
     9  	"github.com/x04/go/src/encoding/asn1"
    10  	"github.com/x04/go/src/errors"
    11  	"github.com/x04/go/src/math/big"
    12  )
    13  
    14  // pkcs1PrivateKey is a structure which mirrors the PKCS#1 ASN.1 for an RSA private key.
    15  type pkcs1PrivateKey struct {
    16  	Version	int
    17  	N	*big.Int
    18  	E	int
    19  	D	*big.Int
    20  	P	*big.Int
    21  	Q	*big.Int
    22  	// We ignore these values, if present, because rsa will calculate them.
    23  	Dp	*big.Int	`asn1:"optional"`
    24  	Dq	*big.Int	`asn1:"optional"`
    25  	Qinv	*big.Int	`asn1:"optional"`
    26  
    27  	AdditionalPrimes	[]pkcs1AdditionalRSAPrime	`asn1:"optional,omitempty"`
    28  }
    29  
    30  type pkcs1AdditionalRSAPrime struct {
    31  	Prime	*big.Int
    32  
    33  	// We ignore these values because rsa will calculate them.
    34  	Exp	*big.Int
    35  	Coeff	*big.Int
    36  }
    37  
    38  // pkcs1PublicKey reflects the ASN.1 structure of a PKCS#1 public key.
    39  type pkcs1PublicKey struct {
    40  	N	*big.Int
    41  	E	int
    42  }
    43  
    44  // ParsePKCS1PrivateKey parses an RSA private key in PKCS#1, ASN.1 DER form.
    45  //
    46  // This kind of key is commonly encoded in PEM blocks of type "RSA PRIVATE KEY".
    47  func ParsePKCS1PrivateKey(der []byte) (*rsa.PrivateKey, error) {
    48  	var priv pkcs1PrivateKey
    49  	rest, err := asn1.Unmarshal(der, &priv)
    50  	if len(rest) > 0 {
    51  		return nil, asn1.SyntaxError{Msg: "trailing data"}
    52  	}
    53  	if err != nil {
    54  		if _, err := asn1.Unmarshal(der, &ecPrivateKey{}); err == nil {
    55  			return nil, errors.New("x509: failed to parse private key (use ParseECPrivateKey instead for this key format)")
    56  		}
    57  		if _, err := asn1.Unmarshal(der, &pkcs8{}); err == nil {
    58  			return nil, errors.New("x509: failed to parse private key (use ParsePKCS8PrivateKey instead for this key format)")
    59  		}
    60  		return nil, err
    61  	}
    62  
    63  	if priv.Version > 1 {
    64  		return nil, errors.New("x509: unsupported private key version")
    65  	}
    66  
    67  	if priv.N.Sign() <= 0 || priv.D.Sign() <= 0 || priv.P.Sign() <= 0 || priv.Q.Sign() <= 0 {
    68  		return nil, errors.New("x509: private key contains zero or negative value")
    69  	}
    70  
    71  	key := new(rsa.PrivateKey)
    72  	key.PublicKey = rsa.PublicKey{
    73  		E:	priv.E,
    74  		N:	priv.N,
    75  	}
    76  
    77  	key.D = priv.D
    78  	key.Primes = make([]*big.Int, 2+len(priv.AdditionalPrimes))
    79  	key.Primes[0] = priv.P
    80  	key.Primes[1] = priv.Q
    81  	for i, a := range priv.AdditionalPrimes {
    82  		if a.Prime.Sign() <= 0 {
    83  			return nil, errors.New("x509: private key contains zero or negative prime")
    84  		}
    85  		key.Primes[i+2] = a.Prime
    86  		// We ignore the other two values because rsa will calculate
    87  		// them as needed.
    88  	}
    89  
    90  	err = key.Validate()
    91  	if err != nil {
    92  		return nil, err
    93  	}
    94  	key.Precompute()
    95  
    96  	return key, nil
    97  }
    98  
    99  // MarshalPKCS1PrivateKey converts an RSA private key to PKCS#1, ASN.1 DER form.
   100  //
   101  // This kind of key is commonly encoded in PEM blocks of type "RSA PRIVATE KEY".
   102  // For a more flexible key format which is not RSA specific, use
   103  // MarshalPKCS8PrivateKey.
   104  func MarshalPKCS1PrivateKey(key *rsa.PrivateKey) []byte {
   105  	key.Precompute()
   106  
   107  	version := 0
   108  	if len(key.Primes) > 2 {
   109  		version = 1
   110  	}
   111  
   112  	priv := pkcs1PrivateKey{
   113  		Version:	version,
   114  		N:		key.N,
   115  		E:		key.PublicKey.E,
   116  		D:		key.D,
   117  		P:		key.Primes[0],
   118  		Q:		key.Primes[1],
   119  		Dp:		key.Precomputed.Dp,
   120  		Dq:		key.Precomputed.Dq,
   121  		Qinv:		key.Precomputed.Qinv,
   122  	}
   123  
   124  	priv.AdditionalPrimes = make([]pkcs1AdditionalRSAPrime, len(key.Precomputed.CRTValues))
   125  	for i, values := range key.Precomputed.CRTValues {
   126  		priv.AdditionalPrimes[i].Prime = key.Primes[2+i]
   127  		priv.AdditionalPrimes[i].Exp = values.Exp
   128  		priv.AdditionalPrimes[i].Coeff = values.Coeff
   129  	}
   130  
   131  	b, _ := asn1.Marshal(priv)
   132  	return b
   133  }
   134  
   135  // ParsePKCS1PublicKey parses an RSA public key in PKCS#1, ASN.1 DER form.
   136  //
   137  // This kind of key is commonly encoded in PEM blocks of type "RSA PUBLIC KEY".
   138  func ParsePKCS1PublicKey(der []byte) (*rsa.PublicKey, error) {
   139  	var pub pkcs1PublicKey
   140  	rest, err := asn1.Unmarshal(der, &pub)
   141  	if err != nil {
   142  		if _, err := asn1.Unmarshal(der, &publicKeyInfo{}); err == nil {
   143  			return nil, errors.New("x509: failed to parse public key (use ParsePKIXPublicKey instead for this key format)")
   144  		}
   145  		return nil, err
   146  	}
   147  	if len(rest) > 0 {
   148  		return nil, asn1.SyntaxError{Msg: "trailing data"}
   149  	}
   150  
   151  	if pub.N.Sign() <= 0 || pub.E <= 0 {
   152  		return nil, errors.New("x509: public key contains zero or negative value")
   153  	}
   154  	if pub.E > 1<<31-1 {
   155  		return nil, errors.New("x509: public key contains large public exponent")
   156  	}
   157  
   158  	return &rsa.PublicKey{
   159  		E:	pub.E,
   160  		N:	pub.N,
   161  	}, nil
   162  }
   163  
   164  // MarshalPKCS1PublicKey converts an RSA public key to PKCS#1, ASN.1 DER form.
   165  //
   166  // This kind of key is commonly encoded in PEM blocks of type "RSA PUBLIC KEY".
   167  func MarshalPKCS1PublicKey(key *rsa.PublicKey) []byte {
   168  	derBytes, _ := asn1.Marshal(pkcs1PublicKey{
   169  		N:	key.N,
   170  		E:	key.E,
   171  	})
   172  	return derBytes
   173  }