2 * px5g - Embedded x509 key and certificate generator based on PolarSSL
4 * Copyright (C) 2009 Steven Barth <steven@midlink.org>
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License, version 2.1 as published by the Free Software Foundation.
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Lesser General Public License for more details.
15 * You should have received a copy of the GNU Lesser General Public
16 * License along with this library; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
26 static char *xfields[] = {"CN", "O", "C", "OU", "ST", "L", "R"};
28 static int px5g_genkey(lua_State *L) {
29 int keysize = luaL_checkint(L, 1), pexp = luaL_optint(L, 2, 65537), ret;
30 px5g_rsa *px5g = lua_newuserdata(L, sizeof(px5g_rsa));
32 return luaL_error(L, "out of memory");
36 havege_init(&px5g->hs);
37 rsa_init(&px5g->rsa, RSA_PKCS_V15, 0, havege_rand, &px5g->hs);
39 if ((ret = rsa_gen_key(&px5g->rsa, keysize, pexp))) {
41 lua_pushinteger(L, ret);
45 luaL_getmetatable(L, PX5G_KEY_META);
46 lua_setmetatable(L, -2);
50 static int px5g_rsa_asn1(lua_State *L) {
52 px5g_rsa *px5g = luaL_checkudata(L, 1, PX5G_KEY_META);
55 x509write_init_node(&node);
56 if ((ret = x509write_serialize_key(&px5g->rsa, &node))) {
57 x509write_free_node(&node);
59 lua_pushinteger(L, ret);
63 lua_pushlstring(L, (char*)node.data, node.len);
64 x509write_free_node(&node);
68 static int px5g_rsa_create_selfsigned(lua_State *L) {
69 px5g_rsa *px5g = luaL_checkudata(L, 1, PX5G_KEY_META);
70 luaL_checktype(L, 2, LUA_TTABLE);
71 time_t from = (time_t)luaL_checknumber(L, 3);
72 time_t to = (time_t)luaL_checknumber(L, 4);
73 char fstr[20], tstr[20];
75 lua_pushliteral(L, "CN");
77 luaL_argcheck(L, lua_isstring(L, -1), 2, "CN missing");
81 strftime(fstr, sizeof(fstr), "%F %H:%M:%S", gmtime(&from)),
85 strftime(tstr, sizeof(tstr), "%F %H:%M:%S", gmtime(&to)),
88 lua_pushliteral(L, "");
89 for (int i = 0; i < (sizeof(xfields) / sizeof(*xfields)); i++) {
90 lua_pushstring(L, xfields[i]);
92 if (lua_isstring(L, -1)) {
93 const char *val = lua_tostring(L, -1);
94 luaL_argcheck(L, !strchr(val, '\''), 2, "Invalid Value");
95 lua_pushfstring(L, "%s%s='%s';",
96 lua_tostring(L, -2), xfields[i], val);
105 x509write_init_raw(&cert);
106 x509write_add_pubkey(&cert, &px5g->rsa);
107 x509write_add_subject(&cert, (unsigned char*)lua_tostring(L, -1));
108 x509write_add_validity(&cert, (unsigned char*)fstr, (unsigned char*)tstr);
109 x509write_create_selfsign(&cert, &px5g->rsa);
111 lua_pushlstring(L, (char*)cert.raw.data, cert.raw.len);
112 x509write_free_raw(&cert);
116 static int px5g_rsa__gc(lua_State *L) {
117 px5g_rsa *px5g = luaL_checkudata(L, 1, PX5G_KEY_META);
119 rsa_free(&px5g->rsa);
125 static int px5g_rsa__tostring(lua_State *L) {
126 px5g_rsa *px5g = luaL_checkudata(L, 1, PX5G_KEY_META);
127 lua_pushfstring(L, "px5g context %p", px5g);
132 static const luaL_reg M[] = {
133 {"asn1", px5g_rsa_asn1},
134 {"create_selfsigned", px5g_rsa_create_selfsigned},
135 {"__gc", px5g_rsa__gc},
136 {"__tostring", px5g_rsa__tostring},
141 static const luaL_reg R[] = {
142 {"genkey", px5g_genkey},
146 int luaopen_px5g(lua_State *L) {
147 /* register module */
148 luaL_register(L, "px5g", R);
151 luaL_newmetatable(L, PX5G_KEY_META);
152 luaL_register(L, NULL, M);
153 lua_pushvalue(L, -1);
154 lua_setfield(L, -2, "__index");
156 lua_setfield(L, -2, "meta_key");