6 #include <mimetic/mimetic.h>
7 #include <mimetic/utils.h>
8 #include <openssl/bio.h>
9 #include <openssl/pkcs7.h>
10 #include <openssl/x509.h>
11 #include <openssl/err.h>
12 #include <openssl/ssl.h>
15 using namespace mimetic;
17 void printMimeStructure(MimeEntity* pMe, int tabcount = 0);
19 int g_verbose; // verbose mode on/off
20 int g_quiet; // quiet mode
21 int g_entityCount; // num of entities found
29 int bca_pkcs7_verify(PKCS7 *p7)
34 int pkcs7MimeHandle(MimeEntity* pMe, int tabcount)
36 BIO *in = NULL, *content = NULL;
40 int rc = ~0, vfy, iMask = imPreamble | imEpilogue;
42 Header& h = pMe->header();
43 ContentType ct = h.contentType();
51 in = BIO_new_mem_buf((void*)me_str.c_str(), me_str.length());
54 BIO_set_mem_eof_return(in, 0);
56 p7 = SMIME_read_PKCS7(in, &content);
60 vfy = bca_pkcs7_verify(p7);
63 cout << ct.type() << "/" << ct.subtype()
64 << " (verify " << (vfy == 0 ? "ok" : "failed") << ")"
69 content = PKCS7_dataInit(p7, NULL);
73 ; /* multipart/signed, content is the cleartext message part */
77 sz = BIO_get_mem_data(content, &pdata);
80 MimeEntity me(pdata, pdata + sz, iMask);
81 printMimeStructure(&me, 1 + tabcount);
94 ERR_print_errors_fp(stderr);
99 void printMimeStructure(MimeEntity* pMe, int tabcount)
101 Header& h = pMe->header();
102 ContentType ct = h.contentType();
103 ContentId ci = h.contentId();
107 if(ct.isMultipart() ||
108 (ct.type() == "message" && ct.subtype() == "rfc822"))
110 if(ct.subtype() == "signed")
112 cerr << "S/MIME multipart/signed not yet supported!" << endl;
115 if(pMe->body().parts().size() != 2)
116 cerr << "bad message!" << endl;
118 cerr << "S/MIME verification failed" << endl;
122 cout << ct.type() << "/" << ct.subtype() << endl;
124 MimeEntityList::iterator mbit = pMe->body().parts().begin(),
125 meit = pMe->body().parts().end();
126 for(; mbit != meit; ++mbit)
127 printMimeStructure(*mbit, 1 + tabcount);
130 if(ct.type() == "application" &&
131 (ct.subtype() == "x-pkcs7-mime" || ct.subtype() == "pkcs7-mime"))
133 pkcs7MimeHandle(pMe, tabcount);
136 cout << ct.type() << "/" << ct.subtype() << endl;
145 cout << "structure [-v] [in_file]..." << endl;
146 cout << " -v Verbose mode" << endl;
147 cout << " -q totaly quiet; exit code = num of entities" << endl;
153 int main(int argc, char** argv)
155 std::ios_base::sync_with_stdio(false);
157 //int iMask = imBody | imPreamble | imEpilogue;
158 int iMask = imPreamble | imEpilogue;
160 /* Initialize the OpenSSL engine. */
161 CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_ON);
162 OpenSSL_add_all_algorithms();
163 ERR_load_crypto_strings();
168 string first = argv[1];
171 else if(first == "-v")
173 else if(first == "-q")
175 fidx = (g_verbose || g_quiet ? 2 : 1); // first filename idx
179 istreambuf_iterator<char> bit(std::cin), eit;
180 MimeEntity me(bit,eit, iMask);
181 printMimeStructure(&me);
183 for(int fc = fidx; fc < argc; ++fc)
188 cerr << "ERR: unable to open file "
193 MimeEntity me(in.begin(), in.end(),iMask);
194 printMimeStructure(&me);
197 return g_entityCount;