go.crypto/openpgp: fix user id signing.
Entity.SignIdentity used the wrong signature function and produced invalid certification signatures. Fixed. VerifyUserIdSignature was used for checking the self-signature on an identity, but didn't support anything but a self-signature. This change alters the low-level API so that checking cross-signatures is possible. Fixes golang/go#7371. LGTM=bradfitz R=bradfitz CC=golang-codereviews https://golang.org/cl/96240043
This commit is contained in:
+2
-2
@@ -364,7 +364,7 @@ EachPacket:
|
||||
}
|
||||
|
||||
if (sig.SigType == packet.SigTypePositiveCert || sig.SigType == packet.SigTypeGenericCert) && sig.IssuerKeyId != nil && *sig.IssuerKeyId == e.PrimaryKey.KeyId {
|
||||
if err = e.PrimaryKey.VerifyUserIdSignature(pkt.Id, sig); err != nil {
|
||||
if err = e.PrimaryKey.VerifyUserIdSignature(pkt.Id, e.PrimaryKey, sig); err != nil {
|
||||
return nil, errors.StructuralError("user ID self-signature invalid: " + err.Error())
|
||||
}
|
||||
current.SelfSignature = sig
|
||||
@@ -616,7 +616,7 @@ func (e *Entity) SignIdentity(identity string, signer *Entity, config *packet.Co
|
||||
CreationTime: config.Now(),
|
||||
IssuerKeyId: &signer.PrivateKey.KeyId,
|
||||
}
|
||||
if err := sig.SignKey(e.PrimaryKey, signer.PrivateKey, config); err != nil {
|
||||
if err := sig.SignUserId(identity, e.PrimaryKey, signer.PrivateKey, config); err != nil {
|
||||
return err
|
||||
}
|
||||
ident.Signatures = append(ident.Signatures, sig)
|
||||
|
||||
@@ -171,7 +171,43 @@ func TestKeyUsage(t *testing.T) {
|
||||
t.Errorf("Unexpected match for signing key id %X", id)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestIdVerification(t *testing.T) {
|
||||
kring, err := ReadKeyRing(readerFromHex(testKeys1And2PrivateHex))
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if err := kring[1].PrivateKey.Decrypt([]byte("passphrase")); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
const identity = "Test Key 1 (RSA)"
|
||||
if err := kring[0].SignIdentity(identity, kring[1], nil); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
ident, ok := kring[0].Identities[identity]
|
||||
if !ok {
|
||||
t.Fatal("identity missing from key after signing")
|
||||
}
|
||||
|
||||
checked := false
|
||||
for _, sig := range ident.Signatures {
|
||||
if sig.IssuerKeyId == nil || *sig.IssuerKeyId != kring[1].PrimaryKey.KeyId {
|
||||
continue
|
||||
}
|
||||
|
||||
if err := kring[1].PrimaryKey.VerifyUserIdSignature(identity, kring[0].PrimaryKey, sig); err != nil {
|
||||
t.Fatalf("error verifying new identity signature: %s", err)
|
||||
}
|
||||
checked = true
|
||||
break
|
||||
}
|
||||
|
||||
if !checked {
|
||||
t.Fatal("didn't find identity signature in Entity")
|
||||
}
|
||||
}
|
||||
|
||||
const expiringKeyHex = "988d0451d1ec5d010400ba3385721f2dc3f4ab096b2ee867ab77213f0a27a8538441c35d2fa225b08798a1439a66a5150e6bdc3f40f5d28d588c712394c632b6299f77db8c0d48d37903fb72ebd794d61be6aa774688839e5fdecfe06b2684cc115d240c98c66cb1ef22ae84e3aa0c2b0c28665c1e7d4d044e7f270706193f5223c8d44e0d70b7b8da830011010001b40f4578706972792074657374206b657988be041301020028050251d1ec5d021b03050900278d00060b090807030206150802090a0b0416020301021e01021780000a091072589ad75e237d8c033503fd10506d72837834eb7f994117740723adc39227104b0d326a1161871c0b415d25b4aedef946ca77ea4c05af9c22b32cf98be86ab890111fced1ee3f75e87b7cc3c00dc63bbc85dfab91c0dc2ad9de2c4d13a34659333a85c6acc1a669c5e1d6cecb0cf1e56c10e72d855ae177ddc9e766f9b2dda57ccbb75f57156438bbdb4e42b88d0451d1ec5d0104009c64906559866c5cb61578f5846a94fcee142a489c9b41e67b12bb54cfe86eb9bc8566460f9a720cb00d6526fbccfd4f552071a8e3f7744b1882d01036d811ee5a3fb91a1c568055758f43ba5d2c6a9676b012f3a1a89e47bbf624f1ad571b208f3cc6224eb378f1645dd3d47584463f9eadeacfd1ce6f813064fbfdcc4b5a53001101000188a504180102000f021b0c050251d1f06b050900093e89000a091072589ad75e237d8c20e00400ab8310a41461425b37889c4da28129b5fae6084fafbc0a47dd1adc74a264c6e9c9cc125f40462ee1433072a58384daef88c961c390ed06426a81b464a53194c4e291ddd7e2e2ba3efced01537d713bd111f48437bde2363446200995e8e0d4e528dda377fd1e8f8ede9c8e2198b393bd86852ce7457a7e3daf74d510461a5b77b88d0451d1ece8010400b3a519f83ab0010307e83bca895170acce8964a044190a2b368892f7a244758d9fc193482648acb1fb9780d28cc22d171931f38bb40279389fc9bf2110876d4f3db4fcfb13f22f7083877fe56592b3b65251312c36f83ffcb6d313c6a17f197dd471f0712aad15a8537b435a92471ba2e5b0c72a6c72536c3b567c558d7b6051001101000188a504180102000f021b0c050251d1f07b050900279091000a091072589ad75e237d8ce69e03fe286026afacf7c97ee20673864d4459a2240b5655219950643c7dba0ac384b1d4359c67805b21d98211f7b09c2a0ccf6410c8c04d4ff4a51293725d8d6570d9d8bb0e10c07d22357caeb49626df99c180be02d77d1fe8ed25e7a54481237646083a9f89a11566cd20b9e995b1487c5f9e02aeb434f3a1897cd416dd0a87861838da3e9e"
|
||||
|
||||
@@ -620,9 +620,9 @@ func userIdSignatureHash(id string, pk *PublicKey, hashFunc crypto.Hash) (h hash
|
||||
}
|
||||
|
||||
// VerifyUserIdSignature returns nil iff sig is a valid signature, made by this
|
||||
// public key, of id.
|
||||
func (pk *PublicKey) VerifyUserIdSignature(id string, sig *Signature) (err error) {
|
||||
h, err := userIdSignatureHash(id, pk, sig.Hash)
|
||||
// public key, that id is the identity of pub.
|
||||
func (pk *PublicKey) VerifyUserIdSignature(id string, pub *PublicKey, sig *Signature) (err error) {
|
||||
h, err := userIdSignatureHash(id, pub, sig.Hash)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -630,9 +630,9 @@ func (pk *PublicKey) VerifyUserIdSignature(id string, sig *Signature) (err error
|
||||
}
|
||||
|
||||
// VerifyUserIdSignatureV3 returns nil iff sig is a valid signature, made by this
|
||||
// public key, of id.
|
||||
func (pk *PublicKey) VerifyUserIdSignatureV3(id string, sig *SignatureV3) (err error) {
|
||||
h, err := userIdSignatureV3Hash(id, pk, sig.Hash)
|
||||
// public key, that id is the identity of pub.
|
||||
func (pk *PublicKey) VerifyUserIdSignatureV3(id string, pub *PublicKey, sig *SignatureV3) (err error) {
|
||||
h, err := userIdSignatureV3Hash(id, pub, sig.Hash)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -133,7 +133,7 @@ func TestEcc384Serialize(t *testing.T) {
|
||||
t.Error(err)
|
||||
}
|
||||
uidSig := p.(*Signature)
|
||||
err = pubkey.VerifyUserIdSignature(uid.Id, uidSig)
|
||||
err = pubkey.VerifyUserIdSignature(uid.Id, pubkey, uidSig)
|
||||
if err != nil {
|
||||
t.Error(err, ": UID")
|
||||
}
|
||||
|
||||
@@ -215,8 +215,8 @@ func (pk *PublicKeyV3) VerifySignatureV3(signed hash.Hash, sig *SignatureV3) (er
|
||||
}
|
||||
|
||||
// VerifyUserIdSignatureV3 returns nil iff sig is a valid signature, made by this
|
||||
// public key, of id.
|
||||
func (pk *PublicKeyV3) VerifyUserIdSignatureV3(id string, sig *SignatureV3) (err error) {
|
||||
// public key, that id is the identity of pub.
|
||||
func (pk *PublicKeyV3) VerifyUserIdSignatureV3(id string, pub *PublicKeyV3, sig *SignatureV3) (err error) {
|
||||
h, err := userIdSignatureV3Hash(id, pk, sig.Hash)
|
||||
if err != nil {
|
||||
return err
|
||||
|
||||
@@ -515,7 +515,7 @@ func (sig *Signature) SignUserId(id string, pub *PublicKey, priv *PrivateKey, co
|
||||
return sig.Sign(h, priv, config)
|
||||
}
|
||||
|
||||
// SignKey computes a signature from priv, asserting that pub is a subkey. On
|
||||
// SignKey computes a signature from priv, asserting that pub is a subkey. On
|
||||
// success, the signature is stored in sig. Call Serialize to write it out.
|
||||
// If config is nil, sensible defaults will be used.
|
||||
func (sig *Signature) SignKey(pub *PublicKey, priv *PrivateKey, config *Config) error {
|
||||
|
||||
Reference in New Issue
Block a user