2018-09-02 15:02:26 +02:00
|
|
|
package pmcrypto
|
|
|
|
|
|
|
|
|
|
import (
|
2018-09-05 14:56:06 +02:00
|
|
|
"proton/pmmime"
|
2018-09-02 15:02:26 +02:00
|
|
|
"net/mail"
|
|
|
|
|
"strings"
|
2018-09-05 14:56:06 +02:00
|
|
|
"golang.org/x/crypto/openpgp/packet"
|
2018-09-02 15:02:26 +02:00
|
|
|
"net/textproto"
|
|
|
|
|
"io/ioutil"
|
|
|
|
|
"bytes"
|
2018-09-04 23:40:35 +02:00
|
|
|
"golang.org/x/crypto/openpgp"
|
2018-09-02 15:02:26 +02:00
|
|
|
)
|
|
|
|
|
|
2018-09-04 20:27:29 +02:00
|
|
|
// ======================== Attachments Collector ==============
|
|
|
|
|
// Collect contents of all attachment parts and return
|
|
|
|
|
// them as a string
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2018-09-04 23:40:35 +02:00
|
|
|
|
2018-09-05 14:56:06 +02:00
|
|
|
func (o OpenPGP) parseMIME(mimeBody string, verifierKey []byte) (*pmmime.BodyCollector, int, []string, []string, error) {
|
|
|
|
|
privKey := bytes.NewReader(verifierKey)
|
|
|
|
|
privKeyEntries, err := openpgp.ReadKeyRing(privKey)
|
2018-09-02 15:02:26 +02:00
|
|
|
|
|
|
|
|
mm, err := mail.ReadMessage(strings.NewReader(mimeBody))
|
|
|
|
|
if err != nil {
|
2018-09-05 14:56:06 +02:00
|
|
|
return nil, 0, nil, nil, err
|
2018-09-02 15:02:26 +02:00
|
|
|
}
|
2018-09-05 14:56:06 +02:00
|
|
|
config := &packet.Config{DefaultCipher: packet.CipherAES256, Time: o.getTimeGenerator()}
|
2018-09-02 15:02:26 +02:00
|
|
|
|
|
|
|
|
h := textproto.MIMEHeader(mm.Header)
|
|
|
|
|
mmBodyData, err := ioutil.ReadAll(mm.Body)
|
|
|
|
|
|
2018-09-04 20:27:29 +02:00
|
|
|
printAccepter := pmmime.NewMIMEPrinter()
|
|
|
|
|
bodyCollector := pmmime.NewBodyCollector(printAccepter)
|
|
|
|
|
attachmentsCollector := pmmime.NewAttachmentsCollector(bodyCollector)
|
|
|
|
|
mimeVisitor := pmmime.NewMimeVisitor(attachmentsCollector)
|
2018-09-05 14:56:06 +02:00
|
|
|
signatureCollector := NewSignatureCollector(mimeVisitor, privKeyEntries, config)
|
2018-09-04 20:27:29 +02:00
|
|
|
err = pmmime.VisitAll(bytes.NewReader(mmBodyData), h, signatureCollector)
|
2018-09-02 15:02:26 +02:00
|
|
|
|
2018-09-05 14:56:06 +02:00
|
|
|
verified := signatureCollector.verified
|
|
|
|
|
body := bodyCollector
|
|
|
|
|
atts := attachmentsCollector.GetAttachments()
|
|
|
|
|
attHeaders := attachmentsCollector.GetAttHeaders()
|
2018-09-04 23:40:35 +02:00
|
|
|
|
2018-09-05 14:56:06 +02:00
|
|
|
return body, verified, atts, attHeaders, nil
|
2018-09-04 23:40:35 +02:00
|
|
|
}
|
|
|
|
|
|
2018-09-02 15:02:26 +02:00
|
|
|
// define call back interface
|
|
|
|
|
type MIMECallbacks interface {
|
|
|
|
|
onBody(body string, mimetype string)
|
|
|
|
|
onAttachment(headers string, data []byte)
|
|
|
|
|
// Encrypted headers can be an attachment and thus be placed at the end of the mime structure
|
|
|
|
|
onEncryptedHeaders(headers string)
|
2018-09-05 14:56:06 +02:00
|
|
|
onVerified(verified int)
|
|
|
|
|
onError(err error)
|
2018-09-04 23:40:35 +02:00
|
|
|
}
|
2018-09-02 15:02:26 +02:00
|
|
|
|
2018-09-05 14:56:06 +02:00
|
|
|
func (o *OpenPGP) decryptMIMEMessage(encryptedText string, verifierKey []byte, privateKeys []byte,
|
|
|
|
|
passphrase string, callbacks MIMECallbacks, verifyTime int64) {
|
|
|
|
|
decsignverify, err := o.decryptMessageVerifyAllBin(encryptedText, verifierKey, privateKeys, passphrase, verifyTime)
|
|
|
|
|
if err != nil {
|
|
|
|
|
callbacks.onError(err)
|
|
|
|
|
return
|
2018-09-02 15:02:26 +02:00
|
|
|
}
|
|
|
|
|
|
2018-09-05 14:56:06 +02:00
|
|
|
body, verified, attachments, attachmentHeaders, err := o.parseMIME(decsignverify.Plaintext, verifierKey)
|
|
|
|
|
if err != nil {
|
|
|
|
|
callbacks.onError(err)
|
|
|
|
|
return
|
2018-09-04 20:27:29 +02:00
|
|
|
}
|
2018-09-02 15:02:26 +02:00
|
|
|
bodyContent, bodyMimeType := body.GetBody()
|
|
|
|
|
callbacks.onBody(bodyContent, bodyMimeType)
|
|
|
|
|
for i := 0; i < len(attachments); i++ {
|
|
|
|
|
callbacks.onAttachment(attachmentHeaders[i], []byte(attachments[i]))
|
|
|
|
|
}
|
|
|
|
|
callbacks.onEncryptedHeaders("")
|
2018-09-05 14:56:06 +02:00
|
|
|
if decsignverify.Verify == notSigned {
|
|
|
|
|
callbacks.onVerified(verified)
|
|
|
|
|
} else {
|
|
|
|
|
callbacks.onVerified(decsignverify.Verify)
|
|
|
|
|
}
|
|
|
|
|
}
|