diff options
Diffstat (limited to 'vendor/golang.org/x/crypto/openpgp/packet/signature_v3.go')
-rw-r--r-- | vendor/golang.org/x/crypto/openpgp/packet/signature_v3.go | 146 |
1 files changed, 146 insertions, 0 deletions
diff --git a/vendor/golang.org/x/crypto/openpgp/packet/signature_v3.go b/vendor/golang.org/x/crypto/openpgp/packet/signature_v3.go new file mode 100644 index 0000000..6edff88 --- /dev/null +++ b/vendor/golang.org/x/crypto/openpgp/packet/signature_v3.go | |||
@@ -0,0 +1,146 @@ | |||
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 | "encoding/binary" | ||
10 | "fmt" | ||
11 | "io" | ||
12 | "strconv" | ||
13 | "time" | ||
14 | |||
15 | "golang.org/x/crypto/openpgp/errors" | ||
16 | "golang.org/x/crypto/openpgp/s2k" | ||
17 | ) | ||
18 | |||
19 | // SignatureV3 represents older version 3 signatures. These signatures are less secure | ||
20 | // than version 4 and should not be used to create new signatures. They are included | ||
21 | // here for backwards compatibility to read and validate with older key material. | ||
22 | // See RFC 4880, section 5.2.2. | ||
23 | type SignatureV3 struct { | ||
24 | SigType SignatureType | ||
25 | CreationTime time.Time | ||
26 | IssuerKeyId uint64 | ||
27 | PubKeyAlgo PublicKeyAlgorithm | ||
28 | Hash crypto.Hash | ||
29 | HashTag [2]byte | ||
30 | |||
31 | RSASignature parsedMPI | ||
32 | DSASigR, DSASigS parsedMPI | ||
33 | } | ||
34 | |||
35 | func (sig *SignatureV3) parse(r io.Reader) (err error) { | ||
36 | // RFC 4880, section 5.2.2 | ||
37 | var buf [8]byte | ||
38 | if _, err = readFull(r, buf[:1]); err != nil { | ||
39 | return | ||
40 | } | ||
41 | if buf[0] < 2 || buf[0] > 3 { | ||
42 | err = errors.UnsupportedError("signature packet version " + strconv.Itoa(int(buf[0]))) | ||
43 | return | ||
44 | } | ||
45 | if _, err = readFull(r, buf[:1]); err != nil { | ||
46 | return | ||
47 | } | ||
48 | if buf[0] != 5 { | ||
49 | err = errors.UnsupportedError( | ||
50 | "invalid hashed material length " + strconv.Itoa(int(buf[0]))) | ||
51 | return | ||
52 | } | ||
53 | |||
54 | // Read hashed material: signature type + creation time | ||
55 | if _, err = readFull(r, buf[:5]); err != nil { | ||
56 | return | ||
57 | } | ||
58 | sig.SigType = SignatureType(buf[0]) | ||
59 | t := binary.BigEndian.Uint32(buf[1:5]) | ||
60 | sig.CreationTime = time.Unix(int64(t), 0) | ||
61 | |||
62 | // Eight-octet Key ID of signer. | ||
63 | if _, err = readFull(r, buf[:8]); err != nil { | ||
64 | return | ||
65 | } | ||
66 | sig.IssuerKeyId = binary.BigEndian.Uint64(buf[:]) | ||
67 | |||
68 | // Public-key and hash algorithm | ||
69 | if _, err = readFull(r, buf[:2]); err != nil { | ||
70 | return | ||
71 | } | ||
72 | sig.PubKeyAlgo = PublicKeyAlgorithm(buf[0]) | ||
73 | switch sig.PubKeyAlgo { | ||
74 | case PubKeyAlgoRSA, PubKeyAlgoRSASignOnly, PubKeyAlgoDSA: | ||
75 | default: | ||
76 | err = errors.UnsupportedError("public key algorithm " + strconv.Itoa(int(sig.PubKeyAlgo))) | ||
77 | return | ||
78 | } | ||
79 | var ok bool | ||
80 | if sig.Hash, ok = s2k.HashIdToHash(buf[1]); !ok { | ||
81 | return errors.UnsupportedError("hash function " + strconv.Itoa(int(buf[2]))) | ||
82 | } | ||
83 | |||
84 | // Two-octet field holding left 16 bits of signed hash value. | ||
85 | if _, err = readFull(r, sig.HashTag[:2]); err != nil { | ||
86 | return | ||
87 | } | ||
88 | |||
89 | switch sig.PubKeyAlgo { | ||
90 | case PubKeyAlgoRSA, PubKeyAlgoRSASignOnly: | ||
91 | sig.RSASignature.bytes, sig.RSASignature.bitLength, err = readMPI(r) | ||
92 | case PubKeyAlgoDSA: | ||
93 | if sig.DSASigR.bytes, sig.DSASigR.bitLength, err = readMPI(r); err != nil { | ||
94 | return | ||
95 | } | ||
96 | sig.DSASigS.bytes, sig.DSASigS.bitLength, err = readMPI(r) | ||
97 | default: | ||
98 | panic("unreachable") | ||
99 | } | ||
100 | return | ||
101 | } | ||
102 | |||
103 | // Serialize marshals sig to w. Sign, SignUserId or SignKey must have been | ||
104 | // called first. | ||
105 | func (sig *SignatureV3) Serialize(w io.Writer) (err error) { | ||
106 | buf := make([]byte, 8) | ||
107 | |||
108 | // Write the sig type and creation time | ||
109 | buf[0] = byte(sig.SigType) | ||
110 | binary.BigEndian.PutUint32(buf[1:5], uint32(sig.CreationTime.Unix())) | ||
111 | if _, err = w.Write(buf[:5]); err != nil { | ||
112 | return | ||
113 | } | ||
114 | |||
115 | // Write the issuer long key ID | ||
116 | binary.BigEndian.PutUint64(buf[:8], sig.IssuerKeyId) | ||
117 | if _, err = w.Write(buf[:8]); err != nil { | ||
118 | return | ||
119 | } | ||
120 | |||
121 | // Write public key algorithm, hash ID, and hash value | ||
122 | buf[0] = byte(sig.PubKeyAlgo) | ||
123 | hashId, ok := s2k.HashToHashId(sig.Hash) | ||
124 | if !ok { | ||
125 | return errors.UnsupportedError(fmt.Sprintf("hash function %v", sig.Hash)) | ||
126 | } | ||
127 | buf[1] = hashId | ||
128 | copy(buf[2:4], sig.HashTag[:]) | ||
129 | if _, err = w.Write(buf[:4]); err != nil { | ||
130 | return | ||
131 | } | ||
132 | |||
133 | if sig.RSASignature.bytes == nil && sig.DSASigR.bytes == nil { | ||
134 | return errors.InvalidArgumentError("Signature: need to call Sign, SignUserId or SignKey before Serialize") | ||
135 | } | ||
136 | |||
137 | switch sig.PubKeyAlgo { | ||
138 | case PubKeyAlgoRSA, PubKeyAlgoRSASignOnly: | ||
139 | err = writeMPIs(w, sig.RSASignature) | ||
140 | case PubKeyAlgoDSA: | ||
141 | err = writeMPIs(w, sig.DSASigR, sig.DSASigS) | ||
142 | default: | ||
143 | panic("impossible") | ||
144 | } | ||
145 | return | ||
146 | } | ||