src/context.c

1
/*--------------------------------------------------------------------------
2
 * LuaSec 0.4
3
 * Copyright (C) 2006-2009 Bruno Silvestre
4
 *
5
 *--------------------------------------------------------------------------*/
6
 
7
#include <string.h>
8
#include <openssl/ssl.h>
9
#include <openssl/err.h>
10
#include <openssl/x509.h>
11
#include <openssl/x509v3.h>
12
 
13
#include <lua.h>
14
#include <lauxlib.h>
15
 
16
#include "context.h"
17
#include "ssl.h"
18
 
19
struct ssl_option_s {
20
  const char *name;
21
  unsigned long code;
22
};
23
typedef struct ssl_option_s ssl_option_t;
24
 
25
/* index into the SSL storage where the context is.
26
 * see SSL_CTX_get_ex_data().
27
 */
28
static int luasec_sslctx_idx = -1;
29
 
30
/* The export DH key */
31
static DH *dh_512    = NULL;
32
/* The larger key (builtin is 2048, caller may specify larger) */
33
static DH *dh_larger = NULL;
34
 
35
/* Generated via "openssl dhparam -2 -noout -C 512 2>/dev/null" */
36
static unsigned char dh512_p[] = {
37
  0xE4,0x3F,0x75,0x82,0xAD,0x0B,0x28,0xC7,0xEF,0xCE,0xBC,0x3B,
38
  0x14,0xBB,0xA6,0xF4,0xA2,0xE9,0xA6,0x59,0xCF,0x97,0x1C,0x86,
39
  0x43,0x3B,0x92,0x4A,0x6B,0x15,0x4B,0x0C,0xAC,0x8F,0xFA,0x43,
40
  0xE2,0xA8,0xC3,0x3B,0x7B,0x51,0x1B,0x46,0x21,0xBF,0x8C,0x06,
41
  0x6C,0xB1,0x49,0x75,0xC7,0xAC,0x47,0x1D,0x9D,0x64,0xD5,0x99,
42
  0x33,0x86,0xAD,0xEB,
43
};
44
 
45
/* Generated via "openssl dhparam -2 -noout -C 2048 2>/dev/null" */
46
static unsigned char dh2048_p[] = {
47
  0x9B,0xF4,0xC5,0x57,0x81,0x8F,0xCF,0x31,0x78,0x95,0x04,0xCD,
48
  0xEA,0xCC,0x30,0xEA,0xF7,0xCA,0x76,0xC8,0x8F,0x91,0xEA,0x0E,
49
  0x44,0x8D,0xE2,0x63,0x19,0x3B,0x4D,0x04,0xC8,0x7D,0x0D,0xFF,
50
  0x3D,0x52,0x76,0x02,0xF3,0xCA,0x1C,0x44,0xAF,0x0E,0xA9,0x59,
51
  0x02,0x40,0x75,0xD6,0xED,0x35,0x4D,0x11,0x5B,0x2B,0x73,0x23,
52
  0xE5,0x53,0x0B,0x1F,0xB0,0x47,0xC4,0x7F,0x95,0x5D,0xB0,0xD5,
53
  0xF3,0xD3,0xAB,0x5F,0x28,0x2B,0xEC,0x2C,0x15,0x0B,0x1B,0x0C,
54
  0xD4,0xBE,0x24,0x2F,0xC5,0x07,0x3C,0xE4,0xC5,0xE6,0x16,0x42,
55
  0x4C,0x31,0x04,0xBB,0x80,0x96,0xFF,0x64,0x50,0xA4,0xA5,0xB5,
56
  0xF5,0x3A,0xBA,0x57,0xE4,0xE6,0xC2,0x23,0x0A,0xB6,0x27,0xC4,
57
  0x06,0x01,0x1E,0x98,0x20,0x09,0xC8,0xB7,0x90,0x09,0x86,0x06,
58
  0xAA,0x85,0xE7,0x02,0xC8,0xC6,0xD9,0x1D,0xAB,0x17,0xEE,0x78,
59
  0x73,0x78,0x88,0x7F,0xA7,0xF2,0x34,0xA7,0xDD,0x02,0x16,0x36,
60
  0x0D,0x77,0x16,0x3E,0x95,0xAE,0x02,0xEE,0x36,0x37,0xD5,0x61,
61
  0x5D,0xFE,0xC6,0x0B,0xDF,0xCE,0xB9,0x26,0x31,0x6F,0x34,0x92,
62
  0xBB,0xBB,0x91,0x29,0x77,0x62,0x1D,0x75,0xA0,0x51,0x8D,0x31,
63
  0x4C,0x64,0x4E,0xBF,0xDC,0xE8,0x67,0x17,0x90,0x6A,0x80,0xE9,
64
  0xD7,0xD8,0x56,0x4E,0x85,0x21,0x9C,0xFB,0xE6,0x1B,0xD8,0x05,
65
  0xFD,0x13,0x77,0x00,0x96,0x2D,0x0C,0x2A,0x95,0x1A,0x08,0x82,
66
  0x2E,0xB3,0xE2,0xFC,0xE8,0xA6,0xF1,0x16,0x37,0x57,0x82,0xD6,
67
  0xF5,0xAB,0xA9,0x43,0x8F,0x33,0xB0,0x57,0x38,0x6E,0x61,0xD4,
68
  0xDD,0xE0,0x1C,0xCB,
69
};
70
 
71
static ssl_option_t ssl_options[] = {
72
  /* OpenSSL 0.9.7 and 0.9.8 */
73
  {"all",                              SSL_OP_ALL},
74
  {"cipher_server_preference",         SSL_OP_CIPHER_SERVER_PREFERENCE},
75
  {"dont_insert_empty_fragments",      SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS},
76
  {"ephemeral_rsa",                    SSL_OP_EPHEMERAL_RSA},
77
  {"netscape_ca_dn_bug",               SSL_OP_NETSCAPE_CA_DN_BUG},
78
  {"netscape_challenge_bug",           SSL_OP_NETSCAPE_CHALLENGE_BUG},
79
  {"microsoft_big_sslv3_buffer",       SSL_OP_MICROSOFT_BIG_SSLV3_BUFFER},
80
  {"microsoft_sess_id_bug",            SSL_OP_MICROSOFT_SESS_ID_BUG},
81
  {"msie_sslv2_rsa_padding",           SSL_OP_MSIE_SSLV2_RSA_PADDING},
82
  {"netscape_demo_cipher_change_bug",  SSL_OP_NETSCAPE_DEMO_CIPHER_CHANGE_BUG},
83
  {"netscape_reuse_cipher_change_bug", SSL_OP_NETSCAPE_REUSE_CIPHER_CHANGE_BUG},
84
  {"no_session_resumption_on_renegotiation", 
85
      SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION},
86
  {"no_sslv2",                         SSL_OP_NO_SSLv2},
87
  {"no_sslv3",                         SSL_OP_NO_SSLv3},
88
  {"no_tlsv1",                         SSL_OP_NO_TLSv1},
89
  {"pkcs1_check_1",                    SSL_OP_PKCS1_CHECK_1},
90
  {"pkcs1_check_2",                    SSL_OP_PKCS1_CHECK_2},
91
  {"single_dh_use",                    SSL_OP_SINGLE_DH_USE},
92
  {"ssleay_080_client_dh_bug",         SSL_OP_SSLEAY_080_CLIENT_DH_BUG},
93
  {"sslref2_reuse_cert_type_bug",      SSL_OP_SSLREF2_REUSE_CERT_TYPE_BUG},
94
  {"tls_block_padding_bug",            SSL_OP_TLS_BLOCK_PADDING_BUG},
95
  {"tls_d5_bug",                       SSL_OP_TLS_D5_BUG},
96
  {"tls_rollback_bug",                 SSL_OP_TLS_ROLLBACK_BUG},
97
  /* OpenSSL 0.9.8 only */
98
#if OPENSSL_VERSION_NUMBER > 0x00908000L
99
  {"cookie_exchange",                  SSL_OP_COOKIE_EXCHANGE},
100
  {"no_query_mtu",                     SSL_OP_NO_QUERY_MTU},
101
  {"single_ecdh_use",                  SSL_OP_SINGLE_ECDH_USE},
102
#endif
103
  /* OpenSSL 0.9.8f and above */
104
#if defined(SSL_OP_NO_TICKET)
105
  {"no_ticket",                        SSL_OP_NO_TICKET},
106
#endif
107
#if defined(SSL_OP_NO_COMPRESSION)
108
  {"no_compression",                          SSL_OP_NO_COMPRESSION},
109
#endif
110
  {NULL, 0L}
111
};
112
 
113
/*--------------------------- Auxiliary Functions ----------------------------*/
114
 
115
/**
116
 * Return the context.
117
 */
118
p_context checkctx(lua_State *L, int idx)
119
{
120
  return (p_context)luaL_checkudata(L, idx, "SSL:Context");
121
}
122
 
123
/**
124
 * Prepare the SSL options flag.
125
 */
126
static int set_option_flag(const char *opt, unsigned long *flag)
127
{
128
  ssl_option_t *p;
129
  for (p = ssl_options; p->name; p++) {
130
    if (!strcmp(opt, p->name)) {
131
      *flag |= p->code;
132
      return 1;
133
    }
134
  }
135
  return 0;
136
}
137
 
138
/**
139
 * Find the protocol.
140
 */
141
static const SSL_METHOD* str2method(const char *method)
142
{
143
  if (!strcmp(method, "sslv3"))  return SSLv3_method();
144
  if (!strcmp(method, "tlsv1"))  return TLSv1_method();
145
  if (!strcmp(method, "sslv23")) return SSLv23_method();
146
  return NULL;
147
}
148
 
149
/**
150
 * Prepare the SSL handshake verify flag.
151
 */
152
static int set_verify_flag(const char *str, int *flag)
153
{
154
  if (!strcmp(str, "none")) { 
155
    *flag |= SSL_VERIFY_NONE;
156
    return 1;
157
  }
158
  if (!strcmp(str, "peer")) {
159
    *flag |= SSL_VERIFY_PEER;
160
    return 1;
161
  }
162
  if (!strcmp(str, "client_once")) {
163
    *flag |= SSL_VERIFY_CLIENT_ONCE;
164
    return 1;
165
  }
166
  if (!strcmp(str, "fail_if_no_peer_cert")) { 
167
    *flag |= SSL_VERIFY_FAIL_IF_NO_PEER_CERT;
168
    return 1;
169
  }
170
  return 0;
171
}
172
 
173
/**
174
 * Password callback for reading the private key.
175
 */
176
static int passwd_cb(char *buf, int size, int flag, void *udata)
177
{
178
  lua_State *L = (lua_State*)udata;
179
  switch (lua_type(L, 3)) {
180
  case LUA_TFUNCTION:
181
    lua_pushvalue(L, 3);
182
    lua_call(L, 0, 1);
183
    if (lua_type(L, -1) != LUA_TSTRING)
184
       return 0;
185
    /* fallback */
186
  case LUA_TSTRING:
187
    strncpy(buf, lua_tostring(L, -1), size);
188
    buf[size-1] = '\0';
189
    return (int)strlen(buf);
190
  }
191
  return 0;
192
}
193
 
194
static DH *get_dh(const unsigned char *p, int len)
195
{
196
  DH *dh = NULL;
197
  static unsigned char g[] = { 0x02 };
198
 
199
  if ((dh = DH_new()) == NULL) return NULL;
200
  dh->p = BN_bin2bn(p, len, NULL);
201
  dh->g = BN_bin2bn(g, sizeof(g), NULL);
202
  if (dh->p == NULL || dh->g == NULL) {
203
    DH_free(dh);
204
    return NULL;
205
  }
206
 
207
  return dh;
208
}
209
 
210
/**
211
 * DH parameter callback
212
 */
213
static DH *dh_param_cb(SSL *ssl, int is_export, int keylength)
214
{
215
  /* Logic in postfix and dovecot, but we're using a 2048-bit group... */
216
  if (is_export && keylength == 512) {
217
    if (dh_512 == NULL) { dh_512 = get_dh(dh512_p, sizeof(dh512_p)); }
218
    return dh_512;
219
  } else {
220
    if (dh_larger == NULL) { dh_larger = get_dh(dh2048_p, sizeof(dh2048_p)); }
221
    return dh_larger;
222
  }
223
}
224
 
225
 
226
/*------------------------------ Lua Functions -------------------------------*/
227
 
228
/**
229
 * Create a SSL context.
230
 */
231
static int create(lua_State *L)
232
{
233
  p_context ctx;
234
  const SSL_METHOD *method;
235
 
236
  if (luasec_sslctx_idx == -1) {
237
    luasec_sslctx_idx = SSL_CTX_get_ex_new_index(0, "luasec sslctx context", NULL, NULL, NULL);
238
    if (luasec_sslctx_idx == -1) {
239
      lua_pushnil(L);
240
      lua_pushstring(L, "error creating luasec SSL index");
241
      return 2;
242
    }
243
  }
244
  method = str2method(luaL_checkstring(L, 1));
245
  if (!method) {
246
    lua_pushnil(L);
247
    lua_pushstring(L, "invalid protocol");
248
    return 2;
249
  }
250
  ctx = (p_context) lua_newuserdata(L, sizeof(t_context));
251
  if (!ctx) {
252
    lua_pushnil(L);
253
    lua_pushstring(L, "error creating context");
254
    return 2;
255
  }
256
  ctx->L = L;
257
  ctx->context = SSL_CTX_new(method);
258
  if (!ctx->context) {
259
    lua_pushnil(L);
260
    lua_pushstring(L, "error creating context");
261
    return 2;
262
  }
263
  ctx->verify_flags = LUASEC_VERIFY_FLAGS_NONE;
264
  ctx->mode = MD_CTX_INVALID;
265
  /* No session support */
266
  SSL_CTX_set_session_cache_mode(ctx->context, SSL_SESS_CACHE_OFF);
267
  /*
268
   * Support ephemeral diffie-hellman key exchange.  This is only needed
269
   * for server mode, but clearer to put it here rather than set_mode.
270
   */
271
  SSL_CTX_set_tmp_dh_callback(ctx->context, dh_param_cb);
272
#if defined(SSL_CTX_set_tmp_ecdh)
273
  /*
274
   * Support ECDH parameters.  This uses the 384 bit prime field from
275
   * NIST.
276
   */
277
  SSL_CTX_set_tmp_ecdh(ctx->context, EC_KEY_new_by_curve_name(NID_secp384r1));
278
#endif
279
 
280
  SSL_CTX_set_ex_data(ctx->context, luasec_sslctx_idx, ctx);
281
 
282
  luaL_getmetatable(L, "SSL:Context");
283
  lua_setmetatable(L, -2);
284
  return 1;
285
}
286
 
287
/**
288
 * Load the trusting certificates.
289
 */
290
static int load_locations(lua_State *L)
291
{
292
  SSL_CTX *ctx = ctx_getcontext(L, 1);
293
  const char *cafile = luaL_optstring(L, 2, NULL);
294
  const char *capath = luaL_optstring(L, 3, NULL);
295
  if (SSL_CTX_load_verify_locations(ctx, cafile, capath) != 1) {
296
    lua_pushboolean(L, 0);
297
    lua_pushfstring(L, "error loading CA locations (%s)",
298
      ERR_reason_error_string(ERR_get_error()));
299
    return 2;
300
  }
301
  lua_pushboolean(L, 1);
302
  return 1;
303
}
304
 
305
/**
306
 * Load the certificate file.
307
 */
308
static int load_cert(lua_State *L)
309
{
310
  SSL_CTX *ctx = ctx_getcontext(L, 1);
311
  const char *filename = luaL_checkstring(L, 2);
312
  if (SSL_CTX_use_certificate_chain_file(ctx, filename) != 1) {
313
    lua_pushboolean(L, 0);
314
    lua_pushfstring(L, "error loading certificate (%s)",
315
      ERR_reason_error_string(ERR_get_error()));
316
    return 2;
317
  }
318
  lua_pushboolean(L, 1);
319
  return 1;
320
}
321
 
322
/**
323
 * Load the key file -- only in PEM format.
324
 */
325
static int load_key(lua_State *L)
326
{
327
  int ret = 1;
328
  SSL_CTX *ctx = ctx_getcontext(L, 1);
329
  const char *filename = luaL_checkstring(L, 2);
330
  switch (lua_type(L, 3)) {
331
  case LUA_TSTRING:
332
  case LUA_TFUNCTION:
333
    SSL_CTX_set_default_passwd_cb(ctx, passwd_cb);
334
    SSL_CTX_set_default_passwd_cb_userdata(ctx, L);
335
    /* fallback */
336
  case LUA_TNIL: 
337
    if (SSL_CTX_use_PrivateKey_file(ctx, filename, SSL_FILETYPE_PEM) == 1)
338
      lua_pushboolean(L, 1);
339
    else {
340
      ret = 2;
341
      lua_pushboolean(L, 0);
342
      lua_pushfstring(L, "error loading private key (%s)",
343
        ERR_reason_error_string(ERR_get_error()));
344
    }
345
    SSL_CTX_set_default_passwd_cb(ctx, NULL);
346
    SSL_CTX_set_default_passwd_cb_userdata(ctx, NULL);
347
    break;
348
  default:
349
    lua_pushstring(L, "invalid callback value");
350
    lua_error(L);
351
  }
352
  return ret;
353
}
354
 
355
/**
356
 * Load a DH params files.  This is a global LuaSec thing.
357
 */
358
static int load_dhparams(lua_State *L)
359
{
360
  const char *filename = luaL_checkstring(L, 1);
361
  FILE *paramfile;
362
  DH *dh;
363
 
364
  paramfile = fopen(filename, "r");
365
  if (!paramfile) {
366
    lua_pushboolean(L, 0);
367
    lua_pushfstring(L, "error reading dh param file %s: %s", filename,
368
      strerror(errno));
369
    return 2;
370
  }
371
 
372
  dh = PEM_read_DHparams(paramfile, NULL, NULL, NULL);
373
  fclose(paramfile);
374
  if (!dh) {
375
    lua_pushboolean(L, 0);
376
    lua_pushfstring(L, "error loading dh param file %s: %s", filename,
377
      ERR_reason_error_string(ERR_get_error()));
378
    return 2;
379
  }
380
 
381
  if (dh_larger)
382
    DH_free(dh_larger);
383
 
384
  dh_larger = dh;
385
 
386
  lua_pushboolean(L, 1);
387
  return 1;
388
}
389
 
390
/**
391
 * Set the cipher list.
392
 */
393
static int set_cipher(lua_State *L)
394
{
395
  SSL_CTX *ctx = ctx_getcontext(L, 1);
396
  const char *list = luaL_checkstring(L, 2);
397
  if (SSL_CTX_set_cipher_list(ctx, list) != 1) {
398
    lua_pushboolean(L, 0);
399
    lua_pushfstring(L, "error setting cipher list (%s)",
400
      ERR_reason_error_string(ERR_get_error()));
401
    return 2;
402
  }
403
  lua_pushboolean(L, 1);
404
  return 1;
405
}
406
 
407
/**
408
 * Set the depth for certificate checking.
409
 */
410
static int set_depth(lua_State *L)
411
{
412
  SSL_CTX *ctx = ctx_getcontext(L, 1);
413
  SSL_CTX_set_verify_depth(ctx, luaL_checkint(L, 2));
414
  lua_pushboolean(L, 1);
415
  return 1;
416
}
417
 
418
static void
419
luasec_push_cert_error(lua_State *L, int ref, int depth, int err)
420
{
421
  int created = 0;
422
 
423
  lua_rawgeti(L, LUA_REGISTRYINDEX, ref);
424
  lua_rawgeti(L, -1, depth + 1);
425
  if (!lua_istable(L, -1)) {
426
    /* If the table doesn't exist, create it */
427
    created = 1;
428
    lua_pop(L, 1);
429
    lua_newtable(L);
430
  }
431
 
432
  lua_pushstring(L, X509_verify_cert_error_string(err));
433
  lua_rawseti(L, -2, lua_objlen(L, -2)+1);
434
 
435
  if (created) {
436
    lua_rawseti(L, -2, depth + 1);
437
    lua_pop(L, 1);
438
  } else
439
    lua_pop(L, 2);
440
}
441
 
442
int verify_cb(int preverify_ok, X509_STORE_CTX *x509_ctx)
443
{
444
  SSL_CTX *context;
445
  SSL *ssl;
446
  p_context l_ctx;
447
  p_ssl l_ssl;
448
  int err, depth;
449
 
450
  /* Short-circuit optimization */
451
  if (preverify_ok)
452
    return 1;
453
 
454
  ssl = X509_STORE_CTX_get_ex_data(x509_ctx, SSL_get_ex_data_X509_STORE_CTX_idx());
455
  context = ssl->ctx;
456
  l_ssl = SSL_get_ex_data(ssl, luasec_ssl_idx);
457
  l_ctx = SSL_CTX_get_ex_data(context, luasec_sslctx_idx);
458
 
459
  err = X509_STORE_CTX_get_error(x509_ctx);
460
  depth = X509_STORE_CTX_get_error_depth(x509_ctx);
461
 
462
  if (err != X509_V_OK) {
463
    if (l_ssl->t_cert_errors == LUA_NOREF) {
464
      lua_newtable(l_ctx->L);
465
      l_ssl->t_cert_errors = luaL_ref(l_ctx->L, LUA_REGISTRYINDEX);
466
    }
467
 
468
    luasec_push_cert_error(l_ctx->L, l_ssl->t_cert_errors, depth, err);
469
  }
470
 
471
  return (l_ctx->verify_flags & LUASEC_VERIFY_FLAGS_ALWAYS_CONTINUE ? 1 : preverify_ok);
472
}
473
 
474
static int luasec_verify(X509_STORE_CTX *x509_ctx, void *ptr)
475
{
476
  p_context ctx = ptr;
477
 
478
  if (ctx->verify_flags & LUASEC_VERIFY_FLAGS_IGNORE_PURPOSE) {
479
    X509_VERIFY_PARAM *param = X509_STORE_CTX_get0_param(x509_ctx);
480
    if (param) {
481
      X509_VERIFY_PARAM_set_purpose(param, X509_PURPOSE_SSL_SERVER);
482
      X509_VERIFY_PARAM_set_trust(param, X509_TRUST_SSL_SERVER);
483
    }
484
  }
485
 
486
  return X509_verify_cert(x509_ctx);
487
}
488
 
489
/**
490
 * Set the handshake verify options.
491
 */
492
static int set_verify(lua_State *L)
493
{
494
  int i;
495
  int flag = 0, vflag = 0;
496
  p_context ctx = checkctx(L, 1);
497
  int max = lua_gettop(L);
498
  /* any flag? */
499
  if (max > 1) {
500
    ctx->verify_flags = LUASEC_VERIFY_FLAGS_NONE;
501
    for (i = 2; i <= max; i++) {
502
      const char *s = luaL_checkstring(L, i);
503
      if (!strcmp(s, "continue")) {
504
        ctx->verify_flags |= LUASEC_VERIFY_FLAGS_ALWAYS_CONTINUE;
505
      } else if (!strcmp(s, "ignore_purpose")) {
506
        ctx->verify_flags |= LUASEC_VERIFY_FLAGS_IGNORE_PURPOSE;
507
      } else if (!strcmp(s, "crl_check")) {
508
        vflag |= X509_V_FLAG_CRL_CHECK;
509
      } else if (!strcmp(s, "crl_check_chain")) {
510
        vflag |= X509_V_FLAG_CRL_CHECK_ALL;
511
      } else if (!set_verify_flag(s, &flag)) {
512
        lua_pushboolean(L, 0);
513
        lua_pushstring(L, "invalid verify option");
514
        return 2;
515
      }
516
    }
517
    SSL_CTX_set_verify(ctx->context, flag, ctx->verify_flags ? verify_cb : NULL);
518
    SSL_CTX_set_cert_verify_callback(ctx->context, luasec_verify, ctx);
519
    if(vflag)
520
    {
521
      X509_STORE *store = SSL_CTX_get_cert_store(ctx->context);
522
      X509_STORE_set_flags(store, vflag);
523
    }
524
  }
525
  lua_pushboolean(L, 1);
526
  return 1;
527
}
528
 
529
/**
530
 * Set the protocol options.
531
 */
532
static int set_options(lua_State *L)
533
{
534
  int i;
535
  unsigned long flag = 0L;
536
  SSL_CTX *ctx = ctx_getcontext(L, 1);
537
  int max = lua_gettop(L);
538
  /* any option? */
539
  if (max > 1) {
540
    for (i = 2; i <= max; i++) {
541
#if !defined(SSL_OP_NO_COMPRESSION)
542
      /* Manually disable compression if built against an older
543
       * OpenSSL which doesn't have SSL_OP_NO_COMPRESSION
544
       */
545
      if (!strcmp(luaL_checkstring(L, i), "no_compression")) {
546
        ctx->comp_methods = NULL;
547
      } else
548
#endif
549
      if (!set_option_flag(luaL_checkstring(L, i), &flag)) {
550
        lua_pushboolean(L, 0);
551
        lua_pushstring(L, "invalid option");
552
        return 2;
553
      }
554
    }
555
    SSL_CTX_set_options(ctx, flag);
556
  }
557
  lua_pushboolean(L, 1);
558
  return 1;
559
}
560
 
561
/**
562
 * Set the context mode.
563
 */
564
static int set_mode(lua_State *L)
565
{
566
  p_context ctx = checkctx(L, 1);
567
  const char *str = luaL_checkstring(L, 2);
568
  if (!strcmp("server", str)) {
569
    ctx->mode = MD_CTX_SERVER;
570
    lua_pushboolean(L, 1);
571
    return 1;
572
  }
573
  if(!strcmp("client", str)) {
574
    ctx->mode = MD_CTX_CLIENT;
575
    lua_pushboolean(L, 1);
576
    return 1;
577
  }
578
  lua_pushboolean(L, 0);
579
  lua_pushstring(L, "invalid mode");
580
  return 1;
581
}   
582
 
583
/**
584
 * Return a pointer to SSL_CTX structure.
585
 */
586
static int raw_ctx(lua_State *L)
587
{
588
  p_context ctx = checkctx(L, 1);
589
  lua_pushlightuserdata(L, (void*)ctx->context);
590
  return 1;
591
}
592
 
593
/**
594
 * Package functions
595
 */
596
static luaL_Reg funcs[] = {
597
  {"create",     create},
598
  {"locations",  load_locations},
599
  {"loadcert",   load_cert},
600
  {"loadkey",    load_key},
601
  {"setcipher",  set_cipher},
602
  {"setdepth",   set_depth},
603
  {"setverify",  set_verify},
604
  {"setoptions", set_options},
605
  {"setmode",    set_mode},
606
  {"rawcontext", raw_ctx},
607
  {"loaddhparams", load_dhparams},
608
  {NULL, NULL}
609
};
610
 
611
/*-------------------------------- Metamethods -------------------------------*/
612
 
613
/**
614
 * Collect SSL context -- GC metamethod.
615
 */
616
static int meth_destroy(lua_State *L)
617
{
618
  p_context ctx = checkctx(L, 1);
619
  if (ctx->context) {
620
    SSL_CTX_free(ctx->context);
621
    ctx->context = NULL;
622
  }
623
  return 0;
624
}
625
 
626
/**
627
 * Object information -- tostring metamethod.
628
 */
629
static int meth_tostring(lua_State *L)
630
{
631
  p_context ctx = checkctx(L, 1);
632
  lua_pushfstring(L, "SSL context: %p", ctx);
633
  return 1;
634
}
635
 
636
/**
637
 * Context metamethods.
638
 */
639
static luaL_Reg meta[] = {
640
  {"__gc",       meth_destroy},
641
  {"__tostring", meth_tostring},
642
  {NULL, NULL}
643
};
644
 
645
 
646
/*----------------------------- Public Functions  ---------------------------*/
647
 
648
/**
649
 * Retrieve the SSL context from the Lua stack.
650
 */
651
SSL_CTX* ctx_getcontext(lua_State *L, int idx)
652
{
653
  p_context ctx = checkctx(L, idx);
654
  return ctx->context;
655
}
656
 
657
/**
658
 * Retrieve the mode from the context in the Lua stack.
659
 */
660
char ctx_getmode(lua_State *L, int idx)
661
{
662
  p_context ctx = checkctx(L, idx);
663
  return ctx->mode;
664
}
665
 
666
/*------------------------------ Initialization ------------------------------*/
667
 
668
/**
669
 * Registre the module.
670
 */
671
int luaopen_ssl_context(lua_State *L)
672
{
673
  luaL_newmetatable(L, "SSL:Context");
674
  luaL_register(L, NULL, meta);
675
  luaL_register(L, "ssl.context", funcs);
676
  return 1;
677
}