github.com/insolar/x-crypto@v0.0.0-20191031140942-75fab8a325f6/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 "encoding/asn1" 9 "errors" 10 "github.com/insolar/x-crypto/rsa" 11 "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 returns an RSA private key from its ASN.1 PKCS#1 DER encoded form. 45 func ParsePKCS1PrivateKey(der []byte) (*rsa.PrivateKey, error) { 46 var priv pkcs1PrivateKey 47 rest, err := asn1.Unmarshal(der, &priv) 48 if len(rest) > 0 { 49 return nil, asn1.SyntaxError{Msg: "trailing data"} 50 } 51 if err != nil { 52 return nil, err 53 } 54 55 if priv.Version > 1 { 56 return nil, errors.New("x509: unsupported private key version") 57 } 58 59 if priv.N.Sign() <= 0 || priv.D.Sign() <= 0 || priv.P.Sign() <= 0 || priv.Q.Sign() <= 0 { 60 return nil, errors.New("x509: private key contains zero or negative value") 61 } 62 63 key := new(rsa.PrivateKey) 64 key.PublicKey = rsa.PublicKey{ 65 E: priv.E, 66 N: priv.N, 67 } 68 69 key.D = priv.D 70 key.Primes = make([]*big.Int, 2+len(priv.AdditionalPrimes)) 71 key.Primes[0] = priv.P 72 key.Primes[1] = priv.Q 73 for i, a := range priv.AdditionalPrimes { 74 if a.Prime.Sign() <= 0 { 75 return nil, errors.New("x509: private key contains zero or negative prime") 76 } 77 key.Primes[i+2] = a.Prime 78 // We ignore the other two values because rsa will calculate 79 // them as needed. 80 } 81 82 err = key.Validate() 83 if err != nil { 84 return nil, err 85 } 86 key.Precompute() 87 88 return key, nil 89 } 90 91 // MarshalPKCS1PrivateKey converts a private key to ASN.1 DER encoded form. 92 func MarshalPKCS1PrivateKey(key *rsa.PrivateKey) []byte { 93 key.Precompute() 94 95 version := 0 96 if len(key.Primes) > 2 { 97 version = 1 98 } 99 100 priv := pkcs1PrivateKey{ 101 Version: version, 102 N: key.N, 103 E: key.PublicKey.E, 104 D: key.D, 105 P: key.Primes[0], 106 Q: key.Primes[1], 107 Dp: key.Precomputed.Dp, 108 Dq: key.Precomputed.Dq, 109 Qinv: key.Precomputed.Qinv, 110 } 111 112 priv.AdditionalPrimes = make([]pkcs1AdditionalRSAPrime, len(key.Precomputed.CRTValues)) 113 for i, values := range key.Precomputed.CRTValues { 114 priv.AdditionalPrimes[i].Prime = key.Primes[2+i] 115 priv.AdditionalPrimes[i].Exp = values.Exp 116 priv.AdditionalPrimes[i].Coeff = values.Coeff 117 } 118 119 b, _ := asn1.Marshal(priv) 120 return b 121 } 122 123 // ParsePKCS1PublicKey parses a PKCS#1 public key in ASN.1 DER form. 124 func ParsePKCS1PublicKey(der []byte) (*rsa.PublicKey, error) { 125 var pub pkcs1PublicKey 126 rest, err := asn1.Unmarshal(der, &pub) 127 if err != nil { 128 return nil, err 129 } 130 if len(rest) > 0 { 131 return nil, asn1.SyntaxError{Msg: "trailing data"} 132 } 133 134 if pub.N.Sign() <= 0 || pub.E <= 0 { 135 return nil, errors.New("x509: public key contains zero or negative value") 136 } 137 if pub.E > 1<<31-1 { 138 return nil, errors.New("x509: public key contains large public exponent") 139 } 140 141 return &rsa.PublicKey{ 142 E: pub.E, 143 N: pub.N, 144 }, nil 145 } 146 147 // MarshalPKCS1PublicKey converts an RSA public key to PKCS#1, ASN.1 DER form. 148 func MarshalPKCS1PublicKey(key *rsa.PublicKey) []byte { 149 derBytes, _ := asn1.Marshal(pkcs1PublicKey{ 150 N: key.N, 151 E: key.E, 152 }) 153 return derBytes 154 }