...

Source file src/github.com/google/certificate-transparency-go/x509/pkcs1.go

Documentation: github.com/google/certificate-transparency-go/x509

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

View as plain text