2018-09-11 11:09:28 +02:00
|
|
|
package crypto
|
2018-09-02 15:02:26 +02:00
|
|
|
|
|
|
|
|
import (
|
|
|
|
|
"bytes"
|
2018-09-20 15:20:45 +02:00
|
|
|
"io/ioutil"
|
|
|
|
|
"net/mail"
|
|
|
|
|
"net/textproto"
|
|
|
|
|
"strings"
|
2019-03-07 17:39:34 +01:00
|
|
|
|
2020-12-08 18:34:39 +01:00
|
|
|
"github.com/ProtonMail/go-crypto/openpgp"
|
|
|
|
|
"github.com/ProtonMail/go-crypto/openpgp/packet"
|
2019-05-15 13:40:19 +02:00
|
|
|
gomime "github.com/ProtonMail/go-mime"
|
2020-10-29 12:42:32 +01:00
|
|
|
"github.com/pkg/errors"
|
2018-09-02 15:02:26 +02:00
|
|
|
)
|
|
|
|
|
|
2019-06-03 17:00:01 +02:00
|
|
|
// MIMECallbacks defines callback methods to process a MIME message.
|
|
|
|
|
type MIMECallbacks interface {
|
|
|
|
|
OnBody(body string, mimetype string)
|
|
|
|
|
OnAttachment(headers string, data []byte)
|
|
|
|
|
// Encrypted headers can be in an attachment and thus be placed at the end of the mime structure.
|
|
|
|
|
OnEncryptedHeaders(headers string)
|
|
|
|
|
OnVerified(verified int)
|
|
|
|
|
OnError(err error)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// DecryptMIMEMessage decrypts a MIME message.
|
|
|
|
|
func (keyRing *KeyRing) DecryptMIMEMessage(
|
|
|
|
|
message *PGPMessage, verifyKey *KeyRing, callbacks MIMECallbacks, verifyTime int64,
|
|
|
|
|
) {
|
2019-07-02 07:36:02 -07:00
|
|
|
decryptedMessage, err := keyRing.Decrypt(message, verifyKey, verifyTime)
|
2019-06-03 17:00:01 +02:00
|
|
|
if err != nil {
|
|
|
|
|
callbacks.OnError(err)
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
|
2020-10-12 21:24:33 +02:00
|
|
|
body, attachments, attachmentHeaders, err := parseMIME(string(decryptedMessage.GetBinary()), verifyKey)
|
2019-06-03 17:00:01 +02:00
|
|
|
if err != nil {
|
|
|
|
|
callbacks.OnError(err)
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
bodyContent, bodyMimeType := body.GetBody()
|
|
|
|
|
callbacks.OnBody(bodyContent, bodyMimeType)
|
|
|
|
|
for i := 0; i < len(attachments); i++ {
|
|
|
|
|
callbacks.OnAttachment(attachmentHeaders[i], []byte(attachments[i]))
|
|
|
|
|
}
|
|
|
|
|
callbacks.OnEncryptedHeaders("")
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// ----- INTERNAL FUNCTIONS -----
|
|
|
|
|
|
2019-10-22 18:44:45 +02:00
|
|
|
func parseMIME(
|
2019-05-14 14:42:38 +00:00
|
|
|
mimeBody string, verifierKey *KeyRing,
|
2019-07-02 07:36:02 -07:00
|
|
|
) (*gomime.BodyCollector, []string, []string, error) {
|
2018-09-02 15:02:26 +02:00
|
|
|
mm, err := mail.ReadMessage(strings.NewReader(mimeBody))
|
|
|
|
|
if err != nil {
|
2020-10-29 12:42:32 +01:00
|
|
|
return nil, nil, nil, errors.Wrap(err, "gopenpgp: error in reading message")
|
2018-09-02 15:02:26 +02:00
|
|
|
}
|
2019-10-22 18:44:45 +02:00
|
|
|
config := &packet.Config{DefaultCipher: packet.CipherAES256, Time: getTimeGenerator()}
|
2018-09-02 15:02:26 +02:00
|
|
|
|
|
|
|
|
h := textproto.MIMEHeader(mm.Header)
|
|
|
|
|
mmBodyData, err := ioutil.ReadAll(mm.Body)
|
2019-05-14 14:42:38 +00:00
|
|
|
if err != nil {
|
2020-10-29 12:42:32 +01:00
|
|
|
return nil, nil, nil, errors.Wrap(err, "gopenpgp: error in reading message body data")
|
2019-05-14 14:42:38 +00:00
|
|
|
}
|
2018-09-02 15:02:26 +02:00
|
|
|
|
2019-05-15 13:40:19 +02:00
|
|
|
printAccepter := gomime.NewMIMEPrinter()
|
|
|
|
|
bodyCollector := gomime.NewBodyCollector(printAccepter)
|
|
|
|
|
attachmentsCollector := gomime.NewAttachmentsCollector(bodyCollector)
|
|
|
|
|
mimeVisitor := gomime.NewMimeVisitor(attachmentsCollector)
|
2018-09-20 15:20:45 +02:00
|
|
|
|
2019-03-07 17:39:34 +01:00
|
|
|
var pgpKering openpgp.KeyRing
|
|
|
|
|
if verifierKey != nil {
|
|
|
|
|
pgpKering = verifierKey.entities
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
signatureCollector := newSignatureCollector(mimeVisitor, pgpKering, config)
|
|
|
|
|
|
2019-05-15 13:40:19 +02:00
|
|
|
err = gomime.VisitAll(bytes.NewReader(mmBodyData), h, signatureCollector)
|
2019-07-02 07:36:02 -07:00
|
|
|
if err == nil && verifierKey != nil {
|
2019-12-27 19:35:43 +01:00
|
|
|
err = signatureCollector.verified
|
2019-07-02 07:36:02 -07:00
|
|
|
}
|
2018-09-02 15:02:26 +02:00
|
|
|
|
2019-07-02 07:36:02 -07:00
|
|
|
return bodyCollector,
|
|
|
|
|
attachmentsCollector.GetAttachments(),
|
|
|
|
|
attachmentsCollector.GetAttHeaders(),
|
|
|
|
|
err
|
2018-09-04 23:40:35 +02:00
|
|
|
}
|