mirror of
https://github.com/wneessen/go-mail.git
synced 2024-12-22 18:50:37 +01:00
feat: s/mime singing supports quoted printable encoding, also added tests
This commit is contained in:
parent
cc4c5bfd04
commit
faffc025cb
3 changed files with 131 additions and 13 deletions
7
msg.go
7
msg.go
|
@ -2184,8 +2184,11 @@ func (m *Msg) signMessage(msg *Msg) (*Msg, error) {
|
|||
|
||||
// createSignaturePart creates an additional part that be used for storing the S/MIME signature of the given body
|
||||
func (m *Msg) createSignaturePart(encoding Encoding, contentType ContentType, charSet Charset, body []byte) (*Part, error) {
|
||||
message := m.sMime.prepareMessage(encoding, contentType, charSet, body)
|
||||
signedMessage, err := m.sMime.signMessage(message)
|
||||
message, err := m.sMime.prepareMessage(encoding, contentType, charSet, body)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
signedMessage, err := m.sMime.signMessage(*message)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
|
29
smime.go
29
smime.go
|
@ -13,6 +13,7 @@ import (
|
|||
"encoding/pem"
|
||||
"errors"
|
||||
"fmt"
|
||||
"mime/quotedprintable"
|
||||
"strings"
|
||||
)
|
||||
|
||||
|
@ -119,8 +120,32 @@ func (sm *SMime) signMessage(message string) (*string, error) {
|
|||
}
|
||||
|
||||
// createMessage prepares the message that will be used for the sign method later
|
||||
func (sm *SMime) prepareMessage(encoding Encoding, contentType ContentType, charset Charset, body []byte) string {
|
||||
return fmt.Sprintf("Content-Transfer-Encoding: %v\r\nContent-Type: %v; charset=%v\r\n\r\n%v", encoding, contentType, charset, string(body))
|
||||
func (sm *SMime) prepareMessage(encoding Encoding, contentType ContentType, charset Charset, body []byte) (*string, error) {
|
||||
encodedMessage, err := sm.encodeMessage(encoding, string(body))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
preparedMessage := fmt.Sprintf("Content-Transfer-Encoding: %v\r\nContent-Type: %v; charset=%v\r\n\r\n%v", encoding, contentType, charset, *encodedMessage)
|
||||
return &preparedMessage, nil
|
||||
}
|
||||
|
||||
// encodeMessage encodes the message with the given encoding
|
||||
func (sm *SMime) encodeMessage(encoding Encoding, message string) (*string, error) {
|
||||
if encoding != EncodingQP {
|
||||
return &message, nil
|
||||
}
|
||||
|
||||
buffer := bytes.Buffer{}
|
||||
writer := quotedprintable.NewWriter(&buffer)
|
||||
if _, err := writer.Write([]byte(message)); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if err := writer.Close(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
encodedMessage := buffer.String()
|
||||
|
||||
return &encodedMessage, nil
|
||||
}
|
||||
|
||||
// encodeToPEM uses the method pem.Encode from the standard library but cuts the typical PEM preamble
|
||||
|
|
108
smime_test.go
108
smime_test.go
|
@ -121,19 +121,109 @@ func TestPrepareMessage(t *testing.T) {
|
|||
contentType := TypeTextPlain
|
||||
charset := CharsetUTF8
|
||||
body := []byte("This is the body!")
|
||||
result := sMime.prepareMessage(encoding, contentType, charset, body)
|
||||
result, err := sMime.prepareMessage(encoding, contentType, charset, body)
|
||||
if err != nil {
|
||||
t.Errorf("Error preparing message: %s", err)
|
||||
}
|
||||
|
||||
if !strings.Contains(result, encoding.String()) {
|
||||
t.Errorf("createMessage() did not return the correct encoding")
|
||||
if !strings.Contains(*result, encoding.String()) {
|
||||
t.Errorf("prepareMessage() did not return the correct encoding")
|
||||
}
|
||||
if !strings.Contains(result, contentType.String()) {
|
||||
t.Errorf("createMessage() did not return the correct contentType")
|
||||
if !strings.Contains(*result, contentType.String()) {
|
||||
t.Errorf("prepareMessage() did not return the correct contentType")
|
||||
}
|
||||
if !strings.Contains(result, string(body)) {
|
||||
t.Errorf("createMessage() did not return the correct body")
|
||||
if !strings.Contains(*result, string(body)) {
|
||||
t.Errorf("prepareMessage() did not return the correct body")
|
||||
}
|
||||
if result != fmt.Sprintf("Content-Transfer-Encoding: %s\r\nContent-Type: %s; charset=%s\r\n\r\n%s", encoding, contentType, charset, string(body)) {
|
||||
t.Errorf("createMessage() did not sucessfully create the message")
|
||||
if *result != fmt.Sprintf("Content-Transfer-Encoding: %s\r\nContent-Type: %s; charset=%s\r\n\r\n%s", encoding, contentType, charset, string(body)) {
|
||||
t.Errorf("prepareMessage() did not sucessfully create the message")
|
||||
}
|
||||
}
|
||||
|
||||
// TestPrepareMessage_QuotedPrintable tests the prepareMessage method with quoted printable encoding
|
||||
func TestPrepareMessage_QuotedPrintable(t *testing.T) {
|
||||
privateKey, certificate, intermediateCertificate, err := getDummyRSACryptoMaterial()
|
||||
if err != nil {
|
||||
t.Errorf("Error getting dummy crypto material: %s", err)
|
||||
}
|
||||
|
||||
sMime, err := newSMimeWithRSA(privateKey, certificate, intermediateCertificate)
|
||||
if err != nil {
|
||||
t.Errorf("Error creating new SMime from keyPair: %s", err)
|
||||
}
|
||||
|
||||
body := "This is the body with special chars like äöü ÄÖÜ ß!"
|
||||
quotedPrintableBody := "This is the body with special chars like =C3=A4=C3=B6=C3=BC =C3=84=C3=96=C3=\r\n=9C =C3=9F!"
|
||||
encoding := EncodingQP
|
||||
contentType := TypeTextPlain
|
||||
charset := CharsetUTF8
|
||||
result, err := sMime.prepareMessage(encoding, contentType, charset, []byte(body))
|
||||
if err != nil {
|
||||
t.Errorf("Error preparing message: %s", err)
|
||||
}
|
||||
|
||||
if !strings.Contains(*result, encoding.String()) {
|
||||
t.Errorf("prepareMessage() did not return the correct encoding")
|
||||
}
|
||||
if !strings.Contains(*result, contentType.String()) {
|
||||
t.Errorf("prepareMessage() did not return the correct contentType")
|
||||
}
|
||||
if !strings.Contains(*result, quotedPrintableBody) {
|
||||
t.Errorf("prepareMessage() did not return the correct body")
|
||||
}
|
||||
if *result != fmt.Sprintf("Content-Transfer-Encoding: %s\r\nContent-Type: %s; charset=%s\r\n\r\n%s", encoding, contentType, charset, quotedPrintableBody) {
|
||||
t.Errorf("prepareMessage() did not sucessfully create the message")
|
||||
}
|
||||
}
|
||||
|
||||
// TestEncodeMessage tests the TestEncodeMessage method without any encoding
|
||||
func TestEncodeMessage(t *testing.T) {
|
||||
body := "This is the body with special chars like äöü ÄÖÜ ß!"
|
||||
encoding := EncodingUSASCII
|
||||
|
||||
privateKey, certificate, intermediateCertificate, err := getDummyRSACryptoMaterial()
|
||||
if err != nil {
|
||||
t.Errorf("Error getting dummy crypto material: %s", err)
|
||||
}
|
||||
|
||||
sMime, err := newSMimeWithRSA(privateKey, certificate, intermediateCertificate)
|
||||
if err != nil {
|
||||
t.Errorf("Error creating new SMime from keyPair: %s", err)
|
||||
}
|
||||
|
||||
result, err := sMime.encodeMessage(encoding, body)
|
||||
if err != nil {
|
||||
t.Errorf("Error preparing message: %s", err)
|
||||
}
|
||||
|
||||
if *result != body {
|
||||
t.Errorf("encodeMessage() did not return the correct encoded message: %s", *result)
|
||||
}
|
||||
}
|
||||
|
||||
// TestEncodeMessage_QuotedPrintable tests the TestEncodeMessage method with quoted printable body
|
||||
func TestEncodeMessage_QuotedPrintable(t *testing.T) {
|
||||
body := "This is the body with special chars like äöü ÄÖÜ ß!"
|
||||
quotedPrintableBody := "This is the body with special chars like =C3=A4=C3=B6=C3=BC =C3=84=C3=96=C3=\r\n=9C =C3=9F!"
|
||||
encoding := EncodingQP
|
||||
|
||||
privateKey, certificate, intermediateCertificate, err := getDummyRSACryptoMaterial()
|
||||
if err != nil {
|
||||
t.Errorf("Error getting dummy crypto material: %s", err)
|
||||
}
|
||||
|
||||
sMime, err := newSMimeWithRSA(privateKey, certificate, intermediateCertificate)
|
||||
if err != nil {
|
||||
t.Errorf("Error creating new SMime from keyPair: %s", err)
|
||||
}
|
||||
|
||||
result, err := sMime.encodeMessage(encoding, body)
|
||||
if err != nil {
|
||||
t.Errorf("Error preparing message: %s", err)
|
||||
}
|
||||
|
||||
if *result != quotedPrintableBody {
|
||||
t.Errorf("encodeMessage() did not return the correct encoded message: %s", *result)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue