SMIME Messaging
Use the S/MIME (Secure Multipurpose Internet Mail Extensions) integration to send and receive secure MIME data.
Utilities · SMIME Messaging
Details
| ID | SMIME Messaging |
|---|---|
| Provider | Open Source |
| Category | Utilities |
| From Version | 5.0.0 |
| Docker Image | demisto/m2crypto:1.0.0.117200 |
| Supported Modules | Agentix XSIAM |
README
Use the S/MIME (Secure Multipurpose Internet Mail Extensions) integration to send and receive secure MIME data.
This integration was integrated and tested with version 0.40.1 of M2Crypto.
Use Cases
- Send an S/MIME-signed message.
- Send an S/MIME-encrypted message.
- Send an S/MIME-signed and encrypted message.
- Decrypt an S/MIME message.
Usage
-
In order to send signed/encrypted messages using the S/MIME Messaging and Mail Sender (New) perform the following steps:
- Run the
smime-sign-and-encryptcommand with the required parameters. - Enter the output message from step 1 as the input for the
raw_messageargument of thesend-mailcommand in the Mail Sender (New) integration (e.g., the value stored in the Context Data underSMIME.SignedAndEncrypted.Message). - Run the
send-mailcommand with theraw_messageargument (as described in step 2), with any of the optional argumentsto,ccandbcc(e.g.,!send-mail to=user@email.com raw_message=${SMIME.SignedAndEncrypted.Message}).
- Run the
-
While decrypting or verifying a message, S/MIME Messaging will attempt to parse the message into readable text, as well as extract any attachments and images if present. If you wish to get the raw message instead, use the raw_output argument.
Configure SMIME Messaging in Cortex
| Parameter | Description | Required |
|---|---|---|
| Public Key | Sender public key required for signing emails. | True |
| Private Key | Sender private key required for decrypting and signing emails. | True |
Commands
You can execute these commands from the CLI, as part of an automation, or in a playbook.
After you successfully execute a command, a DBot message appears in the War Room with the command details.
smime-verify-sign
Verifies the signature.
Warning: This function does not check the CA chain. Ensure the certificate chain is validated separately to avoid security risks.
Base Command
smime-verify-sign
Input
| Argument Name | Description | Required |
|---|---|---|
| signed_message | Entity ID of the file with a .p7 extension containing the signed message. | Required |
| public_key | Sender’s public key to verify. Default is instancePublicKey. | Optional |
| raw_output | Whether to get the full raw output of the email. Possible values are: false, true. | Optional |
| tag | A comma-separated list of tags to be included in the War Room output. | Optional |
Context Output
| Path | Type | Description |
|---|---|---|
| SMIME.Verified.Message | String | The decoded signed message. |
Command example
!smime-verify-sign signed_message=454@6cc2adad-6d3b-4fec-8b98-99b1b1770bc5
Context Example
{
"SMIME": {
"Verified": {
"Message": "This is a message to sign"
}
}
}
Human Readable Output
The signature verified, message is
This is a message to sign
smime-decrypt-email-body
Decrypts the message body.
Base Command
smime-decrypt-email-body
Input
| Argument Name | Description | Required |
|---|---|---|
| encrypt_message | Entity ID of the file with a .p7 extension containing the encrypted email. | Required |
| encoding | The encoding code to use when decoding the message body, e.g., ‘ISO-8859-2’’. | Optional |
| raw_output | Whether to get the full raw output of the email. Possible values are: false, true. | Optional |
| tag | A comma-separated list of tags to be included in the War Room output. | Optional |
Context Output
| Path | Type | Description |
|---|---|---|
| SMIME.Decrypted.Message | String | The decrypted message. |
Command example
!smime-decrypt-email-body encrypt_message=451@6cc2adad-6d3b-4fec-8b98-99b1b1770bc5
Context Example
{
"SMIME": {
"Decrypted": {
"Message": "This is a message to encrypt"
}
}
}
Human Readable Output
The decrypted message is
This is a message to encrypt
smime-sign-and-encrypt
Encrypts and signs an email message with S/MIME protocol by using a public RSA certificate.
Base Command
smime-sign-and-encrypt
Input
| Argument Name | Description | Required |
|---|---|---|
| message | The message body to encrypt and sign. | Required |
| recipients | JSON dict of recipients and their public keys Format: {“recipient@email”:”cert”, “other@email”:”cert”} Use “instancePublicKey” in the cert field to use the instance certificate. |
Optional |
| cc | JSON dict of cc recipients and their public keys Format: {“cc@email”:”cert”, “othercc@email”:”cert”} Use “instancePublicKey” in the cert field to use the instance certificate. |
Optional |
| bcc | JSON dict of bcc recipients and their public keys Format: {“bcc@email”:”cert”, “otherbcc@email”:”cert”} Use “instancePublicKey” in the cert field to use the instance certificate. |
Optional |
| attachment_entry_id | List of War Room entry IDs of files to attach to the mail. | Optional |
| signed | Whether the mail should be signed. Possible values are: true, false. Default is true. | Optional |
| encrypted | Whether the mail should be encrypted. Possible values are: true, false. Default is true. | Optional |
| sender | Sender email address. | Optional |
| subject | Email subject. | Optional |
| create_file_p7 | Whether to create a file with the encrypted/signed content. Possible values are: false, true. | Optional |
Context Output
| Path | Type | Description |
|---|---|---|
| SMIME.SignedAndEncrypted.Message | String | The raw message to send. |
| SMIME.SignedAndEncrypted.RecipientIds | String | Address of the recipient. |
| SMIME.SignedAndEncrypted.FileName | String | Name of the file output if create_file_p7 is used. |
Command example
!smime-sign-and-encrypt message="This is a message to sign" encrypted=false
Context Example
{
"SMIME": {
"SignedAndEncrypted": {
"FileName": "",
"Message": "Date: Mon, 05 Aug 2024 08:56:00 +0000\r\nMIME-Version: 1.0\nContent-Disposition: attachment; filename=\"smime.p7m\"\nContent-Type: application/x-pkcs7-mime; smime-type=signed-data; name=\"smime.p7m\"\nContent-Transfer-Encoding: base64\n\nMIIJ4gYJKoZIhvcNAQcCoIIJ0zCCCc8CAQExDzANBglghkgBZQMEAgEFADCCAUkG\nCSqGSIb3DQEHAaCCAToEggE2Q29udGVudC1UeXBlOiBtdWx0aXBhcnQvbWl4ZWQ7\nIGJvdW5kYXJ5PSI9PT09PT09PT09PT09PT0wNTEzMzU2NzMxMDg3NTk4NjkxPT0i\nDQpNSU1FLVZlcnNpb246IDEuMA0KDQotLT09PT09PT09PT09PT09PTA1MTMzNTY3\nMzEwODc1OTg2OTE9PQ0KQ29udGVudC1UeXBlOiB0ZXh0L3BsYWluOyBjaGFyc2V0\nPSJ1cy1hc2NpaSINCk1JTUUtVmVyc2lvbjogMS4wDQpDb250ZW50LVRyYW5zZmVy\nLUVuY29kaW5nOiA3Yml0DQoNClRoaXMgaXMgYSBtZXNzYWdlIHRvIHNpZ24NCi0t\nPT09PT09PT09PT09PT09MDUxMzM1NjczMTA4NzU5ODY5MT09LS0NCqCCBb0wggW5\nMIIDoaADAgECAhAWjRiNCtW2fdBrguq+Q6aTMA0GCSqGSIb3DQEBCwUAMIGBMQsw\nCQYDVQQGEwJJVDEQMA4GA1UECAwHQmVyZ2FtbzEZMBcGA1UEBwwQUG9udGUgU2Fu\nIFBpZXRybzEXMBUGA1UECgwOQWN0YWxpcyBTLnAuQS4xLDAqBgNVBAMMI0FjdGFs\naXMgQ2xpZW50IEF1dGhlbnRpY2F0aW9uIENBIEczMB4XDTI0MDcyMTA4MzkwMFoX\nDTI1MDcyMTA4MzkwMFowJDEiMCAGA1UEAwwZc20uc21pbWUudGVzdGVyQGdtYWls\nLmNvbTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAOcJHez4H953XJAG\nSRzfh+/HtTvqC0cu+KEeiGK/WYXuYZtjNb3Z7P++/DCZkWZ6FAMKZyMJqEwNiYsd\ndvirSdOHpfgPSKtTILiFXtTogGjPydAZvxri9x8Kg1AnyKwk4WJi3ftfgaIFpo8i\nF7BKS36IDpdb3O43mlLwXfOdWQBPlY0ndYPIWS+elbSHbHH+s8ai6CGcFoB3Akyb\nvIbSjVj5YFKky0wYVeXtJpgYlZoOFUmkCI5jpSTlCFIUm2bwIFwCeXt/hl0xHaXM\nfCPpX7B+EYLd2wUei2ZeEaDMi5Gnd9ANBlP9c8xe+KXQQ3vy1OT1ptd0YscOMz6E\nyhZLut0CAwEAAaOCAYcwggGDMAwGA1UdEwEB/wQCMAAwHwYDVR0jBBgwFoAUvpep\nqoS/gL8QU30JMvnhLjIbz3cwfgYIKwYBBQUHAQEEcjBwMDsGCCsGAQUFBzAChi9o\ndHRwOi8vY2FjZXJ0LmFjdGFsaXMuaXQvY2VydHMvYWN0YWxpcy1hdXRjbGlnMzAx\nBggrBgEFBQcwAYYlaHR0cDovL29jc3AwOS5hY3RhbGlzLml0L1ZBL0FVVEhDTC1H\nMzAkBgNVHREEHTAbgRlzbS5zbWltZS50ZXN0ZXJAZ21haWwuY29tMBQGA1UdIAQN\nMAswCQYHZ4EMAQUBATAdBgNVHSUEFjAUBggrBgEFBQcDAgYIKwYBBQUHAwQwSAYD\nVR0fBEEwPzA9oDugOYY3aHR0cDovL2NybDA5LmFjdGFsaXMuaXQvUmVwb3NpdG9y\neS9BVVRIQ0wtRzMvZ2V0TGFzdENSTDAdBgNVHQ4EFgQUq8xlmZF/uLyAf3JUU1Bc\nXr+QRKMwDgYDVR0PAQH/BAQDAgWgMA0GCSqGSIb3DQEBCwUAA4ICAQCwNi6XtZwt\ne/mwEAswIi9OSHLAT7ruUNksl+RP8LdZQ9gyVxv5kER5mfdOF5ATO2OQ7Z/Y+ahs\n2Fk69tNckmq6tf4yhBGlWsHyYOLo+Njg0UVxah0NtDrbZfwqY6PeE5rcH7evYbpn\nfP25wf/5hZlqokpe+WwBTpxJLC6uRVQIdMpUKjRhpGJlRMUy7VZhzKzTqlkwAFID\nCaYAItFJ8DsVroZxq2A7g+jlrwc5tAaYglydn96HD4DOKmLPtHN3HkUrKuoXYDiN\n/ccZZ8wYRBB3zP1FjNyK8FHhjJpn70DY6sOvPn3ShzSL4vPEKYG1qABwTdToRh8v\ndZ4FlM4apSSRhZyaKGvfRzT1XlAE1zRlUWd2krNV+WXrLrs6NF0RKRtSR+IP5QmH\nKhgZJeUv2cgiOD+7Gx+7QTi0rERj9nH+jvvX1dn8kncT/PYuLBkHg1c1Xyv1o5vW\nNHfiIsqZMVUW+aZPm92k77+/AcgOaHcvqTP8vxbZBOgf959VSLma/n7NDprhjNg6\nO7pHh/cAB35gu9Q7acZE9NEwc+J0vl4LVx7YlP0aEaR8BOaFufQyOwD+2JV2f0bQ\nXwltX2Gr77xsOZKI/2pVn9Oj6xyW3h7ZrlA7Me/l4H9VAHoi6epON8r9wI+UDJKo\nIz3nxuKNFYDgnjtIaYrX5xjprYVX3fJlAzGCAqkwggKlAgEBMIGWMIGBMQswCQYD\nVQQGEwJJVDEQMA4GA1UECAwHQmVyZ2FtbzEZMBcGA1UEBwwQUG9udGUgU2FuIFBp\nZXRybzEXMBUGA1UECgwOQWN0YWxpcyBTLnAuQS4xLDAqBgNVBAMMI0FjdGFsaXMg\nQ2xpZW50IEF1dGhlbnRpY2F0aW9uIENBIEczAhAWjRiNCtW2fdBrguq+Q6aTMA0G\nCWCGSAFlAwQCAQUAoIHkMBgGCSqGSIb3DQEJAzELBgkqhkiG9w0BBwEwHAYJKoZI\nhvcNAQkFMQ8XDTI0MDgwNTA4NTYwMFowLwYJKoZIhvcNAQkEMSIEIJxfZpuZLFhT\n/xN2gZGCKzEPOnGX6uuyA5byB32PPlsqMHkGCSqGSIb3DQEJDzFsMGowCwYJYIZI\nAWUDBAEqMAsGCWCGSAFlAwQBFjALBglghkgBZQMEAQIwCgYIKoZIhvcNAwcwDgYI\nKoZIhvcNAwICAgCAMA0GCCqGSIb3DQMCAgFAMAcGBSsOAwIHMA0GCCqGSIb3DQMC\nAgEoMA0GCSqGSIb3DQEBAQUABIIBAFZZ5ExsKfb+hCgY5YQcVodYC74CmcCaN6fc\nJG6jL0yDNUV7wzuUNMT/DoxhKFI/2MNNJQ54KeyOYWMB0O6WreRnmFulJ3baEgAz\nYgsTPC3QBbdpngcO33dFDXg/TJkeGY9mT5HI1rBonYF1dB+AMbbCUdK5W8bA8+Ow\nhumygMscmnweEFwXT4/MvaAlelVhB0iWoAo/F4X9fEOm5dMVHzjYxTA0R0+Dzny4\nSmKlkzd3gUH4kEtgTBo8slRkO5dfg8Ik64qnQNvSidLWp9PmKkGb2069czQCyKIj\nme4sPRRl8TJQ12xVuOmlRpQ4+rUxhMfZKyyYZ0isoVNYsmeFPQ8=\n\n",
"RecipientIds": {
"bcc": [],
"cc": [],
"to": []
}
}
}
}
Human Readable Output
Date: Mon, 05 Aug 2024 08:56:00 +0000
MIME-Version: 1.0
Content-Disposition: attachment; filename=”smime.p7m”
Content-Type: application/x-pkcs7-mime; smime-type=signed-data; name=”smime.p7m”
Content-Transfer-Encoding: base64MIIJ4gYJKoZIhvcNAQcCoIIJ0zCCCc8CAQExDzANBglghkgBZQMEAgEFADCCAUkG
CSqGSIb3DQEHAaCCAToEggE2Q29udGVudC1UeXBlOiBtdWx0aXBhcnQvbWl4ZWQ7
IGJvdW5kYXJ5PSI9PT09PT09PT09PT09PT0wNTEzMzU2NzMxMDg3NTk4NjkxPT0i
DQpNSU1FLVZlcnNpb246IDEuMA0KDQotLT09PT09PT09PT09PT09PTA1MTMzNTY3
MzEwODc1OTg2OTE9PQ0KQ29udGVudC1UeXBlOiB0ZXh0L3BsYWluOyBjaGFyc2V0
PSJ1cy1hc2NpaSINCk1JTUUtVmVyc2lvbjogMS4wDQpDb250ZW50LVRyYW5zZmVy
LUVuY29kaW5nOiA3Yml0DQoNClRoaXMgaXMgYSBtZXNzYWdlIHRvIHNpZ24NCi0t
PT09PT09PT09PT09PT09MDUxMzM1NjczMTA4NzU5ODY5MT09LS0NCqCCBb0wggW5
MIIDoaADAgECAhAWjRiNCtW2fdBrguq+Q6aTMA0GCSqGSIb3DQEBCwUAMIGBMQsw
CQYDVQQGEwJJVDEQMA4GA1UECAwHQmVyZ2FtbzEZMBcGA1UEBwwQUG9udGUgU2Fu
IFBpZXRybzEXMBUGA1UECgwOQWN0YWxpcyBTLnAuQS4xLDAqBgNVBAMMI0FjdGFs
aXMgQ2xpZW50IEF1dGhlbnRpY2F0aW9uIENBIEczMB4XDTI0MDcyMTA4MzkwMFoX
DTI1MDcyMTA4MzkwMFowJDEiMCAGA1UEAwwZc20uc21pbWUudGVzdGVyQGdtYWls
LmNvbTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAOcJHez4H953XJAG
SRzfh+/HtTvqC0cu+KEeiGK/WYXuYZtjNb3Z7P++/DCZkWZ6FAMKZyMJqEwNiYsd
dvirSdOHpfgPSKtTILiFXtTogGjPydAZvxri9x8Kg1AnyKwk4WJi3ftfgaIFpo8i
F7BKS36IDpdb3O43mlLwXfOdWQBPlY0ndYPIWS+elbSHbHH+s8ai6CGcFoB3Akyb
vIbSjVj5YFKky0wYVeXtJpgYlZoOFUmkCI5jpSTlCFIUm2bwIFwCeXt/hl0xHaXM
fCPpX7B+EYLd2wUei2ZeEaDMi5Gnd9ANBlP9c8xe+KXQQ3vy1OT1ptd0YscOMz6E
yhZLut0CAwEAAaOCAYcwggGDMAwGA1UdEwEB/wQCMAAwHwYDVR0jBBgwFoAUvpep
qoS/gL8QU30JMvnhLjIbz3cwfgYIKwYBBQUHAQEEcjBwMDsGCCsGAQUFBzAChi9o
dHRwOi8vY2FjZXJ0LmFjdGFsaXMuaXQvY2VydHMvYWN0YWxpcy1hdXRjbGlnMzAx
BggrBgEFBQcwAYYlaHR0cDovL29jc3AwOS5hY3RhbGlzLml0L1ZBL0FVVEhDTC1H
MzAkBgNVHREEHTAbgRlzbS5zbWltZS50ZXN0ZXJAZ21haWwuY29tMBQGA1UdIAQN
MAswCQYHZ4EMAQUBATAdBgNVHSUEFjAUBggrBgEFBQcDAgYIKwYBBQUHAwQwSAYD
VR0fBEEwPzA9oDugOYY3aHR0cDovL2NybDA5LmFjdGFsaXMuaXQvUmVwb3NpdG9y
eS9BVVRIQ0wtRzMvZ2V0TGFzdENSTDAdBgNVHQ4EFgQUq8xlmZF/uLyAf3JUU1Bc
Xr+QRKMwDgYDVR0PAQH/BAQDAgWgMA0GCSqGSIb3DQEBCwUAA4ICAQCwNi6XtZwt
e/mwEAswIi9OSHLAT7ruUNksl+RP8LdZQ9gyVxv5kER5mfdOF5ATO2OQ7Z/Y+ahs
2Fk69tNckmq6tf4yhBGlWsHyYOLo+Njg0UVxah0NtDrbZfwqY6PeE5rcH7evYbpn
fP25wf/5hZlqokpe+WwBTpxJLC6uRVQIdMpUKjRhpGJlRMUy7VZhzKzTqlkwAFID
CaYAItFJ8DsVroZxq2A7g+jlrwc5tAaYglydn96HD4DOKmLPtHN3HkUrKuoXYDiN
/ccZZ8wYRBB3zP1FjNyK8FHhjJpn70DY6sOvPn3ShzSL4vPEKYG1qABwTdToRh8v
dZ4FlM4apSSRhZyaKGvfRzT1XlAE1zRlUWd2krNV+WXrLrs6NF0RKRtSR+IP5QmH
KhgZJeUv2cgiOD+7Gx+7QTi0rERj9nH+jvvX1dn8kncT/PYuLBkHg1c1Xyv1o5vW
NHfiIsqZMVUW+aZPm92k77+/AcgOaHcvqTP8vxbZBOgf959VSLma/n7NDprhjNg6
O7pHh/cAB35gu9Q7acZE9NEwc+J0vl4LVx7YlP0aEaR8BOaFufQyOwD+2JV2f0bQ
XwltX2Gr77xsOZKI/2pVn9Oj6xyW3h7ZrlA7Me/l4H9VAHoi6epON8r9wI+UDJKo
Iz3nxuKNFYDgnjtIaYrX5xjprYVX3fJlAzGCAqkwggKlAgEBMIGWMIGBMQswCQYD
VQQGEwJJVDEQMA4GA1UECAwHQmVyZ2FtbzEZMBcGA1UEBwwQUG9udGUgU2FuIFBp
ZXRybzEXMBUGA1UECgwOQWN0YWxpcyBTLnAuQS4xLDAqBgNVBAMMI0FjdGFsaXMg
Q2xpZW50IEF1dGhlbnRpY2F0aW9uIENBIEczAhAWjRiNCtW2fdBrguq+Q6aTMA0G
CWCGSAFlAwQCAQUAoIHkMBgGCSqGSIb3DQEJAzELBgkqhkiG9w0BBwEwHAYJKoZI
hvcNAQkFMQ8XDTI0MDgwNTA4NTYwMFowLwYJKoZIhvcNAQkEMSIEIJxfZpuZLFhT
/xN2gZGCKzEPOnGX6uuyA5byB32PPlsqMHkGCSqGSIb3DQEJDzFsMGowCwYJYIZI
AWUDBAEqMAsGCWCGSAFlAwQBFjALBglghkgBZQMEAQIwCgYIKoZIhvcNAwcwDgYI
KoZIhvcNAwICAgCAMA0GCCqGSIb3DQMCAgFAMAcGBSsOAwIHMA0GCCqGSIb3DQMC
AgEoMA0GCSqGSIb3DQEBAQUABIIBAFZZ5ExsKfb+hCgY5YQcVodYC74CmcCaN6fc
JG6jL0yDNUV7wzuUNMT/DoxhKFI/2MNNJQ54KeyOYWMB0O6WreRnmFulJ3baEgAz
YgsTPC3QBbdpngcO33dFDXg/TJkeGY9mT5HI1rBonYF1dB+AMbbCUdK5W8bA8+Ow
humygMscmnweEFwXT4/MvaAlelVhB0iWoAo/F4X9fEOm5dMVHzjYxTA0R0+Dzny4
SmKlkzd3gUH4kEtgTBo8slRkO5dfg8Ik64qnQNvSidLWp9PmKkGb2069czQCyKIj
me4sPRRl8TJQ12xVuOmlRpQ4+rUxhMfZKyyYZ0isoVNYsmeFPQ8=
Command example
!smime-sign-and-encrypt message="This is a message to encrypt" signed=false
Context Example
{
"SMIME": {
"SignedAndEncrypted": {
"FileName": "",
"Message": "Date: Mon, 05 Aug 2024 08:56:03 +0000\r\nMIME-Version: 1.0\nContent-Disposition: attachment; filename=\"smime.p7m\"\nContent-Type: application/x-pkcs7-mime; smime-type=enveloped-data; name=\"smime.p7m\"\nContent-Transfer-Encoding: base64\n\nMIIDPwYJKoZIhvcNAQcDoIIDMDCCAywCAQAxggGzMIIBrwIBADCBljCBgTELMAkG\nA1UEBhMCSVQxEDAOBgNVBAgMB0JlcmdhbW8xGTAXBgNVBAcMEFBvbnRlIFNhbiBQ\naWV0cm8xFzAVBgNVBAoMDkFjdGFsaXMgUy5wLkEuMSwwKgYDVQQDDCNBY3RhbGlz\nIENsaWVudCBBdXRoZW50aWNhdGlvbiBDQSBHMwIQFo0YjQrVtn3Qa4LqvkOmkzAN\nBgkqhkiG9w0BAQEFAASCAQDFnrTvu16smUFbTBoLJLdM+0hIcsMq66ssFc0BtihR\n6+XQXkE+VRJ6Zn1L+qfUWVUYuZvWwT9TV8CpJV4zJftqcGpyrHSsdA9HNPYMsO/c\nbnWWPfrWeqxcJrnfABIk2f8G+Tar2PcPLRn/DEs10j1ZtKGW0b6veBQowi6zHvto\nc+jY3lRqTLFxBJlvL5PpHItV3GrEorAKN+pR/nwey/xYApdQeIMOF2zt/X5sRaM0\nzaxJ7q+rlfRboxKoQIROsJGP3f7vlcKZx6VF5A3VH0B4/Wu82PNQO7NGXZymCwTo\ntz+twA72J0Dt5wRKY2NDZZnunWGnfSkrX78q9ygdLfuAMIIBbgYJKoZIhvcNAQcB\nMB0GCWCGSAFlAwQBKgQQDnYKpZW9arvx/5zUCivAq4CCAUBM+/9WJMmbRGW6btBo\nIe4S2Yp+RVOWjMSXwJF3I8ugZJ5XMsUUhssmOpIpBrGnDDq/5bn74j+tIIO9UjQm\nODnV2mxradfmh4Xpw215SY+6UcgtvhwoYkqK8X3de+jca07ER8ig0ubzXke1HPd5\n0/qYPL8FmvI2HWML1rx95Z/n07h8KRNcjKX/u5c9kaBa+CayS6T2JqWPXsjCgiuL\nZa1plhvecAWwW4RllCyiyBSQNaOV5PyMZWAd7VOqK7wD3mp9Qo9pffcOzGhB9PMr\nQZzXsSyB78JxSkXCQA+fU7E+EL4B/U04iPjaj9IxrrEN4m3Pxi8i5xG8YrzfMHE0\nKJu33MeFXApz/qZ3OwmmdYl7l8zs12LArs813yMhOpu2vicjrZ+S5BYygM1oOvr+\n+Mmk+dI+iwm16cO4MWhY6szJRQ==\n\n",
"RecipientIds": {
"bcc": [],
"cc": [],
"to": []
}
}
}
}
Human Readable Output
Date: Mon, 05 Aug 2024 08:56:03 +0000
MIME-Version: 1.0
Content-Disposition: attachment; filename=”smime.p7m”
Content-Type: application/x-pkcs7-mime; smime-type=enveloped-data; name=”smime.p7m”
Content-Transfer-Encoding: base64MIIDPwYJKoZIhvcNAQcDoIIDMDCCAywCAQAxggGzMIIBrwIBADCBljCBgTELMAkG
A1UEBhMCSVQxEDAOBgNVBAgMB0JlcmdhbW8xGTAXBgNVBAcMEFBvbnRlIFNhbiBQ
aWV0cm8xFzAVBgNVBAoMDkFjdGFsaXMgUy5wLkEuMSwwKgYDVQQDDCNBY3RhbGlz
IENsaWVudCBBdXRoZW50aWNhdGlvbiBDQSBHMwIQFo0YjQrVtn3Qa4LqvkOmkzAN
BgkqhkiG9w0BAQEFAASCAQDFnrTvu16smUFbTBoLJLdM+0hIcsMq66ssFc0BtihR
6+XQXkE+VRJ6Zn1L+qfUWVUYuZvWwT9TV8CpJV4zJftqcGpyrHSsdA9HNPYMsO/c
bnWWPfrWeqxcJrnfABIk2f8G+Tar2PcPLRn/DEs10j1ZtKGW0b6veBQowi6zHvto
c+jY3lRqTLFxBJlvL5PpHItV3GrEorAKN+pR/nwey/xYApdQeIMOF2zt/X5sRaM0
zaxJ7q+rlfRboxKoQIROsJGP3f7vlcKZx6VF5A3VH0B4/Wu82PNQO7NGXZymCwTo
tz+twA72J0Dt5wRKY2NDZZnunWGnfSkrX78q9ygdLfuAMIIBbgYJKoZIhvcNAQcB
MB0GCWCGSAFlAwQBKgQQDnYKpZW9arvx/5zUCivAq4CCAUBM+/9WJMmbRGW6btBo
Ie4S2Yp+RVOWjMSXwJF3I8ugZJ5XMsUUhssmOpIpBrGnDDq/5bn74j+tIIO9UjQm
ODnV2mxradfmh4Xpw215SY+6UcgtvhwoYkqK8X3de+jca07ER8ig0ubzXke1HPd5
0/qYPL8FmvI2HWML1rx95Z/n07h8KRNcjKX/u5c9kaBa+CayS6T2JqWPXsjCgiuL
Za1plhvecAWwW4RllCyiyBSQNaOV5PyMZWAd7VOqK7wD3mp9Qo9pffcOzGhB9PMr
QZzXsSyB78JxSkXCQA+fU7E+EL4B/U04iPjaj9IxrrEN4m3Pxi8i5xG8YrzfMHE0
KJu33MeFXApz/qZ3OwmmdYl7l8zs12LArs813yMhOpu2vicjrZ+S5BYygM1oOvr+
+Mmk+dI+iwm16cO4MWhY6szJRQ==
Command example
!smime-sign-and-encrypt message="This is a message to sign and encrypt"
Context Example
{
"SMIME": {
"SignedAndEncrypted": {
"FileName": "",
"Message": "Date: Mon, 05 Aug 2024 08:56:06 +0000\r\nMIME-Version: 1.0\nContent-Disposition: attachment; filename=\"smime.p7m\"\nContent-Type: application/x-pkcs7-mime; smime-type=enveloped-data; name=\"smime.p7m\"\nContent-Transfer-Encoding: base64\n\n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\nkuj3\n\n",
"RecipientIds": {
"bcc": [],
"cc": [],
"to": []
}
}
}
}
Human Readable Output
Date: Mon, 05 Aug 2024 08:56:06 +0000
MIME-Version: 1.0
Content-Disposition: attachment; filename=”smime.p7m”
Content-Type: application/x-pkcs7-mime; smime-type=enveloped-data; name=”smime.p7m”
Content-Transfer-Encoding: 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
kuj3
Configuration parameters
public_key— Public Key (required)private_key— Private Key (required)
Commands (5)
-
smime-decrypt-email-bodyDecrypts the message body.
-
smime-encrypt-email-bodyDeprecatedDeprecated. Use smime-sign-and-encrypt instead. Encrypts an email message with S/MIME protocol by using a public RSA certificate.
-
smime-sign-and-encryptEncrypts and signs an email message with S/MIME protocol by using a public RSA certificate.
-
smime-sign-emailDeprecatedDeprecated. Use smime-sign-and-encrypt instead. Retrieves items from the service.
-
smime-verify-signVerifies the signature. Warning: This function does not check the CA chain. Ensure the certificate chain is validated separately to avoid security risks.
import demistomock as demisto from CommonServerPython import * from CommonServerUserPython import * """ IMPORTS """ import mimetypes import quopri import uuid from email import encoders, message_from_string from email.message import Message from email.mime.base import MIMEBase from email.mime.multipart import MIMEMultipart from email.mime.text import MIMEText from tempfile import NamedTemporaryFile import pytz from charset_normalizer import from_bytes from M2Crypto import BIO, SMIME, X509 """ HELPER FUNCTIONS """ def makebuf(text): return BIO.MemoryBuffer(text) def create_pem_string(base64_cert: str) -> str: """Converts a base64 encoded certificate string to a PEM format. Args: base64_cert (str): certificate string with no BEGIN or END markers Returns: pemstring (str): PEM-formatted certificate string """ pem_header = "-----BEGIN CERTIFICATE-----\n" pem_footer = "-----END CERTIFICATE-----\n" # Split the base64 certificate into lines of 64 characters each pem_body = "\n".join(base64_cert[i : i + 64] for i in range(0, len(base64_cert), 64)) return f"{pem_header}{pem_body}\n{pem_footer}" def handle_attachment(attachment_part: Message) -> None: """ Extracts and saves the attachment file to the context. p7 files will be ignored. Args: attachment_part (Message): attachment message part """ file_name = attachment_part.get_filename() if not file_name: demisto.debug("Got nameless attachment, generating file name") mime_type = attachment_part.get_content_type() extension = mimetypes.guess_extension(mime_type) or ".bin" file_name = f"attachment_{uuid.uuid4()}{extension}" # ignore p7 file types and subtypes (e.g. p7m) if file_name.lower().endswith(".p7") or file_name.lower().endswith(".p7", 0, -1): demisto.debug(f"Skipping p7 file: {file_name}") return # create the attachment file_result = fileResult(file_name, attachment_part.get_payload(decode=True)) # check for error if file_result["Type"] == entryTypes["error"]: raise Exception(file_result["Contents"]) # return the attachment to war room return_results(file_result) def handle_image(image_part: Message, payload: Any) -> tuple[str, str, str] | None: """ Handles the payload for an image, extracting the cid and image data Args: image_part (Message): Image message part payload (Any): Message part payload Returns: (cid, content_type, image_data): Complete image data to allow embedding into the message, None if no cid is found """ content_type = image_part.get_content_type() image_data_base64 = base64.b64encode(payload).decode("utf-8") cid = image_part.get("Content-Id") if not cid: return None # Remove angle brackets if present around CID cid = re.sub(r"<(.*?)>", r"\1", cid) return cid, content_type, image_data_base64 def extract_email_body(text_part: Message, payload: Any) -> tuple[str, str]: """ Handles the payload for the email body part Args: text_part (Message): Text message part payload (Any): Message part payload Returns: (email_body, body_type): Strings containing the email body and the body type (text or html) """ email_body = payload.decode(text_part.get_content_charset("utf-8"), errors="ignore") if text_part.get_content_type() == "text/html": body_type = "html" # Clean up whitespaces between </head> and <body> tags email_body = re.sub(r"</head>\s*<body>", "</head><body>", email_body) else: body_type = "text" return email_body, body_type def patch_cid_with_urls(email_body: str, images: list[tuple[str, str, str]]) -> str: """ Replaces HTML image references with their data URLs Args: email_body (str): The html email message to patch images (list): List of images found in the message, each containing (cid, type, data) Returns: patched_body (str): email body with patched URLs """ patched_body = email_body for cid, content_type, image_data_base64 in images: cid_reference = f"cid:{cid}" data_url = f"data:{content_type};base64,{image_data_base64}" patched_body = patched_body.replace(cid_reference, data_url) return patched_body def parse_multipart_message(msg: str) -> tuple[str, str]: """ Extracts the contents from a MIME message. Images (if any exist) will be added to the html email_body, attachments will be added to the context directly. Args: msg (str): Message to parse Returns: (email_body, body_type): Strings containing the parsed email, and the message type (text or html) """ email_message = message_from_string(msg) if email_message.get_content_type() == "multipart/signed": # The message is signed return ("", "") email_body = "" body_type = "" images: list[tuple[str, str, str]] = [] for part in email_message.walk(): if part.is_multipart(): continue content_type = part.get_content_type() if content_type in {"application/pkcs7-signature", "application/pkcs7-mime", "application/x-pkcs7-mime"}: # The message is signed return ("", "") if part.get_content_disposition() == "attachment": handle_attachment(part) continue payload = part.get_payload(decode=True) if not isinstance(payload, bytes): raise TypeError(f"Error in message.get_payload(decode=True), expected bytes, got: {type(payload)}") if part.get_content_maintype() == "image": if image := handle_image(part, payload): images.append(image) elif part.get_content_maintype() == "text" and body_type != "html": email_body, body_type = extract_email_body(part, payload) if body_type == "html": email_body = patch_cid_with_urls(email_body, images) return (email_body, body_type) def create_message_with_attachments(message: str, attach_ids: list[str]) -> str: """ Creates a MIMEMultipart formatted message with message body and attachments Args: message (str): Message body attach_ids (list): list of war room entries containing files to attach Returns: msg (str): Formatted mime message with attachments added """ msg = MIMEMultipart() is_html = bool(re.search(r"<.*?>", message)) if is_html: msg.attach(MIMEText(message, "html")) else: msg.attach(MIMEText(message, "plain")) # Add attachments to message for attach_id in attach_ids: try: fp = demisto.getFilePath(attach_id) file_path = fp["path"] attach_name = fp["name"] except Exception as ex: raise Exception(f"Error while opening attachment id {attach_id}: {ex!s}") if isinstance(attach_name, list): attach_name = attach_name[0] part = MIMEBase("application", "octet-stream") with open(file_path, "rb") as f: part.set_payload(f.read()) encoders.encode_base64(part) part.add_header("Content-Disposition", f"attachment; filename={attach_name}") msg.attach(part) return msg.as_string() def create_email_header(sender: str, subject: str, recipients: list[str], cc: list[str], bcc: list[str]) -> BIO.MemoryBuffer: """ Creates a memory buffer with email headers Args: sender (str): Sender email subject (str): Email subject recipients (list): List of recipient emails cc (list): List of cc emails bcc (list): List of bcc emails Returns: header (MemoryBuffer): memory buffer containing email headers """ header = BIO.MemoryBuffer() current_time = datetime.now(pytz.timezone("UTC")).strftime("%a, %d %b %Y %H:%M:%S %z") header.write(f"Date: {current_time}\r\n") if sender: header.write(f"From: {sender}\r\n") if recipients: header.write(f'To: {", ".join(recipients)}\r\n') if cc: header.write(f'CC: {", ".join(cc)}\r\n') if bcc: header.write(f'BCC: {", ".join(bcc)}\r\n') if subject: header.write(f"Subject: {subject}\r\n") return header class Client: def __init__(self, private_key, public_key): self.smime = SMIME.SMIME() public_key_file = NamedTemporaryFile(delete=False) public_key_file.write(bytes(public_key, "utf-8")) self.public_key_file = public_key_file.name public_key_file.close() private_key_file = NamedTemporaryFile(delete=False) private_key_file.write(bytes(private_key, "utf-8")) self.private_key_file = private_key_file.name private_key_file.close() def set_encryption_params(client: Client, certs: list[str]) -> None: """ Sets the smime cipher and X509 certificate stack Args: client: Client certs: List of recipient certificates to use for the encryption """ client.smime.set_cipher(SMIME.Cipher("aes_256_cbc")) # Create and set certificate stack cert_stack = X509.X509_Stack() if not certs: demisto.debug("No certs given, using instance cert") cert_stack.push(X509.load_cert(client.public_key_file)) for cert in certs: if cert == "instancePublicKey": cert_stack.push(X509.load_cert(client.public_key_file)) continue if ("-----BEGIN CERTIFICATE-----") not in cert: demisto.debug("No ---BEGIN CERTIFICATE--- tag, creating pem from cert") cert = create_pem_string(cert) with NamedTemporaryFile(delete=False) as public_key_file: public_key_file.write(bytes(cert, "utf-8")) public_key_file.close() cert_stack.push(X509.load_cert(public_key_file.name)) os.unlink(public_key_file.name) client.smime.set_x509_stack(cert_stack) """ COMMANDS """ def sign_email(client: Client, args: dict): """ send a S/MIME-signed message via SMTP. """ use_transport_encoding: bool = argToBoolean(args.get("use_transport_encoding", "false")) if use_transport_encoding: message_body = ( b'Content-Type: text/plain; charset="utf-8"\nContent-Transfer-Encoding: quoted-printable\n\n' + quopri.encodestring(args.get("message_body", "").encode("utf-8")) ) buf = makebuf(message_body) client.smime.load_key(client.private_key_file, client.public_key_file) p7 = client.smime.sign(buf, SMIME.PKCS7_DETACHED) buf = makebuf(message_body) out = BIO.MemoryBuffer() client.smime.write(out, p7, buf) else: message_body = args.get("message_body", "") buf = makebuf(message_body.encode()) # type: ignore client.smime.load_key(client.private_key_file, client.public_key_file) p7 = client.smime.sign(buf, SMIME.PKCS7_DETACHED) buf = makebuf(message_body.encode()) # type: ignore out = BIO.MemoryBuffer() client.smime.write(out, p7, buf, SMIME.PKCS7_TEXT) signed = out.read().decode("utf-8") signed_message = signed.split("\n\n") headers = signed_message[0].replace(": ", "=").replace("\n", ",") return CommandResults( readable_output=signed, outputs_prefix="SMIME.Signed", outputs={ "Message": signed, "Headers": headers, }, ) def encrypt_email_body(client: Client, args: dict): """generate an S/MIME-encrypted message Args: client: Client args: Dict """ message_body = args.get("message", "").encode("utf-8") buf = makebuf(message_body) x509 = X509.load_cert(client.public_key_file) sk = X509.X509_Stack() sk.push(x509) client.smime.set_x509_stack(sk) client.smime.set_cipher(SMIME.Cipher("des_ede3_cbc")) p7 = client.smime.encrypt(buf) out = BIO.MemoryBuffer() client.smime.write(out, p7) encrypted_message = out.read().decode("utf-8") message = encrypted_message.split("\n\n") headers = message[0] new_headers = headers.replace(": ", "=").replace("\n", ",") return CommandResults( readable_output=encrypted_message, outputs_prefix="SMIME.Encrypted", outputs={ "Message": encrypted_message, "Headers": new_headers, }, ) def verify(client: Client, args: dict) -> List[CommandResults]: """Verify the signature Args: client (Client): The client instance. args (dict): The arguments for verification. """ signed_message = demisto.getFilePath(args.get("signed_message")) cert = args.get("public_key", "instancePublicKey") raw_output = argToBoolean(args.get("raw_output", "false")) tags = argToList(args.get("tag", "")) sk = X509.X509_Stack() st = X509.X509_Store() if cert == "instancePublicKey": sk.push(X509.load_cert(client.public_key_file)) st.load_info(client.public_key_file) elif cert: with NamedTemporaryFile(delete=False) as public_key_file: public_key_file.write(cert.encode("utf-8")) public_key_file_name = public_key_file.name sk.push(X509.load_cert(public_key_file_name)) st.load_info(public_key_file_name) os.unlink(public_key_file_name) client.smime.set_x509_stack(sk) client.smime.set_x509_store(st) try: result = SMIME.smime_load_pkcs7(signed_message["path"]) if not isinstance(result, tuple): raise DemistoException("SMIME error while loading message") p7, data = result verified_data = client.smime.verify(p7, data, flags=SMIME.PKCS7_NOVERIFY) human_readable = f"The signature verified\n\n{verified_data}" except SMIME.SMIME_Error as e: if str(e) == "no content type": demisto.debug("No content type found in message, testing if it is in DER format (binary)") with open(signed_message["path"], "rb") as message_file: p7data = message_file.read() p7bio = BIO.MemoryBuffer(p7data) p7 = SMIME.load_pkcs7_bio_der(p7bio) verified_data = client.smime.verify(p7, flags=SMIME.PKCS7_NOVERIFY) return_results(fileResult(f'unwrapped-{signed_message["name"]}', verified_data)) human_readable = "The signature verified\n\n" else: raise e if not verified_data: raise ValueError("Unknown error: failed to verify message") msg = verified_data.decode("utf-8") msg_out = msg if not raw_output: # Return message after parsing html/images/attachments demisto.debug(f"Parsing message:\n\n{msg}") msg_out, email_type = parse_multipart_message(msg) if email_type == "html": human_readable = "The signature verified" else: human_readable = f"### The signature verified, message is: \n ___ \n {msg_out}" results = [ CommandResults( readable_output=human_readable, outputs_prefix="SMIME.Verified", outputs={"Message": msg_out}, tags=tags, ) ] if email_type == "html": results.append( CommandResults( raw_response=msg_out, content_format=EntryFormat.HTML, entry_type=EntryType.NOTE, ) ) return results def decode_str(decrypted_text: bytes, encoding: str) -> tuple[str, str]: """ Detect encoding type using chardet, if the confidence of the detected encoding is lower than 0.9 we will add a message indicates it. If encoding is given, will use it. """ msg = "" out = "" if not encoding: with warnings.catch_warnings(record=True) as e: charset_match = from_bytes(decrypted_text) if len(charset_match): out = str(charset_match[0]) demisto.debug(f"Decode decrypted text using {charset_match[0].encoding} encoding") if e: msg = ( f"Note: encoding detection ended with warning: {e[0].message} Characters may be missing." " You can try running this command again and pass the encoding code as argument.\n" ) else: out = decrypted_text.decode(encoding) return out, msg def decrypt_email_body(client: Client, args: dict) -> List[CommandResults]: """Decrypt the message Args: client (Client): The client instance. args (Dict): The arguments for decryption. """ if "test_file_path" in args: # test module encrypt_message = {"path": args.get("test_file_path", "")} else: encrypt_message = demisto.getFilePath(args.get("encrypt_message", "")) demisto.debug(f'File Name:{encrypt_message["name"]}; Type:{type(encrypt_message["name"])}') encoding = args.get("encoding", "") raw_output = argToBoolean(args.get("raw_output", "false")) tags = argToList(args.get("tag", "")) msg = "" client.smime.load_key(client.private_key_file, client.public_key_file) try: p7 = SMIME.smime_load_pkcs7(encrypt_message["path"]) if isinstance(p7, tuple): p7 = p7[0] decrypted_text = client.smime.decrypt(p7) if not decrypted_text: raise ValueError("Unknown error: failed to decrypt message") out, msg = decode_str(decrypted_text, encoding) except SMIME.SMIME_Error as e: if str(e) == "no content type": # If no content type; see if we can process as DER format demisto.debug("No content type found in message, testing if it is in DER format (binary)") with open(encrypt_message["path"], "rb") as message_file: p7data = message_file.read() p7bio = BIO.MemoryBuffer(p7data) p7 = SMIME.load_pkcs7_bio_der(p7bio) decrypted_text = client.smime.decrypt(p7, flags=SMIME.PKCS7_NOVERIFY) if not decrypted_text: raise ValueError("Unknown error: failed to decrypt message") out, msg = decode_str(decrypted_text, encoding) else: raise msg_out = out human_readable = f"{msg}The decrypted message is: \n{out}" if not raw_output: # Return message after parsing html/images/attachments demisto.debug(f"parsing message:\n\n{out}") email_body, email_type = parse_multipart_message(out) if email_type == "html": msg_out = email_body human_readable = f"{msg}Message decrypted successfully" elif email_type == "text": msg_out = email_body human_readable = f"### {msg}The decrypted message is: \n ___ \n {msg_out}" else: human_readable = f"### {msg}The decrypted message is signed, verify to get the original message\n ___ \n{out}" results = [ CommandResults( readable_output=human_readable, outputs_prefix="SMIME.Decrypted", outputs={"Message": msg_out}, tags=tags, ) ] if email_type == "html": results.append( CommandResults( raw_response=msg_out, content_format=EntryFormat.HTML, entry_type=EntryType.NOTE, ) ) return results def sign_and_encrypt(client: Client, args: dict) -> CommandResults: """Sign and encrypt the message Args: client (Client): The client instance. args (Dict): The arguments for signing and encrypting. """ message = args.get("message", "") sign = argToBoolean(args.get("signed", "true")) encrypt = argToBoolean(args.get("encrypted", "true")) sender = args.get("sender", "") subject = args.get("subject", "") create_file = argToBoolean(args.get("create_file_p7", "false")) attachment_ids = argToList(args.get("attachment_entry_id", "")) # type: list[str] recipients = safe_load_json(args.get("recipients", {}) or "{}") if not isinstance(recipients, dict): raise DemistoException('Failed to parse recipients. (format `{"recipient@email":"cert", "other@email":"cert"}`)') cc = safe_load_json(args.get("cc", {}) or "{}") if not isinstance(cc, dict): raise DemistoException('Failed to parse cc. (format `{"recipient@email":"cert", "other@email":"cert"}`)') bcc = safe_load_json(args.get("bcc", {}) or "{}") if not isinstance(bcc, dict): raise DemistoException('Failed to parse bcc. (format `{"recipient@email":"cert", "other@email":"cert"}`)') msg_str = create_message_with_attachments(message, attachment_ids) demisto.debug(f"\n\nMessage:\n\n {msg_str} \n\nMessage end\n") if sign: msg_bio = BIO.MemoryBuffer(msg_str.encode("utf-8")) client.smime.load_key(client.private_key_file, client.public_key_file) p7 = client.smime.sign(msg_bio, algo="sha256") if encrypt: pub_certs = [cert for dest in [recipients, cc, bcc] for cert in dest.values()] # Consolidate all recipient certificates set_encryption_params(client, pub_certs) msg_bio = BIO.MemoryBuffer() if sign: client.smime.write(msg_bio, p7) else: msg_bio.write(msg_str) p7 = client.smime.encrypt(msg_bio) # Prepare output out_bio = create_email_header(sender, subject, list(recipients.keys()), list(cc.keys()), list(bcc.keys())) if encrypt or sign: client.smime.write(out_bio, p7) else: out_bio.write(msg_str) msg_out = out_bio.read().decode("utf-8") file_results = {} if create_file: file_results = fileResult(filename=f"SMIME-{demisto.uniqueFile()[:8]}.p7", data=msg_out, file_type=EntryType.FILE) return_results(file_results) return CommandResults( readable_output=msg_out, outputs_prefix="SMIME.SignedAndEncrypted", outputs={ "Message": msg_out, "RecipientIds": { "to": list(recipients.keys()), "cc": list(cc.keys()), "bcc": list(bcc.keys()), }, "FileName": file_results.get("File", ""), }, ) def test_module(client, *_): message_body = "testing" try: # Encrypt the message encrypted_out = sign_and_encrypt(client, {"message": message_body, "signed": "false"}).to_context() encrypted_msg = encrypted_out["EntryContext"]["SMIME.SignedAndEncrypted"]["Message"] # Write the encrypted message to a temporary file with NamedTemporaryFile(delete=False) as test_file: test_file.write(bytes(encrypted_msg, "utf-8")) test_file_name = test_file.name # Decrypt the message decrypt_out = decrypt_email_body(client, {"test_file_path": test_file_name})[0].to_context() decrypted_msg = decrypt_out["HumanReadable"] if message_body in decrypted_msg: demisto.results("ok") else: raise Exception except Exception: return_error("""Failed to encrypt->decrypt using the provided credentials. Verify that the provided keys are valid and matching.""") finally: os.unlink(test_file.name) def main(): # pragma: no cover public_key: str = demisto.params().get("public_key", "") private_key: str = demisto.params().get("private_key", "") client = Client(private_key, public_key) LOG(f"Command being called is {demisto.command()}") commands = { "test-module": test_module, "smime-sign-email": sign_email, "smime-encrypt-email-body": encrypt_email_body, "smime-verify-sign": verify, "smime-decrypt-email-body": decrypt_email_body, "smime-sign-and-encrypt": sign_and_encrypt, } try: command = demisto.command() if command in commands: return_results(commands[command](client, demisto.args())) # type: ignore except Exception as e: return_error(str(e)) finally: if client.private_key_file: os.unlink(client.private_key_file) if client.public_key_file: os.unlink(client.public_key_file) if __name__ in ["__main__", "builtin", "builtins"]: main()