Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP

Comparing changes

Choose two branches to see what's changed or to start a new pull request. If you need to, you can also compare across forks.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also compare across forks.
  • 13 commits
  • 15 files changed
  • 0 commit comments
  • 2 contributors
Commits on Feb 01, 2012
Brandon Philips Makefile: add test target
Add basic test runner and fixup test.lua to run OK without an argument.
8d36625
Brandon Philips Merge branch 'cleanup-fnew-functions' 39168e0
Commits on Feb 02, 2012
Brandon Philips lcrypto: remove variable key length logic from init_encryptor_decryptor
Variable key ciphers are ones that we never test for, namely:

- Blowfish
- RC2
- RC5
- CAST

This code doesn't work if your openssl implementation doesn't enable any
of these ciphers and there are no tests to even test if this code works.

Disable this code path until someone cares to fix it.
38788da
Brandon Philips Merge branch 'remove-variable-key-support' b43008c
Commits on Feb 03, 2012
Brandon Philips tests: generate a CA and a server cert
Generate some certs to test x509 functionality.
45443fc
Brandon Philips x509_ca: initial commit
Initial commit of code to verify an x509 cert against a CA.

Here is an example usage of the API:

ca = assert(crypto.x509_ca())
ca:add_pem(ca_cert)
assert(ca:verify_pem(cert_to_verify) == true, "failed to verify good cert")
17d6bc7
@philips philips Merge pull request #2 from racker/add-x509-ca-verify
Add x509 ca verify
249d325
Commits on Feb 04, 2012
Brandon Philips lcrypto.c: remove inlines
inlines at best are a micro optimization and all modern compilers figure
it out. On GCC 4.4 the exact same code is output with and without the
inline. And as a bonus this all should compile under Windows now.
8727d21
Brandon Philips lcrypto.c: return true if x509_ca:add_pem is OK
return a boolean instead of nothing on success
12d9742
Commits on Feb 08, 2012
Brandon Philips lcrypto: make it build under windows
Move all of the variable definitions to the top.
e880b12
Commits on Feb 29, 2012
@mkottman Merge pull requests from Brandon Phillips eeee4bc
Commits on Mar 01, 2012
@mkottman Updated documentation for new API - pkey, sign, verify, seal, open 7a6ab6e
@mkottman Bump version to 0.3.0 a6072a8
View
2  README
@@ -2,6 +2,6 @@ LuaCrypto provides a Lua frontend to the OpenSSL cryptographic library.
The OpenSSL features that are currently exposed are digests (MD5, SHA-1,
HMAC, and more) and crypto-grade random number generators.
-LuaCrypto also supports encryption and decryption (warning - beta quality code).
+LuaCrypto also supports encryption and decryption, signing and verifying, sealing and opening using the OpenSSL EVP API.
Please see docs at doc/us/index.html or http://luacrypto.luaforge.net/.
View
47 doc/us/examples.html
@@ -52,15 +52,15 @@
<li><a href="license.html">License</a></li>
</ul>
</div> <!-- id="navigation" -->
-
-<div id="content">
-
-
-<h2><a name="examples"></a>Example</h2>
-
-Below is a sample displaying the basic use of the library.
-
-<pre class="example">
+
+<div id="content">
+
+
+<h2><a name="examples"></a>Example</h2>
+
+Below is a sample displaying the basic use of the library.
+
+<pre class="example">
local crypto = require("crypto")
local evp = require("crypto.evp")
local hmac = require("crypto.hmac")
@@ -83,19 +83,16 @@
end
local md5_of_some_file = evp:digest()
</pre>
-
-</div> <!-- id="content" -->
-
-</div> <!-- id="main" -->
-
-<div id="about">
- <p><a href="http://validator.w3.org/check?uri=referer"><img src="http://www.w3.org/Icons/valid-xhtml10" alt="Valid XHTML 1.0!" height="31" width="88" /></a></p>
- <p><small>
- $Id: examples.html,v 1.1 2006/08/25 03:24:17 nezroy Exp $
- </small></p>
-</div> <!-- id="about" -->
-
-</div> <!-- id="container" -->
-
-</body>
-</html>
+
+</div> <!-- id="content" -->
+
+</div> <!-- id="main" -->
+
+<div id="about">
+ <p><a href="http://validator.w3.org/check?uri=referer"><img src="http://www.w3.org/Icons/valid-xhtml10" alt="Valid XHTML 1.0!" height="31" width="88" /></a></p>
+</div> <!-- id="about" -->
+
+</div> <!-- id="container" -->
+
+</body>
+</html>
View
20 doc/us/index.html
@@ -37,7 +37,7 @@
<li><a href="manual.html">Manual</a>
<ul>
<li><a href="manual.html#introduction">Introduction</a></li>
- <li><a href="manual.html#building">Building</a></li>
+ <li><a href="manual.html#building">Building</a></li>
<li><a href="manual.html#installation">Installation</a></li>
<li><a href="manual.html#reference">Reference</a></li>
</ul>
@@ -63,26 +63,29 @@
<h2><a name="status"></a>Status</h2>
-<p>Current version is 0.2.0. It was developed for Lua 5.1 but it is compatible with Lua 5.0 through the use of <a href="http://www.keplerproject.org/compat/">Compat-5.1.</a></p>
+<p>Current version is 0.3.0. It was developed for Lua 5.1 but it is compatible with Lua 5.0 through the use of <a href="http://www.keplerproject.org/compat/">Compat-5.1.</a></p>
<h2><a name="download"></a>Download</h2>
-<p>LuaCrypto can be downloaded from its <a href="http://luaforge.net/projects/luacrypto/files">Lua Forge</a> page.</p>
+<p>LuaCrypto can be downloaded from <a href="https://github.com/mkottman/luacrypto">GitHub</a> project page.</p>
<h2><a name="dependencies"></a>Dependencies</h2>
<ul>
- <li><a href="http://www.openssl.org/">OpenSSL</a> (0.9.7 or higher)</li>
+ <li><a href="http://www.openssl.org/">OpenSSL</a> (0.9.7 or higher)</li>
<li><a href="http://www.lua.org/">Lua 5.1</a> (or Lua 5.0 plus <a href="http://www.keplerproject.org/compat">Compat-5.1 Release 5</a>)</li>
</ul>
<h2><a name="history"></a>History</h2>
<dl class="history">
+ <dt><strong>0.3.0</strong> [1/Mar/2012]</dt>
+ <dd>Added encryption, decryption, signing, verifying, sealing and opening functionality.</dd>
+
<dt><strong>0.2.0</strong> [24/Aug/2006]</dt>
- <dd>Added random support.</dd>
+ <dd>Added random support.</dd>
<dd>Removed Lua stub files and collapsed modules.</dd>
- <dd>Changed all supporting materials (documentation, build, etc.) to Kepler standards.</dd>
+ <dd>Changed all supporting materials (documentation, build, etc.) to Kepler standards.</dd>
<dt><a href="http://luacrypto.luaforge.net/0.1/">0.1.1</a> [22/Jan/2006]</dt>
<dd>Added Lua 5.0/Compat-5.1 support.</dd>
@@ -93,11 +96,11 @@
<h2><a name="credits"></a>Credits</h2>
-<p>Much of the original release was based on the lmd5 project, written by <a href="http://lua-users.org/wiki/LuizHenriqueDeFigueiredo">Luiz Henrique de Figueiredo</a>. More recent versions were based on existing Kepler components and also incorporate changes contributed by <a href="http://lua-users.org/wiki/MarkEdgar">Mark Edgar</a>.</p>
+<p>Much of the original release was based on the lmd5 project, written by <a href="http://lua-users.org/wiki/LuizHenriqueDeFigueiredo">Luiz Henrique de Figueiredo</a>. More recent versions were based on existing Kepler components and also incorporate changes contributed by <a href="http://lua-users.org/wiki/MarkEdgar">Mark Edgar</a>. Encryption and decryption support was added by Michal Kottman, additional functionality and fixes were contributed by Ignacio Burgueño, Aleksandr Novitskiy and Brandon Philips.</p>
<h2><a name="contact"></a>Contact</h2>
-<p>For more information please <a href="mailto:nezroy-NO-SPAM-THANKS@luaforge.net">contact</a> me. Comments are welcome!</p>
+The project is currently maintained by Michal Kottman on <a href="https://github.com/mkottman/luacrypto">GitHub</a>, where you can file bug reports, feature requests and contribute modifications.
</div> <!-- id="content" -->
@@ -106,7 +109,6 @@
<div id="about">
<p><a href="http://validator.w3.org/check?uri=referer">
<img src="http://www.w3.org/Icons/valid-xhtml10" alt="Valid XHTML 1.0!" height="31" width="88" /></a></p>
- <p><small>$Id: index.html,v 1.2 2006/08/25 03:37:51 nezroy Exp $</small></p>
</div> <!-- id="about" -->
</div> <!-- id="container" -->
View
65 doc/us/license.html
@@ -20,38 +20,38 @@
<div id="main">
-<div id="navigation">
-<h1>LuaCrypto</h1>
- <ul>
- <li><a href="index.html">Home</a>
- <ul>
- <li><a href="index.html#overview">Overview</a></li>
- <li><a href="index.html#status">Status</a></li>
- <li><a href="index.html#download">Download</a></li>
- <li><a href="index.html#dependencies">Dependencies</a></li>
- <li><a href="index.html#history">History</a></li>
- <li><a href="index.html#credits">Credits</a></li>
- <li><a href="index.html#contact">Contact</a></li>
- </ul>
- </li>
- <li><a href="manual.html">Manual</a>
- <ul>
- <li><a href="manual.html#introduction">Introduction</a></li>
- <li><a href="manual.html#building">Building</a></li>
- <li><a href="manual.html#installation">Installation</a></li>
- <li><a href="manual.html#reference">Reference</a></li>
- </ul>
- </li>
- <li><a href="examples.html">Examples</a></li>
- <li><a href="http://luaforge.net/projects/luacrypto/">Project</a>
- <ul>
- <li><a href="http://luaforge.net/tracker/?group_id=149">Bug Tracker</a></li>
- <li><a href="http://luaforge.net/scm/?group_id=149">CVS</a></li>
- </ul>
- </li>
- <li><strong>License</strong></li>
- </ul>
-</div> <!-- id="navigation" -->
+<div id="navigation">
+<h1>LuaCrypto</h1>
+ <ul>
+ <li><a href="index.html">Home</a>
+ <ul>
+ <li><a href="index.html#overview">Overview</a></li>
+ <li><a href="index.html#status">Status</a></li>
+ <li><a href="index.html#download">Download</a></li>
+ <li><a href="index.html#dependencies">Dependencies</a></li>
+ <li><a href="index.html#history">History</a></li>
+ <li><a href="index.html#credits">Credits</a></li>
+ <li><a href="index.html#contact">Contact</a></li>
+ </ul>
+ </li>
+ <li><a href="manual.html">Manual</a>
+ <ul>
+ <li><a href="manual.html#introduction">Introduction</a></li>
+ <li><a href="manual.html#building">Building</a></li>
+ <li><a href="manual.html#installation">Installation</a></li>
+ <li><a href="manual.html#reference">Reference</a></li>
+ </ul>
+ </li>
+ <li><a href="examples.html">Examples</a></li>
+ <li><a href="http://luaforge.net/projects/luacrypto/">Project</a>
+ <ul>
+ <li><a href="http://luaforge.net/tracker/?group_id=149">Bug Tracker</a></li>
+ <li><a href="http://luaforge.net/scm/?group_id=149">CVS</a></li>
+ </ul>
+ </li>
+ <li><strong>License</strong></li>
+ </ul>
+</div> <!-- id="navigation" -->
<div id="content">
@@ -107,7 +107,6 @@
<div id="about">
<p><a href="http://validator.w3.org/check?uri=referer">
<img src="http://www.w3.org/Icons/valid-xhtml10" alt="Valid XHTML 1.0!" height="31" width="88" /></a></p>
- <p><small>$Id: license.html,v 1.1 2006/08/25 03:24:17 nezroy Exp $</small></p>
</div> <!-- id="about" -->
</div> <!-- id="container" -->
View
257 doc/us/manual.html
@@ -1,25 +1,25 @@
-<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
- "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
-<html>
-<head>
- <title>LuaCrypto: A Lua frontend to OpenSSL</title>
- <link rel="stylesheet" href="http://www.keplerproject.org/doc.css" type="text/css"/>
- <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
-</head>
-<body>
-
-<div id="container">
-
-<div id="product">
- <div id="product_logo">
- <a href="http://www.keplerproject.org"><img alt="LuaCrypto logo" src="luacrypto-128.png"/></a>
- </div>
- <div id="product_name"><big><strong>LuaCrypto</strong></big></div>
- <div id="product_description">A Lua frontend to OpenSSL</div>
-</div> <!-- id="product" -->
-
-<div id="main">
-
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
+ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+<html>
+<head>
+ <title>LuaCrypto: A Lua frontend to OpenSSL</title>
+ <link rel="stylesheet" href="http://www.keplerproject.org/doc.css" type="text/css"/>
+ <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
+</head>
+<body>
+
+<div id="container">
+
+<div id="product">
+ <div id="product_logo">
+ <a href="http://www.keplerproject.org"><img alt="LuaCrypto logo" src="luacrypto-128.png"/></a>
+ </div>
+ <div id="product_name"><big><strong>LuaCrypto</strong></big></div>
+ <div id="product_description">A Lua frontend to OpenSSL</div>
+</div> <!-- id="product" -->
+
+<div id="main">
+
<div id="navigation">
<h1>LuaCrypto</h1>
<ul>
@@ -53,26 +53,26 @@
</ul>
</div> <!-- id="navigation" -->
-<div id="content">
-<h2><a name="introduction"></a>Introduction</h2>
-
-<p>LuaCrypto is a <a href="http://www.lua.org">Lua</a> frontend to the <a href="http://www.openssl.org/">OpenSSL</a> cryptographic library. The OpenSSL features that are currently exposed are digests (MD5, SHA-1, HMAC, and more) and crypto-grade random number generators.</p>
-
-<p>The API tries to hide the OpenSSL setup and teardown, so in most cases it is not simply a pass-through to the existing OpenSSL API. Since this is still a very early version of the software, the API may undergo significant future changes! You have been warned.</p>
-
-<h2><a name="building"></a>Building</h2>
-
-<p>LuaCrypto could be built to Lua 5.0 or to Lua 5.1. In both cases, the language library and headers files for the target version must be installed properly.</p>
-
-<p>LuaCrypto offers a Makefile and a separate configuration file,
-<code>config</code>, which should be edited to suit your installation before runnig <code>make</code>. The file has some definitions like paths to the external libraries, compiler options and the like. In particular, you must set the correct path to your installed OpenSSL libraries. Another important setting is the version of Lua language, which is not obtained from the installed software.</p>
-
-<h2><a name="installation"></a>Installation</h2>
-
-<p>The LuaCrypto compiled binary should be copied to a directory in your <a href="http://www.lua.org/manual/5.1/manual.html#pdf-package.cpath">C path</a>. Lua 5.0 users should install <a href="http://www.keplerproject.org/compat">Compat-5.1</a> also.</p>
-
+<div id="content">
+<h2><a name="introduction"></a>Introduction</h2>
+
+<p>LuaCrypto is a <a href="http://www.lua.org">Lua</a> frontend to the <a href="http://www.openssl.org/">OpenSSL</a> cryptographic library. The OpenSSL features that are currently exposed are digests (MD5, SHA-1, HMAC, and more) and crypto-grade random number generators.</p>
+
+<p>The API tries to hide the OpenSSL setup and teardown, so in most cases it is not simply a pass-through to the existing OpenSSL API. Since this is still a very early version of the software, the API may undergo significant future changes! You have been warned.</p>
+
+<h2><a name="building"></a>Building</h2>
+
+<p>LuaCrypto could be built to Lua 5.0 or to Lua 5.1. In both cases, the language library and headers files for the target version must be installed properly.</p>
+
+<p>LuaCrypto offers a Makefile and a separate configuration file,
+<code>config</code>, which should be edited to suit your installation before runnig <code>make</code>. The file has some definitions like paths to the external libraries, compiler options and the like. In particular, you must set the correct path to your installed OpenSSL libraries. Another important setting is the version of Lua language, which is not obtained from the installed software.</p>
+
+<h2><a name="installation"></a>Installation</h2>
+
+<p>The LuaCrypto compiled binary should be copied to a directory in your <a href="http://www.lua.org/manual/5.1/manual.html#pdf-package.cpath">C path</a>. Lua 5.0 users should install <a href="http://www.keplerproject.org/compat">Compat-5.1</a> also.</p>
+
<h2><a name="reference"></a>Reference</h2>
-
+
<h3>Parameters</h3>
<dl>
<dt><strong>dtype</strong></dt>
@@ -86,10 +86,12 @@
<li>mdc2</li>
<li>ripemd160</li>
</ul>
- The list of supported hashing algorithms can also be retrieved by using the <code>crypto.list('digests')</code>.
+ The list of supported hashing algorithms can also be retrieved by using the <code>crypto.list("digests")</code>.
</dd>
+ <dt><strong>ktype</strong></dt>
+ <dd>A <b>string</b> representing public/private key type. Can be <code>"rsa"</code> or <code>"dsa"</code>.</dd>
<dt><strong>cipher</strong></dt>
- <dd>This parameter is a <b>string</b> naming the cipher algorithm used by encryption and decryption. The list of supported hashing algorithms can also be retrieved by using the <code>crypto.list('ciphers')</code>.
+ <dd>This parameter is a <b>string</b> naming the cipher algorithm used by encryption and decryption. The list of supported hashing algorithms can also be retrieved by using the <code>crypto.list("ciphers")</code>.
</dd>
<dt><strong>key</strong></dt>
<dd>The <b>string</b> key/password used for encryption/decryption.</dd>
@@ -106,105 +108,188 @@
The functions throw an error when known invalid parameters are passed, such as nonexistent digest/cipher and too large key or initialization vector. Otherwise, the functions return <code>nil, error</code> in case of runtime errors, such as incorrect input size when padding is enabled.
+
+
<h3>Message Digest - crypto.digest</h3>
+<p>Functions used to calculate cryptographic hashes of strings. Supported digest algorithms are returned by <code>crypto.list("digests")</code>.</p>
<dl>
<dt><strong>crypto.digest(dtype, string [, raw])</strong></dt>
<dd>This function generates the message digest of the input <code>string</code> and returns it. The hashing algorithm to use is specified by <code>dtype</code>. The optional <code>raw</code> flag, defaulted to false, is a boolean indicating whether the output should be a direct binary equivalent of the message digest, or formatted as a hexadecimal string (the default).</dd>
-
+
<dt><strong>crypto.digest.new(dtype)</strong></dt>
- <dd>Creates a new EVP message digest object using the algorithm specified by <code>dtype</code>.</dd>
-
+ <dd>Creates a new message digest object using the algorithm specified by <code>dtype</code>.</dd>
+
<dt><strong>digest:reset()</strong></dt>
<dd>Resets the EVP message digest object to a clean slate.</dd>
-
+
<dt><strong>digest:clone()</strong></dt>
<dd>Returns a new message digest object which is a clone of the object and its current state, including any data loaded to this point.</dd>
-
+
<dt><strong>digest:update(string)</strong></dt>
<dd>Appends the data in <code>string</code> to the current internal data set to be hashed. Returns the object so that it can be reused in nested calls.</dd>
-
+
<dt><strong>digest:final([string] [, raw])</strong></dt>
<dd>Generates the message digest for the loaded data, optionally appending on new data provided by <code>string</code> prior to hashing. The optional <code>raw</code> flag, defaulted to false, is a boolean indicating whether the output should be a direct binary equivalent of the message digest, or formatted as a hexadecimal string (the default).</dd>
</dl>
-<h3>Encryption - crypto.encrypt</h3>
+
+
+<h3>Encryption, decryption - crypto.encrypt, crypto.decrypt</h3>
+<p>A high-level API to encryption and decryption using ciphers. Supported ciphers can be detected by calling <code>crypto.list("ciphers")</code>.</p>
<dl>
<dt><strong>crypto.encrypt(cipher, input, key [, iv[, pad]])</strong></dt>
<dd>This function encrypts the the <code>input</code> string and returns the result. The encryption algorithm to use is specified by <code>cipher</code>. Encryption key is specified by the <code>key</code> parameter and is required. The optional <code>iv</code> parameter specifies an optional initialization vector. If boolean <code>pad</code> is specified after <code>iv</code>, it determines whether padding will be used (on by default).</dd>
-
+
+ <dt><strong>crypto.decrypt(cipher, input, key [, iv[, pad]])</strong></dt>
+ <dd>This function decrypts the the <code>input</code> string and returns the result. The decryption algorithm to use is specified by <code>cipher</code>. Decryption key is specified by the <code>key</code> parameter and is required. The optional <code>iv</code> parameter specifies an optional initialization vector. If boolean <code>pad</code> is specified after <code>iv</code>, it determines whether padding will be used (on by default).</dd>
+
<dt><strong>crypto.encrypt.new(cipher, key [, iv[, pad]])</strong></dt>
- <dd>Creates a new EVP encryption object using the algorithm specified by <code>cipher</code> and encryption key <code>key</code>. Optionally, initialization vector <code>iv</code> may be specified, followed by <code>pad</code> argument.</dd>
+ <dd>Creates a new encryption object using the algorithm specified by <code>cipher</code> and encryption key <code>key</code>. Optionally, initialization vector <code>iv</code> may be specified, followed by <code>pad</code> argument.</dd>
<dt><strong>encrypt:update(string)</strong></dt>
<dd>Appends the data in <code>string</code> to the current internal data. Returns a string with encrypted data, which may be of zero length if less than a message block size of data is provided.</dd>
-
+
<dt><strong>encrypt:final()</strong></dt>
<dd>Finishes the encryption, and returns any leftover encrypted data as string if necessary (due to padding).</dd>
-</dl>
-<h3>Decryption - crypto.decrypt</h3>
-<dl>
- <dt><strong>crypto.decrypt(cipher, input, key [, iv[, pad]])</strong></dt>
- <dd>This function decrypts the the <code>input</code> string and returns the result. The decryption algorithm to use is specified by <code>cipher</code>. Decryption key is specified by the <code>key</code> parameter and is required. The optional <code>iv</code> parameter specifies an optional initialization vector. If boolean <code>pad</code> is specified after <code>iv</code>, it determines whether padding will be used (on by default).</dd>
-
<dt><strong>crypto.decrypt.new(cipher, key [, iv[, pad]])</strong></dt>
- <dd>Creates a new EVP decryption object using the algorithm specified by <code>cipher</code> and decryption key <code>key</code>. Initialization vector <code>iv</code> may optionally be specified, followed by <code>pad</code> argument.</dd>
+ <dd>Creates a new decryption object using the algorithm specified by <code>cipher</code> and decryption key <code>key</code>. Initialization vector <code>iv</code> may optionally be specified, followed by <code>pad</code> argument.</dd>
<dt><strong>decrypt:update(string)</strong></dt>
<dd>Appends the data in <code>string</code> to the current internal data. Returns a string with decrypted data, which may be of zero length if less than a message block size of data is provided.</dd>
-
+
<dt><strong>decrypt:final()</strong></dt>
<dd>Finishes the decryption, and returns a string with any leftover decrypted data.</dd>
</dl>
+
+
+<h3>Public keys - crypto.pkey</h3>
+<p>Functions to work with public and private keys.</p>
+<dl>
+ <dt><strong>crypto.pkey.generate(ktype, len)</strong></dt>
+ <dd>Generates a new <code>ktype</code> ("rsa", "dsa") public/private key pair object of length <code>len</code> bits.</dd>
+
+ <dt><strong>crypto.pkey.read(filename [, private])</strong></dt>
+ <dd>Reads a public key from PEM file <code>filename</code>. If <code>private</code> is set, reads a private key instead.</dd>
+
+ <dt><strong>crypto.pkey.from_pem(key [, private])</strong></dt>
+ <dd>Reads a public key from PEM string <code>key</code>. If <code>private</code> is set, reads it as a private key instead.</dd>
+
+ <dt><strong>pkey:write(publicfile, privatefile)</strong></dt>
+ <dd>If <code>publicfile</code> is a string, writes the public key into PEM file <code>publicfile</code>. If <code>privatefile</code> is a string, writes the private key into PEM file <code>privatefile</code>.</dd>
+
+ <dt><strong>pkey:to_pem([private])</strong></dt>
+ <dd>Generates a PEM string representation of the public key. If <code>private</code> is set, generates a PEM string for the private key.</dd>
+</dl>
+
+
+<h3>Signing, verifying - crypto.sign, crypto.verify</h3>
+<p>A high-level interface to digital signatures. A digest algorithm is used to calculate a hash of the data, which is then signed using a private key into a signature. The signature can be used to verify a message using a public key.</p>
+
+<dl>
+ <dt><strong>crypto.sign(dtype, string, privkey)</strong></dt>
+ <dd>This function generates the message digest of the input <code>string</code>, signs it using the private key <code>privkey</code> and returns it as a raw binary string. The hashing algorithm to use is specified by <code>dtype</code>.</dd>
+
+ <dt><strong>crypto.verify(dtype, string, sig, pubkey)</strong></dt>
+ <dd>This function generates the message digest of the input <code>string</code> using digest <code>dtype</code>, and verifies it against signature <code>sig</code> using public key <code>pubkey</code>. Returns <b>true</b> if the message was verified correctly.</dd>
+
+ <dt><strong>crypto.sign.new(dtype)</strong></dt>
+ <dd>Creates a new signing object using the digest algorithm specified by <code>dtype</code>.</dd>
+
+ <dt><strong>sign:update(string)</strong></dt>
+ <dd>Appends the data in <code>string</code> to the current internal data set to be signed.</dd>
+
+ <dt><strong>sign:final(privkey)</strong></dt>
+ <dd>Generates the message digest for the loaded data and signs it using the private key <code>privkey</code>. The resulting signed hash is returned as a raw binary string.</dd>
+
+ <dt><strong>crypto.verify.new(dtype)</strong></dt>
+ <dd>Creates a new verifying object using the digest algorithm specified by <code>dtype</code>.</dd>
+
+ <dt><strong>verify:update(string)</strong></dt>
+ <dd>Appends the data in <code>string</code> to the current internal data set to be verified.</dd>
+
+ <dt><strong>verify:final(sign, pubkey)</strong></dt>
+ <dd>Generates the message digest for the loaded data and verifies it agains <code>sig</code> using the public key <code>pubkey</code>. Returns <b>true</b> if the message was verified correctly.</dd>
+</dl>
+
+
+
+<h3>Sealing and opening - crypto.seal, crypto.open</h3>
+<p>A high-level interface to digital envelopes. They generate a random key and IV, and then envelope it by using public key encryption. Data can then be encrypted using this key.
+<dl>
+ <dt><strong>envelope, ek, iv = crypto.seal(cipher, message, pubkey)</strong></dt>
+ <dd>Seals a string <code>message</code> using cipher <code>cipher</code> and public key <code>pubkey</code>. Returns 3 string values: sealed message, the generated encryption key signed with public key and the initialization vector.</dd>
+
+ <dt><strong>crypto.open(cipher, envelope, privkey, ek, iv)</strong></dt>
+ <dd>Opens a sealed <code>envelope</code> using private key <code>privkey</code>, key <code>ek</code> and initialization vector <code>iv</code>. Returns the sealed message.</dd>
+
+ <dt><strong>crypto.seal.new(cipher, pubkey)</strong></dt>
+ <dd>Creates a new sealing object using the algorithm specified by <code>cipher</code> and a public key <code>pubkey</code>.</dd>
+
+ <dt><strong>seal:update(string)</strong></dt>
+ <dd>Appends the data in <code>string</code> to the current internal data. Returns a string with encrypted data, which may be of zero length if less than a message block size of data is provided.</dd>
+
+ <dt><strong>seal:final()</strong></dt>
+ <dd>Finishes the sealing and returns 3 values: any leftover encrypted data as string, followed by the encryption key and initialization vector.</dd>
+
+ <dt><strong>crypto.open.new(cipher, privkey, ek, iv)</strong></dt>
+ <dd>Creates a new opening object using the algorithm specified by <code>cipher</code>, private key <code>privkey</code>, encryption key <code>ek</code> and initialization vector <code>iv</code>.</dd>
+
+ <dt><strong>open:update(string)</strong></dt>
+ <dd>Appends the data in <code>string</code> to the current internal data. Returns a string with decrypted data, which may be of zero length if less than a message block size of data is provided.</dd>
+
+ <dt><strong>open:final()</strong></dt>
+ <dd>Finishes the opening, and returns leftover decrypted data as string.</dd>
+</dl>
+
+
<h3>HMAC - crypto.hmac</h3>
<dl>
<dt><strong>crypto.hmac.digest(dtype, string, key [, raw])</strong></dt>
<dd>This function returns the HMAC of the <code>string</code>. The hashing algorithm to use is specified by <code>dtype</code>. The value provided in <code>key</code> will be used as the seed for the HMAC generation. The optional <code>raw</code> flag, defaulted to false, is a boolean indicating whether the output should be a direct binary equivalent of the HMAC or formatted as a hexadecimal string (the default).</dd>
-
+
<dt><strong>crypto.hmac.new(dtype, key)</strong></dt>
<dd>Creates a new HMAC object using the algorithm specified by <code>type</code>. The HMAC seed key to use is provided by <code>key</code>.</dd>
-
+
<dt><strong>hmac:reset()</strong></dt>
<dd>Resets the HMAC object to a clean slate.</dd>
-
+
<dt><strong>hmac:clone()</strong></dt>
<dd>Returns a new HMAC object which is a clone of the object and its current state, including data loaded to this point. DOES NOT WORK YET. Just returns a new pointer to the same object.</dd>
-
+
<dt><strong>hmac:update(string)</strong></dt>
<dd>Appends the data in <code>string</code> to the current internal data set to be hashed.</dd>
-
+
<dt><strong>hmac:final([string] [, raw])</strong></dt>
- <dd>Generates the HMAC for the loaded data, optionally appending on new data provided by <code>string</code> prior to hashing. The optional <code>raw</code> flag, defaulted to false, is a boolean indicating whether the output should be a direct binary equivalent of the message digest or formatted as a hexadecimal string (the default). Note that you can only run this method once on an object; running it a second time will product a bogus HMAC because the internal state is irrecovably destroyed after the first call.</dd>
+ <dd>Generates the HMAC for the loaded data, optionally appending on new data provided by <code>string</code> prior to hashing. The optional <code>raw</code> flag, defaulted to false, is a boolean indicating whether the output should be a direct binary equivalent of the message digest or formatted as a hexadecimal string (the default). Note that you can only run this method once on an object; running it a second time will product a bogus HMAC because the internal state is irrecoverably destroyed after the first call.</dd>
</dl>
+
<h3>Misc functions - crypto</h3>
<dl>
<dt><strong>crypto.list(type)</strong></dt>
- <dd>Returns an array table of supported digests and ciphers, depending on then <code>type</code> argument:
+ <dd>Returns a Lua table array of supported digests and ciphers (strings), depending on then <code>type</code> argument:
<ul>
<li><code>"ciphers"</code> - returns list of ciphers supported by <code>crypto.encrypt</code> and <code>crypto.decrypt</code></li>
<li><code>"digests"</code> - returns list of digests supported by <code>crypto.digest</code></li>
</ul>
</dd>
-
+
<dt><strong>crypto.hex(s)</strong></dt>
<dd>Expects a string <code>s</code> and returns it encoded as hex string (lowercase).</dd>
-</dl>
-
-</div> <!-- id="content" -->
-
-</div> <!-- id="main" -->
-
-<div id="about">
- <p><a href="http://validator.w3.org/check?uri=referer"><img src="http://www.w3.org/Icons/valid-xhtml10" alt="Valid XHTML 1.0!" height="31" width="88" /></a></p>
- <p><small>
- $Id: manual.html,v 1.1 2006/08/25 03:24:17 nezroy Exp $
- </small></p>
-</div> <!-- id="about" -->
-
-</div> <!-- id="container" -->
-
-</body>
-</html>
+</dl>
+
+</div> <!-- id="content" -->
+
+</div> <!-- id="main" -->
+
+<div id="about">
+ <p><a href="http://validator.w3.org/check?uri=referer"><img src="http://www.w3.org/Icons/valid-xhtml10" alt="Valid XHTML 1.0!" height="31" width="88" /></a></p>
+</div> <!-- id="about" -->
+
+</div> <!-- id="container" -->
+
+</body>
+</html>
View
360 src/lcrypto.c
@@ -12,6 +12,7 @@
#include <openssl/dsa.h>
#include <openssl/pem.h>
#include <openssl/bio.h>
+#include <openssl/x509.h>
#include <stddef.h>
@@ -25,21 +26,10 @@
# define UNUSED
#endif
-#ifdef __cplusplus
-#include "lua.hpp"
-#else
#include "lua.h"
-#endif
#include "lauxlib.h"
-#if ! defined (LUA_VERSION_NUM) || LUA_VERSION_NUM < 501
-#include "compat-5.1.h"
-#endif
-
#include "lcrypto.h"
-#ifdef __cplusplus
-extern "C"
-#endif
LUACRYPTO_API int luaopen_crypto(lua_State *L);
static int crypto_error(lua_State *L)
@@ -66,11 +56,12 @@ static int digest_fnew(lua_State *L)
{
const char *s = luaL_checkstring(L, 1);
const EVP_MD *digest = EVP_get_digestbyname(s);
+ EVP_MD_CTX *c;
if (digest == NULL)
return luaL_argerror(L, 1, "invalid digest/cipher type");
- EVP_MD_CTX *c = digest_pnew(L);
+ c = digest_pnew(L);
EVP_MD_CTX_init(c);
if (EVP_DigestInit_ex(c, digest, NULL) != 1)
return crypto_error(L);
@@ -176,17 +167,17 @@ static int digest_fdigest(lua_State *L)
{
const char *type_name = luaL_checkstring(L, 2);
const EVP_MD *type = EVP_get_digestbyname(type_name);
+ const char *s = luaL_checkstring(L, 3);
+ unsigned char digest[EVP_MAX_MD_SIZE];
+ unsigned int written = 0;
+ EVP_MD_CTX *c;
if (type == NULL) {
luaL_argerror(L, 1, "invalid digest type");
return 0;
}
- const char *s = luaL_checkstring(L, 3);
- unsigned char digest[EVP_MAX_MD_SIZE];
- unsigned int written = 0;
-
- EVP_MD_CTX *c = EVP_MD_CTX_create();
+ c = EVP_MD_CTX_create();
if (!EVP_DigestInit_ex(c, type, NULL)) {
EVP_MD_CTX_destroy(c);
return crypto_error(L);
@@ -246,14 +237,14 @@ static int parse_enc_params(lua_State *L, EVP_CIPHER** cipher, char** key, size_
return 1;
}
-static inline int parse_new_enc_params(lua_State *L, EVP_CIPHER** cipher, char** key, size_t *key_len,
+static int parse_new_enc_params(lua_State *L, EVP_CIPHER** cipher, char** key, size_t *key_len,
char** iv, size_t* iv_len, int* pad, int* size_to_return)
{
return parse_enc_params(L, cipher, key, key_len, iv, iv_len, pad, size_to_return,
1, 2, 3, 4);
}
-static inline int parse_f_enc_params(lua_State *L, EVP_CIPHER** cipher, char** key, size_t *key_len,
+static int parse_f_enc_params(lua_State *L, EVP_CIPHER** cipher, char** key, size_t *key_len,
char** iv, size_t* iv_len, int* pad, int* size_to_return)
{
return parse_enc_params(L, cipher, key, key_len, iv, iv_len, pad, size_to_return,
@@ -266,40 +257,21 @@ static int init_encryptor_decryptor(int (*init_fun)(EVP_CIPHER_CTX*, const EVP_C
lua_State *L, EVP_CIPHER_CTX *c, const EVP_CIPHER* cipher, const char* key, size_t key_len,
const char* iv, size_t iv_len, int pad, int* size_to_return)
{
+ unsigned char the_key[EVP_MAX_KEY_LENGTH] = {0};
+ unsigned char the_iv[EVP_MAX_IV_LENGTH] = {0};
+
EVP_CIPHER_CTX_init(c);
TRY_CTX(init_fun(c, cipher, NULL, NULL, NULL))
+
if (!pad)
TRY_CTX(EVP_CIPHER_CTX_set_padding(c, 0))
- const EVP_CIPHER* var_key_ciphers[] = {
- EVP_rc4(), EVP_rc4_40(),
- EVP_rc2_ofb(), EVP_rc2_cbc(), EVP_rc2_ecb(), EVP_rc2_cfb(), EVP_rc2_ofb(),
- EVP_rc2_40_cbc(), EVP_rc2_64_cbc(),
- EVP_bf_cbc(), EVP_bf_ecb(), EVP_bf_cfb(), EVP_bf_ofb(),
- EVP_cast5_cbc(), EVP_cast5_ecb(), EVP_cast5_cfb(), EVP_cast5_ofb(),
-// EVP_rc5_32_12_16_cbc(), EVP_rc5_32_12_16_cfb(), EVP_rc5_32_12_16_ecb(), EVP_rc5_32_12_16_ofb()
- };
- unsigned char the_iv[EVP_MAX_IV_LENGTH] = {0};
- if (iv) {
+ if (iv)
memcpy(the_iv, iv, iv_len);
- }
- int is_var_key = 0;
- size_t i;
- for (i = 0 ; i < sizeof(var_key_ciphers) / sizeof(*var_key_ciphers) ; ++i) {
- if (var_key_ciphers[i] == cipher) {
- is_var_key = 1;
- break;
- }
- }
- if (is_var_key) {
- TRY_CTX(EVP_CIPHER_CTX_set_key_length(c, (int)key_len))
- TRY_CTX(init_fun(c, NULL, NULL, (const unsigned char *)key, iv ? the_iv : NULL))
- } else {
- unsigned char the_key[EVP_MAX_KEY_LENGTH] = {0};
- memcpy(the_key, key, key_len);
- TRY_CTX(init_fun(c, NULL, NULL, the_key, the_iv))
- }
+ memcpy(the_key, key, key_len);
+ TRY_CTX(init_fun(c, NULL, NULL, the_key, the_iv))
+
return 1;
}
@@ -319,12 +291,14 @@ static int encrypt_fnew(lua_State *L)
size_t key_len = 0, iv_len = 0;
int pad = 1, size_to_return = 0;
+ EVP_CIPHER_CTX *c;
+
if (!parse_new_enc_params(L, (EVP_CIPHER**)&cipher, (char**)&key, &key_len,
(char**)&iv, &iv_len, &pad, &size_to_return)) {
return size_to_return;
}
- EVP_CIPHER_CTX *c = encrypt_pnew(L);
+ c = encrypt_pnew(L);
if (!init_encryptor_decryptor(EVP_EncryptInit_ex, L, c, cipher, key, key_len, iv, iv_len, pad, &size_to_return)) {
return size_to_return;
}
@@ -392,18 +366,23 @@ static int encrypt_fencrypt(lua_State *L)
size_t key_len = 0, iv_len = 0;
const char *key = NULL, *iv = NULL;
int pad = 0, size_to_return = 0;
+ EVP_CIPHER_CTX c;
+
+ int output_len = 0;
+ int len = 0;
+
+ unsigned char *buffer;
+
if (!parse_f_enc_params(L, (EVP_CIPHER**)&type, (char**)&key, &key_len, (char**)&iv, &iv_len, &pad, &size_to_return)) {
return size_to_return;
}
- EVP_CIPHER_CTX c;
if (!init_encryptor_decryptor(EVP_EncryptInit_ex, L, &c, type, key, key_len, iv, iv_len, pad, &size_to_return)) {
return size_to_return;
}
- int output_len = 0;
- int len = 0;
- unsigned char *buffer = (unsigned char*)malloc(input_len + (size_t)EVP_CIPHER_CTX_block_size(&c));
+
+ buffer = (unsigned char*)malloc(input_len + (size_t)EVP_CIPHER_CTX_block_size(&c));
if (!EVP_EncryptUpdate(&c, buffer, &len, input, (int)input_len)) {
EVP_CIPHER_CTX_cleanup(&c);
@@ -441,13 +420,14 @@ static int decrypt_fnew(lua_State *L)
size_t key_len = 0, iv_len = 0;
int pad = 1, size_to_return = 0;
+ EVP_CIPHER_CTX *c;
if (!parse_new_enc_params(L, (EVP_CIPHER**)&cipher, (char**)&key, &key_len,
(char**)&iv, &iv_len, &pad, &size_to_return)) {
return size_to_return;
}
- EVP_CIPHER_CTX *c = decrypt_pnew(L);
+ c = decrypt_pnew(L);
if (!init_encryptor_decryptor(EVP_DecryptInit_ex, L, c, cipher, key, key_len, iv, iv_len, pad, &size_to_return)) {
return size_to_return;
}
@@ -513,18 +493,22 @@ static int decrypt_fdecrypt(lua_State *L)
size_t key_len = 0, iv_len = 0;
const char *key = NULL, *iv = NULL;
int pad = 0, size_to_return = 0;
+ EVP_CIPHER_CTX c;
+ unsigned char *buffer;
+ int output_len = 0;
+ int len = 0;
+
+
if (!parse_f_enc_params(L, (EVP_CIPHER**)&type, (char**)&key, &key_len, (char**)&iv, &iv_len, &pad, &size_to_return)) {
return size_to_return;
}
- EVP_CIPHER_CTX c;
+
if (!init_encryptor_decryptor(EVP_DecryptInit_ex, L, &c, type, key, key_len, iv, iv_len, pad, &size_to_return)) {
return size_to_return;
}
- int output_len = 0;
- int len = 0;
- unsigned char *buffer = (unsigned char *)malloc(input_len + (size_t)EVP_CIPHER_CTX_block_size(&c));
+ buffer = (unsigned char *)malloc(input_len + (size_t)EVP_CIPHER_CTX_block_size(&c));
if (!EVP_DecryptUpdate(&c, buffer, &len, input, (int)input_len)) {
EVP_CIPHER_CTX_cleanup(&c);
free(buffer);
@@ -644,18 +628,23 @@ static int hmac_fdigest(lua_State *L)
{
const char *t = luaL_checkstring(L, 1);
const EVP_MD *type = EVP_get_digestbyname(t);
+ const char *s;
+ const char *k;
+ unsigned char digest[EVP_MAX_MD_SIZE];
+ unsigned int written = 0;
+ unsigned int i;
+ char *hex;
+ HMAC_CTX c;
+
if (type == NULL) {
luaL_argerror(L, 1, "invalid digest type");
return 0;
}
- const char *s = luaL_checkstring(L, 2);
- const char *k = luaL_checkstring(L, 3);
+ s = luaL_checkstring(L, 2);
+ k = luaL_checkstring(L, 3);
- unsigned char digest[EVP_MAX_MD_SIZE];
- unsigned int written = 0;
- HMAC_CTX c;
HMAC_CTX_init(&c);
HMAC_Init_ex(&c, k, (int)lua_strlen(L, 3), type, NULL);
HMAC_Update(&c, (unsigned char *)s, lua_strlen(L, 2));
@@ -665,8 +654,7 @@ static int hmac_fdigest(lua_State *L)
if (lua_toboolean(L, 4))
lua_pushlstring(L, (char *)digest, written);
else {
- char *hex = (char*)calloc(sizeof(char), written*2 + 1);
- unsigned int i;
+ hex = (char*)calloc(sizeof(char), written*2 + 1);
for (i = 0; i < written; i++)
sprintf(hex + 2*i, "%02x", digest[i]);
lua_pushlstring(L, hex, written*2);
@@ -690,11 +678,12 @@ static int sign_fnew(lua_State *L)
{
const char *s = luaL_checkstring(L, 1);
const EVP_MD *md = EVP_get_digestbyname(s);
+ EVP_MD_CTX *c;
if (md == NULL)
return luaL_argerror(L, 1, "invalid digest type");
- EVP_MD_CTX *c = sign_pnew(L);
+ c = sign_pnew(L);
EVP_MD_CTX_init(c);
if (EVP_SignInit_ex(c, md, NULL) != 1)
return crypto_error(L);
@@ -1151,13 +1140,15 @@ static int seal_fnew(lua_State* L)
const char *cipher_type = luaL_checkstring(L, 1);
const EVP_CIPHER *cipher = EVP_get_cipherbyname(cipher_type);
int npubk = 1;
+ EVP_PKEY **pkey;
+ seal_context *seal_ctx;
if (cipher == NULL)
return luaL_argerror(L, 1, "invalid encrypt cipher");
- EVP_PKEY **pkey = (EVP_PKEY **)luaL_checkudata(L, 2, LUACRYPTO_PKEYNAME);
+ pkey = (EVP_PKEY **)luaL_checkudata(L, 2, LUACRYPTO_PKEYNAME);
- seal_context *seal_ctx = seal_pnew(L);
+ seal_ctx = seal_pnew(L);
EVP_CIPHER_CTX_init(seal_ctx->ctx);
seal_ctx->ek = (unsigned char*)malloc((size_t)EVP_PKEY_size(*pkey) * (size_t)npubk);
@@ -1210,23 +1201,31 @@ static int seal_fseal(lua_State* L)
/* parameter 1 is the 'crypto.seal' table */
const char *cipher_type = luaL_checkstring(L, 2);
const EVP_CIPHER *cipher = EVP_get_cipherbyname(cipher_type);
+ EVP_PKEY **pkey = (EVP_PKEY **)luaL_checkudata(L, 4, LUACRYPTO_PKEYNAME);
+ int npubk = 1;
+ int eklen;
+ unsigned char iv[EVP_MAX_IV_LENGTH];
+ const unsigned char* message;
+ int message_length;
+ unsigned char *ek;
+ int block_size;
+ EVP_CIPHER_CTX ctx;
+ luaL_Buffer buffer;
+ int output_length;
+ char *temp;
+ int sz;
+
if (cipher == NULL) {
luaL_argerror(L, 1, "invalid encrypt cipher");
return 0;
}
- int npubk = 1;
- int eklen;
- unsigned char iv[EVP_MAX_IV_LENGTH];
-
- const unsigned char* message = (const unsigned char*)luaL_checkstring(L, 3);
- int message_length = (int)lua_objlen(L, 3);
+ message = (const unsigned char*)luaL_checkstring(L, 3);
+ message_length = (int)lua_objlen(L, 3);
- EVP_PKEY **pkey = (EVP_PKEY **)luaL_checkudata(L, 4, LUACRYPTO_PKEYNAME);
- unsigned char *ek = (unsigned char*)malloc((size_t)EVP_PKEY_size(*pkey) * (size_t)npubk);
+ ek = (unsigned char*)malloc((size_t)EVP_PKEY_size(*pkey) * (size_t)npubk);
- EVP_CIPHER_CTX ctx;
EVP_CIPHER_CTX_init(&ctx);
if (!EVP_SealInit(&ctx, cipher, &ek, &eklen, iv, pkey, npubk)) {
@@ -1235,15 +1234,13 @@ static int seal_fseal(lua_State* L)
return crypto_error(L);
}
- luaL_Buffer buffer;
luaL_buffinit(L, &buffer);
- int block_size = EVP_CIPHER_block_size(cipher);
+ block_size = EVP_CIPHER_block_size(cipher);
while (message_length > 0) {
- char* temp = luaL_prepbuffer(&buffer);
- int sz = MIN(LUAL_BUFFERSIZE - block_size - 1, message_length);
- int output_length;
+ temp = luaL_prepbuffer(&buffer);
+ sz = MIN(LUAL_BUFFERSIZE - block_size - 1, message_length);
if(!EVP_SealUpdate(&ctx, (unsigned char*)temp, &output_length, message, sz)) {
free(ek);
@@ -1255,8 +1252,7 @@ static int seal_fseal(lua_State* L)
luaL_addsize(&buffer, output_length);
}
- int output_length;
- char *temp = luaL_prepbuffer(&buffer);
+ temp = luaL_prepbuffer(&buffer);
if (!EVP_SealFinal(&ctx, (unsigned char*)temp, &output_length)) {
free(ek);
EVP_CIPHER_CTX_cleanup(&ctx);
@@ -1298,7 +1294,7 @@ static open_context *open_pnew(lua_State* L)
static int open_gc(lua_State* L)
{
- open_context *c = (open_context*)luaL_checkudata(L, 1, LUACRYPTO_OPENNAME);
+ open_context *c = luaL_checkudata(L, 1, LUACRYPTO_OPENNAME);
EVP_CIPHER_CTX_cleanup(c->ctx);
free(c->ctx);
if (c->pkey_ref != LUA_NOREF) {
@@ -1310,11 +1306,10 @@ static int open_gc(lua_State* L)
static int open_tostring(lua_State* L)
{
open_context *c = (open_context*)luaL_checkudata(L, 1, LUACRYPTO_OPENNAME);
-
- lua_rawgeti(L, LUA_REGISTRYINDEX, c->pkey_ref);
EVP_PKEY **pkey = (EVP_PKEY **)luaL_checkudata(L, -1, LUACRYPTO_PKEYNAME);
-
char s[64];
+
+ lua_rawgeti(L, LUA_REGISTRYINDEX, c->pkey_ref);
sprintf(s, "%s %p %s %s %d %p", LUACRYPTO_OPENNAME, (void *)c, EVP_CIPHER_name(c->cipher),
(*pkey)->type == EVP_PKEY_DSA ? "DSA" : "RSA", EVP_PKEY_bits(*pkey), pkey);
@@ -1329,11 +1324,13 @@ static int open_fnew(lua_State* L)
const EVP_CIPHER *cipher = EVP_get_cipherbyname(type_name);
const unsigned char* encrypted_key;
const unsigned char* iv;
+ EVP_PKEY **pkey;
+ open_context *open_ctx;
if (cipher == NULL)
return luaL_argerror(L, 1, "invalid decrypt cipher");
- EVP_PKEY **pkey = (EVP_PKEY **)luaL_checkudata(L, 2, LUACRYPTO_PKEYNAME);
+ pkey = (EVP_PKEY **)luaL_checkudata(L, 2, LUACRYPTO_PKEYNAME);
/* checks for the encrypted key */
encrypted_key = (const unsigned char*)luaL_checkstring(L, 3);
@@ -1343,7 +1340,7 @@ static int open_fnew(lua_State* L)
if ((size_t)EVP_CIPHER_iv_length(cipher) != lua_objlen(L, 4))
return luaL_argerror(L, 4, "invalid iv length");
- open_context *open_ctx = open_pnew(L);
+ open_ctx = open_pnew(L);
EVP_CIPHER_CTX_init(open_ctx->ctx);
open_ctx->cipher = (EVP_CIPHER*)cipher;
@@ -1400,41 +1397,50 @@ static int open_fopen(lua_State* L)
/* parameter 1 is the 'crypto.open' table */
const char *type_name = luaL_checkstring(L, 2);
const EVP_CIPHER *cipher = EVP_get_cipherbyname(type_name);
+ unsigned char* data;
+ int data_length;
+ EVP_PKEY **pkey;
+ const unsigned char* encrypted_key;
+ const unsigned char* iv;
+ EVP_CIPHER_CTX ctx;
+ int eklen;
+ int output_length;
+ unsigned char* temp;
+ size_t sz;
+ luaL_Buffer buffer;
+
if (cipher == NULL) {
luaL_argerror(L, 1, "invalid decrypt cipher");
return 0;
}
- unsigned char* data = (unsigned char*)luaL_checkstring(L, 3);
- int data_length = (int)lua_objlen(L, 3);
+ data = (unsigned char*)luaL_checkstring(L, 3);
+ data_length = (int)lua_objlen(L, 3);
- EVP_PKEY **pkey = (EVP_PKEY **)luaL_checkudata(L, 4, LUACRYPTO_PKEYNAME);
+ pkey = (EVP_PKEY **)luaL_checkudata(L, 4, LUACRYPTO_PKEYNAME);
- const unsigned char* encrypted_key = (const unsigned char*)luaL_checkstring(L, 5);
- const unsigned char* iv = (const unsigned char*)luaL_checkstring(L, 6);
+ encrypted_key = (const unsigned char*)luaL_checkstring(L, 5);
+ iv = (const unsigned char*)luaL_checkstring(L, 6);
if ((size_t)EVP_CIPHER_iv_length(cipher) != lua_objlen(L, 6)) {
luaL_argerror(L, 6, "invalid iv length");
return 0;
}
- EVP_CIPHER_CTX ctx;
EVP_CIPHER_CTX_init(&ctx);
- int eklen = (int)lua_objlen(L, 5);
+ eklen = (int)lua_objlen(L, 5);
if (!EVP_OpenInit(&ctx, cipher, encrypted_key, eklen, iv, *pkey)) {
EVP_CIPHER_CTX_cleanup(&ctx);
return crypto_error(L);
}
- luaL_Buffer buffer;
luaL_buffinit(L, &buffer);
while (data_length > 0) {
- int output_length;
- unsigned char* temp = (unsigned char*)luaL_prepbuffer(&buffer);
- size_t sz = MIN(LUAL_BUFFERSIZE - 1U, (size_t)data_length);
+ temp = (unsigned char*)luaL_prepbuffer(&buffer);
+ sz = MIN(LUAL_BUFFERSIZE - 1U, (size_t)data_length);
if(!EVP_OpenUpdate(&ctx, temp, &output_length, data, (int)sz)) {
EVP_CIPHER_CTX_cleanup(&ctx);
return crypto_error(L);
@@ -1445,8 +1451,7 @@ static int open_fopen(lua_State* L)
luaL_addsize(&buffer, output_length);
}
- int output_length;
- unsigned char *temp = (unsigned char*)luaL_prepbuffer(&buffer);
+ temp = (unsigned char*)luaL_prepbuffer(&buffer);
if (!EVP_OpenFinal(&ctx, temp, &output_length)) {
EVP_CIPHER_CTX_cleanup(&ctx);
return crypto_error(L);
@@ -1491,6 +1496,135 @@ static int luacrypto_hex(lua_State *L)
return 1;
}
+/*************** x509 API ***************/
+
+static X509 *x509__load_cert(BIO *cert)
+{
+ X509 *x = PEM_read_bio_X509_AUX(cert, NULL, NULL, NULL);
+ return x;
+}
+
+struct x509_ca {
+ X509_STORE *store;
+ STACK_OF(X509) *stack;
+};
+
+static int x509_ca_fnew(lua_State *L)
+{
+ struct x509_ca *x = lua_newuserdata(L, sizeof(struct x509_ca));
+
+ x->store = X509_STORE_new();
+ x->stack = sk_X509_new_null();
+
+ luaL_getmetatable(L, LUACRYPTO_X509_CA_NAME);
+ lua_setmetatable(L, -2);
+
+ return 1;
+}
+
+static int x509_ca_fx509_ca(lua_State *L)
+{
+ return x509_ca_fnew(L);
+}
+
+static struct x509_ca *x509_ca__get(lua_State *L)
+{
+ return luaL_checkudata(L, 1, LUACRYPTO_X509_CA_NAME);
+}
+
+static int x509_ca_gc(lua_State *L)
+{
+ struct x509_ca *c = x509_ca__get(L);
+ sk_X509_pop_free(c->stack, X509_free);
+ X509_STORE_free(c->store);
+ return 0;
+}
+
+/* verify a cert is signed by the ca */
+static int x509_ca__verify(struct x509_ca *x, X509 *cert)
+{
+ X509_STORE_CTX *csc;
+ int ret = -1;
+
+ csc = X509_STORE_CTX_new();
+ if (csc == NULL)
+ return ret;
+
+ X509_STORE_set_flags(x->store, 0);
+ if(!X509_STORE_CTX_init(csc, x->store, cert, 0))
+ goto out;
+
+ X509_STORE_CTX_trusted_stack(csc, x->stack);
+ ret = X509_verify_cert(csc);
+
+out:
+ X509_STORE_CTX_free(csc);
+ return ret;
+}
+
+/* verify a cert is signed by the ca */
+static X509 *x509_ca__x509_from_string(const char *pem)
+{
+ BIO *mem = BIO_new(BIO_s_mem());
+ X509 *cert;
+ int ret;
+
+ if (!mem)
+ return NULL;
+
+ ret = BIO_puts(mem, pem);
+ if (ret != (int)strlen(pem))
+ goto error;
+
+ cert = x509__load_cert(mem);
+ if (cert == NULL)
+ goto error;
+
+ return cert;
+
+error:
+ BIO_free(mem);
+ return NULL;
+}
+
+static int x509_ca_verify_pem(lua_State *L)
+{
+ struct x509_ca *x = x509_ca__get(L);
+ const char *pem = luaL_checkstring(L, 2);
+ X509 *cert;
+ int ret;
+
+ cert = x509_ca__x509_from_string(pem);
+ if (!cert)
+ return crypto_error(L);
+
+ ret = x509_ca__verify(x, cert);
+ X509_free(cert);
+ if (ret < 0)
+ return crypto_error(L);
+
+ lua_pushboolean(L, ret);
+
+ return 1;
+}
+
+static int x509_ca_add_pem(lua_State *L)
+{
+ struct x509_ca *x = x509_ca__get(L);
+ const char *pem = luaL_checkstring(L, 2);
+ X509 *cert;
+
+ cert = x509_ca__x509_from_string(pem);
+ if (!cert)
+ return crypto_error(L);
+
+ sk_X509_push(x->stack, cert);
+
+ lua_pushboolean(L, 1);
+
+ return 1;
+}
+
/*
** Create a metatable and leave it on top of the stack.
*/
@@ -1604,6 +1738,15 @@ static void create_metatables (lua_State *L)
{ "to_pem", pkey_to_pem},
{ NULL, NULL }
};
+ struct luaL_reg x509_ca_functions[] = {
+ { NULL, NULL }
+ };
+ struct luaL_reg x509_ca_methods[] = {
+ { "__gc", x509_ca_gc },
+ { "add_pem", x509_ca_add_pem },
+ { "verify_pem", x509_ca_verify_pem },
+ { NULL, NULL }
+ };
luaL_register (L, LUACRYPTO_CORENAME, core_functions);
#define CALLTABLE(n) create_call_table(L, #n, n##_fnew, n##_f##n)
@@ -1614,6 +1757,7 @@ static void create_metatables (lua_State *L)
CALLTABLE(sign);
CALLTABLE(seal);
CALLTABLE(open);
+ CALLTABLE(x509_ca);
luacrypto_createmeta(L, LUACRYPTO_DIGESTNAME, digest_methods);
luacrypto_createmeta(L, LUACRYPTO_ENCRYPTNAME, encrypt_methods);
@@ -1624,10 +1768,12 @@ static void create_metatables (lua_State *L)
luacrypto_createmeta(L, LUACRYPTO_PKEYNAME, pkey_methods);
luacrypto_createmeta(L, LUACRYPTO_SEALNAME, seal_methods);
luacrypto_createmeta(L, LUACRYPTO_OPENNAME, open_methods);
+ luacrypto_createmeta(L, LUACRYPTO_X509_CA_NAME, x509_ca_methods);
luaL_register (L, LUACRYPTO_RANDNAME, rand_functions);
luaL_register (L, LUACRYPTO_HMACNAME, hmac_functions);
luaL_register (L, LUACRYPTO_PKEYNAME, pkey_functions);
+ luaL_register (L, LUACRYPTO_X509_CA_NAME, x509_ca_functions);
lua_pop (L, 3);
}
@@ -1653,7 +1799,7 @@ LUACRYPTO_API void luacrypto_set_info (lua_State *L)
lua_pushliteral (L, "LuaCrypto is a Lua wrapper for OpenSSL");
lua_settable (L, -3);
lua_pushliteral (L, "_VERSION");
- lua_pushliteral (L, "LuaCrypto 0.2.0");
+ lua_pushliteral (L, "LuaCrypto 0.3.0");
lua_settable (L, -3);
}
@@ -1661,17 +1807,15 @@ LUACRYPTO_API void luacrypto_set_info (lua_State *L)
** Creates the metatables for the objects and registers the
** driver open method.
*/
-#ifdef __cplusplus
-extern "C"
-#endif
LUACRYPTO_API int luaopen_crypto(lua_State *L)
{
- OpenSSL_add_all_digests();
- OpenSSL_add_all_ciphers();
-
struct luaL_reg core[] = {
{NULL, NULL},
};
+
+ OpenSSL_add_all_digests();
+ OpenSSL_add_all_ciphers();
+
create_metatables (L);
luaL_openlib (L, LUACRYPTO_CORENAME, core, 0);
luacrypto_set_info (L);
View
1  src/lcrypto.h
@@ -24,6 +24,7 @@
#define LUACRYPTO_HMACNAME "crypto.hmac"
#define LUACRYPTO_RANDNAME "crypto.rand"
#define LUACRYPTO_PKEYNAME "crypto.pkey"
+#define LUACRYPTO_X509_CA_NAME "crypto.x509_ca"
LUACRYPTO_API int luacrypto_createmeta (lua_State *L, const char *name, const luaL_reg *methods);
LUACRYPTO_API void luacrypto_setmeta (lua_State *L, const char *name);
View
17 tests/ca/README
@@ -0,0 +1,17 @@
+Testing x509 certs for luacrypto
+
+# Make the CA cert
+openssl genrsa -des3 -out ca.key 4096
+openssl req -new -x509 -days 365 -key ca.key -out ca.crt
+
+# Make server cert and signing request
+openssl genrsa -des3 -out server.key 4096
+openssl req -new -key server.key -out server.csr
+
+# Sign the server csr and generate a crt
+openssl x509 -req -days 365 -in server.csr -CA ca.crt -CAkey ca.key -set_serial 01 -out server.crt
+
+# Output unencrypted server key
+openssl rsa -in server.key -out server.key.insecure
+
+
View
39 tests/ca/ca.crt
@@ -0,0 +1,39 @@
+-----BEGIN CERTIFICATE-----
+MIIG1jCCBL6gAwIBAgIJALZOkAY0D6wQMA0GCSqGSIb3DQEBBQUAMIGiMQswCQYD
+VQQGEwJVUzETMBEGA1UECBMKQ2FsaWZvcm5pYTEWMBQGA1UEBxMNU2FuIEZyYW5j
+aXNjbzEOMAwGA1UEChMFVmlyZ28xEDAOBgNVBAsTB0hhY2tlcnMxGDAWBgNVBAMT
+D0JyYW5kb24gUGhpbGlwczEqMCgGCSqGSIb3DQEJARYbYnJhbmRvbi5waGlsaXBz
+QGV4YW1wbGUuY29tMB4XDTEyMDEyNjIyMDAxOFoXDTIyMDEyMzIyMDAxOFowgaIx
+CzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpDYWxpZm9ybmlhMRYwFAYDVQQHEw1TYW4g
+RnJhbmNpc2NvMQ4wDAYDVQQKEwVWaXJnbzEQMA4GA1UECxMHSGFja2VyczEYMBYG
+A1UEAxMPQnJhbmRvbiBQaGlsaXBzMSowKAYJKoZIhvcNAQkBFhticmFuZG9uLnBo
+aWxpcHNAZXhhbXBsZS5jb20wggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoIC
+AQC5YVbGpZHLeWDu30o9UUF2yrqizDzbuDshWT8RlVQDdYvvKNFMFt8OCmgabl2k
+8T19zMqnWof72iviZDsLGxOmMbMUFvk1TN7cMfWNsD6P/ja4BYxh90Jt8y65yC/T
+6Xm1NLqFyhhOPWvzHvhAuvHg5qWvcyzsx3wDoh+dr3hVIJfxq9Ufu8t4JzOjJplQ
+8kwklW6CafrcYF85YJqhxObWeL6gYWnYd3AzDE/S4j7C/nNNQah0NZvu6cO/Sc9l
+qAw9gI5a6f9Pd7VFAzW7b8jRZ6pMmkNM9rm83i8tjiBgXDIBHZVEhtkC+5Kp0mU6
+ywn/regQGGJ46cInLpCEnDbFhmzOgg4wvNtiy7JT+zyaFQYM0dHPs4JQRfGIc4LO
+3M4r5na1qcbNQFQVVbMtsNETg+TrUyrmXDEO9PwwOXU1Khgnrk4A1UWZlf+n5dds
+K6KhlRxD+nMzyR+lBPH9vdBtbzoOdy/D/mm6SMKkUIAXWdrPb8ucRMQkxusvq0Dv
+8UikFV2Y16r7uqXqiOWCXEKrKMT+cAArCRBzUIoAIWTH4MKoEu9tYRzJcYM+EBc8
+nXrvnUBdE8GNiWW444SPoCTM7SakHnQC34YY6WbEctQhGG2QW1fcPycWO5Aqr4WW
+8hrbqjb6X15Y/J5OwqM0n3MrrNNv1nhHqaAVYIQYYlNH2QIDAQABo4IBCzCCAQcw
+HQYDVR0OBBYEFLgWlUKomtnlKUEJZHAwCL3pSJt1MIHXBgNVHSMEgc8wgcyAFLgW
+lUKomtnlKUEJZHAwCL3pSJt1oYGopIGlMIGiMQswCQYDVQQGEwJVUzETMBEGA1UE
+CBMKQ2FsaWZvcm5pYTEWMBQGA1UEBxMNU2FuIEZyYW5jaXNjbzEOMAwGA1UEChMF
+VmlyZ28xEDAOBgNVBAsTB0hhY2tlcnMxGDAWBgNVBAMTD0JyYW5kb24gUGhpbGlw
+czEqMCgGCSqGSIb3DQEJARYbYnJhbmRvbi5waGlsaXBzQGV4YW1wbGUuY29tggkA
+tk6QBjQPrBAwDAYDVR0TBAUwAwEB/zANBgkqhkiG9w0BAQUFAAOCAgEAgoSv+w9R
+Zlm7XxOD1xKo0AcgtJq6uWic14Y/sVaabN9GPGZVyPI9zywiAPbi9zpBozEWykXz
+RA3Tac5Y1xLS+1PCRJcgWiAzIVP0wX0nIj+rxBcXxJ5t7+CiNTQ0BSD3IDgtiWkb
+hFYzrUZiTluDs5erR0fatOE4deYLewGErU69rtW+blyCouGzcvBSn/ZmTUhq+VkP
+LRfzc1dcHxKw25WL5+O59FkJ3Ytpk7u9xxumNxsugar8ssfs+/Qu5wytVQ1+jPQC
+9CFu6n0GNPK3A7ebfUDc7qfUGhvM6YoAvSGK0iRgdDvdqR+47+3UKZ56H7cJufSQ
+wNAAWu3CagAXCmQaIKX2C8PS5FxnKymXSZTUVQ55NBcNRrYEfF0+ba6xW9ehSD5N
+G2C5FjA7z8eV+FjTDJPBVLZrwutDpyciGT4mpH6ul8rMFTxJuNjzCMT278CEgy5l
+IYrjS9B16k/wDfSxtDWyy6laaRnvf7vI+mTTUxZJZVd7ADeW9+Fxx/fddBsFuONw
+d81hvMemWe0uz/9SZyb0bmq+ox4zvzS2N05us3vIcZNaIrsG6baVFiTA6js503K5
+KjXgcfC980pnPG37oH41aaAHZEpTGgkpVp92dsHlwkrOjtZO2Tt+c4IUiflkPEvt
+QKI92udYACbXW5hT8jwyOo/ugwFMMpNmLvM=
+-----END CERTIFICATE-----
View
54 tests/ca/ca.key
@@ -0,0 +1,54 @@
+-----BEGIN RSA PRIVATE KEY-----
+Proc-Type: 4,ENCRYPTED
+DEK-Info: DES-EDE3-CBC,CD751BE331A58811
+
+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
+-----END RSA PRIVATE KEY-----
View
33 tests/ca/server.crt
@@ -0,0 +1,33 @@
+-----BEGIN CERTIFICATE-----
+MIIFxTCCA60CAQEwDQYJKoZIhvcNAQEFBQAwgaIxCzAJBgNVBAYTAlVTMRMwEQYD
+VQQIEwpDYWxpZm9ybmlhMRYwFAYDVQQHEw1TYW4gRnJhbmNpc2NvMQ4wDAYDVQQK
+EwVWaXJnbzEQMA4GA1UECxMHSGFja2VyczEYMBYGA1UEAxMPQnJhbmRvbiBQaGls
+aXBzMSowKAYJKoZIhvcNAQkBFhticmFuZG9uLnBoaWxpcHNAZXhhbXBsZS5jb20w
+HhcNMTIwMTI2MjIwMjI0WhcNMjIwMTIzMjIwMjI0WjCBrTELMAkGA1UEBhMCVVMx
+EzARBgNVBAgTCkNhbGlmb3JuaWExFjAUBgNVBAcTDVNhbiBGcmFuY2lzY28xGjAY
+BgNVBAoTEVZpcmdvIFRlc3QgU2lnbmVyMQ8wDQYDVQQLEwZIYWNrZXIxGDAWBgNV
+BAMTD0JyYW5kb24gUGhpbGlwczEqMCgGCSqGSIb3DQEJARYbYnJhbmRvbi5waGls
+aXBzQGV4YW1wbGUuY29tMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEA
+0Py2Gaq9lsxS7gN4UoF17iV9fI/NW+tgtfgjLqDrNpyvFqlBchhKVeoA2wdaRWpH
+uDPWLnwUQNRYu4YVLuAt/32oG9AYzgBEjNMLGdAaqGGSl8HCdnXQh2hJD24WRa1O
+dcj+o1kIoUKi5BklBZd+HzTEjbinLUZgCAYxohaIC8yLsZGy6Ez35pAu4XokP9HM
+xVM9tZN6HwHI//givYkKv7R6a9iY0fLIHwmEoc4yVw7zNtBqzLLUHROjLCqqvIoi
+Zkn7Z4k3080WCD1Q0hQt0SKsf+DCDGS3zaE5EeyVvfBVelqz2v4kFzNf+0lEA411
+UnPEMkfZt+x2Gwr2UAObag961p46Ba+QgifQpyXNQ3bCapqMghfSz6PHeGYeFPNW
+QKzVLNQSjnPBc0i0h+AckAFJRzYXWZsh1Jq2TCvTiw+1Irm1m9Ltuv+W85hvhLuB
+1AY3runMLQN0eQ0gvjbkcKCKtpoKy4rHtVTiy+8hzL1zaWYu3Bny7BgPiKciiMbo
+7TkDzWVX0hIfjcgJAzVogLC1/TVEQkoImomAvzPGXQpbLlX843juVeBCSwdkBAjj
+lMoJyGcv6wfO91tkG8PWxUjPQQcJCr8/VSoK10jdUjrQocb3u+ud27n/6eQZOpvw
+sbn5q3mr2+zUIon/9k8DbgPEhk6nrCq5rN6A7eCcdwMCAwEAATANBgkqhkiG9w0B
+AQUFAAOCAgEAOJfGCRbeByGWHxU1DWTmkqG97NoROUw0Gq9BO3WvxbFCvMettDPz
+SF6uUu+C7u5uQ5rCqAB1nDe2uCDljvB6XKBjfk/jbhFBa+56JDKmXxjXRaSLFpX2
+NxByCb48Hir5021Qcebz+ojScwS6O/jpj/sOlGipssICJExBQs0ywlFKbLsM7zRs
+v+s0MO5C8cgFO5Yz0KdOXep8rXStaM9N0IZApG+bywBI+1yQbOqP+BUJ95drmXfe
+meDJR1/srhxRUicgq1psE2xsd9UEx6AdoakUDv7T2owtVw3PJavNQCW+8ql67DQj
+7epQTQ5wVty1ED5PyfHYOlC0LNlUNmoADegUwyYcQ4246ayfqcnJxacQXIpWylF/
+mGHQcR4AmVYsr26UkDYXcwb7BDxH0eb3w5s7X0hwtFzd8jwx3Vagdf4fafm4Vahz
+XDiDXVMTZqyncIBu4/8PFfgqgLra/MhHODbLamndPMeHAn0zNXk5HEkiNRhHymSe
+oTKkB4Ol10/kEWvOswU/LS69w7HDFgJAnnEi2+XCTHMim8kDcbhoGr2rlL1cT7yL
+B3P11S3lepH+PFTFfU19IlrDGfXDxlKNWR9XNVqtQw/qnN+T7XZFW2tuDiMecCYj
+64Qm7mwOJZDp1eFU0GiTuF7r7ZMBWTDDe98eOFOOiUZ3m+m43SGVb+U=
+-----END CERTIFICATE-----
View
29 tests/ca/server.csr
@@ -0,0 +1,29 @@
+-----BEGIN CERTIFICATE REQUEST-----
+MIIE8zCCAtsCAQAwga0xCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpDYWxpZm9ybmlh
+MRYwFAYDVQQHEw1TYW4gRnJhbmNpc2NvMRowGAYDVQQKExFWaXJnbyBUZXN0IFNp
+Z25lcjEPMA0GA1UECxMGSGFja2VyMRgwFgYDVQQDEw9CcmFuZG9uIFBoaWxpcHMx
+KjAoBgkqhkiG9w0BCQEWG2JyYW5kb24ucGhpbGlwc0BleGFtcGxlLmNvbTCCAiIw
+DQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAND8thmqvZbMUu4DeFKBde4lfXyP
+zVvrYLX4Iy6g6zacrxapQXIYSlXqANsHWkVqR7gz1i58FEDUWLuGFS7gLf99qBvQ
+GM4ARIzTCxnQGqhhkpfBwnZ10IdoSQ9uFkWtTnXI/qNZCKFCouQZJQWXfh80xI24
+py1GYAgGMaIWiAvMi7GRsuhM9+aQLuF6JD/RzMVTPbWTeh8ByP/4Ir2JCr+0emvY
+mNHyyB8JhKHOMlcO8zbQasyy1B0ToywqqryKImZJ+2eJN9PNFgg9UNIULdEirH/g
+wgxkt82hORHslb3wVXpas9r+JBczX/tJRAONdVJzxDJH2bfsdhsK9lADm2oPetae
+OgWvkIIn0KclzUN2wmqajIIX0s+jx3hmHhTzVkCs1SzUEo5zwXNItIfgHJABSUc2
+F1mbIdSatkwr04sPtSK5tZvS7br/lvOYb4S7gdQGN67pzC0DdHkNIL425HCgiraa
+CsuKx7VU4svvIcy9c2lmLtwZ8uwYD4inIojG6O05A81lV9ISH43ICQM1aICwtf01
+REJKCJqJgL8zxl0KWy5V/ON47lXgQksHZAQI45TKCchnL+sHzvdbZBvD1sVIz0EH
+CQq/P1UqCtdI3VI60KHG97vrndu5/+nkGTqb8LG5+at5q9vs1CKJ//ZPA24DxIZO
+p6wquazegO3gnHcDAgMBAAGgADANBgkqhkiG9w0BAQUFAAOCAgEAuVh+WHyD0ED+
+a5K+fyIXOjAPoYM/IyiCyGREkn5+6LENGEu5EhXVgyph6uxgJTn4UpUypJrMMFRq
+ESNe0nuAd6NgXBU0aF5973lGpLP8kVtSlESEmXHHlMf8y5eOGTO4L+QKgCkMedzP
+rrFb6GweerdxRZMiFcReF6A93cupApdKVMZZ2/p4vo5mgjq/54KZR8/5pnbjNZhW
+ZgVxQvpKvzbDCMYlraK6O7yX0ftE0076TQqK0v91ceue1evZE/BaYZsM+mVF9PiL
+SrrkhwCMfusp1N2pS5K24z29a/MvBbKpTB0jFVgijbfKKD+0/e3OlSJJxGhflTBU
+93xHXuYK5/FbgDEYURGwsbsUqOTIpsekzqS3Q0FgcpolB3phDb5D8HaUfvnScEup
+fplMZDU5rZl3281z3+abV4oArD+X9mnIiKWSt5AKoYoiQtynPPEGQoWcQSi02kfz
+ny88TPQpaiJ4g03JoxLCkH2R12uETazKqPYJIqhZ0pfYnEDVoE1luIfa5b47fAWd
+v7gmanoJn6NziDmJD0rVu131y4+bbRgd/2aPsVBhpP8qrbvc6GbLp4JvmwSfYEg9
+EcO9hYCe1CVUTVwvH0mNhYSQtknvnOWOj8nGPcScBJVXl7Dt74WgmWGzuWya8fzs
+DvfNYR414sCH+SNdMRv1tFsdFTguqSE=
+-----END CERTIFICATE REQUEST-----
View
54 tests/ca/server.key
@@ -0,0 +1,54 @@
+-----BEGIN RSA PRIVATE KEY-----
+Proc-Type: 4,ENCRYPTED
+DEK-Info: DES-EDE3-CBC,6EBAB18EB50B0A06
+
+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
+-----END RSA PRIVATE KEY-----
View
51 tests/ca/server.key.insecure
@@ -0,0 +1,51 @@
+-----BEGIN RSA PRIVATE KEY-----
+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
+-----END RSA PRIVATE KEY-----
View
121 tests/x509_ca.lua
@@ -0,0 +1,121 @@
+require 'crypto'
+
+assert(crypto.x509_ca, "crypto.x509_ca is unavaliable")
+
+local ca_cert = [[-----BEGIN CERTIFICATE-----
+MIIG1jCCBL6gAwIBAgIJALZOkAY0D6wQMA0GCSqGSIb3DQEBBQUAMIGiMQswCQYD
+VQQGEwJVUzETMBEGA1UECBMKQ2FsaWZvcm5pYTEWMBQGA1UEBxMNU2FuIEZyYW5j
+aXNjbzEOMAwGA1UEChMFVmlyZ28xEDAOBgNVBAsTB0hhY2tlcnMxGDAWBgNVBAMT
+D0JyYW5kb24gUGhpbGlwczEqMCgGCSqGSIb3DQEJARYbYnJhbmRvbi5waGlsaXBz
+QGV4YW1wbGUuY29tMB4XDTEyMDEyNjIyMDAxOFoXDTIyMDEyMzIyMDAxOFowgaIx
+CzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpDYWxpZm9ybmlhMRYwFAYDVQQHEw1TYW4g
+RnJhbmNpc2NvMQ4wDAYDVQQKEwVWaXJnbzEQMA4GA1UECxMHSGFja2VyczEYMBYG
+A1UEAxMPQnJhbmRvbiBQaGlsaXBzMSowKAYJKoZIhvcNAQkBFhticmFuZG9uLnBo
+aWxpcHNAZXhhbXBsZS5jb20wggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoIC
+AQC5YVbGpZHLeWDu30o9UUF2yrqizDzbuDshWT8RlVQDdYvvKNFMFt8OCmgabl2k
+8T19zMqnWof72iviZDsLGxOmMbMUFvk1TN7cMfWNsD6P/ja4BYxh90Jt8y65yC/T
+6Xm1NLqFyhhOPWvzHvhAuvHg5qWvcyzsx3wDoh+dr3hVIJfxq9Ufu8t4JzOjJplQ
+8kwklW6CafrcYF85YJqhxObWeL6gYWnYd3AzDE/S4j7C/nNNQah0NZvu6cO/Sc9l
+qAw9gI5a6f9Pd7VFAzW7b8jRZ6pMmkNM9rm83i8tjiBgXDIBHZVEhtkC+5Kp0mU6
+ywn/regQGGJ46cInLpCEnDbFhmzOgg4wvNtiy7JT+zyaFQYM0dHPs4JQRfGIc4LO
+3M4r5na1qcbNQFQVVbMtsNETg+TrUyrmXDEO9PwwOXU1Khgnrk4A1UWZlf+n5dds
+K6KhlRxD+nMzyR+lBPH9vdBtbzoOdy/D/mm6SMKkUIAXWdrPb8ucRMQkxusvq0Dv
+8UikFV2Y16r7uqXqiOWCXEKrKMT+cAArCRBzUIoAIWTH4MKoEu9tYRzJcYM+EBc8
+nXrvnUBdE8GNiWW444SPoCTM7SakHnQC34YY6WbEctQhGG2QW1fcPycWO5Aqr4WW
+8hrbqjb6X15Y/J5OwqM0n3MrrNNv1nhHqaAVYIQYYlNH2QIDAQABo4IBCzCCAQcw
+HQYDVR0OBBYEFLgWlUKomtnlKUEJZHAwCL3pSJt1MIHXBgNVHSMEgc8wgcyAFLgW
+lUKomtnlKUEJZHAwCL3pSJt1oYGopIGlMIGiMQswCQYDVQQGEwJVUzETMBEGA1UE
+CBMKQ2FsaWZvcm5pYTEWMBQGA1UEBxMNU2FuIEZyYW5jaXNjbzEOMAwGA1UEChMF
+VmlyZ28xEDAOBgNVBAsTB0hhY2tlcnMxGDAWBgNVBAMTD0JyYW5kb24gUGhpbGlw
+czEqMCgGCSqGSIb3DQEJARYbYnJhbmRvbi5waGlsaXBzQGV4YW1wbGUuY29tggkA
+tk6QBjQPrBAwDAYDVR0TBAUwAwEB/zANBgkqhkiG9w0BAQUFAAOCAgEAgoSv+w9R
+Zlm7XxOD1xKo0AcgtJq6uWic14Y/sVaabN9GPGZVyPI9zywiAPbi9zpBozEWykXz
+RA3Tac5Y1xLS+1PCRJcgWiAzIVP0wX0nIj+rxBcXxJ5t7+CiNTQ0BSD3IDgtiWkb
+hFYzrUZiTluDs5erR0fatOE4deYLewGErU69rtW+blyCouGzcvBSn/ZmTUhq+VkP
+LRfzc1dcHxKw25WL5+O59FkJ3Ytpk7u9xxumNxsugar8ssfs+/Qu5wytVQ1+jPQC
+9CFu6n0GNPK3A7ebfUDc7qfUGhvM6YoAvSGK0iRgdDvdqR+47+3UKZ56H7cJufSQ
+wNAAWu3CagAXCmQaIKX2C8PS5FxnKymXSZTUVQ55NBcNRrYEfF0+ba6xW9ehSD5N
+G2C5FjA7z8eV+FjTDJPBVLZrwutDpyciGT4mpH6ul8rMFTxJuNjzCMT278CEgy5l
+IYrjS9B16k/wDfSxtDWyy6laaRnvf7vI+mTTUxZJZVd7ADeW9+Fxx/fddBsFuONw
+d81hvMemWe0uz/9SZyb0bmq+ox4zvzS2N05us3vIcZNaIrsG6baVFiTA6js503K5
+KjXgcfC980pnPG37oH41aaAHZEpTGgkpVp92dsHlwkrOjtZO2Tt+c4IUiflkPEvt
+QKI92udYACbXW5hT8jwyOo/ugwFMMpNmLvM=
+-----END CERTIFICATE-----]]
+
+local cert_to_verify = [[-----BEGIN CERTIFICATE-----
+MIIFxTCCA60CAQEwDQYJKoZIhvcNAQEFBQAwgaIxCzAJBgNVBAYTAlVTMRMwEQYD
+VQQIEwpDYWxpZm9ybmlhMRYwFAYDVQQHEw1TYW4gRnJhbmNpc2NvMQ4wDAYDVQQK
+EwVWaXJnbzEQMA4GA1UECxMHSGFja2VyczEYMBYGA1UEAxMPQnJhbmRvbiBQaGls
+aXBzMSowKAYJKoZIhvcNAQkBFhticmFuZG9uLnBoaWxpcHNAZXhhbXBsZS5jb20w
+HhcNMTIwMTI2MjIwMjI0WhcNMjIwMTIzMjIwMjI0WjCBrTELMAkGA1UEBhMCVVMx
+EzARBgNVBAgTCkNhbGlmb3JuaWExFjAUBgNVBAcTDVNhbiBGcmFuY2lzY28xGjAY
+BgNVBAoTEVZpcmdvIFRlc3QgU2lnbmVyMQ8wDQYDVQQLEwZIYWNrZXIxGDAWBgNV
+BAMTD0JyYW5kb24gUGhpbGlwczEqMCgGCSqGSIb3DQEJARYbYnJhbmRvbi5waGls
+aXBzQGV4YW1wbGUuY29tMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEA
+0Py2Gaq9lsxS7gN4UoF17iV9fI/NW+tgtfgjLqDrNpyvFqlBchhKVeoA2wdaRWpH
+uDPWLnwUQNRYu4YVLuAt/32oG9AYzgBEjNMLGdAaqGGSl8HCdnXQh2hJD24WRa1O
+dcj+o1kIoUKi5BklBZd+HzTEjbinLUZgCAYxohaIC8yLsZGy6Ez35pAu4XokP9HM
+xVM9tZN6HwHI//givYkKv7R6a9iY0fLIHwmEoc4yVw7zNtBqzLLUHROjLCqqvIoi
+Zkn7Z4k3080WCD1Q0hQt0SKsf+DCDGS3zaE5EeyVvfBVelqz2v4kFzNf+0lEA411
+UnPEMkfZt+x2Gwr2UAObag961p46Ba+QgifQpyXNQ3bCapqMghfSz6PHeGYeFPNW
+QKzVLNQSjnPBc0i0h+AckAFJRzYXWZsh1Jq2TCvTiw+1Irm1m9Ltuv+W85hvhLuB
+1AY3runMLQN0eQ0gvjbkcKCKtpoKy4rHtVTiy+8hzL1zaWYu3Bny7BgPiKciiMbo
+7TkDzWVX0hIfjcgJAzVogLC1/TVEQkoImomAvzPGXQpbLlX843juVeBCSwdkBAjj
+lMoJyGcv6wfO91tkG8PWxUjPQQcJCr8/VSoK10jdUjrQocb3u+ud27n/6eQZOpvw
+sbn5q3mr2+zUIon/9k8DbgPEhk6nrCq5rN6A7eCcdwMCAwEAATANBgkqhkiG9w0B
+AQUFAAOCAgEAOJfGCRbeByGWHxU1DWTmkqG97NoROUw0Gq9BO3WvxbFCvMettDPz
+SF6uUu+C7u5uQ5rCqAB1nDe2uCDljvB6XKBjfk/jbhFBa+56JDKmXxjXRaSLFpX2
+NxByCb48Hir5021Qcebz+ojScwS6O/jpj/sOlGipssICJExBQs0ywlFKbLsM7zRs
+v+s0MO5C8cgFO5Yz0KdOXep8rXStaM9N0IZApG+bywBI+1yQbOqP+BUJ95drmXfe
+meDJR1/srhxRUicgq1psE2xsd9UEx6AdoakUDv7T2owtVw3PJavNQCW+8ql67DQj
+7epQTQ5wVty1ED5PyfHYOlC0LNlUNmoADegUwyYcQ4246ayfqcnJxacQXIpWylF/
+mGHQcR4AmVYsr26UkDYXcwb7BDxH0eb3w5s7X0hwtFzd8jwx3Vagdf4fafm4Vahz
+XDiDXVMTZqyncIBu4/8PFfgqgLra/MhHODbLamndPMeHAn0zNXk5HEkiNRhHymSe
+oTKkB4Ol10/kEWvOswU/LS69w7HDFgJAnnEi2+XCTHMim8kDcbhoGr2rlL1cT7yL
+B3P11S3lepH+PFTFfU19IlrDGfXDxlKNWR9XNVqtQw/qnN+T7XZFW2tuDiMecCYj
+64Qm7mwOJZDp1eFU0GiTuF7r7ZMBWTDDe98eOFOOiUZ3m+m43SGVb+U=
+-----END CERTIFICATE-----]]
+
+local bad_cert = [[-----BEGIN CERTIFICATE-----
+MIIFxTCCA60CAQEwDQYJKoZIhvcNAQEFBQAwgaIxCzAJBgNVBAYTAlVTMRMwEQYD
+VQQIEwpDYWxpZm9ybmlhMRYwFAYDVQQHEw1TYW4gRnJhbmNpc2NvMQ4wDAYDVQQK
+EwVWaXJnbzEQMA4GA1UECxMHSGFja2VyczEYMBYGA1UEAxMPQnJhbmRvbiBQaGls
+aXBzMSowKAYJKoZIhvcNAQkBFhticmFuZG9uLnBoaWxpcHNAZXhhbXBsZS5jb20w
+HhcNMTIwMTI2MjIwMjI0WhcNMjIwMTIzMjIwMjI0WjCBrTELMAkGA1UEBhMCVVMx
+EzARBgNVBAgTCkNhbGlmb3JuaWExFjAUBgNVBAcTDVNhbiBGcmFuY2lzY28xGjAY
+BgNVBAoTEVZpcmdvIFRlc3QgU2lnbmVyMQ8wDQYDVQQLEwZIYWNrZXIxGDAWBgNV
+BAMTD0JyYW5kb24gUGhpbGlwczEqMCgGCSqGSIb3DQEJARYbYnJhbmRvbi5waGls
+aXBzQGV4YW1wbGUuY29tMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEA
+0Py2Gaq9lsxS7gN4UoF17iV9fI/NW+tgtfgjLqDrNpyvFqlBchhKVeoA2wdaRWpH
+uDPWLnwUQNRYu4YVLuAt/32oG9AYzgBEjNMLGdAaqGGSl8HCdnXQh2hJD24WRa1O
+dcj+o1kIoUKi5BklBZd+HzTEjbinLUZgCAYxohaIC8yLsZGy6Ez35pAu4XokP9HM
+xVM9tZN6HwHI//givYkKv7R6a9iY0fLIHwmEoc4yVw7zNtBqzLLUHROjLCqqvIoi
+Zkn7Z4k3080WCD1Q0hQt0SKsf+DCDGS3zaE5EeyVvfBVelqz2v4kFzNf+0lEA411
+UnPEMkfZt+x2Gwr2UAObag961p46Ba+QgifQpyXNQ3bCapqMghfSz6PHeGYeFPNW
+QKzVLNQSjnPBc0i0h+AckAFJRzYXWZsh1Jq2TCvTiw+1Irm1m9Ltuv+W85hvhLuB
+1AY3runMLQN0eQ0gvjbkcKCKtpoKy4rHtVTiy+8hzL1zaWYu3Bny7BgPiKciiMbo
+7TkDzWVX0hIfjcgJAzVogLC1/TVEQkoImomAvzPGXQpbLlX843juVeBCSwdkBAjj
+lMoJyGcv6wfO91tkG8PWxUjPQQcJCr8/VSoK10jdUjrQocb3u+ud27n/6eQZOpvw
+sbn5q3mr2+zUIon/9k8DbgPEhk6nrCq5rN6A7eCcdwMCAwEAATANBgkqhkiG9w0B
+AQUFAAOCAgEAOJfGCRbeByGWHxU1DWTmkqG97NoROUw0Gq9BO3WvxbFCvMettDPz
+SF6uUu+C7u5uQ5rCqAB1nDe2uCDljvB6XKBjfk/jbhFBa+56JDKmXxjXRaSLFpX2
+NxByCb48Hir5021Qcebz+ojScwS6O/jpj/sOlGipssICJExBQs0ywlFKbLsM7zRs
+v+s0MO5C8cgFO5Yz0KdOXep8rXStaM9N0IZApG+bywBI+1yQbOqP+BUJ95drmXfe
+meDJR1/srhxRUicgq1psE2xsd9UEx6AdoakUDv7T2owtVw3PJavNQCW+8ql67DQj
+7epQTQ5wVty1ED5PyfHYOlC0LNlUNmoADegUwyYcQ4246ayfqcnJxacQXIpWylF/
+mGHQcR4AmVYsr26UkDYXcwb7BDxH0eb3w5s7X0hwtFzd8jwx3Vagdf4fafm4Vahz
+XDiDXVMTZqyncIBu4/8PFfgqgLra/MhHODbLamndPMeHAn0zNXk5HEkiNRhHymSe
+oTKkB4Ol10/kEWvOswU/LS69w7HDFgJAnnEi2+XCTHMim8kDcbhoGr3rlL1cT7yL
+B3P11S3lepH+PFTFfU19IlrDGfXDxlKNWR9XNVqtQw/qnN+T7XZFW2tuDiMecCYj
+64Qm7mwOJZDp1eFU0GiTuF7r7ZMBWTDDe98eOFOOiUZ3m+m43SGVb+U=
+-----END CERTIFICATE-----]]
+
+
+ca = assert(crypto.x509_ca())
+
+ca:add_pem(ca_cert)
+assert(ca:add_pem("FOBAR") == nil, "bad cert succeeded")
+
+assert(ca:verify_pem(cert_to_verify) == true, "failed to verify good cert")
+assert(ca:verify_pem(bad_cert) == false, "verified bad cert, noooooo")
+print("OK x509_ca")

No commit comments for this range

Something went wrong with that request. Please try again.