Fix compilation for gomobile iOS (#17)

* Move signature verification to errors

* Move cleartext messages to ClearTextMessage struct

* Fix documentation
This commit is contained in:
wussler 2019-07-02 07:36:02 -07:00 committed by GitHub
parent 552ce9554f
commit 9195b9ae92
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
16 changed files with 311 additions and 296 deletions

View file

@ -38,7 +38,7 @@ func TestAttachmentSetKey(t *testing.T) {
assert.Exactly(t, testSymmetricKey, symmetricKey)
}
func TestAttachnentEncryptDecrypt(t *testing.T) {
func TestAttachmentEncryptDecrypt(t *testing.T) {
var testAttachmentCleartext = "cc,\ndille."
var message = NewPlainMessage([]byte(testAttachmentCleartext))
@ -55,7 +55,7 @@ func TestAttachnentEncryptDecrypt(t *testing.T) {
assert.Exactly(t, message, redecData)
}
func TestAttachnentEncrypt(t *testing.T) {
func TestAttachmentEncrypt(t *testing.T) {
var testAttachmentCleartext = "cc,\ndille."
var message = NewPlainMessage([]byte(testAttachmentCleartext))
@ -66,7 +66,7 @@ func TestAttachnentEncrypt(t *testing.T) {
pgpMessage := NewPGPMessage(append(encSplit.GetKeyPacket(), encSplit.GetDataPacket()...))
redecData, _, err := testPrivateKeyRing.Decrypt(pgpMessage, nil, 0)
redecData, err := testPrivateKeyRing.Decrypt(pgpMessage, nil, 0)
if err != nil {
t.Fatal("Expected no error while decrypting attachment, got:", err)
}
@ -74,7 +74,7 @@ func TestAttachnentEncrypt(t *testing.T) {
assert.Exactly(t, message, redecData)
}
func TestAttachnentDecrypt(t *testing.T) {
func TestAttachmentDecrypt(t *testing.T) {
var testAttachmentCleartext = "cc,\ndille."
var message = NewPlainMessage([]byte(testAttachmentCleartext))

View file

@ -322,20 +322,16 @@ func (keyRing *KeyRing) UnlockJSONKeyRing(jsonData []byte) (newKeyRing *KeyRing,
return nil, err
}
token, _, err := keyRing.Decrypt(message, nil, 0)
token, err := keyRing.Decrypt(message, nil, 0)
if err != nil {
return nil, err
}
ver, err := keyRing.VerifyDetached(token, signature, 0)
err = keyRing.VerifyDetached(token, signature, 0)
if err != nil {
return nil, err
}
if !ver.IsValid() {
return nil, errors.New("gopenpgp: unable to verify token")
}
err = newKeyRing.Unlock(token.GetBinary())
if err != nil {
return nil, errors.New("gopenpgp: wrong token")

View file

@ -3,18 +3,11 @@ package crypto
import (
"bytes"
"crypto"
"errors"
"io"
"io/ioutil"
"math"
"time"
"golang.org/x/crypto/openpgp"
pgpErrors "golang.org/x/crypto/openpgp/errors"
"golang.org/x/crypto/openpgp/packet"
"github.com/ProtonMail/gopenpgp/constants"
"github.com/ProtonMail/gopenpgp/internal"
)
// Encrypt encrypts a PlainMessage, outputs a PGPMessage.
@ -36,13 +29,10 @@ func (keyRing *KeyRing) Encrypt(message *PlainMessage, privateKey *KeyRing) (*PG
// verifyTime : Time at verification (necessary only if verifyKey is not nil)
func (keyRing *KeyRing) Decrypt(
message *PGPMessage, verifyKey *KeyRing, verifyTime int64,
) (*PlainMessage, *Verification, error) {
decrypted, verifyStatus, err := asymmetricDecrypt(message.NewReader(), keyRing, verifyKey, verifyTime)
if err != nil {
return nil, nil, err
}
) (*PlainMessage, error) {
decrypted, err := asymmetricDecrypt(message.NewReader(), keyRing, verifyKey, verifyTime)
return NewPlainMessage(decrypted), newVerification(verifyStatus), nil
return NewPlainMessage(decrypted), err
}
// SignDetached generates and returns a PGPSignature for a given PlainMessage
@ -63,18 +53,16 @@ func (keyRing *KeyRing) SignDetached(message *PlainMessage) (*PGPSignature, erro
}
// VerifyDetached verifies a PlainMessage with embedded a PGPSignature
// and returns a Verification with the filled Verified field.
// and returns a SignatureVerificationError if fails
func (keyRing *KeyRing) VerifyDetached(
message *PlainMessage, signature *PGPSignature, verifyTime int64,
) (*Verification, error) {
var err error
verifyVal, err := verifySignature(
) (error) {
return verifySignature(
keyRing.GetEntities(),
message.NewReader(),
signature.GetBinary(),
verifyTime,
)
return newVerification(verifyVal), err
}
// ------ INTERNAL FUNCTIONS -------
@ -123,7 +111,7 @@ func asymmetricEncrypt(data []byte, publicKey *KeyRing, privateKey *KeyRing, isB
// Core for decryption+verification functions
func asymmetricDecrypt(
encryptedIO io.Reader, privateKey *KeyRing, verifyKey *KeyRing, verifyTime int64,
) (plaintext []byte, verified int, err error) {
) (plaintext []byte, err error) {
privKeyEntries := privateKey.GetEntities()
var additionalEntries openpgp.EntityList
@ -139,12 +127,12 @@ func asymmetricDecrypt(
messageDetails, err := openpgp.ReadMessage(encryptedIO, privKeyEntries, nil, config)
if err != nil {
return nil, constants.SIGNATURE_NOT_SIGNED, err
return nil, err
}
body, err := ioutil.ReadAll(messageDetails.UnverifiedBody)
if err != nil {
return nil, constants.SIGNATURE_NOT_SIGNED, err
return nil, err
}
if verifyKey != nil {
@ -152,104 +140,8 @@ func asymmetricDecrypt(
}
if verifyKey != nil {
verifyStatus, verifyError := verifyDetailsSignature(messageDetails, verifyKey)
if verifyStatus == constants.SIGNATURE_FAILED {
return nil, verifyStatus, errors.New(verifyError)
}
return body, verifyStatus, nil
return body, verifyDetailsSignature(messageDetails, verifyKey)
}
return body, constants.SIGNATURE_NOT_SIGNED, nil
}
// processSignatureExpiration handles signature time verification manually, so we can add a margin to the
// creationTime check.
func processSignatureExpiration(md *openpgp.MessageDetails, verifyTime int64) {
if md.SignatureError == pgpErrors.ErrSignatureExpired {
if verifyTime > 0 {
created := md.Signature.CreationTime.Unix()
expires := int64(math.MaxInt64)
if md.Signature.SigLifetimeSecs != nil {
expires = int64(*md.Signature.SigLifetimeSecs) + created
}
if created-internal.CreationTimeOffset <= verifyTime && verifyTime <= expires {
md.SignatureError = nil
}
} else {
// verifyTime = 0: time check disabled, everything is okay
md.SignatureError = nil
}
}
}
// Verify signature from message details
func verifyDetailsSignature(md *openpgp.MessageDetails, verifierKey *KeyRing) (int, string) {
if md.IsSigned {
if md.SignedBy != nil {
if len(verifierKey.entities) > 0 {
matches := verifierKey.entities.KeysById(md.SignedByKeyId)
if len(matches) > 0 {
if md.SignatureError == nil {
return constants.SIGNATURE_OK, ""
}
return constants.SIGNATURE_FAILED, md.SignatureError.Error()
}
} else {
return constants.SIGNATURE_NO_VERIFIER, ""
}
} else {
return constants.SIGNATURE_NO_VERIFIER, ""
}
}
return constants.SIGNATURE_NOT_SIGNED, ""
}
// verifySignature verifies if a signature is valid with the entity list
func verifySignature(
pubKeyEntries openpgp.EntityList, origText io.Reader, signature []byte, verifyTime int64) (int, error) {
config := &packet.Config{}
if verifyTime == 0 {
config.Time = func() time.Time {
return time.Unix(0, 0)
}
} else {
config.Time = func() time.Time {
return time.Unix(verifyTime+internal.CreationTimeOffset, 0)
}
}
signatureReader := bytes.NewReader(signature)
signer, err := openpgp.CheckDetachedSignature(pubKeyEntries, origText, signatureReader, config)
if err == pgpErrors.ErrSignatureExpired && signer != nil {
if verifyTime > 0 { // if verifyTime = 0: time check disabled, everything is okay
// Maybe the creation time offset pushed it over the edge
// Retry with the actual verification time
config.Time = func() time.Time {
return time.Unix(verifyTime, 0)
}
_, err = signatureReader.Seek(0, io.SeekStart)
if err != nil {
return constants.SIGNATURE_FAILED, err
}
signer, err = openpgp.CheckDetachedSignature(pubKeyEntries, origText, signatureReader, config)
if err != nil {
return constants.SIGNATURE_FAILED, err
}
}
}
if signer == nil {
return constants.SIGNATURE_FAILED, errors.New("gopenpgp: signer is empty")
}
// if signer.PrimaryKey.KeyId != signed.PrimaryKey.KeyId {
// // t.Errorf("wrong signer got:%x want:%x", signer.PrimaryKey.KeyId, 0)
// return false, errors.New("signer is nil")
// }
return constants.SIGNATURE_OK, nil
return body, nil
}

View file

@ -14,6 +14,7 @@ import (
"github.com/ProtonMail/gopenpgp/constants"
"github.com/ProtonMail/gopenpgp/internal"
"golang.org/x/crypto/openpgp/clearsign"
"golang.org/x/crypto/openpgp/packet"
)
@ -27,12 +28,6 @@ type PlainMessage struct {
TextType bool
}
// Verification for a PlainMessage
type Verification struct {
// If the decoded message was correctly signed. See constants.SIGNATURE* for all values.
Verified int
}
// PGPMessage stores a PGP-encrypted message.
type PGPMessage struct {
// The content of the message
@ -52,6 +47,12 @@ type PGPSplitMessage struct {
KeyPacket []byte
}
// ClearTextMessage, split signed clear text message container
type ClearTextMessage struct {
Data []byte
Signature []byte
}
// ---- GENERATORS -----
// NewPlainMessage generates a new binary PlainMessage ready for encryption,
@ -72,13 +73,6 @@ func NewPlainMessageFromString(text string) *PlainMessage {
}
}
// newVerification returns a new instance of *Verification with the specified value
func newVerification(value int) *Verification {
return &Verification{
Verified: value,
}
}
// NewPGPMessage generates a new PGPMessage from the unarmored binary data.
func NewPGPMessage(data []byte) *PGPMessage {
return &PGPMessage{
@ -147,6 +141,29 @@ func NewPGPSignatureFromArmored(armored string) (*PGPSignature, error) {
}, nil
}
// NewClearTextMessage generates a new ClearTextMessage from data and signature
func NewClearTextMessage(data []byte, signature []byte) *ClearTextMessage {
return &ClearTextMessage{
Data: data,
Signature: signature,
}
}
// NewClearTextMessageFromArmored returns the message body and unarmored signature from a clearsigned message.
func NewClearTextMessageFromArmored(signedMessage string) (*ClearTextMessage, error) {
modulusBlock, rest := clearsign.Decode([]byte(signedMessage))
if len(rest) != 0 {
return nil, errors.New("pmapi: extra data after modulus")
}
signature, err := ioutil.ReadAll(modulusBlock.ArmoredSignature.Body)
if err != nil {
return nil, err
}
return NewClearTextMessage(modulusBlock.Bytes, signature), nil
}
// ---- MODEL METHODS -----
// GetBinary returns the binary content of the message as a []byte
@ -164,19 +181,6 @@ func (msg *PlainMessage) GetBase64() string {
return base64.StdEncoding.EncodeToString(msg.Data)
}
// GetVerification returns the verification status of a verification,
// to use after the KeyRing.Decrypt* or KeyRing.Verify* functions.
// The int value returned is to compare to constants.SIGNATURE*.
func (ver *Verification) GetVerification() int {
return ver.Verified
}
// IsValid returns true if the message is signed and the signature is valid.
// To use after the KeyRing.Decrypt* or KeyRing.Verify* functions.
func (ver *Verification) IsValid() bool {
return ver.Verified == constants.SIGNATURE_OK
}
// NewReader returns a New io.Reader for the bianry data of the message
func (msg *PlainMessage) NewReader() io.Reader {
return bytes.NewReader(msg.GetBinary())
@ -317,6 +321,36 @@ func (msg *PGPSignature) GetArmored() (string, error) {
return armor.ArmorWithType(msg.Data, constants.PGPSignatureHeader)
}
// GetBinary returns the unarmored signed data as a []byte
func (msg *ClearTextMessage) GetBinary() []byte {
return msg.Data
}
// GetString returns the unarmored signed data as a string
func (msg *ClearTextMessage) GetString() string {
return string(msg.Data)
}
// GetSignature returns the unarmored binary signature as a []byte
func (msg *ClearTextMessage) GetSignature() []byte {
return msg.Signature
}
// GetArmored armors plaintext and signature with the PGP SIGNED MESSAGE armoring
func (msg *ClearTextMessage) GetArmored() (string, error) {
armSignature, err := armor.ArmorWithType(msg.GetSignature(), constants.PGPSignatureHeader)
if err != nil {
return "", err
}
str := "-----BEGIN PGP SIGNED MESSAGE-----\r\nHash:SHA512\r\n\r\n"
str += msg.GetString()
str += "\r\n"
str += armSignature
return str, nil
}
// ---- UTILS -----
// IsPGPMessage checks if data if has armored PGP message format.

View file

@ -5,7 +5,6 @@ import (
"strings"
"testing"
"github.com/ProtonMail/gopenpgp/constants"
"github.com/stretchr/testify/assert"
)
@ -67,13 +66,11 @@ func TestTextMessageEncryption(t *testing.T) {
t.Fatal("Expected no error when encrypting, got:", err)
}
decrypted, ver, err := testPrivateKeyRing.Decrypt(ciphertext, testPublicKeyRing, pgp.GetUnixTime())
decrypted, err := testPrivateKeyRing.Decrypt(ciphertext, testPublicKeyRing, pgp.GetUnixTime())
if err != nil {
t.Fatal("Expected no error when decrypting, got:", err)
}
assert.Exactly(t, message.GetString(), decrypted.GetString())
assert.Exactly(t, constants.SIGNATURE_OK, ver.GetVerification())
assert.Exactly(t, true, ver.IsValid())
}
func TestBinaryMessageEncryption(t *testing.T) {
@ -94,13 +91,11 @@ func TestBinaryMessageEncryption(t *testing.T) {
t.Fatal("Expected no error when encrypting, got:", err)
}
decrypted, ver, err := testPrivateKeyRing.Decrypt(ciphertext, testPublicKeyRing, pgp.GetUnixTime())
decrypted, err := testPrivateKeyRing.Decrypt(ciphertext, testPublicKeyRing, pgp.GetUnixTime())
if err != nil {
t.Fatal("Expected no error when decrypting, got:", err)
}
assert.Exactly(t, message.GetBinary(), decrypted.GetBinary())
assert.Exactly(t, constants.SIGNATURE_OK, ver.GetVerification())
assert.Exactly(t, true, ver.IsValid())
}
func TestIssue11(t *testing.T) {
@ -126,11 +121,10 @@ func TestIssue11(t *testing.T) {
t.Fatal("Expected no error while unlocking private keyring, got:", err)
}
plainMessage, verification, err := myKeyring.Decrypt(pgpMessage, senderKeyring, 0)
plainMessage, err := myKeyring.Decrypt(pgpMessage, senderKeyring, 0)
if err != nil {
t.Fatal("Expected no error while decrypting/verifying, got:", err)
}
assert.Exactly(t, "message from sender", plainMessage.GetString())
assert.Exactly(t, true, verification.IsValid())
}

View file

@ -8,7 +8,6 @@ import (
"strings"
gomime "github.com/ProtonMail/go-mime"
"github.com/ProtonMail/gopenpgp/constants"
"golang.org/x/crypto/openpgp"
"golang.org/x/crypto/openpgp/packet"
@ -28,13 +27,13 @@ type MIMECallbacks interface {
func (keyRing *KeyRing) DecryptMIMEMessage(
message *PGPMessage, verifyKey *KeyRing, callbacks MIMECallbacks, verifyTime int64,
) {
decryptedMessage, verification, err := keyRing.Decrypt(message, verifyKey, verifyTime)
decryptedMessage, err := keyRing.Decrypt(message, verifyKey, verifyTime)
if err != nil {
callbacks.OnError(err)
return
}
body, verified, attachments, attachmentHeaders, err := pgp.parseMIME(decryptedMessage.GetString(), verifyKey)
body, attachments, attachmentHeaders, err := pgp.parseMIME(decryptedMessage.GetString(), verifyKey)
if err != nil {
callbacks.OnError(err)
return
@ -45,28 +44,23 @@ func (keyRing *KeyRing) DecryptMIMEMessage(
callbacks.OnAttachment(attachmentHeaders[i], []byte(attachments[i]))
}
callbacks.OnEncryptedHeaders("")
if verification.GetVerification() != constants.SIGNATURE_NOT_SIGNED {
callbacks.OnVerified(verification.GetVerification())
} else {
callbacks.OnVerified(verified)
}
}
// ----- INTERNAL FUNCTIONS -----
func (pgp GopenPGP) parseMIME(
mimeBody string, verifierKey *KeyRing,
) (*gomime.BodyCollector, int, []string, []string, error) {
) (*gomime.BodyCollector, []string, []string, error) {
mm, err := mail.ReadMessage(strings.NewReader(mimeBody))
if err != nil {
return nil, 0, nil, nil, err
return nil, nil, nil, err
}
config := &packet.Config{DefaultCipher: packet.CipherAES256, Time: pgp.getTimeGenerator()}
h := textproto.MIMEHeader(mm.Header)
mmBodyData, err := ioutil.ReadAll(mm.Body)
if err != nil {
return nil, 0, nil, nil, err
return nil, nil, nil, err
}
printAccepter := gomime.NewMIMEPrinter()
@ -82,11 +76,12 @@ func (pgp GopenPGP) parseMIME(
signatureCollector := newSignatureCollector(mimeVisitor, pgpKering, config)
err = gomime.VisitAll(bytes.NewReader(mmBodyData), h, signatureCollector)
if err == nil && verifierKey != nil {
err = signatureCollector.verified;
}
verified := signatureCollector.verified
body := bodyCollector
atts := attachmentsCollector.GetAttachments()
attHeaders := attachmentsCollector.GetAttHeaders()
return body, verified, atts, attHeaders, err
return bodyCollector,
attachmentsCollector.GetAttachments(),
attachmentsCollector.GetAttHeaders(),
err
}

View file

@ -1,10 +1,9 @@
package crypto
import (
"github.com/ProtonMail/gopenpgp/internal"
"github.com/stretchr/testify/assert"
"io/ioutil"
"testing"
"github.com/stretchr/testify/assert"
)
// Corresponding key in testdata/mime_privateKey
@ -38,21 +37,8 @@ func TestDecrypt(t *testing.T) {
callbacks := Callbacks{
Testing: t,
}
privateKeyRing, _ := pgp.BuildKeyRingArmored(readTestFile("mime_privateKey", false))
block, err := internal.Unarmor(readTestFile("mime_publicKey", false))
if err != nil {
t.Fatal("Cannot unarmor public key: ", err)
}
publicKeyUnarmored, _ := ioutil.ReadAll(block.Body)
block, err = internal.Unarmor(readTestFile("mime_privateKey", false))
if err != nil {
t.Fatal("Cannot unarmor private key:", err)
}
privateKeyUnarmored, _ := ioutil.ReadAll(block.Body)
privateKeyRing, _ := pgp.BuildKeyRing(privateKeyUnarmored)
err = privateKeyRing.UnlockWithPassphrase(privateKeyPassword)
if err != nil {
t.Fatal("Cannot unlock private key:", err)
@ -65,13 +51,13 @@ func TestDecrypt(t *testing.T) {
privateKeyRing.DecryptMIMEMessage(
message,
pgp.BuildKeyRingNoError(publicKeyUnarmored),
nil,
&callbacks,
pgp.GetUnixTime())
}
func TestParse(t *testing.T) {
body, _, atts, attHeaders, err := pgp.parseMIME(readTestFile("mime_testMessage", false), nil)
body, atts, attHeaders, err := pgp.parseMIME(readTestFile("mime_testMessage", false), nil)
if err != nil {
t.Error("Expected no error while parsing message, got:", err)

141
crypto/signature.go Normal file
View file

@ -0,0 +1,141 @@
package crypto
import (
"bytes"
"fmt"
"io"
"math"
"time"
"golang.org/x/crypto/openpgp"
"golang.org/x/crypto/openpgp/packet"
pgpErrors "golang.org/x/crypto/openpgp/errors"
"github.com/ProtonMail/gopenpgp/constants"
"github.com/ProtonMail/gopenpgp/internal"
)
// SignatureVerificationError is returned from Decrypt and VerifyDetached functions when signature verification fails
type SignatureVerificationError struct {
Status int
Message string
}
// Error is the base method for all errors
func (e SignatureVerificationError) Error() string {
return fmt.Sprintf("Signature Verification Error: %v", e.Message)
}
// ------------------
// Internal functions
// ------------------
// newSignatureFailed creates a new SignatureVerificationError, type SIGNATURE_FAILED
func newSignatureFailed() SignatureVerificationError {
return SignatureVerificationError {
constants.SIGNATURE_FAILED,
"Invalid signature",
}
}
// newSignatureNotSigned creates a new SignatureVerificationError, type SIGNATURE_NOT_SIGNED
func newSignatureNotSigned() SignatureVerificationError {
return SignatureVerificationError {
constants.SIGNATURE_NOT_SIGNED,
"Missing signature",
}
}
// newSignatureNoVerifier creates a new SignatureVerificationError, type SIGNATURE_NO_VERIFIER
func newSignatureNoVerifier() SignatureVerificationError {
return SignatureVerificationError {
constants.SIGNATURE_NO_VERIFIER,
"No matching signature",
}
}
// processSignatureExpiration handles signature time verification manually, so we can add a margin to the
// creationTime check.
func processSignatureExpiration(md *openpgp.MessageDetails, verifyTime int64) {
if md.SignatureError == pgpErrors.ErrSignatureExpired {
if verifyTime > 0 {
created := md.Signature.CreationTime.Unix()
expires := int64(math.MaxInt64)
if md.Signature.SigLifetimeSecs != nil {
expires = int64(*md.Signature.SigLifetimeSecs) + created
}
if created-internal.CreationTimeOffset <= verifyTime && verifyTime <= expires {
md.SignatureError = nil
}
} else {
// verifyTime = 0: time check disabled, everything is okay
md.SignatureError = nil
}
}
}
// verifyDetailsSignature verifies signature from message details
func verifyDetailsSignature(md *openpgp.MessageDetails, verifierKey *KeyRing) error {
if md.IsSigned {
if md.SignedBy != nil {
if len(verifierKey.entities) > 0 {
matches := verifierKey.entities.KeysById(md.SignedByKeyId)
if len(matches) > 0 {
if md.SignatureError == nil {
return nil
}
return newSignatureFailed()
}
} else {
return newSignatureNoVerifier()
}
} else {
return newSignatureNoVerifier()
}
}
return newSignatureNoVerifier()
}
// verifySignature verifies if a signature is valid with the entity list
func verifySignature(pubKeyEntries openpgp.EntityList, origText io.Reader, signature []byte, verifyTime int64) error {
config := &packet.Config{}
if verifyTime == 0 {
config.Time = func() time.Time {
return time.Unix(0, 0)
}
} else {
config.Time = func() time.Time {
return time.Unix(verifyTime+internal.CreationTimeOffset, 0)
}
}
signatureReader := bytes.NewReader(signature)
signer, err := openpgp.CheckDetachedSignature(pubKeyEntries, origText, signatureReader, config)
if err == pgpErrors.ErrSignatureExpired && signer != nil {
if verifyTime > 0 { // if verifyTime = 0: time check disabled, everything is okay
// Maybe the creation time offset pushed it over the edge
// Retry with the actual verification time
config.Time = func() time.Time {
return time.Unix(verifyTime, 0)
}
_, err = signatureReader.Seek(0, io.SeekStart)
if err != nil {
return newSignatureFailed()
}
signer, err = openpgp.CheckDetachedSignature(pubKeyEntries, origText, signatureReader, config)
if err != nil {
return newSignatureFailed()
}
}
}
if signer == nil {
return newSignatureFailed()
}
return nil
}

View file

@ -8,7 +8,6 @@ import (
"net/textproto"
gomime "github.com/ProtonMail/go-mime"
"github.com/ProtonMail/gopenpgp/constants"
"golang.org/x/crypto/openpgp"
"golang.org/x/crypto/openpgp/packet"
@ -20,7 +19,7 @@ type SignatureCollector struct {
keyring openpgp.KeyRing
target gomime.VisitAcceptor
signature string
verified int
verified error
}
func newSignatureCollector(
@ -52,7 +51,7 @@ func (sc *SignatureCollector) Accept(
}
}
if len(multiparts) != 2 {
sc.verified = constants.SIGNATURE_NOT_SIGNED
sc.verified = newSignatureNotSigned()
// Invalid multipart/signed format just pass along
_, err = ioutil.ReadAll(rawBody)
if err != nil {
@ -97,12 +96,12 @@ func (sc *SignatureCollector) Accept(
_, err = openpgp.CheckArmoredDetachedSignature(sc.keyring, rawBody, bytes.NewReader(buffer), sc.config)
if err != nil {
sc.verified = constants.SIGNATURE_FAILED
sc.verified = newSignatureFailed()
} else {
sc.verified = constants.SIGNATURE_OK
sc.verified = nil
}
} else {
sc.verified = constants.SIGNATURE_NO_VERIFIER
sc.verified = newSignatureNoVerifier()
}
return nil
}

View file

@ -48,20 +48,20 @@ func TestSignTextDetached(t *testing.T) {
}
func TestVerifyTextDetachedSig(t *testing.T) {
signedMessage, err := signingKeyRing.VerifyDetached(message, textSignature, testTime)
if err != nil {
verificationError := signingKeyRing.VerifyDetached(message, textSignature, testTime)
if verificationError != nil {
t.Fatal("Cannot verify plaintext signature:", err)
}
assert.Exactly(t, constants.SIGNATURE_OK, signedMessage.GetVerification())
}
func TestVerifyTextDetachedSigWrong(t *testing.T) {
fakeMessage := NewPlainMessageFromString("wrong text")
signedMessage, err := signingKeyRing.VerifyDetached(fakeMessage, textSignature, testTime)
verificationError := signingKeyRing.VerifyDetached(fakeMessage, textSignature, testTime)
assert.EqualError(t, err, "gopenpgp: signer is empty")
assert.Exactly(t, constants.SIGNATURE_FAILED, signedMessage.GetVerification())
assert.EqualError(t, verificationError, "Signature Verification Error: Invalid signature")
err, _ := verificationError.(SignatureVerificationError)
assert.Exactly(t, constants.SIGNATURE_FAILED, err.Status)
}
func TestSignBinDetached(t *testing.T) {
@ -81,10 +81,8 @@ func TestSignBinDetached(t *testing.T) {
}
func TestVerifyBinDetachedSig(t *testing.T) {
signedMessage, err := signingKeyRing.VerifyDetached(message, binSignature, testTime)
if err != nil {
verificationError := signingKeyRing.VerifyDetached(message, binSignature, testTime)
if verificationError != nil {
t.Fatal("Cannot verify binary signature:", err)
}
assert.Exactly(t, constants.SIGNATURE_OK, signedMessage.GetVerification())
}