package gpg import "strings" import "testing" import "github.com/ProtonMail/go-crypto/openpgp" // Generated keys must carry no signature notations (e.g. go-crypto's default // salt@notations.openpgpjs.org), which old yum/rpm OpenPGP parsers reject. func TestGeneratedKeyHasNoNotations(t *testing.T) { var km KeyMaterial var list openpgp.EntityList var name string var err error km, err = Generate("Repo Signer", "signer@example.com") if err != nil { t.Fatalf("generate: %v", err) } list, err = openpgp.ReadArmoredKeyRing(strings.NewReader(km.PrivateArmored)) if err != nil { t.Fatalf("read key: %v", err) } for name = range list[0].Identities { if list[0].Identities[name].SelfSignature != nil && len(list[0].Identities[name].SelfSignature.Notations) != 0 { t.Fatalf("identity %q self-signature has %d notation(s), want 0", name, len(list[0].Identities[name].SelfSignature.Notations)) } } } func TestVerifyDetachedMatchesSignerFingerprint(t *testing.T) { var km KeyMaterial var other KeyMaterial var sig string var message []byte var fingerprint string var keyID string var ok bool var err error km, err = Generate("Committer", "dev@example.com") if err != nil { t.Fatalf("generate: %v", err) } other, err = Generate("Someone Else", "other@example.com") if err != nil { t.Fatalf("generate other: %v", err) } message = []byte("tree 1234\nauthor Dev \n\ncommit body") sig, err = SignDetached(km.PrivateArmored, message) if err != nil { t.Fatalf("sign: %v", err) } fingerprint, keyID, ok = SignatureIssuer(sig) if !ok { t.Fatalf("expected signature issuer metadata") } if fingerprint != km.Fingerprint { t.Fatalf("issuer fingerprint = %q, want %q", fingerprint, km.Fingerprint) } if keyID != km.KeyID { t.Fatalf("issuer key id = %q, want %q", keyID, km.KeyID) } // Verifies against a keyring containing the signer's public key, returning // the signer's primary-key fingerprint. fingerprint, ok = VerifyDetached([]string{other.PublicArmored, km.PublicArmored}, message, sig) if !ok { t.Fatalf("expected signature to verify") } if fingerprint != km.Fingerprint { t.Fatalf("fingerprint = %q, want %q", fingerprint, km.Fingerprint) } // Tampered payload must not verify. _, ok = VerifyDetached([]string{km.PublicArmored}, []byte("tampered"), sig) if ok { t.Fatalf("expected tampered payload to fail verification") } // A keyring without the signer's key must not verify. _, ok = VerifyDetached([]string{other.PublicArmored}, message, sig) if ok { t.Fatalf("expected verification to fail without the signer's key") } } func TestSignDetachedVerifies(t *testing.T) { var km KeyMaterial var sig string var err error var keyring openpgp.EntityList var message []byte km, err = Generate("Repo Signer", "signer@example.com") if err != nil { t.Fatalf("generate: %v", err) } message = []byte("example metadata") sig, err = SignDetached(km.PrivateArmored, message) if err != nil { t.Fatalf("sign: %v", err) } if !strings.Contains(sig, "BEGIN PGP SIGNATURE") { t.Fatalf("expected armored signature, got: %q", sig) } keyring, err = openpgp.ReadArmoredKeyRing(strings.NewReader(km.PublicArmored)) if err != nil { t.Fatalf("read public key: %v", err) } _, err = openpgp.CheckArmoredDetachedSignature(keyring, strings.NewReader(string(message)), strings.NewReader(sig), nil) if err != nil { t.Fatalf("verify good signature: %v", err) } _, err = openpgp.CheckArmoredDetachedSignature(keyring, strings.NewReader("tampered"), strings.NewReader(sig), nil) if err == nil { t.Fatalf("expected verification to fail for tampered message") } }