/* * smime-decode.c * + decode S/MIME message * + print out the plaintext * + verify signature (for now ignore the certificate chain) * - can't write opuput to a file (only stdout) * - doesn't verify the certificate chain * - can't decrypt encrypted messages * * Michal Ludvig (c) 2003 * Homepage: http://www.logix.cz/michal/devel/smime * * This code is public domain. Use it as you want to, * but don't blame me if something doesn't work as you * expect. * NOTE: This code works with cryptography - you should double * chack and fully understand it before relying on it's output! */ #include #include #include #include #include #include #include #include int main (int argc, char *argv[]) { BIO *bin, *bout, *content = NULL; PKCS7 *p7; X509_STORE *store = NULL; X509_LOOKUP *lookup; int res, flags = 0; /* Initialize the OpenSSL engine. */ CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_ON); OpenSSL_add_all_algorithms(); ERR_load_crypto_strings(); /* Open output BIO. */ bout = BIO_new_fp (stdout, BIO_NOCLOSE); if (! bout) { printf ("Can not attach stdout: %s\n", strerror (errno)); return 1; } /* Open input BIO. */ if (argc < 2) { bin = BIO_new_fp (stdin, BIO_NOCLOSE); if (! bin) { BIO_printf (bout, "Can not attach stdin: %s\n", strerror (errno)); return 1; } } else { bin = BIO_new_file (argv[1], "r"); if (! bin) { BIO_printf (bout, "%s: %s\n", argv[1], strerror (errno)); return 1; } } /* Prepare for using CA certificates. Useless for now. */ store = X509_STORE_new (); lookup = X509_STORE_add_lookup (store, X509_LOOKUP_file ()); X509_LOOKUP_load_file (lookup, NULL, X509_FILETYPE_DEFAULT); lookup = X509_STORE_add_lookup (store, X509_LOOKUP_hash_dir ()); X509_LOOKUP_add_dir (lookup, NULL, X509_FILETYPE_DEFAULT); /* Read and decode S/MIME message. */ p7 = SMIME_read_PKCS7(bin, &content); if (! p7) { BIO_printf (bout, "Read: %s\n", ERR_error_string(ERR_get_error (), NULL)); return 1; } /* Exit if it isn't a signed-only message. */ if (PKCS7_type_is_enveloped (p7)) { printf ("[Message is encrypted - can't handle it]\n"); return 11; } if (PKCS7_type_is_signedAndEnveloped (p7)) { printf ("[Message is signed & encrypted - can't handle it]\n"); return 12; } /* IMPORTANT: Verify only the signature, not the certificate! * This is probably not what you want, because the signature could * be easily forged! */ flags = PKCS7_NOVERIFY; /* Verification itself. Plaintext is written to 'bout' BIO. */ res = PKCS7_verify (p7, NULL, store, content, bout, flags); /* Print a result. */ BIO_printf (bout, "********************\n"); BIO_printf (bout, "[%s signature %s]\n", PKCS7_get_detached (p7) ? "Detached" : "Embedded", res == 1 ? "verified" : "broken"); return 0; }