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
)),
89 lua_pushliteral(L
, "");
90 for (int i
= 0; i
< (sizeof(xfields
) / sizeof(*xfields
)); i
++) {
91 lua_pushstring(L
, xfields
[i
]);
93 if (lua_isstring(L
, -1)) {
94 const char *val
= lua_tostring(L
, -1);
95 luaL_argcheck(L
, !strchr(val
, ';'), 2, "Invalid Value");
96 lua_pushfstring(L
, "%s=%s;", xfields
[i
], val
);
106 x509write_init_raw(&cert
);
107 x509write_add_pubkey(&cert
, &px5g
->rsa
);
108 x509write_add_subject(&cert
, (unsigned char*)lua_tostring(L
, -1));
109 x509write_add_validity(&cert
, (unsigned char*)fstr
, (unsigned char*)tstr
);
110 x509write_create_selfsign(&cert
, &px5g
->rsa
);
112 lua_pushlstring(L
, (char*)cert
.raw
.data
, cert
.raw
.len
);
113 x509write_free_raw(&cert
);
117 static int px5g_rsa__gc(lua_State
*L
) {
118 px5g_rsa
*px5g
= luaL_checkudata(L
, 1, PX5G_KEY_META
);
120 rsa_free(&px5g
->rsa
);
126 static int px5g_rsa__tostring(lua_State
*L
) {
127 px5g_rsa
*px5g
= luaL_checkudata(L
, 1, PX5G_KEY_META
);
128 lua_pushfstring(L
, "px5g context %p", px5g
);
133 static const luaL_reg M
[] = {
134 {"asn1", px5g_rsa_asn1
},
135 {"create_selfsigned", px5g_rsa_create_selfsigned
},
136 {"__gc", px5g_rsa__gc
},
137 {"__tostring", px5g_rsa__tostring
},
142 static const luaL_reg R
[] = {
143 {"genkey", px5g_genkey
},
147 int luaopen_px5g(lua_State
*L
) {
148 /* register module */
149 luaL_register(L
, "px5g", R
);
152 luaL_newmetatable(L
, PX5G_KEY_META
);
153 luaL_register(L
, NULL
, M
);
154 lua_pushvalue(L
, -1);
155 lua_setfield(L
, -2, "__index");
157 lua_setfield(L
, -2, "meta_key");