@@ -206,7 +206,7 @@ func Decode(data []byte) (b *Block, rest []byte) {
206
206
type dashEscaper struct {
207
207
buffered * bufio.Writer
208
208
hashers []hash.Hash // one per key in privateKeys
209
- hashType crypto.Hash
209
+ hashTypes [] crypto.Hash
210
210
toHash io.Writer // writes to all the hashes in hashers
211
211
salts [][]byte // salts for the signatures if v6
212
212
armorHeader map [string ]string // Armor headers
@@ -328,7 +328,7 @@ func (d *dashEscaper) Close() (err error) {
328
328
sig .Version = k .Version
329
329
sig .SigType = packet .SigTypeText
330
330
sig .PubKeyAlgo = k .PubKeyAlgo
331
- sig .Hash = d .hashType
331
+ sig .Hash = d .hashTypes [ i ]
332
332
sig .CreationTime = t
333
333
sig .IssuerKeyId = & k .KeyId
334
334
sig .IssuerFingerprint = k .Fingerprint
@@ -398,11 +398,22 @@ func EncodeMultiWithHeader(w io.Writer, privateKeys []*packet.PrivateKey, config
398
398
if ! hashType .Available () {
399
399
return nil , errors .UnsupportedError ("unsupported hash type: " + strconv .Itoa (int (hashType )))
400
400
}
401
+
401
402
var hashers []hash.Hash
403
+ var hashTypes []crypto.Hash
402
404
var ws []io.Writer
403
405
var salts [][]byte
404
406
for _ , sk := range privateKeys {
405
- h := hashType .New ()
407
+ acceptedHashes := acceptableHashesToWrite (& sk .PublicKey )
408
+ // acceptedHashes contains at least one hash
409
+ selectedHashType := acceptedHashes [0 ]
410
+ for _ , acceptedHash := range acceptedHashes {
411
+ if hashType == acceptedHash {
412
+ selectedHashType = hashType
413
+ break
414
+ }
415
+ }
416
+ h := selectedHashType .New ()
406
417
if sk .Version == 6 {
407
418
// generate salt
408
419
var salt []byte
@@ -416,6 +427,7 @@ func EncodeMultiWithHeader(w io.Writer, privateKeys []*packet.PrivateKey, config
416
427
salts = append (salts , salt )
417
428
}
418
429
hashers = append (hashers , h )
430
+ hashTypes = append (hashTypes , selectedHashType )
419
431
ws = append (ws , h )
420
432
}
421
433
toHash := io .MultiWriter (ws ... )
@@ -446,7 +458,7 @@ func EncodeMultiWithHeader(w io.Writer, privateKeys []*packet.PrivateKey, config
446
458
plaintext = & dashEscaper {
447
459
buffered : buffered ,
448
460
hashers : hashers ,
449
- hashType : hashType ,
461
+ hashTypes : hashTypes ,
450
462
toHash : toHash ,
451
463
salts : salts ,
452
464
armorHeader : headers ,
@@ -489,3 +501,38 @@ func nameOfHash(h crypto.Hash) string {
489
501
}
490
502
return ""
491
503
}
504
+
505
+ func acceptableHashesToWrite (singingKey * packet.PublicKey ) []crypto.Hash {
506
+ switch singingKey .PubKeyAlgo {
507
+ case packet .PubKeyAlgoEd448 :
508
+ return []crypto.Hash {
509
+ crypto .SHA512 ,
510
+ crypto .SHA3_512 ,
511
+ }
512
+ case packet .PubKeyAlgoECDSA , packet .PubKeyAlgoEdDSA :
513
+ if curve , err := singingKey .Curve (); err == nil {
514
+ if curve == packet .Curve448 ||
515
+ curve == packet .CurveNistP521 ||
516
+ curve == packet .CurveBrainpoolP512 {
517
+ return []crypto.Hash {
518
+ crypto .SHA512 ,
519
+ crypto .SHA3_512 ,
520
+ }
521
+ } else if curve == packet .CurveBrainpoolP384 ||
522
+ curve == packet .CurveNistP384 {
523
+ return []crypto.Hash {
524
+ crypto .SHA384 ,
525
+ crypto .SHA512 ,
526
+ crypto .SHA3_512 ,
527
+ }
528
+ }
529
+ }
530
+ }
531
+ return []crypto.Hash {
532
+ crypto .SHA256 ,
533
+ crypto .SHA384 ,
534
+ crypto .SHA512 ,
535
+ crypto .SHA3_256 ,
536
+ crypto .SHA3_512 ,
537
+ }
538
+ }
0 commit comments