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 { |