<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
    <title>Passing Curiosity: Posts tagged openssl</title>
    <link href="https://passingcuriosity.com/tags/openssl/openssl.xml" rel="self" />
    <link href="https://passingcuriosity.com" />
    <id>https://passingcuriosity.com/tags/openssl/openssl.xml</id>
    <author>
        <name>Thomas Sutton</name>
        
        <email>me@thomas-sutton.id.au</email>
        
    </author>
    <updated>2024-01-20T00:00:00Z</updated>
    <entry>
    <title>Extract a CA certificate bundle from macOS Keychain</title>
    <link href="https://passingcuriosity.com/2024/export-keychain-certificates-to-pem/" />
    <id>https://passingcuriosity.com/2024/export-keychain-certificates-to-pem/</id>
    <published>2024-01-20T00:00:00Z</published>
    <updated>2024-01-20T00:00:00Z</updated>
    <summary type="html"><![CDATA[<p>How to generate a PEM file containing the trusted CA certificates in your macOS
Keychain. As described in <a href="https://stackoverflow.com/a/41853880">this answer on Stack Exchange</a> you can use the
<a href="https://ss64.com/mac/security.html"><code>security</code></a> tool added in Mac OS X 10.3:</p>
<pre><code>security find-certificate -a -p /System/Library/Keychains/SystemRootCertificates.keychain &gt; cacerts.pem

security find-certificate -a -p /Library/Keychains/System.keychain &gt;&gt; cacerts.pem</code></pre>
<p>If there are missing CA certificates you need to trust, just append them to the
end of the file:</p>
<pre><code>cat MyTlsStrippingCorporateProxyCA.pem &gt;&gt; cacerts.pem</code></pre>
<p>You can store the <code>cacerts.pem</code> file somewhere convenient – maybe somewhere
under <code>~/Library/</code> would be sensible on macOS – and then export the many and
varied environment variables that will configure various tools to use the file:</p>
<pre><code>export AWS_CA_BUNDLE=&quot;$HOME/Library/cacerts.pem&quot;
export CURL_CA_BUNDLE=&quot;$HOME/Library/cacerts.pem&quot;
export HTTPLIB2_CA_CERTS=&quot;$HOME/Library/cacerts.pem&quot;
export REQUESTS_CA_BUNDLE=&quot;$HOME/Library/cacerts.pem&quot;
export SSL_CERT_FILE=&quot;$HOME/Library/cacerts.pem&quot;
export NODE_EXTRA_CA_CERTS=&quot;$HOME/Library/cacerts.pem&quot;</code></pre>]]></summary>
</entry>
<entry>
    <title>Reducing TLS client security requirements on OpenSSL and GnuTLS</title>
    <link href="https://passingcuriosity.com/2021/diffie-hellman-short-primes-disable/" />
    <id>https://passingcuriosity.com/2021/diffie-hellman-short-primes-disable/</id>
    <published>2021-03-30T00:00:00Z</published>
    <updated>2021-03-30T00:00:00Z</updated>
    <summary type="html"><![CDATA[<p>Most operating systems do a pretty OK job of shipping libraries that have
relatively secure configurations. Unfortunately, lots of organisations –
especially large organisations – do a terrible job of building secure
networks for them to run in. After “security” “appliances”, TLS is one thing
that sticks out as regularly screwed up.</p>
<p>In my current organisation we must interact with a number of servers with,
by modern standards, insecure TLS configuration. In particular, Diffie-Hellman
parameters that are too short to be considered secure. OpenSSL and GnuTLS as
shipped in Ubuntu 20.04 both refuse to handshake with these services. Well
done!</p>
<p>Unfortunately, it’s a large organisation so there is absolutely no chance of
getting these server configurations updated. So we need to reconfigure our
TLS client libraries to accept the low-security servers.</p>
<p>First, a disclaimer: I am not a cryptographer, security engineer, encryption
library developer, informed amateur, or even a particularly observant
bystander. You should be accepting security advice from me.</p>
<h2 id="gnutls">GnuTLS</h2>
<p>A great deal of GnuTLS operation is configured using a priority string. In
the version I’m looking at, the default priority string is</p>
<pre><code>NORMAL:-VERS-ALL:+VERS-TLS1.3:+VERS-TLS1.2:+VERS-DTLS1.2:%PROFILE_MEDIUM</code></pre>
<p>It’s the <code>%PROFILE_MEDIUM</code> that does things like set the minimum lengths
for keys, DH primes, etc. You can find the various security profile options
in the GnuTLS manual at <a href="https://www.gnutls.org/manual/html_node/Selecting-cryptographic-key-sizes.html">Section 6.11 Selecting cryptographic key sizes</a>.
My current project needs to support servers using Diffie-Hellman primes of
1024 bits, so I need to use <code>PROFILE_LOW</code>.</p>
<p>You can override the default priority string by editing (or creating)
<code>/etc/gnutls/config</code> like so:</p>
<pre><code>[overrides]
default-priority-string = NORMAL:-VERS-ALL:+VERS-TLS1.3:+VERS-TLS1.2:+VERS-DTLS1.2:%PROFILE_LOW</code></pre>
<p>This should then apply to any application that doesn’t specify it’s own
priority string.</p>
<h2 id="openssl">OpenSSL</h2>
<p>Updating the OpenSSL configuration is a <em>much</em> more complicated proposition.
The configuration used by applications is stored in a section named by the
<code>openssl_conf</code> variable. This is <em>not</em> in a section, so it’ll be at the top
of the file if it’s set. In my experience, it often isn’t set.</p>
<p>If it is set, go find the section it names, then follow <code>ssl_conf</code> to the
section containing the SSL configuration, then follow <code>system_default</code> to
the section <em>it</em> names.</p>
<p>Here, you can specify something like:</p>
<pre><code>CipherString = DEFAULT:@SECLEVEL=1</code></pre>
<p>If all that isn’t already in your <code>openssl.cnf</code>, you need to create a new
section, which points to a section, which points to a section. This can all
go at the end of the file. Then you need to add a variable <em>not</em> in a section
that points to the first of those sections.</p>
<p>Here’s a shell script that does just that:</p>
<pre><code>#!/bin/sh
# Update the OpenSSL configuration to use lower default security level. This
# allows us to connect to TLS servers using insecure certificates issued by the
# internal CA.

set -eux

mv /etc/ssl/openssl.cnf /etc/ssl/openssl.cnf.orig

{
cat &lt;&lt;EOF
# Override the default OpenSSL configuration with less secure settings that
# allow communication with the many services that use insecure certificates
# issued by the internal CA.
openssl_conf = default_conf
EOF

cat /etc/ssl/openssl.cnf.orig;

cat &lt;&lt;EOF
# Default configuration for applications which use OpenSSL.
[ default_conf ]
ssl_conf = ssl_sect

[ ssl_sect ]
system_default = system_default_sect

[ system_default_sect ]
MinProtocol = TLSv1.2
# Be less secure when negotiating ciphers, verifying certificates, etc.
CipherString = DEFAULT:@SECLEVEL=1
EOF
} &gt; /etc/ssl/openssl.cnf</code></pre>
<p>It’s probably a bit too lax but I use it in Docker images based on
<code>ubuntu:20.04</code> and it seems to do the trick.</p>]]></summary>
</entry>
<entry>
    <title>AES encryption in Python with M2Crypto</title>
    <link href="https://passingcuriosity.com/2009/aes-encryption-in-python-with-m2crypto/" />
    <id>https://passingcuriosity.com/2009/aes-encryption-in-python-with-m2crypto/</id>
    <published>2009-08-16T00:00:00Z</published>
    <updated>2009-08-16T00:00:00Z</updated>
    <summary type="html"><![CDATA[<p>I’ve needed to write some Python code to handle encryption and decryption
recently. This is a short post describing how I did it.</p>
<p>I’m interacting with a system which encrypts data in transit like so:</p>
<blockquote>
<p>The encryption algorithm is AES with a 16 bit [sic] key. The cipher mode is
CBC with PKCS5 padding. The initialisation vector is 16 bytes of 00.</p>
</blockquote>
<p>Thus I need to handle 128-bit AES in CBC mode, and padding according to PKCS5.
In addition, the key and encrypted data is all base64 encoded.</p>
<p>There are a number of cryptography packages for Python. The first I found was
a blog post describing <a href="http://www.codekoala.com/blog/2009/aes-encryption-python-using-pycrypto/">PyCrypto</a>. My requirements include <a href="http://www.chilkatsoft.com/faq/PKCS5_Padding.html">PKCS5
padding</a>, which PyCrypto doesn’t seem to do. It also has it’s own
implementations of the encryption algorithms.</p>
<p>The padding algorithm seems pretty simple. If I understand correctly, it’d go
something like this in Python:</p>
<div class="sourceCode" id="cb1"><pre class="sourceCode python"><code class="sourceCode python"><span id="cb1-1"><a href="#cb1-1" aria-hidden="true" tabindex="-1"></a>pad <span class="op">=</span> <span class="kw">lambda</span> s: s <span class="op">+</span> (BS <span class="op">-</span> <span class="bu">len</span>(s) <span class="op">%</span> BS) <span class="op">*</span> <span class="bu">chr</span>(BS <span class="op">-</span> <span class="bu">len</span>(s) <span class="op">%</span> BS)</span>
<span id="cb1-2"><a href="#cb1-2" aria-hidden="true" tabindex="-1"></a>unpad <span class="op">=</span> <span class="kw">lambda</span> s : s[<span class="dv">0</span>:<span class="op">-</span><span class="bu">ord</span>(s[<span class="op">-</span><span class="dv">1</span>])]</span></code></pre></div>
<p>But I’ve got better things to do than convince myself that I’ve implemented it
correctly.</p>
<p>Thankfully, there’s another options: <a href="http://chandlerproject.org/Projects/MeTooCrypto">Me Too Crypto</a>. Unlike
PyCrypto, M2Crypto is a Python wrapper around <a href="http://openssl.org/">OpenSSL</a> which is
nice, as my code will be running under <a href="http://code.google.com/p/modwsgi/">mod_wsgi</a> embedded in Apache
along with <a href="http://httpd.apache.org/docs/2.2/mod/mod_ssl.html">mod_ssl</a>.</p>
<p>Alas, it has rather poor documentation. The best guide to using it I’ve seen
is the <a href="http://svn.osafoundation.org/m2crypto/trunk/tests/">test code</a>. I’m using the EVP interface, and found <code>test_AES()</code>
in the <a href="http://svn.osafoundation.org/m2crypto/trunk/tests/test_evp.py">EVP tests</a> invaluable.</p>
<p>Without further ado, the code:</p>
<div class="sourceCode" id="cb2"><pre class="sourceCode python"><code class="sourceCode python"><span id="cb2-1"><a href="#cb2-1" aria-hidden="true" tabindex="-1"></a><span class="im">from</span> base64 <span class="im">import</span> b64encode, b64decode</span>
<span id="cb2-2"><a href="#cb2-2" aria-hidden="true" tabindex="-1"></a><span class="im">from</span> M2Crypto.EVP <span class="im">import</span> Cipher</span>
<span id="cb2-3"><a href="#cb2-3" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb2-4"><a href="#cb2-4" aria-hidden="true" tabindex="-1"></a>__all__ <span class="op">=</span> [<span class="st">'encryptor'</span>, <span class="st">'decryptor'</span>]</span>
<span id="cb2-5"><a href="#cb2-5" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb2-6"><a href="#cb2-6" aria-hidden="true" tabindex="-1"></a>ENC<span class="op">=</span><span class="dv">1</span></span>
<span id="cb2-7"><a href="#cb2-7" aria-hidden="true" tabindex="-1"></a>DEC<span class="op">=</span><span class="dv">0</span></span>
<span id="cb2-8"><a href="#cb2-8" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb2-9"><a href="#cb2-9" aria-hidden="true" tabindex="-1"></a><span class="kw">def</span> build_cipher(key, iv, op<span class="op">=</span>ENC):</span>
<span id="cb2-10"><a href="#cb2-10" aria-hidden="true" tabindex="-1"></a>    <span class="co">&quot;&quot;&quot;&quot;&quot;&quot;</span><span class="st">&quot;&quot;</span></span>
<span id="cb2-11"><a href="#cb2-11" aria-hidden="true" tabindex="-1"></a>    <span class="cf">return</span> Cipher(alg<span class="op">=</span><span class="st">'aes_128_cbc'</span>, key<span class="op">=</span>key, iv<span class="op">=</span>iv, op<span class="op">=</span>op)</span>
<span id="cb2-12"><a href="#cb2-12" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb2-13"><a href="#cb2-13" aria-hidden="true" tabindex="-1"></a><span class="kw">def</span> encryptor(key, iv<span class="op">=</span><span class="va">None</span>):</span>
<span id="cb2-14"><a href="#cb2-14" aria-hidden="true" tabindex="-1"></a>    <span class="co">&quot;&quot;&quot;&quot;&quot;&quot;</span></span>
<span id="cb2-15"><a href="#cb2-15" aria-hidden="true" tabindex="-1"></a>    <span class="co"># Decode the key and iv</span></span>
<span id="cb2-16"><a href="#cb2-16" aria-hidden="true" tabindex="-1"></a>    key <span class="op">=</span> b64decode(key)</span>
<span id="cb2-17"><a href="#cb2-17" aria-hidden="true" tabindex="-1"></a>    <span class="cf">if</span> iv <span class="kw">is</span> <span class="va">None</span>:</span>
<span id="cb2-18"><a href="#cb2-18" aria-hidden="true" tabindex="-1"></a>        iv <span class="op">=</span> <span class="st">'</span><span class="ch">\0</span><span class="st">'</span> <span class="op">*</span> <span class="dv">16</span></span>
<span id="cb2-19"><a href="#cb2-19" aria-hidden="true" tabindex="-1"></a>    <span class="cf">else</span>:</span>
<span id="cb2-20"><a href="#cb2-20" aria-hidden="true" tabindex="-1"></a>        iv <span class="op">=</span> b64decode(iv)</span>
<span id="cb2-21"><a href="#cb2-21" aria-hidden="true" tabindex="-1"></a>   </span>
<span id="cb2-22"><a href="#cb2-22" aria-hidden="true" tabindex="-1"></a>   <span class="co"># Return the encryption function</span></span>
<span id="cb2-23"><a href="#cb2-23" aria-hidden="true" tabindex="-1"></a>    <span class="kw">def</span> encrypt(data):</span>
<span id="cb2-24"><a href="#cb2-24" aria-hidden="true" tabindex="-1"></a>        cipher <span class="op">=</span> build_cipher(key, iv, ENC)</span>
<span id="cb2-25"><a href="#cb2-25" aria-hidden="true" tabindex="-1"></a>        v <span class="op">=</span> cipher.update(data)</span>
<span id="cb2-26"><a href="#cb2-26" aria-hidden="true" tabindex="-1"></a>        v <span class="op">=</span> v <span class="op">+</span> cipher.final()</span>
<span id="cb2-27"><a href="#cb2-27" aria-hidden="true" tabindex="-1"></a>        <span class="kw">del</span> cipher</span>
<span id="cb2-28"><a href="#cb2-28" aria-hidden="true" tabindex="-1"></a>        v <span class="op">=</span> b64encode(v)</span>
<span id="cb2-29"><a href="#cb2-29" aria-hidden="true" tabindex="-1"></a>        <span class="cf">return</span> v</span>
<span id="cb2-30"><a href="#cb2-30" aria-hidden="true" tabindex="-1"></a>    <span class="cf">return</span> encrypt</span>
<span id="cb2-31"><a href="#cb2-31" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb2-32"><a href="#cb2-32" aria-hidden="true" tabindex="-1"></a><span class="kw">def</span> decryptor(key, iv<span class="op">=</span><span class="va">None</span>):</span>
<span id="cb2-33"><a href="#cb2-33" aria-hidden="true" tabindex="-1"></a>    <span class="co">&quot;&quot;&quot;&quot;&quot;&quot;</span></span>
<span id="cb2-34"><a href="#cb2-34" aria-hidden="true" tabindex="-1"></a>    <span class="co"># Decode the key and iv</span></span>
<span id="cb2-35"><a href="#cb2-35" aria-hidden="true" tabindex="-1"></a>    key <span class="op">=</span> b64decode(key)</span>
<span id="cb2-36"><a href="#cb2-36" aria-hidden="true" tabindex="-1"></a>    <span class="cf">if</span> iv <span class="kw">is</span> <span class="va">None</span>:</span>
<span id="cb2-37"><a href="#cb2-37" aria-hidden="true" tabindex="-1"></a>        iv <span class="op">=</span> <span class="st">'</span><span class="ch">\0</span><span class="st">'</span> <span class="op">*</span> <span class="dv">16</span></span>
<span id="cb2-38"><a href="#cb2-38" aria-hidden="true" tabindex="-1"></a>    <span class="cf">else</span>:</span>
<span id="cb2-39"><a href="#cb2-39" aria-hidden="true" tabindex="-1"></a>        iv <span class="op">=</span> b64decode(iv)</span>
<span id="cb2-40"><a href="#cb2-40" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb2-41"><a href="#cb2-41" aria-hidden="true" tabindex="-1"></a>   <span class="co"># Return the decryption function</span></span>
<span id="cb2-42"><a href="#cb2-42" aria-hidden="true" tabindex="-1"></a>    <span class="kw">def</span> decrypt(data):</span>
<span id="cb2-43"><a href="#cb2-43" aria-hidden="true" tabindex="-1"></a>        data <span class="op">=</span> b64decode(data)</span>
<span id="cb2-44"><a href="#cb2-44" aria-hidden="true" tabindex="-1"></a>        cipher <span class="op">=</span> build_cipher(key, iv, DEC)</span>
<span id="cb2-45"><a href="#cb2-45" aria-hidden="true" tabindex="-1"></a>        v <span class="op">=</span> cipher.update(data)</span>
<span id="cb2-46"><a href="#cb2-46" aria-hidden="true" tabindex="-1"></a>        v <span class="op">=</span> v <span class="op">+</span> cipher.final()</span>
<span id="cb2-47"><a href="#cb2-47" aria-hidden="true" tabindex="-1"></a>        <span class="kw">del</span> cipher</span>
<span id="cb2-48"><a href="#cb2-48" aria-hidden="true" tabindex="-1"></a>        <span class="cf">return</span> v</span>
<span id="cb2-49"><a href="#cb2-49" aria-hidden="true" tabindex="-1"></a>    <span class="cf">return</span> decrypt</span></code></pre></div>]]></summary>
</entry>
<entry>
    <title>Extending Lua in C</title>
    <link href="https://passingcuriosity.com/2009/extending-lua-in-c/" />
    <id>https://passingcuriosity.com/2009/extending-lua-in-c/</id>
    <published>2009-03-03T00:00:00Z</published>
    <updated>2009-03-03T00:00:00Z</updated>
    <summary type="html"><![CDATA[<p>Lua is a small, portable, and fast scripting language designed for embedding in other software. Being designed for embedding, it has a simple but powerful API which makes it easy to communicate both ways: from C into Lua and from Lua into C. In this post, I’ll describe the process of writing a small module adding support for OpenSSL’s hashing functions to Lua.</p>
<h3 id="hashing-data-with-openssl">Hashing data with OpenSSL</h3>
<p>Generating hashes of data is an relatively simple problem to address in a library: is has a small, simple interface which can be implemented using any of a large number of hashing libraries. Rather than locate, evaluate and include one of the many open source or public domain hashing libraries, I’ve decided to wrap the hashing functions from <a href="http://www.openssl.org/">OpenSSL</a>. This provides a number of benefits:</p>
<ol type="1">
<li>It’s reasonably well trusted (and I don’t have to try to vet it).</li>
<li>It’s installed pretty much everywhere (so I don’t need to include it with my code).</li>
<li>It’s API is simple, consistent, and flexible.</li>
<li>We’ll see later that it makes my code powerful and lends it an elegant interface.</li>
</ol>
<p>Before I can write a Lua wrapper for the OpenSSL functions, I’ll need to know how they work. The <code>man</code> pages help immeasurably, especially as they contain code demonstrating <a href="http://www.openssl.org/docs/crypto/EVP_DigestInit.html#EXAMPLE">how to hash data using OpenSSL</a>. Following the example in that man page, a first cut of my code will look like this:</p>
<div class="sourceCode" id="cb1"><pre class="sourceCode c"><code class="sourceCode c"><span id="cb1-1"><a href="#cb1-1" aria-hidden="true" tabindex="-1"></a><span class="dt">unsigned</span> <span class="dt">char</span> <span class="op">*</span>digest<span class="op">(</span><span class="dt">char</span> <span class="op">*</span>algorithm<span class="op">,</span> <span class="dt">void</span> <span class="op">*</span>data<span class="op">,</span> <span class="dt">size_t</span> len<span class="op">)</span> <span class="op">{</span></span>
<span id="cb1-2"><a href="#cb1-2" aria-hidden="true" tabindex="-1"></a>    <span class="co">// The hash context</span></span>
<span id="cb1-3"><a href="#cb1-3" aria-hidden="true" tabindex="-1"></a>    <span class="dt">const</span> EVP_MD <span class="op">*</span>md<span class="op">;</span></span>
<span id="cb1-4"><a href="#cb1-4" aria-hidden="true" tabindex="-1"></a>    EVP_MD_CTX mdctx<span class="op">;</span></span>
<span id="cb1-5"><a href="#cb1-5" aria-hidden="true" tabindex="-1"></a>    <span class="co">// The hash</span></span>
<span id="cb1-6"><a href="#cb1-6" aria-hidden="true" tabindex="-1"></a>    <span class="dt">unsigned</span> <span class="dt">char</span>  hash_data<span class="op">[</span>EVP_MAX_MD_SIZE<span class="op">];</span></span>
<span id="cb1-7"><a href="#cb1-7" aria-hidden="true" tabindex="-1"></a>    <span class="dt">unsigned</span> <span class="dt">int</span>   hash_len <span class="op">=</span> <span class="dv">0</span><span class="op">;</span></span>
<span id="cb1-8"><a href="#cb1-8" aria-hidden="true" tabindex="-1"></a>    <span class="dt">unsigned</span> <span class="dt">char</span> <span class="op">*</span>hash_str <span class="op">=</span> NULL<span class="op">;</span></span>
<span id="cb1-9"><a href="#cb1-9" aria-hidden="true" tabindex="-1"></a>    <span class="co">// Loop variables</span></span>
<span id="cb1-10"><a href="#cb1-10" aria-hidden="true" tabindex="-1"></a>    <span class="dt">unsigned</span> <span class="dt">char</span> <span class="op">*</span>cur <span class="op">=</span> NULL<span class="op">;</span></span>
<span id="cb1-11"><a href="#cb1-11" aria-hidden="true" tabindex="-1"></a>    <span class="dt">unsigned</span> <span class="dt">int</span> i <span class="op">=</span> <span class="dv">0</span><span class="op">;</span></span>
<span id="cb1-12"><a href="#cb1-12" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb1-13"><a href="#cb1-13" aria-hidden="true" tabindex="-1"></a>    <span class="co">// Get the hash algorithm the caller requested</span></span>
<span id="cb1-14"><a href="#cb1-14" aria-hidden="true" tabindex="-1"></a>    OpenSSL_add_all_digests<span class="op">();</span></span>
<span id="cb1-15"><a href="#cb1-15" aria-hidden="true" tabindex="-1"></a>    md <span class="op">=</span> EVP_get_digestbyname<span class="op">(</span>algorithm<span class="op">);</span></span>
<span id="cb1-16"><a href="#cb1-16" aria-hidden="true" tabindex="-1"></a>    <span class="cf">if</span> <span class="op">(!</span> md <span class="op">)</span> <span class="op">{</span></span>
<span id="cb1-17"><a href="#cb1-17" aria-hidden="true" tabindex="-1"></a>        <span class="co">// The requested algorithm is not available</span></span>
<span id="cb1-18"><a href="#cb1-18" aria-hidden="true" tabindex="-1"></a>        <span class="co">// This is an error</span></span>
<span id="cb1-19"><a href="#cb1-19" aria-hidden="true" tabindex="-1"></a>    <span class="op">}</span></span>
<span id="cb1-20"><a href="#cb1-20" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb1-21"><a href="#cb1-21" aria-hidden="true" tabindex="-1"></a>    <span class="co">// Initialize the hashing context to use the algorithm named in md</span></span>
<span id="cb1-22"><a href="#cb1-22" aria-hidden="true" tabindex="-1"></a>    EVP_MD_CTX_init<span class="op">(&amp;</span>mdctx<span class="op">);</span></span>
<span id="cb1-23"><a href="#cb1-23" aria-hidden="true" tabindex="-1"></a>    EVP_DigestInit_ex<span class="op">(&amp;</span>mdctx<span class="op">,</span> md<span class="op">,</span> NULL<span class="op">);</span></span>
<span id="cb1-24"><a href="#cb1-24" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb1-25"><a href="#cb1-25" aria-hidden="true" tabindex="-1"></a>    <span class="co">// Feed the data to the hash function</span></span>
<span id="cb1-26"><a href="#cb1-26" aria-hidden="true" tabindex="-1"></a>    EVP_DigestUpdate<span class="op">(&amp;</span>mdctx<span class="op">,</span> data<span class="op">,</span> len<span class="op">);</span></span>
<span id="cb1-27"><a href="#cb1-27" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb1-28"><a href="#cb1-28" aria-hidden="true" tabindex="-1"></a>    <span class="co">// Finalize the hashing context putting the hash into hash_data and</span></span>
<span id="cb1-29"><a href="#cb1-29" aria-hidden="true" tabindex="-1"></a>    <span class="co">// it's length into hash_len</span></span>
<span id="cb1-30"><a href="#cb1-30" aria-hidden="true" tabindex="-1"></a>    EVP_DigestFinal_ex<span class="op">(&amp;</span>mdctx<span class="op">,</span> hash_data<span class="op">,</span> <span class="op">&amp;</span>hash_len<span class="op">);</span></span>
<span id="cb1-31"><a href="#cb1-31" aria-hidden="true" tabindex="-1"></a>    EVP_MD_CTX_cleanup<span class="op">(&amp;</span>mdctx<span class="op">);</span></span>
<span id="cb1-32"><a href="#cb1-32" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb1-33"><a href="#cb1-33" aria-hidden="true" tabindex="-1"></a>    <span class="co">// Translate the data into a string of hexadecimal characters</span></span>
<span id="cb1-34"><a href="#cb1-34" aria-hidden="true" tabindex="-1"></a>    cur <span class="op">=</span> hash_str <span class="op">=</span> <span class="op">(</span><span class="dt">unsigned</span> <span class="dt">char</span><span class="op">*)</span>malloc<span class="op">(</span><span class="dv">1</span> <span class="op">+</span> <span class="dv">2</span> <span class="op">*</span> hash_len<span class="op">);</span></span>
<span id="cb1-35"><a href="#cb1-35" aria-hidden="true" tabindex="-1"></a>    <span class="cf">for</span> <span class="op">(</span> i <span class="op">=</span> <span class="dv">0</span><span class="op">;</span> i <span class="op">&lt;</span> hash_len<span class="op">;</span> i<span class="op">++</span> <span class="op">)</span> <span class="op">{</span></span>
<span id="cb1-36"><a href="#cb1-36" aria-hidden="true" tabindex="-1"></a>        snprintf<span class="op">(</span>cur<span class="op">,</span> <span class="dv">3</span><span class="op">,</span> <span class="st">&quot;</span><span class="sc">%02x</span><span class="st">&quot;</span><span class="op">,</span> hash_data<span class="op">[</span>i<span class="op">]);</span></span>
<span id="cb1-37"><a href="#cb1-37" aria-hidden="true" tabindex="-1"></a>        cur <span class="op">=</span> cur <span class="op">+</span> <span class="dv">2</span><span class="op">;</span></span>
<span id="cb1-38"><a href="#cb1-38" aria-hidden="true" tabindex="-1"></a>    <span class="op">}</span></span>
<span id="cb1-39"><a href="#cb1-39" aria-hidden="true" tabindex="-1"></a>    cur<span class="op">[</span><span class="dv">0</span><span class="op">]</span> <span class="op">=</span> <span class="ch">'</span><span class="sc">\0</span><span class="ch">'</span><span class="op">;</span></span>
<span id="cb1-40"><a href="#cb1-40" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb1-41"><a href="#cb1-41" aria-hidden="true" tabindex="-1"></a>    <span class="co">// Return the hex string of the hash</span></span>
<span id="cb1-42"><a href="#cb1-42" aria-hidden="true" tabindex="-1"></a>    <span class="cf">return</span> hash_str<span class="op">;</span></span>
<span id="cb1-43"><a href="#cb1-43" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code></pre></div>
<p>Easy! Variable arguments are a pain in the arse in C, so I’ve omitted them from the code above but it’d be great if the Lua module will accept any number of input values and hash them all. Thanks to the great OpenSSL API, doing so is just a matter of calling <code>EVP_DigestUpdate()</code> in a loop over each of the input values. It couldn’t be simpler!</p>
<h3 id="calling-c-code-from-lua">Calling C code from Lua</h3>
<p>Now that I can hash values with the OpenSSL functions, it’s time to think about calling that code from Lua. Lua has a fairly simple API for implementing module in C:</p>
<ul>
<li>functions take a single argument – the state of the Lua interpreter</li>
<li>they can manipulate that state, including pushing or poping values off the argument stack</li>
<li>and then return an integer – the number of items they push onto the stack as return values.</li>
</ul>
<p>As simple example may help illustrate. The following function inspects the stack to see how many parameters it was invoked with, and returns a message state such. Unlike the stacks used in many other systems, the Lua stack is indexed (you can access any item by its index, rather than only the top item) and these indexes start from 1 (instead of the traditional 0). As a consequence, the index of the top of the stack is the number of items on it.</p>
<div class="sourceCode" id="cb2"><pre class="sourceCode c"><code class="sourceCode c"><span id="cb2-1"><a href="#cb2-1" aria-hidden="true" tabindex="-1"></a><span class="dt">static</span> <span class="dt">int</span> example<span class="op">(</span>lua_State <span class="op">*</span>L<span class="op">)</span> <span class="op">{</span></span>
<span id="cb2-2"><a href="#cb2-2" aria-hidden="true" tabindex="-1"></a>    <span class="dt">unsigned</span> <span class="dt">int</span> n <span class="op">=</span> <span class="dv">0</span><span class="op">;</span></span>
<span id="cb2-3"><a href="#cb2-3" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb2-4"><a href="#cb2-4" aria-hidden="true" tabindex="-1"></a>    <span class="co">// Get the index of the top of the stack</span></span>
<span id="cb2-5"><a href="#cb2-5" aria-hidden="true" tabindex="-1"></a>    n <span class="op">=</span> lua_gettop<span class="op">(</span>L<span class="op">);</span></span>
<span id="cb2-6"><a href="#cb2-6" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb2-7"><a href="#cb2-7" aria-hidden="true" tabindex="-1"></a>    <span class="co">// Push a string onto the stack using a printf-like convenience</span></span>
<span id="cb2-8"><a href="#cb2-8" aria-hidden="true" tabindex="-1"></a>    <span class="co">// function.</span></span>
<span id="cb2-9"><a href="#cb2-9" aria-hidden="true" tabindex="-1"></a>    lua_pushfstring<span class="op">(</span>L<span class="op">,</span> <span class="st">&quot;You passed </span><span class="sc">%d</span><span class="st"> arguments.&quot;</span><span class="op">,</span> n<span class="op">);</span></span>
<span id="cb2-10"><a href="#cb2-10" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb2-11"><a href="#cb2-11" aria-hidden="true" tabindex="-1"></a>    <span class="co">// Return the number of return values pushed onto the stack.</span></span>
<span id="cb2-12"><a href="#cb2-12" aria-hidden="true" tabindex="-1"></a>    <span class="cf">return</span> <span class="dv">1</span><span class="op">;</span></span>
<span id="cb2-13"><a href="#cb2-13" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code></pre></div>
<p>Using just few more functions from the API, I can modify the OpenSSL code above to be called from Lua. All it requires is a change of signature, a call to <code>lua_tolstring()</code> to get the algorithm name, a call to <code>lua_gettop()</code> to get the number of inputs, a loop calling <code>lua_tolstring()</code> to get each of them in turn and feed them to the hashing code, and a call to <code>lua_pushstring()</code> to push the return value onto the stack.</p>
<p>The revised code looks like this:</p>
<div class="sourceCode" id="cb3"><pre class="sourceCode c"><code class="sourceCode c"><span id="cb3-1"><a href="#cb3-1" aria-hidden="true" tabindex="-1"></a><span class="dt">static</span> <span class="dt">int</span> hash_hash <span class="op">(</span>lua_State <span class="op">*</span>L<span class="op">)</span> <span class="op">{</span></span>
<span id="cb3-2"><a href="#cb3-2" aria-hidden="true" tabindex="-1"></a>    EVP_MD_CTX mdctx<span class="op">;</span></span>
<span id="cb3-3"><a href="#cb3-3" aria-hidden="true" tabindex="-1"></a>    <span class="dt">const</span> EVP_MD <span class="op">*</span>md<span class="op">;</span></span>
<span id="cb3-4"><a href="#cb3-4" aria-hidden="true" tabindex="-1"></a>    <span class="dt">unsigned</span> <span class="dt">char</span> md_value<span class="op">[</span>EVP_MAX_MD_SIZE<span class="op">];</span></span>
<span id="cb3-5"><a href="#cb3-5" aria-hidden="true" tabindex="-1"></a>    <span class="dt">char</span> <span class="op">*</span>algorithm <span class="op">=</span> NULL<span class="op">;</span></span>
<span id="cb3-6"><a href="#cb3-6" aria-hidden="true" tabindex="-1"></a>    <span class="dt">char</span> <span class="op">*</span>digest <span class="op">=</span> NULL<span class="op">;</span></span>
<span id="cb3-7"><a href="#cb3-7" aria-hidden="true" tabindex="-1"></a>    <span class="dt">char</span> <span class="op">*</span>cur  <span class="op">=</span> NULL<span class="op">;</span></span>
<span id="cb3-8"><a href="#cb3-8" aria-hidden="true" tabindex="-1"></a>    <span class="dt">unsigned</span> <span class="dt">int</span> md_len <span class="op">=</span> <span class="dv">0</span><span class="op">;</span></span>
<span id="cb3-9"><a href="#cb3-9" aria-hidden="true" tabindex="-1"></a>    <span class="dt">unsigned</span> <span class="dt">int</span> arguments <span class="op">=</span> <span class="dv">0</span><span class="op">;</span></span>
<span id="cb3-10"><a href="#cb3-10" aria-hidden="true" tabindex="-1"></a>    <span class="dt">unsigned</span> <span class="dt">int</span> i <span class="op">=</span> <span class="dv">0</span><span class="op">;</span></span>
<span id="cb3-11"><a href="#cb3-11" aria-hidden="true" tabindex="-1"></a>    <span class="dt">size_t</span> msg_len <span class="op">=</span> <span class="dv">0</span><span class="op">;</span></span>
<span id="cb3-12"><a href="#cb3-12" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb3-13"><a href="#cb3-13" aria-hidden="true" tabindex="-1"></a>    <span class="co">// Get the algorithm name from the closure</span></span>
<span id="cb3-14"><a href="#cb3-14" aria-hidden="true" tabindex="-1"></a>    algorithm <span class="op">=</span> <span class="op">(</span><span class="dt">char</span> <span class="op">*)</span>lua_tostring<span class="op">(</span>L<span class="op">,</span> <span class="dv">1</span><span class="op">);</span></span>
<span id="cb3-15"><a href="#cb3-15" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb3-16"><a href="#cb3-16" aria-hidden="true" tabindex="-1"></a>    <span class="co">// Get the number of stack arguments</span></span>
<span id="cb3-17"><a href="#cb3-17" aria-hidden="true" tabindex="-1"></a>    arguments <span class="op">=</span> lua_gettop<span class="op">(</span>L<span class="op">);</span></span>
<span id="cb3-18"><a href="#cb3-18" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb3-19"><a href="#cb3-19" aria-hidden="true" tabindex="-1"></a>    <span class="co">// Get the digest</span></span>
<span id="cb3-20"><a href="#cb3-20" aria-hidden="true" tabindex="-1"></a>    OpenSSL_add_all_digests<span class="op">();</span></span>
<span id="cb3-21"><a href="#cb3-21" aria-hidden="true" tabindex="-1"></a>    md <span class="op">=</span> EVP_get_digestbyname<span class="op">(</span>algorithm<span class="op">);</span></span>
<span id="cb3-22"><a href="#cb3-22" aria-hidden="true" tabindex="-1"></a>    <span class="cf">if</span> <span class="op">(!</span> md <span class="op">)</span> <span class="op">{</span></span>
<span id="cb3-23"><a href="#cb3-23" aria-hidden="true" tabindex="-1"></a>        lua_pushfstring<span class="op">(</span>L<span class="op">,</span> <span class="st">&quot;No such hash algorithm: </span><span class="sc">%s</span><span class="st">&quot;</span><span class="op">,</span> algorithm<span class="op">);</span></span>
<span id="cb3-24"><a href="#cb3-24" aria-hidden="true" tabindex="-1"></a>        <span class="cf">return</span> lua_error<span class="op">(</span>L<span class="op">);</span></span>
<span id="cb3-25"><a href="#cb3-25" aria-hidden="true" tabindex="-1"></a>    <span class="op">}</span></span>
<span id="cb3-26"><a href="#cb3-26" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb3-27"><a href="#cb3-27" aria-hidden="true" tabindex="-1"></a>    <span class="co">// Initialise the hash context</span></span>
<span id="cb3-28"><a href="#cb3-28" aria-hidden="true" tabindex="-1"></a>    EVP_MD_CTX_init<span class="op">(&amp;</span>mdctx<span class="op">);</span></span>
<span id="cb3-29"><a href="#cb3-29" aria-hidden="true" tabindex="-1"></a>    EVP_DigestInit_ex<span class="op">(&amp;</span>mdctx<span class="op">,</span> md<span class="op">,</span> NULL<span class="op">);</span></span>
<span id="cb3-30"><a href="#cb3-30" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb3-31"><a href="#cb3-31" aria-hidden="true" tabindex="-1"></a>    <span class="co">// Add the arguments to the hash.</span></span>
<span id="cb3-32"><a href="#cb3-32" aria-hidden="true" tabindex="-1"></a>    <span class="cf">for</span> <span class="op">(</span> i <span class="op">=</span> <span class="dv">2</span><span class="op">;</span> i <span class="op">&lt;=</span> arguments<span class="op">;</span> i<span class="op">++</span> <span class="op">)</span> <span class="op">{</span></span>
<span id="cb3-33"><a href="#cb3-33" aria-hidden="true" tabindex="-1"></a>        cur <span class="op">=</span> <span class="op">(</span><span class="dt">char</span> <span class="op">*)</span>lua_tolstring<span class="op">(</span>L<span class="op">,</span> i<span class="op">,</span> <span class="op">&amp;</span>msg_len<span class="op">);</span></span>
<span id="cb3-34"><a href="#cb3-34" aria-hidden="true" tabindex="-1"></a>        EVP_DigestUpdate<span class="op">(&amp;</span>mdctx<span class="op">,</span> cur<span class="op">,</span> msg_len<span class="op">);</span></span>
<span id="cb3-35"><a href="#cb3-35" aria-hidden="true" tabindex="-1"></a>    <span class="op">}</span></span>
<span id="cb3-36"><a href="#cb3-36" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb3-37"><a href="#cb3-37" aria-hidden="true" tabindex="-1"></a>    <span class="co">// Finalise the hash</span></span>
<span id="cb3-38"><a href="#cb3-38" aria-hidden="true" tabindex="-1"></a>    EVP_DigestFinal_ex<span class="op">(&amp;</span>mdctx<span class="op">,</span> md_value<span class="op">,</span> <span class="op">&amp;</span>md_len<span class="op">);</span></span>
<span id="cb3-39"><a href="#cb3-39" aria-hidden="true" tabindex="-1"></a>    EVP_MD_CTX_cleanup<span class="op">(&amp;</span>mdctx<span class="op">);</span></span>
<span id="cb3-40"><a href="#cb3-40" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb3-41"><a href="#cb3-41" aria-hidden="true" tabindex="-1"></a>    <span class="co">// Convert the hash to a string</span></span>
<span id="cb3-42"><a href="#cb3-42" aria-hidden="true" tabindex="-1"></a>    msg_len <span class="op">=</span> <span class="dv">1</span> <span class="op">+</span> <span class="dv">2</span> <span class="op">*</span> md_len<span class="op">;</span></span>
<span id="cb3-43"><a href="#cb3-43" aria-hidden="true" tabindex="-1"></a>    cur <span class="op">=</span> digest <span class="op">=</span> <span class="op">(</span><span class="dt">char</span><span class="op">*)</span>malloc<span class="op">(</span>msg_len<span class="op">);</span></span>
<span id="cb3-44"><a href="#cb3-44" aria-hidden="true" tabindex="-1"></a>    <span class="cf">for</span> <span class="op">(</span>i<span class="op">=</span><span class="dv">0</span><span class="op">;</span>i<span class="op">&lt;</span>md_len<span class="op">;</span>i<span class="op">++)</span> <span class="op">{</span></span>
<span id="cb3-45"><a href="#cb3-45" aria-hidden="true" tabindex="-1"></a>        snprintf<span class="op">(</span>cur<span class="op">,</span> <span class="dv">3</span><span class="op">,</span> <span class="st">&quot;</span><span class="sc">%02x</span><span class="st">&quot;</span><span class="op">,</span> md_value<span class="op">[</span>i<span class="op">]);</span></span>
<span id="cb3-46"><a href="#cb3-46" aria-hidden="true" tabindex="-1"></a>        cur <span class="op">=</span> cur <span class="op">+</span> <span class="dv">2</span><span class="op">;</span></span>
<span id="cb3-47"><a href="#cb3-47" aria-hidden="true" tabindex="-1"></a>    <span class="op">}</span></span>
<span id="cb3-48"><a href="#cb3-48" aria-hidden="true" tabindex="-1"></a>    cur<span class="op">[</span><span class="dv">0</span><span class="op">]</span> <span class="op">=</span> <span class="ch">'</span><span class="sc">\0</span><span class="ch">'</span><span class="op">;</span></span>
<span id="cb3-49"><a href="#cb3-49" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb3-50"><a href="#cb3-50" aria-hidden="true" tabindex="-1"></a>    <span class="co">// Push the result onto the stack</span></span>
<span id="cb3-51"><a href="#cb3-51" aria-hidden="true" tabindex="-1"></a>    lua_pushstring<span class="op">(</span>L<span class="op">,</span> digest<span class="op">);</span></span>
<span id="cb3-52"><a href="#cb3-52" aria-hidden="true" tabindex="-1"></a>    free<span class="op">(</span>digest<span class="op">);</span></span>
<span id="cb3-53"><a href="#cb3-53" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb3-54"><a href="#cb3-54" aria-hidden="true" tabindex="-1"></a>    <span class="co">// Return the number of return values</span></span>
<span id="cb3-55"><a href="#cb3-55" aria-hidden="true" tabindex="-1"></a>    <span class="cf">return</span><span class="op">(</span><span class="dv">1</span><span class="op">);</span></span>
<span id="cb3-56"><a href="#cb3-56" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code></pre></div>
<p>With the function itself written, registering it so that it can be called by Lua code is simple too. Each C module (whether compiled into Lua or loaded as a shared object library) has a <code>luaopen_*()</code> function that is responsible for initialising the library and registering the resources it provides. There are utility functions to automatically register entire modules based on arrays of function pointers, but I’ve only got one function and there’s no point cramming it into a table, so I’ll go it alone. Again, it’s really easy:</p>
<div class="sourceCode" id="cb4"><pre class="sourceCode c"><code class="sourceCode c"><span id="cb4-1"><a href="#cb4-1" aria-hidden="true" tabindex="-1"></a>LUALIB_API <span class="dt">int</span> luaopen_hash<span class="op">(</span>lua_State <span class="op">*</span>L<span class="op">)</span> <span class="op">{</span></span>
<span id="cb4-2"><a href="#cb4-2" aria-hidden="true" tabindex="-1"></a>    lua_register<span class="op">(</span>L<span class="op">,</span> <span class="st">&quot;hash&quot;</span><span class="op">,</span> hash_hash<span class="op">);</span></span>
<span id="cb4-3"><a href="#cb4-3" aria-hidden="true" tabindex="-1"></a>    <span class="cf">return</span> <span class="dv">0</span><span class="op">;</span></span>
<span id="cb4-4"><a href="#cb4-4" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code></pre></div>
<h3 id="an-elegant-api">An elegant API</h3>
<p>This is all very well and good, but the API is pretty poor as it stands: a single function which takes a string (denoting the actual function to compute) and a bunch of inputs. It’s pretty cool that we can support all these functions with a single piece of code, but it’d be even better if our single piece of code implementing many functions looked like the many functions to the callers. Rather than <code>hash(&amp;quot;md5&amp;quot;, v1, v2, v3)</code>, we should be writing <code>md5(v1,v2,v3)</code>. Happily, this too is a cinch!</p>
<h4 id="tables-and-meta-tables">Tables and meta-tables</h4>
<p>You may or may not be familiar with <em>tables</em> – Lua’s single complex data-structure. Tables are a combination of arrays (sequential, integer indexed, etc.) with dictionaries/hashes (matching arbitrary keys with a value). Lua uses tables for pretty much everything including environments (wherein variables are stored) and modules (like our library).</p>
<p>If that was all there was to tables, then they wouldn’t be such a big thing. Thankfully it is not. In addition to their workaday nature as Lua’s catch all storage thingy, the semantics of tables can be modified using <a href="http://www.lua.org/manual/5.1/manual.html#2.8"><em>meta-tables</em></a> full of functions which implement aspects of their table’s semantics. Using meta-tables I can override the default behaviour of, say, looking up a value my module table and return a brand new object instead. An object that didn’t even exist until you asked for it.</p>
<p>Using this facility along with closures and anonymous functions I can hide my <code>hash_hash()</code> function above in a meta-table. It’s as simple as modifying <code>hash_hash()</code> to take the algorithm name from its closure (rather than the first parameter) and adding a new <em>wrapper</em> function to create these closures on request. It is this wrapper function that will go in the meta-table to give us a shiny new API.</p>
<h4 id="creating-the-closure">Creating the closure</h4>
<p>The first task is to create a closure of <code>hash_hash()</code> along with the algorithm name. Bearing in mind that this function is going to be called as the <strong>index</strong> operation, it will need to take two parameters: the table and the key. Given that it’ll only be called for my module table, I’ll just ignore the table argument.</p>
<div class="sourceCode" id="cb5"><pre class="sourceCode c"><code class="sourceCode c"><span id="cb5-1"><a href="#cb5-1" aria-hidden="true" tabindex="-1"></a><span class="dt">static</span> <span class="dt">int</span> hash<span class="op">(</span>lua_State <span class="op">*</span>L<span class="op">)</span> <span class="op">{</span></span>
<span id="cb5-2"><a href="#cb5-2" aria-hidden="true" tabindex="-1"></a>    <span class="dt">char</span> <span class="op">*</span>algorithm <span class="op">=</span> NULL<span class="op">;</span></span>
<span id="cb5-3"><a href="#cb5-3" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb5-4"><a href="#cb5-4" aria-hidden="true" tabindex="-1"></a>    <span class="co">// Get the name of the algorithm (the key)</span></span>
<span id="cb5-5"><a href="#cb5-5" aria-hidden="true" tabindex="-1"></a>    algorithm <span class="op">=</span> lua_tostring<span class="op">(</span>L<span class="op">,</span> <span class="dv">2</span><span class="op">);</span></span>
<span id="cb5-6"><a href="#cb5-6" aria-hidden="true" tabindex="-1"></a>    lua_pushstring<span class="op">(</span>L<span class="op">,</span> algorithm<span class="op">);</span></span>
<span id="cb5-7"><a href="#cb5-7" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb5-8"><a href="#cb5-8" aria-hidden="true" tabindex="-1"></a>    <span class="co">// Push a closure of that value with hash_hash()</span></span>
<span id="cb5-9"><a href="#cb5-9" aria-hidden="true" tabindex="-1"></a>    lua_pushcclosure<span class="op">(</span>L<span class="op">,</span> hash_hash<span class="op">,</span> <span class="dv">1</span><span class="op">);</span></span>
<span id="cb5-10"><a href="#cb5-10" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb5-11"><a href="#cb5-11" aria-hidden="true" tabindex="-1"></a>    <span class="cf">return</span> <span class="dv">1</span><span class="op">;</span></span>
<span id="cb5-12"><a href="#cb5-12" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code></pre></div>
<p>This code just reads the key from the stack as a string and pushes it back onto the stack (this may not be necessary, I’m not sure). Then it pushes a closure of this one value with <code>hash_hash()</code> onto the stack.</p>
<p>Modifying <code>hash_hash()</code> to use this closure value is just as ease. I just need to modify the <code>lua_tostring()</code> call that gets the algorithm name to get the first value from the closure instead of the first argument on the stack:</p>
<div class="sourceCode" id="cb6"><pre class="sourceCode c"><code class="sourceCode c"><span id="cb6-1"><a href="#cb6-1" aria-hidden="true" tabindex="-1"></a>algorithm <span class="op">=</span> <span class="op">(</span><span class="dt">char</span> <span class="op">*)</span>lua_tostring<span class="op">(</span>L<span class="op">,</span> lua_upvalueindex<span class="op">(</span><span class="dv">1</span><span class="op">));</span></span></code></pre></div>
<p>and modify the <code>for</code> loop to start at first argument instead of the second:</p>
<div class="sourceCode" id="cb7"><pre class="sourceCode c"><code class="sourceCode c"><span id="cb7-1"><a href="#cb7-1" aria-hidden="true" tabindex="-1"></a><span class="cf">for</span> <span class="op">(</span> i <span class="op">=</span> <span class="dv">1</span><span class="op">;</span> i <span class="op">&lt;=</span> arguments<span class="op">;</span> i<span class="op">++</span> <span class="op">)</span> <span class="op">{</span></span>
<span id="cb7-2"><a href="#cb7-2" aria-hidden="true" tabindex="-1"></a>    <span class="co">// ...</span></span>
<span id="cb7-3"><a href="#cb7-3" aria-hidden="true" tabindex="-1"></a><span class="op">}</span></span></code></pre></div>
<p>Now I’m ready to build and install the meta-table for my module and my powerful new API will be complete.</p>
<h4 id="hiding-behind-a-meta-table">Hiding behind a meta-table</h4>
<p>Binding this all up as an API is a little involved. As everything needs to pass through the stack, it’s easiest to create the various objects in order and avoid having to shuffle them around. In code order:</p>
<ol type="1">
<li>Create the module table;</li>
<li>Create the meta-table;</li>
<li>Add a reference to <code>hash_index()</code> in the meta-table;</li>
<li>Join the table and the meta-table; and</li>
<li>Assign the table to the global variable “hash”.</li>
</ol>
<p>This isn’t much longer in code. The body of <code>luaopen_hash()</code> now looks like:</p>
<div class="sourceCode" id="cb8"><pre class="sourceCode c"><code class="sourceCode c"><span id="cb8-1"><a href="#cb8-1" aria-hidden="true" tabindex="-1"></a><span class="co">// Create the table</span></span>
<span id="cb8-2"><a href="#cb8-2" aria-hidden="true" tabindex="-1"></a>lua_createtable<span class="op">(</span>L<span class="op">,</span><span class="dv">0</span><span class="op">,</span><span class="dv">0</span><span class="op">);</span></span>
<span id="cb8-3"><a href="#cb8-3" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb8-4"><a href="#cb8-4" aria-hidden="true" tabindex="-1"></a><span class="co">// Create the meta-table</span></span>
<span id="cb8-5"><a href="#cb8-5" aria-hidden="true" tabindex="-1"></a>lua_createtable<span class="op">(</span>L<span class="op">,</span><span class="dv">0</span><span class="op">,</span><span class="dv">1</span><span class="op">);</span></span>
<span id="cb8-6"><a href="#cb8-6" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb8-7"><a href="#cb8-7" aria-hidden="true" tabindex="-1"></a><span class="co">// Add the __index</span></span>
<span id="cb8-8"><a href="#cb8-8" aria-hidden="true" tabindex="-1"></a>lua_pushcfunction<span class="op">(</span>L<span class="op">,</span> hash_index<span class="op">);</span></span>
<span id="cb8-9"><a href="#cb8-9" aria-hidden="true" tabindex="-1"></a>lua_setfield<span class="op">(</span>L<span class="op">,</span> <span class="op">-</span><span class="dv">2</span><span class="op">,</span> <span class="st">&quot;__index&quot;</span><span class="op">);</span></span>
<span id="cb8-10"><a href="#cb8-10" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb8-11"><a href="#cb8-11" aria-hidden="true" tabindex="-1"></a><span class="co">// Set the meta-table</span></span>
<span id="cb8-12"><a href="#cb8-12" aria-hidden="true" tabindex="-1"></a>lua_setmetatable<span class="op">(</span>L<span class="op">,</span> <span class="op">-</span><span class="dv">2</span><span class="op">);</span></span>
<span id="cb8-13"><a href="#cb8-13" aria-hidden="true" tabindex="-1"></a></span>
<span id="cb8-14"><a href="#cb8-14" aria-hidden="true" tabindex="-1"></a><span class="co">// Set the global hash</span></span>
<span id="cb8-15"><a href="#cb8-15" aria-hidden="true" tabindex="-1"></a>lua_setfield<span class="op">(</span>L<span class="op">,</span> LUA_GLOBALSINDEX<span class="op">,</span> <span class="st">&quot;hash&quot;</span><span class="op">);</span></span></code></pre></div>
<p>A few notes might help make the above a little clearer. The stack can be
accessed with negative indices which count from the top rather than the bottom
(i.e. <code>-1</code> is the top, <code>-2</code> is second from the top, etc.) and there are a
number of magical indices that access such things as the globals table (like
<code>LUA_GLOBALSINDEX</code>).</p>
<p>With these changes made, my code now has an API that’s actually pretty great:
a single table that, by the magic of meta-tables, looks-up the appropriate
function as requested by the caller. It exposes a lot of functionality (six
different functions on my machine) but is implemented which only a fraction of
the code a traditional approach would need (about a sixth of it).</p>
<h3 id="where-do-we-go-from-here">“Where do we go from here?”</h3>
<p>The code I’ve described in this post is very simple but provides a powerful,
elegant interface that belies that simplicity.</p>
<p>The complete code for the module developed in this article is available as <a href="/files/2009/03/01/lhash.c">lhash.c</a>. Note, though, that I make no warranty as to its correctness or its fitness or suitability for any purpose.</p>
<p>Useful though it is, there are many ways it could be improved. Perhaps the
most important is improved error handling. As it stands, my code delays error
detection and handling ’til the latest possible moment: right as it’s about to
perform the hashing operation. It’s entirely reasonable (given Lua’s first
class functions) that a user might get a reference to a hash function and not
call it until much later in the program. It would be nice if, instead of
happily returning a closure, code like</p>
<div class="sourceCode" id="cb9"><pre class="sourceCode lua"><code class="sourceCode lua"><span id="cb9-1"><a href="#cb9-1" aria-hidden="true" tabindex="-1"></a><span class="va">f</span> <span class="op">=</span> <span class="va">hash</span><span class="op">.</span><span class="va">nonsense</span></span></code></pre></div>
<p>would fail immediately, rather than waiting until the program tries to call
<code>f</code>. To make it so, I need only to make to the code is to copy and paste the
algorithm lookup and test and – for good measure – move the OpenSSL
initialization call into the library open function. See the revised
<a href="/files/2009/03/01/lhash2.c">lhash2.c</a> for these changes. To make this even
more useful, I’d like to find out how to set the function name in the call
stack without registering it (and thus allowing the users to call it
directly).</p>
<p>It’s also not particularly self-documenting. Tables in Lua are iterable just
like similar structures in other languages. It’d be nice if callers could
iterate over the table and get a list of the valid keys, just as they can with
most other modules.</p>
<p>While generating a new closure every time the user wants one is cheap, it
would be nice to add memoization so that <code>hash_index()</code> doesn’t need to create
a new closure if it’s already created one for the requested algorithm. This
would also ensure that references to the same hash algorithm are identical
which is not currently the case (alas <code>hash.md5 != hash.md5</code>).</p>
<p>Finally, allowing the user to hash values other than strings and numbers.
Alas, this would be rather more complex what with having to serialize tables
for hashing (a difficult task without a stable sort and in the possible
presence of arbitrary opaque values from other C extensions).</p>
<p>When that lot’s done, it’ll be time to move on to the rest of OpenSSL…</p>]]></summary>
</entry>

</feed>
