diff --git a/openpgp/clearsign/clearsign.go b/openpgp/clearsign/clearsign.go index 460347af..245a66f1 100644 --- a/openpgp/clearsign/clearsign.go +++ b/openpgp/clearsign/clearsign.go @@ -337,6 +337,7 @@ func (d *dashEscaper) Close() (err error) { sig.Hash = d.hashTypes[i] sig.CreationTime = t sig.IssuerKeyId = &k.KeyId + sig.IssuerKeyVersion = uint8(k.Version) sig.IssuerFingerprint = k.Fingerprint sig.Notations = d.config.Notations() sigLifetimeSecs := d.config.SigLifetime() diff --git a/openpgp/packet/signature.go b/openpgp/packet/signature.go index 4490fdf8..8dd6213b 100644 --- a/openpgp/packet/signature.go +++ b/openpgp/packet/signature.go @@ -87,11 +87,13 @@ type Signature struct { // The following are optional so are nil when not included in the // signature. + // The exception is IssuerKeyVersion, which defaults to 0. SigLifetimeSecs, KeyLifetimeSecs *uint32 PreferredSymmetric, PreferredHash, PreferredCompression []uint8 PreferredCipherSuites [][2]uint8 IssuerKeyId *uint64 + IssuerKeyVersion uint8 IssuerFingerprint []byte SignerUserId *string IsPrimaryId *bool @@ -637,6 +639,7 @@ func parseSignatureSubpacket(sig *Signature, subpacket []byte, isHashed bool) (r if v >= 5 && l != 32 || v < 5 && l != 20 { return nil, errors.StructuralError("bad fingerprint length") } + sig.IssuerKeyVersion = subpacket[0] sig.IssuerFingerprint = make([]byte, l) copy(sig.IssuerFingerprint, subpacket[1:]) sig.IssuerKeyId = new(uint64) @@ -694,14 +697,14 @@ func subpacketLengthLength(length int) int { } func (sig *Signature) CheckKeyIdOrFingerprint(pk *PublicKey) bool { - if sig.IssuerFingerprint != nil && len(sig.IssuerFingerprint) >= 20 { - return bytes.Equal(sig.IssuerFingerprint, pk.Fingerprint) + if sig.IssuerKeyVersion != 0 && len(sig.IssuerFingerprint) >= 20 { + return int(sig.IssuerKeyVersion) == pk.Version && bytes.Equal(sig.IssuerFingerprint, pk.Fingerprint) } return sig.IssuerKeyId != nil && *sig.IssuerKeyId == pk.KeyId } func (sig *Signature) CheckKeyIdOrFingerprintExplicit(fingerprint []byte, keyId uint64) bool { - if sig.IssuerFingerprint != nil && len(sig.IssuerFingerprint) >= 20 && fingerprint != nil { + if sig.IssuerKeyVersion != 0 && len(sig.IssuerFingerprint) >= 20 && fingerprint != nil { return bytes.Equal(sig.IssuerFingerprint, fingerprint) } return sig.IssuerKeyId != nil && *sig.IssuerKeyId == keyId @@ -918,6 +921,7 @@ func (sig *Signature) Sign(h hash.Hash, priv *PrivateKey, config *Config) (err e return errors.ErrDummyPrivateKey("dummy key found") } sig.Version = priv.PublicKey.Version + sig.IssuerKeyVersion = uint8(priv.PublicKey.Version) sig.IssuerFingerprint = priv.PublicKey.Fingerprint if sig.Version < 6 && config.RandomizeSignaturesViaNotation() { sig.removeNotationsWithName(SaltNotationName) @@ -933,7 +937,7 @@ func (sig *Signature) Sign(h hash.Hash, priv *PrivateKey, config *Config) (err e } sig.Notations = append(sig.Notations, ¬ation) } - sig.outSubpackets, err = sig.buildSubpackets(priv.PublicKey, config) + sig.outSubpackets, err = sig.buildSubpackets(config) if err != nil { return err } @@ -1254,7 +1258,7 @@ type outputSubpacket struct { contents []byte } -func (sig *Signature) buildSubpackets(issuer PublicKey, config *Config) (subpackets []outputSubpacket, err error) { +func (sig *Signature) buildSubpackets(config *Config) (subpackets []outputSubpacket, err error) { creationTime := make([]byte, 4) binary.BigEndian.PutUint32(creationTime, uint32(sig.CreationTime.Unix())) // Signature Creation Time @@ -1391,8 +1395,8 @@ func (sig *Signature) buildSubpackets(issuer PublicKey, config *Config) (subpack subpackets = append(subpackets, outputSubpacket{true, embeddedSignatureSubpacket, true, buf.Bytes()}) } // Issuer Fingerprint - if sig.IssuerFingerprint != nil { - contents := append([]uint8{uint8(issuer.Version)}, sig.IssuerFingerprint...) + if sig.IssuerKeyVersion != 0 && sig.IssuerFingerprint != nil { + contents := append([]uint8{sig.IssuerKeyVersion}, sig.IssuerFingerprint...) subpackets = append(subpackets, outputSubpacket{true, issuerFingerprintSubpacket, sig.Version >= 5, contents}) } // Intended Recipient Fingerprint diff --git a/openpgp/v2/read.go b/openpgp/v2/read.go index 7980c9b2..b04c67e4 100644 --- a/openpgp/v2/read.go +++ b/openpgp/v2/read.go @@ -297,8 +297,8 @@ func newSignatureCandidate(ops *packet.OnePassSignature) (sigCandidate *Signatur HashAlgorithm: ops.Hash, PubKeyAlgo: ops.PubKeyAlgo, IssuerKeyId: ops.KeyId, - Salt: ops.Salt, IssuerFingerprint: ops.KeyFingerprint, + Salt: ops.Salt, } sigCandidate.Hash, sigCandidate.WrappedHash, sigCandidate.SignatureError = hashForSignature( sigCandidate.HashAlgorithm, @@ -331,18 +331,20 @@ func newSignatureCandidateFromSignature(sig *packet.Signature) (sigCandidate *Si } func (sc *SignatureCandidate) validate() bool { + if sc.CorrespondingSig == nil { + return false + } correspondingSig := sc.CorrespondingSig invalidV3 := sc.OPSVersion == 3 && correspondingSig.Version == 6 - invalidV6 := (sc.OPSVersion == 6 && correspondingSig.Version != 6) || - (sc.OPSVersion == 6 && !bytes.Equal(sc.IssuerFingerprint, correspondingSig.IssuerFingerprint)) || - (sc.OPSVersion == 6 && !bytes.Equal(sc.Salt, correspondingSig.Salt())) - return correspondingSig != nil && + invalidV6 := sc.OPSVersion == 6 && + (correspondingSig.Version != 6 || + !bytes.Equal(sc.IssuerFingerprint, correspondingSig.IssuerFingerprint) || + !bytes.Equal(sc.Salt, correspondingSig.Salt())) + return !invalidV3 && !invalidV6 && sc.SigType == correspondingSig.SigType && sc.HashAlgorithm == correspondingSig.Hash && sc.PubKeyAlgo == correspondingSig.PubKeyAlgo && - sc.IssuerKeyId == *correspondingSig.IssuerKeyId && - !invalidV3 && - !invalidV6 + sc.IssuerKeyId == *correspondingSig.IssuerKeyId } // readSignedMessage reads a possibly signed message if mdin is non-zero then diff --git a/openpgp/v2/write.go b/openpgp/v2/write.go index 0692cec6..804a895a 100644 --- a/openpgp/v2/write.go +++ b/openpgp/v2/write.go @@ -910,6 +910,7 @@ func createSignaturePacket(signer *packet.PublicKey, sigType packet.SignatureTyp Hash: hash, CreationTime: config.Now(), IssuerKeyId: &signer.KeyId, + IssuerKeyVersion: uint8(signer.Version), IssuerFingerprint: signer.Fingerprint, Notations: config.Notations(), SigLifetimeSecs: &sigLifetimeSecs, diff --git a/openpgp/write.go b/openpgp/write.go index 84bc27d8..f66f8ff5 100644 --- a/openpgp/write.go +++ b/openpgp/write.go @@ -566,6 +566,7 @@ func createSignaturePacket(signer *packet.PublicKey, sigType packet.SignatureTyp Hash: hash, CreationTime: config.Now(), IssuerKeyId: &signer.KeyId, + IssuerKeyVersion: uint8(signer.Version), IssuerFingerprint: signer.Fingerprint, Notations: config.Notations(), SigLifetimeSecs: &sigLifetimeSecs,