src/ssl.c

changeset 11
8d7698d3fd26
parent 10
a4a1fd8c1b43
child 12
ac943b31f40c
equal deleted inserted replaced
10:a4a1fd8c1b43 11:8d7698d3fd26
5 *--------------------------------------------------------------------------*/ 5 *--------------------------------------------------------------------------*/
6 6
7 #include <string.h> 7 #include <string.h>
8 8
9 #include <openssl/ssl.h> 9 #include <openssl/ssl.h>
10 #include <openssl/x509v3.h>
10 #include <openssl/err.h> 11 #include <openssl/err.h>
11 12
12 #include <lua.h> 13 #include <lua.h>
13 #include <lauxlib.h> 14 #include <lauxlib.h>
14 15
15 #include "io.h" 16 #include "io.h"
16 #include "buffer.h" 17 #include "buffer.h"
17 #include "timeout.h" 18 #include "timeout.h"
18 #include "socket.h" 19 #include "socket.h"
19 #include "ssl.h" 20 #include "ssl.h"
21
22 #define min(a, b) (a<b)?a:b
20 23
21 /** 24 /**
22 * Map error code into string. 25 * Map error code into string.
23 */ 26 */
24 static const char *ssl_ioerror(void *ctx, int err) 27 static const char *ssl_ioerror(void *ctx, int err)
371 lua_pushboolean(L, 0); 374 lua_pushboolean(L, 0);
372 return 1; 375 return 1;
373 } 376 }
374 } 377 }
375 378
379 void luasec_push_asn1_objname(lua_State* L, ASN1_OBJECT *object, int no_name)
380 {
381 char buffer[256];
382 int len = OBJ_obj2txt(buffer, sizeof(buffer), object, no_name);
383 lua_pushlstring(L, buffer, min(sizeof(buffer),len));
384 }
385
386 void luasec_push_asn1_string(lua_State* L, ASN1_STRING *string)
387 {
388 if(string)
389 lua_pushlstring(L, (char*)ASN1_STRING_data(string), ASN1_STRING_length(string));
390 else
391 lua_pushnil(L);
392 }
393
394 int luasec_push_subtable(lua_State* L, int idx)
395 {
396
397 lua_pushvalue(L, -1);
398 lua_gettable(L, idx-1);
399
400 if(lua_isnil(L, -1))
401 {
402 lua_pop(L, 1);
403 lua_newtable(L);
404 lua_pushvalue(L, -2);
405 lua_pushvalue(L, -2);
406 lua_settable(L, idx-3);
407
408 lua_replace(L, -2); /* Replace key with table */
409 return 1;
410 }
411 lua_replace(L, -2); /* Replace key with table */
412 return 0;
413 }
414
376 /** 415 /**
377 * Return the peer certificate. 416 * Return the peer certificate.
378 */ 417 */
379 static int meth_getpeercertificate(lua_State *L) 418 static int meth_getpeercertificate(lua_State *L)
380 { 419 {
381 X509 *peer; 420 X509 *peer;
421 int i, j;
382 p_ssl ssl = (p_ssl)luaL_checkudata(L, 1, "SSL:Connection"); 422 p_ssl ssl = (p_ssl)luaL_checkudata(L, 1, "SSL:Connection");
383 peer = SSL_get_peer_certificate(ssl->ssl); 423 peer = SSL_get_peer_certificate(ssl->ssl);
384 if (peer == NULL) { 424 if (peer == NULL) {
385 /* No client certificate available */ 425 /* No client certificate available */
386 lua_pushboolean(L, 0); 426 lua_pushboolean(L, 0);
387 return 1; 427 return 1;
388 } 428 }
389 else 429 else
390 { 430 {
391 X509_NAME *subject; 431 X509_NAME *subject;
392 int i, n_entries, len; 432 int n_entries;
393 char buffer[4096];
394 433
395 lua_newtable(L); /* ret */ 434 lua_newtable(L); /* ret */
396 435
397 lua_pushboolean(L, (SSL_get_verify_result(ssl->ssl) == X509_V_OK)); 436 lua_pushboolean(L, (SSL_get_verify_result(ssl->ssl) == X509_V_OK));
398 lua_setfield(L, -2, "trusted"); 437 lua_setfield(L, -2, "trusted");
406 lua_setfield(L, -3, "subject"); /* ret.subject = {} */ 445 lua_setfield(L, -3, "subject"); /* ret.subject = {} */
407 for(i = 0; i <= n_entries; i++) 446 for(i = 0; i <= n_entries; i++)
408 { 447 {
409 X509_NAME_ENTRY *entry; 448 X509_NAME_ENTRY *entry;
410 ASN1_OBJECT *object; 449 ASN1_OBJECT *object;
411 ASN1_STRING *value;
412 int len;
413 450
414 entry = X509_NAME_get_entry(subject, i); 451 entry = X509_NAME_get_entry(subject, i);
415 object = X509_NAME_ENTRY_get_object(entry); 452 object = X509_NAME_ENTRY_get_object(entry);
416 453
417 /* Get numeric ID as string into buffer */ 454 luasec_push_asn1_objname(L, object, 1);
418 len = OBJ_obj2txt(buffer, sizeof(buffer), object, 1); 455
419 456 if(luasec_push_subtable(L, -2))
420 if(len == 0)
421 continue;
422
423 /* Push numeric ID to Lua (e.g. 1.22.3...) */
424 lua_pushlstring(L, buffer, (len>sizeof(buffer))?sizeof(buffer):(len));
425
426 lua_pushvalue(L, -1); /* k */
427 lua_gettable(L, -4); /* ret.subject[k] */
428
429 if(lua_isnil(L, -1))
430 { 457 {
431 lua_pop(L, 1);
432 lua_newtable(L);
433 lua_pushvalue(L, -2); /* k */
434 lua_pushvalue(L, -2); /* v */
435 lua_settable(L, -5); /* ret.subject[k] = v */
436 /* Get short/long name of the entry */ 458 /* Get short/long name of the entry */
437 len = OBJ_obj2txt(buffer, sizeof(buffer), object, 0); 459 luasec_push_asn1_objname(L, object, 0);
438 lua_pushlstring(L, buffer, (len>sizeof(buffer))?sizeof(buffer):(len));
439 lua_setfield(L, -2, "name"); 460 lua_setfield(L, -2, "name");
440 } 461 }
441 462
442 value = X509_NAME_ENTRY_get_data(entry); 463 luasec_push_asn1_string(L, X509_NAME_ENTRY_get_data(entry));
443 if(value) 464 lua_rawseti(L, -2, lua_objlen(L, -2)+1);
465
466 lua_pop(L, 1);
467 }
468 }
469 lua_pop(L, 1); /* ret.subject */
470
471 lua_newtable(L); /* {} */
472 lua_pushvalue(L, -1);
473 lua_setfield(L, -3, "extensions"); /* ret.extensions = {} */
474
475 i = -1;
476 while((i = X509_get_ext_by_NID(peer, NID_subject_alt_name, i)) != -1)
477 {
478 X509_EXTENSION *extension;
479 STACK_OF(GENERAL_NAME) *values;
480 int n_general_names;
481
482 extension = X509_get_ext(peer, i);
483 if(extension == NULL)
484 break;
485
486 values = X509V3_EXT_d2i(extension);
487 if(values == NULL)
488 break;
489
490 /* Push ret.extensions[oid] */
491 luasec_push_asn1_objname(L, extension->object, 1);
492 luasec_push_subtable(L, -2);
493 /* Set ret.extensions[oid].name = name */
494 luasec_push_asn1_objname(L, extension->object, 0);
495 lua_setfield(L, -2, "name");
496
497 n_general_names = sk_GENERAL_NAME_num(values);
498 for(j = 0; j < n_general_names; j++)
499 {
500 GENERAL_NAME *general_name;
501
502 general_name = sk_GENERAL_NAME_value(values, j);
503
504 switch(general_name->type)
444 { 505 {
445 lua_pushlstring(L, (char*)ASN1_STRING_data(value), ASN1_STRING_length(value)); 506 case GEN_OTHERNAME:
507 {
508 OTHERNAME *otherName = general_name->d.otherName;
509
510 luasec_push_asn1_objname(L, otherName->type_id, 1);
511
512 if(luasec_push_subtable(L, -2))
513 {
514 luasec_push_asn1_objname(L, otherName->type_id, 0);
515 lua_setfield(L, -2, "name");
516 }
517
518 luasec_push_asn1_string(L, otherName->value->value.asn1_string);
446 lua_rawseti(L, -2, lua_objlen(L, -2)+1); 519 lua_rawseti(L, -2, lua_objlen(L, -2)+1);
520
521 lua_pop(L, 1);
522 break;
447 } 523 }
448 524 case GEN_DNS:
449 lua_pop(L, 2); /* k, v */ 525 {
526 lua_pushstring(L, "dNSName");
527 luasec_push_subtable(L, -2);
528 luasec_push_asn1_string(L, general_name->d.dNSName);
529 lua_rawseti(L, -2, lua_objlen(L, -2)+1);
530 lua_pop(L, 1);
531 break;
532 }
533 default:
534 break;
535 }
450 } 536 }
451 } 537
452 lua_pop(L, 1); /* ret.subject */ 538 lua_pop(L, 1); /* array */
539 i++; /* Next extension */
540 }
541 lua_pop(L, 1); /* ret.extensions */
542
453 return 1; 543 return 1;
454 } 544 }
455 545
456 static int meth_getfinished(lua_State *L) 546 static int meth_getfinished(lua_State *L)
457 { 547 {

mercurial