1 /* Licensed to the Apache Software Foundation (ASF) under one or more
2  * contributor license agreements.
3  * The ASF licenses this file to You under the Apache License, Version 2.0
4  * (the "License"); you may not use this file except in compliance with
5  * the License.  You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  *
15  * ---------------------------------------------------------------------------
16  * This work is derived from the famos luacrypto library:
17  *
18  * The LuaCrypto library is designed and implemented by Keith Howe. The
19  * implementation is not derived from licensed software.
20  *
21  * Copyright © 2006 Keith Howe.
22  *
23  * Permission is hereby granted, free of charge, to any person obtaining a copy
24  * of this software and associated documentation files (the "Software"), to
25  * deal in the Software without restriction, including without limitation the
26  * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
27  * sell copies of the Software, and to permit persons to whom the Software is
28  * furnished to do so, subject to the following conditions:
29  *
30  * The above copyright notice and this permission notice shall be included in all
31  * copies or substantial portions of the Software.
32  *
33  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
34  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
35  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
36  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
37  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
38  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
39  * IN THE SOFTWARE.
40  * ---------------------------------------------------------------------------
41  */
42 
43 /**
44  * @file
45  *
46  * @Author christian liesch <liesch@gmx.ch>
47  *
48  * Interface of the HTTP Test Tool lua crypto extention.
49  */
50 
51 
52 /************************************************************************
53  * Includes
54  ***********************************************************************/
55 
56 #ifdef HAVE_CONFIG_H
57 #include <config.h>
58 #endif
59 
60 #include <string.h>
61 #include <openssl/ssl.h>
62 #include <openssl/err.h>
63 #include <openssl/asn1.h>
64 #include <openssl/evp.h>
65 #include <openssl/hmac.h>
66 #include <openssl/rand.h>
67 #include <openssl/x509.h>
68 #include <openssl/dh.h>
69 
70 #define LUA_COMPAT_MODULE
71 #include "lua.h"
72 #include "lauxlib.h"
73 #if ! defined (LUA_VERSION_NUM) || LUA_VERSION_NUM < 501
74 #include "compat-5.1.h"
75 #endif
76 
77 #include "lua_crypto.h"
78 #include "module.h"
79 
80 /************************************************************************
81  * Definitions
82  ***********************************************************************/
83 
84 #define LUACRYPTO_PREFIX "LuaCrypto: "
85 #define LUACRYPTO_CORE "crypto"
86 #define LUACRYPTO_EVP "crypto.evp"
87 #define LUACRYPTO_HMAC "crypto.hmac"
88 #define LUACRYPTO_RAND "crypto.rand"
89 #define LUACRYPTO_BASE64 "crypto.base64"
90 #define LUACRYPTO_X509 "crypto.x509"
91 #define LUACRYPTO_X509NAME "crypto.x509name"
92 #define LUACRYPTO_ASN1TIME "crypto.asn1time"
93 #define LUACRYPTO_DH "crypto.dh"
94 
95 
96 /************************************************************************
97  * Forward declaration
98  ***********************************************************************/
99 
100 int luaopen_crypto(lua_State *L);
101 
102 
103 /************************************************************************
104  * Implementation
105  ***********************************************************************/
106 
crypto_error(lua_State * L)107 static int crypto_error(lua_State *L) {
108   char buf[120];
109   unsigned long e = ERR_get_error();
110   ERR_load_crypto_strings();
111   lua_pushnil(L);
112   lua_pushstring(L, ERR_error_string(e, buf));
113   return 2;
114 }
115 
116 /**
117  * EVP Object
118  */
evp_pget(lua_State * L,int i)119 static EVP_MD_CTX *evp_pget(lua_State *L, int i) {
120   if (luaL_checkudata(L, i, LUACRYPTO_EVP) == NULL) {
121     luaL_argerror(L, 1, "invalid object type");
122   }
123   return lua_touserdata(L, i);
124 }
125 
evp_pnew(lua_State * L)126 static EVP_MD_CTX *evp_pnew(lua_State *L) {
127   EVP_MD_CTX *c = lua_newuserdata(L, sizeof(c));
128   luaL_getmetatable(L, LUACRYPTO_EVP);
129   lua_setmetatable(L, -2);
130   return c;
131 }
132 
evp_fnew(lua_State * L)133 static int evp_fnew(lua_State *L) {
134   EVP_MD_CTX *c = NULL;
135   const char *s = luaL_checkstring(L, 1);
136   const EVP_MD *type = EVP_get_digestbyname(s);
137 
138   if (type == NULL) {
139     luaL_argerror(L, 1, "invalid digest type");
140     return 0;
141   }
142 
143   c = evp_pnew(L);
144   EVP_MD_CTX_init(c);
145   EVP_DigestInit_ex(c, type, NULL);
146 
147   return 1;
148 }
149 
evp_clone(lua_State * L)150 static int evp_clone(lua_State *L) {
151   EVP_MD_CTX *c = evp_pget(L, 1);
152   EVP_MD_CTX *d = evp_pnew(L);
153   EVP_MD_CTX_init(d);
154   EVP_MD_CTX_copy_ex(d, c);
155   return 1;
156 }
157 
evp_reset(lua_State * L)158 static int evp_reset(lua_State *L) {
159   EVP_MD_CTX *c = evp_pget(L, 1);
160   const EVP_MD *t = EVP_MD_CTX_md(c);
161   EVP_MD_CTX_reset(c);
162   EVP_DigestInit_ex(c, t, NULL);
163   return 0;
164 }
165 
evp_update(lua_State * L)166 static int evp_update(lua_State *L) {
167   EVP_MD_CTX *c = evp_pget(L, 1);
168   const char *s = luaL_checkstring(L, 2);
169 
170   EVP_DigestUpdate(c, s, strlen(s));
171 
172   lua_settop(L, 1);
173   return 1;
174 }
175 
evp_digest(lua_State * L)176 static int evp_digest(lua_State *L) {
177   EVP_MD_CTX *c = evp_pget(L, 1);
178   EVP_MD_CTX *d = NULL;
179   unsigned char digest[EVP_MAX_MD_SIZE];
180   unsigned int written = 0;
181   unsigned int i;
182   char *hex;
183 
184   if (lua_isstring(L, 2)) {
185     const char *s = luaL_checkstring(L, 2);
186     EVP_DigestUpdate(c, s, strlen(s));
187   }
188 
189   d = EVP_MD_CTX_create();
190   EVP_MD_CTX_copy_ex(d, c);
191   EVP_DigestFinal_ex(d, digest, &written);
192   EVP_MD_CTX_destroy(d);
193 
194   if (lua_toboolean(L, 3)) {
195     lua_pushlstring(L, (char *)digest, written);
196   }
197   else {
198     hex = calloc(sizeof(char), written*2 + 1);
199     for (i = 0; i < written; i++)
200       sprintf(hex + 2*i, "%02x", digest[i]);
201     lua_pushlstring(L, hex, written*2);
202     free(hex);
203   }
204 
205   return 1;
206 }
207 
evp_tostring(lua_State * L)208 static int evp_tostring(lua_State *L) {
209   EVP_MD_CTX *c = evp_pget(L, 1);
210   char s[64];
211   sprintf(s, "%s %p", LUACRYPTO_EVP, (void *)c);
212   lua_pushstring(L, s);
213   return 1;
214 }
215 
evp_gc(lua_State * L)216 static int evp_gc(lua_State *L) {
217   EVP_MD_CTX *c = evp_pget(L, 1);
218   EVP_MD_CTX_free(c);
219   return 1;
220 }
221 
evp_fdigest(lua_State * L)222 static int evp_fdigest(lua_State *L) {
223   EVP_MD_CTX *c = NULL;
224   const char *type_name = luaL_checkstring(L, 1);
225   const char *s = luaL_checkstring(L, 2);
226   const EVP_MD *type = EVP_get_digestbyname(type_name);
227   unsigned char digest[EVP_MAX_MD_SIZE];
228   unsigned int written = 0;
229   unsigned int i;
230   char *hex;
231 
232   if (type == NULL) {
233     luaL_argerror(L, 1, "invalid digest type");
234     return 0;
235   }
236 
237   c = EVP_MD_CTX_create();
238   EVP_DigestInit_ex(c, type, NULL);
239   EVP_DigestUpdate(c, s, strlen(s));
240   EVP_DigestFinal_ex(c, digest, &written);
241 
242   if (lua_toboolean(L, 3)) {
243     lua_pushlstring(L, (char *)digest, written);
244   }
245   else {
246     hex = calloc(sizeof(char), written*2 + 1);
247     for (i = 0; i < written; i++) {
248       sprintf(hex + 2*i, "%02x", digest[i]);
249     }
250     lua_pushlstring(L, hex, written*2);
251     free(hex);
252   }
253 
254   return 1;
255 }
256 
257 /**
258  * HMAC Object
259  */
hmac_pget(lua_State * L,int i)260 static HMAC_CTX *hmac_pget(lua_State *L, int i) {
261  if (luaL_checkudata(L, i, LUACRYPTO_HMAC) == NULL) {
262     luaL_argerror(L, 1, "invalid object type");
263  }
264  return lua_touserdata(L, i);
265 }
266 
hmac_pnew(lua_State * L)267 static HMAC_CTX *hmac_pnew(lua_State *L) {
268   HMAC_CTX *c = lua_newuserdata(L, sizeof(c));
269   luaL_getmetatable(L, LUACRYPTO_HMAC);
270   lua_setmetatable(L, -2);
271   return c;
272 }
273 
hmac_fnew(lua_State * L)274 static int hmac_fnew(lua_State *L) {
275   HMAC_CTX *c = hmac_pnew(L);
276   const char *s = luaL_checkstring(L, 1);
277   const char *k = luaL_checkstring(L, 2);
278   const EVP_MD *type = EVP_get_digestbyname(s);
279 
280   if (type == NULL) {
281     luaL_argerror(L, 1, "invalid digest type");
282     return 0;
283   }
284 
285   c = HMAC_CTX_new();
286   HMAC_Init_ex(c, k, strlen(k), type, NULL);
287 
288   return 1;
289 }
290 
hmac_clone(lua_State * L)291 static int hmac_clone(lua_State *L) {
292  HMAC_CTX *c = hmac_pget(L, 1);
293  HMAC_CTX *d = hmac_pnew(L);
294  HMAC_CTX_copy(d, c);
295  return 1;
296 }
297 
hmac_reset(lua_State * L)298 static int hmac_reset(lua_State *L) {
299   HMAC_CTX *c = hmac_pget(L, 1);
300   HMAC_Init_ex(c, NULL, 0, NULL, NULL);
301   return 0;
302 }
303 
hmac_update(lua_State * L)304 static int hmac_update(lua_State *L) {
305   HMAC_CTX *c = hmac_pget(L, 1);
306   const char *s = luaL_checkstring(L, 2);
307 
308   HMAC_Update(c, (unsigned char *)s, strlen(s));
309 
310   lua_settop(L, 1);
311   return 1;
312 }
313 
hmac_digest(lua_State * L)314 static int hmac_digest(lua_State *L) {
315   HMAC_CTX *c = hmac_pget(L, 1);
316   unsigned char digest[EVP_MAX_MD_SIZE];
317   unsigned int written = 0;
318   unsigned int i;
319   char *hex;
320 
321   if (lua_isstring(L, 2))
322   {
323     const char *s = luaL_checkstring(L, 2);
324     HMAC_Update(c, (unsigned char *)s, strlen(s));
325   }
326 
327   HMAC_Final(c, digest, &written);
328 
329   if (lua_toboolean(L, 3)) {
330     lua_pushlstring(L, (char *)digest, written);
331   }
332   else {
333     hex = calloc(sizeof(char), written*2 + 1);
334     for (i = 0; i < written; i++) {
335       sprintf(hex + 2*i, "%02x", digest[i]);
336     }
337     lua_pushlstring(L, hex, written*2);
338     free(hex);
339   }
340 
341   return 1;
342 }
343 
hmac_tostring(lua_State * L)344 static int hmac_tostring(lua_State *L) {
345   HMAC_CTX *c = hmac_pget(L, 1);
346   char s[64];
347   sprintf(s, "%s %p", LUACRYPTO_HMAC, (void *)c);
348   lua_pushstring(L, s);
349   return 1;
350 }
351 
hmac_gc(lua_State * L)352 static int hmac_gc(lua_State *L) {
353   HMAC_CTX *c = hmac_pget(L, 1);
354   HMAC_CTX_free(c);
355   return 1;
356 }
357 
hmac_fdigest(lua_State * L)358 static int hmac_fdigest(lua_State *L) {
359   HMAC_CTX *c;
360   unsigned char digest[EVP_MAX_MD_SIZE];
361   unsigned int written = 0;
362   unsigned int i;
363   char *hex;
364   const char *t = luaL_checkstring(L, 1);
365   const char *s = luaL_checkstring(L, 2);
366   const char *k = luaL_checkstring(L, 3);
367   const EVP_MD *type = EVP_get_digestbyname(t);
368 
369   if (type == NULL) {
370     luaL_argerror(L, 1, "invalid digest type");
371     return 0;
372   }
373 
374   c = HMAC_CTX_new();
375   HMAC_Init_ex(c, k, strlen(k), type, NULL);
376   HMAC_Update(c, (unsigned char *)s, strlen(s));
377   HMAC_Final(c, digest, &written);
378   HMAC_CTX_free(c);
379 
380   if (lua_toboolean(L, 4)) {
381     lua_pushlstring(L, (char *)digest, written);
382   }
383   else {
384     hex = calloc(sizeof(char), written*2 + 1);
385     for (i = 0; i < written; i++) {
386       sprintf(hex + 2*i, "%02x", digest[i]);
387     }
388     lua_pushlstring(L, hex, written*2);
389     free(hex);
390   }
391 
392   return 1;
393 }
394 
395 /**
396  * Random Object
397  */
rand_do_bytes(lua_State * L,int (* bytes)(unsigned char * buf,int len))398 static int rand_do_bytes(lua_State *L, int (*bytes)(unsigned char *buf, int len)) {
399   size_t count = luaL_checkint(L, 1);
400   unsigned char tmp[256], *buf = tmp;
401   if (count > sizeof tmp) {
402     buf = malloc(count);
403   }
404   if (!buf) {
405     return luaL_error(L, "out of memory");
406   }
407   else if (!bytes(buf, count)) {
408     return crypto_error(L);
409   }
410   lua_pushlstring(L, (char *)buf, count);
411   if (buf != tmp) {
412     free(buf);
413   }
414   return 1;
415 }
416 
rand_bytes(lua_State * L)417 static int rand_bytes(lua_State *L) {
418   return rand_do_bytes(L, RAND_bytes);
419 }
420 
rand_pseudo_bytes(lua_State * L)421 static int rand_pseudo_bytes(lua_State *L) {
422   return rand_do_bytes(L, RAND_pseudo_bytes);
423 }
424 
rand_add(lua_State * L)425 static int rand_add(lua_State *L) {
426   size_t num;
427   const void *buf = luaL_checklstring(L, 1, &num);
428   double entropy = luaL_optnumber(L, 2, num);
429   RAND_add(buf, num, entropy);
430   return 0;
431 }
432 
rand_status(lua_State * L)433 static int rand_status(lua_State *L) {
434   lua_pushboolean(L, RAND_status());
435   return 1;
436 }
437 
438 enum { WRITE_FILE_COUNT = 1024 };
rand_load(lua_State * L)439 static int rand_load(lua_State *L) {
440   const char *name = luaL_optstring(L, 1, 0);
441   char tmp[256];
442   int n;
443   if (!name && !(name = RAND_file_name(tmp, sizeof tmp))) {
444     return crypto_error(L);
445   }
446   n = RAND_load_file(name, WRITE_FILE_COUNT);
447   if (n == 0) {
448     return crypto_error(L);
449   }
450   lua_pushnumber(L, n);
451   return 1;
452 }
453 
rand_write(lua_State * L)454 static int rand_write(lua_State *L) {
455   const char *name = luaL_optstring(L, 1, 0);
456   char tmp[256];
457   int n;
458   if (!name && !(name = RAND_file_name(tmp, sizeof tmp))) {
459     return crypto_error(L);
460   }
461   n = RAND_write_file(name);
462   if (n == 0) {
463     return crypto_error(L);
464   }
465   lua_pushnumber(L, n);
466   return 1;
467 }
468 
rand_cleanup(lua_State * L)469 static int rand_cleanup(lua_State *L) {
470   RAND_cleanup();
471   return 0;
472 }
473 
474 /**
475  * Base64
476  */
b64_encode(lua_State * L)477 static int b64_encode(lua_State *L) {
478   if (lua_isstring(L, -1)) {
479     apr_pool_t *pool;
480     apr_size_t len;
481     apr_size_t b64len;
482     char *base64;
483 
484     const char *buffer = lua_tolstring(L, -1, &len);
485 
486     HT_POOL_CREATE(&pool);
487     b64len = apr_base64_encode_len(len);
488     base64 = apr_pcalloc(pool, b64len + 1);
489     apr_base64_encode(base64, buffer, len);
490 
491     lua_pushstring(L, base64);
492     apr_pool_destroy(pool);
493     return 1;
494   }
495   else {
496     luaL_error(L, "Expect a string parameter");
497     return 1;
498   }
499 }
500 
b64_decode(lua_State * L)501 static int b64_decode(lua_State *L) {
502   if (lua_isstring(L, -1)) {
503     apr_pool_t *pool;
504     apr_size_t len;
505     unsigned char *plain;
506 
507     const char *buffer = lua_tolstring(L, -1, &len);
508 
509     HT_POOL_CREATE(&pool);
510 
511     len = apr_base64_decode_len(buffer);
512     plain = apr_pcalloc(pool, len);
513     apr_base64_decode_binary(plain, buffer);
514 
515     lua_pushlstring(L, (char *)plain, len);
516     apr_pool_destroy(pool);
517     return 1;
518   }
519   else {
520     luaL_error(L, "Expect a string parameter");
521     return 1;
522   }
523 }
524 
525 /**
526  * X509 Object
527  */
x509_pget(lua_State * L,int i)528 static X509 *x509_pget(lua_State *L, int i) {
529   if (luaL_checkudata(L, i, LUACRYPTO_X509) == NULL) {
530     luaL_argerror(L, 1, "invalid object type");
531   }
532   return lua_touserdata(L, i);
533 }
534 
x509_fnew(lua_State * L)535 static int x509_fnew(lua_State *L) {
536   apr_size_t len;
537   const char *data = luaL_checklstring(L, 1, &len);
538   X509 *cert;
539   BIO *mem;
540 
541   if (data == NULL) {
542     luaL_argerror(L, 1, "PEM cert to load");
543     return 0;
544   }
545 
546   mem = BIO_new_mem_buf((void *)data, len);
547   cert = PEM_read_bio_X509(mem, NULL, NULL, NULL);
548 
549   lua_pushlightuserdata(L, cert);
550   luaL_getmetatable(L, LUACRYPTO_X509);
551   lua_setmetatable(L, -2);
552 
553   return 1;
554 }
555 
x509_fload(lua_State * L)556 static int x509_fload(lua_State *L) {
557   const char *filename = luaL_checkstring(L, 1);
558   X509 *cert;
559   BIO *file;
560 
561   if (filename == NULL) {
562     luaL_argerror(L, 1, "path to x509 pem formated cert missing");
563     return 0;
564   }
565 
566   file = BIO_new_file(filename, "r");
567   cert = PEM_read_bio_X509(file, NULL, NULL, NULL);
568 
569   lua_pushlightuserdata(L, cert);
570   luaL_getmetatable(L, LUACRYPTO_X509);
571   lua_setmetatable(L, -2);
572 
573   return 1;
574 }
575 
x509_clone(lua_State * L)576 static int x509_clone(lua_State *L) {
577   X509 *cert = x509_pget(L, 1);
578   X509 *copy = X509_dup(cert);
579 
580   lua_pushlightuserdata(L, copy);
581   luaL_getmetatable(L, LUACRYPTO_X509);
582   lua_setmetatable(L, -2);
583   return 1;
584 }
585 
x509_get_subject_name(lua_State * L)586 static int x509_get_subject_name(lua_State *L) {
587   X509 *cert = x509_pget(L, 1);
588   X509_NAME *name = X509_get_subject_name(cert);
589 
590   lua_pushlightuserdata(L, name);
591   luaL_getmetatable(L, LUACRYPTO_X509NAME);
592   lua_setmetatable(L, -2);
593   return 1;
594 }
595 
x509_get_issuer_name(lua_State * L)596 static int x509_get_issuer_name(lua_State *L) {
597   X509 *cert = x509_pget(L, 1);
598   X509_NAME *name = X509_get_issuer_name(cert);
599 
600   lua_pushlightuserdata(L, name);
601   luaL_getmetatable(L, LUACRYPTO_X509NAME);
602   lua_setmetatable(L, -2);
603   return 1;
604 }
605 
x509_get_not_before(lua_State * L)606 static int x509_get_not_before(lua_State *L) {
607   X509 *cert = x509_pget(L, 1);
608   ASN1_TIME *time = X509_get_notBefore(cert);
609 
610   lua_pushlightuserdata(L, time);
611   luaL_getmetatable(L, LUACRYPTO_ASN1TIME);
612   lua_setmetatable(L, -2);
613   return 1;
614 }
615 
x509_get_not_after(lua_State * L)616 static int x509_get_not_after(lua_State *L) {
617   X509 *cert = x509_pget(L, 1);
618   ASN1_TIME *time = X509_get_notAfter(cert);
619 
620   lua_pushlightuserdata(L, time);
621   luaL_getmetatable(L, LUACRYPTO_ASN1TIME);
622   lua_setmetatable(L, -2);
623   return 1;
624 }
625 
x509_tostring(lua_State * L)626 static int x509_tostring(lua_State *L) {
627   apr_pool_t *pool;
628   X509 *cert = x509_pget(L, 1);
629   char *s;
630   HT_POOL_CREATE(&pool);
631   s = apr_psprintf(pool, "X509 cert %p", (void *)cert);
632   lua_pushstring(L, s);
633   apr_pool_destroy(pool);
634   return 1;
635 }
636 
x509_gc(lua_State * L)637 static int x509_gc(lua_State *L) {
638   X509 *c = x509_pget(L, 1);
639   X509_free(c);
640   return 1;
641 }
642 
643 /**
644  * X509_NAME Object
645  */
x509_name_pget(lua_State * L,int i)646 static X509_NAME *x509_name_pget(lua_State *L, int i) {
647   if (luaL_checkudata(L, i, LUACRYPTO_X509NAME) == NULL) {
648     luaL_argerror(L, 1, "invalid object type");
649   }
650   return lua_touserdata(L, i);
651 }
652 
x509_name_clone(lua_State * L)653 static int x509_name_clone(lua_State *L) {
654   X509_NAME *name = x509_name_pget(L, 1);
655   X509_NAME *copy = X509_NAME_dup(name);
656 
657   lua_pushlightuserdata(L, copy);
658   luaL_getmetatable(L, LUACRYPTO_X509NAME);
659   lua_setmetatable(L, -2);
660   return 1;
661 }
662 
x509_name_tostring(lua_State * L)663 static int x509_name_tostring(lua_State *L) {
664   char *s;
665   X509_NAME *name = x509_name_pget(L, 1);
666   s = X509_NAME_oneline(name, NULL, 0);
667   lua_pushstring(L, s);
668   OPENSSL_free(s);
669   return 1;
670 }
671 
x509_name_toasn1(lua_State * L)672 static int x509_name_toasn1(lua_State *L) {
673   unsigned char *s = NULL;
674   apr_size_t len;
675   X509_NAME *name = x509_name_pget(L, 1);
676   len = i2d_X509_NAME(name, &s);
677   lua_pushlstring(L, (char *)s, len);
678   OPENSSL_free(s);
679   return 1;
680 }
681 
x509_name_gc(lua_State * L)682 static int x509_name_gc(lua_State *L) {
683   X509_NAME *name = x509_name_pget(L, 1);
684   X509_NAME_free(name);
685   return 1;
686 }
687 
688 /**
689  * ASN1_TIME Object
690  */
asn1_time_pget(lua_State * L,int i)691 static ASN1_TIME *asn1_time_pget(lua_State *L, int i) {
692   if (luaL_checkudata(L, i, LUACRYPTO_ASN1TIME) == NULL) {
693     luaL_argerror(L, 1, "invalid object type");
694   }
695   return lua_touserdata(L, i);
696 }
697 
asn1_time_fnew(lua_State * L)698 static int asn1_time_fnew(lua_State *L) {
699   ASN1_TIME *asn1time = (ASN1_TIME *)ASN1_STRING_type_new(V_ASN1_UTCTIME);
700   time_t t = time(NULL);
701   ASN1_TIME_set(asn1time, t);
702   lua_pushlightuserdata(L, asn1time);
703   luaL_getmetatable(L, LUACRYPTO_ASN1TIME);
704   lua_setmetatable(L, -2);
705 
706   return 1;
707 }
708 
asn1_time_clone(lua_State * L)709 static int asn1_time_clone(lua_State *L) {
710   ASN1_TIME *time = asn1_time_pget(L, 1);
711   ASN1_TIME *copy = ASN1_STRING_dup((const ASN1_STRING *)time);
712 
713   lua_pushlightuserdata(L, copy);
714   luaL_getmetatable(L, LUACRYPTO_ASN1TIME);
715   lua_setmetatable(L, -2);
716   return 1;
717 }
718 
asn1_time_tostring(lua_State * L)719 static int asn1_time_tostring(lua_State *L) {
720   char s[1024];
721   BIO *mem;
722   ASN1_TIME *time = asn1_time_pget(L, 1);
723   mem = BIO_new_mem_buf((void *)s, 1024);
724   ASN1_TIME_print(mem, time);
725   lua_pushstring(L, s);
726   return 1;
727 }
728 
asn1_time_toasn1(lua_State * L)729 static int asn1_time_toasn1(lua_State *L) {
730   unsigned char *s = NULL;
731   apr_size_t len;
732   ASN1_TIME *time = asn1_time_pget(L, 1);
733   len = i2d_ASN1_TIME(time, &s);
734   lua_pushlstring(L, (char *)s, len);
735   OPENSSL_free(s);
736   return 1;
737 }
738 
asn1_time_gc(lua_State * L)739 static int asn1_time_gc(lua_State *L) {
740   ASN1_TIME *time = asn1_time_pget(L, 1);
741   ASN1_STRING_free((ASN1_STRING *)time);
742   return 1;
743 }
744 
745 /**
746  * DH object
747  */
748 
dh_cb(int p,int n,BN_GENCB * cb)749 static int dh_cb(int p, int n, BN_GENCB *cb) {
750   char c='*';
751 
752   switch (p) {
753   case 0:
754     c='.';
755     break;
756   case 1:
757     c='+';
758     break;
759   case 2:
760     c='*';
761     break;
762   case 3:
763     c='\n';
764     break;
765   }
766   BIO_write(BN_GENCB_get_arg(cb),&c,1);
767   (void)BIO_flush(BN_GENCB_get_arg(cb));
768   return 1;
769 }
770 
dh_pget(lua_State * L,int i)771 static DH *dh_pget(lua_State *L, int i) {
772   if (luaL_checkudata(L, i, LUACRYPTO_DH) == NULL) {
773     luaL_argerror(L, 1, "invalid object type");
774   }
775   return lua_touserdata(L, i);
776 }
777 
dh_fnew(lua_State * L)778 static int dh_fnew(lua_State *L) {
779   int generator = luaL_checknumber(L, 1);
780   int num = luaL_checknumber(L, 2);
781   DH *dh = DH_new();
782   BIO *bio_err;
783   BN_GENCB *cb;
784   cb = BN_GENCB_new();
785   if (!cb) {
786     luaL_argerror(L, 1, "could not create BN_GENCB structure");
787     return 1;
788   }
789   if ((bio_err = BIO_new(BIO_s_file())) != NULL) {
790     BIO_set_fp(bio_err,stderr,BIO_NOCLOSE|BIO_FP_TEXT);
791   }
792   BN_GENCB_set(cb, dh_cb, bio_err);
793   if (!DH_generate_parameters_ex(dh, num, generator, cb)) {
794     luaL_argerror(L, 1, "could not generate DH paramters");
795     BN_GENCB_free(cb);
796     return 1;
797   }
798   DH_generate_key(dh);
799   lua_pushlightuserdata(L, dh);
800   luaL_getmetatable(L, LUACRYPTO_DH);
801   lua_setmetatable(L, -2);
802   BN_GENCB_free(cb);
803 
804   return 1;
805 }
806 
dh_clone(lua_State * L)807 static int dh_clone(lua_State *L) {
808   DH *dh = dh_pget(L, 1);
809   DH *copy = DHparams_dup(dh);
810 
811   lua_pushlightuserdata(L, copy);
812   luaL_getmetatable(L, LUACRYPTO_DH);
813   lua_setmetatable(L, -2);
814   return 1;
815 }
816 
dh_tostring(lua_State * L)817 static int dh_tostring(lua_State *L) {
818   char *s;
819   apr_pool_t *pool;
820   DH *dh = dh_pget(L, 1);
821   HT_POOL_CREATE(&pool);
822   s = apr_psprintf(pool, "DH %p", (void *)dh);
823   lua_pushstring(L, s);
824   apr_pool_destroy(pool);
825   return 1;
826 }
827 
828 #if !defined(LIBRESSL_VERSION_NUMBER)
dh_get_prime(lua_State * L)829 static int dh_get_prime(lua_State *L) {
830   apr_size_t len;
831   unsigned char *s;
832   apr_pool_t *pool;
833   DH *dh = dh_pget(L, 1);
834   HT_POOL_CREATE(&pool);
835   s = apr_pcalloc(pool, BN_num_bytes(DH_get0_p(dh)));
836   len = BN_bn2bin(DH_get0_p(dh), s);
837   lua_pushlstring(L, (char *)s, len);
838   apr_pool_destroy(pool);
839   return 1;
840 }
841 #endif
842 
843 #if !defined(LIBRESSL_VERSION_NUMBER)
dh_get_priv_key(lua_State * L)844 static int dh_get_priv_key(lua_State *L) {
845   apr_size_t len;
846   unsigned char *s;
847   apr_pool_t *pool;
848   DH *dh = dh_pget(L, 1);
849   HT_POOL_CREATE(&pool);
850   s = apr_pcalloc(pool, BN_num_bytes(DH_get0_priv_key(dh)));
851   len = BN_bn2bin(DH_get0_priv_key(dh), s);
852   lua_pushlstring(L, (char *)s, len);
853   apr_pool_destroy(pool);
854   return 1;
855 }
856 #endif
857 
858 #if !defined(LIBRESSL_VERSION_NUMBER)
dh_get_pub_key(lua_State * L)859 static int dh_get_pub_key(lua_State *L) {
860   apr_size_t len;
861   unsigned char *s;
862   apr_pool_t *pool;
863   DH *dh = dh_pget(L, 1);
864   HT_POOL_CREATE(&pool);
865   s = apr_pcalloc(pool, BN_num_bytes(DH_get0_pub_key(dh)));
866   len = BN_bn2bin(DH_get0_pub_key(dh), s);
867   lua_pushlstring(L, (char *)s, len);
868   apr_pool_destroy(pool);
869   return 1;
870 }
871 #endif
872 
dh_gc(lua_State * L)873 static int dh_gc(lua_State *L) {
874   DH *dh = dh_pget(L, 1);
875   DH_free(dh);
876   return 1;
877 }
878 
879 /**
880  * Create a metatable and leave it on top of the stack.
881  */
luacrypto_createmeta(lua_State * L,const char * name,const luaL_Reg * methods)882 int luacrypto_createmeta (lua_State *L, const char *name, const luaL_Reg *methods) {
883   if (!luaL_newmetatable (L, name)) {
884     return 0;
885   }
886 
887   /* define methods */
888   luaL_openlib (L, NULL, methods, 0);
889 
890   /* define metamethods */
891   lua_pushliteral (L, "__index");
892   lua_pushvalue (L, -2);
893   lua_settable (L, -3);
894 
895   lua_pushliteral (L, "__metatable");
896   lua_pushliteral (L, LUACRYPTO_PREFIX"you're not allowed to get this metatable");
897   lua_settable (L, -3);
898 
899   return 1;
900 }
901 
902 /**
903  * Create metatables for each class of object.
904  */
create_metatables(lua_State * L)905 static void create_metatables (lua_State *L) {
906   struct luaL_Reg evp_functions[] = {
907     { "digest", evp_fdigest },
908     { "new", evp_fnew },
909     {NULL, NULL},
910   };
911 
912   struct luaL_Reg evp_methods[] = {
913     { "__tostring", evp_tostring },
914     { "__gc", evp_gc },
915     { "clone", evp_clone },
916     { "digest", evp_digest },
917     { "reset", evp_reset },
918     { "tostring", evp_tostring },
919     { "update",	evp_update },
920     {NULL, NULL},
921   };
922 
923   struct luaL_Reg hmac_functions[] = {
924     { "digest", hmac_fdigest },
925     { "new", hmac_fnew },
926     { NULL, NULL }
927   };
928 
929   struct luaL_Reg hmac_methods[] = {
930     { "__tostring", hmac_tostring },
931     { "__gc", hmac_gc },
932     { "clone", hmac_clone },
933     { "digest", hmac_digest },
934     { "reset", hmac_reset },
935     { "tostring", hmac_tostring },
936     { "update", hmac_update },
937     { NULL, NULL }
938   };
939   struct luaL_Reg rand_functions[] = {
940     { "bytes", rand_bytes },
941     { "pseudo_bytes", rand_pseudo_bytes },
942     { "add", rand_add },
943     { "seed", rand_add },
944     { "status", rand_status },
945     { "load", rand_load },
946     { "write", rand_write },
947     { "cleanup", rand_cleanup },
948     { NULL, NULL }
949   };
950   struct luaL_Reg b64_functions[] = {
951     { "encode", b64_encode },
952     { "decode", b64_decode },
953     {NULL, NULL},
954   };
955 
956   struct luaL_Reg x509_functions[] = {
957     { "new", x509_fnew },
958     { "load", x509_fload },
959     {NULL, NULL},
960   };
961 
962   struct luaL_Reg x509_methods[] = {
963     { "__tostring", x509_tostring },
964     { "__gc", x509_gc },
965     { "clone", x509_clone },
966     { "tostring", x509_tostring },
967     { "get_subject_name", x509_get_subject_name },
968     { "get_issuer_name", x509_get_issuer_name },
969     { "get_not_before", x509_get_not_before },
970     { "get_not_after", x509_get_not_after },
971     {NULL, NULL},
972   };
973 
974   struct luaL_Reg x509_name_methods[] = {
975     { "__tostring", x509_name_tostring },
976     { "__gc", x509_name_gc },
977     { "clone", x509_name_clone },
978     { "tostring", x509_name_tostring },
979     { "toasn1", x509_name_toasn1 },
980     {NULL, NULL},
981   };
982 
983   struct luaL_Reg asn1_time_functions[] = {
984     { "new", asn1_time_fnew },
985     {NULL, NULL},
986   };
987 
988   struct luaL_Reg asn1_time_methods[] = {
989     { "__tostring", asn1_time_tostring },
990     { "__gc", asn1_time_gc },
991     { "clone", asn1_time_clone },
992     { "tostring", asn1_time_tostring },
993     { "toasn1", asn1_time_toasn1 },
994     {NULL, NULL},
995   };
996 
997   struct luaL_Reg dh_functions[] = {
998     { "new", dh_fnew },
999     {NULL, NULL},
1000   };
1001 
1002   struct luaL_Reg dh_methods[] = {
1003     { "__tostring", dh_tostring },
1004     { "__gc", dh_gc },
1005     { "clone", dh_clone },
1006     { "tostring", dh_tostring },
1007 #if !defined(LIBRESSL_VERSION_NUMBER)
1008     { "get_prime", dh_get_prime },
1009     { "get_priv_key", dh_get_priv_key },
1010     { "get_pub_key", dh_get_pub_key },
1011 #endif
1012     {NULL, NULL},
1013   };
1014 
1015   luaL_openlib (L, LUACRYPTO_EVP, evp_functions, 0);
1016   luacrypto_createmeta(L, LUACRYPTO_EVP, evp_methods);
1017   luaL_openlib (L, LUACRYPTO_HMAC, hmac_functions, 0);
1018   luacrypto_createmeta(L, LUACRYPTO_HMAC, hmac_methods);
1019   luaL_openlib (L, LUACRYPTO_RAND, rand_functions, 0);
1020   luaL_openlib (L, LUACRYPTO_BASE64, b64_functions, 0);
1021   luaL_openlib (L, LUACRYPTO_X509, x509_functions, 0);
1022   luacrypto_createmeta(L, LUACRYPTO_X509, x509_methods);
1023   luacrypto_createmeta(L, LUACRYPTO_X509NAME, x509_name_methods);
1024   luaL_openlib (L, LUACRYPTO_ASN1TIME, asn1_time_functions, 0);
1025   luacrypto_createmeta(L, LUACRYPTO_ASN1TIME, asn1_time_methods);
1026   luaL_openlib (L, LUACRYPTO_DH, dh_functions, 0);
1027   luacrypto_createmeta(L, LUACRYPTO_DH, dh_methods);
1028   lua_pop (L, 3);
1029 }
1030 
1031 /**
1032  * Creates the metatables for the objects and registers the
1033  * driver open method.
1034  * @param L IN Lua hook
1035  * @return 1
1036  */
luaopen_crypto(lua_State * L)1037 int luaopen_crypto(lua_State *L) {
1038   struct luaL_Reg core[] = {
1039     {NULL, NULL},
1040   };
1041   OpenSSL_add_all_digests();
1042   create_metatables (L);
1043   luaL_openlib (L, LUACRYPTO_CORE, core, 0);
1044   return 1;
1045 }
1046