Skip to content

Comparing changes

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

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also .
  • 5 commits
  • 3 files changed
  • 0 commit comments
  • 2 contributors
Commits on Mar 14, 2012
Brandon Philips x509_cert: add x509_cert to read out pubkey
With this patch we can now do things like verify a x509 cert against a x509_ca
then extract its pubkey and test a message signature.

    cert = crypto.x509_cert()
    cert:from_pem(server_cert)
    kpub = cert:pubkey()
    message = 'Hello world'
    verified = crypto.verify('md5', message, signature, kpub)
f1b6e55
Brandon Philips docs: add x509_cert and x509_ca
add docs for the x509_cert and x509_ca objects.
0c89a46
Commits on Mar 20, 2012
Brandon Philips pkey: use DSA and RSA PrivateKey functions in to_pem
Detect what type of key we are dealing with and use the right to_pem
function. This way we match the enconding that the openssl dsa|rsa apps
use for certificates.
be18148
Brandon Philips pkey: to_pem: check return codes
check the return codes of wrote_bio_PrivateKey for any error.
90539d7
@mkottman Merge pull request #15 from racker/fix-rsa-openssl-mismatch
Fix rsa openssl mismatch
104d3c8
Showing with 145 additions and 33 deletions.
  1. +23 −0 doc/us/manual.html
  2. +121 −33 src/lcrypto.c
  3. +1 −0 src/lcrypto.h
View
23 doc/us/manual.html
@@ -102,6 +102,8 @@
<dt><strong>pad</strong></dt>
<dd>An optional <b>boolean</b> flag whether padding should be used. The default is true, which means that input of any size can be provided. Returned date may be larger than input string due to the padding. If explicitly set to <b>false</b>, the padding is turned off and the input data size has to be multiple of block length.</dd>
</dd>
+ <dt><strong>pem</strong></dt>
+ <dd>A <b>string</b> containing a PEM formatted certificate.</dd>
</dl>
<h3>Error handling</h3>
@@ -265,7 +267,28 @@
<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>X509 Certificate - crypto.x509_cert</h3>
+<dl>
+ <dt><strong>crypto.x509_cert()</strong></dt>
+ <dd>Return an empty x509 certificate object.</dd>
+
+ <dt><strong>x509_cert:pubkey()</strong></dt>
+ <dd>Get a <code>crypto.pkey</code> object that represents the raw key of the <code>x509_cert</code>.</dd>
+</dl>
+
+<h3>X509 Certificate Authority - crypto.x509_ca</h3>
+<dl>
+ <dt><strong>crypto.x509()</strong></dt>
+ <dd>Return an empty x509 certificate authority.</dd>
+
+ <dt><strong>x509_ca:add_pem(pem)</strong></dt>
+ <dd>Add a x509 CA certificate as a trusted cert.</dd>
+
+ <dt><strong>x509_ca:verify_pem(pem)</strong></dt>
+ <dd>Verify that the pem is signed by one of the x509 CA's added via <code>x509_ca:add_pem</code></dd>
+
+</dl>
<h3>Misc functions - crypto</h3>
<dl>
View
154 src/lcrypto.c
@@ -986,22 +986,34 @@ static int pkey_to_pem(lua_State *L)
{
EVP_PKEY **pkey = (EVP_PKEY **)luaL_checkudata(L, 1, LUACRYPTO_PKEYNAME);
int private = lua_isboolean(L, 2) && lua_toboolean(L, 2);
+ struct evp_pkey_st *pkey_st = *pkey;
+ int ret;
long len;
BUF_MEM *buf;
BIO *mem = BIO_new(BIO_s_mem());
- if(private)
- PEM_write_bio_PrivateKey(mem, *pkey, NULL, NULL, 0, NULL, NULL);
+ if (private && pkey_st->type == EVP_PKEY_DSA)
+ ret = PEM_write_bio_DSAPrivateKey(mem, pkey_st->pkey.dsa, NULL, NULL, 0, NULL, NULL);
+ else if (private && pkey_st->type == EVP_PKEY_RSA)
+ ret = PEM_write_bio_RSAPrivateKey(mem, pkey_st->pkey.rsa, NULL, NULL, 0, NULL, NULL);
+ else if (private)
+ ret = PEM_write_bio_PrivateKey(mem, *pkey, NULL, NULL, 0, NULL, NULL);
else
- PEM_write_bio_PUBKEY(mem, *pkey);
+ ret = PEM_write_bio_PUBKEY(mem, *pkey);
- len = BIO_get_mem_ptr(mem, &buf);
+ if (ret == 0) {
+ ret = crypto_error(L);
+ goto error;
+ }
+ len = BIO_get_mem_ptr(mem, &buf);
lua_pushlstring(L, buf->data, buf->length);
- BIO_free(mem);
+ ret = 1;
- return 1;
+error:
+ BIO_free(mem);
+ return ret;
}
static int pkey_read(lua_State *L)
@@ -1036,8 +1048,9 @@ static int pkey_from_pem(lua_State *L)
int ret;
ret = BIO_puts(mem, key);
- if (ret != strlen(key))
+ if (ret != strlen(key)) {
goto error;
+ }
if(private)
*pkey = PEM_read_bio_PrivateKey(mem, NULL, NULL, NULL);
@@ -1504,6 +1517,92 @@ static X509 *x509__load_cert(BIO *cert)
return x;
}
+static X509 *x509__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;
+}
+
+struct x509_cert {
+ X509 *cert;
+};
+
+static struct x509_cert *x509_cert__get(lua_State *L)
+{
+ return luaL_checkudata(L, 1, LUACRYPTO_X509_CERT_NAME);
+}
+
+static int x509_cert_fnew(lua_State *L)
+{
+ struct x509_cert *x = lua_newuserdata(L, sizeof(struct x509_cert));
+
+ x->cert = NULL;
+
+ luaL_getmetatable(L, LUACRYPTO_X509_CERT_NAME);
+ lua_setmetatable(L, -2);
+
+ return 1;
+}
+
+static int x509_cert_fx509_cert(lua_State *L)
+{
+ return x509_cert_fnew(L);
+}
+
+static int x509_cert_gc(lua_State *L)
+{
+ struct x509_cert *c = x509_cert__get(L);
+ X509_free(c->cert);
+ return 0;
+}
+
+static int x509_cert_from_pem(lua_State *L)
+{
+ struct x509_cert *x = x509_cert__get(L);
+ const char *pem = luaL_checkstring(L, 2);
+
+ if (x->cert != NULL)
+ X509_free(x->cert);
+
+ x->cert = x509__x509_from_string(pem);
+ if (!x->cert)
+ return crypto_error(L);
+
+ return 1;
+}
+
+static int x509_cert_pubkey(lua_State *L)
+{
+ struct x509_cert *x = x509_cert__get(L);
+ EVP_PKEY *pkey = X509_get_pubkey(x->cert);
+
+ if (!pkey)
+ return crypto_error(L);
+
+ EVP_PKEY **out_pkey = pkey_new(L);
+ *out_pkey = pkey;
+
+ return 1;
+}
+
struct x509_ca {
X509_STORE *store;
STACK_OF(X509) *stack;
@@ -1562,39 +1661,16 @@ static int x509_ca__verify(struct x509_ca *x, X509 *cert)
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;
-}
+/* verify a cert is signed by the ca */
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);
+ cert = x509__x509_from_string(pem);
if (!cert)
return crypto_error(L);
@@ -1614,7 +1690,7 @@ static int x509_ca_add_pem(lua_State *L)
const char *pem = luaL_checkstring(L, 2);
X509 *cert;
- cert = x509_ca__x509_from_string(pem);
+ cert = x509__x509_from_string(pem);
if (!cert)
return crypto_error(L);
@@ -1738,6 +1814,15 @@ static void create_metatables (lua_State *L)
{ "to_pem", pkey_to_pem},
{ NULL, NULL }
};
+ struct luaL_reg x509_functions[] = {
+ { NULL, NULL }
+ };
+ struct luaL_reg x509_methods[] = {
+ { "__gc", x509_cert_gc },
+ { "from_pem", x509_cert_from_pem},
+ { "pubkey", x509_cert_pubkey},
+ { NULL, NULL }
+ };
struct luaL_reg x509_ca_functions[] = {
{ NULL, NULL }
};
@@ -1757,6 +1842,7 @@ static void create_metatables (lua_State *L)
CALLTABLE(sign);
CALLTABLE(seal);
CALLTABLE(open);
+ CALLTABLE(x509_cert);
CALLTABLE(x509_ca);
luacrypto_createmeta(L, LUACRYPTO_DIGESTNAME, digest_methods);
@@ -1768,11 +1854,13 @@ 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_CERT_NAME, x509_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_CERT_NAME, x509_functions);
luaL_register (L, LUACRYPTO_X509_CA_NAME, x509_ca_functions);
lua_pop (L, 3);
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_CERT_NAME "crypto.x509"
#define LUACRYPTO_X509_CA_NAME "crypto.x509_ca"
LUACRYPTO_API int luacrypto_createmeta (lua_State *L, const char *name, const luaL_reg *methods);

No commit comments for this range

Something went wrong with that request. Please try again.