OSDN Git Service

libgo: Update to weekly.2011-11-02.
[pf3gnuchains/gcc-fork.git] / libgo / go / crypto / openpgp / packet / public_key.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 packet
6
7 import (
8         "big"
9         "crypto/dsa"
10         "crypto/openpgp/elgamal"
11         error_ "crypto/openpgp/error"
12         "crypto/rsa"
13         "crypto/sha1"
14         "encoding/binary"
15         "fmt"
16         "hash"
17         "io"
18         "strconv"
19 )
20
21 // PublicKey represents an OpenPGP public key. See RFC 4880, section 5.5.2.
22 type PublicKey struct {
23         CreationTime uint32 // seconds since the epoch
24         PubKeyAlgo   PublicKeyAlgorithm
25         PublicKey    interface{} // Either a *rsa.PublicKey or *dsa.PublicKey
26         Fingerprint  [20]byte
27         KeyId        uint64
28         IsSubkey     bool
29
30         n, e, p, q, g, y parsedMPI
31 }
32
33 func fromBig(n *big.Int) parsedMPI {
34         return parsedMPI{
35                 bytes:     n.Bytes(),
36                 bitLength: uint16(n.BitLen()),
37         }
38 }
39
40 // NewRSAPublicKey returns a PublicKey that wraps the given rsa.PublicKey.
41 func NewRSAPublicKey(creationTimeSecs uint32, pub *rsa.PublicKey, isSubkey bool) *PublicKey {
42         pk := &PublicKey{
43                 CreationTime: creationTimeSecs,
44                 PubKeyAlgo:   PubKeyAlgoRSA,
45                 PublicKey:    pub,
46                 IsSubkey:     isSubkey,
47                 n:            fromBig(pub.N),
48                 e:            fromBig(big.NewInt(int64(pub.E))),
49         }
50
51         pk.setFingerPrintAndKeyId()
52         return pk
53 }
54
55 func (pk *PublicKey) parse(r io.Reader) (err error) {
56         // RFC 4880, section 5.5.2
57         var buf [6]byte
58         _, err = readFull(r, buf[:])
59         if err != nil {
60                 return
61         }
62         if buf[0] != 4 {
63                 return error_.UnsupportedError("public key version")
64         }
65         pk.CreationTime = uint32(buf[1])<<24 | uint32(buf[2])<<16 | uint32(buf[3])<<8 | uint32(buf[4])
66         pk.PubKeyAlgo = PublicKeyAlgorithm(buf[5])
67         switch pk.PubKeyAlgo {
68         case PubKeyAlgoRSA, PubKeyAlgoRSAEncryptOnly, PubKeyAlgoRSASignOnly:
69                 err = pk.parseRSA(r)
70         case PubKeyAlgoDSA:
71                 err = pk.parseDSA(r)
72         case PubKeyAlgoElGamal:
73                 err = pk.parseElGamal(r)
74         default:
75                 err = error_.UnsupportedError("public key type: " + strconv.Itoa(int(pk.PubKeyAlgo)))
76         }
77         if err != nil {
78                 return
79         }
80
81         pk.setFingerPrintAndKeyId()
82         return
83 }
84
85 func (pk *PublicKey) setFingerPrintAndKeyId() {
86         // RFC 4880, section 12.2
87         fingerPrint := sha1.New()
88         pk.SerializeSignaturePrefix(fingerPrint)
89         pk.serializeWithoutHeaders(fingerPrint)
90         copy(pk.Fingerprint[:], fingerPrint.Sum())
91         pk.KeyId = binary.BigEndian.Uint64(pk.Fingerprint[12:20])
92 }
93
94 // parseRSA parses RSA public key material from the given Reader. See RFC 4880,
95 // section 5.5.2.
96 func (pk *PublicKey) parseRSA(r io.Reader) (err error) {
97         pk.n.bytes, pk.n.bitLength, err = readMPI(r)
98         if err != nil {
99                 return
100         }
101         pk.e.bytes, pk.e.bitLength, err = readMPI(r)
102         if err != nil {
103                 return
104         }
105
106         if len(pk.e.bytes) > 3 {
107                 err = error_.UnsupportedError("large public exponent")
108                 return
109         }
110         rsa := &rsa.PublicKey{
111                 N: new(big.Int).SetBytes(pk.n.bytes),
112                 E: 0,
113         }
114         for i := 0; i < len(pk.e.bytes); i++ {
115                 rsa.E <<= 8
116                 rsa.E |= int(pk.e.bytes[i])
117         }
118         pk.PublicKey = rsa
119         return
120 }
121
122 // parseDSA parses DSA public key material from the given Reader. See RFC 4880,
123 // section 5.5.2.
124 func (pk *PublicKey) parseDSA(r io.Reader) (err error) {
125         pk.p.bytes, pk.p.bitLength, err = readMPI(r)
126         if err != nil {
127                 return
128         }
129         pk.q.bytes, pk.q.bitLength, err = readMPI(r)
130         if err != nil {
131                 return
132         }
133         pk.g.bytes, pk.g.bitLength, err = readMPI(r)
134         if err != nil {
135                 return
136         }
137         pk.y.bytes, pk.y.bitLength, err = readMPI(r)
138         if err != nil {
139                 return
140         }
141
142         dsa := new(dsa.PublicKey)
143         dsa.P = new(big.Int).SetBytes(pk.p.bytes)
144         dsa.Q = new(big.Int).SetBytes(pk.q.bytes)
145         dsa.G = new(big.Int).SetBytes(pk.g.bytes)
146         dsa.Y = new(big.Int).SetBytes(pk.y.bytes)
147         pk.PublicKey = dsa
148         return
149 }
150
151 // parseElGamal parses ElGamal public key material from the given Reader. See
152 // RFC 4880, section 5.5.2.
153 func (pk *PublicKey) parseElGamal(r io.Reader) (err error) {
154         pk.p.bytes, pk.p.bitLength, err = readMPI(r)
155         if err != nil {
156                 return
157         }
158         pk.g.bytes, pk.g.bitLength, err = readMPI(r)
159         if err != nil {
160                 return
161         }
162         pk.y.bytes, pk.y.bitLength, err = readMPI(r)
163         if err != nil {
164                 return
165         }
166
167         elgamal := new(elgamal.PublicKey)
168         elgamal.P = new(big.Int).SetBytes(pk.p.bytes)
169         elgamal.G = new(big.Int).SetBytes(pk.g.bytes)
170         elgamal.Y = new(big.Int).SetBytes(pk.y.bytes)
171         pk.PublicKey = elgamal
172         return
173 }
174
175 // SerializeSignaturePrefix writes the prefix for this public key to the given Writer.
176 // The prefix is used when calculating a signature over this public key. See
177 // RFC 4880, section 5.2.4.
178 func (pk *PublicKey) SerializeSignaturePrefix(h hash.Hash) {
179         var pLength uint16
180         switch pk.PubKeyAlgo {
181         case PubKeyAlgoRSA, PubKeyAlgoRSAEncryptOnly, PubKeyAlgoRSASignOnly:
182                 pLength += 2 + uint16(len(pk.n.bytes))
183                 pLength += 2 + uint16(len(pk.e.bytes))
184         case PubKeyAlgoDSA:
185                 pLength += 2 + uint16(len(pk.p.bytes))
186                 pLength += 2 + uint16(len(pk.q.bytes))
187                 pLength += 2 + uint16(len(pk.g.bytes))
188                 pLength += 2 + uint16(len(pk.y.bytes))
189         case PubKeyAlgoElGamal:
190                 pLength += 2 + uint16(len(pk.p.bytes))
191                 pLength += 2 + uint16(len(pk.g.bytes))
192                 pLength += 2 + uint16(len(pk.y.bytes))
193         default:
194                 panic("unknown public key algorithm")
195         }
196         pLength += 6
197         h.Write([]byte{0x99, byte(pLength >> 8), byte(pLength)})
198         return
199 }
200
201 func (pk *PublicKey) Serialize(w io.Writer) (err error) {
202         length := 6 // 6 byte header
203
204         switch pk.PubKeyAlgo {
205         case PubKeyAlgoRSA, PubKeyAlgoRSAEncryptOnly, PubKeyAlgoRSASignOnly:
206                 length += 2 + len(pk.n.bytes)
207                 length += 2 + len(pk.e.bytes)
208         case PubKeyAlgoDSA:
209                 length += 2 + len(pk.p.bytes)
210                 length += 2 + len(pk.q.bytes)
211                 length += 2 + len(pk.g.bytes)
212                 length += 2 + len(pk.y.bytes)
213         case PubKeyAlgoElGamal:
214                 length += 2 + len(pk.p.bytes)
215                 length += 2 + len(pk.g.bytes)
216                 length += 2 + len(pk.y.bytes)
217         default:
218                 panic("unknown public key algorithm")
219         }
220
221         packetType := packetTypePublicKey
222         if pk.IsSubkey {
223                 packetType = packetTypePublicSubkey
224         }
225         err = serializeHeader(w, packetType, length)
226         if err != nil {
227                 return
228         }
229         return pk.serializeWithoutHeaders(w)
230 }
231
232 // serializeWithoutHeaders marshals the PublicKey to w in the form of an
233 // OpenPGP public key packet, not including the packet header.
234 func (pk *PublicKey) serializeWithoutHeaders(w io.Writer) (err error) {
235         var buf [6]byte
236         buf[0] = 4
237         buf[1] = byte(pk.CreationTime >> 24)
238         buf[2] = byte(pk.CreationTime >> 16)
239         buf[3] = byte(pk.CreationTime >> 8)
240         buf[4] = byte(pk.CreationTime)
241         buf[5] = byte(pk.PubKeyAlgo)
242
243         _, err = w.Write(buf[:])
244         if err != nil {
245                 return
246         }
247
248         switch pk.PubKeyAlgo {
249         case PubKeyAlgoRSA, PubKeyAlgoRSAEncryptOnly, PubKeyAlgoRSASignOnly:
250                 return writeMPIs(w, pk.n, pk.e)
251         case PubKeyAlgoDSA:
252                 return writeMPIs(w, pk.p, pk.q, pk.g, pk.y)
253         case PubKeyAlgoElGamal:
254                 return writeMPIs(w, pk.p, pk.g, pk.y)
255         }
256         return error_.InvalidArgumentError("bad public-key algorithm")
257 }
258
259 // CanSign returns true iff this public key can generate signatures
260 func (pk *PublicKey) CanSign() bool {
261         return pk.PubKeyAlgo != PubKeyAlgoRSAEncryptOnly && pk.PubKeyAlgo != PubKeyAlgoElGamal
262 }
263
264 // VerifySignature returns nil iff sig is a valid signature, made by this
265 // public key, of the data hashed into signed. signed is mutated by this call.
266 func (pk *PublicKey) VerifySignature(signed hash.Hash, sig *Signature) (err error) {
267         if !pk.CanSign() {
268                 return error_.InvalidArgumentError("public key cannot generate signatures")
269         }
270
271         signed.Write(sig.HashSuffix)
272         hashBytes := signed.Sum()
273
274         if hashBytes[0] != sig.HashTag[0] || hashBytes[1] != sig.HashTag[1] {
275                 return error_.SignatureError("hash tag doesn't match")
276         }
277
278         if pk.PubKeyAlgo != sig.PubKeyAlgo {
279                 return error_.InvalidArgumentError("public key and signature use different algorithms")
280         }
281
282         switch pk.PubKeyAlgo {
283         case PubKeyAlgoRSA, PubKeyAlgoRSASignOnly:
284                 rsaPublicKey, _ := pk.PublicKey.(*rsa.PublicKey)
285                 err = rsa.VerifyPKCS1v15(rsaPublicKey, sig.Hash, hashBytes, sig.RSASignature.bytes)
286                 if err != nil {
287                         return error_.SignatureError("RSA verification failure")
288                 }
289                 return nil
290         case PubKeyAlgoDSA:
291                 dsaPublicKey, _ := pk.PublicKey.(*dsa.PublicKey)
292                 if !dsa.Verify(dsaPublicKey, hashBytes, new(big.Int).SetBytes(sig.DSASigR.bytes), new(big.Int).SetBytes(sig.DSASigS.bytes)) {
293                         return error_.SignatureError("DSA verification failure")
294                 }
295                 return nil
296         default:
297                 panic("shouldn't happen")
298         }
299         panic("unreachable")
300 }
301
302 // keySignatureHash returns a Hash of the message that needs to be signed for
303 // pk to assert a subkey relationship to signed.
304 func keySignatureHash(pk, signed *PublicKey, sig *Signature) (h hash.Hash, err error) {
305         h = sig.Hash.New()
306         if h == nil {
307                 return nil, error_.UnsupportedError("hash function")
308         }
309
310         // RFC 4880, section 5.2.4
311         pk.SerializeSignaturePrefix(h)
312         pk.serializeWithoutHeaders(h)
313         signed.SerializeSignaturePrefix(h)
314         signed.serializeWithoutHeaders(h)
315         return
316 }
317
318 // VerifyKeySignature returns nil iff sig is a valid signature, made by this
319 // public key, of signed.
320 func (pk *PublicKey) VerifyKeySignature(signed *PublicKey, sig *Signature) (err error) {
321         h, err := keySignatureHash(pk, signed, sig)
322         if err != nil {
323                 return err
324         }
325         return pk.VerifySignature(h, sig)
326 }
327
328 // userIdSignatureHash returns a Hash of the message that needs to be signed
329 // to assert that pk is a valid key for id.
330 func userIdSignatureHash(id string, pk *PublicKey, sig *Signature) (h hash.Hash, err error) {
331         h = sig.Hash.New()
332         if h == nil {
333                 return nil, error_.UnsupportedError("hash function")
334         }
335
336         // RFC 4880, section 5.2.4
337         pk.SerializeSignaturePrefix(h)
338         pk.serializeWithoutHeaders(h)
339
340         var buf [5]byte
341         buf[0] = 0xb4
342         buf[1] = byte(len(id) >> 24)
343         buf[2] = byte(len(id) >> 16)
344         buf[3] = byte(len(id) >> 8)
345         buf[4] = byte(len(id))
346         h.Write(buf[:])
347         h.Write([]byte(id))
348
349         return
350 }
351
352 // VerifyUserIdSignature returns nil iff sig is a valid signature, made by this
353 // public key, of id.
354 func (pk *PublicKey) VerifyUserIdSignature(id string, sig *Signature) (err error) {
355         h, err := userIdSignatureHash(id, pk, sig)
356         if err != nil {
357                 return err
358         }
359         return pk.VerifySignature(h, sig)
360 }
361
362 // KeyIdString returns the public key's fingerprint in capital hex
363 // (e.g. "6C7EE1B8621CC013").
364 func (pk *PublicKey) KeyIdString() string {
365         return fmt.Sprintf("%X", pk.Fingerprint[12:20])
366 }
367
368 // KeyIdShortString returns the short form of public key's fingerprint
369 // in capital hex, as shown by gpg --list-keys (e.g. "621CC013").
370 func (pk *PublicKey) KeyIdShortString() string {
371         return fmt.Sprintf("%X", pk.Fingerprint[16:20])
372 }
373
374 // A parsedMPI is used to store the contents of a big integer, along with the
375 // bit length that was specified in the original input. This allows the MPI to
376 // be reserialized exactly.
377 type parsedMPI struct {
378         bytes     []byte
379         bitLength uint16
380 }
381
382 // writeMPIs is a utility function for serializing several big integers to the
383 // given Writer.
384 func writeMPIs(w io.Writer, mpis ...parsedMPI) (err error) {
385         for _, mpi := range mpis {
386                 err = writeMPI(w, mpi.bitLength, mpi.bytes)
387                 if err != nil {
388                         return
389                 }
390         }
391         return
392 }