Fix verification of signature for PGP/MIME messages
We fix the verification of embedded and PGM/MIME signatures when decrypting PGP/MIME messages.
This commit is contained in:
parent
b97b3d886b
commit
e2f03af655
17 changed files with 749 additions and 8 deletions
|
|
@ -10,6 +10,7 @@ import (
|
|||
"github.com/ProtonMail/go-crypto/openpgp"
|
||||
"github.com/ProtonMail/go-crypto/openpgp/packet"
|
||||
gomime "github.com/ProtonMail/go-mime"
|
||||
"github.com/ProtonMail/gopenpgp/v2/constants"
|
||||
"github.com/pkg/errors"
|
||||
)
|
||||
|
||||
|
|
@ -28,16 +29,26 @@ func (keyRing *KeyRing) DecryptMIMEMessage(
|
|||
message *PGPMessage, verifyKey *KeyRing, callbacks MIMECallbacks, verifyTime int64,
|
||||
) {
|
||||
decryptedMessage, err := keyRing.Decrypt(message, verifyKey, verifyTime)
|
||||
embeddedSigError, err := separateSigError(err)
|
||||
if err != nil {
|
||||
callbacks.OnError(err)
|
||||
return
|
||||
}
|
||||
|
||||
body, attachments, attachmentHeaders, err := parseMIME(string(decryptedMessage.GetBinary()), verifyKey)
|
||||
mimeSigError, err := separateSigError(err)
|
||||
if err != nil {
|
||||
callbacks.OnError(err)
|
||||
return
|
||||
}
|
||||
// We only consider the signature to be failed if both embedded and mime verification failed
|
||||
if embeddedSigError != nil && mimeSigError != nil {
|
||||
callbacks.OnError(embeddedSigError)
|
||||
callbacks.OnError(mimeSigError)
|
||||
callbacks.OnVerified(prioritizeSignatureErrors(embeddedSigError, mimeSigError))
|
||||
return
|
||||
} else if verifyKey != nil {
|
||||
callbacks.OnVerified(constants.SIGNATURE_OK)
|
||||
}
|
||||
bodyContent, bodyMimeType := body.GetBody()
|
||||
callbacks.OnBody(bodyContent, bodyMimeType)
|
||||
for i := 0; i < len(attachments); i++ {
|
||||
|
|
@ -48,6 +59,27 @@ func (keyRing *KeyRing) DecryptMIMEMessage(
|
|||
|
||||
// ----- INTERNAL FUNCTIONS -----
|
||||
|
||||
func prioritizeSignatureErrors(signatureErrs ...*SignatureVerificationError) (maxError int) {
|
||||
// select error with the highest value, if any
|
||||
// FAILED > NO VERIFIER > NOT SIGNED > SIGNATURE OK
|
||||
maxError = constants.SIGNATURE_OK
|
||||
for _, err := range signatureErrs {
|
||||
if err.Status > maxError {
|
||||
maxError = err.Status
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func separateSigError(err error) (*SignatureVerificationError, error) {
|
||||
sigErr := &SignatureVerificationError{}
|
||||
isSigError := errors.As(err, sigErr)
|
||||
if isSigError {
|
||||
return sigErr, nil
|
||||
}
|
||||
return nil, err
|
||||
}
|
||||
|
||||
func parseMIME(
|
||||
mimeBody string, verifierKey *KeyRing,
|
||||
) (*gomime.BodyCollector, []string, []string, error) {
|
||||
|
|
@ -68,12 +100,12 @@ func parseMIME(
|
|||
attachmentsCollector := gomime.NewAttachmentsCollector(bodyCollector)
|
||||
mimeVisitor := gomime.NewMimeVisitor(attachmentsCollector)
|
||||
|
||||
var pgpKering openpgp.KeyRing
|
||||
var verifierEntities openpgp.KeyRing
|
||||
if verifierKey != nil {
|
||||
pgpKering = verifierKey.entities
|
||||
verifierEntities = verifierKey.entities
|
||||
}
|
||||
|
||||
signatureCollector := newSignatureCollector(mimeVisitor, pgpKering, config)
|
||||
signatureCollector := newSignatureCollector(mimeVisitor, verifierEntities, config)
|
||||
|
||||
err = gomime.VisitAll(bytes.NewReader(mmBodyData), h, signatureCollector)
|
||||
if err == nil && verifierKey != nil {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue