Don't trim trailing spaces from non-clearsigned text messages

This commit is contained in:
Daniel Huigens 2022-11-16 14:41:38 +01:00
parent 9b9463553c
commit b189309152
5 changed files with 12 additions and 7 deletions

View file

@ -92,7 +92,7 @@ func NewPlainMessageFromFile(data []byte, filename string, time uint32) *PlainMe
// This allows seamless conversion to clear text signed messages (see RFC 4880 5.2.1 and 7.1). // This allows seamless conversion to clear text signed messages (see RFC 4880 5.2.1 and 7.1).
func NewPlainMessageFromString(text string) *PlainMessage { func NewPlainMessageFromString(text string) *PlainMessage {
return &PlainMessage{ return &PlainMessage{
Data: []byte(internal.CanonicalizeAndTrim(text)), Data: []byte(internal.Canonicalize(text)),
TextType: true, TextType: true,
Filename: "", Filename: "",
Time: uint32(GetUnixTime()), Time: uint32(GetUnixTime()),

View file

@ -99,7 +99,7 @@ func (sc *SignatureCollector) Accept(
} }
sc.signature = string(buffer) sc.signature = string(buffer)
str, _ := ioutil.ReadAll(rawBody) str, _ := ioutil.ReadAll(rawBody)
canonicalizedBody := internal.CanonicalizeAndTrim(string(str)) canonicalizedBody := internal.Canonicalize(internal.TrimEachLine(string(str)))
rawBody = bytes.NewReader([]byte(canonicalizedBody)) rawBody = bytes.NewReader([]byte(canonicalizedBody))
if sc.keyring != nil { if sc.keyring != nil {
_, err = openpgp.CheckArmoredDetachedSignature(sc.keyring, rawBody, bytes.NewReader(buffer), sc.config) _, err = openpgp.CheckArmoredDetachedSignature(sc.keyring, rawBody, bytes.NewReader(buffer), sc.config)

View file

@ -2,6 +2,7 @@ package helper
import ( import (
"github.com/ProtonMail/gopenpgp/v2/crypto" "github.com/ProtonMail/gopenpgp/v2/crypto"
"github.com/ProtonMail/gopenpgp/v2/internal"
"github.com/pkg/errors" "github.com/pkg/errors"
) )
@ -48,7 +49,7 @@ func VerifyCleartextMessageArmored(publicKey, armored string, verifyTime int64)
// SignCleartextMessage signs text given a private keyring, canonicalizes and // SignCleartextMessage signs text given a private keyring, canonicalizes and
// trims the newlines, and returns the PGP-compliant special armoring. // trims the newlines, and returns the PGP-compliant special armoring.
func SignCleartextMessage(keyRing *crypto.KeyRing, text string) (string, error) { func SignCleartextMessage(keyRing *crypto.KeyRing, text string) (string, error) {
message := crypto.NewPlainMessageFromString(text) message := crypto.NewPlainMessageFromString(internal.TrimEachLine(text))
signature, err := keyRing.SignDetached(message) signature, err := keyRing.SignDetached(message)
if err != nil { if err != nil {
@ -67,7 +68,7 @@ func VerifyCleartextMessage(keyRing *crypto.KeyRing, armored string, verifyTime
return "", errors.Wrap(err, "gopengpp: unable to unarmor cleartext message") return "", errors.Wrap(err, "gopengpp: unable to unarmor cleartext message")
} }
message := crypto.NewPlainMessageFromString(clearTextMessage.GetString()) message := crypto.NewPlainMessageFromString(internal.TrimEachLine(clearTextMessage.GetString()))
signature := crypto.NewPGPSignature(clearTextMessage.GetBinarySignature()) signature := crypto.NewPGPSignature(clearTextMessage.GetBinarySignature())
err = keyRing.VerifyDetached(message, signature, verifyTime) err = keyRing.VerifyDetached(message, signature, verifyTime)
if err != nil { if err != nil {

View file

@ -45,5 +45,5 @@ func TestSignClearText(t *testing.T) {
if err != nil { if err != nil {
t.Fatal("Cannot parse message:", err) t.Fatal("Cannot parse message:", err)
} }
assert.Exactly(t, internal.CanonicalizeAndTrim(inputPlainText), string(clearTextMessage.GetBinary())) assert.Exactly(t, internal.Canonicalize(internal.TrimEachLine(inputPlainText)), string(clearTextMessage.GetBinary()))
} }

View file

@ -7,14 +7,18 @@ import (
"github.com/ProtonMail/gopenpgp/v2/constants" "github.com/ProtonMail/gopenpgp/v2/constants"
) )
func CanonicalizeAndTrim(text string) string { func Canonicalize(text string) string {
return strings.ReplaceAll(strings.ReplaceAll(text, "\r\n", "\n"), "\n", "\r\n")
}
func TrimEachLine(text string) string {
lines := strings.Split(text, "\n") lines := strings.Split(text, "\n")
for i := range lines { for i := range lines {
lines[i] = strings.TrimRight(lines[i], " \t\r") lines[i] = strings.TrimRight(lines[i], " \t\r")
} }
return strings.Join(lines, "\r\n") return strings.Join(lines, "\n")
} }
// CreationTimeOffset stores the amount of seconds that a signature may be // CreationTimeOffset stores the amount of seconds that a signature may be