]>
Commit | Line | Data |
---|---|---|
c680a8e1 RS |
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 | "crypto" | |
9 | "encoding/binary" | |
10 | "golang.org/x/crypto/openpgp/errors" | |
11 | "golang.org/x/crypto/openpgp/s2k" | |
12 | "io" | |
13 | "strconv" | |
14 | ) | |
15 | ||
16 | // OnePassSignature represents a one-pass signature packet. See RFC 4880, | |
17 | // section 5.4. | |
18 | type OnePassSignature struct { | |
19 | SigType SignatureType | |
20 | Hash crypto.Hash | |
21 | PubKeyAlgo PublicKeyAlgorithm | |
22 | KeyId uint64 | |
23 | IsLast bool | |
24 | } | |
25 | ||
26 | const onePassSignatureVersion = 3 | |
27 | ||
28 | func (ops *OnePassSignature) parse(r io.Reader) (err error) { | |
29 | var buf [13]byte | |
30 | ||
31 | _, err = readFull(r, buf[:]) | |
32 | if err != nil { | |
33 | return | |
34 | } | |
35 | if buf[0] != onePassSignatureVersion { | |
36 | err = errors.UnsupportedError("one-pass-signature packet version " + strconv.Itoa(int(buf[0]))) | |
37 | } | |
38 | ||
39 | var ok bool | |
40 | ops.Hash, ok = s2k.HashIdToHash(buf[2]) | |
41 | if !ok { | |
42 | return errors.UnsupportedError("hash function: " + strconv.Itoa(int(buf[2]))) | |
43 | } | |
44 | ||
45 | ops.SigType = SignatureType(buf[1]) | |
46 | ops.PubKeyAlgo = PublicKeyAlgorithm(buf[3]) | |
47 | ops.KeyId = binary.BigEndian.Uint64(buf[4:12]) | |
48 | ops.IsLast = buf[12] != 0 | |
49 | return | |
50 | } | |
51 | ||
52 | // Serialize marshals the given OnePassSignature to w. | |
53 | func (ops *OnePassSignature) Serialize(w io.Writer) error { | |
54 | var buf [13]byte | |
55 | buf[0] = onePassSignatureVersion | |
56 | buf[1] = uint8(ops.SigType) | |
57 | var ok bool | |
58 | buf[2], ok = s2k.HashToHashId(ops.Hash) | |
59 | if !ok { | |
60 | return errors.UnsupportedError("hash type: " + strconv.Itoa(int(ops.Hash))) | |
61 | } | |
62 | buf[3] = uint8(ops.PubKeyAlgo) | |
63 | binary.BigEndian.PutUint64(buf[4:12], ops.KeyId) | |
64 | if ops.IsLast { | |
65 | buf[12] = 1 | |
66 | } | |
67 | ||
68 | if err := serializeHeader(w, packetTypeOnePassSignature, len(buf)); err != nil { | |
69 | return err | |
70 | } | |
71 | _, err := w.Write(buf[:]) | |
72 | return err | |
73 | } |