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:
marin thiercelin 2021-12-15 11:01:04 +01:00
parent b97b3d886b
commit e2f03af655
No known key found for this signature in database
GPG key ID: 117C025B1F21B2C6
17 changed files with 749 additions and 8 deletions

View file

@ -10,6 +10,7 @@ import (
"github.com/ProtonMail/go-crypto/openpgp" "github.com/ProtonMail/go-crypto/openpgp"
"github.com/ProtonMail/go-crypto/openpgp/packet" "github.com/ProtonMail/go-crypto/openpgp/packet"
gomime "github.com/ProtonMail/go-mime" gomime "github.com/ProtonMail/go-mime"
"github.com/ProtonMail/gopenpgp/v2/constants"
"github.com/pkg/errors" "github.com/pkg/errors"
) )
@ -28,16 +29,26 @@ func (keyRing *KeyRing) DecryptMIMEMessage(
message *PGPMessage, verifyKey *KeyRing, callbacks MIMECallbacks, verifyTime int64, message *PGPMessage, verifyKey *KeyRing, callbacks MIMECallbacks, verifyTime int64,
) { ) {
decryptedMessage, err := keyRing.Decrypt(message, verifyKey, verifyTime) decryptedMessage, err := keyRing.Decrypt(message, verifyKey, verifyTime)
embeddedSigError, err := separateSigError(err)
if err != nil { if err != nil {
callbacks.OnError(err) callbacks.OnError(err)
return return
} }
body, attachments, attachmentHeaders, err := parseMIME(string(decryptedMessage.GetBinary()), verifyKey) body, attachments, attachmentHeaders, err := parseMIME(string(decryptedMessage.GetBinary()), verifyKey)
mimeSigError, err := separateSigError(err)
if err != nil { if err != nil {
callbacks.OnError(err) callbacks.OnError(err)
return 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() bodyContent, bodyMimeType := body.GetBody()
callbacks.OnBody(bodyContent, bodyMimeType) callbacks.OnBody(bodyContent, bodyMimeType)
for i := 0; i < len(attachments); i++ { for i := 0; i < len(attachments); i++ {
@ -48,6 +59,27 @@ func (keyRing *KeyRing) DecryptMIMEMessage(
// ----- INTERNAL FUNCTIONS ----- // ----- 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( func parseMIME(
mimeBody string, verifierKey *KeyRing, mimeBody string, verifierKey *KeyRing,
) (*gomime.BodyCollector, []string, []string, error) { ) (*gomime.BodyCollector, []string, []string, error) {
@ -68,12 +100,12 @@ func parseMIME(
attachmentsCollector := gomime.NewAttachmentsCollector(bodyCollector) attachmentsCollector := gomime.NewAttachmentsCollector(bodyCollector)
mimeVisitor := gomime.NewMimeVisitor(attachmentsCollector) mimeVisitor := gomime.NewMimeVisitor(attachmentsCollector)
var pgpKering openpgp.KeyRing var verifierEntities openpgp.KeyRing
if verifierKey != nil { 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) err = gomime.VisitAll(bytes.NewReader(mmBodyData), h, signatureCollector)
if err == nil && verifierKey != nil { if err == nil && verifierKey != nil {

View file

@ -1,6 +1,9 @@
package crypto package crypto
import ( import (
"errors"
"io/ioutil"
"path/filepath"
"testing" "testing"
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
@ -79,3 +82,261 @@ func TestParse(t *testing.T) {
assert.Exactly(t, readTestFile("mime_decodedBodyHeaders", false), body.GetHeaders()) assert.Exactly(t, readTestFile("mime_decodedBodyHeaders", false), body.GetHeaders())
assert.Exactly(t, 2, len(atts)) assert.Exactly(t, 2, len(atts))
} }
type testMIMECallbacks struct {
onBody []struct{ body, mimetype string }
onAttachment []struct {
headers string
data []byte
}
onEncryptedHeaders []string
onVerified []int
onError []error
}
func (tc *testMIMECallbacks) OnBody(body string, mimetype string) {
tc.onBody = append(tc.onBody, struct {
body string
mimetype string
}{body, mimetype})
}
func (tc *testMIMECallbacks) OnAttachment(headers string, data []byte) {
tc.onAttachment = append(tc.onAttachment, struct {
headers string
data []byte
}{headers, data})
}
func (tc *testMIMECallbacks) OnEncryptedHeaders(headers string) {
tc.onEncryptedHeaders = append(tc.onEncryptedHeaders, headers)
}
func (tc *testMIMECallbacks) OnVerified(status int) {
tc.onVerified = append(tc.onVerified, status)
}
func (tc *testMIMECallbacks) OnError(err error) {
tc.onError = append(tc.onError, err)
}
func loadPrivateKeyRing(file string, passphrase string) (*KeyRing, error) {
armored, err := ioutil.ReadFile(filepath.Clean(file))
if err != nil {
return nil, err
}
key, err := NewKeyFromArmored(string(armored))
if err != nil {
return nil, err
}
unlockedKey, err := key.Unlock([]byte(passphrase))
if err != nil {
return nil, err
}
keyRing, err := NewKeyRing(unlockedKey)
if err != nil {
return nil, err
}
return keyRing, nil
}
func loadPublicKeyRing(file string) (*KeyRing, error) {
armored, err := ioutil.ReadFile(filepath.Clean(file))
if err != nil {
return nil, err
}
key, err := NewKeyFromArmored(string(armored))
if err != nil {
return nil, err
}
if key.IsPrivate() {
publicKey, err := key.GetPublicKey()
if err != nil {
return nil, err
}
key, err = NewKey(publicKey)
if err != nil {
return nil, err
}
}
keyRing, err := NewKeyRing(key)
if err != nil {
return nil, err
}
return keyRing, nil
}
func loadMessage(file string) (*PGPMessage, error) {
armored, err := ioutil.ReadFile(filepath.Clean(file))
if err != nil {
return nil, err
}
message, err := NewPGPMessageFromArmored(string(armored))
if err != nil {
return nil, err
}
return message, nil
}
func runScenario(t *testing.T, messageFile string) *testMIMECallbacks {
decryptionKeyRing, err := loadPrivateKeyRing("testdata/mime/decryption-key.asc", "test_passphrase")
if err != nil {
t.Errorf("Failed to load decryption key %v", err)
}
verificationKeyRing, err := loadPublicKeyRing("testdata/mime/verification-key.asc")
if err != nil {
t.Errorf("Failed to load verification key %v", err)
}
message, err := loadMessage(messageFile)
if err != nil {
t.Errorf("Failed to load message %v", err)
}
callbacks := &testMIMECallbacks{}
decryptionKeyRing.DecryptMIMEMessage(message, verificationKeyRing, callbacks, 0)
return callbacks
}
func compareStatus(expected []int, actual []int, t *testing.T) {
if len(actual) != len(expected) {
t.Errorf("Expected %v, got %v", expected, actual)
} else {
for i, actualStatus := range actual {
if actualStatus != expected[i] {
t.Errorf("Expected status %v, got %v", expected[i], actualStatus)
}
}
}
}
func TestMessageVerificationOkOk(t *testing.T) {
callbackResults := runScenario(t, "testdata/mime/scenario_00.asc")
if len(callbackResults.onError) != 0 {
for _, err := range callbackResults.onError {
t.Errorf("Expected no errors got %v", err)
}
}
expectedStatus := []int{0}
compareStatus(expectedStatus, callbackResults.onVerified, t)
}
func TestMessageVerificationOkNotSigned(t *testing.T) {
callbackResults := runScenario(t, "testdata/mime/scenario_01.asc")
if len(callbackResults.onError) != 0 {
for _, err := range callbackResults.onError {
t.Errorf("Expected no errors got %v", err)
}
}
expectedStatus := []int{0}
compareStatus(expectedStatus, callbackResults.onVerified, t)
}
func TestMessageVerificationOkNoVerifier(t *testing.T) {
callbackResults := runScenario(t, "testdata/mime/scenario_02.asc")
if len(callbackResults.onError) != 0 {
for _, err := range callbackResults.onError {
t.Errorf("Expected no errors got %v", err)
}
}
expectedStatus := []int{0}
compareStatus(expectedStatus, callbackResults.onVerified, t)
}
func TestMessageVerificationOkFailed(t *testing.T) {
callbackResults := runScenario(t, "testdata/mime/scenario_03.asc")
if len(callbackResults.onError) != 0 {
for _, err := range callbackResults.onError {
t.Errorf("Expected no errors got %v", err)
}
}
expectedStatus := []int{0}
compareStatus(expectedStatus, callbackResults.onVerified, t)
}
func TestMessageVerificationNotSignedOk(t *testing.T) {
callbackResults := runScenario(t, "testdata/mime/scenario_10.asc")
if len(callbackResults.onError) != 0 {
for _, err := range callbackResults.onError {
t.Errorf("Expected no errors got %v", err)
}
}
expectedStatus := []int{0}
compareStatus(expectedStatus, callbackResults.onVerified, t)
}
func checkIsSigErr(t *testing.T, err error) int {
sigErr := &SignatureVerificationError{}
if errors.As(err, &sigErr) {
return sigErr.Status
}
t.Errorf("Expected a signature verification error, got %v", err)
return -1
}
func compareErrors(expected []SignatureVerificationError, actual []error, t *testing.T) {
if len(actual) != len(expected) {
t.Errorf("Expected %v, got %v", expected, actual)
} else {
for i, err := range actual {
actualStatus := checkIsSigErr(t, err)
if actualStatus != expected[i].Status {
t.Errorf("Expected sig error with status %v, got %v", expected[i].Status, actualStatus)
}
}
}
}
func TestMessageVerificationNotSignedNotSigned(t *testing.T) {
callbackResults := runScenario(t, "testdata/mime/scenario_11.asc")
var expectedErrors = []SignatureVerificationError{newSignatureNotSigned(), newSignatureNotSigned()}
compareErrors(expectedErrors, callbackResults.onError, t)
expectedStatus := []int{1}
compareStatus(expectedStatus, callbackResults.onVerified, t)
}
func TestMessageVerificationNotSignedNoVerifier(t *testing.T) {
callbackResults := runScenario(t, "testdata/mime/scenario_12.asc")
var expectedErrors = []SignatureVerificationError{newSignatureNotSigned(), newSignatureNoVerifier()}
compareErrors(expectedErrors, callbackResults.onError, t)
expectedStatus := []int{2}
compareStatus(expectedStatus, callbackResults.onVerified, t)
}
func TestMessageVerificationNotSignedFailed(t *testing.T) {
callbackResults := runScenario(t, "testdata/mime/scenario_13.asc")
var expectedErrors = []SignatureVerificationError{newSignatureNotSigned(), newSignatureFailed()}
compareErrors(expectedErrors, callbackResults.onError, t)
expectedStatus := []int{3}
compareStatus(expectedStatus, callbackResults.onVerified, t)
}
func TestMessageVerificationNoVerifierOk(t *testing.T) {
callbackResults := runScenario(t, "testdata/mime/scenario_20.asc")
var expectedErrors = []SignatureVerificationError{}
compareErrors(expectedErrors, callbackResults.onError, t)
expectedStatus := []int{0}
compareStatus(expectedStatus, callbackResults.onVerified, t)
}
func TestMessageVerificationNoVerifierNotSigned(t *testing.T) {
callbackResults := runScenario(t, "testdata/mime/scenario_21.asc")
var expectedErrors = []SignatureVerificationError{newSignatureNoVerifier(), newSignatureNotSigned()}
compareErrors(expectedErrors, callbackResults.onError, t)
expectedStatus := []int{2}
compareStatus(expectedStatus, callbackResults.onVerified, t)
}
func TestMessageVerificationNoVerifierNoVerifier(t *testing.T) {
callbackResults := runScenario(t, "testdata/mime/scenario_22.asc")
var expectedErrors = []SignatureVerificationError{newSignatureNoVerifier(), newSignatureNoVerifier()}
compareErrors(expectedErrors, callbackResults.onError, t)
expectedStatus := []int{2}
compareStatus(expectedStatus, callbackResults.onVerified, t)
}
func TestMessageVerificationNoVerifierFailed(t *testing.T) {
callbackResults := runScenario(t, "testdata/mime/scenario_23.asc")
var expectedErrors = []SignatureVerificationError{newSignatureNoVerifier(), newSignatureFailed()}
compareErrors(expectedErrors, callbackResults.onError, t)
expectedStatus := []int{3}
compareStatus(expectedStatus, callbackResults.onVerified, t)
}

View file

@ -7,6 +7,8 @@ import (
"mime" "mime"
"net/textproto" "net/textproto"
pgpErrors "github.com/ProtonMail/go-crypto/openpgp/errors"
"github.com/ProtonMail/go-crypto/openpgp" "github.com/ProtonMail/go-crypto/openpgp"
"github.com/ProtonMail/go-crypto/openpgp/packet" "github.com/ProtonMail/go-crypto/openpgp/packet"
gomime "github.com/ProtonMail/go-mime" gomime "github.com/ProtonMail/go-mime"
@ -40,6 +42,7 @@ func (sc *SignatureCollector) Accept(
parentMediaType, params, _ := mime.ParseMediaType(header.Get("Content-Type")) parentMediaType, params, _ := mime.ParseMediaType(header.Get("Content-Type"))
if parentMediaType != "multipart/signed" { if parentMediaType != "multipart/signed" {
sc.verified = newSignatureNotSigned()
return sc.target.Accept(part, header, hasPlainSibling, isFirst, isLast) return sc.target.Accept(part, header, hasPlainSibling, isFirst, isLast)
} }
@ -97,12 +100,15 @@ func (sc *SignatureCollector) Accept(
str, _ := ioutil.ReadAll(rawBody) str, _ := ioutil.ReadAll(rawBody)
rawBody = bytes.NewReader(str) rawBody = bytes.NewReader(str)
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)
if err != nil { switch {
sc.verified = newSignatureFailed() case err == nil:
} else {
sc.verified = nil sc.verified = nil
case errors.Is(err, pgpErrors.ErrUnknownIssuer):
sc.verified = newSignatureNoVerifier()
default:
sc.verified = newSignatureFailed()
} }
} else { } else {
sc.verified = newSignatureNoVerifier() sc.verified = newSignatureNoVerifier()

19
crypto/testdata/mime/decryption-key.asc vendored Normal file
View file

@ -0,0 +1,19 @@
-----BEGIN PGP PRIVATE KEY BLOCK-----
Comment: https://gopenpgp.org
Version: GopenPGP 2.3.0
xYYEXNidoBYJKwYBBAHaRw8BAQdA+m7Tp1+dRVJZsRvttdFqmiZIII/4Uv8skGP1
1JGh0+3+CQMI0Pb7S9AsV35gyfdk4YKSemLhHXlRCdJd+8/xgdNriqnoDXlhz4Su
SAiG2ZLZ4jjUxqFJ210FkGtD/Sm7GfEmXAmr8fNUxy6+Zl8rqE6kiM0pdGVzdEBw
cm90b25tYWlsLmNvbSA8dGVzdEBwcm90b25tYWlsLmNvbT7CjAQTFggAPgUCXNid
oAmQEWMuVvE3zy0WoQR+XgWd8bEfbuz9DrMRYy5W8TfPLQIbAwIeAQIZAQMLCQcC
FQgDFgACAiIBAACcjgEA8MTkoIdbPqkMbpHtu6k69myfnXhEzuwvvTuCkojxjNUB
AJW+dX9U4l7nAalKlnpegWABqgEbIkltP4Z4rSq+CrwBx4sEXNidoBIKKwYBBAGX
VQEFAQEHQA9m0MrPcQAcTfsmg0nYMLrgokDcNkMFXn5VnVg/BP1UAwEKCf4JAwgA
BF/uTUFKSGA92pFmYVxejMSpfR9GwlebM4vJ0pTU5F0exvWdMwItAl4LqYTbzjXL
PlyIThiX7iMYLq5ks9KO290OV/jnv5GxviKH5qtAwngEGBYIACoFAlzYnaAJkBFj
LlbxN88tFqEEfl4FnfGxH27s/Q6zEWMuVvE3zy0CGwwAAHAgAQCZzruwu80he4fN
jizTO6iOIjaaTUPrDLBWhhJAlIT5zAEAm8Cs3Q4nViehE9PZTjZIyGd8rVppu0pR
whfuoQfLVQs=
=36V+
-----END PGP PRIVATE KEY BLOCK-----

39
crypto/testdata/mime/scenario_00.asc vendored Normal file
View file

@ -0,0 +1,39 @@
-----BEGIN PGP MESSAGE-----
Comment: https://gopenpgp.org
Version: GopenPGP 2.3.0
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
Sd2GXbfo3SFzL0cX
=WgDf
-----END PGP MESSAGE-----

23
crypto/testdata/mime/scenario_01.asc vendored Normal file
View file

@ -0,0 +1,23 @@
-----BEGIN PGP MESSAGE-----
Version: GopenPGP 2.3.0
Comment: https://gopenpgp.org
wV4DJ5XBV9zAEI0SAQdAZX1wJ562piYWaoZTb5faVaKchbb4yhyMc7ONPQJofgMw
p9oSNLM8OYK7SwmSbLL5zYO4FMhYPAVyY1ENYKYT6yiu2WOaWIAtLpqWkj/2d0tX
0ukB/U4jflL9Dn5i4ZVtiShsoEIpL0Q3zb5rPnqIRoaociOEDP/+g2BMv/sPk14x
+uyhM4fzNr1Sjbc39FppRv2ffkg4rc8s6mE7M51aiExfvhUddccSNPIUiSMAiz4q
4ICTONeV7iD/cXg0vp23AcVxhz4tpMyyEY/k1yykukGkwHA3IgozKwn6cypAq1pQ
H6hil/BPErQT/NcA1HNO9KJtKTeGsku2InCeuxP3LKPomf2lqR1FCRYfrC1Jh5mO
oPvOrtWVF4oJSaF6u/xMOiThkKRiVUbw4vI95VrvFep7rGAJIQHcvzwX4mDYI5rh
CsmpTSILtdbAs/DH5bI8bn+aO53GaCto9NDDRmVr7GqJ87kHSzW2Z9zQPlBTP3VR
pLWsLDqz9DTprGgfSB9TdwenxaezXbc5mky9TMRrTqIdUxCEvUjd9n1RKRrzn6bY
JLC4s/iNgXkopig21IQvD1FfBcnix3xtDAMT9pjDY6AYLgIhSOhJoH8+DX3qBPsF
lQVbRHe7ExRLCJon8RgXReSquG/vQDcWFX8/SJJEbqtAO8XSbdFB+3pAWoYH+B4d
eyn2jEHiwvlsbOpb2cDWFmcOZ3FiNMZiBvHXZQmIfUuWZOHBSEe31y6Di1w1E8Qh
rGO0vuMkRl0/F2o5HZOphN2NCnep4K3yUl8D0751NpMrlKLBLEmgqVMHcCryGxTt
HVpglwuzLNVQj5gQJKumMrh1evfaCJk9gYZoZ551opCFCNFRVg5/DbMCpMHb5REV
O/A9ktmhgMvTPl5VNewzpQpczLbZ39zi0NoPDPFgc3gbQ16Bg3UIgs2exNLqJwG/
Of2ClL8n6fwO45HGNawEaMBfKLdTw6MeUbGLyG3h3ScBVIlXNV1R02RHSf0dO1jM
wbJGhgI=
=ft2z
-----END PGP MESSAGE-----

39
crypto/testdata/mime/scenario_02.asc vendored Normal file
View file

@ -0,0 +1,39 @@
-----BEGIN PGP MESSAGE-----
Version: GopenPGP 2.3.0
Comment: https://gopenpgp.org
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
+A+xXjMvtFTCJAus
=rZK0
-----END PGP MESSAGE-----

39
crypto/testdata/mime/scenario_03.asc vendored Normal file
View file

@ -0,0 +1,39 @@
-----BEGIN PGP MESSAGE-----
Version: GopenPGP 2.3.0
Comment: https://gopenpgp.org
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
Az9cIPbJmjF4bXNd
=L6aD
-----END PGP MESSAGE-----

36
crypto/testdata/mime/scenario_10.asc vendored Normal file
View file

@ -0,0 +1,36 @@
-----BEGIN PGP MESSAGE-----
Version: GopenPGP 2.3.0
Comment: https://gopenpgp.org
wV4DJ5XBV9zAEI0SAQdApsGzHeemI2UUZfnNwTtko48R26DyUvEcmRhkY2PcVD4w
Np66YzGKs8cJVpZIvKDIK0xpAKzHLKKo08QcJ2ebAWwboFaXYPmENOxvvWVz8Eom
0uoB2+ncyfaqsVYKWd2MJvcYt5LuqF44HYMRsKGL13wTBg6gz2axY8ZWfs6DN89b
3BIGRf+sxFxWxjg32hbnK0PajYVkG6l+ky4akeIGk4VRzyKl2EFFkQZfsvZAuK2z
SycxrHg99ex/JKfWLJ3sBJJn4iYWaHa9N4opgfgu6DoS5voR6mv1UuXxNbZi8NSe
WfMb+XEiypAZCwdf/2NlMjrCCfOTik35tcGOippZiEiAivaPEYLBmXLLr/cQCEuk
RQBKmdn+/XitiJ3//CUE/4WtYGkLDjq7W1gsnzoT7P6+8DYl9XWqFJeBNWjjeoit
3TfVwM7B9DYwAV66oiPejoDrQLwE9yDo7aDxgfnk/v4CxaNPkthtVLFPat00BdQl
utHK0uWWqf+eaUbcQbsffuPebUuf+DvQ3/ynXOTdaTLeQQM9LR0XaoIOKQHu/Nr7
Fx0AH7p/Rgs+f1SYHK4nt6f/g7MJceicXw4oEl8pgV3WUKlFNygU/ju8D6b8VISK
/wuxvTtnMl0YKdwBW3qNUT/fI/FD3+MQ0OUu8mVkdU1DoT9MiNBq5xs6pLTh1an3
WE6abtlEqCZWUOxOzlKBwMTh1TXOtLzgOr/m4eBfM1Y7nfZy+Tc22EW2uZz3mKIE
O5xXoW5H/XtrD6co33IB3opcvGyu4UC47H4u04c7bdQY9olhAvx83T/q6JSOyYYY
T6rPrmaulxTr8GDjrGmGNRfhITHwCzj/DH05kNO06rnaSik5Xs+ei+bnEXM4EDrK
cd4uuUzyfNEWpL0zY+6pnZDOOW2d6u1I98gNORDEBzooprSbnUaI+J+2tH0RYglZ
TT/KBEsTZeHH0U5WBxan0txTe+vlYcxWD7jwzjWC3Wb2pKXJb+0vmcP4JpRWSi9G
BWo61UjL8aB2SQ0OIYXR7MX2gOaRYkoh1UhgqeO5OAqnAIk+6PhmbZFXcWnaakTv
X+Kd1jbn37zCkqkbQhoC4W7THjDbMr9ZOExx1j7j1S/GuRtF3YNczRn4rmAKkNon
UN74LAigjUutNZRFCOqKiH37S5ZC9FiwzKOLXC6ICx6mFwODIiFc7/1sDEsJrbZe
pQ0aCsHHNDX44evftz/7vc14YjrExCgEcZYwGJ058p/CH2SV+I6qirU76skavDtg
hFIBYDtqJlOHw1SZN8CHQ9seRqVQXE44H7ub5MzyshZpBa912daDJdspqe8jTw0O
P3bvlZ+ToIojbFq4qrt7mFRnLtDG0V49riLaX1Dd3xTkorqwidXqMsCEay010S5I
6e7GT8BYIffeXVsVQd/0YTjvOKAq+/D8Zlq59ieyQ1AJb6oy26YPTWWypNyrhsl+
VtHyi9oV4oMTtmhHcO4FZXiSwGJPHS5yKlVffxQUo9u6DlDiZLHeF6/uBH0Zvjpk
GQp2wwz1Mu+T6xnY0jK0zmpFYoCLQkXeM517YcwcCWVH/B09PxJeKKWI2gFgEavF
DyYmjeZsVDvJMbDV0mRYTWArG3FPfGW4GvWpUBjhYfFNU0LuGJJH4mYmbfj/mhRq
IxQFWGuwA9Ekr38X6RYFU3BD+Wuc+4OabLpKCp+JbczRCPFSt2CtKNFs45rhiKl0
GIUckZl4zGgN4mt7X8z9TmZmedvCx0yXaS2wNm3issT9ga430yvfQlhNS1v1MP1h
29pwlvIpUB7l/RZnKV/YUMa1QBQ1Dazr7sheKrwsO116K78rrwBRSUJ7RkS2SQTE
DxMaIJyQgc/6LB8qU0gT74e8uQOYwg==
=kUIM
-----END PGP MESSAGE-----

20
crypto/testdata/mime/scenario_11.asc vendored Normal file
View file

@ -0,0 +1,20 @@
-----BEGIN PGP MESSAGE-----
Version: GopenPGP 2.3.0
Comment: https://gopenpgp.org
wV4DJ5XBV9zAEI0SAQdAaHyLlcodvjvkMIv+sYkPA0XPjBhg4i78Sp9rmFNEpkIw
loKGaFcZA4NXBhNGLrNixSIuhpHBVYb3Zjme5r0w8fNMDwkp6xGKsMkroekbyGb+
0ukBpReu6vaCKNs9nwnyNpduR4YnRy6/aSrhcqjEYgjk2fQc056fJoc7O66tI6+B
8VANRBeqY3jqbDrDbtKIjC1sQFSNfyNgsHz+BNymqHgAO7AnLHoTy7pwNI1hM1Ee
Ob3rLYfJuZH31zzT/CUAEKNMK6yu2g1DScMVGU7TLWKTyBBDsSImVrVkIyQdn2Ph
ZNrSU69heuRMoq6xp1XqFnvpI0ayAWSX5W8kf2ihef4/2vjHETNrd3rHEDTccSr7
DUNkWxzHYPhmhg7zynamZ/eRnrc8ZJ8PGrJSpuKJAN63f3MFkSnh3JWEpB976wyD
MN/QKfqtOfdc881SSlz88UPaY8VPY38RymE3wNi3iJZgYKwVkuygfp2hKhBIaTxZ
1/RfthB7TZZuY7gQCnlJpljaZHXHUNNCiv6tNrxJ6GkjCjwG79MUod4eSbbrxaM7
ONRTaTOXFX14ygfm11pInqoSKmX7YhZQMHVSLa2Jrf9OmZnJho91epze78tG+wFL
teaX2s3mlHgJmzMX1jEBnT0jZEZ5AIUYTBnfmyOEIJD6JbVe77TBNaobD8y4gDMg
2o1CHG+8UMhXOcBunQz3foH5hUIfJWRmFmQn0d6IUSvFjOihF1EvN9u+oD2RXbc5
tCRhWgSiOnWRiAgCRjmyQ66OOhDT1xoaS8DWyXpcvX87RRzjLu5JFeGbBQd3I/pD
0UVynMs1yjha9G2GkCAI
=cGGr
-----END PGP MESSAGE-----

36
crypto/testdata/mime/scenario_12.asc vendored Normal file
View file

@ -0,0 +1,36 @@
-----BEGIN PGP MESSAGE-----
Version: GopenPGP 2.3.0
Comment: https://gopenpgp.org
wV4DJ5XBV9zAEI0SAQdAr+3cQzwcQBljmHzzOaIQR6dnLCRNViqn4GBL5tSCeiUw
3y9VCTDvPhNO33NI/pE5s8kOp+4ok1BUD2vnOYG4MJFRjOFaKv/Lxdg9KrMusct6
0uoBiniYKX382jEfyvhCuatZqnnFdko2jr8+vIx4PPBnXdSnxIBC+iCBrvBKhz22
TYyfLzQsnw+gc4DRziN8XFH8eOld5NCQzE2InvYsrV3sn4JBXUovfIZF2MjYasSS
Qhx+9+3me/9ycGCln0smCCFJf9oRKdiFIaynZOmEzXpEqoxcuecyKoEkZqKOWWZo
D9HCGDV8eeoXaH+yivXy8UUj9ChExt9cZxB8qdYOy91VgOlY5VVYy/MPx9HxKk3V
yo2r00VK9P50RNFKhvGWvyxuZtC43GucnUlPeRvHpqKP1YaK9XF47sd4byWz+TYU
7m/mAjvmSakwqcWBLspMDI+Y4si0FUeJxHBRzhyuXUjpvkbbDypDFA+Bm1W98mAI
WQhR/M7wuJSiH7Pj72X/xWKgfVDGeLpm4BEQXiv8GM9elfKLI67Zsn/Uv0tqG4n7
w7KKOlvS6v5TcZnTw0iGY8DfqB5SSSePGp0o/XN4Al0xyaRVlPTg3krduhTpJ7Jb
Jju9yqgsZi4OptBuw0kEi0VbhTZAUfnPOkdplyDmJuH0RenBqfsT/oDJq6sDP/qY
iC0Qq8I8urh9Eja9qvLxSN3oDC63DJeF0d01Cr/fSbUKccleipe7JYwWifCFLqcS
+NzRonPe8SO3bjMvvwHo+fRpX364c9Ek7ovNndCI7bLg58WOGIx5mH7tv/3O7YiV
mtp4+mlZXr8ud9qnpADayF1fMP8KpJhB0537DTkSVbgF/NFAEAWJviWmNxS6aMGM
gJNjDpXlcnDhkVIdOQOuTy3Wffweqblr8dBOcHHKPDi19OwcqrbAhadoLkCTskRl
ItXqyMluP5LMGbuOw/RoXwpdngC2RRc3iks4cc5Pq7kTIlEzX2JeDzU+mcC17YaG
hYN8h8sY4KLWS1TP+D5n2bQ2H3X1f9xVUE2VCGVeI57x6Xxf2FNxYFuFg3ecXefd
zjUAGZ6Tr/vHNuFBLExui4h3Cw3qcNyJSxijT3bQBsrV1dbB2sCu3DGFcKmX1ta7
HUOSTuTOs2RGWXy21hRSPSddUXep5i3bl2a0re5fh7UUGD1EF05fyWqBRMz+uuYY
PuXUoYI9WLII0dt4kDRCUxTVctij0uT4y/ckjhwfjL0aDmXkJecoG5bopm9XzhU1
XuzR2FkU7gPZcceMqpn6HjPuexbfdHxu307l8juaU9IKOKjeXaPFVNyca7VuwOjr
6rinJ88rNhN5Cq6twN5BJA+BtO6aBAq8gktPpYQvTKBYTeCxRHoadnWzzhWsgxJo
Z2CgtoUnBdnWyx0VBlU+UYHrNSXX+pDZu3ECy0JWHWRppCI0g9VgeVFGPweDv6w5
5fAPTDhtwxohU/fLKL7ChqLMwGJHyRPAjfXrFBX8rJeEk396ZzhfQrx8aMN5u4GB
WHescDL4KH6rVda1xJjF5BADj+3C07+f2R9o0YU9WcNLF11NgqCVy6c8LTRRluhc
qNAark5KomEs9biaAu+5xIrQ1eF0PfZWZM97lfi6SVvbsQwMY18598aHLniEzsc1
7RwFg+wkAYCX0gb6CE86UzAD+GmRDZY/GN6z4QN9NmSTUs82aqZ7r/lV2t2oje+t
poD8S/c5u8JwCxgnp5+MwxWiUnkeB8O9pXboi4h+gaZQdsvhWQ7krD4aHlnH3PDq
k4plN+MXgZbnAiriYtaZHueyw4DgYDvXzchpLny8wJ3jfw1vEGyTRf1NzkzsI2Tm
JZjEZXphxJSjvc4fMuqGy8AeBHJ4iw==
=Zo9B
-----END PGP MESSAGE-----

36
crypto/testdata/mime/scenario_13.asc vendored Normal file
View file

@ -0,0 +1,36 @@
-----BEGIN PGP MESSAGE-----
Version: GopenPGP 2.3.0
Comment: https://gopenpgp.org
wV4DJ5XBV9zAEI0SAQdA5/2MvBKwZ4zaxrnTtpRIOgw15NSo+3VgPHfk8wZTCnQw
df4jHJ5NbO61cN3N9hI7JVi2k2PU8rR0mG5PwwOr3O0dYvxvhNnyUUZioCvWl02i
0uoBY3mbeaXzSmpaFmR+KCqXQ1aZ0UmSbcTZi7yVs/qBtT9V+GDI/AEyItR6Rpgv
Ls2K4lvqzFSE59BG3nuAx59jU7F3pBLQEuyykMtXhuYJw/X+sY/FTN7ojZjCsctY
qD4lr+ka5cUCXr6aSQhpcjwnwwbGZwXIr5MHVoXmwaFgCubQj95xv3CDiSPTxdvC
TfahPZ5Jw5ZpDEGH6Dm98wLBW273aPiFh8q9l9ef81uD8TCS5/l4BD+9W3iaA0Ct
5TcetXc+QPTdMI3e+2CMsUzdBdCWqPG82c92OTUUFS+Aq/XKrZqo0yOAe7QaalTu
1AyDGL3yR3FpY6En+qjmQXetXl+7C/GzG0vB6loeB32PoVMjyPfqP5vD1Fr42QWC
cFYK4hp11VY3d5+aDX4fpK2DCUfRIpssHCLKGenX23LawXwSaazyaB0Fp0WvBk5m
2xloT8v3UvgFct2LyEImEC6A0p5thqq3X12ojdKzhWsw4OpefX/3jU3ZHYOI9y07
AayUoClnYwtnKMfR0MXReUr6/FZ7+SP93uCWMK0gSzYiYNG1ckOhuplRelZj+r19
M24fael3LpALb7XEc5o6luVZnL/QGVkGf1QSXBOqgB3CvBJmJweQYHbsM15aisTq
DSsZdjNA3tpf6pnVr4mz42qiJ8dQhyNpx44+fDfmALNQ7k1MgpWBp5n7X1fVm8K9
YluimlZnXsbKpTilraJVc+XSjn/f5PLh8K5rhgxuurmQfNOEKMGi8a8RfB8h7Zyy
e+R7w7LUbmpzFnYQYV9dlMNm5vZhL6L0MqlL/Mb3ahw4gZneDlnCRLXar6JHLLkq
LUQyXwTrfNgRpaSHVrt/A/wbJoVS1hU2+i9KDUtZoeQWK2cDeQZZ7eDRAkIzQW+v
qw3dbTa1ahKKvPctSI2z363V6VfiXFYjFH4eHqbGoN3PTK2V0tlgSscTM6Fhrcai
obOSj1flzsH8iHCC/eTnDDqkIT6gP/mLlISM2S6Hkm/F2ekRR4OPolJaHru2DNEJ
H2m2iyV3KFZnzqrJaobGagHIPF8g8+1tzubPl31EsuiaLtRcjnJTv9Ds+Mc5L1VK
Nvxaf+7CDzZ477nOsdlbnniO0VYscdQ54ewPKngzmEHSSS9gvlWg2UXiJhcLAO4K
nc29OzJsKKtlcfpBVNBs74RTPASAnV9Xl+pzTGUXXt3RE6GWidKFoppVhjWamRq2
+/5R56FY0uW99ZFMaXBcCE1IQ/dJQY78Wvazayif3W5EiiScYDpBFzAy9IdpATMf
9lkMgTo39AKqB0mCTBWzcCuY+omeRPhHXn6YQeqL967ABt98TGljv1u9CxKYwzn7
wHpeJUqV1aJcAWzHRUbV+S/wwGJ5wc5rjK52asC3hsujs/koUhBaz2IqyW9KLti9
ozhZ47cEPMxbzyniZpEoN2LT2oTUxcapj5nB+V8NhSajBaKRvsZmtdslcBpNp54h
SwrKj7SmDfFGlKPMR9804ppQUdxG3I0fxrsv/UG/o7UbMoS16/S81Ux+ElpEK9NF
dJGNOENg4u6Cum5VfVsxySggrDit+tq8jBi4mtSA+YUGsPJpg0fC/IlwtpFQre6e
TJp8M5RjmftNWm6nRROSmq8lMXEs/28Ntm4bWgUjakPPuez8MSxxHfFkBaauY/w+
4njZfso0d7ea8Tyk40TnvKPNe3+1zs86mGOyRu/X04ff3atKXbjeAkKJjtVF0qui
ohuO0C6rMQqaRPME2W7mT/RmLVG1Ag==
=eU//
-----END PGP MESSAGE-----

39
crypto/testdata/mime/scenario_20.asc vendored Normal file
View file

@ -0,0 +1,39 @@
-----BEGIN PGP MESSAGE-----
Version: GopenPGP 2.3.0
Comment: https://gopenpgp.org
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
Ij6H5wiVu7KMnjDt
=yeLD
-----END PGP MESSAGE-----

23
crypto/testdata/mime/scenario_21.asc vendored Normal file
View file

@ -0,0 +1,23 @@
-----BEGIN PGP MESSAGE-----
Version: GopenPGP 2.3.0
Comment: https://gopenpgp.org
wV4DJ5XBV9zAEI0SAQdAvdPN0I33NGYZeVexYVElck6clJ1bbacK+r9PgaYhrHkw
t5KHA15TLj0jtVSSDAfnbpKDWOH+I2OvoegYTszgGiL1WByG+b7bm2n4cFWw+Lvn
0ukBkSEU/uQAB1v37p47GIJy/VVUWnDMXZnCO8/Shmx5AGaj21hnn662/Wg7p/JX
yFC4DNFf04vu1WQqm+5TitfNKLmcKQdS4l6P9zB8xT3br72ApbKNsN5Ni8V2F4+M
BHjPqYIFq4Q6XNS7ob+swXsC87/+eey4uyjRamapkRp1eZIaY7MALBrWMJc+mvqc
TQEG/XpVaDFo08WKmF7eE+d+1MoAXzo5TqMKJyrp4E59CqMRGPDdMXZEpOO/G8w0
w0/uyPbq0+o2u8JC7GzfiWOdHcOOYwfRue6Vy3O97g2vgltnHM1WX0iwplB3q2BC
QURm+LDaFXTEwc7n2dRIT7UsDYplreMRn5NkYdCl6p/xXrNu7Bwmw/BKl1r3IML6
neSIBaGlEMXlABaZUKFtjWNBDJakErZyEJytNBuk7sgxgwfYAy/OTRoQwUStQHBn
SH25hawhhxKt00V1ckm58dPztnoKUfJat1UWfJG5nfByssGLCqK0qNm4rPkkvcpI
dske1l6z1ItmLiXhTbZyuW/IicAtmoebVUHNp+kUjT179S8A/vnbKFi3lMPk5sQT
jZEW5OMCJ3jahp6x5NLeewnHJbOb17k+MwDbQDxnUAEytfzw8brkK0e/IWSETcJU
pWMR2eHIMmvD8+8QcXKCX3FY+RnR1UthgNPXkM4Xgizb6qLucSB7juer6sZhGWST
2GuunVYRnGfvKU1psacBm/RVI12vUcqLfFP6du87XygbNJO6kAfkwfNijxjsLv3I
2Gdh4UoarU8vYK1m5EXqdZk6NM+pXp2yGYWadK3xVBJQVzDJCop17RXsVw8D9iCA
ClnZfEEYSXBTDQEG+WacWeUrwWMS/dYv7iW9SXPfXVq7SnwPDHsXY6IAkS+tPS5X
+tzLl8Q=
=cBFZ
-----END PGP MESSAGE-----

39
crypto/testdata/mime/scenario_22.asc vendored Normal file
View file

@ -0,0 +1,39 @@
-----BEGIN PGP MESSAGE-----
Version: GopenPGP 2.3.0
Comment: https://gopenpgp.org
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
jn+AOb9hQrhC2MSU
=PkfB
-----END PGP MESSAGE-----

39
crypto/testdata/mime/scenario_23.asc vendored Normal file
View file

@ -0,0 +1,39 @@
-----BEGIN PGP MESSAGE-----
Version: GopenPGP 2.3.0
Comment: https://gopenpgp.org
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
+P31KcApEHzngYcN
=WbqD
-----END PGP MESSAGE-----

View file

@ -0,0 +1,15 @@
-----BEGIN PGP PUBLIC KEY BLOCK-----
Version: GopenPGP 2.3.0
Comment: https://gopenpgp.org
xjMEXNidoBYJKwYBBAHaRw8BAQdAJGftDER4jTxZx23Ksf+aJFv8yyv2nxvRhjqu
AsKF5lfNKXRlc3RAcHJvdG9ubWFpbC5jb20gPHRlc3RAcHJvdG9ubWFpbC5jb20+
wowEExYIAD4FAlzYnaAJkFJeTumSSXDmFqEEdmasnK7fmVUlyJ2mUl5O6ZJJcOYC
GwMCHgECGQEDCwkHAhUIAxYAAgIiAQAAxgQA/2FxHkDXhB+e3ThY6QEWlD/byIKK
RG5j6Ac3/8iagpeWAQC+KJHPjaMLoa7/LCpVZNsWISakvy98gMlZijcZzbnIC844
BFzYnaASCisGAQQBl1UBBQEBB0DrPwqPBGJGgAfJeohxSnPuEFiOdrlfdHVRvzy5
CpfRSAMBCgnCeAQYFggAKgUCXNidoAmQUl5O6ZJJcOYWoQR2Zqycrt+ZVSXInaZS
Xk7pkklw5gIbDAAAf8gA/iUFOuRmCTc0RxsWzyPFlkF8CInyRtVRVPpUV1lp5xjo
AP4h3KtT3Ju0LICUDzsMyWdO78c7ef+YvCcko3b/3rASAQ==
=9F0e
-----END PGP PUBLIC KEY BLOCK-----