OSDN Git Service

new repo
[bytom/vapor.git] / vendor / golang.org / x / crypto / openpgp / packet / public_key_v3.go
1 // Copyright 2013 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 packet
6
7 import (
8         "crypto"
9         "crypto/md5"
10         "crypto/rsa"
11         "encoding/binary"
12         "fmt"
13         "hash"
14         "io"
15         "math/big"
16         "strconv"
17         "time"
18
19         "golang.org/x/crypto/openpgp/errors"
20 )
21
22 // PublicKeyV3 represents older, version 3 public keys. These keys are less secure and
23 // should not be used for signing or encrypting. They are supported here only for
24 // parsing version 3 key material and validating signatures.
25 // See RFC 4880, section 5.5.2.
26 type PublicKeyV3 struct {
27         CreationTime time.Time
28         DaysToExpire uint16
29         PubKeyAlgo   PublicKeyAlgorithm
30         PublicKey    *rsa.PublicKey
31         Fingerprint  [16]byte
32         KeyId        uint64
33         IsSubkey     bool
34
35         n, e parsedMPI
36 }
37
38 // newRSAPublicKeyV3 returns a PublicKey that wraps the given rsa.PublicKey.
39 // Included here for testing purposes only. RFC 4880, section 5.5.2:
40 // "an implementation MUST NOT generate a V3 key, but MAY accept it."
41 func newRSAPublicKeyV3(creationTime time.Time, pub *rsa.PublicKey) *PublicKeyV3 {
42         pk := &PublicKeyV3{
43                 CreationTime: creationTime,
44                 PublicKey:    pub,
45                 n:            fromBig(pub.N),
46                 e:            fromBig(big.NewInt(int64(pub.E))),
47         }
48
49         pk.setFingerPrintAndKeyId()
50         return pk
51 }
52
53 func (pk *PublicKeyV3) parse(r io.Reader) (err error) {
54         // RFC 4880, section 5.5.2
55         var buf [8]byte
56         if _, err = readFull(r, buf[:]); err != nil {
57                 return
58         }
59         if buf[0] < 2 || buf[0] > 3 {
60                 return errors.UnsupportedError("public key version")
61         }
62         pk.CreationTime = time.Unix(int64(uint32(buf[1])<<24|uint32(buf[2])<<16|uint32(buf[3])<<8|uint32(buf[4])), 0)
63         pk.DaysToExpire = binary.BigEndian.Uint16(buf[5:7])
64         pk.PubKeyAlgo = PublicKeyAlgorithm(buf[7])
65         switch pk.PubKeyAlgo {
66         case PubKeyAlgoRSA, PubKeyAlgoRSAEncryptOnly, PubKeyAlgoRSASignOnly:
67                 err = pk.parseRSA(r)
68         default:
69                 err = errors.UnsupportedError("public key type: " + strconv.Itoa(int(pk.PubKeyAlgo)))
70         }
71         if err != nil {
72                 return
73         }
74
75         pk.setFingerPrintAndKeyId()
76         return
77 }
78
79 func (pk *PublicKeyV3) setFingerPrintAndKeyId() {
80         // RFC 4880, section 12.2
81         fingerPrint := md5.New()
82         fingerPrint.Write(pk.n.bytes)
83         fingerPrint.Write(pk.e.bytes)
84         fingerPrint.Sum(pk.Fingerprint[:0])
85         pk.KeyId = binary.BigEndian.Uint64(pk.n.bytes[len(pk.n.bytes)-8:])
86 }
87
88 // parseRSA parses RSA public key material from the given Reader. See RFC 4880,
89 // section 5.5.2.
90 func (pk *PublicKeyV3) parseRSA(r io.Reader) (err error) {
91         if pk.n.bytes, pk.n.bitLength, err = readMPI(r); err != nil {
92                 return
93         }
94         if pk.e.bytes, pk.e.bitLength, err = readMPI(r); err != nil {
95                 return
96         }
97
98         // RFC 4880 Section 12.2 requires the low 8 bytes of the
99         // modulus to form the key id.
100         if len(pk.n.bytes) < 8 {
101                 return errors.StructuralError("v3 public key modulus is too short")
102         }
103         if len(pk.e.bytes) > 3 {
104                 err = errors.UnsupportedError("large public exponent")
105                 return
106         }
107         rsa := &rsa.PublicKey{N: new(big.Int).SetBytes(pk.n.bytes)}
108         for i := 0; i < len(pk.e.bytes); i++ {
109                 rsa.E <<= 8
110                 rsa.E |= int(pk.e.bytes[i])
111         }
112         pk.PublicKey = rsa
113         return
114 }
115
116 // SerializeSignaturePrefix writes the prefix for this public key to the given Writer.
117 // The prefix is used when calculating a signature over this public key. See
118 // RFC 4880, section 5.2.4.
119 func (pk *PublicKeyV3) SerializeSignaturePrefix(w io.Writer) {
120         var pLength uint16
121         switch pk.PubKeyAlgo {
122         case PubKeyAlgoRSA, PubKeyAlgoRSAEncryptOnly, PubKeyAlgoRSASignOnly:
123                 pLength += 2 + uint16(len(pk.n.bytes))
124                 pLength += 2 + uint16(len(pk.e.bytes))
125         default:
126                 panic("unknown public key algorithm")
127         }
128         pLength += 6
129         w.Write([]byte{0x99, byte(pLength >> 8), byte(pLength)})
130         return
131 }
132
133 func (pk *PublicKeyV3) Serialize(w io.Writer) (err error) {
134         length := 8 // 8 byte header
135
136         switch pk.PubKeyAlgo {
137         case PubKeyAlgoRSA, PubKeyAlgoRSAEncryptOnly, PubKeyAlgoRSASignOnly:
138                 length += 2 + len(pk.n.bytes)
139                 length += 2 + len(pk.e.bytes)
140         default:
141                 panic("unknown public key algorithm")
142         }
143
144         packetType := packetTypePublicKey
145         if pk.IsSubkey {
146                 packetType = packetTypePublicSubkey
147         }
148         if err = serializeHeader(w, packetType, length); err != nil {
149                 return
150         }
151         return pk.serializeWithoutHeaders(w)
152 }
153
154 // serializeWithoutHeaders marshals the PublicKey to w in the form of an
155 // OpenPGP public key packet, not including the packet header.
156 func (pk *PublicKeyV3) serializeWithoutHeaders(w io.Writer) (err error) {
157         var buf [8]byte
158         // Version 3
159         buf[0] = 3
160         // Creation time
161         t := uint32(pk.CreationTime.Unix())
162         buf[1] = byte(t >> 24)
163         buf[2] = byte(t >> 16)
164         buf[3] = byte(t >> 8)
165         buf[4] = byte(t)
166         // Days to expire
167         buf[5] = byte(pk.DaysToExpire >> 8)
168         buf[6] = byte(pk.DaysToExpire)
169         // Public key algorithm
170         buf[7] = byte(pk.PubKeyAlgo)
171
172         if _, err = w.Write(buf[:]); err != nil {
173                 return
174         }
175
176         switch pk.PubKeyAlgo {
177         case PubKeyAlgoRSA, PubKeyAlgoRSAEncryptOnly, PubKeyAlgoRSASignOnly:
178                 return writeMPIs(w, pk.n, pk.e)
179         }
180         return errors.InvalidArgumentError("bad public-key algorithm")
181 }
182
183 // CanSign returns true iff this public key can generate signatures
184 func (pk *PublicKeyV3) CanSign() bool {
185         return pk.PubKeyAlgo != PubKeyAlgoRSAEncryptOnly
186 }
187
188 // VerifySignatureV3 returns nil iff sig is a valid signature, made by this
189 // public key, of the data hashed into signed. signed is mutated by this call.
190 func (pk *PublicKeyV3) VerifySignatureV3(signed hash.Hash, sig *SignatureV3) (err error) {
191         if !pk.CanSign() {
192                 return errors.InvalidArgumentError("public key cannot generate signatures")
193         }
194
195         suffix := make([]byte, 5)
196         suffix[0] = byte(sig.SigType)
197         binary.BigEndian.PutUint32(suffix[1:], uint32(sig.CreationTime.Unix()))
198         signed.Write(suffix)
199         hashBytes := signed.Sum(nil)
200
201         if hashBytes[0] != sig.HashTag[0] || hashBytes[1] != sig.HashTag[1] {
202                 return errors.SignatureError("hash tag doesn't match")
203         }
204
205         if pk.PubKeyAlgo != sig.PubKeyAlgo {
206                 return errors.InvalidArgumentError("public key and signature use different algorithms")
207         }
208
209         switch pk.PubKeyAlgo {
210         case PubKeyAlgoRSA, PubKeyAlgoRSASignOnly:
211                 if err = rsa.VerifyPKCS1v15(pk.PublicKey, sig.Hash, hashBytes, sig.RSASignature.bytes); err != nil {
212                         return errors.SignatureError("RSA verification failure")
213                 }
214                 return
215         default:
216                 // V3 public keys only support RSA.
217                 panic("shouldn't happen")
218         }
219 }
220
221 // VerifyUserIdSignatureV3 returns nil iff sig is a valid signature, made by this
222 // public key, that id is the identity of pub.
223 func (pk *PublicKeyV3) VerifyUserIdSignatureV3(id string, pub *PublicKeyV3, sig *SignatureV3) (err error) {
224         h, err := userIdSignatureV3Hash(id, pk, sig.Hash)
225         if err != nil {
226                 return err
227         }
228         return pk.VerifySignatureV3(h, sig)
229 }
230
231 // VerifyKeySignatureV3 returns nil iff sig is a valid signature, made by this
232 // public key, of signed.
233 func (pk *PublicKeyV3) VerifyKeySignatureV3(signed *PublicKeyV3, sig *SignatureV3) (err error) {
234         h, err := keySignatureHash(pk, signed, sig.Hash)
235         if err != nil {
236                 return err
237         }
238         return pk.VerifySignatureV3(h, sig)
239 }
240
241 // userIdSignatureV3Hash returns a Hash of the message that needs to be signed
242 // to assert that pk is a valid key for id.
243 func userIdSignatureV3Hash(id string, pk signingKey, hfn crypto.Hash) (h hash.Hash, err error) {
244         if !hfn.Available() {
245                 return nil, errors.UnsupportedError("hash function")
246         }
247         h = hfn.New()
248
249         // RFC 4880, section 5.2.4
250         pk.SerializeSignaturePrefix(h)
251         pk.serializeWithoutHeaders(h)
252
253         h.Write([]byte(id))
254
255         return
256 }
257
258 // KeyIdString returns the public key's fingerprint in capital hex
259 // (e.g. "6C7EE1B8621CC013").
260 func (pk *PublicKeyV3) KeyIdString() string {
261         return fmt.Sprintf("%X", pk.KeyId)
262 }
263
264 // KeyIdShortString returns the short form of public key's fingerprint
265 // in capital hex, as shown by gpg --list-keys (e.g. "621CC013").
266 func (pk *PublicKeyV3) KeyIdShortString() string {
267         return fmt.Sprintf("%X", pk.KeyId&0xFFFFFFFF)
268 }
269
270 // BitLength returns the bit length for the given public key.
271 func (pk *PublicKeyV3) BitLength() (bitLength uint16, err error) {
272         switch pk.PubKeyAlgo {
273         case PubKeyAlgoRSA, PubKeyAlgoRSAEncryptOnly, PubKeyAlgoRSASignOnly:
274                 bitLength = pk.n.bitLength
275         default:
276                 err = errors.InvalidArgumentError("bad public-key algorithm")
277         }
278         return
279 }