<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <html> <head> <meta http-equiv="Content-Type" content="text/html;charset=utf-8"> <meta http-equiv="cache-control" content="no-cache"> <title>Genivia - The mecevp streaming message encryption and decryption engine</title> <link href="genivia_tabs.css" rel="stylesheet" type="text/css"/> <script type="text/javascript" src="jquery.js"></script> <script type="text/javascript" src="dynsections.js"></script> <link href="doxygen.css" rel="stylesheet" type="text/css"> <link href="genivia_content.css" rel="stylesheet" type="text/css"> </head> <body> <div id="top"> <div id="titlearea"> <table height="72px" width="100%" cellspacing="0" cellpadding="0"> <tbody> <tr> <td width="10%"> </td> <td width="175px"><a href="https://www.genivia.com"><img alt="Genivia" src="GeniviaLogo2_trans_noslogan.png"/></a></td> <td class="tab_home"><a href="https://www.genivia.com">Home</a></td> <td class="tab_home"><a href="https://www.genivia.com/docs.html">Documentation</a></td> <td> <div style="float: right; font-size: 18px; font-weight: bold;">The mecevp streaming message encryption and decryption engine</div> <br> <div style="float: right; font-size: 10px;">updated Mon May 14 2018 by Robert van Engelen</div> </td> <td width="10%"> </td> </tr> </tbody> </table> </div> <!-- Generated by Doxygen 1.8.11 --> <div id="navrow1" class="tabs"> <ul class="tablist"> <li><a href="index.html"><span>Main Page</span></a></li> <li class="current"><a href="pages.html"><span>Related Pages</span></a></li> <li><a href="annotated.html"><span>Classes</span></a></li> <li><a href="files.html"><span>Files</span></a></li> </ul> </div> </div><!-- top --> <div class="header"> <div class="headertitle"> <div class="title">The mecevp streaming message encryption and decryption engine </div> </div> </div><!--header--> <div class="contents"> <div class="textblock"><p>The gSOAP mecevp engine encrypts and decrypts messages using the EVP interface of OpenSSL. It supports envelope encryption/decryption with public and private RSA keys and symmetric encryption with shared secret keys. Streaming and buffered message encryption modes are supported.</p> <p>An encryption and decryption algorithm and mode is selected with one of the following:</p> <ul> <li><a class="el" href="mecevp_8h.html#a8976847eff9cf2faebc7697e0d596047">SOAP_MEC_ENV_ENC_DES_CBC</a> envelope encryption with triple DES CBC</li> <li><a class="el" href="mecevp_8h.html#aab870a983b1ea7cf45884462d2c3502b">SOAP_MEC_ENV_ENC_AES256_CBC</a> envelope encryption with AES256 CBC</li> <li><a class="el" href="mecevp_8h.html#a239ab02045baa8901ab2dd0d99698713">SOAP_MEC_ENV_ENC_AES256_GCM</a> envelope authenticated encryption with AES256 GCM</li> <li><a class="el" href="mecevp_8h.html#ae8f63ce4ee6492f0b07949d301eda7d6">SOAP_MEC_ENC_DES_CBC</a> symmetric encryption with triple DES CBC</li> <li><a class="el" href="mecevp_8h.html#aeb9a2bf88cf42f85a4ace0d3cc4a1508">SOAP_MEC_ENC_AES256_CBC</a> symmetric encryption with AES256 CBC</li> <li><a class="el" href="mecevp_8h.html#ab4b4ac089f92d93113ee8129dc895e61">SOAP_MEC_ENC_AES256_GCM</a> symmetric authenticated encryption with AES256 GCM</li> <li><a class="el" href="mecevp_8h.html#a533b28fdec1dba756bdd69dea83ad244">SOAP_MEC_ENV_DEC_DES_CBC</a> envelope decryption with triple DES CBC</li> <li><a class="el" href="mecevp_8h.html#a614a07a8c4fa0aa814e1009033403b84">SOAP_MEC_ENV_DEC_AES256_CBC</a> envelope decryption with AES256 CBC</li> <li><a class="el" href="mecevp_8h.html#a86d91a11d9401b4bd0bb86d3b0478fca">SOAP_MEC_ENV_DEC_AES256_GCM</a> envelope authenticated decryption with AES256 GCM</li> <li><a class="el" href="mecevp_8h.html#a9226364c4bf1cd277c417cd4d2706561">SOAP_MEC_DEC_DES_CBC</a> symmetric decryption with triple DES CBC</li> <li><a class="el" href="mecevp_8h.html#a7151041a3f95a45edce0660f0fbcea44">SOAP_MEC_DEC_AES256_CBC</a> symmetric decryption with AES256 CBC</li> <li><a class="el" href="mecevp_8h.html#ab3853c4ab88cd32c4ba6058335f76fdf">SOAP_MEC_DEC_AES256_GCM</a> symmetric authenticated decryption with AES256 GCM</li> </ul> <p>where, in the above, AES256 can be replaced with AES128 ot AES192.</p> <p>Algorithm options:</p> <ul> <li><a class="el" href="mecevp_8h.html#a3ec89ef31a2fbfa3437815768f8ec089">SOAP_MEC_STORE</a> buffer all output in memory</li> <li><a class="el" href="mecevp_8h.html#aa1e17bb2df8b81479aa1bd6bedf700cd">SOAP_MEC_OAEP</a> use OAEP padding for CBC</li> </ul> <p>The mecevp engine wraps the EVP API with four new functions:</p> <ul> <li><a class="el" href="mecevp_8c.html#a6144725452c8086c7b1807f6310ff79d">soap_mec_init</a> to initialize the engine</li> <li><a class="el" href="mecevp_8c.html#a8c447a82872a919bb1935f34b849c1c4">soap_mec_update</a> to encrypt/decrypt a message part</li> <li><a class="el" href="mecevp_8c.html#aaa93413bd3e4136fe87a067821cfed53">soap_mec_final</a> to finalize encryption/decryption</li> <li><a class="el" href="mecevp_8c.html#a81ba68931cefa8b7a0f246d99e31e3ed">soap_mec_cleanup</a> to deallocate the engine and buffers</li> </ul> <p>All cipher data is written and read in base64 format.</p> <p>A higher-level interface for message encryption/decryption in parts (such as individual XML elements) is defined by two new functions:</p> <ul> <li><a class="el" href="mecevp_8c.html#a4c388668cf9472d0bf8abcb3e758786f">soap_mec_begin</a> to begin a streaming sequence of encryptions/decryptions</li> <li><a class="el" href="mecevp_8c.html#af225c0e603c01f9a59c60d6465d90535">soap_mec_start</a> to start encryption/decryption of a message part</li> <li><a class="el" href="mecevp_8c.html#aedaa8cd525cac9cbe0904378419573d9">soap_mec_stop</a> to stop encryption/decryption of a message part</li> <li><a class="el" href="mecevp_8c.html#a52b1ae6b5677aff39ac6f9548e9789b7">soap_mec_end</a> to end the sequence and deallocate the engine buffers</li> </ul> <p>Compile all source codes with -DWITH_OPENSSL and link with ssl and crypto libraries.</p> <p>Here is an example to encrypt a message while streaming it to the output. The example uses the public key of the recipient/reader of the message. The recipient/reader uses its private key to decrypt. Envelope encryption is used with SOAP_MEC_ENV_ENC_DES_CBC, which means an ephemeral secret key is generated and encrypted with the public key. This encrypted secret key should be communicated to the recipient/reader with the message to decrypt:</p> <div class="fragment"><div class="line"><span class="preprocessor">#include "<a class="code" href="mecevp_8h.html">mecevp.h</a>"</span></div><div class="line"><a class="code" href="structsoap__mec__data.html">soap_mec_data</a> mec;</div><div class="line">ns__Object object;</div><div class="line"><span class="keywordtype">int</span> alg = <a class="code" href="mecevp_8h.html#a8976847eff9cf2faebc7697e0d596047">SOAP_MEC_ENV_ENC_DES_CBC</a>;</div><div class="line">FILE *fd = fopen(<span class="stringliteral">"key.pem"</span>, <span class="stringliteral">"r"</span>);</div><div class="line">EVP_PKEY *pubk;</div><div class="line"><span class="keywordtype">unsigned</span> <span class="keywordtype">char</span> *key;</div><div class="line"><span class="keywordtype">int</span> keylen;</div><div class="line"><span class="keywordflow">if</span> (...) <span class="comment">// key file contains public key?</span></div><div class="line"> pubk = PEM_read_PUBKEY(fd, NULL, NULL, NULL);</div><div class="line"><span class="keywordflow">else</span> <span class="comment">// key file contains certificate</span></div><div class="line">{</div><div class="line"> X509 *cert = PEM_read_X509(fd, NULL, NULL, NULL);</div><div class="line"> pubk = X509_get_pubkey(cert);</div><div class="line"> X509_free(cert);</div><div class="line">}</div><div class="line">fclose(fd);</div><div class="line">key = soap_malloc(soap, <a class="code" href="mecevp_8h.html#ad2d26a59a33fafa445fa71ff72d23f02">soap_mec_size</a>(alg, pubk));</div><div class="line"><span class="keywordflow">if</span> (soap_begin_send(soap)</div><div class="line"> || <a class="code" href="mecevp_8h.html#abd9dd5e6e38fb46977f5c75aa89f4104">soap_mec_begin</a>(soap, &mec, alg, pubk, key, &keylen)</div><div class="line"> || <a class="code" href="mecevp_8h.html#a8053a2c0cda70dd37b944408dd3f8f0e">soap_mec_start</a>(soap, NULL)</div><div class="line"> || soap_out_ns__Object(soap, <span class="stringliteral">"ns:Object"</span>, 0, &<span class="keywordtype">object</span>, NULL)</div><div class="line"> || <a class="code" href="mecevp_8h.html#a8fdc3daea4e2c9c3bbde4e480209b0d0">soap_mec_stop</a>(soap)</div><div class="line"> || <a class="code" href="mecevp_8h.html#ae93d7dae06e1568cc6ee2420cd29faaf">soap_mec_end</a>(soap, &mec)</div><div class="line"> || soap_end_send(soap))</div><div class="line">{</div><div class="line"> <a class="code" href="mecevp_8h.html#aaa1e6fa1abac32acdd7f76232fa30241">soap_mec_cleanup</a>(soap, &mec); <span class="comment">// clean up when error</span></div><div class="line"> soap_print_fault(soap, stderr);</div><div class="line">}</div><div class="line">EVP_PKEY_free(pubk);</div></div><!-- fragment --><p>The example given above sends the output to stdout. To save the output in a string use the following in C:</p> <div class="fragment"><div class="line"><span class="keywordtype">char</span> *str = NULL; <span class="comment">// string to be set to the encrypted output</span></div><div class="line">soap->os = &str; <span class="comment">// for C code only </span></div><div class="line"><span class="keywordflow">if</span> (soap_begin_send(soap)</div><div class="line"> ...</div><div class="line">soap->os = NULL;</div><div class="line">... <span class="comment">// use str, which is set to the encrypted output</span></div><div class="line">soap_end(soap); <span class="comment">// auto-deletes str</span></div></div><!-- fragment --><p>With C++ you should use a string stream:</p> <div class="fragment"><div class="line">std::stringstream ss;</div><div class="line">soap->os = &ss;</div><div class="line"><span class="keywordflow">if</span> (soap_begin_send(soap)</div><div class="line"> ...</div><div class="line">soap->os = NULL;</div><div class="line">... <span class="comment">// use ss.str()</span></div><div class="line">soap_destroy(soap); <span class="comment">// cleanup</span></div><div class="line">soap_end(soap); <span class="comment">// cleanup</span></div></div><!-- fragment --><p>The decryption by the recipient/reader requires the ephemeral encrypted secret key generated by soap_mec_begin by the sender (as set above) to decrypt the message using envelope decryption with SOAP_MEC_ENV_DEC_DES_CBC.</p> <div class="fragment"><div class="line"><span class="preprocessor">#include "<a class="code" href="mecevp_8h.html">mecevp.h</a>"</span></div><div class="line"><a class="code" href="structsoap__mec__data.html">soap_mec_data</a> mec;</div><div class="line">ns__Object object;</div><div class="line"><span class="keywordtype">int</span> alg = <a class="code" href="mecevp_8h.html#a533b28fdec1dba756bdd69dea83ad244">SOAP_MEC_ENV_DEC_DES_CBC</a>;</div><div class="line">FILE *fd = fopen(<span class="stringliteral">"key.pem"</span>, <span class="stringliteral">"r"</span>);</div><div class="line">EVP_PKEY *privk = PEM_read_PrivateKey(fd, NULL, NULL, <span class="stringliteral">"password"</span>);</div><div class="line"><span class="keywordtype">unsigned</span> <span class="keywordtype">char</span> *key;</div><div class="line"><span class="keywordtype">int</span> keylen;</div><div class="line">fclose(fd);</div><div class="line">key = ... <span class="comment">// value set as above by sender</span></div><div class="line">keylen = ... <span class="comment">// value set as above by sender</span></div><div class="line"><span class="keywordflow">if</span> (soap_begin_recv(soap)</div><div class="line"> || <a class="code" href="mecevp_8h.html#abd9dd5e6e38fb46977f5c75aa89f4104">soap_mec_begin</a>(soap, &mec, alg, privk, key, &keylen)</div><div class="line"> || <a class="code" href="mecevp_8h.html#a8053a2c0cda70dd37b944408dd3f8f0e">soap_mec_start</a>(soap)</div><div class="line"> || soap_in_ns__Object(soap, <span class="stringliteral">"ns:Object"</span>, &<span class="keywordtype">object</span>, NULL) == NULL</div><div class="line"> || <a class="code" href="mecevp_8h.html#a8fdc3daea4e2c9c3bbde4e480209b0d0">soap_mec_stop</a>(soap)</div><div class="line"> || <a class="code" href="mecevp_8h.html#ae93d7dae06e1568cc6ee2420cd29faaf">soap_mec_end</a>(soap, &mec)</div><div class="line"> || soap_end_recv(soap))</div><div class="line">{</div><div class="line"> <a class="code" href="mecevp_8h.html#aaa1e6fa1abac32acdd7f76232fa30241">soap_mec_cleanup</a>(soap, &mec); <span class="comment">// clean up when error</span></div><div class="line"> soap_print_fault(soap, stderr);</div><div class="line">}</div><div class="line">EVP_PKEY_free(privk);</div></div><!-- fragment --><p>The example given above reads the input from stdin. To read input from a string use the following in C:</p> <div class="fragment"><div class="line"><span class="keywordtype">char</span> *str; <span class="comment">// string with encrupted input</span></div><div class="line">soap->is = str;</div><div class="line"><span class="keywordflow">if</span> (soap_begin_recv(soap)</div><div class="line"> ...</div><div class="line">soap->is = NULL;</div><div class="line">soap_end(soap); <span class="comment">// cleanup</span></div></div><!-- fragment --><p>With C++ you should use a string stream:</p> <div class="fragment"><div class="line">std::stringstream ss;</div><div class="line">ss.str(...); <span class="comment">// string with encrypted input</span></div><div class="line">soap->is = &ss;</div><div class="line"><span class="keywordflow">if</span> (soap_begin_recv(soap)</div><div class="line"> ...</div><div class="line">soap->is = NULL;</div><div class="line">soap_destroy(soap); <span class="comment">// cleanup</span></div><div class="line">soap_end(soap); <span class="comment">// cleanup</span></div></div><!-- fragment --><p>Note that the encrypted secret key can be sent in the clear or stored openly, since only the recipient/reader will be able to decode it (with its private key) and use it for message decryption.</p> <p>Symmetric encryption and decryption can be used if both parties can safely share a secret symmetric key that no other party has access to. We use SOAP_MEC_ENC_DES_CBC for encryption and SOAP_MEC_DEC_DES_CBC for decryption using a 160-bit triple DES key. You can also use AES128, AES192, AES256 ciphers.</p> <p>Here is an example to encrypt a message using a shared secret key while streaming it to the output.</p> <div class="fragment"><div class="line"><span class="preprocessor">#include "<a class="code" href="mecevp_8h.html">mecevp.h</a>"</span></div><div class="line"><a class="code" href="structsoap__mec__data.html">soap_mec_data</a> mec;</div><div class="line">ns__Object object;</div><div class="line"><span class="keywordtype">int</span> alg = <a class="code" href="mecevp_8h.html#ae8f63ce4ee6492f0b07949d301eda7d6">SOAP_MEC_ENC_DES_CBC</a>;</div><div class="line"><span class="keywordtype">unsigned</span> <span class="keywordtype">char</span> key[20] = { ... }; <span class="comment">// shared secret triple DES key</span></div><div class="line"><span class="keywordtype">int</span> keylen = 20;</div><div class="line"><span class="keywordflow">if</span> (soap_begin_send(soap)</div><div class="line"> || <a class="code" href="mecevp_8h.html#abd9dd5e6e38fb46977f5c75aa89f4104">soap_mec_begin</a>(soap, &mec, alg, NULL, key, &keylen)</div><div class="line"> || <a class="code" href="mecevp_8h.html#a8053a2c0cda70dd37b944408dd3f8f0e">soap_mec_start</a>(soap, NULL)</div><div class="line"> || soap_out_ns__Object(soap, <span class="stringliteral">"ns:Object"</span>, 0, &<span class="keywordtype">object</span>, NULL)</div><div class="line"> || <a class="code" href="mecevp_8h.html#a8fdc3daea4e2c9c3bbde4e480209b0d0">soap_mec_stop</a>(soap)</div><div class="line"> || <a class="code" href="mecevp_8h.html#ae93d7dae06e1568cc6ee2420cd29faaf">soap_mec_end</a>(soap, &mec)</div><div class="line"> || soap_end_send(soap))</div><div class="line">{</div><div class="line"> <a class="code" href="mecevp_8h.html#aaa1e6fa1abac32acdd7f76232fa30241">soap_mec_cleanup</a>(soap, &mec); <span class="comment">// clean up when error</span></div><div class="line"> soap_print_fault(soap, stderr);</div><div class="line">}</div></div><!-- fragment --><p>The decryption by the recipient/reader requires the same shared secret key to decrypt the message using envelope decryption with SOAP_MEC_DEC_DES_CBC. This key is secret and unencrypted, so it should never be shared with any other party besides the sender/writer and recipient/reader.</p> <div class="fragment"><div class="line"><span class="preprocessor">#include "<a class="code" href="mecevp_8h.html">mecevp.h</a>"</span></div><div class="line"><a class="code" href="structsoap__mec__data.html">soap_mec_data</a> mec;</div><div class="line">ns__Object object;</div><div class="line"><span class="keywordtype">int</span> alg = <a class="code" href="mecevp_8h.html#a9226364c4bf1cd277c417cd4d2706561">SOAP_MEC_DEC_DES_CBC</a>;</div><div class="line"><span class="keywordtype">unsigned</span> <span class="keywordtype">char</span> key[20] = { ... }; <span class="comment">// shared secret triple DES key</span></div><div class="line"><span class="keywordtype">int</span> keylen = 20;</div><div class="line"><span class="keywordflow">if</span> (soap_begin_recv(soap)</div><div class="line"> || <a class="code" href="mecevp_8h.html#abd9dd5e6e38fb46977f5c75aa89f4104">soap_mec_begin</a>(soap, &mec, alg, NULL, key, &keylen)</div><div class="line"> || <a class="code" href="mecevp_8h.html#a8053a2c0cda70dd37b944408dd3f8f0e">soap_mec_start</a>(soap)</div><div class="line"> || soap_in_ns__Object(soap, <span class="stringliteral">"ns:Object"</span>, &<span class="keywordtype">object</span>, NULL) == NULL</div><div class="line"> || <a class="code" href="mecevp_8h.html#a8fdc3daea4e2c9c3bbde4e480209b0d0">soap_mec_stop</a>(soap)</div><div class="line"> || <a class="code" href="mecevp_8h.html#ae93d7dae06e1568cc6ee2420cd29faaf">soap_mec_end</a>(soap, &mec)</div><div class="line"> || soap_end_recv(soap))</div><div class="line">{</div><div class="line"> <a class="code" href="mecevp_8h.html#aaa1e6fa1abac32acdd7f76232fa30241">soap_mec_cleanup</a>(soap, &mec); <span class="comment">// clean up when error</span></div><div class="line"> soap_print_fault(soap, stderr);</div><div class="line">}</div></div><!-- fragment --><dl class="section note"><dt>Note</dt><dd>The mecevp engine uses callbacks of the gSOAP engine that were introduced in version 2.8.1. Earlier gSOAP version releases are not compatible with the mecevp plugin and engine. </dd></dl> </div></div><!-- contents --> <hr class="footer"> <address class="footer"> Copyright (C) 2018, Robert van Engelen, Genivia Inc., All Rights Reserved. </address> <address class="footer"><small> Converted on Mon May 14 2018 21:30:25 by <a target="_blank" href="http://www.doxygen.org/index.html">Doxygen</a> 1.8.11</small></address> <br> <div style="height: 246px; background: #DBDBDB;"> </body> </html>