File: rotn_encrypt_8c-example.html

package info (click to toggle)
wiredtiger 3.2.1-1
  • links: PTS
  • area: main
  • in suites: bookworm, bullseye, forky, sid, trixie
  • size: 25,456 kB
  • sloc: ansic: 102,922; python: 52,573; sh: 6,915; java: 6,130; cpp: 2,311; makefile: 1,018; xml: 176
file content (81 lines) | stat: -rw-r--r-- 42,843 bytes parent folder | download
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">
   &#160;<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 &quot;AS IS&quot;, 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 &lt;errno.h&gt;</span></div><div class="line"><span class="preprocessor">#include &lt;stdlib.h&gt;</span></div><div class="line"><span class="preprocessor">#include &lt;string.h&gt;</span></div><div class="line"></div><div class="line"><span class="preprocessor">#include &lt;wiredtiger.h&gt;</span></div><div class="line"><span class="preprocessor">#include &lt;wiredtiger_ext.h&gt;</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"> * &quot;Caesar cipher&quot;), where N is the value of keyid.  Thus, with keyid=13,</span></div><div class="line"><span class="comment"> * text &quot;Hello&quot; maps to &quot;Uryyb&quot;, 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 &#39;A&#39; 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 &quot;ABC&quot; and keyid &quot;2&quot;, we show how</span></div><div class="line"><span class="comment"> * we map the input &quot;MySecret&quot;.</span></div><div class="line"><span class="comment"> *    secretkey          = ABC</span></div><div class="line"><span class="comment"> *    distances from &#39;A&#39; = 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-&gt;wt_api;</div><div class="line">    (void)wt_api-&gt;<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">&quot;rotn encryption: %s: %s&quot;</span>, msg, wt_api-&gt;<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 &lt; CHKSUM_LEN; i++)</div><div class="line">        dst[i] = <span class="charliteral">&#39;C&#39;</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 &lt; IV_LEN; i++)</div><div class="line">        dst[i] = <span class="charliteral">&#39;I&#39;</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 &quot;C&quot;.</span></div><div class="line"><span class="comment">     */</span></div><div class="line">    <span class="keywordflow">for</span> (i = 0; i &lt; len; i++) {</div><div class="line">        <span class="keywordflow">if</span> (<span class="charliteral">&#39;a&#39;</span> &lt;= buf[i] &amp;&amp; buf[i] &lt;= <span class="charliteral">&#39;z&#39;</span>)</div><div class="line">            buf[i] = ((buf[i] - <span class="charliteral">&#39;a&#39;</span>) + rotn) % 26 + <span class="charliteral">&#39;a&#39;</span>;</div><div class="line">        <span class="keywordflow">else</span> <span class="keywordflow">if</span> (<span class="charliteral">&#39;A&#39;</span> &lt;= buf[i] &amp;&amp; buf[i] &lt;= <span class="charliteral">&#39;Z&#39;</span>)</div><div class="line">            buf[i] = ((buf[i] - <span class="charliteral">&#39;A&#39;</span>) + rotn) % 26 + <span class="charliteral">&#39;A&#39;</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 &lt; 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 &lt; src_len + CHKSUM_LEN + IV_LEN)</div><div class="line">        <span class="keywordflow">return</span> (rotn_error(rotn_encryptor, session, ENOMEM, <span class="stringliteral">&quot;encrypt buffer not big enough&quot;</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(&amp;dst[i], &amp;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-&gt;shift_len == 0)</div><div class="line">        do_rotate((<span class="keywordtype">char</span> *)dst + i, src_len, rotn_encryptor-&gt;rot_N);</div><div class="line">    <span class="keywordflow">else</span></div><div class="line">        do_shift(&amp;dst[i], src_len, rotn_encryptor-&gt;shift_forw, rotn_encryptor-&gt;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(&amp;dst[i]);</div><div class="line">    i += CHKSUM_LEN;</div><div class="line">    make_iv(&amp;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-&gt;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 &lt; mylen)</div><div class="line">        <span class="keywordflow">return</span> (rotn_error(rotn_encryptor, session, ENOMEM, <span class="stringliteral">&quot;decrypt buffer not big enough&quot;</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(&amp;dst[0], &amp;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-&gt;shift_len == 0)</div><div class="line">        do_rotate((<span class="keywordtype">char</span> *)dst, mylen, 26 - rotn_encryptor-&gt;rot_N);</div><div class="line">    <span class="keywordflow">else</span></div><div class="line">        do_shift(&amp;dst[0], mylen, rotn_encryptor-&gt;shift_back, rotn_encryptor-&gt;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-&gt;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-&gt;keyid = rotn_encryptor-&gt;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-&gt;<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">&quot;keyid&quot;</span>, &amp;keyid)) == 0 &amp;&amp;</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>)) &lt; 0) {</div><div class="line">            ret = rotn_error(rotn_encryptor, NULL, EINVAL, <span class="stringliteral">&quot;rotn_customize: invalid keyid&quot;</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-&gt;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-&gt;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-&gt;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">&#39;\0&#39;</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-&gt;<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">&quot;secretkey&quot;</span>, &amp;secret)) == 0 &amp;&amp;</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-&gt;secretkey = malloc(len + 1)) == NULL ||</div><div class="line">          (rotn_encryptor-&gt;shift_forw = malloc(len)) == NULL ||</div><div class="line">          (rotn_encryptor-&gt;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 &lt; len; i++) {</div><div class="line">            <span class="keywordflow">if</span> (<span class="charliteral">&#39;a&#39;</span> &lt;= secret.<a class="code" href="struct_w_t___c_o_n_f_i_g___i_t_e_m.html#aa0ce7d30a32600e16824966c638ee45f">str</a>[i] &amp;&amp; secret.<a class="code" href="struct_w_t___c_o_n_f_i_g___i_t_e_m.html#aa0ce7d30a32600e16824966c638ee45f">str</a>[i] &lt;= <span class="charliteral">&#39;z&#39;</span>)</div><div class="line">                base = <span class="charliteral">&#39;a&#39;</span>;</div><div class="line">            <span class="keywordflow">else</span> <span class="keywordflow">if</span> (<span class="charliteral">&#39;A&#39;</span> &lt;= secret.<a class="code" href="struct_w_t___c_o_n_f_i_g___i_t_e_m.html#aa0ce7d30a32600e16824966c638ee45f">str</a>[i] &amp;&amp; secret.<a class="code" href="struct_w_t___c_o_n_f_i_g___i_t_e_m.html#aa0ce7d30a32600e16824966c638ee45f">str</a>[i] &lt;= <span class="charliteral">&#39;Z&#39;</span>)</div><div class="line">                base = <span class="charliteral">&#39;A&#39;</span>;</div><div class="line">            <span class="keywordflow">else</span> {</div><div class="line">                ret = rotn_error(rotn_encryptor, NULL, EINVAL, <span class="stringliteral">&quot;rotn_customize: invalid key&quot;</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-&gt;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-&gt;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-&gt;shift_len = len;</div><div class="line">        strncpy(rotn_encryptor-&gt;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-&gt;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">&#39;\0&#39;</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-&gt;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-&gt;keyid);</div><div class="line">    free(rotn_encryptor-&gt;secretkey);</div><div class="line">    free(rotn_encryptor-&gt;shift_forw);</div><div class="line">    free(rotn_encryptor-&gt;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-&gt;secretkey);</div><div class="line">    free(rotn_encryptor-&gt;keyid);</div><div class="line">    free(rotn_encryptor-&gt;shift_forw);</div><div class="line">    free(rotn_encryptor-&gt;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-&gt;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-&gt;<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">&quot;rotn_force_error&quot;</span>, &amp;v)) == 0)</div><div class="line">        rotn_encryptor-&gt;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">&quot;error parsing config&quot;</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-&gt;encryptor.encrypt = rotn_encrypt;</div><div class="line">    rotn_encryptor-&gt;encryptor.decrypt = rotn_decrypt;</div><div class="line">    rotn_encryptor-&gt;encryptor.sizing = rotn_sizing;</div><div class="line">    rotn_encryptor-&gt;encryptor.customize = rotn_customize;</div><div class="line">    rotn_encryptor-&gt;encryptor.terminate = rotn_terminate;</div><div class="line">    rotn_encryptor-&gt;wt_api = connection-&gt;<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-&gt;<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">&quot;rotn&quot;</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>