1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81
|
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
<meta http-equiv="X-UA-Compatible" content="IE=9"/>
<title>WiredTiger: rotn_encrypt.c</title>
<link href="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="navtree.css" rel="stylesheet" type="text/css"/>
<script type="text/javascript" src="resize.js"></script>
<script type="text/javascript" src="navtreedata.js"></script>
<script type="text/javascript" src="navtree.js"></script>
<script type="text/javascript">
$(document).ready(initResizable);
</script>
<link href="doxygen.css" rel="stylesheet" type="text/css" />
<link href="wiredtiger.css" rel="stylesheet" type="text/css"/>
</head>
<body>
<div id="top"><!-- do not remove this div, it is closed by doxygen! -->
<div id="titlearea">
<table cellspacing="0" cellpadding="0">
<tbody>
<tr style="height: 56px;">
<td id="projectlogo"><a href="http://wiredtiger.com/"><img alt="Logo" src="LogoFinal-header.png" alt="WiredTiger" /></a></td>
<td style="padding-left: 0.5em;">
<div id="projectname">
 <span id="projectnumber">Version 3.2.1</span>
</div>
<div id="projectbrief"><!-- 3.2.1 --></div>
</td>
</tr>
</tbody>
</table>
</div>
<div class="banner">
<a href="https://github.com/wiredtiger/wiredtiger">Fork me on GitHub</a>
<a class="last" href="http://groups.google.com/group/wiredtiger-users">Join my user group</a>
</div>
<!-- end header part -->
<!-- Generated by Doxygen 1.8.13 -->
<script type="text/javascript" src="menudata.js"></script>
<script type="text/javascript" src="menu.js"></script>
<script type="text/javascript">
$(function() {
initMenu('',false,false,'search.php','Search');
});
</script>
<div id="main-nav"></div>
</div><!-- top -->
<div id="side-nav" class="ui-resizable side-nav-resizable">
<div id="nav-tree">
<div id="nav-tree-contents">
<div id="nav-sync" class="sync"></div>
</div>
</div>
<div id="splitbar" style="-moz-user-select:none;"
class="ui-resizable-handle">
</div>
</div>
<script type="text/javascript">
$(document).ready(function(){initNavTree('rotn_encrypt_8c-example.html','');});
</script>
<div id="doc-content">
<div class="header">
<div class="headertitle">
<div class="title">rotn_encrypt.c</div> </div>
</div><!--header-->
<div class="contents">
<p>Shows a simple encryptor as a plug in library.</p>
<div class="fragment"><div class="line"><span class="comment">/*-</span></div><div class="line"><span class="comment"> * Public Domain 2014-2019 MongoDB, Inc.</span></div><div class="line"><span class="comment"> * Public Domain 2008-2014 WiredTiger, Inc.</span></div><div class="line"><span class="comment"> *</span></div><div class="line"><span class="comment"> * This is free and unencumbered software released into the public domain.</span></div><div class="line"><span class="comment"> *</span></div><div class="line"><span class="comment"> * Anyone is free to copy, modify, publish, use, compile, sell, or</span></div><div class="line"><span class="comment"> * distribute this software, either in source code form or as a compiled</span></div><div class="line"><span class="comment"> * binary, for any purpose, commercial or non-commercial, and by any</span></div><div class="line"><span class="comment"> * means.</span></div><div class="line"><span class="comment"> *</span></div><div class="line"><span class="comment"> * In jurisdictions that recognize copyright laws, the author or authors</span></div><div class="line"><span class="comment"> * of this software dedicate any and all copyright interest in the</span></div><div class="line"><span class="comment"> * software to the public domain. We make this dedication for the benefit</span></div><div class="line"><span class="comment"> * of the public at large and to the detriment of our heirs and</span></div><div class="line"><span class="comment"> * successors. We intend this dedication to be an overt act of</span></div><div class="line"><span class="comment"> * relinquishment in perpetuity of all present and future rights to this</span></div><div class="line"><span class="comment"> * software under copyright law.</span></div><div class="line"><span class="comment"> *</span></div><div class="line"><span class="comment"> * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,</span></div><div class="line"><span class="comment"> * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF</span></div><div class="line"><span class="comment"> * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.</span></div><div class="line"><span class="comment"> * IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR</span></div><div class="line"><span class="comment"> * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,</span></div><div class="line"><span class="comment"> * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR</span></div><div class="line"><span class="comment"> * OTHER DEALINGS IN THE SOFTWARE.</span></div><div class="line"><span class="comment"> */</span></div><div class="line"></div><div class="line"><span class="preprocessor">#include <errno.h></span></div><div class="line"><span class="preprocessor">#include <stdlib.h></span></div><div class="line"><span class="preprocessor">#include <string.h></span></div><div class="line"></div><div class="line"><span class="preprocessor">#include <wiredtiger.h></span></div><div class="line"><span class="preprocessor">#include <wiredtiger_ext.h></span></div><div class="line"></div><div class="line"><span class="comment">/*</span></div><div class="line"><span class="comment"> * This encryptor is used for testing and demonstration only.</span></div><div class="line"><span class="comment"> *</span></div><div class="line"><span class="comment"> * IT IS TRIVIAL TO BREAK AND DOES NOT OFFER ANY SECURITY!</span></div><div class="line"><span class="comment"> *</span></div><div class="line"><span class="comment"> * There are two configuration parameters that control it: the keyid and the</span></div><div class="line"><span class="comment"> * secretkey (which may be thought of as a password). The keyid is expected</span></div><div class="line"><span class="comment"> * to be a digits giving a number between 0 and 25. The secretkey, when</span></div><div class="line"><span class="comment"> * present, must be composed of alphabetic characters.</span></div><div class="line"><span class="comment"> *</span></div><div class="line"><span class="comment"> * When there is no secretkey, the encryptor acts as a ROT(N) encryptor (a</span></div><div class="line"><span class="comment"> * "Caesar cipher"), where N is the value of keyid. Thus, with keyid=13,</span></div><div class="line"><span class="comment"> * text "Hello" maps to "Uryyb", as we preserve case. Only the alphabetic</span></div><div class="line"><span class="comment"> * characters in the input text are changed.</span></div><div class="line"><span class="comment"> *</span></div><div class="line"><span class="comment"> * When there is a secretkey we are implementing a Vigenere cipher.</span></div><div class="line"><span class="comment"> * Each byte is rotated the distance from 'A' for each letter in the</span></div><div class="line"><span class="comment"> * (repeating) secretkey. The distance is increased by the value of</span></div><div class="line"><span class="comment"> * the keyid. Thus, with secretkey "ABC" and keyid "2", we show how</span></div><div class="line"><span class="comment"> * we map the input "MySecret".</span></div><div class="line"><span class="comment"> * secretkey = ABC</span></div><div class="line"><span class="comment"> * distances from 'A' = 012</span></div><div class="line"><span class="comment"> * add keyid (2) = 234</span></div><div class="line"><span class="comment"> * repeated = 23423423</span></div><div class="line"><span class="comment"> * input = MySecret</span></div><div class="line"><span class="comment"> * output = ObWgfvgw</span></div><div class="line"><span class="comment"> * In this case, we transform all bytes in the input.</span></div><div class="line"><span class="comment"> */</span></div><div class="line"></div><div class="line"><span class="comment">/* Local encryptor structure. */</span></div><div class="line"><span class="keyword">typedef</span> <span class="keyword">struct </span>{</div><div class="line"> <a name="_a0"></a><a class="code" href="struct_w_t___e_n_c_r_y_p_t_o_r.html">WT_ENCRYPTOR</a> encryptor; <span class="comment">/* Must come first */</span></div><div class="line"></div><div class="line"> <a name="_a1"></a><a class="code" href="struct_w_t___e_x_t_e_n_s_i_o_n___a_p_i.html">WT_EXTENSION_API</a> *wt_api; <span class="comment">/* Extension API */</span></div><div class="line"></div><div class="line"> <span class="keywordtype">int</span> rot_N; <span class="comment">/* rotN value */</span></div><div class="line"> <span class="keywordtype">char</span> *keyid; <span class="comment">/* Saved keyid */</span></div><div class="line"> <span class="keywordtype">char</span> *secretkey; <span class="comment">/* Saved secretkey */</span></div><div class="line"> u_char *shift_forw; <span class="comment">/* Encrypt shift data from secretkey */</span></div><div class="line"> u_char *shift_back; <span class="comment">/* Decrypt shift data from secretkey */</span></div><div class="line"> <span class="keywordtype">size_t</span> shift_len; <span class="comment">/* Length of shift* byte arrays */</span></div><div class="line"> <span class="keywordtype">bool</span> force_error; <span class="comment">/* Force a decrypt error for testing */</span></div><div class="line"></div><div class="line">} ROTN_ENCRYPTOR;</div><div class="line"><span class="preprocessor">#define CHKSUM_LEN 4</span></div><div class="line"><span class="preprocessor">#define IV_LEN 16</span></div><div class="line"></div><div class="line"><span class="comment">/*</span></div><div class="line"><span class="comment"> * rotn_error --</span></div><div class="line"><span class="comment"> * Display an error from this module in a standard way.</span></div><div class="line"><span class="comment"> */</span></div><div class="line"><span class="keyword">static</span> <span class="keywordtype">int</span></div><div class="line">rotn_error(ROTN_ENCRYPTOR *encryptor, <a name="_a2"></a><a class="code" href="struct_w_t___s_e_s_s_i_o_n.html">WT_SESSION</a> *session, <span class="keywordtype">int</span> err, <span class="keyword">const</span> <span class="keywordtype">char</span> *msg)</div><div class="line">{</div><div class="line"> <a class="code" href="struct_w_t___e_x_t_e_n_s_i_o_n___a_p_i.html">WT_EXTENSION_API</a> *wt_api;</div><div class="line"></div><div class="line"> wt_api = encryptor->wt_api;</div><div class="line"> (void)wt_api-><a name="a3"></a><a class="code" href="struct_w_t___e_x_t_e_n_s_i_o_n___a_p_i.html#a6d58298e356dbf58ac854c3d1af99678">err_printf</a>(</div><div class="line"> wt_api, session, <span class="stringliteral">"rotn encryption: %s: %s"</span>, msg, wt_api-><a name="a4"></a><a class="code" href="struct_w_t___e_x_t_e_n_s_i_o_n___a_p_i.html#a3fd4b5255e2f82139a846d66d67be565">strerror</a>(wt_api, NULL, err));</div><div class="line"> <span class="keywordflow">return</span> (err);</div><div class="line">}</div><div class="line"></div><div class="line"><span class="comment">/*</span></div><div class="line"><span class="comment"> * make_checksum --</span></div><div class="line"><span class="comment"> * This is where one would call a checksum function on the encrypted buffer. Here we just put a</span></div><div class="line"><span class="comment"> * constant value in it.</span></div><div class="line"><span class="comment"> */</span></div><div class="line"><span class="keyword">static</span> <span class="keywordtype">void</span></div><div class="line">make_checksum(uint8_t *dst)</div><div class="line">{</div><div class="line"> <span class="keywordtype">int</span> i;</div><div class="line"> <span class="comment">/*</span></div><div class="line"><span class="comment"> * Assume array is big enough for the checksum.</span></div><div class="line"><span class="comment"> */</span></div><div class="line"> <span class="keywordflow">for</span> (i = 0; i < CHKSUM_LEN; i++)</div><div class="line"> dst[i] = <span class="charliteral">'C'</span>;</div><div class="line">}</div><div class="line"></div><div class="line"><span class="comment">/*</span></div><div class="line"><span class="comment"> * make_iv --</span></div><div class="line"><span class="comment"> * This is where one would generate the initialization vector. Here we just put a constant value</span></div><div class="line"><span class="comment"> * in it.</span></div><div class="line"><span class="comment"> */</span></div><div class="line"><span class="keyword">static</span> <span class="keywordtype">void</span></div><div class="line">make_iv(uint8_t *dst)</div><div class="line">{</div><div class="line"> <span class="keywordtype">int</span> i;</div><div class="line"> <span class="comment">/*</span></div><div class="line"><span class="comment"> * Assume array is big enough for the initialization vector.</span></div><div class="line"><span class="comment"> */</span></div><div class="line"> <span class="keywordflow">for</span> (i = 0; i < IV_LEN; i++)</div><div class="line"> dst[i] = <span class="charliteral">'I'</span>;</div><div class="line">}</div><div class="line"></div><div class="line"><span class="comment">/*</span></div><div class="line"><span class="comment"> * Rotate encryption functions.</span></div><div class="line"><span class="comment"> */</span></div><div class="line"><span class="comment">/*</span></div><div class="line"><span class="comment"> * do_rotate --</span></div><div class="line"><span class="comment"> * Perform rot-N on the buffer given.</span></div><div class="line"><span class="comment"> */</span></div><div class="line"><span class="keyword">static</span> <span class="keywordtype">void</span></div><div class="line">do_rotate(<span class="keywordtype">char</span> *buf, <span class="keywordtype">size_t</span> len, <span class="keywordtype">int</span> rotn)</div><div class="line">{</div><div class="line"> uint32_t i;</div><div class="line"> <span class="comment">/*</span></div><div class="line"><span class="comment"> * Now rotate.</span></div><div class="line"><span class="comment"> *</span></div><div class="line"><span class="comment"> * Avoid ctype functions because they behave in unexpected ways,</span></div><div class="line"><span class="comment"> * particularly when the locale is not "C".</span></div><div class="line"><span class="comment"> */</span></div><div class="line"> <span class="keywordflow">for</span> (i = 0; i < len; i++) {</div><div class="line"> <span class="keywordflow">if</span> (<span class="charliteral">'a'</span> <= buf[i] && buf[i] <= <span class="charliteral">'z'</span>)</div><div class="line"> buf[i] = ((buf[i] - <span class="charliteral">'a'</span>) + rotn) % 26 + <span class="charliteral">'a'</span>;</div><div class="line"> <span class="keywordflow">else</span> <span class="keywordflow">if</span> (<span class="charliteral">'A'</span> <= buf[i] && buf[i] <= <span class="charliteral">'Z'</span>)</div><div class="line"> buf[i] = ((buf[i] - <span class="charliteral">'A'</span>) + rotn) % 26 + <span class="charliteral">'A'</span>;</div><div class="line"> }</div><div class="line">}</div><div class="line"></div><div class="line"><span class="comment">/*</span></div><div class="line"><span class="comment"> * do_shift --</span></div><div class="line"><span class="comment"> * Perform a Vigenere cipher</span></div><div class="line"><span class="comment"> */</span></div><div class="line"><span class="keyword">static</span> <span class="keywordtype">void</span></div><div class="line">do_shift(uint8_t *buf, <span class="keywordtype">size_t</span> len, u_char *shift, <span class="keywordtype">size_t</span> shiftlen)</div><div class="line">{</div><div class="line"> uint32_t i;</div><div class="line"> <span class="comment">/*</span></div><div class="line"><span class="comment"> * Now shift.</span></div><div class="line"><span class="comment"> */</span></div><div class="line"> <span class="keywordflow">for</span> (i = 0; i < len; i++)</div><div class="line"> buf[i] += shift[i % shiftlen];</div><div class="line">}</div><div class="line"></div><div class="line"><span class="comment">/*</span></div><div class="line"><span class="comment"> * rotn_encrypt --</span></div><div class="line"><span class="comment"> * A simple encryption example that passes data through unchanged.</span></div><div class="line"><span class="comment"> */</span></div><div class="line"><span class="keyword">static</span> <span class="keywordtype">int</span></div><div class="line">rotn_encrypt(<a class="code" href="struct_w_t___e_n_c_r_y_p_t_o_r.html">WT_ENCRYPTOR</a> *encryptor, <a class="code" href="struct_w_t___s_e_s_s_i_o_n.html">WT_SESSION</a> *session, uint8_t *src, <span class="keywordtype">size_t</span> src_len,</div><div class="line"> uint8_t *dst, <span class="keywordtype">size_t</span> dst_len, <span class="keywordtype">size_t</span> *result_lenp)</div><div class="line">{</div><div class="line"> ROTN_ENCRYPTOR *rotn_encryptor = (ROTN_ENCRYPTOR *)encryptor;</div><div class="line"> uint32_t i;</div><div class="line"></div><div class="line"> (void)session; <span class="comment">/* Unused */</span></div><div class="line"></div><div class="line"> <span class="keywordflow">if</span> (dst_len < src_len + CHKSUM_LEN + IV_LEN)</div><div class="line"> <span class="keywordflow">return</span> (rotn_error(rotn_encryptor, session, ENOMEM, <span class="stringliteral">"encrypt buffer not big enough"</span>));</div><div class="line"></div><div class="line"> <span class="comment">/*</span></div><div class="line"><span class="comment"> * !!! Most implementations would verify any needed</span></div><div class="line"><span class="comment"> * checksum and initialize the IV here.</span></div><div class="line"><span class="comment"> */</span></div><div class="line"> i = CHKSUM_LEN + IV_LEN;</div><div class="line"> memcpy(&dst[i], &src[0], src_len);</div><div class="line"> <span class="comment">/*</span></div><div class="line"><span class="comment"> * Depending on whether we have a secret key or not, call the common rotate or shift function on</span></div><div class="line"><span class="comment"> * the text portion of the destination buffer. Send in src_len as the length of the text.</span></div><div class="line"><span class="comment"> */</span></div><div class="line"> <span class="keywordflow">if</span> (rotn_encryptor->shift_len == 0)</div><div class="line"> do_rotate((<span class="keywordtype">char</span> *)dst + i, src_len, rotn_encryptor->rot_N);</div><div class="line"> <span class="keywordflow">else</span></div><div class="line"> do_shift(&dst[i], src_len, rotn_encryptor->shift_forw, rotn_encryptor->shift_len);</div><div class="line"> <span class="comment">/*</span></div><div class="line"><span class="comment"> * Checksum the encrypted buffer and add the IV.</span></div><div class="line"><span class="comment"> */</span></div><div class="line"> i = 0;</div><div class="line"> make_checksum(&dst[i]);</div><div class="line"> i += CHKSUM_LEN;</div><div class="line"> make_iv(&dst[i]);</div><div class="line"> *result_lenp = dst_len;</div><div class="line"> <span class="keywordflow">return</span> (0);</div><div class="line">}</div><div class="line"><span class="comment">/*</span></div><div class="line"><span class="comment"> * rotn_decrypt --</span></div><div class="line"><span class="comment"> * A simple decryption example that passes data through unchanged.</span></div><div class="line"><span class="comment"> */</span></div><div class="line"><span class="keyword">static</span> <span class="keywordtype">int</span></div><div class="line">rotn_decrypt(<a class="code" href="struct_w_t___e_n_c_r_y_p_t_o_r.html">WT_ENCRYPTOR</a> *encryptor, <a class="code" href="struct_w_t___s_e_s_s_i_o_n.html">WT_SESSION</a> *session, uint8_t *src, <span class="keywordtype">size_t</span> src_len,</div><div class="line"> uint8_t *dst, <span class="keywordtype">size_t</span> dst_len, <span class="keywordtype">size_t</span> *result_lenp)</div><div class="line">{</div><div class="line"> ROTN_ENCRYPTOR *rotn_encryptor = (ROTN_ENCRYPTOR *)encryptor;</div><div class="line"> <span class="keywordtype">size_t</span> mylen;</div><div class="line"> uint32_t i;</div><div class="line"></div><div class="line"> (void)session; <span class="comment">/* Unused */</span></div><div class="line"></div><div class="line"> <span class="comment">/*</span></div><div class="line"><span class="comment"> * For certain tests, force an error we can recognize.</span></div><div class="line"><span class="comment"> */</span></div><div class="line"> <span class="keywordflow">if</span> (rotn_encryptor->force_error)</div><div class="line"> <span class="keywordflow">return</span> (-1000);</div><div class="line"></div><div class="line"> <span class="comment">/*</span></div><div class="line"><span class="comment"> * Make sure it is big enough.</span></div><div class="line"><span class="comment"> */</span></div><div class="line"> mylen = src_len - (CHKSUM_LEN + IV_LEN);</div><div class="line"> <span class="keywordflow">if</span> (dst_len < mylen)</div><div class="line"> <span class="keywordflow">return</span> (rotn_error(rotn_encryptor, session, ENOMEM, <span class="stringliteral">"decrypt buffer not big enough"</span>));</div><div class="line"></div><div class="line"> <span class="comment">/*</span></div><div class="line"><span class="comment"> * !!! Most implementations would verify the checksum here.</span></div><div class="line"><span class="comment"> */</span></div><div class="line"> <span class="comment">/*</span></div><div class="line"><span class="comment"> * Copy the encrypted data to the destination buffer and then decrypt the destination buffer.</span></div><div class="line"><span class="comment"> */</span></div><div class="line"> i = CHKSUM_LEN + IV_LEN;</div><div class="line"> memcpy(&dst[0], &src[i], mylen);</div><div class="line"> <span class="comment">/*</span></div><div class="line"><span class="comment"> * Depending on whether we have a secret key or not, call the common rotate or shift function on</span></div><div class="line"><span class="comment"> * the text portion of the destination buffer. Send in dst_len as the length of the text.</span></div><div class="line"><span class="comment"> */</span></div><div class="line"> <span class="comment">/*</span></div><div class="line"><span class="comment"> * !!! Most implementations would need the IV too.</span></div><div class="line"><span class="comment"> */</span></div><div class="line"> <span class="keywordflow">if</span> (rotn_encryptor->shift_len == 0)</div><div class="line"> do_rotate((<span class="keywordtype">char</span> *)dst, mylen, 26 - rotn_encryptor->rot_N);</div><div class="line"> <span class="keywordflow">else</span></div><div class="line"> do_shift(&dst[0], mylen, rotn_encryptor->shift_back, rotn_encryptor->shift_len);</div><div class="line"> *result_lenp = mylen;</div><div class="line"> <span class="keywordflow">return</span> (0);</div><div class="line">}</div><div class="line"><span class="comment">/*</span></div><div class="line"><span class="comment"> * rotn_sizing --</span></div><div class="line"><span class="comment"> * A sizing example that returns the header size needed.</span></div><div class="line"><span class="comment"> */</span></div><div class="line"><span class="keyword">static</span> <span class="keywordtype">int</span></div><div class="line">rotn_sizing(<a class="code" href="struct_w_t___e_n_c_r_y_p_t_o_r.html">WT_ENCRYPTOR</a> *encryptor, <a class="code" href="struct_w_t___s_e_s_s_i_o_n.html">WT_SESSION</a> *session, <span class="keywordtype">size_t</span> *expansion_constantp)</div><div class="line">{</div><div class="line"> (void)encryptor; <span class="comment">/* Unused parameters */</span></div><div class="line"> (void)session; <span class="comment">/* Unused parameters */</span></div><div class="line"></div><div class="line"> *expansion_constantp = CHKSUM_LEN + IV_LEN;</div><div class="line"> <span class="keywordflow">return</span> (0);</div><div class="line">}</div><div class="line"><span class="comment">/*</span></div><div class="line"><span class="comment"> * rotn_customize --</span></div><div class="line"><span class="comment"> * The customize function creates a customized encryptor</span></div><div class="line"><span class="comment"> */</span></div><div class="line"><span class="keyword">static</span> <span class="keywordtype">int</span></div><div class="line">rotn_customize(<a class="code" href="struct_w_t___e_n_c_r_y_p_t_o_r.html">WT_ENCRYPTOR</a> *encryptor, <a class="code" href="struct_w_t___s_e_s_s_i_o_n.html">WT_SESSION</a> *session, <a class="code" href="group__wt__ext.html#ga6fa5797cf581d18dc843e07333a497e4">WT_CONFIG_ARG</a> *encrypt_config,</div><div class="line"> <a class="code" href="struct_w_t___e_n_c_r_y_p_t_o_r.html">WT_ENCRYPTOR</a> **customp)</div><div class="line">{</div><div class="line"> <span class="keyword">const</span> ROTN_ENCRYPTOR *orig;</div><div class="line"> ROTN_ENCRYPTOR *rotn_encryptor;</div><div class="line"> <a name="_a5"></a><a class="code" href="struct_w_t___c_o_n_f_i_g___i_t_e_m.html">WT_CONFIG_ITEM</a> keyid, secret;</div><div class="line"> <a class="code" href="struct_w_t___e_x_t_e_n_s_i_o_n___a_p_i.html">WT_EXTENSION_API</a> *wt_api;</div><div class="line"> <span class="keywordtype">size_t</span> i, len;</div><div class="line"> <span class="keywordtype">int</span> ret, keyid_val;</div><div class="line"> u_char base;</div><div class="line"></div><div class="line"> ret = 0;</div><div class="line"> keyid_val = 0;</div><div class="line"></div><div class="line"> orig = (<span class="keyword">const</span> ROTN_ENCRYPTOR *)encryptor;</div><div class="line"> wt_api = orig->wt_api;</div><div class="line"></div><div class="line"> <span class="keywordflow">if</span> ((rotn_encryptor = calloc(1, <span class="keyword">sizeof</span>(ROTN_ENCRYPTOR))) == NULL)</div><div class="line"> <span class="keywordflow">return</span> (errno);</div><div class="line"> *rotn_encryptor = *orig;</div><div class="line"> rotn_encryptor->keyid = rotn_encryptor->secretkey = NULL;</div><div class="line"></div><div class="line"> <span class="comment">/*</span></div><div class="line"><span class="comment"> * Stash the keyid from the configuration string.</span></div><div class="line"><span class="comment"> */</span></div><div class="line"> <span class="keywordflow">if</span> ((ret = wt_api-><a name="a6"></a><a class="code" href="struct_w_t___e_x_t_e_n_s_i_o_n___a_p_i.html#a0d3aae2ceac28f7b45188bcfa4306d45">config_get</a>(wt_api, session, encrypt_config, <span class="stringliteral">"keyid"</span>, &keyid)) == 0 &&</div><div class="line"> keyid.<a name="a7"></a><a class="code" href="struct_w_t___c_o_n_f_i_g___i_t_e_m.html#adff0f6e5a3f781f0228015e8336f1a14">len</a> != 0) {</div><div class="line"> <span class="comment">/*</span></div><div class="line"><span class="comment"> * In this demonstration, we expect keyid to be a number.</span></div><div class="line"><span class="comment"> */</span></div><div class="line"> <span class="keywordflow">if</span> ((keyid_val = atoi(keyid.<a name="a8"></a><a class="code" href="struct_w_t___c_o_n_f_i_g___i_t_e_m.html#aa0ce7d30a32600e16824966c638ee45f">str</a>)) < 0) {</div><div class="line"> ret = rotn_error(rotn_encryptor, NULL, EINVAL, <span class="stringliteral">"rotn_customize: invalid keyid"</span>);</div><div class="line"> <span class="keywordflow">goto</span> err;</div><div class="line"> }</div><div class="line"> <span class="keywordflow">if</span> ((rotn_encryptor->keyid = malloc(keyid.<a class="code" href="struct_w_t___c_o_n_f_i_g___i_t_e_m.html#adff0f6e5a3f781f0228015e8336f1a14">len</a> + 1)) == NULL) {</div><div class="line"> ret = errno;</div><div class="line"> <span class="keywordflow">goto</span> err;</div><div class="line"> }</div><div class="line"> strncpy(rotn_encryptor->keyid, keyid.<a class="code" href="struct_w_t___c_o_n_f_i_g___i_t_e_m.html#aa0ce7d30a32600e16824966c638ee45f">str</a>, keyid.<a class="code" href="struct_w_t___c_o_n_f_i_g___i_t_e_m.html#adff0f6e5a3f781f0228015e8336f1a14">len</a> + 1);</div><div class="line"> rotn_encryptor->keyid[keyid.<a class="code" href="struct_w_t___c_o_n_f_i_g___i_t_e_m.html#adff0f6e5a3f781f0228015e8336f1a14">len</a>] = <span class="charliteral">'\0'</span>;</div><div class="line"> }</div><div class="line"></div><div class="line"> <span class="comment">/*</span></div><div class="line"><span class="comment"> * In this demonstration, the secret key must be alphabetic characters. We stash the secret key</span></div><div class="line"><span class="comment"> * from the configuration string and build some shift bytes to make encryption/decryption easy.</span></div><div class="line"><span class="comment"> */</span></div><div class="line"> <span class="keywordflow">if</span> ((ret = wt_api-><a class="code" href="struct_w_t___e_x_t_e_n_s_i_o_n___a_p_i.html#a0d3aae2ceac28f7b45188bcfa4306d45">config_get</a>(wt_api, session, encrypt_config, <span class="stringliteral">"secretkey"</span>, &secret)) == 0 &&</div><div class="line"> secret.<a class="code" href="struct_w_t___c_o_n_f_i_g___i_t_e_m.html#adff0f6e5a3f781f0228015e8336f1a14">len</a> != 0) {</div><div class="line"> len = secret.<a class="code" href="struct_w_t___c_o_n_f_i_g___i_t_e_m.html#adff0f6e5a3f781f0228015e8336f1a14">len</a>;</div><div class="line"> <span class="keywordflow">if</span> ((rotn_encryptor->secretkey = malloc(len + 1)) == NULL ||</div><div class="line"> (rotn_encryptor->shift_forw = malloc(len)) == NULL ||</div><div class="line"> (rotn_encryptor->shift_back = malloc(len)) == NULL) {</div><div class="line"> ret = errno;</div><div class="line"> <span class="keywordflow">goto</span> err;</div><div class="line"> }</div><div class="line"> <span class="keywordflow">for</span> (i = 0; i < len; i++) {</div><div class="line"> <span class="keywordflow">if</span> (<span class="charliteral">'a'</span> <= secret.<a class="code" href="struct_w_t___c_o_n_f_i_g___i_t_e_m.html#aa0ce7d30a32600e16824966c638ee45f">str</a>[i] && secret.<a class="code" href="struct_w_t___c_o_n_f_i_g___i_t_e_m.html#aa0ce7d30a32600e16824966c638ee45f">str</a>[i] <= <span class="charliteral">'z'</span>)</div><div class="line"> base = <span class="charliteral">'a'</span>;</div><div class="line"> <span class="keywordflow">else</span> <span class="keywordflow">if</span> (<span class="charliteral">'A'</span> <= secret.<a class="code" href="struct_w_t___c_o_n_f_i_g___i_t_e_m.html#aa0ce7d30a32600e16824966c638ee45f">str</a>[i] && secret.<a class="code" href="struct_w_t___c_o_n_f_i_g___i_t_e_m.html#aa0ce7d30a32600e16824966c638ee45f">str</a>[i] <= <span class="charliteral">'Z'</span>)</div><div class="line"> base = <span class="charliteral">'A'</span>;</div><div class="line"> <span class="keywordflow">else</span> {</div><div class="line"> ret = rotn_error(rotn_encryptor, NULL, EINVAL, <span class="stringliteral">"rotn_customize: invalid key"</span>);</div><div class="line"> <span class="keywordflow">goto</span> err;</div><div class="line"> }</div><div class="line"> base -= (u_char)keyid_val;</div><div class="line"> rotn_encryptor->shift_forw[i] = (u_char)secret.<a class="code" href="struct_w_t___c_o_n_f_i_g___i_t_e_m.html#aa0ce7d30a32600e16824966c638ee45f">str</a>[i] - base;</div><div class="line"> rotn_encryptor->shift_back[i] = base - (u_char)secret.<a class="code" href="struct_w_t___c_o_n_f_i_g___i_t_e_m.html#aa0ce7d30a32600e16824966c638ee45f">str</a>[i];</div><div class="line"> }</div><div class="line"> rotn_encryptor->shift_len = len;</div><div class="line"> strncpy(rotn_encryptor->secretkey, secret.<a class="code" href="struct_w_t___c_o_n_f_i_g___i_t_e_m.html#aa0ce7d30a32600e16824966c638ee45f">str</a>, secret.<a class="code" href="struct_w_t___c_o_n_f_i_g___i_t_e_m.html#adff0f6e5a3f781f0228015e8336f1a14">len</a> + 1);</div><div class="line"> rotn_encryptor->secretkey[secret.<a class="code" href="struct_w_t___c_o_n_f_i_g___i_t_e_m.html#adff0f6e5a3f781f0228015e8336f1a14">len</a>] = <span class="charliteral">'\0'</span>;</div><div class="line"> }</div><div class="line"></div><div class="line"> <span class="comment">/*</span></div><div class="line"><span class="comment"> * In a real encryptor, we could use some sophisticated key management here to map the keyid</span></div><div class="line"><span class="comment"> * onto a secret key.</span></div><div class="line"><span class="comment"> */</span></div><div class="line"> rotn_encryptor->rot_N = keyid_val;</div><div class="line"></div><div class="line"> *customp = (<a class="code" href="struct_w_t___e_n_c_r_y_p_t_o_r.html">WT_ENCRYPTOR</a> *)rotn_encryptor;</div><div class="line"> <span class="keywordflow">return</span> (0);</div><div class="line"></div><div class="line">err:</div><div class="line"> free(rotn_encryptor->keyid);</div><div class="line"> free(rotn_encryptor->secretkey);</div><div class="line"> free(rotn_encryptor->shift_forw);</div><div class="line"> free(rotn_encryptor->shift_back);</div><div class="line"> free(rotn_encryptor);</div><div class="line"> <span class="keywordflow">return</span> (ret);</div><div class="line">}</div><div class="line"><span class="comment">/*</span></div><div class="line"><span class="comment"> * rotn_terminate --</span></div><div class="line"><span class="comment"> * WiredTiger no-op encryption termination.</span></div><div class="line"><span class="comment"> */</span></div><div class="line"><span class="keyword">static</span> <span class="keywordtype">int</span></div><div class="line">rotn_terminate(<a class="code" href="struct_w_t___e_n_c_r_y_p_t_o_r.html">WT_ENCRYPTOR</a> *encryptor, <a class="code" href="struct_w_t___s_e_s_s_i_o_n.html">WT_SESSION</a> *session)</div><div class="line">{</div><div class="line"> ROTN_ENCRYPTOR *rotn_encryptor = (ROTN_ENCRYPTOR *)encryptor;</div><div class="line"></div><div class="line"> (void)session; <span class="comment">/* Unused parameters */</span></div><div class="line"></div><div class="line"> <span class="comment">/* Free the allocated memory. */</span></div><div class="line"> free(rotn_encryptor->secretkey);</div><div class="line"> free(rotn_encryptor->keyid);</div><div class="line"> free(rotn_encryptor->shift_forw);</div><div class="line"> free(rotn_encryptor->shift_back);</div><div class="line"> free(encryptor);</div><div class="line"> <span class="keywordflow">return</span> (0);</div><div class="line">}</div><div class="line"><span class="comment">/*</span></div><div class="line"><span class="comment"> * rotn_configure --</span></div><div class="line"><span class="comment"> * WiredTiger no-op encryption configuration.</span></div><div class="line"><span class="comment"> */</span></div><div class="line"><span class="keyword">static</span> <span class="keywordtype">int</span></div><div class="line">rotn_configure(ROTN_ENCRYPTOR *rotn_encryptor, <a class="code" href="group__wt__ext.html#ga6fa5797cf581d18dc843e07333a497e4">WT_CONFIG_ARG</a> *config)</div><div class="line">{</div><div class="line"> <a class="code" href="struct_w_t___c_o_n_f_i_g___i_t_e_m.html">WT_CONFIG_ITEM</a> v;</div><div class="line"> <a class="code" href="struct_w_t___e_x_t_e_n_s_i_o_n___a_p_i.html">WT_EXTENSION_API</a> *wt_api; <span class="comment">/* Extension API */</span></div><div class="line"> <span class="keywordtype">int</span> ret;</div><div class="line"></div><div class="line"> wt_api = rotn_encryptor->wt_api;</div><div class="line"></div><div class="line"> <span class="comment">/* Get the configuration string. */</span></div><div class="line"> <span class="keywordflow">if</span> ((ret = wt_api-><a class="code" href="struct_w_t___e_x_t_e_n_s_i_o_n___a_p_i.html#a0d3aae2ceac28f7b45188bcfa4306d45">config_get</a>(wt_api, NULL, config, <span class="stringliteral">"rotn_force_error"</span>, &v)) == 0)</div><div class="line"> rotn_encryptor->force_error = v.<a name="a9"></a><a class="code" href="struct_w_t___c_o_n_f_i_g___i_t_e_m.html#a4aefab7843f434e5a5cc18203e9fec5f">val</a> != 0;</div><div class="line"> <span class="keywordflow">else</span> <span class="keywordflow">if</span> (ret != <a name="a10"></a><a class="code" href="group__wt.html#ga3c9e1b494d95cf34404ab7a974af6bf8">WT_NOTFOUND</a>)</div><div class="line"> <span class="keywordflow">return</span> (rotn_error(rotn_encryptor, NULL, EINVAL, <span class="stringliteral">"error parsing config"</span>));</div><div class="line"></div><div class="line"> <span class="keywordflow">return</span> (0);</div><div class="line">}</div><div class="line"></div><div class="line"><span class="comment">/*</span></div><div class="line"><span class="comment"> * wiredtiger_extension_init --</span></div><div class="line"><span class="comment"> * A simple shared library encryption example.</span></div><div class="line"><span class="comment"> */</span></div><div class="line"><span class="keywordtype">int</span></div><div class="line"><a name="a11"></a><a class="code" href="group__wt__ext.html#ga5ed14c916d5dcfe0e81aea9d9ccb7fe3">wiredtiger_extension_init</a>(<a name="_a12"></a><a class="code" href="struct_w_t___c_o_n_n_e_c_t_i_o_n.html">WT_CONNECTION</a> *connection, <a class="code" href="group__wt__ext.html#ga6fa5797cf581d18dc843e07333a497e4">WT_CONFIG_ARG</a> *config)</div><div class="line">{</div><div class="line"> ROTN_ENCRYPTOR *rotn_encryptor;</div><div class="line"> <span class="keywordtype">int</span> ret;</div><div class="line"></div><div class="line"> <span class="keywordflow">if</span> ((rotn_encryptor = calloc(1, <span class="keyword">sizeof</span>(ROTN_ENCRYPTOR))) == NULL)</div><div class="line"> <span class="keywordflow">return</span> (errno);</div><div class="line"></div><div class="line"> <span class="comment">/*</span></div><div class="line"><span class="comment"> * Allocate a local encryptor structure, with a WT_ENCRYPTOR structure</span></div><div class="line"><span class="comment"> * as the first field, allowing us to treat references to either type of</span></div><div class="line"><span class="comment"> * structure as a reference to the other type.</span></div><div class="line"><span class="comment"> *</span></div><div class="line"><span class="comment"> * Heap memory (not static), because it can support multiple databases.</span></div><div class="line"><span class="comment"> */</span></div><div class="line"> rotn_encryptor->encryptor.encrypt = rotn_encrypt;</div><div class="line"> rotn_encryptor->encryptor.decrypt = rotn_decrypt;</div><div class="line"> rotn_encryptor->encryptor.sizing = rotn_sizing;</div><div class="line"> rotn_encryptor->encryptor.customize = rotn_customize;</div><div class="line"> rotn_encryptor->encryptor.terminate = rotn_terminate;</div><div class="line"> rotn_encryptor->wt_api = connection-><a name="a13"></a><a class="code" href="struct_w_t___c_o_n_n_e_c_t_i_o_n.html#a99df5b3a17564eb5b3e4ec076590133d">get_extension_api</a>(connection);</div><div class="line"></div><div class="line"> <span class="keywordflow">if</span> ((ret = rotn_configure(rotn_encryptor, config)) != 0) {</div><div class="line"> free(rotn_encryptor);</div><div class="line"> <span class="keywordflow">return</span> (ret);</div><div class="line"> }</div><div class="line"> <span class="comment">/* Load the encryptor */</span></div><div class="line"> <span class="keywordflow">if</span> ((ret = connection-><a name="a14"></a><a class="code" href="struct_w_t___c_o_n_n_e_c_t_i_o_n.html#a59d203f4474780ca34bd3e07b8064949">add_encryptor</a>(</div><div class="line"> connection, <span class="stringliteral">"rotn"</span>, (<a class="code" href="struct_w_t___e_n_c_r_y_p_t_o_r.html">WT_ENCRYPTOR</a> *)rotn_encryptor, NULL)) == 0)</div><div class="line"> <span class="keywordflow">return</span> (0);</div><div class="line"></div><div class="line"> free(rotn_encryptor);</div><div class="line"> <span class="keywordflow">return</span> (ret);</div><div class="line">}</div></div><!-- fragment --> </div><!-- contents -->
</div><!-- doc-content -->
<!-- start footer part -->
<div id="nav-path" class="navpath"><!-- id is needed for treeview function! -->
<ul>
<li class="footer">Copyright (c) 2008-2019 MongoDB, Inc. All rights reserved. Contact <a href="mailto:info@wiredtiger.com">info@wiredtiger.com</a> for more information.</li>
</ul>
</div>
</body>
</html>
|