diff --git a/openpgp/key_generation.go b/openpgp/key_generation.go index 0d2eb45b8..0a8ae5b4f 100644 --- a/openpgp/key_generation.go +++ b/openpgp/key_generation.go @@ -66,6 +66,12 @@ func NewEntity(name, comment, email string, config *packet.Config) (*Entity, err selfSignature.PreferredHash = []uint8{hashToHashId(config.Hash())} if config.Hash() != crypto.SHA256 { selfSignature.PreferredHash = append(selfSignature.PreferredHash, hashToHashId(crypto.SHA256)) + } else { + selfSignature.PreferredHash = []uint8{ + hashToHashId(crypto.SHA256), + hashToHashId(crypto.SHA512), + hashToHashId(crypto.SHA1), + } } // Likewise for DefaultCipher. @@ -74,10 +80,32 @@ func NewEntity(name, comment, email string, config *packet.Config) (*Entity, err selfSignature.PreferredSymmetric = append(selfSignature.PreferredSymmetric, uint8(packet.CipherAES128)) } + if config.Cipher() == packet.CipherAES256 { + selfSignature.PreferredSymmetric = append(selfSignature.PreferredSymmetric, []uint8{ + uint8(packet.CipherAES192), + uint8(packet.CipherCAST5), + uint8(packet.Cipher3DES), + }...) + } + + // Set for compression. + selfSignature.PreferredCompression = []uint8{uint8(config.Compression())} + if config.Compression() != packet.CompressionNone { + selfSignature.PreferredSymmetric = append(selfSignature.PreferredSymmetric, uint8(packet.CompressionNone)) + } else { + selfSignature.PreferredCompression = []uint8{ + uint8(packet.CompressionZLIB), + uint8(packet.CompressionZIP), + uint8(packet.CompressionNone), + } + } + // And for DefaultMode. - selfSignature.PreferredAEAD = []uint8{uint8(config.AEAD().Mode())} - if config.AEAD().Mode() != packet.AEADModeEAX { - selfSignature.PreferredAEAD = append(selfSignature.PreferredAEAD, uint8(packet.AEADModeEAX)) + if config.AEAD() != nil { + selfSignature.PreferredAEAD = []uint8{uint8(config.AEAD().Mode())} + if config.AEAD().Mode() != packet.AEADModeEAX { + selfSignature.PreferredAEAD = append(selfSignature.PreferredAEAD, uint8(packet.AEADModeEAX)) + } } // User ID binding signature diff --git a/openpgp/keys_test.go b/openpgp/keys_test.go index 7e30f4aee..5d334adcb 100644 --- a/openpgp/keys_test.go +++ b/openpgp/keys_test.go @@ -667,8 +667,8 @@ func TestNewEntityNilConfigPreferredHash(t *testing.T) { for _, identity := range entity.Identities { prefs := identity.SelfSignature.PreferredHash - if len(prefs) != 1 { - t.Fatal("expected preferred hashes list to be [SHA256]") + if len(prefs) != 3 { + t.Fatal("expected preferred hashes list to be long 3 items") } } } diff --git a/openpgp/packet/signature.go b/openpgp/packet/signature.go index 4662ec347..788054d1b 100644 --- a/openpgp/packet/signature.go +++ b/openpgp/packet/signature.go @@ -834,23 +834,35 @@ func (sig *Signature) buildSubpackets(issuer PublicKey) (subpackets []outputSubp binary.BigEndian.PutUint32(creationTime, uint32(sig.CreationTime.Unix())) subpackets = append(subpackets, outputSubpacket{true, creationTimeSubpacket, false, creationTime}) - if sig.IssuerKeyId != nil && sig.Version == 4 { - keyId := make([]byte, 8) - binary.BigEndian.PutUint64(keyId, *sig.IssuerKeyId) - subpackets = append(subpackets, outputSubpacket{true, issuerSubpacket, true, keyId}) - } - if sig.IssuerFingerprint != nil { - contents := append([]uint8{uint8(issuer.Version)}, sig.IssuerFingerprint...) - subpackets = append(subpackets, outputSubpacket{true, issuerFingerprintSubpacket, true, contents}) - } if sig.SigLifetimeSecs != nil && *sig.SigLifetimeSecs != 0 { sigLifetime := make([]byte, 4) binary.BigEndian.PutUint32(sigLifetime, *sig.SigLifetimeSecs) subpackets = append(subpackets, outputSubpacket{true, signatureExpirationSubpacket, true, sigLifetime}) } - // Key flags may only appear in self-signatures or certification signatures. + if sig.KeyLifetimeSecs != nil && *sig.KeyLifetimeSecs != 0 { + keyLifetime := make([]byte, 4) + binary.BigEndian.PutUint32(keyLifetime, *sig.KeyLifetimeSecs) + subpackets = append(subpackets, outputSubpacket{true, keyExpirationSubpacket, true, keyLifetime}) + } + if len(sig.PreferredSymmetric) > 0 { + subpackets = append(subpackets, outputSubpacket{true, prefSymmetricAlgosSubpacket, false, sig.PreferredSymmetric}) + } + + if len(sig.PreferredHash) > 0 { + subpackets = append(subpackets, outputSubpacket{true, prefHashAlgosSubpacket, false, sig.PreferredHash}) + } + + if len(sig.PreferredCompression) > 0 { + subpackets = append(subpackets, outputSubpacket{true, prefCompressionSubpacket, false, sig.PreferredCompression}) + } + + if sig.IsPrimaryId != nil && *sig.IsPrimaryId { + subpackets = append(subpackets, outputSubpacket{true, primaryUserIdSubpacket, false, []byte{1}}) + } + + // Key flags may only appear in self-signatures or certification signatures. if sig.FlagsValid { var flags byte if sig.FlagCertify { @@ -869,7 +881,6 @@ func (sig *Signature) buildSubpackets(issuer PublicKey) (subpackets []outputSubp } // The following subpackets may only appear in self-signatures. - var features = byte(0x00) if sig.MDC { features |= 0x01 @@ -885,28 +896,6 @@ func (sig *Signature) buildSubpackets(issuer PublicKey) (subpackets []outputSubp subpackets = append(subpackets, outputSubpacket{true, featuresSubpacket, false, []byte{features}}) } - if sig.KeyLifetimeSecs != nil && *sig.KeyLifetimeSecs != 0 { - keyLifetime := make([]byte, 4) - binary.BigEndian.PutUint32(keyLifetime, *sig.KeyLifetimeSecs) - subpackets = append(subpackets, outputSubpacket{true, keyExpirationSubpacket, true, keyLifetime}) - } - - if sig.IsPrimaryId != nil && *sig.IsPrimaryId { - subpackets = append(subpackets, outputSubpacket{true, primaryUserIdSubpacket, false, []byte{1}}) - } - - if len(sig.PreferredSymmetric) > 0 { - subpackets = append(subpackets, outputSubpacket{true, prefSymmetricAlgosSubpacket, false, sig.PreferredSymmetric}) - } - - if len(sig.PreferredHash) > 0 { - subpackets = append(subpackets, outputSubpacket{true, prefHashAlgosSubpacket, false, sig.PreferredHash}) - } - - if len(sig.PreferredCompression) > 0 { - subpackets = append(subpackets, outputSubpacket{true, prefCompressionSubpacket, false, sig.PreferredCompression}) - } - if len(sig.PolicyURI) > 0 { subpackets = append(subpackets, outputSubpacket{true, policyUriSubpacket, false, []uint8(sig.PolicyURI)}) } @@ -921,6 +910,17 @@ func (sig *Signature) buildSubpackets(issuer PublicKey) (subpackets []outputSubp append([]uint8{*sig.RevocationReason}, []uint8(sig.RevocationReasonText)...)}) } + if sig.IssuerKeyId != nil && sig.Version == 4 { + keyId := make([]byte, 8) + binary.BigEndian.PutUint64(keyId, *sig.IssuerKeyId) + subpackets = append(subpackets, outputSubpacket{false, issuerSubpacket, false, keyId}) + } + + if sig.IssuerFingerprint != nil { + contents := append([]uint8{uint8(issuer.Version)}, sig.IssuerFingerprint...) + subpackets = append(subpackets, outputSubpacket{false, issuerFingerprintSubpacket, false, contents}) + } + // EmbeddedSignature appears only in subkeys capable of signing and is serialized as per section 5.2.3.26. if sig.EmbeddedSignature != nil { var buf bytes.Buffer