Add keyRing.GetVerifiedSignatureTimestamp()

Add a function to verify a detached signature and access
its creation time.
This commit is contained in:
marin thiercelin 2021-12-20 15:45:14 +01:00
parent eec288520e
commit 6f86adc432
No known key found for this signature in database
GPG key ID: 117C025B1F21B2C6
7 changed files with 211 additions and 8 deletions

View file

@ -1,10 +1,14 @@
package crypto
import (
"bytes"
"errors"
"io"
"io/ioutil"
"regexp"
"testing"
"github.com/ProtonMail/go-crypto/openpgp/packet"
"github.com/ProtonMail/gopenpgp/v2/constants"
"github.com/stretchr/testify/assert"
)
@ -73,3 +77,120 @@ func TestVerifyBinDetachedSig(t *testing.T) {
t.Fatal("Cannot verify binary signature:", verificationError)
}
}
func Test_KeyRing_GetVerifiedSignatureTimestampSuccess(t *testing.T) {
message := NewPlainMessageFromString("Hello world!")
var time int64 = 1600000000
pgp.latestServerTime = time
defer func() {
pgp.latestServerTime = testTime
}()
signature, err := keyRingTestPrivate.SignDetached(message)
if err != nil {
t.Errorf("Got an error while generating the signature: %v", err)
}
actualTime, err := keyRingTestPublic.GetVerifiedSignatureTimestamp(message, signature, 0)
if err != nil {
t.Errorf("Got an error while parsing the signature creation time: %v", err)
}
if time != actualTime {
t.Errorf("Expected creation time to be %d, got %d", time, actualTime)
}
}
func Test_KeyRing_GetVerifiedSignatureWithTwoKeysTimestampSuccess(t *testing.T) {
publicKey1Armored, err := ioutil.ReadFile("testdata/signature/publicKey1")
if err != nil {
t.Errorf("Couldn't read the public key file: %v", err)
}
publicKey1 := parseKey(t, string(publicKey1Armored))
publicKey2Armored, err := ioutil.ReadFile("testdata/signature/publicKey2")
if err != nil {
t.Errorf("Couldn't read the public key file: %v", err)
}
publicKey2 := parseKey(t, string(publicKey2Armored))
message := NewPlainMessageFromString("hello world")
signatureArmored, err := ioutil.ReadFile("testdata/signature/detachedSigSignedTwice")
if err != nil {
t.Errorf("Couldn't read the signature file: %v", err)
}
signature, err := NewPGPSignatureFromArmored(string(signatureArmored))
if err != nil {
t.Errorf("Got an error while parsing the signature: %v", err)
}
time1 := getTimestampOfIssuer(signature, publicKey1.GetKeyID())
time2 := getTimestampOfIssuer(signature, publicKey2.GetKeyID())
keyRing, err := NewKeyRing(publicKey1)
if err != nil {
t.Errorf("Got an error while building the key ring: %v", err)
}
err = keyRing.AddKey(publicKey2)
if err != nil {
t.Errorf("Got an error while adding key 2 to the key ring: %v", err)
}
actualTime, err := keyRing.GetVerifiedSignatureTimestamp(message, signature, 0)
if err != nil {
t.Errorf("Got an error while parsing the signature creation time: %v", err)
}
if time1 != actualTime {
t.Errorf("Expected creation time to be %d, got %d", time1, actualTime)
}
if time2 == actualTime {
t.Errorf("Expected creation time to be different from %d", time2)
}
}
func parseKey(t *testing.T, keyArmored string) *Key {
key, err := NewKeyFromArmored(keyArmored)
if err != nil {
t.Errorf("Couldn't parse key: %v", err)
return nil
}
return key
}
func getTimestampOfIssuer(signature *PGPSignature, keyID uint64) int64 {
packets := packet.NewReader(bytes.NewReader(signature.Data))
var err error
var p packet.Packet
for {
p, err = packets.Next()
if errors.Is(err, io.EOF) {
break
}
if err != nil {
continue
}
sigPacket, ok := p.(*packet.Signature)
if !ok {
continue
}
var outBuf bytes.Buffer
err = sigPacket.Serialize(&outBuf)
if err != nil {
continue
}
if *sigPacket.IssuerKeyId == keyID {
return sigPacket.CreationTime.Unix()
}
}
return -1
}
func Test_KeyRing_GetVerifiedSignatureTimestampError(t *testing.T) {
message := NewPlainMessageFromString("Hello world!")
var time int64 = 1600000000
pgp.latestServerTime = time
defer func() {
pgp.latestServerTime = testTime
}()
signature, err := keyRingTestPrivate.SignDetached(message)
if err != nil {
t.Errorf("Got an error while generating the signature: %v", err)
}
message_corrupted := NewPlainMessageFromString("Ciao world!")
_, err = keyRingTestPublic.GetVerifiedSignatureTimestamp(message_corrupted, signature, 0)
if err == nil {
t.Errorf("Expected an error while parsing the creation time of a wrong signature, got nil")
}
}