OSDN Git Service

Update Go library to last weekly.
[pf3gnuchains/gcc-fork.git] / libgo / go / crypto / x509 / pkcs1.go
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         "asn1"
9         "big"
10         "os"
11         "crypto/rsa"
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"`
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 // ParsePKCS1PrivateKey returns an RSA private key from its ASN.1 PKCS#1 DER encoded form.
39 func ParsePKCS1PrivateKey(der []byte) (key *rsa.PrivateKey, err os.Error) {
40         var priv pkcs1PrivateKey
41         rest, err := asn1.Unmarshal(der, &priv)
42         if len(rest) > 0 {
43                 err = asn1.SyntaxError{"trailing data"}
44                 return
45         }
46         if err != nil {
47                 return
48         }
49
50         if priv.Version > 1 {
51                 return nil, os.NewError("x509: unsupported private key version")
52         }
53
54         if priv.N.Sign() <= 0 || priv.D.Sign() <= 0 || priv.P.Sign() <= 0 || priv.Q.Sign() <= 0 {
55                 return nil, os.NewError("private key contains zero or negative value")
56         }
57
58         key = new(rsa.PrivateKey)
59         key.PublicKey = rsa.PublicKey{
60                 E: priv.E,
61                 N: priv.N,
62         }
63
64         key.D = priv.D
65         key.Primes = make([]*big.Int, 2+len(priv.AdditionalPrimes))
66         key.Primes[0] = priv.P
67         key.Primes[1] = priv.Q
68         for i, a := range priv.AdditionalPrimes {
69                 if a.Prime.Sign() <= 0 {
70                         return nil, os.NewError("private key contains zero or negative prime")
71                 }
72                 key.Primes[i+2] = a.Prime
73                 // We ignore the other two values because rsa will calculate
74                 // them as needed.
75         }
76
77         err = key.Validate()
78         if err != nil {
79                 return nil, err
80         }
81         key.Precompute()
82
83         return
84 }
85
86 // MarshalPKCS1PrivateKey converts a private key to ASN.1 DER encoded form.
87 func MarshalPKCS1PrivateKey(key *rsa.PrivateKey) []byte {
88         key.Precompute()
89
90         version := 0
91         if len(key.Primes) > 2 {
92                 version = 1
93         }
94
95         priv := pkcs1PrivateKey{
96                 Version: version,
97                 N:       key.N,
98                 E:       key.PublicKey.E,
99                 D:       key.D,
100                 P:       key.Primes[0],
101                 Q:       key.Primes[1],
102                 Dp:      key.Precomputed.Dp,
103                 Dq:      key.Precomputed.Dq,
104                 Qinv:    key.Precomputed.Qinv,
105         }
106
107         priv.AdditionalPrimes = make([]pkcs1AdditionalRSAPrime, len(key.Precomputed.CRTValues))
108         for i, values := range key.Precomputed.CRTValues {
109                 priv.AdditionalPrimes[i].Prime = key.Primes[2+i]
110                 priv.AdditionalPrimes[i].Exp = values.Exp
111                 priv.AdditionalPrimes[i].Coeff = values.Coeff
112         }
113
114         b, _ := asn1.Marshal(priv)
115         return b
116 }
117
118 // rsaPublicKey reflects the ASN.1 structure of a PKCS#1 public key.
119 type rsaPublicKey struct {
120         N *big.Int
121         E int
122 }