...
Run Format

Source file src/crypto/x509/pkcs1.go

Documentation: crypto/x509

  // Copyright 2011 The Go Authors. All rights reserved.
  // Use of this source code is governed by a BSD-style
  // license that can be found in the LICENSE file.
  
  package x509
  
  import (
  	"crypto/rsa"
  	"encoding/asn1"
  	"errors"
  	"math/big"
  )
  
  // pkcs1PrivateKey is a structure which mirrors the PKCS#1 ASN.1 for an RSA private key.
  type pkcs1PrivateKey struct {
  	Version int
  	N       *big.Int
  	E       int
  	D       *big.Int
  	P       *big.Int
  	Q       *big.Int
  	// We ignore these values, if present, because rsa will calculate them.
  	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
  
  	// We ignore these values because rsa will calculate them.
  	Exp   *big.Int
  	Coeff *big.Int
  }
  
  // pkcs1PublicKey reflects the ASN.1 structure of a PKCS#1 public key.
  type pkcs1PublicKey struct {
  	N *big.Int
  	E int
  }
  
  // ParsePKCS1PrivateKey returns an RSA private key from its ASN.1 PKCS#1 DER encoded form.
  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 {
  		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
  		// We ignore the other two values because rsa will calculate
  		// them as needed.
  	}
  
  	err = key.Validate()
  	if err != nil {
  		return nil, err
  	}
  	key.Precompute()
  
  	return key, nil
  }
  
  // MarshalPKCS1PrivateKey converts a private key to ASN.1 DER encoded form.
  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
  }
  

View as plain text