diff options
Diffstat (limited to 'vendor/golang.org/x/crypto/openpgp/write.go')
-rw-r--r-- | vendor/golang.org/x/crypto/openpgp/write.go | 174 |
1 files changed, 107 insertions, 67 deletions
diff --git a/vendor/golang.org/x/crypto/openpgp/write.go b/vendor/golang.org/x/crypto/openpgp/write.go index 65a304c..4ee7178 100644 --- a/vendor/golang.org/x/crypto/openpgp/write.go +++ b/vendor/golang.org/x/crypto/openpgp/write.go | |||
@@ -164,12 +164,12 @@ func hashToHashId(h crypto.Hash) uint8 { | |||
164 | return v | 164 | return v |
165 | } | 165 | } |
166 | 166 | ||
167 | // Encrypt encrypts a message to a number of recipients and, optionally, signs | 167 | // writeAndSign writes the data as a payload package and, optionally, signs |
168 | // it. hints contains optional information, that is also encrypted, that aids | 168 | // it. hints contains optional information, that is also encrypted, |
169 | // the recipients in processing the message. The resulting WriteCloser must | 169 | // that aids the recipients in processing the message. The resulting |
170 | // be closed after the contents of the file have been written. | 170 | // WriteCloser must be closed after the contents of the file have been |
171 | // If config is nil, sensible defaults will be used. | 171 | // written. If config is nil, sensible defaults will be used. |
172 | func Encrypt(ciphertext io.Writer, to []*Entity, signed *Entity, hints *FileHints, config *packet.Config) (plaintext io.WriteCloser, err error) { | 172 | func writeAndSign(payload io.WriteCloser, candidateHashes []uint8, signed *Entity, hints *FileHints, config *packet.Config) (plaintext io.WriteCloser, err error) { |
173 | var signer *packet.PrivateKey | 173 | var signer *packet.PrivateKey |
174 | if signed != nil { | 174 | if signed != nil { |
175 | signKey, ok := signed.signingKey(config.Now()) | 175 | signKey, ok := signed.signingKey(config.Now()) |
@@ -185,6 +185,83 @@ func Encrypt(ciphertext io.Writer, to []*Entity, signed *Entity, hints *FileHint | |||
185 | } | 185 | } |
186 | } | 186 | } |
187 | 187 | ||
188 | var hash crypto.Hash | ||
189 | for _, hashId := range candidateHashes { | ||
190 | if h, ok := s2k.HashIdToHash(hashId); ok && h.Available() { | ||
191 | hash = h | ||
192 | break | ||
193 | } | ||
194 | } | ||
195 | |||
196 | // If the hash specified by config is a candidate, we'll use that. | ||
197 | if configuredHash := config.Hash(); configuredHash.Available() { | ||
198 | for _, hashId := range candidateHashes { | ||
199 | if h, ok := s2k.HashIdToHash(hashId); ok && h == configuredHash { | ||
200 | hash = h | ||
201 | break | ||
202 | } | ||
203 | } | ||
204 | } | ||
205 | |||
206 | if hash == 0 { | ||
207 | hashId := candidateHashes[0] | ||
208 | name, ok := s2k.HashIdToString(hashId) | ||
209 | if !ok { | ||
210 | name = "#" + strconv.Itoa(int(hashId)) | ||
211 | } | ||
212 | return nil, errors.InvalidArgumentError("cannot encrypt because no candidate hash functions are compiled in. (Wanted " + name + " in this case.)") | ||
213 | } | ||
214 | |||
215 | if signer != nil { | ||
216 | ops := &packet.OnePassSignature{ | ||
217 | SigType: packet.SigTypeBinary, | ||
218 | Hash: hash, | ||
219 | PubKeyAlgo: signer.PubKeyAlgo, | ||
220 | KeyId: signer.KeyId, | ||
221 | IsLast: true, | ||
222 | } | ||
223 | if err := ops.Serialize(payload); err != nil { | ||
224 | return nil, err | ||
225 | } | ||
226 | } | ||
227 | |||
228 | if hints == nil { | ||
229 | hints = &FileHints{} | ||
230 | } | ||
231 | |||
232 | w := payload | ||
233 | if signer != nil { | ||
234 | // If we need to write a signature packet after the literal | ||
235 | // data then we need to stop literalData from closing | ||
236 | // encryptedData. | ||
237 | w = noOpCloser{w} | ||
238 | |||
239 | } | ||
240 | var epochSeconds uint32 | ||
241 | if !hints.ModTime.IsZero() { | ||
242 | epochSeconds = uint32(hints.ModTime.Unix()) | ||
243 | } | ||
244 | literalData, err := packet.SerializeLiteral(w, hints.IsBinary, hints.FileName, epochSeconds) | ||
245 | if err != nil { | ||
246 | return nil, err | ||
247 | } | ||
248 | |||
249 | if signer != nil { | ||
250 | return signatureWriter{payload, literalData, hash, hash.New(), signer, config}, nil | ||
251 | } | ||
252 | return literalData, nil | ||
253 | } | ||
254 | |||
255 | // Encrypt encrypts a message to a number of recipients and, optionally, signs | ||
256 | // it. hints contains optional information, that is also encrypted, that aids | ||
257 | // the recipients in processing the message. The resulting WriteCloser must | ||
258 | // be closed after the contents of the file have been written. | ||
259 | // If config is nil, sensible defaults will be used. | ||
260 | func Encrypt(ciphertext io.Writer, to []*Entity, signed *Entity, hints *FileHints, config *packet.Config) (plaintext io.WriteCloser, err error) { | ||
261 | if len(to) == 0 { | ||
262 | return nil, errors.InvalidArgumentError("no encryption recipient provided") | ||
263 | } | ||
264 | |||
188 | // These are the possible ciphers that we'll use for the message. | 265 | // These are the possible ciphers that we'll use for the message. |
189 | candidateCiphers := []uint8{ | 266 | candidateCiphers := []uint8{ |
190 | uint8(packet.CipherAES128), | 267 | uint8(packet.CipherAES128), |
@@ -194,6 +271,7 @@ func Encrypt(ciphertext io.Writer, to []*Entity, signed *Entity, hints *FileHint | |||
194 | // These are the possible hash functions that we'll use for the signature. | 271 | // These are the possible hash functions that we'll use for the signature. |
195 | candidateHashes := []uint8{ | 272 | candidateHashes := []uint8{ |
196 | hashToHashId(crypto.SHA256), | 273 | hashToHashId(crypto.SHA256), |
274 | hashToHashId(crypto.SHA384), | ||
197 | hashToHashId(crypto.SHA512), | 275 | hashToHashId(crypto.SHA512), |
198 | hashToHashId(crypto.SHA1), | 276 | hashToHashId(crypto.SHA1), |
199 | hashToHashId(crypto.RIPEMD160), | 277 | hashToHashId(crypto.RIPEMD160), |
@@ -241,33 +319,6 @@ func Encrypt(ciphertext io.Writer, to []*Entity, signed *Entity, hints *FileHint | |||
241 | } | 319 | } |
242 | } | 320 | } |
243 | 321 | ||
244 | var hash crypto.Hash | ||
245 | for _, hashId := range candidateHashes { | ||
246 | if h, ok := s2k.HashIdToHash(hashId); ok && h.Available() { | ||
247 | hash = h | ||
248 | break | ||
249 | } | ||
250 | } | ||
251 | |||
252 | // If the hash specified by config is a candidate, we'll use that. | ||
253 | if configuredHash := config.Hash(); configuredHash.Available() { | ||
254 | for _, hashId := range candidateHashes { | ||
255 | if h, ok := s2k.HashIdToHash(hashId); ok && h == configuredHash { | ||
256 | hash = h | ||
257 | break | ||
258 | } | ||
259 | } | ||
260 | } | ||
261 | |||
262 | if hash == 0 { | ||
263 | hashId := candidateHashes[0] | ||
264 | name, ok := s2k.HashIdToString(hashId) | ||
265 | if !ok { | ||
266 | name = "#" + strconv.Itoa(int(hashId)) | ||
267 | } | ||
268 | return nil, errors.InvalidArgumentError("cannot encrypt because no candidate hash functions are compiled in. (Wanted " + name + " in this case.)") | ||
269 | } | ||
270 | |||
271 | symKey := make([]byte, cipher.KeySize()) | 322 | symKey := make([]byte, cipher.KeySize()) |
272 | if _, err := io.ReadFull(config.Random(), symKey); err != nil { | 323 | if _, err := io.ReadFull(config.Random(), symKey); err != nil { |
273 | return nil, err | 324 | return nil, err |
@@ -279,49 +330,38 @@ func Encrypt(ciphertext io.Writer, to []*Entity, signed *Entity, hints *FileHint | |||
279 | } | 330 | } |
280 | } | 331 | } |
281 | 332 | ||
282 | encryptedData, err := packet.SerializeSymmetricallyEncrypted(ciphertext, cipher, symKey, config) | 333 | payload, err := packet.SerializeSymmetricallyEncrypted(ciphertext, cipher, symKey, config) |
283 | if err != nil { | 334 | if err != nil { |
284 | return | 335 | return |
285 | } | 336 | } |
286 | 337 | ||
287 | if signer != nil { | 338 | return writeAndSign(payload, candidateHashes, signed, hints, config) |
288 | ops := &packet.OnePassSignature{ | 339 | } |
289 | SigType: packet.SigTypeBinary, | ||
290 | Hash: hash, | ||
291 | PubKeyAlgo: signer.PubKeyAlgo, | ||
292 | KeyId: signer.KeyId, | ||
293 | IsLast: true, | ||
294 | } | ||
295 | if err := ops.Serialize(encryptedData); err != nil { | ||
296 | return nil, err | ||
297 | } | ||
298 | } | ||
299 | 340 | ||
300 | if hints == nil { | 341 | // Sign signs a message. The resulting WriteCloser must be closed after the |
301 | hints = &FileHints{} | 342 | // contents of the file have been written. hints contains optional information |
343 | // that aids the recipients in processing the message. | ||
344 | // If config is nil, sensible defaults will be used. | ||
345 | func Sign(output io.Writer, signed *Entity, hints *FileHints, config *packet.Config) (input io.WriteCloser, err error) { | ||
346 | if signed == nil { | ||
347 | return nil, errors.InvalidArgumentError("no signer provided") | ||
302 | } | 348 | } |
303 | 349 | ||
304 | w := encryptedData | 350 | // These are the possible hash functions that we'll use for the signature. |
305 | if signer != nil { | 351 | candidateHashes := []uint8{ |
306 | // If we need to write a signature packet after the literal | 352 | hashToHashId(crypto.SHA256), |
307 | // data then we need to stop literalData from closing | 353 | hashToHashId(crypto.SHA384), |
308 | // encryptedData. | 354 | hashToHashId(crypto.SHA512), |
309 | w = noOpCloser{encryptedData} | 355 | hashToHashId(crypto.SHA1), |
310 | 356 | hashToHashId(crypto.RIPEMD160), | |
311 | } | ||
312 | var epochSeconds uint32 | ||
313 | if !hints.ModTime.IsZero() { | ||
314 | epochSeconds = uint32(hints.ModTime.Unix()) | ||
315 | } | ||
316 | literalData, err := packet.SerializeLiteral(w, hints.IsBinary, hints.FileName, epochSeconds) | ||
317 | if err != nil { | ||
318 | return nil, err | ||
319 | } | 357 | } |
320 | 358 | defaultHashes := candidateHashes[len(candidateHashes)-1:] | |
321 | if signer != nil { | 359 | preferredHashes := signed.primaryIdentity().SelfSignature.PreferredHash |
322 | return signatureWriter{encryptedData, literalData, hash, hash.New(), signer, config}, nil | 360 | if len(preferredHashes) == 0 { |
361 | preferredHashes = defaultHashes | ||
323 | } | 362 | } |
324 | return literalData, nil | 363 | candidateHashes = intersectPreferences(candidateHashes, preferredHashes) |
364 | return writeAndSign(noOpCloser{output}, candidateHashes, signed, hints, config) | ||
325 | } | 365 | } |
326 | 366 | ||
327 | // signatureWriter hashes the contents of a message while passing it along to | 367 | // signatureWriter hashes the contents of a message while passing it along to |