diff --git a/msg_test.go b/msg_test.go index d90981f..3a669e6 100644 --- a/msg_test.go +++ b/msg_test.go @@ -18,6 +18,7 @@ import ( "io" "net" "os" + "os/exec" "reflect" "runtime" "strings" @@ -6129,7 +6130,7 @@ func TestMsg_WriteTo(t *testing.T) { t.Fatalf("failed to initialize S/MIME signing: %s", err) } buffer := bytes.NewBuffer(nil) - if _, err := message.WriteTo(buffer); err != nil { + if _, err = message.WriteTo(buffer); err != nil { t.Fatalf("failed to write message to buffer: %s", err) } fileContentType := "text/plain; charset=utf-8" @@ -6767,6 +6768,35 @@ func TestMsg_WriteToTempFile(t *testing.T) { t.Errorf("expected message buffer to contain Testmail, got: %s", got) } }) + t.Run("WriteToTempFile S/MIME signed simple text message, verified with OpenSSL", func(t *testing.T) { + openSSL := getOpenSSLPath() + if openSSL == "" { + t.Skip("OpenSSL not found - skipping test") + } + message := testMessage(t) + keypair, err := getDummyKeyPairTLS() + if err != nil { + t.Fatalf("failed to load dummy key material: %s", err) + } + if err = message.SignWithTLSCertificate(keypair); err != nil { + t.Fatalf("failed to initialize S/MIME signing: %s", err) + } + msgFile, err := message.WriteToTempFile() + if err != nil { + t.Fatalf("failed to write message to buffer: %s", err) + } + t.Cleanup(func() { + if err := os.RemoveAll(msgFile); err != nil { + t.Errorf("failed to remove temp file: %s", err) + } + }) + openSSLExec := exec.Command(openSSL, "smime", "-verify", "-noverify", "-in", msgFile) + out, err := openSSLExec.CombinedOutput() + if err != nil { + t.Errorf("S/MIME signing failed, expected OpenSSL to verify the message but got error: %s "+ + "// exec output: %s", err, out) + } + }) } func TestMsg_hasAlt(t *testing.T) { diff --git a/smime_test.go b/smime_test.go index 17a25d0..14b7e0f 100644 --- a/smime_test.go +++ b/smime_test.go @@ -12,6 +12,7 @@ import ( "crypto/tls" "crypto/x509" "errors" + "os" "strings" "testing" ) @@ -183,6 +184,21 @@ func TestGetLeafCertificate(t *testing.T) { }) } +func getOpenSSLPath() string { + paths := []string{"/bin/openssl", "/usr/bin/openssl", "/usr/local/bin/openssl"} + openSSL := "" + for _, path := range paths { + if info, err := os.Stat(path); err == nil { + if info.IsDir() || info.Mode()&0o111 == 0 { + continue + } + openSSL = path + break + } + } + return openSSL +} + // getDummyRSACryptoMaterial loads a certificate (RSA), the associated private key and certificate (RSA) is loaded // from local disk for testing purposes func getDummyRSACryptoMaterial() (crypto.PrivateKey, *x509.Certificate, *x509.Certificate, error) {