123 lines
3.6 KiB
Go
123 lines
3.6 KiB
Go
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 <dev@example.com>\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("<repomd>example metadata</repomd>")
|
|
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")
|
|
}
|
|
}
|