diff options
author | Radek Simko <radek.simko@gmail.com> | 2017-08-14 16:10:17 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2017-08-14 16:10:17 +0200 |
commit | 00a66330be57dc8d7f987b4235d65d372f6b471f (patch) | |
tree | 864f925049d422033dd25a73bafce32b361c8827 /vendor/golang.org/x/crypto/openpgp/packet | |
parent | b6a7c48445fdb87dcae46906aa7e9349209d8bb5 (diff) | |
parent | c680a8e1622ed0f18751d9d167c836ee24f5e897 (diff) | |
download | terraform-provider-statuscake-00a66330be57dc8d7f987b4235d65d372f6b471f.tar.gz terraform-provider-statuscake-00a66330be57dc8d7f987b4235d65d372f6b471f.tar.zst terraform-provider-statuscake-00a66330be57dc8d7f987b4235d65d372f6b471f.zip |
Merge pull request #3 from terraform-providers/vendor-tf-0.10
vendor: github.com/hashicorp/terraform/...@v0.10.0
Diffstat (limited to 'vendor/golang.org/x/crypto/openpgp/packet')
18 files changed, 4473 insertions, 0 deletions
diff --git a/vendor/golang.org/x/crypto/openpgp/packet/compressed.go b/vendor/golang.org/x/crypto/openpgp/packet/compressed.go new file mode 100644 index 0000000..e8f0b5c --- /dev/null +++ b/vendor/golang.org/x/crypto/openpgp/packet/compressed.go | |||
@@ -0,0 +1,123 @@ | |||
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 | "compress/bzip2" | ||
9 | "compress/flate" | ||
10 | "compress/zlib" | ||
11 | "golang.org/x/crypto/openpgp/errors" | ||
12 | "io" | ||
13 | "strconv" | ||
14 | ) | ||
15 | |||
16 | // Compressed represents a compressed OpenPGP packet. The decompressed contents | ||
17 | // will contain more OpenPGP packets. See RFC 4880, section 5.6. | ||
18 | type Compressed struct { | ||
19 | Body io.Reader | ||
20 | } | ||
21 | |||
22 | const ( | ||
23 | NoCompression = flate.NoCompression | ||
24 | BestSpeed = flate.BestSpeed | ||
25 | BestCompression = flate.BestCompression | ||
26 | DefaultCompression = flate.DefaultCompression | ||
27 | ) | ||
28 | |||
29 | // CompressionConfig contains compressor configuration settings. | ||
30 | type CompressionConfig struct { | ||
31 | // Level is the compression level to use. It must be set to | ||
32 | // between -1 and 9, with -1 causing the compressor to use the | ||
33 | // default compression level, 0 causing the compressor to use | ||
34 | // no compression and 1 to 9 representing increasing (better, | ||
35 | // slower) compression levels. If Level is less than -1 or | ||
36 | // more then 9, a non-nil error will be returned during | ||
37 | // encryption. See the constants above for convenient common | ||
38 | // settings for Level. | ||
39 | Level int | ||
40 | } | ||
41 | |||
42 | func (c *Compressed) parse(r io.Reader) error { | ||
43 | var buf [1]byte | ||
44 | _, err := readFull(r, buf[:]) | ||
45 | if err != nil { | ||
46 | return err | ||
47 | } | ||
48 | |||
49 | switch buf[0] { | ||
50 | case 1: | ||
51 | c.Body = flate.NewReader(r) | ||
52 | case 2: | ||
53 | c.Body, err = zlib.NewReader(r) | ||
54 | case 3: | ||
55 | c.Body = bzip2.NewReader(r) | ||
56 | default: | ||
57 | err = errors.UnsupportedError("unknown compression algorithm: " + strconv.Itoa(int(buf[0]))) | ||
58 | } | ||
59 | |||
60 | return err | ||
61 | } | ||
62 | |||
63 | // compressedWriterCloser represents the serialized compression stream | ||
64 | // header and the compressor. Its Close() method ensures that both the | ||
65 | // compressor and serialized stream header are closed. Its Write() | ||
66 | // method writes to the compressor. | ||
67 | type compressedWriteCloser struct { | ||
68 | sh io.Closer // Stream Header | ||
69 | c io.WriteCloser // Compressor | ||
70 | } | ||
71 | |||
72 | func (cwc compressedWriteCloser) Write(p []byte) (int, error) { | ||
73 | return cwc.c.Write(p) | ||
74 | } | ||
75 | |||
76 | func (cwc compressedWriteCloser) Close() (err error) { | ||
77 | err = cwc.c.Close() | ||
78 | if err != nil { | ||
79 | return err | ||
80 | } | ||
81 | |||
82 | return cwc.sh.Close() | ||
83 | } | ||
84 | |||
85 | // SerializeCompressed serializes a compressed data packet to w and | ||
86 | // returns a WriteCloser to which the literal data packets themselves | ||
87 | // can be written and which MUST be closed on completion. If cc is | ||
88 | // nil, sensible defaults will be used to configure the compression | ||
89 | // algorithm. | ||
90 | func SerializeCompressed(w io.WriteCloser, algo CompressionAlgo, cc *CompressionConfig) (literaldata io.WriteCloser, err error) { | ||
91 | compressed, err := serializeStreamHeader(w, packetTypeCompressed) | ||
92 | if err != nil { | ||
93 | return | ||
94 | } | ||
95 | |||
96 | _, err = compressed.Write([]byte{uint8(algo)}) | ||
97 | if err != nil { | ||
98 | return | ||
99 | } | ||
100 | |||
101 | level := DefaultCompression | ||
102 | if cc != nil { | ||
103 | level = cc.Level | ||
104 | } | ||
105 | |||
106 | var compressor io.WriteCloser | ||
107 | switch algo { | ||
108 | case CompressionZIP: | ||
109 | compressor, err = flate.NewWriter(compressed, level) | ||
110 | case CompressionZLIB: | ||
111 | compressor, err = zlib.NewWriterLevel(compressed, level) | ||
112 | default: | ||
113 | s := strconv.Itoa(int(algo)) | ||
114 | err = errors.UnsupportedError("Unsupported compression algorithm: " + s) | ||
115 | } | ||
116 | if err != nil { | ||
117 | return | ||
118 | } | ||
119 | |||
120 | literaldata = compressedWriteCloser{compressed, compressor} | ||
121 | |||
122 | return | ||
123 | } | ||
diff --git a/vendor/golang.org/x/crypto/openpgp/packet/config.go b/vendor/golang.org/x/crypto/openpgp/packet/config.go new file mode 100644 index 0000000..c76eecc --- /dev/null +++ b/vendor/golang.org/x/crypto/openpgp/packet/config.go | |||
@@ -0,0 +1,91 @@ | |||
1 | // Copyright 2012 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/rand" | ||
10 | "io" | ||
11 | "time" | ||
12 | ) | ||
13 | |||
14 | // Config collects a number of parameters along with sensible defaults. | ||
15 | // A nil *Config is valid and results in all default values. | ||
16 | type Config struct { | ||
17 | // Rand provides the source of entropy. | ||
18 | // If nil, the crypto/rand Reader is used. | ||
19 | Rand io.Reader | ||
20 | // DefaultHash is the default hash function to be used. | ||
21 | // If zero, SHA-256 is used. | ||
22 | DefaultHash crypto.Hash | ||
23 | // DefaultCipher is the cipher to be used. | ||
24 | // If zero, AES-128 is used. | ||
25 | DefaultCipher CipherFunction | ||
26 | // Time returns the current time as the number of seconds since the | ||
27 | // epoch. If Time is nil, time.Now is used. | ||
28 | Time func() time.Time | ||
29 | // DefaultCompressionAlgo is the compression algorithm to be | ||
30 | // applied to the plaintext before encryption. If zero, no | ||
31 | // compression is done. | ||
32 | DefaultCompressionAlgo CompressionAlgo | ||
33 | // CompressionConfig configures the compression settings. | ||
34 | CompressionConfig *CompressionConfig | ||
35 | // S2KCount is only used for symmetric encryption. It | ||
36 | // determines the strength of the passphrase stretching when | ||
37 | // the said passphrase is hashed to produce a key. S2KCount | ||
38 | // should be between 1024 and 65011712, inclusive. If Config | ||
39 | // is nil or S2KCount is 0, the value 65536 used. Not all | ||
40 | // values in the above range can be represented. S2KCount will | ||
41 | // be rounded up to the next representable value if it cannot | ||
42 | // be encoded exactly. When set, it is strongly encrouraged to | ||
43 | // use a value that is at least 65536. See RFC 4880 Section | ||
44 | // 3.7.1.3. | ||
45 | S2KCount int | ||
46 | // RSABits is the number of bits in new RSA keys made with NewEntity. | ||
47 | // If zero, then 2048 bit keys are created. | ||
48 | RSABits int | ||
49 | } | ||
50 | |||
51 | func (c *Config) Random() io.Reader { | ||
52 | if c == nil || c.Rand == nil { | ||
53 | return rand.Reader | ||
54 | } | ||
55 | return c.Rand | ||
56 | } | ||
57 | |||
58 | func (c *Config) Hash() crypto.Hash { | ||
59 | if c == nil || uint(c.DefaultHash) == 0 { | ||
60 | return crypto.SHA256 | ||
61 | } | ||
62 | return c.DefaultHash | ||
63 | } | ||
64 | |||
65 | func (c *Config) Cipher() CipherFunction { | ||
66 | if c == nil || uint8(c.DefaultCipher) == 0 { | ||
67 | return CipherAES128 | ||
68 | } | ||
69 | return c.DefaultCipher | ||
70 | } | ||
71 | |||
72 | func (c *Config) Now() time.Time { | ||
73 | if c == nil || c.Time == nil { | ||
74 | return time.Now() | ||
75 | } | ||
76 | return c.Time() | ||
77 | } | ||
78 | |||
79 | func (c *Config) Compression() CompressionAlgo { | ||
80 | if c == nil { | ||
81 | return CompressionNone | ||
82 | } | ||
83 | return c.DefaultCompressionAlgo | ||
84 | } | ||
85 | |||
86 | func (c *Config) PasswordHashIterations() int { | ||
87 | if c == nil || c.S2KCount == 0 { | ||
88 | return 0 | ||
89 | } | ||
90 | return c.S2KCount | ||
91 | } | ||
diff --git a/vendor/golang.org/x/crypto/openpgp/packet/encrypted_key.go b/vendor/golang.org/x/crypto/openpgp/packet/encrypted_key.go new file mode 100644 index 0000000..266840d --- /dev/null +++ b/vendor/golang.org/x/crypto/openpgp/packet/encrypted_key.go | |||
@@ -0,0 +1,199 @@ | |||
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/rsa" | ||
9 | "encoding/binary" | ||
10 | "io" | ||
11 | "math/big" | ||
12 | "strconv" | ||
13 | |||
14 | "golang.org/x/crypto/openpgp/elgamal" | ||
15 | "golang.org/x/crypto/openpgp/errors" | ||
16 | ) | ||
17 | |||
18 | const encryptedKeyVersion = 3 | ||
19 | |||
20 | // EncryptedKey represents a public-key encrypted session key. See RFC 4880, | ||
21 | // section 5.1. | ||
22 | type EncryptedKey struct { | ||
23 | KeyId uint64 | ||
24 | Algo PublicKeyAlgorithm | ||
25 | CipherFunc CipherFunction // only valid after a successful Decrypt | ||
26 | Key []byte // only valid after a successful Decrypt | ||
27 | |||
28 | encryptedMPI1, encryptedMPI2 parsedMPI | ||
29 | } | ||
30 | |||
31 | func (e *EncryptedKey) parse(r io.Reader) (err error) { | ||
32 | var buf [10]byte | ||
33 | _, err = readFull(r, buf[:]) | ||
34 | if err != nil { | ||
35 | return | ||
36 | } | ||
37 | if buf[0] != encryptedKeyVersion { | ||
38 | return errors.UnsupportedError("unknown EncryptedKey version " + strconv.Itoa(int(buf[0]))) | ||
39 | } | ||
40 | e.KeyId = binary.BigEndian.Uint64(buf[1:9]) | ||
41 | e.Algo = PublicKeyAlgorithm(buf[9]) | ||
42 | switch e.Algo { | ||
43 | case PubKeyAlgoRSA, PubKeyAlgoRSAEncryptOnly: | ||
44 | e.encryptedMPI1.bytes, e.encryptedMPI1.bitLength, err = readMPI(r) | ||
45 | case PubKeyAlgoElGamal: | ||
46 | e.encryptedMPI1.bytes, e.encryptedMPI1.bitLength, err = readMPI(r) | ||
47 | if err != nil { | ||
48 | return | ||
49 | } | ||
50 | e.encryptedMPI2.bytes, e.encryptedMPI2.bitLength, err = readMPI(r) | ||
51 | } | ||
52 | _, err = consumeAll(r) | ||
53 | return | ||
54 | } | ||
55 | |||
56 | func checksumKeyMaterial(key []byte) uint16 { | ||
57 | var checksum uint16 | ||
58 | for _, v := range key { | ||
59 | checksum += uint16(v) | ||
60 | } | ||
61 | return checksum | ||
62 | } | ||
63 | |||
64 | // Decrypt decrypts an encrypted session key with the given private key. The | ||
65 | // private key must have been decrypted first. | ||
66 | // If config is nil, sensible defaults will be used. | ||
67 | func (e *EncryptedKey) Decrypt(priv *PrivateKey, config *Config) error { | ||
68 | var err error | ||
69 | var b []byte | ||
70 | |||
71 | // TODO(agl): use session key decryption routines here to avoid | ||
72 | // padding oracle attacks. | ||
73 | switch priv.PubKeyAlgo { | ||
74 | case PubKeyAlgoRSA, PubKeyAlgoRSAEncryptOnly: | ||
75 | b, err = rsa.DecryptPKCS1v15(config.Random(), priv.PrivateKey.(*rsa.PrivateKey), e.encryptedMPI1.bytes) | ||
76 | case PubKeyAlgoElGamal: | ||
77 | c1 := new(big.Int).SetBytes(e.encryptedMPI1.bytes) | ||
78 | c2 := new(big.Int).SetBytes(e.encryptedMPI2.bytes) | ||
79 | b, err = elgamal.Decrypt(priv.PrivateKey.(*elgamal.PrivateKey), c1, c2) | ||
80 | default: | ||
81 | err = errors.InvalidArgumentError("cannot decrypted encrypted session key with private key of type " + strconv.Itoa(int(priv.PubKeyAlgo))) | ||
82 | } | ||
83 | |||
84 | if err != nil { | ||
85 | return err | ||
86 | } | ||
87 | |||
88 | e.CipherFunc = CipherFunction(b[0]) | ||
89 | e.Key = b[1 : len(b)-2] | ||
90 | expectedChecksum := uint16(b[len(b)-2])<<8 | uint16(b[len(b)-1]) | ||
91 | checksum := checksumKeyMaterial(e.Key) | ||
92 | if checksum != expectedChecksum { | ||
93 | return errors.StructuralError("EncryptedKey checksum incorrect") | ||
94 | } | ||
95 | |||
96 | return nil | ||
97 | } | ||
98 | |||
99 | // Serialize writes the encrypted key packet, e, to w. | ||
100 | func (e *EncryptedKey) Serialize(w io.Writer) error { | ||
101 | var mpiLen int | ||
102 | switch e.Algo { | ||
103 | case PubKeyAlgoRSA, PubKeyAlgoRSAEncryptOnly: | ||
104 | mpiLen = 2 + len(e.encryptedMPI1.bytes) | ||
105 | case PubKeyAlgoElGamal: | ||
106 | mpiLen = 2 + len(e.encryptedMPI1.bytes) + 2 + len(e.encryptedMPI2.bytes) | ||
107 | default: | ||
108 | return errors.InvalidArgumentError("don't know how to serialize encrypted key type " + strconv.Itoa(int(e.Algo))) | ||
109 | } | ||
110 | |||
111 | serializeHeader(w, packetTypeEncryptedKey, 1 /* version */ +8 /* key id */ +1 /* algo */ +mpiLen) | ||
112 | |||
113 | w.Write([]byte{encryptedKeyVersion}) | ||
114 | binary.Write(w, binary.BigEndian, e.KeyId) | ||
115 | w.Write([]byte{byte(e.Algo)}) | ||
116 | |||
117 | switch e.Algo { | ||
118 | case PubKeyAlgoRSA, PubKeyAlgoRSAEncryptOnly: | ||
119 | writeMPIs(w, e.encryptedMPI1) | ||
120 | case PubKeyAlgoElGamal: | ||
121 | writeMPIs(w, e.encryptedMPI1, e.encryptedMPI2) | ||
122 | default: | ||
123 | panic("internal error") | ||
124 | } | ||
125 | |||
126 | return nil | ||
127 | } | ||
128 | |||
129 | // SerializeEncryptedKey serializes an encrypted key packet to w that contains | ||
130 | // key, encrypted to pub. | ||
131 | // If config is nil, sensible defaults will be used. | ||
132 | func SerializeEncryptedKey(w io.Writer, pub *PublicKey, cipherFunc CipherFunction, key []byte, config *Config) error { | ||
133 | var buf [10]byte | ||
134 | buf[0] = encryptedKeyVersion | ||
135 | binary.BigEndian.PutUint64(buf[1:9], pub.KeyId) | ||
136 | buf[9] = byte(pub.PubKeyAlgo) | ||
137 | |||
138 | keyBlock := make([]byte, 1 /* cipher type */ +len(key)+2 /* checksum */) | ||
139 | keyBlock[0] = byte(cipherFunc) | ||
140 | copy(keyBlock[1:], key) | ||
141 | checksum := checksumKeyMaterial(key) | ||
142 | keyBlock[1+len(key)] = byte(checksum >> 8) | ||
143 | keyBlock[1+len(key)+1] = byte(checksum) | ||
144 | |||
145 | switch pub.PubKeyAlgo { | ||
146 | case PubKeyAlgoRSA, PubKeyAlgoRSAEncryptOnly: | ||
147 | return serializeEncryptedKeyRSA(w, config.Random(), buf, pub.PublicKey.(*rsa.PublicKey), keyBlock) | ||
148 | case PubKeyAlgoElGamal: | ||
149 | return serializeEncryptedKeyElGamal(w, config.Random(), buf, pub.PublicKey.(*elgamal.PublicKey), keyBlock) | ||
150 | case PubKeyAlgoDSA, PubKeyAlgoRSASignOnly: | ||
151 | return errors.InvalidArgumentError("cannot encrypt to public key of type " + strconv.Itoa(int(pub.PubKeyAlgo))) | ||
152 | } | ||
153 | |||
154 | return errors.UnsupportedError("encrypting a key to public key of type " + strconv.Itoa(int(pub.PubKeyAlgo))) | ||
155 | } | ||
156 | |||
157 | func serializeEncryptedKeyRSA(w io.Writer, rand io.Reader, header [10]byte, pub *rsa.PublicKey, keyBlock []byte) error { | ||
158 | cipherText, err := rsa.EncryptPKCS1v15(rand, pub, keyBlock) | ||
159 | if err != nil { | ||
160 | return errors.InvalidArgumentError("RSA encryption failed: " + err.Error()) | ||
161 | } | ||
162 | |||
163 | packetLen := 10 /* header length */ + 2 /* mpi size */ + len(cipherText) | ||
164 | |||
165 | err = serializeHeader(w, packetTypeEncryptedKey, packetLen) | ||
166 | if err != nil { | ||
167 | return err | ||
168 | } | ||
169 | _, err = w.Write(header[:]) | ||
170 | if err != nil { | ||
171 | return err | ||
172 | } | ||
173 | return writeMPI(w, 8*uint16(len(cipherText)), cipherText) | ||
174 | } | ||
175 | |||
176 | func serializeEncryptedKeyElGamal(w io.Writer, rand io.Reader, header [10]byte, pub *elgamal.PublicKey, keyBlock []byte) error { | ||
177 | c1, c2, err := elgamal.Encrypt(rand, pub, keyBlock) | ||
178 | if err != nil { | ||
179 | return errors.InvalidArgumentError("ElGamal encryption failed: " + err.Error()) | ||
180 | } | ||
181 | |||
182 | packetLen := 10 /* header length */ | ||
183 | packetLen += 2 /* mpi size */ + (c1.BitLen()+7)/8 | ||
184 | packetLen += 2 /* mpi size */ + (c2.BitLen()+7)/8 | ||
185 | |||
186 | err = serializeHeader(w, packetTypeEncryptedKey, packetLen) | ||
187 | if err != nil { | ||
188 | return err | ||
189 | } | ||
190 | _, err = w.Write(header[:]) | ||
191 | if err != nil { | ||
192 | return err | ||
193 | } | ||
194 | err = writeBig(w, c1) | ||
195 | if err != nil { | ||
196 | return err | ||
197 | } | ||
198 | return writeBig(w, c2) | ||
199 | } | ||
diff --git a/vendor/golang.org/x/crypto/openpgp/packet/literal.go b/vendor/golang.org/x/crypto/openpgp/packet/literal.go new file mode 100644 index 0000000..1a9ec6e --- /dev/null +++ b/vendor/golang.org/x/crypto/openpgp/packet/literal.go | |||
@@ -0,0 +1,89 @@ | |||
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 | "encoding/binary" | ||
9 | "io" | ||
10 | ) | ||
11 | |||
12 | // LiteralData represents an encrypted file. See RFC 4880, section 5.9. | ||
13 | type LiteralData struct { | ||
14 | IsBinary bool | ||
15 | FileName string | ||
16 | Time uint32 // Unix epoch time. Either creation time or modification time. 0 means undefined. | ||
17 | Body io.Reader | ||
18 | } | ||
19 | |||
20 | // ForEyesOnly returns whether the contents of the LiteralData have been marked | ||
21 | // as especially sensitive. | ||
22 | func (l *LiteralData) ForEyesOnly() bool { | ||
23 | return l.FileName == "_CONSOLE" | ||
24 | } | ||
25 | |||
26 | func (l *LiteralData) parse(r io.Reader) (err error) { | ||
27 | var buf [256]byte | ||
28 | |||
29 | _, err = readFull(r, buf[:2]) | ||
30 | if err != nil { | ||
31 | return | ||
32 | } | ||
33 | |||
34 | l.IsBinary = buf[0] == 'b' | ||
35 | fileNameLen := int(buf[1]) | ||
36 | |||
37 | _, err = readFull(r, buf[:fileNameLen]) | ||
38 | if err != nil { | ||
39 | return | ||
40 | } | ||
41 | |||
42 | l.FileName = string(buf[:fileNameLen]) | ||
43 | |||
44 | _, err = readFull(r, buf[:4]) | ||
45 | if err != nil { | ||
46 | return | ||
47 | } | ||
48 | |||
49 | l.Time = binary.BigEndian.Uint32(buf[:4]) | ||
50 | l.Body = r | ||
51 | return | ||
52 | } | ||
53 | |||
54 | // SerializeLiteral serializes a literal data packet to w and returns a | ||
55 | // WriteCloser to which the data itself can be written and which MUST be closed | ||
56 | // on completion. The fileName is truncated to 255 bytes. | ||
57 | func SerializeLiteral(w io.WriteCloser, isBinary bool, fileName string, time uint32) (plaintext io.WriteCloser, err error) { | ||
58 | var buf [4]byte | ||
59 | buf[0] = 't' | ||
60 | if isBinary { | ||
61 | buf[0] = 'b' | ||
62 | } | ||
63 | if len(fileName) > 255 { | ||
64 | fileName = fileName[:255] | ||
65 | } | ||
66 | buf[1] = byte(len(fileName)) | ||
67 | |||
68 | inner, err := serializeStreamHeader(w, packetTypeLiteralData) | ||
69 | if err != nil { | ||
70 | return | ||
71 | } | ||
72 | |||
73 | _, err = inner.Write(buf[:2]) | ||
74 | if err != nil { | ||
75 | return | ||
76 | } | ||
77 | _, err = inner.Write([]byte(fileName)) | ||
78 | if err != nil { | ||
79 | return | ||
80 | } | ||
81 | binary.BigEndian.PutUint32(buf[:], time) | ||
82 | _, err = inner.Write(buf[:]) | ||
83 | if err != nil { | ||
84 | return | ||
85 | } | ||
86 | |||
87 | plaintext = inner | ||
88 | return | ||
89 | } | ||
diff --git a/vendor/golang.org/x/crypto/openpgp/packet/ocfb.go b/vendor/golang.org/x/crypto/openpgp/packet/ocfb.go new file mode 100644 index 0000000..ce2a33a --- /dev/null +++ b/vendor/golang.org/x/crypto/openpgp/packet/ocfb.go | |||
@@ -0,0 +1,143 @@ | |||
1 | // Copyright 2010 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 | // OpenPGP CFB Mode. http://tools.ietf.org/html/rfc4880#section-13.9 | ||
6 | |||
7 | package packet | ||
8 | |||
9 | import ( | ||
10 | "crypto/cipher" | ||
11 | ) | ||
12 | |||
13 | type ocfbEncrypter struct { | ||
14 | b cipher.Block | ||
15 | fre []byte | ||
16 | outUsed int | ||
17 | } | ||
18 | |||
19 | // An OCFBResyncOption determines if the "resynchronization step" of OCFB is | ||
20 | // performed. | ||
21 | type OCFBResyncOption bool | ||
22 | |||
23 | const ( | ||
24 | OCFBResync OCFBResyncOption = true | ||
25 | OCFBNoResync OCFBResyncOption = false | ||
26 | ) | ||
27 | |||
28 | // NewOCFBEncrypter returns a cipher.Stream which encrypts data with OpenPGP's | ||
29 | // cipher feedback mode using the given cipher.Block, and an initial amount of | ||
30 | // ciphertext. randData must be random bytes and be the same length as the | ||
31 | // cipher.Block's block size. Resync determines if the "resynchronization step" | ||
32 | // from RFC 4880, 13.9 step 7 is performed. Different parts of OpenPGP vary on | ||
33 | // this point. | ||
34 | func NewOCFBEncrypter(block cipher.Block, randData []byte, resync OCFBResyncOption) (cipher.Stream, []byte) { | ||
35 | blockSize := block.BlockSize() | ||
36 | if len(randData) != blockSize { | ||
37 | return nil, nil | ||
38 | } | ||
39 | |||
40 | x := &ocfbEncrypter{ | ||
41 | b: block, | ||
42 | fre: make([]byte, blockSize), | ||
43 | outUsed: 0, | ||
44 | } | ||
45 | prefix := make([]byte, blockSize+2) | ||
46 | |||
47 | block.Encrypt(x.fre, x.fre) | ||
48 | for i := 0; i < blockSize; i++ { | ||
49 | prefix[i] = randData[i] ^ x.fre[i] | ||
50 | } | ||
51 | |||
52 | block.Encrypt(x.fre, prefix[:blockSize]) | ||
53 | prefix[blockSize] = x.fre[0] ^ randData[blockSize-2] | ||
54 | prefix[blockSize+1] = x.fre[1] ^ randData[blockSize-1] | ||
55 | |||
56 | if resync { | ||
57 | block.Encrypt(x.fre, prefix[2:]) | ||
58 | } else { | ||
59 | x.fre[0] = prefix[blockSize] | ||
60 | x.fre[1] = prefix[blockSize+1] | ||
61 | x.outUsed = 2 | ||
62 | } | ||
63 | return x, prefix | ||
64 | } | ||
65 | |||
66 | func (x *ocfbEncrypter) XORKeyStream(dst, src []byte) { | ||
67 | for i := 0; i < len(src); i++ { | ||
68 | if x.outUsed == len(x.fre) { | ||
69 | x.b.Encrypt(x.fre, x.fre) | ||
70 | x.outUsed = 0 | ||
71 | } | ||
72 | |||
73 | x.fre[x.outUsed] ^= src[i] | ||
74 | dst[i] = x.fre[x.outUsed] | ||
75 | x.outUsed++ | ||
76 | } | ||
77 | } | ||
78 | |||
79 | type ocfbDecrypter struct { | ||
80 | b cipher.Block | ||
81 | fre []byte | ||
82 | outUsed int | ||
83 | } | ||
84 | |||
85 | // NewOCFBDecrypter returns a cipher.Stream which decrypts data with OpenPGP's | ||
86 | // cipher feedback mode using the given cipher.Block. Prefix must be the first | ||
87 | // blockSize + 2 bytes of the ciphertext, where blockSize is the cipher.Block's | ||
88 | // block size. If an incorrect key is detected then nil is returned. On | ||
89 | // successful exit, blockSize+2 bytes of decrypted data are written into | ||
90 | // prefix. Resync determines if the "resynchronization step" from RFC 4880, | ||
91 | // 13.9 step 7 is performed. Different parts of OpenPGP vary on this point. | ||
92 | func NewOCFBDecrypter(block cipher.Block, prefix []byte, resync OCFBResyncOption) cipher.Stream { | ||
93 | blockSize := block.BlockSize() | ||
94 | if len(prefix) != blockSize+2 { | ||
95 | return nil | ||
96 | } | ||
97 | |||
98 | x := &ocfbDecrypter{ | ||
99 | b: block, | ||
100 | fre: make([]byte, blockSize), | ||
101 | outUsed: 0, | ||
102 | } | ||
103 | prefixCopy := make([]byte, len(prefix)) | ||
104 | copy(prefixCopy, prefix) | ||
105 | |||
106 | block.Encrypt(x.fre, x.fre) | ||
107 | for i := 0; i < blockSize; i++ { | ||
108 | prefixCopy[i] ^= x.fre[i] | ||
109 | } | ||
110 | |||
111 | block.Encrypt(x.fre, prefix[:blockSize]) | ||
112 | prefixCopy[blockSize] ^= x.fre[0] | ||
113 | prefixCopy[blockSize+1] ^= x.fre[1] | ||
114 | |||
115 | if prefixCopy[blockSize-2] != prefixCopy[blockSize] || | ||
116 | prefixCopy[blockSize-1] != prefixCopy[blockSize+1] { | ||
117 | return nil | ||
118 | } | ||
119 | |||
120 | if resync { | ||
121 | block.Encrypt(x.fre, prefix[2:]) | ||
122 | } else { | ||
123 | x.fre[0] = prefix[blockSize] | ||
124 | x.fre[1] = prefix[blockSize+1] | ||
125 | x.outUsed = 2 | ||
126 | } | ||
127 | copy(prefix, prefixCopy) | ||
128 | return x | ||
129 | } | ||
130 | |||
131 | func (x *ocfbDecrypter) XORKeyStream(dst, src []byte) { | ||
132 | for i := 0; i < len(src); i++ { | ||
133 | if x.outUsed == len(x.fre) { | ||
134 | x.b.Encrypt(x.fre, x.fre) | ||
135 | x.outUsed = 0 | ||
136 | } | ||
137 | |||
138 | c := src[i] | ||
139 | dst[i] = x.fre[x.outUsed] ^ src[i] | ||
140 | x.fre[x.outUsed] = c | ||
141 | x.outUsed++ | ||
142 | } | ||
143 | } | ||
diff --git a/vendor/golang.org/x/crypto/openpgp/packet/one_pass_signature.go b/vendor/golang.org/x/crypto/openpgp/packet/one_pass_signature.go new file mode 100644 index 0000000..1713503 --- /dev/null +++ b/vendor/golang.org/x/crypto/openpgp/packet/one_pass_signature.go | |||
@@ -0,0 +1,73 @@ | |||
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 | } | ||
diff --git a/vendor/golang.org/x/crypto/openpgp/packet/opaque.go b/vendor/golang.org/x/crypto/openpgp/packet/opaque.go new file mode 100644 index 0000000..456d807 --- /dev/null +++ b/vendor/golang.org/x/crypto/openpgp/packet/opaque.go | |||
@@ -0,0 +1,162 @@ | |||
1 | // Copyright 2012 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 | "bytes" | ||
9 | "io" | ||
10 | "io/ioutil" | ||
11 | |||
12 | "golang.org/x/crypto/openpgp/errors" | ||
13 | ) | ||
14 | |||
15 | // OpaquePacket represents an OpenPGP packet as raw, unparsed data. This is | ||
16 | // useful for splitting and storing the original packet contents separately, | ||
17 | // handling unsupported packet types or accessing parts of the packet not yet | ||
18 | // implemented by this package. | ||
19 | type OpaquePacket struct { | ||
20 | // Packet type | ||
21 | Tag uint8 | ||
22 | // Reason why the packet was parsed opaquely | ||
23 | Reason error | ||
24 | // Binary contents of the packet data | ||
25 | Contents []byte | ||
26 | } | ||
27 | |||
28 | func (op *OpaquePacket) parse(r io.Reader) (err error) { | ||
29 | op.Contents, err = ioutil.ReadAll(r) | ||
30 | return | ||
31 | } | ||
32 | |||
33 | // Serialize marshals the packet to a writer in its original form, including | ||
34 | // the packet header. | ||
35 | func (op *OpaquePacket) Serialize(w io.Writer) (err error) { | ||
36 | err = serializeHeader(w, packetType(op.Tag), len(op.Contents)) | ||
37 | if err == nil { | ||
38 | _, err = w.Write(op.Contents) | ||
39 | } | ||
40 | return | ||
41 | } | ||
42 | |||
43 | // Parse attempts to parse the opaque contents into a structure supported by | ||
44 | // this package. If the packet is not known then the result will be another | ||
45 | // OpaquePacket. | ||
46 | func (op *OpaquePacket) Parse() (p Packet, err error) { | ||
47 | hdr := bytes.NewBuffer(nil) | ||
48 | err = serializeHeader(hdr, packetType(op.Tag), len(op.Contents)) | ||
49 | if err != nil { | ||
50 | op.Reason = err | ||
51 | return op, err | ||
52 | } | ||
53 | p, err = Read(io.MultiReader(hdr, bytes.NewBuffer(op.Contents))) | ||
54 | if err != nil { | ||
55 | op.Reason = err | ||
56 | p = op | ||
57 | } | ||
58 | return | ||
59 | } | ||
60 | |||
61 | // OpaqueReader reads OpaquePackets from an io.Reader. | ||
62 | type OpaqueReader struct { | ||
63 | r io.Reader | ||
64 | } | ||
65 | |||
66 | func NewOpaqueReader(r io.Reader) *OpaqueReader { | ||
67 | return &OpaqueReader{r: r} | ||
68 | } | ||
69 | |||
70 | // Read the next OpaquePacket. | ||
71 | func (or *OpaqueReader) Next() (op *OpaquePacket, err error) { | ||
72 | tag, _, contents, err := readHeader(or.r) | ||
73 | if err != nil { | ||
74 | return | ||
75 | } | ||
76 | op = &OpaquePacket{Tag: uint8(tag), Reason: err} | ||
77 | err = op.parse(contents) | ||
78 | if err != nil { | ||
79 | consumeAll(contents) | ||
80 | } | ||
81 | return | ||
82 | } | ||
83 | |||
84 | // OpaqueSubpacket represents an unparsed OpenPGP subpacket, | ||
85 | // as found in signature and user attribute packets. | ||
86 | type OpaqueSubpacket struct { | ||
87 | SubType uint8 | ||
88 | Contents []byte | ||
89 | } | ||
90 | |||
91 | // OpaqueSubpackets extracts opaque, unparsed OpenPGP subpackets from | ||
92 | // their byte representation. | ||
93 | func OpaqueSubpackets(contents []byte) (result []*OpaqueSubpacket, err error) { | ||
94 | var ( | ||
95 | subHeaderLen int | ||
96 | subPacket *OpaqueSubpacket | ||
97 | ) | ||
98 | for len(contents) > 0 { | ||
99 | subHeaderLen, subPacket, err = nextSubpacket(contents) | ||
100 | if err != nil { | ||
101 | break | ||
102 | } | ||
103 | result = append(result, subPacket) | ||
104 | contents = contents[subHeaderLen+len(subPacket.Contents):] | ||
105 | } | ||
106 | return | ||
107 | } | ||
108 | |||
109 | func nextSubpacket(contents []byte) (subHeaderLen int, subPacket *OpaqueSubpacket, err error) { | ||
110 | // RFC 4880, section 5.2.3.1 | ||
111 | var subLen uint32 | ||
112 | if len(contents) < 1 { | ||
113 | goto Truncated | ||
114 | } | ||
115 | subPacket = &OpaqueSubpacket{} | ||
116 | switch { | ||
117 | case contents[0] < 192: | ||
118 | subHeaderLen = 2 // 1 length byte, 1 subtype byte | ||
119 | if len(contents) < subHeaderLen { | ||
120 | goto Truncated | ||
121 | } | ||
122 | subLen = uint32(contents[0]) | ||
123 | contents = contents[1:] | ||
124 | case contents[0] < 255: | ||
125 | subHeaderLen = 3 // 2 length bytes, 1 subtype | ||
126 | if len(contents) < subHeaderLen { | ||
127 | goto Truncated | ||
128 | } | ||
129 | subLen = uint32(contents[0]-192)<<8 + uint32(contents[1]) + 192 | ||
130 | contents = contents[2:] | ||
131 | default: | ||
132 | subHeaderLen = 6 // 5 length bytes, 1 subtype | ||
133 | if len(contents) < subHeaderLen { | ||
134 | goto Truncated | ||
135 | } | ||
136 | subLen = uint32(contents[1])<<24 | | ||
137 | uint32(contents[2])<<16 | | ||
138 | uint32(contents[3])<<8 | | ||
139 | uint32(contents[4]) | ||
140 | contents = contents[5:] | ||
141 | } | ||
142 | if subLen > uint32(len(contents)) || subLen == 0 { | ||
143 | goto Truncated | ||
144 | } | ||
145 | subPacket.SubType = contents[0] | ||
146 | subPacket.Contents = contents[1:subLen] | ||
147 | return | ||
148 | Truncated: | ||
149 | err = errors.StructuralError("subpacket truncated") | ||
150 | return | ||
151 | } | ||
152 | |||
153 | func (osp *OpaqueSubpacket) Serialize(w io.Writer) (err error) { | ||
154 | buf := make([]byte, 6) | ||
155 | n := serializeSubpacketLength(buf, len(osp.Contents)+1) | ||
156 | buf[n] = osp.SubType | ||
157 | if _, err = w.Write(buf[:n+1]); err != nil { | ||
158 | return | ||
159 | } | ||
160 | _, err = w.Write(osp.Contents) | ||
161 | return | ||
162 | } | ||
diff --git a/vendor/golang.org/x/crypto/openpgp/packet/packet.go b/vendor/golang.org/x/crypto/openpgp/packet/packet.go new file mode 100644 index 0000000..3eded93 --- /dev/null +++ b/vendor/golang.org/x/crypto/openpgp/packet/packet.go | |||
@@ -0,0 +1,537 @@ | |||
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 implements parsing and serialization of OpenPGP packets, as | ||
6 | // specified in RFC 4880. | ||
7 | package packet // import "golang.org/x/crypto/openpgp/packet" | ||
8 | |||
9 | import ( | ||
10 | "bufio" | ||
11 | "crypto/aes" | ||
12 | "crypto/cipher" | ||
13 | "crypto/des" | ||
14 | "golang.org/x/crypto/cast5" | ||
15 | "golang.org/x/crypto/openpgp/errors" | ||
16 | "io" | ||
17 | "math/big" | ||
18 | ) | ||
19 | |||
20 | // readFull is the same as io.ReadFull except that reading zero bytes returns | ||
21 | // ErrUnexpectedEOF rather than EOF. | ||
22 | func readFull(r io.Reader, buf []byte) (n int, err error) { | ||
23 | n, err = io.ReadFull(r, buf) | ||
24 | if err == io.EOF { | ||
25 | err = io.ErrUnexpectedEOF | ||
26 | } | ||
27 | return | ||
28 | } | ||
29 | |||
30 | // readLength reads an OpenPGP length from r. See RFC 4880, section 4.2.2. | ||
31 | func readLength(r io.Reader) (length int64, isPartial bool, err error) { | ||
32 | var buf [4]byte | ||
33 | _, err = readFull(r, buf[:1]) | ||
34 | if err != nil { | ||
35 | return | ||
36 | } | ||
37 | switch { | ||
38 | case buf[0] < 192: | ||
39 | length = int64(buf[0]) | ||
40 | case buf[0] < 224: | ||
41 | length = int64(buf[0]-192) << 8 | ||
42 | _, err = readFull(r, buf[0:1]) | ||
43 | if err != nil { | ||
44 | return | ||
45 | } | ||
46 | length += int64(buf[0]) + 192 | ||
47 | case buf[0] < 255: | ||
48 | length = int64(1) << (buf[0] & 0x1f) | ||
49 | isPartial = true | ||
50 | default: | ||
51 | _, err = readFull(r, buf[0:4]) | ||
52 | if err != nil { | ||
53 | return | ||
54 | } | ||
55 | length = int64(buf[0])<<24 | | ||
56 | int64(buf[1])<<16 | | ||
57 | int64(buf[2])<<8 | | ||
58 | int64(buf[3]) | ||
59 | } | ||
60 | return | ||
61 | } | ||
62 | |||
63 | // partialLengthReader wraps an io.Reader and handles OpenPGP partial lengths. | ||
64 | // The continuation lengths are parsed and removed from the stream and EOF is | ||
65 | // returned at the end of the packet. See RFC 4880, section 4.2.2.4. | ||
66 | type partialLengthReader struct { | ||
67 | r io.Reader | ||
68 | remaining int64 | ||
69 | isPartial bool | ||
70 | } | ||
71 | |||
72 | func (r *partialLengthReader) Read(p []byte) (n int, err error) { | ||
73 | for r.remaining == 0 { | ||
74 | if !r.isPartial { | ||
75 | return 0, io.EOF | ||
76 | } | ||
77 | r.remaining, r.isPartial, err = readLength(r.r) | ||
78 | if err != nil { | ||
79 | return 0, err | ||
80 | } | ||
81 | } | ||
82 | |||
83 | toRead := int64(len(p)) | ||
84 | if toRead > r.remaining { | ||
85 | toRead = r.remaining | ||
86 | } | ||
87 | |||
88 | n, err = r.r.Read(p[:int(toRead)]) | ||
89 | r.remaining -= int64(n) | ||
90 | if n < int(toRead) && err == io.EOF { | ||
91 | err = io.ErrUnexpectedEOF | ||
92 | } | ||
93 | return | ||
94 | } | ||
95 | |||
96 | // partialLengthWriter writes a stream of data using OpenPGP partial lengths. | ||
97 | // See RFC 4880, section 4.2.2.4. | ||
98 | type partialLengthWriter struct { | ||
99 | w io.WriteCloser | ||
100 | lengthByte [1]byte | ||
101 | } | ||
102 | |||
103 | func (w *partialLengthWriter) Write(p []byte) (n int, err error) { | ||
104 | for len(p) > 0 { | ||
105 | for power := uint(14); power < 32; power-- { | ||
106 | l := 1 << power | ||
107 | if len(p) >= l { | ||
108 | w.lengthByte[0] = 224 + uint8(power) | ||
109 | _, err = w.w.Write(w.lengthByte[:]) | ||
110 | if err != nil { | ||
111 | return | ||
112 | } | ||
113 | var m int | ||
114 | m, err = w.w.Write(p[:l]) | ||
115 | n += m | ||
116 | if err != nil { | ||
117 | return | ||
118 | } | ||
119 | p = p[l:] | ||
120 | break | ||
121 | } | ||
122 | } | ||
123 | } | ||
124 | return | ||
125 | } | ||
126 | |||
127 | func (w *partialLengthWriter) Close() error { | ||
128 | w.lengthByte[0] = 0 | ||
129 | _, err := w.w.Write(w.lengthByte[:]) | ||
130 | if err != nil { | ||
131 | return err | ||
132 | } | ||
133 | return w.w.Close() | ||
134 | } | ||
135 | |||
136 | // A spanReader is an io.LimitReader, but it returns ErrUnexpectedEOF if the | ||
137 | // underlying Reader returns EOF before the limit has been reached. | ||
138 | type spanReader struct { | ||
139 | r io.Reader | ||
140 | n int64 | ||
141 | } | ||
142 | |||
143 | func (l *spanReader) Read(p []byte) (n int, err error) { | ||
144 | if l.n <= 0 { | ||
145 | return 0, io.EOF | ||
146 | } | ||
147 | if int64(len(p)) > l.n { | ||
148 | p = p[0:l.n] | ||
149 | } | ||
150 | n, err = l.r.Read(p) | ||
151 | l.n -= int64(n) | ||
152 | if l.n > 0 && err == io.EOF { | ||
153 | err = io.ErrUnexpectedEOF | ||
154 | } | ||
155 | return | ||
156 | } | ||
157 | |||
158 | // readHeader parses a packet header and returns an io.Reader which will return | ||
159 | // the contents of the packet. See RFC 4880, section 4.2. | ||
160 | func readHeader(r io.Reader) (tag packetType, length int64, contents io.Reader, err error) { | ||
161 | var buf [4]byte | ||
162 | _, err = io.ReadFull(r, buf[:1]) | ||
163 | if err != nil { | ||
164 | return | ||
165 | } | ||
166 | if buf[0]&0x80 == 0 { | ||
167 | err = errors.StructuralError("tag byte does not have MSB set") | ||
168 | return | ||
169 | } | ||
170 | if buf[0]&0x40 == 0 { | ||
171 | // Old format packet | ||
172 | tag = packetType((buf[0] & 0x3f) >> 2) | ||
173 | lengthType := buf[0] & 3 | ||
174 | if lengthType == 3 { | ||
175 | length = -1 | ||
176 | contents = r | ||
177 | return | ||
178 | } | ||
179 | lengthBytes := 1 << lengthType | ||
180 | _, err = readFull(r, buf[0:lengthBytes]) | ||
181 | if err != nil { | ||
182 | return | ||
183 | } | ||
184 | for i := 0; i < lengthBytes; i++ { | ||
185 | length <<= 8 | ||
186 | length |= int64(buf[i]) | ||
187 | } | ||
188 | contents = &spanReader{r, length} | ||
189 | return | ||
190 | } | ||
191 | |||
192 | // New format packet | ||
193 | tag = packetType(buf[0] & 0x3f) | ||
194 | length, isPartial, err := readLength(r) | ||
195 | if err != nil { | ||
196 | return | ||
197 | } | ||
198 | if isPartial { | ||
199 | contents = &partialLengthReader{ | ||
200 | remaining: length, | ||
201 | isPartial: true, | ||
202 | r: r, | ||
203 | } | ||
204 | length = -1 | ||
205 | } else { | ||
206 | contents = &spanReader{r, length} | ||
207 | } | ||
208 | return | ||
209 | } | ||
210 | |||
211 | // serializeHeader writes an OpenPGP packet header to w. See RFC 4880, section | ||
212 | // 4.2. | ||
213 | func serializeHeader(w io.Writer, ptype packetType, length int) (err error) { | ||
214 | var buf [6]byte | ||
215 | var n int | ||
216 | |||
217 | buf[0] = 0x80 | 0x40 | byte(ptype) | ||
218 | if length < 192 { | ||
219 | buf[1] = byte(length) | ||
220 | n = 2 | ||
221 | } else if length < 8384 { | ||
222 | length -= 192 | ||
223 | buf[1] = 192 + byte(length>>8) | ||
224 | buf[2] = byte(length) | ||
225 | n = 3 | ||
226 | } else { | ||
227 | buf[1] = 255 | ||
228 | buf[2] = byte(length >> 24) | ||
229 | buf[3] = byte(length >> 16) | ||
230 | buf[4] = byte(length >> 8) | ||
231 | buf[5] = byte(length) | ||
232 | n = 6 | ||
233 | } | ||
234 | |||
235 | _, err = w.Write(buf[:n]) | ||
236 | return | ||
237 | } | ||
238 | |||
239 | // serializeStreamHeader writes an OpenPGP packet header to w where the | ||
240 | // length of the packet is unknown. It returns a io.WriteCloser which can be | ||
241 | // used to write the contents of the packet. See RFC 4880, section 4.2. | ||
242 | func serializeStreamHeader(w io.WriteCloser, ptype packetType) (out io.WriteCloser, err error) { | ||
243 | var buf [1]byte | ||
244 | buf[0] = 0x80 | 0x40 | byte(ptype) | ||
245 | _, err = w.Write(buf[:]) | ||
246 | if err != nil { | ||
247 | return | ||
248 | } | ||
249 | out = &partialLengthWriter{w: w} | ||
250 | return | ||
251 | } | ||
252 | |||
253 | // Packet represents an OpenPGP packet. Users are expected to try casting | ||
254 | // instances of this interface to specific packet types. | ||
255 | type Packet interface { | ||
256 | parse(io.Reader) error | ||
257 | } | ||
258 | |||
259 | // consumeAll reads from the given Reader until error, returning the number of | ||
260 | // bytes read. | ||
261 | func consumeAll(r io.Reader) (n int64, err error) { | ||
262 | var m int | ||
263 | var buf [1024]byte | ||
264 | |||
265 | for { | ||
266 | m, err = r.Read(buf[:]) | ||
267 | n += int64(m) | ||
268 | if err == io.EOF { | ||
269 | err = nil | ||
270 | return | ||
271 | } | ||
272 | if err != nil { | ||
273 | return | ||
274 | } | ||
275 | } | ||
276 | } | ||
277 | |||
278 | // packetType represents the numeric ids of the different OpenPGP packet types. See | ||
279 | // http://www.iana.org/assignments/pgp-parameters/pgp-parameters.xhtml#pgp-parameters-2 | ||
280 | type packetType uint8 | ||
281 | |||
282 | const ( | ||
283 | packetTypeEncryptedKey packetType = 1 | ||
284 | packetTypeSignature packetType = 2 | ||
285 | packetTypeSymmetricKeyEncrypted packetType = 3 | ||
286 | packetTypeOnePassSignature packetType = 4 | ||
287 | packetTypePrivateKey packetType = 5 | ||
288 | packetTypePublicKey packetType = 6 | ||
289 | packetTypePrivateSubkey packetType = 7 | ||
290 | packetTypeCompressed packetType = 8 | ||
291 | packetTypeSymmetricallyEncrypted packetType = 9 | ||
292 | packetTypeLiteralData packetType = 11 | ||
293 | packetTypeUserId packetType = 13 | ||
294 | packetTypePublicSubkey packetType = 14 | ||
295 | packetTypeUserAttribute packetType = 17 | ||
296 | packetTypeSymmetricallyEncryptedMDC packetType = 18 | ||
297 | ) | ||
298 | |||
299 | // peekVersion detects the version of a public key packet about to | ||
300 | // be read. A bufio.Reader at the original position of the io.Reader | ||
301 | // is returned. | ||
302 | func peekVersion(r io.Reader) (bufr *bufio.Reader, ver byte, err error) { | ||
303 | bufr = bufio.NewReader(r) | ||
304 | var verBuf []byte | ||
305 | if verBuf, err = bufr.Peek(1); err != nil { | ||
306 | return | ||
307 | } | ||
308 | ver = verBuf[0] | ||
309 | return | ||
310 | } | ||
311 | |||
312 | // Read reads a single OpenPGP packet from the given io.Reader. If there is an | ||
313 | // error parsing a packet, the whole packet is consumed from the input. | ||
314 | func Read(r io.Reader) (p Packet, err error) { | ||
315 | tag, _, contents, err := readHeader(r) | ||
316 | if err != nil { | ||
317 | return | ||
318 | } | ||
319 | |||
320 | switch tag { | ||
321 | case packetTypeEncryptedKey: | ||
322 | p = new(EncryptedKey) | ||
323 | case packetTypeSignature: | ||
324 | var version byte | ||
325 | // Detect signature version | ||
326 | if contents, version, err = peekVersion(contents); err != nil { | ||
327 | return | ||
328 | } | ||
329 | if version < 4 { | ||
330 | p = new(SignatureV3) | ||
331 | } else { | ||
332 | p = new(Signature) | ||
333 | } | ||
334 | case packetTypeSymmetricKeyEncrypted: | ||
335 | p = new(SymmetricKeyEncrypted) | ||
336 | case packetTypeOnePassSignature: | ||
337 | p = new(OnePassSignature) | ||
338 | case packetTypePrivateKey, packetTypePrivateSubkey: | ||
339 | pk := new(PrivateKey) | ||
340 | if tag == packetTypePrivateSubkey { | ||
341 | pk.IsSubkey = true | ||
342 | } | ||
343 | p = pk | ||
344 | case packetTypePublicKey, packetTypePublicSubkey: | ||
345 | var version byte | ||
346 | if contents, version, err = peekVersion(contents); err != nil { | ||
347 | return | ||
348 | } | ||
349 | isSubkey := tag == packetTypePublicSubkey | ||
350 | if version < 4 { | ||
351 | p = &PublicKeyV3{IsSubkey: isSubkey} | ||
352 | } else { | ||
353 | p = &PublicKey{IsSubkey: isSubkey} | ||
354 | } | ||
355 | case packetTypeCompressed: | ||
356 | p = new(Compressed) | ||
357 | case packetTypeSymmetricallyEncrypted: | ||
358 | p = new(SymmetricallyEncrypted) | ||
359 | case packetTypeLiteralData: | ||
360 | p = new(LiteralData) | ||
361 | case packetTypeUserId: | ||
362 | p = new(UserId) | ||
363 | case packetTypeUserAttribute: | ||
364 | p = new(UserAttribute) | ||
365 | case packetTypeSymmetricallyEncryptedMDC: | ||
366 | se := new(SymmetricallyEncrypted) | ||
367 | se.MDC = true | ||
368 | p = se | ||
369 | default: | ||
370 | err = errors.UnknownPacketTypeError(tag) | ||
371 | } | ||
372 | if p != nil { | ||
373 | err = p.parse(contents) | ||
374 | } | ||
375 | if err != nil { | ||
376 | consumeAll(contents) | ||
377 | } | ||
378 | return | ||
379 | } | ||
380 | |||
381 | // SignatureType represents the different semantic meanings of an OpenPGP | ||
382 | // signature. See RFC 4880, section 5.2.1. | ||
383 | type SignatureType uint8 | ||
384 | |||
385 | const ( | ||
386 | SigTypeBinary SignatureType = 0 | ||
387 | SigTypeText = 1 | ||
388 | SigTypeGenericCert = 0x10 | ||
389 | SigTypePersonaCert = 0x11 | ||
390 | SigTypeCasualCert = 0x12 | ||
391 | SigTypePositiveCert = 0x13 | ||
392 | SigTypeSubkeyBinding = 0x18 | ||
393 | SigTypePrimaryKeyBinding = 0x19 | ||
394 | SigTypeDirectSignature = 0x1F | ||
395 | SigTypeKeyRevocation = 0x20 | ||
396 | SigTypeSubkeyRevocation = 0x28 | ||
397 | ) | ||
398 | |||
399 | // PublicKeyAlgorithm represents the different public key system specified for | ||
400 | // OpenPGP. See | ||
401 | // http://www.iana.org/assignments/pgp-parameters/pgp-parameters.xhtml#pgp-parameters-12 | ||
402 | type PublicKeyAlgorithm uint8 | ||
403 | |||
404 | const ( | ||
405 | PubKeyAlgoRSA PublicKeyAlgorithm = 1 | ||
406 | PubKeyAlgoRSAEncryptOnly PublicKeyAlgorithm = 2 | ||
407 | PubKeyAlgoRSASignOnly PublicKeyAlgorithm = 3 | ||
408 | PubKeyAlgoElGamal PublicKeyAlgorithm = 16 | ||
409 | PubKeyAlgoDSA PublicKeyAlgorithm = 17 | ||
410 | // RFC 6637, Section 5. | ||
411 | PubKeyAlgoECDH PublicKeyAlgorithm = 18 | ||
412 | PubKeyAlgoECDSA PublicKeyAlgorithm = 19 | ||
413 | ) | ||
414 | |||
415 | // CanEncrypt returns true if it's possible to encrypt a message to a public | ||
416 | // key of the given type. | ||
417 | func (pka PublicKeyAlgorithm) CanEncrypt() bool { | ||
418 | switch pka { | ||
419 | case PubKeyAlgoRSA, PubKeyAlgoRSAEncryptOnly, PubKeyAlgoElGamal: | ||
420 | return true | ||
421 | } | ||
422 | return false | ||
423 | } | ||
424 | |||
425 | // CanSign returns true if it's possible for a public key of the given type to | ||
426 | // sign a message. | ||
427 | func (pka PublicKeyAlgorithm) CanSign() bool { | ||
428 | switch pka { | ||
429 | case PubKeyAlgoRSA, PubKeyAlgoRSASignOnly, PubKeyAlgoDSA, PubKeyAlgoECDSA: | ||
430 | return true | ||
431 | } | ||
432 | return false | ||
433 | } | ||
434 | |||
435 | // CipherFunction represents the different block ciphers specified for OpenPGP. See | ||
436 | // http://www.iana.org/assignments/pgp-parameters/pgp-parameters.xhtml#pgp-parameters-13 | ||
437 | type CipherFunction uint8 | ||
438 | |||
439 | const ( | ||
440 | Cipher3DES CipherFunction = 2 | ||
441 | CipherCAST5 CipherFunction = 3 | ||
442 | CipherAES128 CipherFunction = 7 | ||
443 | CipherAES192 CipherFunction = 8 | ||
444 | CipherAES256 CipherFunction = 9 | ||
445 | ) | ||
446 | |||
447 | // KeySize returns the key size, in bytes, of cipher. | ||
448 | func (cipher CipherFunction) KeySize() int { | ||
449 | switch cipher { | ||
450 | case Cipher3DES: | ||
451 | return 24 | ||
452 | case CipherCAST5: | ||
453 | return cast5.KeySize | ||
454 | case CipherAES128: | ||
455 | return 16 | ||
456 | case CipherAES192: | ||
457 | return 24 | ||
458 | case CipherAES256: | ||
459 | return 32 | ||
460 | } | ||
461 | return 0 | ||
462 | } | ||
463 | |||
464 | // blockSize returns the block size, in bytes, of cipher. | ||
465 | func (cipher CipherFunction) blockSize() int { | ||
466 | switch cipher { | ||
467 | case Cipher3DES: | ||
468 | return des.BlockSize | ||
469 | case CipherCAST5: | ||
470 | return 8 | ||
471 | case CipherAES128, CipherAES192, CipherAES256: | ||
472 | return 16 | ||
473 | } | ||
474 | return 0 | ||
475 | } | ||
476 | |||
477 | // new returns a fresh instance of the given cipher. | ||
478 | func (cipher CipherFunction) new(key []byte) (block cipher.Block) { | ||
479 | switch cipher { | ||
480 | case Cipher3DES: | ||
481 | block, _ = des.NewTripleDESCipher(key) | ||
482 | case CipherCAST5: | ||
483 | block, _ = cast5.NewCipher(key) | ||
484 | case CipherAES128, CipherAES192, CipherAES256: | ||
485 | block, _ = aes.NewCipher(key) | ||
486 | } | ||
487 | return | ||
488 | } | ||
489 | |||
490 | // readMPI reads a big integer from r. The bit length returned is the bit | ||
491 | // length that was specified in r. This is preserved so that the integer can be | ||
492 | // reserialized exactly. | ||
493 | func readMPI(r io.Reader) (mpi []byte, bitLength uint16, err error) { | ||
494 | var buf [2]byte | ||
495 | _, err = readFull(r, buf[0:]) | ||
496 | if err != nil { | ||
497 | return | ||
498 | } | ||
499 | bitLength = uint16(buf[0])<<8 | uint16(buf[1]) | ||
500 | numBytes := (int(bitLength) + 7) / 8 | ||
501 | mpi = make([]byte, numBytes) | ||
502 | _, err = readFull(r, mpi) | ||
503 | return | ||
504 | } | ||
505 | |||
506 | // mpiLength returns the length of the given *big.Int when serialized as an | ||
507 | // MPI. | ||
508 | func mpiLength(n *big.Int) (mpiLengthInBytes int) { | ||
509 | mpiLengthInBytes = 2 /* MPI length */ | ||
510 | mpiLengthInBytes += (n.BitLen() + 7) / 8 | ||
511 | return | ||
512 | } | ||
513 | |||
514 | // writeMPI serializes a big integer to w. | ||
515 | func writeMPI(w io.Writer, bitLength uint16, mpiBytes []byte) (err error) { | ||
516 | _, err = w.Write([]byte{byte(bitLength >> 8), byte(bitLength)}) | ||
517 | if err == nil { | ||
518 | _, err = w.Write(mpiBytes) | ||
519 | } | ||
520 | return | ||
521 | } | ||
522 | |||
523 | // writeBig serializes a *big.Int to w. | ||
524 | func writeBig(w io.Writer, i *big.Int) error { | ||
525 | return writeMPI(w, uint16(i.BitLen()), i.Bytes()) | ||
526 | } | ||
527 | |||
528 | // CompressionAlgo Represents the different compression algorithms | ||
529 | // supported by OpenPGP (except for BZIP2, which is not currently | ||
530 | // supported). See Section 9.3 of RFC 4880. | ||
531 | type CompressionAlgo uint8 | ||
532 | |||
533 | const ( | ||
534 | CompressionNone CompressionAlgo = 0 | ||
535 | CompressionZIP CompressionAlgo = 1 | ||
536 | CompressionZLIB CompressionAlgo = 2 | ||
537 | ) | ||
diff --git a/vendor/golang.org/x/crypto/openpgp/packet/private_key.go b/vendor/golang.org/x/crypto/openpgp/packet/private_key.go new file mode 100644 index 0000000..34734cc --- /dev/null +++ b/vendor/golang.org/x/crypto/openpgp/packet/private_key.go | |||
@@ -0,0 +1,380 @@ | |||
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 | "bytes" | ||
9 | "crypto" | ||
10 | "crypto/cipher" | ||
11 | "crypto/dsa" | ||
12 | "crypto/ecdsa" | ||
13 | "crypto/rsa" | ||
14 | "crypto/sha1" | ||
15 | "io" | ||
16 | "io/ioutil" | ||
17 | "math/big" | ||
18 | "strconv" | ||
19 | "time" | ||
20 | |||
21 | "golang.org/x/crypto/openpgp/elgamal" | ||
22 | "golang.org/x/crypto/openpgp/errors" | ||
23 | "golang.org/x/crypto/openpgp/s2k" | ||
24 | ) | ||
25 | |||
26 | // PrivateKey represents a possibly encrypted private key. See RFC 4880, | ||
27 | // section 5.5.3. | ||
28 | type PrivateKey struct { | ||
29 | PublicKey | ||
30 | Encrypted bool // if true then the private key is unavailable until Decrypt has been called. | ||
31 | encryptedData []byte | ||
32 | cipher CipherFunction | ||
33 | s2k func(out, in []byte) | ||
34 | PrivateKey interface{} // An *{rsa|dsa|ecdsa}.PrivateKey or a crypto.Signer. | ||
35 | sha1Checksum bool | ||
36 | iv []byte | ||
37 | } | ||
38 | |||
39 | func NewRSAPrivateKey(currentTime time.Time, priv *rsa.PrivateKey) *PrivateKey { | ||
40 | pk := new(PrivateKey) | ||
41 | pk.PublicKey = *NewRSAPublicKey(currentTime, &priv.PublicKey) | ||
42 | pk.PrivateKey = priv | ||
43 | return pk | ||
44 | } | ||
45 | |||
46 | func NewDSAPrivateKey(currentTime time.Time, priv *dsa.PrivateKey) *PrivateKey { | ||
47 | pk := new(PrivateKey) | ||
48 | pk.PublicKey = *NewDSAPublicKey(currentTime, &priv.PublicKey) | ||
49 | pk.PrivateKey = priv | ||
50 | return pk | ||
51 | } | ||
52 | |||
53 | func NewElGamalPrivateKey(currentTime time.Time, priv *elgamal.PrivateKey) *PrivateKey { | ||
54 | pk := new(PrivateKey) | ||
55 | pk.PublicKey = *NewElGamalPublicKey(currentTime, &priv.PublicKey) | ||
56 | pk.PrivateKey = priv | ||
57 | return pk | ||
58 | } | ||
59 | |||
60 | func NewECDSAPrivateKey(currentTime time.Time, priv *ecdsa.PrivateKey) *PrivateKey { | ||
61 | pk := new(PrivateKey) | ||
62 | pk.PublicKey = *NewECDSAPublicKey(currentTime, &priv.PublicKey) | ||
63 | pk.PrivateKey = priv | ||
64 | return pk | ||
65 | } | ||
66 | |||
67 | // NewSignerPrivateKey creates a sign-only PrivateKey from a crypto.Signer that | ||
68 | // implements RSA or ECDSA. | ||
69 | func NewSignerPrivateKey(currentTime time.Time, signer crypto.Signer) *PrivateKey { | ||
70 | pk := new(PrivateKey) | ||
71 | switch pubkey := signer.Public().(type) { | ||
72 | case rsa.PublicKey: | ||
73 | pk.PublicKey = *NewRSAPublicKey(currentTime, &pubkey) | ||
74 | pk.PubKeyAlgo = PubKeyAlgoRSASignOnly | ||
75 | case ecdsa.PublicKey: | ||
76 | pk.PublicKey = *NewECDSAPublicKey(currentTime, &pubkey) | ||
77 | default: | ||
78 | panic("openpgp: unknown crypto.Signer type in NewSignerPrivateKey") | ||
79 | } | ||
80 | pk.PrivateKey = signer | ||
81 | return pk | ||
82 | } | ||
83 | |||
84 | func (pk *PrivateKey) parse(r io.Reader) (err error) { | ||
85 | err = (&pk.PublicKey).parse(r) | ||
86 | if err != nil { | ||
87 | return | ||
88 | } | ||
89 | var buf [1]byte | ||
90 | _, err = readFull(r, buf[:]) | ||
91 | if err != nil { | ||
92 | return | ||
93 | } | ||
94 | |||
95 | s2kType := buf[0] | ||
96 | |||
97 | switch s2kType { | ||
98 | case 0: | ||
99 | pk.s2k = nil | ||
100 | pk.Encrypted = false | ||
101 | case 254, 255: | ||
102 | _, err = readFull(r, buf[:]) | ||
103 | if err != nil { | ||
104 | return | ||
105 | } | ||
106 | pk.cipher = CipherFunction(buf[0]) | ||
107 | pk.Encrypted = true | ||
108 | pk.s2k, err = s2k.Parse(r) | ||
109 | if err != nil { | ||
110 | return | ||
111 | } | ||
112 | if s2kType == 254 { | ||
113 | pk.sha1Checksum = true | ||
114 | } | ||
115 | default: | ||
116 | return errors.UnsupportedError("deprecated s2k function in private key") | ||
117 | } | ||
118 | |||
119 | if pk.Encrypted { | ||
120 | blockSize := pk.cipher.blockSize() | ||
121 | if blockSize == 0 { | ||
122 | return errors.UnsupportedError("unsupported cipher in private key: " + strconv.Itoa(int(pk.cipher))) | ||
123 | } | ||
124 | pk.iv = make([]byte, blockSize) | ||
125 | _, err = readFull(r, pk.iv) | ||
126 | if err != nil { | ||
127 | return | ||
128 | } | ||
129 | } | ||
130 | |||
131 | pk.encryptedData, err = ioutil.ReadAll(r) | ||
132 | if err != nil { | ||
133 | return | ||
134 | } | ||
135 | |||
136 | if !pk.Encrypted { | ||
137 | return pk.parsePrivateKey(pk.encryptedData) | ||
138 | } | ||
139 | |||
140 | return | ||
141 | } | ||
142 | |||
143 | func mod64kHash(d []byte) uint16 { | ||
144 | var h uint16 | ||
145 | for _, b := range d { | ||
146 | h += uint16(b) | ||
147 | } | ||
148 | return h | ||
149 | } | ||
150 | |||
151 | func (pk *PrivateKey) Serialize(w io.Writer) (err error) { | ||
152 | // TODO(agl): support encrypted private keys | ||
153 | buf := bytes.NewBuffer(nil) | ||
154 | err = pk.PublicKey.serializeWithoutHeaders(buf) | ||
155 | if err != nil { | ||
156 | return | ||
157 | } | ||
158 | buf.WriteByte(0 /* no encryption */) | ||
159 | |||
160 | privateKeyBuf := bytes.NewBuffer(nil) | ||
161 | |||
162 | switch priv := pk.PrivateKey.(type) { | ||
163 | case *rsa.PrivateKey: | ||
164 | err = serializeRSAPrivateKey(privateKeyBuf, priv) | ||
165 | case *dsa.PrivateKey: | ||
166 | err = serializeDSAPrivateKey(privateKeyBuf, priv) | ||
167 | case *elgamal.PrivateKey: | ||
168 | err = serializeElGamalPrivateKey(privateKeyBuf, priv) | ||
169 | case *ecdsa.PrivateKey: | ||
170 | err = serializeECDSAPrivateKey(privateKeyBuf, priv) | ||
171 | default: | ||
172 | err = errors.InvalidArgumentError("unknown private key type") | ||
173 | } | ||
174 | if err != nil { | ||
175 | return | ||
176 | } | ||
177 | |||
178 | ptype := packetTypePrivateKey | ||
179 | contents := buf.Bytes() | ||
180 | privateKeyBytes := privateKeyBuf.Bytes() | ||
181 | if pk.IsSubkey { | ||
182 | ptype = packetTypePrivateSubkey | ||
183 | } | ||
184 | err = serializeHeader(w, ptype, len(contents)+len(privateKeyBytes)+2) | ||
185 | if err != nil { | ||
186 | return | ||
187 | } | ||
188 | _, err = w.Write(contents) | ||
189 | if err != nil { | ||
190 | return | ||
191 | } | ||
192 | _, err = w.Write(privateKeyBytes) | ||
193 | if err != nil { | ||
194 | return | ||
195 | } | ||
196 | |||
197 | checksum := mod64kHash(privateKeyBytes) | ||
198 | var checksumBytes [2]byte | ||
199 | checksumBytes[0] = byte(checksum >> 8) | ||
200 | checksumBytes[1] = byte(checksum) | ||
201 | _, err = w.Write(checksumBytes[:]) | ||
202 | |||
203 | return | ||
204 | } | ||
205 | |||
206 | func serializeRSAPrivateKey(w io.Writer, priv *rsa.PrivateKey) error { | ||
207 | err := writeBig(w, priv.D) | ||
208 | if err != nil { | ||
209 | return err | ||
210 | } | ||
211 | err = writeBig(w, priv.Primes[1]) | ||
212 | if err != nil { | ||
213 | return err | ||
214 | } | ||
215 | err = writeBig(w, priv.Primes[0]) | ||
216 | if err != nil { | ||
217 | return err | ||
218 | } | ||
219 | return writeBig(w, priv.Precomputed.Qinv) | ||
220 | } | ||
221 | |||
222 | func serializeDSAPrivateKey(w io.Writer, priv *dsa.PrivateKey) error { | ||
223 | return writeBig(w, priv.X) | ||
224 | } | ||
225 | |||
226 | func serializeElGamalPrivateKey(w io.Writer, priv *elgamal.PrivateKey) error { | ||
227 | return writeBig(w, priv.X) | ||
228 | } | ||
229 | |||
230 | func serializeECDSAPrivateKey(w io.Writer, priv *ecdsa.PrivateKey) error { | ||
231 | return writeBig(w, priv.D) | ||
232 | } | ||
233 | |||
234 | // Decrypt decrypts an encrypted private key using a passphrase. | ||
235 | func (pk *PrivateKey) Decrypt(passphrase []byte) error { | ||
236 | if !pk.Encrypted { | ||
237 | return nil | ||
238 | } | ||
239 | |||
240 | key := make([]byte, pk.cipher.KeySize()) | ||
241 | pk.s2k(key, passphrase) | ||
242 | block := pk.cipher.new(key) | ||
243 | cfb := cipher.NewCFBDecrypter(block, pk.iv) | ||
244 | |||
245 | data := make([]byte, len(pk.encryptedData)) | ||
246 | cfb.XORKeyStream(data, pk.encryptedData) | ||
247 | |||
248 | if pk.sha1Checksum { | ||
249 | if len(data) < sha1.Size { | ||
250 | return errors.StructuralError("truncated private key data") | ||
251 | } | ||
252 | h := sha1.New() | ||
253 | h.Write(data[:len(data)-sha1.Size]) | ||
254 | sum := h.Sum(nil) | ||
255 | if !bytes.Equal(sum, data[len(data)-sha1.Size:]) { | ||
256 | return errors.StructuralError("private key checksum failure") | ||
257 | } | ||
258 | data = data[:len(data)-sha1.Size] | ||
259 | } else { | ||
260 | if len(data) < 2 { | ||
261 | return errors.StructuralError("truncated private key data") | ||
262 | } | ||
263 | var sum uint16 | ||
264 | for i := 0; i < len(data)-2; i++ { | ||
265 | sum += uint16(data[i]) | ||
266 | } | ||
267 | if data[len(data)-2] != uint8(sum>>8) || | ||
268 | data[len(data)-1] != uint8(sum) { | ||
269 | return errors.StructuralError("private key checksum failure") | ||
270 | } | ||
271 | data = data[:len(data)-2] | ||
272 | } | ||
273 | |||
274 | return pk.parsePrivateKey(data) | ||
275 | } | ||
276 | |||
277 | func (pk *PrivateKey) parsePrivateKey(data []byte) (err error) { | ||
278 | switch pk.PublicKey.PubKeyAlgo { | ||
279 | case PubKeyAlgoRSA, PubKeyAlgoRSASignOnly, PubKeyAlgoRSAEncryptOnly: | ||
280 | return pk.parseRSAPrivateKey(data) | ||
281 | case PubKeyAlgoDSA: | ||
282 | return pk.parseDSAPrivateKey(data) | ||
283 | case PubKeyAlgoElGamal: | ||
284 | return pk.parseElGamalPrivateKey(data) | ||
285 | case PubKeyAlgoECDSA: | ||
286 | return pk.parseECDSAPrivateKey(data) | ||
287 | } | ||
288 | panic("impossible") | ||
289 | } | ||
290 | |||
291 | func (pk *PrivateKey) parseRSAPrivateKey(data []byte) (err error) { | ||
292 | rsaPub := pk.PublicKey.PublicKey.(*rsa.PublicKey) | ||
293 | rsaPriv := new(rsa.PrivateKey) | ||
294 | rsaPriv.PublicKey = *rsaPub | ||
295 | |||
296 | buf := bytes.NewBuffer(data) | ||
297 | d, _, err := readMPI(buf) | ||
298 | if err != nil { | ||
299 | return | ||
300 | } | ||
301 | p, _, err := readMPI(buf) | ||
302 | if err != nil { | ||
303 | return | ||
304 | } | ||
305 | q, _, err := readMPI(buf) | ||
306 | if err != nil { | ||
307 | return | ||
308 | } | ||
309 | |||
310 | rsaPriv.D = new(big.Int).SetBytes(d) | ||
311 | rsaPriv.Primes = make([]*big.Int, 2) | ||
312 | rsaPriv.Primes[0] = new(big.Int).SetBytes(p) | ||
313 | rsaPriv.Primes[1] = new(big.Int).SetBytes(q) | ||
314 | if err := rsaPriv.Validate(); err != nil { | ||
315 | return err | ||
316 | } | ||
317 | rsaPriv.Precompute() | ||
318 | pk.PrivateKey = rsaPriv | ||
319 | pk.Encrypted = false | ||
320 | pk.encryptedData = nil | ||
321 | |||
322 | return nil | ||
323 | } | ||
324 | |||
325 | func (pk *PrivateKey) parseDSAPrivateKey(data []byte) (err error) { | ||
326 | dsaPub := pk.PublicKey.PublicKey.(*dsa.PublicKey) | ||
327 | dsaPriv := new(dsa.PrivateKey) | ||
328 | dsaPriv.PublicKey = *dsaPub | ||
329 | |||
330 | buf := bytes.NewBuffer(data) | ||
331 | x, _, err := readMPI(buf) | ||
332 | if err != nil { | ||
333 | return | ||
334 | } | ||
335 | |||
336 | dsaPriv.X = new(big.Int).SetBytes(x) | ||
337 | pk.PrivateKey = dsaPriv | ||
338 | pk.Encrypted = false | ||
339 | pk.encryptedData = nil | ||
340 | |||
341 | return nil | ||
342 | } | ||
343 | |||
344 | func (pk *PrivateKey) parseElGamalPrivateKey(data []byte) (err error) { | ||
345 | pub := pk.PublicKey.PublicKey.(*elgamal.PublicKey) | ||
346 | priv := new(elgamal.PrivateKey) | ||
347 | priv.PublicKey = *pub | ||
348 | |||
349 | buf := bytes.NewBuffer(data) | ||
350 | x, _, err := readMPI(buf) | ||
351 | if err != nil { | ||
352 | return | ||
353 | } | ||
354 | |||
355 | priv.X = new(big.Int).SetBytes(x) | ||
356 | pk.PrivateKey = priv | ||
357 | pk.Encrypted = false | ||
358 | pk.encryptedData = nil | ||
359 | |||
360 | return nil | ||
361 | } | ||
362 | |||
363 | func (pk *PrivateKey) parseECDSAPrivateKey(data []byte) (err error) { | ||
364 | ecdsaPub := pk.PublicKey.PublicKey.(*ecdsa.PublicKey) | ||
365 | |||
366 | buf := bytes.NewBuffer(data) | ||
367 | d, _, err := readMPI(buf) | ||
368 | if err != nil { | ||
369 | return | ||
370 | } | ||
371 | |||
372 | pk.PrivateKey = &ecdsa.PrivateKey{ | ||
373 | PublicKey: *ecdsaPub, | ||
374 | D: new(big.Int).SetBytes(d), | ||
375 | } | ||
376 | pk.Encrypted = false | ||
377 | pk.encryptedData = nil | ||
378 | |||
379 | return nil | ||
380 | } | ||
diff --git a/vendor/golang.org/x/crypto/openpgp/packet/public_key.go b/vendor/golang.org/x/crypto/openpgp/packet/public_key.go new file mode 100644 index 0000000..ead2623 --- /dev/null +++ b/vendor/golang.org/x/crypto/openpgp/packet/public_key.go | |||
@@ -0,0 +1,748 @@ | |||
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 | "bytes" | ||
9 | "crypto" | ||
10 | "crypto/dsa" | ||
11 | "crypto/ecdsa" | ||
12 | "crypto/elliptic" | ||
13 | "crypto/rsa" | ||
14 | "crypto/sha1" | ||
15 | _ "crypto/sha256" | ||
16 | _ "crypto/sha512" | ||
17 | "encoding/binary" | ||
18 | "fmt" | ||
19 | "hash" | ||
20 | "io" | ||
21 | "math/big" | ||
22 | "strconv" | ||
23 | "time" | ||
24 | |||
25 | "golang.org/x/crypto/openpgp/elgamal" | ||
26 | "golang.org/x/crypto/openpgp/errors" | ||
27 | ) | ||
28 | |||
29 | var ( | ||
30 | // NIST curve P-256 | ||
31 | oidCurveP256 []byte = []byte{0x2A, 0x86, 0x48, 0xCE, 0x3D, 0x03, 0x01, 0x07} | ||
32 | // NIST curve P-384 | ||
33 | oidCurveP384 []byte = []byte{0x2B, 0x81, 0x04, 0x00, 0x22} | ||
34 | // NIST curve P-521 | ||
35 | oidCurveP521 []byte = []byte{0x2B, 0x81, 0x04, 0x00, 0x23} | ||
36 | ) | ||
37 | |||
38 | const maxOIDLength = 8 | ||
39 | |||
40 | // ecdsaKey stores the algorithm-specific fields for ECDSA keys. | ||
41 | // as defined in RFC 6637, Section 9. | ||
42 | type ecdsaKey struct { | ||
43 | // oid contains the OID byte sequence identifying the elliptic curve used | ||
44 | oid []byte | ||
45 | // p contains the elliptic curve point that represents the public key | ||
46 | p parsedMPI | ||
47 | } | ||
48 | |||
49 | // parseOID reads the OID for the curve as defined in RFC 6637, Section 9. | ||
50 | func parseOID(r io.Reader) (oid []byte, err error) { | ||
51 | buf := make([]byte, maxOIDLength) | ||
52 | if _, err = readFull(r, buf[:1]); err != nil { | ||
53 | return | ||
54 | } | ||
55 | oidLen := buf[0] | ||
56 | if int(oidLen) > len(buf) { | ||
57 | err = errors.UnsupportedError("invalid oid length: " + strconv.Itoa(int(oidLen))) | ||
58 | return | ||
59 | } | ||
60 | oid = buf[:oidLen] | ||
61 | _, err = readFull(r, oid) | ||
62 | return | ||
63 | } | ||
64 | |||
65 | func (f *ecdsaKey) parse(r io.Reader) (err error) { | ||
66 | if f.oid, err = parseOID(r); err != nil { | ||
67 | return err | ||
68 | } | ||
69 | f.p.bytes, f.p.bitLength, err = readMPI(r) | ||
70 | return | ||
71 | } | ||
72 | |||
73 | func (f *ecdsaKey) serialize(w io.Writer) (err error) { | ||
74 | buf := make([]byte, maxOIDLength+1) | ||
75 | buf[0] = byte(len(f.oid)) | ||
76 | copy(buf[1:], f.oid) | ||
77 | if _, err = w.Write(buf[:len(f.oid)+1]); err != nil { | ||
78 | return | ||
79 | } | ||
80 | return writeMPIs(w, f.p) | ||
81 | } | ||
82 | |||
83 | func (f *ecdsaKey) newECDSA() (*ecdsa.PublicKey, error) { | ||
84 | var c elliptic.Curve | ||
85 | if bytes.Equal(f.oid, oidCurveP256) { | ||
86 | c = elliptic.P256() | ||
87 | } else if bytes.Equal(f.oid, oidCurveP384) { | ||
88 | c = elliptic.P384() | ||
89 | } else if bytes.Equal(f.oid, oidCurveP521) { | ||
90 | c = elliptic.P521() | ||
91 | } else { | ||
92 | return nil, errors.UnsupportedError(fmt.Sprintf("unsupported oid: %x", f.oid)) | ||
93 | } | ||
94 | x, y := elliptic.Unmarshal(c, f.p.bytes) | ||
95 | if x == nil { | ||
96 | return nil, errors.UnsupportedError("failed to parse EC point") | ||
97 | } | ||
98 | return &ecdsa.PublicKey{Curve: c, X: x, Y: y}, nil | ||
99 | } | ||
100 | |||
101 | func (f *ecdsaKey) byteLen() int { | ||
102 | return 1 + len(f.oid) + 2 + len(f.p.bytes) | ||
103 | } | ||
104 | |||
105 | type kdfHashFunction byte | ||
106 | type kdfAlgorithm byte | ||
107 | |||
108 | // ecdhKdf stores key derivation function parameters | ||
109 | // used for ECDH encryption. See RFC 6637, Section 9. | ||
110 | type ecdhKdf struct { | ||
111 | KdfHash kdfHashFunction | ||
112 | KdfAlgo kdfAlgorithm | ||
113 | } | ||
114 | |||
115 | func (f *ecdhKdf) parse(r io.Reader) (err error) { | ||
116 | buf := make([]byte, 1) | ||
117 | if _, err = readFull(r, buf); err != nil { | ||
118 | return | ||
119 | } | ||
120 | kdfLen := int(buf[0]) | ||
121 | if kdfLen < 3 { | ||
122 | return errors.UnsupportedError("Unsupported ECDH KDF length: " + strconv.Itoa(kdfLen)) | ||
123 | } | ||
124 | buf = make([]byte, kdfLen) | ||
125 | if _, err = readFull(r, buf); err != nil { | ||
126 | return | ||
127 | } | ||
128 | reserved := int(buf[0]) | ||
129 | f.KdfHash = kdfHashFunction(buf[1]) | ||
130 | f.KdfAlgo = kdfAlgorithm(buf[2]) | ||
131 | if reserved != 0x01 { | ||
132 | return errors.UnsupportedError("Unsupported KDF reserved field: " + strconv.Itoa(reserved)) | ||
133 | } | ||
134 | return | ||
135 | } | ||
136 | |||
137 | func (f *ecdhKdf) serialize(w io.Writer) (err error) { | ||
138 | buf := make([]byte, 4) | ||
139 | // See RFC 6637, Section 9, Algorithm-Specific Fields for ECDH keys. | ||
140 | buf[0] = byte(0x03) // Length of the following fields | ||
141 | buf[1] = byte(0x01) // Reserved for future extensions, must be 1 for now | ||
142 | buf[2] = byte(f.KdfHash) | ||
143 | buf[3] = byte(f.KdfAlgo) | ||
144 | _, err = w.Write(buf[:]) | ||
145 | return | ||
146 | } | ||
147 | |||
148 | func (f *ecdhKdf) byteLen() int { | ||
149 | return 4 | ||
150 | } | ||
151 | |||
152 | // PublicKey represents an OpenPGP public key. See RFC 4880, section 5.5.2. | ||
153 | type PublicKey struct { | ||
154 | CreationTime time.Time | ||
155 | PubKeyAlgo PublicKeyAlgorithm | ||
156 | PublicKey interface{} // *rsa.PublicKey, *dsa.PublicKey or *ecdsa.PublicKey | ||
157 | Fingerprint [20]byte | ||
158 | KeyId uint64 | ||
159 | IsSubkey bool | ||
160 | |||
161 | n, e, p, q, g, y parsedMPI | ||
162 | |||
163 | // RFC 6637 fields | ||
164 | ec *ecdsaKey | ||
165 | ecdh *ecdhKdf | ||
166 | } | ||
167 | |||
168 | // signingKey provides a convenient abstraction over signature verification | ||
169 | // for v3 and v4 public keys. | ||
170 | type signingKey interface { | ||
171 | SerializeSignaturePrefix(io.Writer) | ||
172 | serializeWithoutHeaders(io.Writer) error | ||
173 | } | ||
174 | |||
175 | func fromBig(n *big.Int) parsedMPI { | ||
176 | return parsedMPI{ | ||
177 | bytes: n.Bytes(), | ||
178 | bitLength: uint16(n.BitLen()), | ||
179 | } | ||
180 | } | ||
181 | |||
182 | // NewRSAPublicKey returns a PublicKey that wraps the given rsa.PublicKey. | ||
183 | func NewRSAPublicKey(creationTime time.Time, pub *rsa.PublicKey) *PublicKey { | ||
184 | pk := &PublicKey{ | ||
185 | CreationTime: creationTime, | ||
186 | PubKeyAlgo: PubKeyAlgoRSA, | ||
187 | PublicKey: pub, | ||
188 | n: fromBig(pub.N), | ||
189 | e: fromBig(big.NewInt(int64(pub.E))), | ||
190 | } | ||
191 | |||
192 | pk.setFingerPrintAndKeyId() | ||
193 | return pk | ||
194 | } | ||
195 | |||
196 | // NewDSAPublicKey returns a PublicKey that wraps the given dsa.PublicKey. | ||
197 | func NewDSAPublicKey(creationTime time.Time, pub *dsa.PublicKey) *PublicKey { | ||
198 | pk := &PublicKey{ | ||
199 | CreationTime: creationTime, | ||
200 | PubKeyAlgo: PubKeyAlgoDSA, | ||
201 | PublicKey: pub, | ||
202 | p: fromBig(pub.P), | ||
203 | q: fromBig(pub.Q), | ||
204 | g: fromBig(pub.G), | ||
205 | y: fromBig(pub.Y), | ||
206 | } | ||
207 | |||
208 | pk.setFingerPrintAndKeyId() | ||
209 | return pk | ||
210 | } | ||
211 | |||
212 | // NewElGamalPublicKey returns a PublicKey that wraps the given elgamal.PublicKey. | ||
213 | func NewElGamalPublicKey(creationTime time.Time, pub *elgamal.PublicKey) *PublicKey { | ||
214 | pk := &PublicKey{ | ||
215 | CreationTime: creationTime, | ||
216 | PubKeyAlgo: PubKeyAlgoElGamal, | ||
217 | PublicKey: pub, | ||
218 | p: fromBig(pub.P), | ||
219 | g: fromBig(pub.G), | ||
220 | y: fromBig(pub.Y), | ||
221 | } | ||
222 | |||
223 | pk.setFingerPrintAndKeyId() | ||
224 | return pk | ||
225 | } | ||
226 | |||
227 | func NewECDSAPublicKey(creationTime time.Time, pub *ecdsa.PublicKey) *PublicKey { | ||
228 | pk := &PublicKey{ | ||
229 | CreationTime: creationTime, | ||
230 | PubKeyAlgo: PubKeyAlgoECDSA, | ||
231 | PublicKey: pub, | ||
232 | ec: new(ecdsaKey), | ||
233 | } | ||
234 | |||
235 | switch pub.Curve { | ||
236 | case elliptic.P256(): | ||
237 | pk.ec.oid = oidCurveP256 | ||
238 | case elliptic.P384(): | ||
239 | pk.ec.oid = oidCurveP384 | ||
240 | case elliptic.P521(): | ||
241 | pk.ec.oid = oidCurveP521 | ||
242 | default: | ||
243 | panic("unknown elliptic curve") | ||
244 | } | ||
245 | |||
246 | pk.ec.p.bytes = elliptic.Marshal(pub.Curve, pub.X, pub.Y) | ||
247 | pk.ec.p.bitLength = uint16(8 * len(pk.ec.p.bytes)) | ||
248 | |||
249 | pk.setFingerPrintAndKeyId() | ||
250 | return pk | ||
251 | } | ||
252 | |||
253 | func (pk *PublicKey) parse(r io.Reader) (err error) { | ||
254 | // RFC 4880, section 5.5.2 | ||
255 | var buf [6]byte | ||
256 | _, err = readFull(r, buf[:]) | ||
257 | if err != nil { | ||
258 | return | ||
259 | } | ||
260 | if buf[0] != 4 { | ||
261 | return errors.UnsupportedError("public key version") | ||
262 | } | ||
263 | pk.CreationTime = time.Unix(int64(uint32(buf[1])<<24|uint32(buf[2])<<16|uint32(buf[3])<<8|uint32(buf[4])), 0) | ||
264 | pk.PubKeyAlgo = PublicKeyAlgorithm(buf[5]) | ||
265 | switch pk.PubKeyAlgo { | ||
266 | case PubKeyAlgoRSA, PubKeyAlgoRSAEncryptOnly, PubKeyAlgoRSASignOnly: | ||
267 | err = pk.parseRSA(r) | ||
268 | case PubKeyAlgoDSA: | ||
269 | err = pk.parseDSA(r) | ||
270 | case PubKeyAlgoElGamal: | ||
271 | err = pk.parseElGamal(r) | ||
272 | case PubKeyAlgoECDSA: | ||
273 | pk.ec = new(ecdsaKey) | ||
274 | if err = pk.ec.parse(r); err != nil { | ||
275 | return err | ||
276 | } | ||
277 | pk.PublicKey, err = pk.ec.newECDSA() | ||
278 | case PubKeyAlgoECDH: | ||
279 | pk.ec = new(ecdsaKey) | ||
280 | if err = pk.ec.parse(r); err != nil { | ||
281 | return | ||
282 | } | ||
283 | pk.ecdh = new(ecdhKdf) | ||
284 | if err = pk.ecdh.parse(r); err != nil { | ||
285 | return | ||
286 | } | ||
287 | // The ECDH key is stored in an ecdsa.PublicKey for convenience. | ||
288 | pk.PublicKey, err = pk.ec.newECDSA() | ||
289 | default: | ||
290 | err = errors.UnsupportedError("public key type: " + strconv.Itoa(int(pk.PubKeyAlgo))) | ||
291 | } | ||
292 | if err != nil { | ||
293 | return | ||
294 | } | ||
295 | |||
296 | pk.setFingerPrintAndKeyId() | ||
297 | return | ||
298 | } | ||
299 | |||
300 | func (pk *PublicKey) setFingerPrintAndKeyId() { | ||
301 | // RFC 4880, section 12.2 | ||
302 | fingerPrint := sha1.New() | ||
303 | pk.SerializeSignaturePrefix(fingerPrint) | ||
304 | pk.serializeWithoutHeaders(fingerPrint) | ||
305 | copy(pk.Fingerprint[:], fingerPrint.Sum(nil)) | ||
306 | pk.KeyId = binary.BigEndian.Uint64(pk.Fingerprint[12:20]) | ||
307 | } | ||
308 | |||
309 | // parseRSA parses RSA public key material from the given Reader. See RFC 4880, | ||
310 | // section 5.5.2. | ||
311 | func (pk *PublicKey) parseRSA(r io.Reader) (err error) { | ||
312 | pk.n.bytes, pk.n.bitLength, err = readMPI(r) | ||
313 | if err != nil { | ||
314 | return | ||
315 | } | ||
316 | pk.e.bytes, pk.e.bitLength, err = readMPI(r) | ||
317 | if err != nil { | ||
318 | return | ||
319 | } | ||
320 | |||
321 | if len(pk.e.bytes) > 3 { | ||
322 | err = errors.UnsupportedError("large public exponent") | ||
323 | return | ||
324 | } | ||
325 | rsa := &rsa.PublicKey{ | ||
326 | N: new(big.Int).SetBytes(pk.n.bytes), | ||
327 | E: 0, | ||
328 | } | ||
329 | for i := 0; i < len(pk.e.bytes); i++ { | ||
330 | rsa.E <<= 8 | ||
331 | rsa.E |= int(pk.e.bytes[i]) | ||
332 | } | ||
333 | pk.PublicKey = rsa | ||
334 | return | ||
335 | } | ||
336 | |||
337 | // parseDSA parses DSA public key material from the given Reader. See RFC 4880, | ||
338 | // section 5.5.2. | ||
339 | func (pk *PublicKey) parseDSA(r io.Reader) (err error) { | ||
340 | pk.p.bytes, pk.p.bitLength, err = readMPI(r) | ||
341 | if err != nil { | ||
342 | return | ||
343 | } | ||
344 | pk.q.bytes, pk.q.bitLength, err = readMPI(r) | ||
345 | if err != nil { | ||
346 | return | ||
347 | } | ||
348 | pk.g.bytes, pk.g.bitLength, err = readMPI(r) | ||
349 | if err != nil { | ||
350 | return | ||
351 | } | ||
352 | pk.y.bytes, pk.y.bitLength, err = readMPI(r) | ||
353 | if err != nil { | ||
354 | return | ||
355 | } | ||
356 | |||
357 | dsa := new(dsa.PublicKey) | ||
358 | dsa.P = new(big.Int).SetBytes(pk.p.bytes) | ||
359 | dsa.Q = new(big.Int).SetBytes(pk.q.bytes) | ||
360 | dsa.G = new(big.Int).SetBytes(pk.g.bytes) | ||
361 | dsa.Y = new(big.Int).SetBytes(pk.y.bytes) | ||
362 | pk.PublicKey = dsa | ||
363 | return | ||
364 | } | ||
365 | |||
366 | // parseElGamal parses ElGamal public key material from the given Reader. See | ||
367 | // RFC 4880, section 5.5.2. | ||
368 | func (pk *PublicKey) parseElGamal(r io.Reader) (err error) { | ||
369 | pk.p.bytes, pk.p.bitLength, err = readMPI(r) | ||
370 | if err != nil { | ||
371 | return | ||
372 | } | ||
373 | pk.g.bytes, pk.g.bitLength, err = readMPI(r) | ||
374 | if err != nil { | ||
375 | return | ||
376 | } | ||
377 | pk.y.bytes, pk.y.bitLength, err = readMPI(r) | ||
378 | if err != nil { | ||
379 | return | ||
380 | } | ||
381 | |||
382 | elgamal := new(elgamal.PublicKey) | ||
383 | elgamal.P = new(big.Int).SetBytes(pk.p.bytes) | ||
384 | elgamal.G = new(big.Int).SetBytes(pk.g.bytes) | ||
385 | elgamal.Y = new(big.Int).SetBytes(pk.y.bytes) | ||
386 | pk.PublicKey = elgamal | ||
387 | return | ||
388 | } | ||
389 | |||
390 | // SerializeSignaturePrefix writes the prefix for this public key to the given Writer. | ||
391 | // The prefix is used when calculating a signature over this public key. See | ||
392 | // RFC 4880, section 5.2.4. | ||
393 | func (pk *PublicKey) SerializeSignaturePrefix(h io.Writer) { | ||
394 | var pLength uint16 | ||
395 | switch pk.PubKeyAlgo { | ||
396 | case PubKeyAlgoRSA, PubKeyAlgoRSAEncryptOnly, PubKeyAlgoRSASignOnly: | ||
397 | pLength += 2 + uint16(len(pk.n.bytes)) | ||
398 | pLength += 2 + uint16(len(pk.e.bytes)) | ||
399 | case PubKeyAlgoDSA: | ||
400 | pLength += 2 + uint16(len(pk.p.bytes)) | ||
401 | pLength += 2 + uint16(len(pk.q.bytes)) | ||
402 | pLength += 2 + uint16(len(pk.g.bytes)) | ||
403 | pLength += 2 + uint16(len(pk.y.bytes)) | ||
404 | case PubKeyAlgoElGamal: | ||
405 | pLength += 2 + uint16(len(pk.p.bytes)) | ||
406 | pLength += 2 + uint16(len(pk.g.bytes)) | ||
407 | pLength += 2 + uint16(len(pk.y.bytes)) | ||
408 | case PubKeyAlgoECDSA: | ||
409 | pLength += uint16(pk.ec.byteLen()) | ||
410 | case PubKeyAlgoECDH: | ||
411 | pLength += uint16(pk.ec.byteLen()) | ||
412 | pLength += uint16(pk.ecdh.byteLen()) | ||
413 | default: | ||
414 | panic("unknown public key algorithm") | ||
415 | } | ||
416 | pLength += 6 | ||
417 | h.Write([]byte{0x99, byte(pLength >> 8), byte(pLength)}) | ||
418 | return | ||
419 | } | ||
420 | |||
421 | func (pk *PublicKey) Serialize(w io.Writer) (err error) { | ||
422 | length := 6 // 6 byte header | ||
423 | |||
424 | switch pk.PubKeyAlgo { | ||
425 | case PubKeyAlgoRSA, PubKeyAlgoRSAEncryptOnly, PubKeyAlgoRSASignOnly: | ||
426 | length += 2 + len(pk.n.bytes) | ||
427 | length += 2 + len(pk.e.bytes) | ||
428 | case PubKeyAlgoDSA: | ||
429 | length += 2 + len(pk.p.bytes) | ||
430 | length += 2 + len(pk.q.bytes) | ||
431 | length += 2 + len(pk.g.bytes) | ||
432 | length += 2 + len(pk.y.bytes) | ||
433 | case PubKeyAlgoElGamal: | ||
434 | length += 2 + len(pk.p.bytes) | ||
435 | length += 2 + len(pk.g.bytes) | ||
436 | length += 2 + len(pk.y.bytes) | ||
437 | case PubKeyAlgoECDSA: | ||
438 | length += pk.ec.byteLen() | ||
439 | case PubKeyAlgoECDH: | ||
440 | length += pk.ec.byteLen() | ||
441 | length += pk.ecdh.byteLen() | ||
442 | default: | ||
443 | panic("unknown public key algorithm") | ||
444 | } | ||
445 | |||
446 | packetType := packetTypePublicKey | ||
447 | if pk.IsSubkey { | ||
448 | packetType = packetTypePublicSubkey | ||
449 | } | ||
450 | err = serializeHeader(w, packetType, length) | ||
451 | if err != nil { | ||
452 | return | ||
453 | } | ||
454 | return pk.serializeWithoutHeaders(w) | ||
455 | } | ||
456 | |||
457 | // serializeWithoutHeaders marshals the PublicKey to w in the form of an | ||
458 | // OpenPGP public key packet, not including the packet header. | ||
459 | func (pk *PublicKey) serializeWithoutHeaders(w io.Writer) (err error) { | ||
460 | var buf [6]byte | ||
461 | buf[0] = 4 | ||
462 | t := uint32(pk.CreationTime.Unix()) | ||
463 | buf[1] = byte(t >> 24) | ||
464 | buf[2] = byte(t >> 16) | ||
465 | buf[3] = byte(t >> 8) | ||
466 | buf[4] = byte(t) | ||
467 | buf[5] = byte(pk.PubKeyAlgo) | ||
468 | |||
469 | _, err = w.Write(buf[:]) | ||
470 | if err != nil { | ||
471 | return | ||
472 | } | ||
473 | |||
474 | switch pk.PubKeyAlgo { | ||
475 | case PubKeyAlgoRSA, PubKeyAlgoRSAEncryptOnly, PubKeyAlgoRSASignOnly: | ||
476 | return writeMPIs(w, pk.n, pk.e) | ||
477 | case PubKeyAlgoDSA: | ||
478 | return writeMPIs(w, pk.p, pk.q, pk.g, pk.y) | ||
479 | case PubKeyAlgoElGamal: | ||
480 | return writeMPIs(w, pk.p, pk.g, pk.y) | ||
481 | case PubKeyAlgoECDSA: | ||
482 | return pk.ec.serialize(w) | ||
483 | case PubKeyAlgoECDH: | ||
484 | if err = pk.ec.serialize(w); err != nil { | ||
485 | return | ||
486 | } | ||
487 | return pk.ecdh.serialize(w) | ||
488 | } | ||
489 | return errors.InvalidArgumentError("bad public-key algorithm") | ||
490 | } | ||
491 | |||
492 | // CanSign returns true iff this public key can generate signatures | ||
493 | func (pk *PublicKey) CanSign() bool { | ||
494 | return pk.PubKeyAlgo != PubKeyAlgoRSAEncryptOnly && pk.PubKeyAlgo != PubKeyAlgoElGamal | ||
495 | } | ||
496 | |||
497 | // VerifySignature returns nil iff sig is a valid signature, made by this | ||
498 | // public key, of the data hashed into signed. signed is mutated by this call. | ||
499 | func (pk *PublicKey) VerifySignature(signed hash.Hash, sig *Signature) (err error) { | ||
500 | if !pk.CanSign() { | ||
501 | return errors.InvalidArgumentError("public key cannot generate signatures") | ||
502 | } | ||
503 | |||
504 | signed.Write(sig.HashSuffix) | ||
505 | hashBytes := signed.Sum(nil) | ||
506 | |||
507 | if hashBytes[0] != sig.HashTag[0] || hashBytes[1] != sig.HashTag[1] { | ||
508 | return errors.SignatureError("hash tag doesn't match") | ||
509 | } | ||
510 | |||
511 | if pk.PubKeyAlgo != sig.PubKeyAlgo { | ||
512 | return errors.InvalidArgumentError("public key and signature use different algorithms") | ||
513 | } | ||
514 | |||
515 | switch pk.PubKeyAlgo { | ||
516 | case PubKeyAlgoRSA, PubKeyAlgoRSASignOnly: | ||
517 | rsaPublicKey, _ := pk.PublicKey.(*rsa.PublicKey) | ||
518 | err = rsa.VerifyPKCS1v15(rsaPublicKey, sig.Hash, hashBytes, sig.RSASignature.bytes) | ||
519 | if err != nil { | ||
520 | return errors.SignatureError("RSA verification failure") | ||
521 | } | ||
522 | return nil | ||
523 | case PubKeyAlgoDSA: | ||
524 | dsaPublicKey, _ := pk.PublicKey.(*dsa.PublicKey) | ||
525 | // Need to truncate hashBytes to match FIPS 186-3 section 4.6. | ||
526 | subgroupSize := (dsaPublicKey.Q.BitLen() + 7) / 8 | ||
527 | if len(hashBytes) > subgroupSize { | ||
528 | hashBytes = hashBytes[:subgroupSize] | ||
529 | } | ||
530 | if !dsa.Verify(dsaPublicKey, hashBytes, new(big.Int).SetBytes(sig.DSASigR.bytes), new(big.Int).SetBytes(sig.DSASigS.bytes)) { | ||
531 | return errors.SignatureError("DSA verification failure") | ||
532 | } | ||
533 | return nil | ||
534 | case PubKeyAlgoECDSA: | ||
535 | ecdsaPublicKey := pk.PublicKey.(*ecdsa.PublicKey) | ||
536 | if !ecdsa.Verify(ecdsaPublicKey, hashBytes, new(big.Int).SetBytes(sig.ECDSASigR.bytes), new(big.Int).SetBytes(sig.ECDSASigS.bytes)) { | ||
537 | return errors.SignatureError("ECDSA verification failure") | ||
538 | } | ||
539 | return nil | ||
540 | default: | ||
541 | return errors.SignatureError("Unsupported public key algorithm used in signature") | ||
542 | } | ||
543 | } | ||
544 | |||
545 | // VerifySignatureV3 returns nil iff sig is a valid signature, made by this | ||
546 | // public key, of the data hashed into signed. signed is mutated by this call. | ||
547 | func (pk *PublicKey) VerifySignatureV3(signed hash.Hash, sig *SignatureV3) (err error) { | ||
548 | if !pk.CanSign() { | ||
549 | return errors.InvalidArgumentError("public key cannot generate signatures") | ||
550 | } | ||
551 | |||
552 | suffix := make([]byte, 5) | ||
553 | suffix[0] = byte(sig.SigType) | ||
554 | binary.BigEndian.PutUint32(suffix[1:], uint32(sig.CreationTime.Unix())) | ||
555 | signed.Write(suffix) | ||
556 | hashBytes := signed.Sum(nil) | ||
557 | |||
558 | if hashBytes[0] != sig.HashTag[0] || hashBytes[1] != sig.HashTag[1] { | ||
559 | return errors.SignatureError("hash tag doesn't match") | ||
560 | } | ||
561 | |||
562 | if pk.PubKeyAlgo != sig.PubKeyAlgo { | ||
563 | return errors.InvalidArgumentError("public key and signature use different algorithms") | ||
564 | } | ||
565 | |||
566 | switch pk.PubKeyAlgo { | ||
567 | case PubKeyAlgoRSA, PubKeyAlgoRSASignOnly: | ||
568 | rsaPublicKey := pk.PublicKey.(*rsa.PublicKey) | ||
569 | if err = rsa.VerifyPKCS1v15(rsaPublicKey, sig.Hash, hashBytes, sig.RSASignature.bytes); err != nil { | ||
570 | return errors.SignatureError("RSA verification failure") | ||
571 | } | ||
572 | return | ||
573 | case PubKeyAlgoDSA: | ||
574 | dsaPublicKey := pk.PublicKey.(*dsa.PublicKey) | ||
575 | // Need to truncate hashBytes to match FIPS 186-3 section 4.6. | ||
576 | subgroupSize := (dsaPublicKey.Q.BitLen() + 7) / 8 | ||
577 | if len(hashBytes) > subgroupSize { | ||
578 | hashBytes = hashBytes[:subgroupSize] | ||
579 | } | ||
580 | if !dsa.Verify(dsaPublicKey, hashBytes, new(big.Int).SetBytes(sig.DSASigR.bytes), new(big.Int).SetBytes(sig.DSASigS.bytes)) { | ||
581 | return errors.SignatureError("DSA verification failure") | ||
582 | } | ||
583 | return nil | ||
584 | default: | ||
585 | panic("shouldn't happen") | ||
586 | } | ||
587 | } | ||
588 | |||
589 | // keySignatureHash returns a Hash of the message that needs to be signed for | ||
590 | // pk to assert a subkey relationship to signed. | ||
591 | func keySignatureHash(pk, signed signingKey, hashFunc crypto.Hash) (h hash.Hash, err error) { | ||
592 | if !hashFunc.Available() { | ||
593 | return nil, errors.UnsupportedError("hash function") | ||
594 | } | ||
595 | h = hashFunc.New() | ||
596 | |||
597 | // RFC 4880, section 5.2.4 | ||
598 | pk.SerializeSignaturePrefix(h) | ||
599 | pk.serializeWithoutHeaders(h) | ||
600 | signed.SerializeSignaturePrefix(h) | ||
601 | signed.serializeWithoutHeaders(h) | ||
602 | return | ||
603 | } | ||
604 | |||
605 | // VerifyKeySignature returns nil iff sig is a valid signature, made by this | ||
606 | // public key, of signed. | ||
607 | func (pk *PublicKey) VerifyKeySignature(signed *PublicKey, sig *Signature) error { | ||
608 | h, err := keySignatureHash(pk, signed, sig.Hash) | ||
609 | if err != nil { | ||
610 | return err | ||
611 | } | ||
612 | if err = pk.VerifySignature(h, sig); err != nil { | ||
613 | return err | ||
614 | } | ||
615 | |||
616 | if sig.FlagSign { | ||
617 | // Signing subkeys must be cross-signed. See | ||
618 | // https://www.gnupg.org/faq/subkey-cross-certify.html. | ||
619 | if sig.EmbeddedSignature == nil { | ||
620 | return errors.StructuralError("signing subkey is missing cross-signature") | ||
621 | } | ||
622 | // Verify the cross-signature. This is calculated over the same | ||
623 | // data as the main signature, so we cannot just recursively | ||
624 | // call signed.VerifyKeySignature(...) | ||
625 | if h, err = keySignatureHash(pk, signed, sig.EmbeddedSignature.Hash); err != nil { | ||
626 | return errors.StructuralError("error while hashing for cross-signature: " + err.Error()) | ||
627 | } | ||
628 | if err := signed.VerifySignature(h, sig.EmbeddedSignature); err != nil { | ||
629 | return errors.StructuralError("error while verifying cross-signature: " + err.Error()) | ||
630 | } | ||
631 | } | ||
632 | |||
633 | return nil | ||
634 | } | ||
635 | |||
636 | func keyRevocationHash(pk signingKey, hashFunc crypto.Hash) (h hash.Hash, err error) { | ||
637 | if !hashFunc.Available() { | ||
638 | return nil, errors.UnsupportedError("hash function") | ||
639 | } | ||
640 | h = hashFunc.New() | ||
641 | |||
642 | // RFC 4880, section 5.2.4 | ||
643 | pk.SerializeSignaturePrefix(h) | ||
644 | pk.serializeWithoutHeaders(h) | ||
645 | |||
646 | return | ||
647 | } | ||
648 | |||
649 | // VerifyRevocationSignature returns nil iff sig is a valid signature, made by this | ||
650 | // public key. | ||
651 | func (pk *PublicKey) VerifyRevocationSignature(sig *Signature) (err error) { | ||
652 | h, err := keyRevocationHash(pk, sig.Hash) | ||
653 | if err != nil { | ||
654 | return err | ||
655 | } | ||
656 | return pk.VerifySignature(h, sig) | ||
657 | } | ||
658 | |||
659 | // userIdSignatureHash returns a Hash of the message that needs to be signed | ||
660 | // to assert that pk is a valid key for id. | ||
661 | func userIdSignatureHash(id string, pk *PublicKey, hashFunc crypto.Hash) (h hash.Hash, err error) { | ||
662 | if !hashFunc.Available() { | ||
663 | return nil, errors.UnsupportedError("hash function") | ||
664 | } | ||
665 | h = hashFunc.New() | ||
666 | |||
667 | // RFC 4880, section 5.2.4 | ||
668 | pk.SerializeSignaturePrefix(h) | ||
669 | pk.serializeWithoutHeaders(h) | ||
670 | |||
671 | var buf [5]byte | ||
672 | buf[0] = 0xb4 | ||
673 | buf[1] = byte(len(id) >> 24) | ||
674 | buf[2] = byte(len(id) >> 16) | ||
675 | buf[3] = byte(len(id) >> 8) | ||
676 | buf[4] = byte(len(id)) | ||
677 | h.Write(buf[:]) | ||
678 | h.Write([]byte(id)) | ||
679 | |||
680 | return | ||
681 | } | ||
682 | |||
683 | // VerifyUserIdSignature returns nil iff sig is a valid signature, made by this | ||
684 | // public key, that id is the identity of pub. | ||
685 | func (pk *PublicKey) VerifyUserIdSignature(id string, pub *PublicKey, sig *Signature) (err error) { | ||
686 | h, err := userIdSignatureHash(id, pub, sig.Hash) | ||
687 | if err != nil { | ||
688 | return err | ||
689 | } | ||
690 | return pk.VerifySignature(h, sig) | ||
691 | } | ||
692 | |||
693 | // VerifyUserIdSignatureV3 returns nil iff sig is a valid signature, made by this | ||
694 | // public key, that id is the identity of pub. | ||
695 | func (pk *PublicKey) VerifyUserIdSignatureV3(id string, pub *PublicKey, sig *SignatureV3) (err error) { | ||
696 | h, err := userIdSignatureV3Hash(id, pub, sig.Hash) | ||
697 | if err != nil { | ||
698 | return err | ||
699 | } | ||
700 | return pk.VerifySignatureV3(h, sig) | ||
701 | } | ||
702 | |||
703 | // KeyIdString returns the public key's fingerprint in capital hex | ||
704 | // (e.g. "6C7EE1B8621CC013"). | ||
705 | func (pk *PublicKey) KeyIdString() string { | ||
706 | return fmt.Sprintf("%X", pk.Fingerprint[12:20]) | ||
707 | } | ||
708 | |||
709 | // KeyIdShortString returns the short form of public key's fingerprint | ||
710 | // in capital hex, as shown by gpg --list-keys (e.g. "621CC013"). | ||
711 | func (pk *PublicKey) KeyIdShortString() string { | ||
712 | return fmt.Sprintf("%X", pk.Fingerprint[16:20]) | ||
713 | } | ||
714 | |||
715 | // A parsedMPI is used to store the contents of a big integer, along with the | ||
716 | // bit length that was specified in the original input. This allows the MPI to | ||
717 | // be reserialized exactly. | ||
718 | type parsedMPI struct { | ||
719 | bytes []byte | ||
720 | bitLength uint16 | ||
721 | } | ||
722 | |||
723 | // writeMPIs is a utility function for serializing several big integers to the | ||
724 | // given Writer. | ||
725 | func writeMPIs(w io.Writer, mpis ...parsedMPI) (err error) { | ||
726 | for _, mpi := range mpis { | ||
727 | err = writeMPI(w, mpi.bitLength, mpi.bytes) | ||
728 | if err != nil { | ||
729 | return | ||
730 | } | ||
731 | } | ||
732 | return | ||
733 | } | ||
734 | |||
735 | // BitLength returns the bit length for the given public key. | ||
736 | func (pk *PublicKey) BitLength() (bitLength uint16, err error) { | ||
737 | switch pk.PubKeyAlgo { | ||
738 | case PubKeyAlgoRSA, PubKeyAlgoRSAEncryptOnly, PubKeyAlgoRSASignOnly: | ||
739 | bitLength = pk.n.bitLength | ||
740 | case PubKeyAlgoDSA: | ||
741 | bitLength = pk.p.bitLength | ||
742 | case PubKeyAlgoElGamal: | ||
743 | bitLength = pk.p.bitLength | ||
744 | default: | ||
745 | err = errors.InvalidArgumentError("bad public-key algorithm") | ||
746 | } | ||
747 | return | ||
748 | } | ||
diff --git a/vendor/golang.org/x/crypto/openpgp/packet/public_key_v3.go b/vendor/golang.org/x/crypto/openpgp/packet/public_key_v3.go new file mode 100644 index 0000000..5daf7b6 --- /dev/null +++ b/vendor/golang.org/x/crypto/openpgp/packet/public_key_v3.go | |||
@@ -0,0 +1,279 @@ | |||
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 | } | ||
diff --git a/vendor/golang.org/x/crypto/openpgp/packet/reader.go b/vendor/golang.org/x/crypto/openpgp/packet/reader.go new file mode 100644 index 0000000..34bc7c6 --- /dev/null +++ b/vendor/golang.org/x/crypto/openpgp/packet/reader.go | |||
@@ -0,0 +1,76 @@ | |||
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 | "golang.org/x/crypto/openpgp/errors" | ||
9 | "io" | ||
10 | ) | ||
11 | |||
12 | // Reader reads packets from an io.Reader and allows packets to be 'unread' so | ||
13 | // that they result from the next call to Next. | ||
14 | type Reader struct { | ||
15 | q []Packet | ||
16 | readers []io.Reader | ||
17 | } | ||
18 | |||
19 | // New io.Readers are pushed when a compressed or encrypted packet is processed | ||
20 | // and recursively treated as a new source of packets. However, a carefully | ||
21 | // crafted packet can trigger an infinite recursive sequence of packets. See | ||
22 | // http://mumble.net/~campbell/misc/pgp-quine | ||
23 | // https://web.nvd.nist.gov/view/vuln/detail?vulnId=CVE-2013-4402 | ||
24 | // This constant limits the number of recursive packets that may be pushed. | ||
25 | const maxReaders = 32 | ||
26 | |||
27 | // Next returns the most recently unread Packet, or reads another packet from | ||
28 | // the top-most io.Reader. Unknown packet types are skipped. | ||
29 | func (r *Reader) Next() (p Packet, err error) { | ||
30 | if len(r.q) > 0 { | ||
31 | p = r.q[len(r.q)-1] | ||
32 | r.q = r.q[:len(r.q)-1] | ||
33 | return | ||
34 | } | ||
35 | |||
36 | for len(r.readers) > 0 { | ||
37 | p, err = Read(r.readers[len(r.readers)-1]) | ||
38 | if err == nil { | ||
39 | return | ||
40 | } | ||
41 | if err == io.EOF { | ||
42 | r.readers = r.readers[:len(r.readers)-1] | ||
43 | continue | ||
44 | } | ||
45 | if _, ok := err.(errors.UnknownPacketTypeError); !ok { | ||
46 | return nil, err | ||
47 | } | ||
48 | } | ||
49 | |||
50 | return nil, io.EOF | ||
51 | } | ||
52 | |||
53 | // Push causes the Reader to start reading from a new io.Reader. When an EOF | ||
54 | // error is seen from the new io.Reader, it is popped and the Reader continues | ||
55 | // to read from the next most recent io.Reader. Push returns a StructuralError | ||
56 | // if pushing the reader would exceed the maximum recursion level, otherwise it | ||
57 | // returns nil. | ||
58 | func (r *Reader) Push(reader io.Reader) (err error) { | ||
59 | if len(r.readers) >= maxReaders { | ||
60 | return errors.StructuralError("too many layers of packets") | ||
61 | } | ||
62 | r.readers = append(r.readers, reader) | ||
63 | return nil | ||
64 | } | ||
65 | |||
66 | // Unread causes the given Packet to be returned from the next call to Next. | ||
67 | func (r *Reader) Unread(p Packet) { | ||
68 | r.q = append(r.q, p) | ||
69 | } | ||
70 | |||
71 | func NewReader(r io.Reader) *Reader { | ||
72 | return &Reader{ | ||
73 | q: nil, | ||
74 | readers: []io.Reader{r}, | ||
75 | } | ||
76 | } | ||
diff --git a/vendor/golang.org/x/crypto/openpgp/packet/signature.go b/vendor/golang.org/x/crypto/openpgp/packet/signature.go new file mode 100644 index 0000000..6ce0cbe --- /dev/null +++ b/vendor/golang.org/x/crypto/openpgp/packet/signature.go | |||
@@ -0,0 +1,731 @@ | |||
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 | "bytes" | ||
9 | "crypto" | ||
10 | "crypto/dsa" | ||
11 | "crypto/ecdsa" | ||
12 | "encoding/asn1" | ||
13 | "encoding/binary" | ||
14 | "hash" | ||
15 | "io" | ||
16 | "math/big" | ||
17 | "strconv" | ||
18 | "time" | ||
19 | |||
20 | "golang.org/x/crypto/openpgp/errors" | ||
21 | "golang.org/x/crypto/openpgp/s2k" | ||
22 | ) | ||
23 | |||
24 | const ( | ||
25 | // See RFC 4880, section 5.2.3.21 for details. | ||
26 | KeyFlagCertify = 1 << iota | ||
27 | KeyFlagSign | ||
28 | KeyFlagEncryptCommunications | ||
29 | KeyFlagEncryptStorage | ||
30 | ) | ||
31 | |||
32 | // Signature represents a signature. See RFC 4880, section 5.2. | ||
33 | type Signature struct { | ||
34 | SigType SignatureType | ||
35 | PubKeyAlgo PublicKeyAlgorithm | ||
36 | Hash crypto.Hash | ||
37 | |||
38 | // HashSuffix is extra data that is hashed in after the signed data. | ||
39 | HashSuffix []byte | ||
40 | // HashTag contains the first two bytes of the hash for fast rejection | ||
41 | // of bad signed data. | ||
42 | HashTag [2]byte | ||
43 | CreationTime time.Time | ||
44 | |||
45 | RSASignature parsedMPI | ||
46 | DSASigR, DSASigS parsedMPI | ||
47 | ECDSASigR, ECDSASigS parsedMPI | ||
48 | |||
49 | // rawSubpackets contains the unparsed subpackets, in order. | ||
50 | rawSubpackets []outputSubpacket | ||
51 | |||
52 | // The following are optional so are nil when not included in the | ||
53 | // signature. | ||
54 | |||
55 | SigLifetimeSecs, KeyLifetimeSecs *uint32 | ||
56 | PreferredSymmetric, PreferredHash, PreferredCompression []uint8 | ||
57 | IssuerKeyId *uint64 | ||
58 | IsPrimaryId *bool | ||
59 | |||
60 | // FlagsValid is set if any flags were given. See RFC 4880, section | ||
61 | // 5.2.3.21 for details. | ||
62 | FlagsValid bool | ||
63 | FlagCertify, FlagSign, FlagEncryptCommunications, FlagEncryptStorage bool | ||
64 | |||
65 | // RevocationReason is set if this signature has been revoked. | ||
66 | // See RFC 4880, section 5.2.3.23 for details. | ||
67 | RevocationReason *uint8 | ||
68 | RevocationReasonText string | ||
69 | |||
70 | // MDC is set if this signature has a feature packet that indicates | ||
71 | // support for MDC subpackets. | ||
72 | MDC bool | ||
73 | |||
74 | // EmbeddedSignature, if non-nil, is a signature of the parent key, by | ||
75 | // this key. This prevents an attacker from claiming another's signing | ||
76 | // subkey as their own. | ||
77 | EmbeddedSignature *Signature | ||
78 | |||
79 | outSubpackets []outputSubpacket | ||
80 | } | ||
81 | |||
82 | func (sig *Signature) parse(r io.Reader) (err error) { | ||
83 | // RFC 4880, section 5.2.3 | ||
84 | var buf [5]byte | ||
85 | _, err = readFull(r, buf[:1]) | ||
86 | if err != nil { | ||
87 | return | ||
88 | } | ||
89 | if buf[0] != 4 { | ||
90 | err = errors.UnsupportedError("signature packet version " + strconv.Itoa(int(buf[0]))) | ||
91 | return | ||
92 | } | ||
93 | |||
94 | _, err = readFull(r, buf[:5]) | ||
95 | if err != nil { | ||
96 | return | ||
97 | } | ||
98 | sig.SigType = SignatureType(buf[0]) | ||
99 | sig.PubKeyAlgo = PublicKeyAlgorithm(buf[1]) | ||
100 | switch sig.PubKeyAlgo { | ||
101 | case PubKeyAlgoRSA, PubKeyAlgoRSASignOnly, PubKeyAlgoDSA, PubKeyAlgoECDSA: | ||
102 | default: | ||
103 | err = errors.UnsupportedError("public key algorithm " + strconv.Itoa(int(sig.PubKeyAlgo))) | ||
104 | return | ||
105 | } | ||
106 | |||
107 | var ok bool | ||
108 | sig.Hash, ok = s2k.HashIdToHash(buf[2]) | ||
109 | if !ok { | ||
110 | return errors.UnsupportedError("hash function " + strconv.Itoa(int(buf[2]))) | ||
111 | } | ||
112 | |||
113 | hashedSubpacketsLength := int(buf[3])<<8 | int(buf[4]) | ||
114 | l := 6 + hashedSubpacketsLength | ||
115 | sig.HashSuffix = make([]byte, l+6) | ||
116 | sig.HashSuffix[0] = 4 | ||
117 | copy(sig.HashSuffix[1:], buf[:5]) | ||
118 | hashedSubpackets := sig.HashSuffix[6:l] | ||
119 | _, err = readFull(r, hashedSubpackets) | ||
120 | if err != nil { | ||
121 | return | ||
122 | } | ||
123 | // See RFC 4880, section 5.2.4 | ||
124 | trailer := sig.HashSuffix[l:] | ||
125 | trailer[0] = 4 | ||
126 | trailer[1] = 0xff | ||
127 | trailer[2] = uint8(l >> 24) | ||
128 | trailer[3] = uint8(l >> 16) | ||
129 | trailer[4] = uint8(l >> 8) | ||
130 | trailer[5] = uint8(l) | ||
131 | |||
132 | err = parseSignatureSubpackets(sig, hashedSubpackets, true) | ||
133 | if err != nil { | ||
134 | return | ||
135 | } | ||
136 | |||
137 | _, err = readFull(r, buf[:2]) | ||
138 | if err != nil { | ||
139 | return | ||
140 | } | ||
141 | unhashedSubpacketsLength := int(buf[0])<<8 | int(buf[1]) | ||
142 | unhashedSubpackets := make([]byte, unhashedSubpacketsLength) | ||
143 | _, err = readFull(r, unhashedSubpackets) | ||
144 | if err != nil { | ||
145 | return | ||
146 | } | ||
147 | err = parseSignatureSubpackets(sig, unhashedSubpackets, false) | ||
148 | if err != nil { | ||
149 | return | ||
150 | } | ||
151 | |||
152 | _, err = readFull(r, sig.HashTag[:2]) | ||
153 | if err != nil { | ||
154 | return | ||
155 | } | ||
156 | |||
157 | switch sig.PubKeyAlgo { | ||
158 | case PubKeyAlgoRSA, PubKeyAlgoRSASignOnly: | ||
159 | sig.RSASignature.bytes, sig.RSASignature.bitLength, err = readMPI(r) | ||
160 | case PubKeyAlgoDSA: | ||
161 | sig.DSASigR.bytes, sig.DSASigR.bitLength, err = readMPI(r) | ||
162 | if err == nil { | ||
163 | sig.DSASigS.bytes, sig.DSASigS.bitLength, err = readMPI(r) | ||
164 | } | ||
165 | case PubKeyAlgoECDSA: | ||
166 | sig.ECDSASigR.bytes, sig.ECDSASigR.bitLength, err = readMPI(r) | ||
167 | if err == nil { | ||
168 | sig.ECDSASigS.bytes, sig.ECDSASigS.bitLength, err = readMPI(r) | ||
169 | } | ||
170 | default: | ||
171 | panic("unreachable") | ||
172 | } | ||
173 | return | ||
174 | } | ||
175 | |||
176 | // parseSignatureSubpackets parses subpackets of the main signature packet. See | ||
177 | // RFC 4880, section 5.2.3.1. | ||
178 | func parseSignatureSubpackets(sig *Signature, subpackets []byte, isHashed bool) (err error) { | ||
179 | for len(subpackets) > 0 { | ||
180 | subpackets, err = parseSignatureSubpacket(sig, subpackets, isHashed) | ||
181 | if err != nil { | ||
182 | return | ||
183 | } | ||
184 | } | ||
185 | |||
186 | if sig.CreationTime.IsZero() { | ||
187 | err = errors.StructuralError("no creation time in signature") | ||
188 | } | ||
189 | |||
190 | return | ||
191 | } | ||
192 | |||
193 | type signatureSubpacketType uint8 | ||
194 | |||
195 | const ( | ||
196 | creationTimeSubpacket signatureSubpacketType = 2 | ||
197 | signatureExpirationSubpacket signatureSubpacketType = 3 | ||
198 | keyExpirationSubpacket signatureSubpacketType = 9 | ||
199 | prefSymmetricAlgosSubpacket signatureSubpacketType = 11 | ||
200 | issuerSubpacket signatureSubpacketType = 16 | ||
201 | prefHashAlgosSubpacket signatureSubpacketType = 21 | ||
202 | prefCompressionSubpacket signatureSubpacketType = 22 | ||
203 | primaryUserIdSubpacket signatureSubpacketType = 25 | ||
204 | keyFlagsSubpacket signatureSubpacketType = 27 | ||
205 | reasonForRevocationSubpacket signatureSubpacketType = 29 | ||
206 | featuresSubpacket signatureSubpacketType = 30 | ||
207 | embeddedSignatureSubpacket signatureSubpacketType = 32 | ||
208 | ) | ||
209 | |||
210 | // parseSignatureSubpacket parses a single subpacket. len(subpacket) is >= 1. | ||
211 | func parseSignatureSubpacket(sig *Signature, subpacket []byte, isHashed bool) (rest []byte, err error) { | ||
212 | // RFC 4880, section 5.2.3.1 | ||
213 | var ( | ||
214 | length uint32 | ||
215 | packetType signatureSubpacketType | ||
216 | isCritical bool | ||
217 | ) | ||
218 | switch { | ||
219 | case subpacket[0] < 192: | ||
220 | length = uint32(subpacket[0]) | ||
221 | subpacket = subpacket[1:] | ||
222 | case subpacket[0] < 255: | ||
223 | if len(subpacket) < 2 { | ||
224 | goto Truncated | ||
225 | } | ||
226 | length = uint32(subpacket[0]-192)<<8 + uint32(subpacket[1]) + 192 | ||
227 | subpacket = subpacket[2:] | ||
228 | default: | ||
229 | if len(subpacket) < 5 { | ||
230 | goto Truncated | ||
231 | } | ||
232 | length = uint32(subpacket[1])<<24 | | ||
233 | uint32(subpacket[2])<<16 | | ||
234 | uint32(subpacket[3])<<8 | | ||
235 | uint32(subpacket[4]) | ||
236 | subpacket = subpacket[5:] | ||
237 | } | ||
238 | if length > uint32(len(subpacket)) { | ||
239 | goto Truncated | ||
240 | } | ||
241 | rest = subpacket[length:] | ||
242 | subpacket = subpacket[:length] | ||
243 | if len(subpacket) == 0 { | ||
244 | err = errors.StructuralError("zero length signature subpacket") | ||
245 | return | ||
246 | } | ||
247 | packetType = signatureSubpacketType(subpacket[0] & 0x7f) | ||
248 | isCritical = subpacket[0]&0x80 == 0x80 | ||
249 | subpacket = subpacket[1:] | ||
250 | sig.rawSubpackets = append(sig.rawSubpackets, outputSubpacket{isHashed, packetType, isCritical, subpacket}) | ||
251 | switch packetType { | ||
252 | case creationTimeSubpacket: | ||
253 | if !isHashed { | ||
254 | err = errors.StructuralError("signature creation time in non-hashed area") | ||
255 | return | ||
256 | } | ||
257 | if len(subpacket) != 4 { | ||
258 | err = errors.StructuralError("signature creation time not four bytes") | ||
259 | return | ||
260 | } | ||
261 | t := binary.BigEndian.Uint32(subpacket) | ||
262 | sig.CreationTime = time.Unix(int64(t), 0) | ||
263 | case signatureExpirationSubpacket: | ||
264 | // Signature expiration time, section 5.2.3.10 | ||
265 | if !isHashed { | ||
266 | return | ||
267 | } | ||
268 | if len(subpacket) != 4 { | ||
269 | err = errors.StructuralError("expiration subpacket with bad length") | ||
270 | return | ||
271 | } | ||
272 | sig.SigLifetimeSecs = new(uint32) | ||
273 | *sig.SigLifetimeSecs = binary.BigEndian.Uint32(subpacket) | ||
274 | case keyExpirationSubpacket: | ||
275 | // Key expiration time, section 5.2.3.6 | ||
276 | if !isHashed { | ||
277 | return | ||
278 | } | ||
279 | if len(subpacket) != 4 { | ||
280 | err = errors.StructuralError("key expiration subpacket with bad length") | ||
281 | return | ||
282 | } | ||
283 | sig.KeyLifetimeSecs = new(uint32) | ||
284 | *sig.KeyLifetimeSecs = binary.BigEndian.Uint32(subpacket) | ||
285 | case prefSymmetricAlgosSubpacket: | ||
286 | // Preferred symmetric algorithms, section 5.2.3.7 | ||
287 | if !isHashed { | ||
288 | return | ||
289 | } | ||
290 | sig.PreferredSymmetric = make([]byte, len(subpacket)) | ||
291 | copy(sig.PreferredSymmetric, subpacket) | ||
292 | case issuerSubpacket: | ||
293 | // Issuer, section 5.2.3.5 | ||
294 | if len(subpacket) != 8 { | ||
295 | err = errors.StructuralError("issuer subpacket with bad length") | ||
296 | return | ||
297 | } | ||
298 | sig.IssuerKeyId = new(uint64) | ||
299 | *sig.IssuerKeyId = binary.BigEndian.Uint64(subpacket) | ||
300 | case prefHashAlgosSubpacket: | ||
301 | // Preferred hash algorithms, section 5.2.3.8 | ||
302 | if !isHashed { | ||
303 | return | ||
304 | } | ||
305 | sig.PreferredHash = make([]byte, len(subpacket)) | ||
306 | copy(sig.PreferredHash, subpacket) | ||
307 | case prefCompressionSubpacket: | ||
308 | // Preferred compression algorithms, section 5.2.3.9 | ||
309 | if !isHashed { | ||
310 | return | ||
311 | } | ||
312 | sig.PreferredCompression = make([]byte, len(subpacket)) | ||
313 | copy(sig.PreferredCompression, subpacket) | ||
314 | case primaryUserIdSubpacket: | ||
315 | // Primary User ID, section 5.2.3.19 | ||
316 | if !isHashed { | ||
317 | return | ||
318 | } | ||
319 | if len(subpacket) != 1 { | ||
320 | err = errors.StructuralError("primary user id subpacket with bad length") | ||
321 | return | ||
322 | } | ||
323 | sig.IsPrimaryId = new(bool) | ||
324 | if subpacket[0] > 0 { | ||
325 | *sig.IsPrimaryId = true | ||
326 | } | ||
327 | case keyFlagsSubpacket: | ||
328 | // Key flags, section 5.2.3.21 | ||
329 | if !isHashed { | ||
330 | return | ||
331 | } | ||
332 | if len(subpacket) == 0 { | ||
333 | err = errors.StructuralError("empty key flags subpacket") | ||
334 | return | ||
335 | } | ||
336 | sig.FlagsValid = true | ||
337 | if subpacket[0]&KeyFlagCertify != 0 { | ||
338 | sig.FlagCertify = true | ||
339 | } | ||
340 | if subpacket[0]&KeyFlagSign != 0 { | ||
341 | sig.FlagSign = true | ||
342 | } | ||
343 | if subpacket[0]&KeyFlagEncryptCommunications != 0 { | ||
344 | sig.FlagEncryptCommunications = true | ||
345 | } | ||
346 | if subpacket[0]&KeyFlagEncryptStorage != 0 { | ||
347 | sig.FlagEncryptStorage = true | ||
348 | } | ||
349 | case reasonForRevocationSubpacket: | ||
350 | // Reason For Revocation, section 5.2.3.23 | ||
351 | if !isHashed { | ||
352 | return | ||
353 | } | ||
354 | if len(subpacket) == 0 { | ||
355 | err = errors.StructuralError("empty revocation reason subpacket") | ||
356 | return | ||
357 | } | ||
358 | sig.RevocationReason = new(uint8) | ||
359 | *sig.RevocationReason = subpacket[0] | ||
360 | sig.RevocationReasonText = string(subpacket[1:]) | ||
361 | case featuresSubpacket: | ||
362 | // Features subpacket, section 5.2.3.24 specifies a very general | ||
363 | // mechanism for OpenPGP implementations to signal support for new | ||
364 | // features. In practice, the subpacket is used exclusively to | ||
365 | // indicate support for MDC-protected encryption. | ||
366 | sig.MDC = len(subpacket) >= 1 && subpacket[0]&1 == 1 | ||
367 | case embeddedSignatureSubpacket: | ||
368 | // Only usage is in signatures that cross-certify | ||
369 | // signing subkeys. section 5.2.3.26 describes the | ||
370 | // format, with its usage described in section 11.1 | ||
371 | if sig.EmbeddedSignature != nil { | ||
372 | err = errors.StructuralError("Cannot have multiple embedded signatures") | ||
373 | return | ||
374 | } | ||
375 | sig.EmbeddedSignature = new(Signature) | ||
376 | // Embedded signatures are required to be v4 signatures see | ||
377 | // section 12.1. However, we only parse v4 signatures in this | ||
378 | // file anyway. | ||
379 | if err := sig.EmbeddedSignature.parse(bytes.NewBuffer(subpacket)); err != nil { | ||
380 | return nil, err | ||
381 | } | ||
382 | if sigType := sig.EmbeddedSignature.SigType; sigType != SigTypePrimaryKeyBinding { | ||
383 | return nil, errors.StructuralError("cross-signature has unexpected type " + strconv.Itoa(int(sigType))) | ||
384 | } | ||
385 | default: | ||
386 | if isCritical { | ||
387 | err = errors.UnsupportedError("unknown critical signature subpacket type " + strconv.Itoa(int(packetType))) | ||
388 | return | ||
389 | } | ||
390 | } | ||
391 | return | ||
392 | |||
393 | Truncated: | ||
394 | err = errors.StructuralError("signature subpacket truncated") | ||
395 | return | ||
396 | } | ||
397 | |||
398 | // subpacketLengthLength returns the length, in bytes, of an encoded length value. | ||
399 | func subpacketLengthLength(length int) int { | ||
400 | if length < 192 { | ||
401 | return 1 | ||
402 | } | ||
403 | if length < 16320 { | ||
404 | return 2 | ||
405 | } | ||
406 | return 5 | ||
407 | } | ||
408 | |||
409 | // serializeSubpacketLength marshals the given length into to. | ||
410 | func serializeSubpacketLength(to []byte, length int) int { | ||
411 | // RFC 4880, Section 4.2.2. | ||
412 | if length < 192 { | ||
413 | to[0] = byte(length) | ||
414 | return 1 | ||
415 | } | ||
416 | if length < 16320 { | ||
417 | length -= 192 | ||
418 | to[0] = byte((length >> 8) + 192) | ||
419 | to[1] = byte(length) | ||
420 | return 2 | ||
421 | } | ||
422 | to[0] = 255 | ||
423 | to[1] = byte(length >> 24) | ||
424 | to[2] = byte(length >> 16) | ||
425 | to[3] = byte(length >> 8) | ||
426 | to[4] = byte(length) | ||
427 | return 5 | ||
428 | } | ||
429 | |||
430 | // subpacketsLength returns the serialized length, in bytes, of the given | ||
431 | // subpackets. | ||
432 | func subpacketsLength(subpackets []outputSubpacket, hashed bool) (length int) { | ||
433 | for _, subpacket := range subpackets { | ||
434 | if subpacket.hashed == hashed { | ||
435 | length += subpacketLengthLength(len(subpacket.contents) + 1) | ||
436 | length += 1 // type byte | ||
437 | length += len(subpacket.contents) | ||
438 | } | ||
439 | } | ||
440 | return | ||
441 | } | ||
442 | |||
443 | // serializeSubpackets marshals the given subpackets into to. | ||
444 | func serializeSubpackets(to []byte, subpackets []outputSubpacket, hashed bool) { | ||
445 | for _, subpacket := range subpackets { | ||
446 | if subpacket.hashed == hashed { | ||
447 | n := serializeSubpacketLength(to, len(subpacket.contents)+1) | ||
448 | to[n] = byte(subpacket.subpacketType) | ||
449 | to = to[1+n:] | ||
450 | n = copy(to, subpacket.contents) | ||
451 | to = to[n:] | ||
452 | } | ||
453 | } | ||
454 | return | ||
455 | } | ||
456 | |||
457 | // KeyExpired returns whether sig is a self-signature of a key that has | ||
458 | // expired. | ||
459 | func (sig *Signature) KeyExpired(currentTime time.Time) bool { | ||
460 | if sig.KeyLifetimeSecs == nil { | ||
461 | return false | ||
462 | } | ||
463 | expiry := sig.CreationTime.Add(time.Duration(*sig.KeyLifetimeSecs) * time.Second) | ||
464 | return currentTime.After(expiry) | ||
465 | } | ||
466 | |||
467 | // buildHashSuffix constructs the HashSuffix member of sig in preparation for signing. | ||
468 | func (sig *Signature) buildHashSuffix() (err error) { | ||
469 | hashedSubpacketsLen := subpacketsLength(sig.outSubpackets, true) | ||
470 | |||
471 | var ok bool | ||
472 | l := 6 + hashedSubpacketsLen | ||
473 | sig.HashSuffix = make([]byte, l+6) | ||
474 | sig.HashSuffix[0] = 4 | ||
475 | sig.HashSuffix[1] = uint8(sig.SigType) | ||
476 | sig.HashSuffix[2] = uint8(sig.PubKeyAlgo) | ||
477 | sig.HashSuffix[3], ok = s2k.HashToHashId(sig.Hash) | ||
478 | if !ok { | ||
479 | sig.HashSuffix = nil | ||
480 | return errors.InvalidArgumentError("hash cannot be represented in OpenPGP: " + strconv.Itoa(int(sig.Hash))) | ||
481 | } | ||
482 | sig.HashSuffix[4] = byte(hashedSubpacketsLen >> 8) | ||
483 | sig.HashSuffix[5] = byte(hashedSubpacketsLen) | ||
484 | serializeSubpackets(sig.HashSuffix[6:l], sig.outSubpackets, true) | ||
485 | trailer := sig.HashSuffix[l:] | ||
486 | trailer[0] = 4 | ||
487 | trailer[1] = 0xff | ||
488 | trailer[2] = byte(l >> 24) | ||
489 | trailer[3] = byte(l >> 16) | ||
490 | trailer[4] = byte(l >> 8) | ||
491 | trailer[5] = byte(l) | ||
492 | return | ||
493 | } | ||
494 | |||
495 | func (sig *Signature) signPrepareHash(h hash.Hash) (digest []byte, err error) { | ||
496 | err = sig.buildHashSuffix() | ||
497 | if err != nil { | ||
498 | return | ||
499 | } | ||
500 | |||
501 | h.Write(sig.HashSuffix) | ||
502 | digest = h.Sum(nil) | ||
503 | copy(sig.HashTag[:], digest) | ||
504 | return | ||
505 | } | ||
506 | |||
507 | // Sign signs a message with a private key. The hash, h, must contain | ||
508 | // the hash of the message to be signed and will be mutated by this function. | ||
509 | // On success, the signature is stored in sig. Call Serialize to write it out. | ||
510 | // If config is nil, sensible defaults will be used. | ||
511 | func (sig *Signature) Sign(h hash.Hash, priv *PrivateKey, config *Config) (err error) { | ||
512 | sig.outSubpackets = sig.buildSubpackets() | ||
513 | digest, err := sig.signPrepareHash(h) | ||
514 | if err != nil { | ||
515 | return | ||
516 | } | ||
517 | |||
518 | switch priv.PubKeyAlgo { | ||
519 | case PubKeyAlgoRSA, PubKeyAlgoRSASignOnly: | ||
520 | // supports both *rsa.PrivateKey and crypto.Signer | ||
521 | sig.RSASignature.bytes, err = priv.PrivateKey.(crypto.Signer).Sign(config.Random(), digest, sig.Hash) | ||
522 | sig.RSASignature.bitLength = uint16(8 * len(sig.RSASignature.bytes)) | ||
523 | case PubKeyAlgoDSA: | ||
524 | dsaPriv := priv.PrivateKey.(*dsa.PrivateKey) | ||
525 | |||
526 | // Need to truncate hashBytes to match FIPS 186-3 section 4.6. | ||
527 | subgroupSize := (dsaPriv.Q.BitLen() + 7) / 8 | ||
528 | if len(digest) > subgroupSize { | ||
529 | digest = digest[:subgroupSize] | ||
530 | } | ||
531 | r, s, err := dsa.Sign(config.Random(), dsaPriv, digest) | ||
532 | if err == nil { | ||
533 | sig.DSASigR.bytes = r.Bytes() | ||
534 | sig.DSASigR.bitLength = uint16(8 * len(sig.DSASigR.bytes)) | ||
535 | sig.DSASigS.bytes = s.Bytes() | ||
536 | sig.DSASigS.bitLength = uint16(8 * len(sig.DSASigS.bytes)) | ||
537 | } | ||
538 | case PubKeyAlgoECDSA: | ||
539 | var r, s *big.Int | ||
540 | if pk, ok := priv.PrivateKey.(*ecdsa.PrivateKey); ok { | ||
541 | // direct support, avoid asn1 wrapping/unwrapping | ||
542 | r, s, err = ecdsa.Sign(config.Random(), pk, digest) | ||
543 | } else { | ||
544 | var b []byte | ||
545 | b, err = priv.PrivateKey.(crypto.Signer).Sign(config.Random(), digest, nil) | ||
546 | if err == nil { | ||
547 | r, s, err = unwrapECDSASig(b) | ||
548 | } | ||
549 | } | ||
550 | if err == nil { | ||
551 | sig.ECDSASigR = fromBig(r) | ||
552 | sig.ECDSASigS = fromBig(s) | ||
553 | } | ||
554 | default: | ||
555 | err = errors.UnsupportedError("public key algorithm: " + strconv.Itoa(int(sig.PubKeyAlgo))) | ||
556 | } | ||
557 | |||
558 | return | ||
559 | } | ||
560 | |||
561 | // unwrapECDSASig parses the two integer components of an ASN.1-encoded ECDSA | ||
562 | // signature. | ||
563 | func unwrapECDSASig(b []byte) (r, s *big.Int, err error) { | ||
564 | var ecsdaSig struct { | ||
565 | R, S *big.Int | ||
566 | } | ||
567 | _, err = asn1.Unmarshal(b, &ecsdaSig) | ||
568 | if err != nil { | ||
569 | return | ||
570 | } | ||
571 | return ecsdaSig.R, ecsdaSig.S, nil | ||
572 | } | ||
573 | |||
574 | // SignUserId computes a signature from priv, asserting that pub is a valid | ||
575 | // key for the identity id. On success, the signature is stored in sig. Call | ||
576 | // Serialize to write it out. | ||
577 | // If config is nil, sensible defaults will be used. | ||
578 | func (sig *Signature) SignUserId(id string, pub *PublicKey, priv *PrivateKey, config *Config) error { | ||
579 | h, err := userIdSignatureHash(id, pub, sig.Hash) | ||
580 | if err != nil { | ||
581 | return err | ||
582 | } | ||
583 | return sig.Sign(h, priv, config) | ||
584 | } | ||
585 | |||
586 | // SignKey computes a signature from priv, asserting that pub is a subkey. On | ||
587 | // success, the signature is stored in sig. Call Serialize to write it out. | ||
588 | // If config is nil, sensible defaults will be used. | ||
589 | func (sig *Signature) SignKey(pub *PublicKey, priv *PrivateKey, config *Config) error { | ||
590 | h, err := keySignatureHash(&priv.PublicKey, pub, sig.Hash) | ||
591 | if err != nil { | ||
592 | return err | ||
593 | } | ||
594 | return sig.Sign(h, priv, config) | ||
595 | } | ||
596 | |||
597 | // Serialize marshals sig to w. Sign, SignUserId or SignKey must have been | ||
598 | // called first. | ||
599 | func (sig *Signature) Serialize(w io.Writer) (err error) { | ||
600 | if len(sig.outSubpackets) == 0 { | ||
601 | sig.outSubpackets = sig.rawSubpackets | ||
602 | } | ||
603 | if sig.RSASignature.bytes == nil && sig.DSASigR.bytes == nil && sig.ECDSASigR.bytes == nil { | ||
604 | return errors.InvalidArgumentError("Signature: need to call Sign, SignUserId or SignKey before Serialize") | ||
605 | } | ||
606 | |||
607 | sigLength := 0 | ||
608 | switch sig.PubKeyAlgo { | ||
609 | case PubKeyAlgoRSA, PubKeyAlgoRSASignOnly: | ||
610 | sigLength = 2 + len(sig.RSASignature.bytes) | ||
611 | case PubKeyAlgoDSA: | ||
612 | sigLength = 2 + len(sig.DSASigR.bytes) | ||
613 | sigLength += 2 + len(sig.DSASigS.bytes) | ||
614 | case PubKeyAlgoECDSA: | ||
615 | sigLength = 2 + len(sig.ECDSASigR.bytes) | ||
616 | sigLength += 2 + len(sig.ECDSASigS.bytes) | ||
617 | default: | ||
618 | panic("impossible") | ||
619 | } | ||
620 | |||
621 | unhashedSubpacketsLen := subpacketsLength(sig.outSubpackets, false) | ||
622 | length := len(sig.HashSuffix) - 6 /* trailer not included */ + | ||
623 | 2 /* length of unhashed subpackets */ + unhashedSubpacketsLen + | ||
624 | 2 /* hash tag */ + sigLength | ||
625 | err = serializeHeader(w, packetTypeSignature, length) | ||
626 | if err != nil { | ||
627 | return | ||
628 | } | ||
629 | |||
630 | _, err = w.Write(sig.HashSuffix[:len(sig.HashSuffix)-6]) | ||
631 | if err != nil { | ||
632 | return | ||
633 | } | ||
634 | |||
635 | unhashedSubpackets := make([]byte, 2+unhashedSubpacketsLen) | ||
636 | unhashedSubpackets[0] = byte(unhashedSubpacketsLen >> 8) | ||
637 | unhashedSubpackets[1] = byte(unhashedSubpacketsLen) | ||
638 | serializeSubpackets(unhashedSubpackets[2:], sig.outSubpackets, false) | ||
639 | |||
640 | _, err = w.Write(unhashedSubpackets) | ||
641 | if err != nil { | ||
642 | return | ||
643 | } | ||
644 | _, err = w.Write(sig.HashTag[:]) | ||
645 | if err != nil { | ||
646 | return | ||
647 | } | ||
648 | |||
649 | switch sig.PubKeyAlgo { | ||
650 | case PubKeyAlgoRSA, PubKeyAlgoRSASignOnly: | ||
651 | err = writeMPIs(w, sig.RSASignature) | ||
652 | case PubKeyAlgoDSA: | ||
653 | err = writeMPIs(w, sig.DSASigR, sig.DSASigS) | ||
654 | case PubKeyAlgoECDSA: | ||
655 | err = writeMPIs(w, sig.ECDSASigR, sig.ECDSASigS) | ||
656 | default: | ||
657 | panic("impossible") | ||
658 | } | ||
659 | return | ||
660 | } | ||
661 | |||
662 | // outputSubpacket represents a subpacket to be marshaled. | ||
663 | type outputSubpacket struct { | ||
664 | hashed bool // true if this subpacket is in the hashed area. | ||
665 | subpacketType signatureSubpacketType | ||
666 | isCritical bool | ||
667 | contents []byte | ||
668 | } | ||
669 | |||
670 | func (sig *Signature) buildSubpackets() (subpackets []outputSubpacket) { | ||
671 | creationTime := make([]byte, 4) | ||
672 | binary.BigEndian.PutUint32(creationTime, uint32(sig.CreationTime.Unix())) | ||
673 | subpackets = append(subpackets, outputSubpacket{true, creationTimeSubpacket, false, creationTime}) | ||
674 | |||
675 | if sig.IssuerKeyId != nil { | ||
676 | keyId := make([]byte, 8) | ||
677 | binary.BigEndian.PutUint64(keyId, *sig.IssuerKeyId) | ||
678 | subpackets = append(subpackets, outputSubpacket{true, issuerSubpacket, false, keyId}) | ||
679 | } | ||
680 | |||
681 | if sig.SigLifetimeSecs != nil && *sig.SigLifetimeSecs != 0 { | ||
682 | sigLifetime := make([]byte, 4) | ||
683 | binary.BigEndian.PutUint32(sigLifetime, *sig.SigLifetimeSecs) | ||
684 | subpackets = append(subpackets, outputSubpacket{true, signatureExpirationSubpacket, true, sigLifetime}) | ||
685 | } | ||
686 | |||
687 | // Key flags may only appear in self-signatures or certification signatures. | ||
688 | |||
689 | if sig.FlagsValid { | ||
690 | var flags byte | ||
691 | if sig.FlagCertify { | ||
692 | flags |= KeyFlagCertify | ||
693 | } | ||
694 | if sig.FlagSign { | ||
695 | flags |= KeyFlagSign | ||
696 | } | ||
697 | if sig.FlagEncryptCommunications { | ||
698 | flags |= KeyFlagEncryptCommunications | ||
699 | } | ||
700 | if sig.FlagEncryptStorage { | ||
701 | flags |= KeyFlagEncryptStorage | ||
702 | } | ||
703 | subpackets = append(subpackets, outputSubpacket{true, keyFlagsSubpacket, false, []byte{flags}}) | ||
704 | } | ||
705 | |||
706 | // The following subpackets may only appear in self-signatures | ||
707 | |||
708 | if sig.KeyLifetimeSecs != nil && *sig.KeyLifetimeSecs != 0 { | ||
709 | keyLifetime := make([]byte, 4) | ||
710 | binary.BigEndian.PutUint32(keyLifetime, *sig.KeyLifetimeSecs) | ||
711 | subpackets = append(subpackets, outputSubpacket{true, keyExpirationSubpacket, true, keyLifetime}) | ||
712 | } | ||
713 | |||
714 | if sig.IsPrimaryId != nil && *sig.IsPrimaryId { | ||
715 | subpackets = append(subpackets, outputSubpacket{true, primaryUserIdSubpacket, false, []byte{1}}) | ||
716 | } | ||
717 | |||
718 | if len(sig.PreferredSymmetric) > 0 { | ||
719 | subpackets = append(subpackets, outputSubpacket{true, prefSymmetricAlgosSubpacket, false, sig.PreferredSymmetric}) | ||
720 | } | ||
721 | |||
722 | if len(sig.PreferredHash) > 0 { | ||
723 | subpackets = append(subpackets, outputSubpacket{true, prefHashAlgosSubpacket, false, sig.PreferredHash}) | ||
724 | } | ||
725 | |||
726 | if len(sig.PreferredCompression) > 0 { | ||
727 | subpackets = append(subpackets, outputSubpacket{true, prefCompressionSubpacket, false, sig.PreferredCompression}) | ||
728 | } | ||
729 | |||
730 | return | ||
731 | } | ||
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 | } | ||
diff --git a/vendor/golang.org/x/crypto/openpgp/packet/symmetric_key_encrypted.go b/vendor/golang.org/x/crypto/openpgp/packet/symmetric_key_encrypted.go new file mode 100644 index 0000000..744c2d2 --- /dev/null +++ b/vendor/golang.org/x/crypto/openpgp/packet/symmetric_key_encrypted.go | |||
@@ -0,0 +1,155 @@ | |||
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 | "bytes" | ||
9 | "crypto/cipher" | ||
10 | "io" | ||
11 | "strconv" | ||
12 | |||
13 | "golang.org/x/crypto/openpgp/errors" | ||
14 | "golang.org/x/crypto/openpgp/s2k" | ||
15 | ) | ||
16 | |||
17 | // This is the largest session key that we'll support. Since no 512-bit cipher | ||
18 | // has even been seriously used, this is comfortably large. | ||
19 | const maxSessionKeySizeInBytes = 64 | ||
20 | |||
21 | // SymmetricKeyEncrypted represents a passphrase protected session key. See RFC | ||
22 | // 4880, section 5.3. | ||
23 | type SymmetricKeyEncrypted struct { | ||
24 | CipherFunc CipherFunction | ||
25 | s2k func(out, in []byte) | ||
26 | encryptedKey []byte | ||
27 | } | ||
28 | |||
29 | const symmetricKeyEncryptedVersion = 4 | ||
30 | |||
31 | func (ske *SymmetricKeyEncrypted) parse(r io.Reader) error { | ||
32 | // RFC 4880, section 5.3. | ||
33 | var buf [2]byte | ||
34 | if _, err := readFull(r, buf[:]); err != nil { | ||
35 | return err | ||
36 | } | ||
37 | if buf[0] != symmetricKeyEncryptedVersion { | ||
38 | return errors.UnsupportedError("SymmetricKeyEncrypted version") | ||
39 | } | ||
40 | ske.CipherFunc = CipherFunction(buf[1]) | ||
41 | |||
42 | if ske.CipherFunc.KeySize() == 0 { | ||
43 | return errors.UnsupportedError("unknown cipher: " + strconv.Itoa(int(buf[1]))) | ||
44 | } | ||
45 | |||
46 | var err error | ||
47 | ske.s2k, err = s2k.Parse(r) | ||
48 | if err != nil { | ||
49 | return err | ||
50 | } | ||
51 | |||
52 | encryptedKey := make([]byte, maxSessionKeySizeInBytes) | ||
53 | // The session key may follow. We just have to try and read to find | ||
54 | // out. If it exists then we limit it to maxSessionKeySizeInBytes. | ||
55 | n, err := readFull(r, encryptedKey) | ||
56 | if err != nil && err != io.ErrUnexpectedEOF { | ||
57 | return err | ||
58 | } | ||
59 | |||
60 | if n != 0 { | ||
61 | if n == maxSessionKeySizeInBytes { | ||
62 | return errors.UnsupportedError("oversized encrypted session key") | ||
63 | } | ||
64 | ske.encryptedKey = encryptedKey[:n] | ||
65 | } | ||
66 | |||
67 | return nil | ||
68 | } | ||
69 | |||
70 | // Decrypt attempts to decrypt an encrypted session key and returns the key and | ||
71 | // the cipher to use when decrypting a subsequent Symmetrically Encrypted Data | ||
72 | // packet. | ||
73 | func (ske *SymmetricKeyEncrypted) Decrypt(passphrase []byte) ([]byte, CipherFunction, error) { | ||
74 | key := make([]byte, ske.CipherFunc.KeySize()) | ||
75 | ske.s2k(key, passphrase) | ||
76 | |||
77 | if len(ske.encryptedKey) == 0 { | ||
78 | return key, ske.CipherFunc, nil | ||
79 | } | ||
80 | |||
81 | // the IV is all zeros | ||
82 | iv := make([]byte, ske.CipherFunc.blockSize()) | ||
83 | c := cipher.NewCFBDecrypter(ske.CipherFunc.new(key), iv) | ||
84 | plaintextKey := make([]byte, len(ske.encryptedKey)) | ||
85 | c.XORKeyStream(plaintextKey, ske.encryptedKey) | ||
86 | cipherFunc := CipherFunction(plaintextKey[0]) | ||
87 | if cipherFunc.blockSize() == 0 { | ||
88 | return nil, ske.CipherFunc, errors.UnsupportedError("unknown cipher: " + strconv.Itoa(int(cipherFunc))) | ||
89 | } | ||
90 | plaintextKey = plaintextKey[1:] | ||
91 | if l, cipherKeySize := len(plaintextKey), cipherFunc.KeySize(); l != cipherFunc.KeySize() { | ||
92 | return nil, cipherFunc, errors.StructuralError("length of decrypted key (" + strconv.Itoa(l) + ") " + | ||
93 | "not equal to cipher keysize (" + strconv.Itoa(cipherKeySize) + ")") | ||
94 | } | ||
95 | return plaintextKey, cipherFunc, nil | ||
96 | } | ||
97 | |||
98 | // SerializeSymmetricKeyEncrypted serializes a symmetric key packet to w. The | ||
99 | // packet contains a random session key, encrypted by a key derived from the | ||
100 | // given passphrase. The session key is returned and must be passed to | ||
101 | // SerializeSymmetricallyEncrypted. | ||
102 | // If config is nil, sensible defaults will be used. | ||
103 | func SerializeSymmetricKeyEncrypted(w io.Writer, passphrase []byte, config *Config) (key []byte, err error) { | ||
104 | cipherFunc := config.Cipher() | ||
105 | keySize := cipherFunc.KeySize() | ||
106 | if keySize == 0 { | ||
107 | return nil, errors.UnsupportedError("unknown cipher: " + strconv.Itoa(int(cipherFunc))) | ||
108 | } | ||
109 | |||
110 | s2kBuf := new(bytes.Buffer) | ||
111 | keyEncryptingKey := make([]byte, keySize) | ||
112 | // s2k.Serialize salts and stretches the passphrase, and writes the | ||
113 | // resulting key to keyEncryptingKey and the s2k descriptor to s2kBuf. | ||
114 | err = s2k.Serialize(s2kBuf, keyEncryptingKey, config.Random(), passphrase, &s2k.Config{Hash: config.Hash(), S2KCount: config.PasswordHashIterations()}) | ||
115 | if err != nil { | ||
116 | return | ||
117 | } | ||
118 | s2kBytes := s2kBuf.Bytes() | ||
119 | |||
120 | packetLength := 2 /* header */ + len(s2kBytes) + 1 /* cipher type */ + keySize | ||
121 | err = serializeHeader(w, packetTypeSymmetricKeyEncrypted, packetLength) | ||
122 | if err != nil { | ||
123 | return | ||
124 | } | ||
125 | |||
126 | var buf [2]byte | ||
127 | buf[0] = symmetricKeyEncryptedVersion | ||
128 | buf[1] = byte(cipherFunc) | ||
129 | _, err = w.Write(buf[:]) | ||
130 | if err != nil { | ||
131 | return | ||
132 | } | ||
133 | _, err = w.Write(s2kBytes) | ||
134 | if err != nil { | ||
135 | return | ||
136 | } | ||
137 | |||
138 | sessionKey := make([]byte, keySize) | ||
139 | _, err = io.ReadFull(config.Random(), sessionKey) | ||
140 | if err != nil { | ||
141 | return | ||
142 | } | ||
143 | iv := make([]byte, cipherFunc.blockSize()) | ||
144 | c := cipher.NewCFBEncrypter(cipherFunc.new(keyEncryptingKey), iv) | ||
145 | encryptedCipherAndKey := make([]byte, keySize+1) | ||
146 | c.XORKeyStream(encryptedCipherAndKey, buf[1:]) | ||
147 | c.XORKeyStream(encryptedCipherAndKey[1:], sessionKey) | ||
148 | _, err = w.Write(encryptedCipherAndKey) | ||
149 | if err != nil { | ||
150 | return | ||
151 | } | ||
152 | |||
153 | key = sessionKey | ||
154 | return | ||
155 | } | ||
diff --git a/vendor/golang.org/x/crypto/openpgp/packet/symmetrically_encrypted.go b/vendor/golang.org/x/crypto/openpgp/packet/symmetrically_encrypted.go new file mode 100644 index 0000000..6126030 --- /dev/null +++ b/vendor/golang.org/x/crypto/openpgp/packet/symmetrically_encrypted.go | |||
@@ -0,0 +1,290 @@ | |||
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/cipher" | ||
9 | "crypto/sha1" | ||
10 | "crypto/subtle" | ||
11 | "golang.org/x/crypto/openpgp/errors" | ||
12 | "hash" | ||
13 | "io" | ||
14 | "strconv" | ||
15 | ) | ||
16 | |||
17 | // SymmetricallyEncrypted represents a symmetrically encrypted byte string. The | ||
18 | // encrypted contents will consist of more OpenPGP packets. See RFC 4880, | ||
19 | // sections 5.7 and 5.13. | ||
20 | type SymmetricallyEncrypted struct { | ||
21 | MDC bool // true iff this is a type 18 packet and thus has an embedded MAC. | ||
22 | contents io.Reader | ||
23 | prefix []byte | ||
24 | } | ||
25 | |||
26 | const symmetricallyEncryptedVersion = 1 | ||
27 | |||
28 | func (se *SymmetricallyEncrypted) parse(r io.Reader) error { | ||
29 | if se.MDC { | ||
30 | // See RFC 4880, section 5.13. | ||
31 | var buf [1]byte | ||
32 | _, err := readFull(r, buf[:]) | ||
33 | if err != nil { | ||
34 | return err | ||
35 | } | ||
36 | if buf[0] != symmetricallyEncryptedVersion { | ||
37 | return errors.UnsupportedError("unknown SymmetricallyEncrypted version") | ||
38 | } | ||
39 | } | ||
40 | se.contents = r | ||
41 | return nil | ||
42 | } | ||
43 | |||
44 | // Decrypt returns a ReadCloser, from which the decrypted contents of the | ||
45 | // packet can be read. An incorrect key can, with high probability, be detected | ||
46 | // immediately and this will result in a KeyIncorrect error being returned. | ||
47 | func (se *SymmetricallyEncrypted) Decrypt(c CipherFunction, key []byte) (io.ReadCloser, error) { | ||
48 | keySize := c.KeySize() | ||
49 | if keySize == 0 { | ||
50 | return nil, errors.UnsupportedError("unknown cipher: " + strconv.Itoa(int(c))) | ||
51 | } | ||
52 | if len(key) != keySize { | ||
53 | return nil, errors.InvalidArgumentError("SymmetricallyEncrypted: incorrect key length") | ||
54 | } | ||
55 | |||
56 | if se.prefix == nil { | ||
57 | se.prefix = make([]byte, c.blockSize()+2) | ||
58 | _, err := readFull(se.contents, se.prefix) | ||
59 | if err != nil { | ||
60 | return nil, err | ||
61 | } | ||
62 | } else if len(se.prefix) != c.blockSize()+2 { | ||
63 | return nil, errors.InvalidArgumentError("can't try ciphers with different block lengths") | ||
64 | } | ||
65 | |||
66 | ocfbResync := OCFBResync | ||
67 | if se.MDC { | ||
68 | // MDC packets use a different form of OCFB mode. | ||
69 | ocfbResync = OCFBNoResync | ||
70 | } | ||
71 | |||
72 | s := NewOCFBDecrypter(c.new(key), se.prefix, ocfbResync) | ||
73 | if s == nil { | ||
74 | return nil, errors.ErrKeyIncorrect | ||
75 | } | ||
76 | |||
77 | plaintext := cipher.StreamReader{S: s, R: se.contents} | ||
78 | |||
79 | if se.MDC { | ||
80 | // MDC packets have an embedded hash that we need to check. | ||
81 | h := sha1.New() | ||
82 | h.Write(se.prefix) | ||
83 | return &seMDCReader{in: plaintext, h: h}, nil | ||
84 | } | ||
85 | |||
86 | // Otherwise, we just need to wrap plaintext so that it's a valid ReadCloser. | ||
87 | return seReader{plaintext}, nil | ||
88 | } | ||
89 | |||
90 | // seReader wraps an io.Reader with a no-op Close method. | ||
91 | type seReader struct { | ||
92 | in io.Reader | ||
93 | } | ||
94 | |||
95 | func (ser seReader) Read(buf []byte) (int, error) { | ||
96 | return ser.in.Read(buf) | ||
97 | } | ||
98 | |||
99 | func (ser seReader) Close() error { | ||
100 | return nil | ||
101 | } | ||
102 | |||
103 | const mdcTrailerSize = 1 /* tag byte */ + 1 /* length byte */ + sha1.Size | ||
104 | |||
105 | // An seMDCReader wraps an io.Reader, maintains a running hash and keeps hold | ||
106 | // of the most recent 22 bytes (mdcTrailerSize). Upon EOF, those bytes form an | ||
107 | // MDC packet containing a hash of the previous contents which is checked | ||
108 | // against the running hash. See RFC 4880, section 5.13. | ||
109 | type seMDCReader struct { | ||
110 | in io.Reader | ||
111 | h hash.Hash | ||
112 | trailer [mdcTrailerSize]byte | ||
113 | scratch [mdcTrailerSize]byte | ||
114 | trailerUsed int | ||
115 | error bool | ||
116 | eof bool | ||
117 | } | ||
118 | |||
119 | func (ser *seMDCReader) Read(buf []byte) (n int, err error) { | ||
120 | if ser.error { | ||
121 | err = io.ErrUnexpectedEOF | ||
122 | return | ||
123 | } | ||
124 | if ser.eof { | ||
125 | err = io.EOF | ||
126 | return | ||
127 | } | ||
128 | |||
129 | // If we haven't yet filled the trailer buffer then we must do that | ||
130 | // first. | ||
131 | for ser.trailerUsed < mdcTrailerSize { | ||
132 | n, err = ser.in.Read(ser.trailer[ser.trailerUsed:]) | ||
133 | ser.trailerUsed += n | ||
134 | if err == io.EOF { | ||
135 | if ser.trailerUsed != mdcTrailerSize { | ||
136 | n = 0 | ||
137 | err = io.ErrUnexpectedEOF | ||
138 | ser.error = true | ||
139 | return | ||
140 | } | ||
141 | ser.eof = true | ||
142 | n = 0 | ||
143 | return | ||
144 | } | ||
145 | |||
146 | if err != nil { | ||
147 | n = 0 | ||
148 | return | ||
149 | } | ||
150 | } | ||
151 | |||
152 | // If it's a short read then we read into a temporary buffer and shift | ||
153 | // the data into the caller's buffer. | ||
154 | if len(buf) <= mdcTrailerSize { | ||
155 | n, err = readFull(ser.in, ser.scratch[:len(buf)]) | ||
156 | copy(buf, ser.trailer[:n]) | ||
157 | ser.h.Write(buf[:n]) | ||
158 | copy(ser.trailer[:], ser.trailer[n:]) | ||
159 | copy(ser.trailer[mdcTrailerSize-n:], ser.scratch[:]) | ||
160 | if n < len(buf) { | ||
161 | ser.eof = true | ||
162 | err = io.EOF | ||
163 | } | ||
164 | return | ||
165 | } | ||
166 | |||
167 | n, err = ser.in.Read(buf[mdcTrailerSize:]) | ||
168 | copy(buf, ser.trailer[:]) | ||
169 | ser.h.Write(buf[:n]) | ||
170 | copy(ser.trailer[:], buf[n:]) | ||
171 | |||
172 | if err == io.EOF { | ||
173 | ser.eof = true | ||
174 | } | ||
175 | return | ||
176 | } | ||
177 | |||
178 | // This is a new-format packet tag byte for a type 19 (MDC) packet. | ||
179 | const mdcPacketTagByte = byte(0x80) | 0x40 | 19 | ||
180 | |||
181 | func (ser *seMDCReader) Close() error { | ||
182 | if ser.error { | ||
183 | return errors.SignatureError("error during reading") | ||
184 | } | ||
185 | |||
186 | for !ser.eof { | ||
187 | // We haven't seen EOF so we need to read to the end | ||
188 | var buf [1024]byte | ||
189 | _, err := ser.Read(buf[:]) | ||
190 | if err == io.EOF { | ||
191 | break | ||
192 | } | ||
193 | if err != nil { | ||
194 | return errors.SignatureError("error during reading") | ||
195 | } | ||
196 | } | ||
197 | |||
198 | if ser.trailer[0] != mdcPacketTagByte || ser.trailer[1] != sha1.Size { | ||
199 | return errors.SignatureError("MDC packet not found") | ||
200 | } | ||
201 | ser.h.Write(ser.trailer[:2]) | ||
202 | |||
203 | final := ser.h.Sum(nil) | ||
204 | if subtle.ConstantTimeCompare(final, ser.trailer[2:]) != 1 { | ||
205 | return errors.SignatureError("hash mismatch") | ||
206 | } | ||
207 | return nil | ||
208 | } | ||
209 | |||
210 | // An seMDCWriter writes through to an io.WriteCloser while maintains a running | ||
211 | // hash of the data written. On close, it emits an MDC packet containing the | ||
212 | // running hash. | ||
213 | type seMDCWriter struct { | ||
214 | w io.WriteCloser | ||
215 | h hash.Hash | ||
216 | } | ||
217 | |||
218 | func (w *seMDCWriter) Write(buf []byte) (n int, err error) { | ||
219 | w.h.Write(buf) | ||
220 | return w.w.Write(buf) | ||
221 | } | ||
222 | |||
223 | func (w *seMDCWriter) Close() (err error) { | ||
224 | var buf [mdcTrailerSize]byte | ||
225 | |||
226 | buf[0] = mdcPacketTagByte | ||
227 | buf[1] = sha1.Size | ||
228 | w.h.Write(buf[:2]) | ||
229 | digest := w.h.Sum(nil) | ||
230 | copy(buf[2:], digest) | ||
231 | |||
232 | _, err = w.w.Write(buf[:]) | ||
233 | if err != nil { | ||
234 | return | ||
235 | } | ||
236 | return w.w.Close() | ||
237 | } | ||
238 | |||
239 | // noOpCloser is like an ioutil.NopCloser, but for an io.Writer. | ||
240 | type noOpCloser struct { | ||
241 | w io.Writer | ||
242 | } | ||
243 | |||
244 | func (c noOpCloser) Write(data []byte) (n int, err error) { | ||
245 | return c.w.Write(data) | ||
246 | } | ||
247 | |||
248 | func (c noOpCloser) Close() error { | ||
249 | return nil | ||
250 | } | ||
251 | |||
252 | // SerializeSymmetricallyEncrypted serializes a symmetrically encrypted packet | ||
253 | // to w and returns a WriteCloser to which the to-be-encrypted packets can be | ||
254 | // written. | ||
255 | // If config is nil, sensible defaults will be used. | ||
256 | func SerializeSymmetricallyEncrypted(w io.Writer, c CipherFunction, key []byte, config *Config) (contents io.WriteCloser, err error) { | ||
257 | if c.KeySize() != len(key) { | ||
258 | return nil, errors.InvalidArgumentError("SymmetricallyEncrypted.Serialize: bad key length") | ||
259 | } | ||
260 | writeCloser := noOpCloser{w} | ||
261 | ciphertext, err := serializeStreamHeader(writeCloser, packetTypeSymmetricallyEncryptedMDC) | ||
262 | if err != nil { | ||
263 | return | ||
264 | } | ||
265 | |||
266 | _, err = ciphertext.Write([]byte{symmetricallyEncryptedVersion}) | ||
267 | if err != nil { | ||
268 | return | ||
269 | } | ||
270 | |||
271 | block := c.new(key) | ||
272 | blockSize := block.BlockSize() | ||
273 | iv := make([]byte, blockSize) | ||
274 | _, err = config.Random().Read(iv) | ||
275 | if err != nil { | ||
276 | return | ||
277 | } | ||
278 | s, prefix := NewOCFBEncrypter(block, iv, OCFBNoResync) | ||
279 | _, err = ciphertext.Write(prefix) | ||
280 | if err != nil { | ||
281 | return | ||
282 | } | ||
283 | plaintext := cipher.StreamWriter{S: s, W: ciphertext} | ||
284 | |||
285 | h := sha1.New() | ||
286 | h.Write(iv) | ||
287 | h.Write(iv[blockSize-2:]) | ||
288 | contents = &seMDCWriter{w: plaintext, h: h} | ||
289 | return | ||
290 | } | ||
diff --git a/vendor/golang.org/x/crypto/openpgp/packet/userattribute.go b/vendor/golang.org/x/crypto/openpgp/packet/userattribute.go new file mode 100644 index 0000000..96a2b38 --- /dev/null +++ b/vendor/golang.org/x/crypto/openpgp/packet/userattribute.go | |||
@@ -0,0 +1,91 @@ | |||
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 | "bytes" | ||
9 | "image" | ||
10 | "image/jpeg" | ||
11 | "io" | ||
12 | "io/ioutil" | ||
13 | ) | ||
14 | |||
15 | const UserAttrImageSubpacket = 1 | ||
16 | |||
17 | // UserAttribute is capable of storing other types of data about a user | ||
18 | // beyond name, email and a text comment. In practice, user attributes are typically used | ||
19 | // to store a signed thumbnail photo JPEG image of the user. | ||
20 | // See RFC 4880, section 5.12. | ||
21 | type UserAttribute struct { | ||
22 | Contents []*OpaqueSubpacket | ||
23 | } | ||
24 | |||
25 | // NewUserAttributePhoto creates a user attribute packet | ||
26 | // containing the given images. | ||
27 | func NewUserAttributePhoto(photos ...image.Image) (uat *UserAttribute, err error) { | ||
28 | uat = new(UserAttribute) | ||
29 | for _, photo := range photos { | ||
30 | var buf bytes.Buffer | ||
31 | // RFC 4880, Section 5.12.1. | ||
32 | data := []byte{ | ||
33 | 0x10, 0x00, // Little-endian image header length (16 bytes) | ||
34 | 0x01, // Image header version 1 | ||
35 | 0x01, // JPEG | ||
36 | 0, 0, 0, 0, // 12 reserved octets, must be all zero. | ||
37 | 0, 0, 0, 0, | ||
38 | 0, 0, 0, 0} | ||
39 | if _, err = buf.Write(data); err != nil { | ||
40 | return | ||
41 | } | ||
42 | if err = jpeg.Encode(&buf, photo, nil); err != nil { | ||
43 | return | ||
44 | } | ||
45 | uat.Contents = append(uat.Contents, &OpaqueSubpacket{ | ||
46 | SubType: UserAttrImageSubpacket, | ||
47 | Contents: buf.Bytes()}) | ||
48 | } | ||
49 | return | ||
50 | } | ||
51 | |||
52 | // NewUserAttribute creates a new user attribute packet containing the given subpackets. | ||
53 | func NewUserAttribute(contents ...*OpaqueSubpacket) *UserAttribute { | ||
54 | return &UserAttribute{Contents: contents} | ||
55 | } | ||
56 | |||
57 | func (uat *UserAttribute) parse(r io.Reader) (err error) { | ||
58 | // RFC 4880, section 5.13 | ||
59 | b, err := ioutil.ReadAll(r) | ||
60 | if err != nil { | ||
61 | return | ||
62 | } | ||
63 | uat.Contents, err = OpaqueSubpackets(b) | ||
64 | return | ||
65 | } | ||
66 | |||
67 | // Serialize marshals the user attribute to w in the form of an OpenPGP packet, including | ||
68 | // header. | ||
69 | func (uat *UserAttribute) Serialize(w io.Writer) (err error) { | ||
70 | var buf bytes.Buffer | ||
71 | for _, sp := range uat.Contents { | ||
72 | sp.Serialize(&buf) | ||
73 | } | ||
74 | if err = serializeHeader(w, packetTypeUserAttribute, buf.Len()); err != nil { | ||
75 | return err | ||
76 | } | ||
77 | _, err = w.Write(buf.Bytes()) | ||
78 | return | ||
79 | } | ||
80 | |||
81 | // ImageData returns zero or more byte slices, each containing | ||
82 | // JPEG File Interchange Format (JFIF), for each photo in the | ||
83 | // the user attribute packet. | ||
84 | func (uat *UserAttribute) ImageData() (imageData [][]byte) { | ||
85 | for _, sp := range uat.Contents { | ||
86 | if sp.SubType == UserAttrImageSubpacket && len(sp.Contents) > 16 { | ||
87 | imageData = append(imageData, sp.Contents[16:]) | ||
88 | } | ||
89 | } | ||
90 | return | ||
91 | } | ||
diff --git a/vendor/golang.org/x/crypto/openpgp/packet/userid.go b/vendor/golang.org/x/crypto/openpgp/packet/userid.go new file mode 100644 index 0000000..d6bea7d --- /dev/null +++ b/vendor/golang.org/x/crypto/openpgp/packet/userid.go | |||
@@ -0,0 +1,160 @@ | |||
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 | "io" | ||
9 | "io/ioutil" | ||
10 | "strings" | ||
11 | ) | ||
12 | |||
13 | // UserId contains text that is intended to represent the name and email | ||
14 | // address of the key holder. See RFC 4880, section 5.11. By convention, this | ||
15 | // takes the form "Full Name (Comment) <email@example.com>" | ||
16 | type UserId struct { | ||
17 | Id string // By convention, this takes the form "Full Name (Comment) <email@example.com>" which is split out in the fields below. | ||
18 | |||
19 | Name, Comment, Email string | ||
20 | } | ||
21 | |||
22 | func hasInvalidCharacters(s string) bool { | ||
23 | for _, c := range s { | ||
24 | switch c { | ||
25 | case '(', ')', '<', '>', 0: | ||
26 | return true | ||
27 | } | ||
28 | } | ||
29 | return false | ||
30 | } | ||
31 | |||
32 | // NewUserId returns a UserId or nil if any of the arguments contain invalid | ||
33 | // characters. The invalid characters are '\x00', '(', ')', '<' and '>' | ||
34 | func NewUserId(name, comment, email string) *UserId { | ||
35 | // RFC 4880 doesn't deal with the structure of userid strings; the | ||
36 | // name, comment and email form is just a convention. However, there's | ||
37 | // no convention about escaping the metacharacters and GPG just refuses | ||
38 | // to create user ids where, say, the name contains a '('. We mirror | ||
39 | // this behaviour. | ||
40 | |||
41 | if hasInvalidCharacters(name) || hasInvalidCharacters(comment) || hasInvalidCharacters(email) { | ||
42 | return nil | ||
43 | } | ||
44 | |||
45 | uid := new(UserId) | ||
46 | uid.Name, uid.Comment, uid.Email = name, comment, email | ||
47 | uid.Id = name | ||
48 | if len(comment) > 0 { | ||
49 | if len(uid.Id) > 0 { | ||
50 | uid.Id += " " | ||
51 | } | ||
52 | uid.Id += "(" | ||
53 | uid.Id += comment | ||
54 | uid.Id += ")" | ||
55 | } | ||
56 | if len(email) > 0 { | ||
57 | if len(uid.Id) > 0 { | ||
58 | uid.Id += " " | ||
59 | } | ||
60 | uid.Id += "<" | ||
61 | uid.Id += email | ||
62 | uid.Id += ">" | ||
63 | } | ||
64 | return uid | ||
65 | } | ||
66 | |||
67 | func (uid *UserId) parse(r io.Reader) (err error) { | ||
68 | // RFC 4880, section 5.11 | ||
69 | b, err := ioutil.ReadAll(r) | ||
70 | if err != nil { | ||
71 | return | ||
72 | } | ||
73 | uid.Id = string(b) | ||
74 | uid.Name, uid.Comment, uid.Email = parseUserId(uid.Id) | ||
75 | return | ||
76 | } | ||
77 | |||
78 | // Serialize marshals uid to w in the form of an OpenPGP packet, including | ||
79 | // header. | ||
80 | func (uid *UserId) Serialize(w io.Writer) error { | ||
81 | err := serializeHeader(w, packetTypeUserId, len(uid.Id)) | ||
82 | if err != nil { | ||
83 | return err | ||
84 | } | ||
85 | _, err = w.Write([]byte(uid.Id)) | ||
86 | return err | ||
87 | } | ||
88 | |||
89 | // parseUserId extracts the name, comment and email from a user id string that | ||
90 | // is formatted as "Full Name (Comment) <email@example.com>". | ||
91 | func parseUserId(id string) (name, comment, email string) { | ||
92 | var n, c, e struct { | ||
93 | start, end int | ||
94 | } | ||
95 | var state int | ||
96 | |||
97 | for offset, rune := range id { | ||
98 | switch state { | ||
99 | case 0: | ||
100 | // Entering name | ||
101 | n.start = offset | ||
102 | state = 1 | ||
103 | fallthrough | ||
104 | case 1: | ||
105 | // In name | ||
106 | if rune == '(' { | ||
107 | state = 2 | ||
108 | n.end = offset | ||
109 | } else if rune == '<' { | ||
110 | state = 5 | ||
111 | n.end = offset | ||
112 | } | ||
113 | case 2: | ||
114 | // Entering comment | ||
115 | c.start = offset | ||
116 | state = 3 | ||
117 | fallthrough | ||
118 | case 3: | ||
119 | // In comment | ||
120 | if rune == ')' { | ||
121 | state = 4 | ||
122 | c.end = offset | ||
123 | } | ||
124 | case 4: | ||
125 | // Between comment and email | ||
126 | if rune == '<' { | ||
127 | state = 5 | ||
128 | } | ||
129 | case 5: | ||
130 | // Entering email | ||
131 | e.start = offset | ||
132 | state = 6 | ||
133 | fallthrough | ||
134 | case 6: | ||
135 | // In email | ||
136 | if rune == '>' { | ||
137 | state = 7 | ||
138 | e.end = offset | ||
139 | } | ||
140 | default: | ||
141 | // After email | ||
142 | } | ||
143 | } | ||
144 | switch state { | ||
145 | case 1: | ||
146 | // ended in the name | ||
147 | n.end = len(id) | ||
148 | case 3: | ||
149 | // ended in comment | ||
150 | c.end = len(id) | ||
151 | case 6: | ||
152 | // ended in email | ||
153 | e.end = len(id) | ||
154 | } | ||
155 | |||
156 | name = strings.TrimSpace(id[n.start:n.end]) | ||
157 | comment = strings.TrimSpace(id[c.start:c.end]) | ||
158 | email = strings.TrimSpace(id[e.start:e.end]) | ||
159 | return | ||
160 | } | ||