416 * Return the peer certificate. |
416 * Return the peer certificate. |
417 */ |
417 */ |
418 static int meth_getpeercertificate(lua_State *L) |
418 static int meth_getpeercertificate(lua_State *L) |
419 { |
419 { |
420 X509 *peer; |
420 X509 *peer; |
421 int i, j; |
|
422 p_ssl ssl = (p_ssl)luaL_checkudata(L, 1, "SSL:Connection"); |
421 p_ssl ssl = (p_ssl)luaL_checkudata(L, 1, "SSL:Connection"); |
423 peer = SSL_get_peer_certificate(ssl->ssl); |
422 peer = SSL_get_peer_certificate(ssl->ssl); |
424 if (peer == NULL) { |
423 if (peer == NULL) { |
425 /* No client certificate available */ |
424 /* No client certificate available */ |
426 lua_pushboolean(L, 0); |
425 lua_pushnil(L); |
427 return 1; |
|
428 } |
426 } |
429 else |
427 else |
430 { |
428 { |
431 X509_NAME *subject; |
429 /* Push metatabled peer */ |
432 int n_entries; |
430 luasec_push_x509(L, peer); |
433 |
431 } |
434 lua_newtable(L); /* ret */ |
|
435 |
|
436 lua_pushboolean(L, (SSL_get_verify_result(ssl->ssl) == X509_V_OK)); |
|
437 lua_setfield(L, -2, "trusted"); |
|
438 |
|
439 subject = X509_get_subject_name(peer); |
|
440 |
|
441 n_entries = X509_NAME_entry_count(subject); |
|
442 |
|
443 lua_newtable(L); /* {} */ |
|
444 lua_pushvalue(L, -1); |
|
445 lua_setfield(L, -3, "subject"); /* ret.subject = {} */ |
|
446 for(i = 0; i <= n_entries; i++) |
|
447 { |
|
448 X509_NAME_ENTRY *entry; |
|
449 ASN1_OBJECT *object; |
|
450 |
|
451 entry = X509_NAME_get_entry(subject, i); |
|
452 object = X509_NAME_ENTRY_get_object(entry); |
|
453 |
|
454 luasec_push_asn1_objname(L, object, 1); |
|
455 |
|
456 if(luasec_push_subtable(L, -2)) |
|
457 { |
|
458 /* Get short/long name of the entry */ |
|
459 luasec_push_asn1_objname(L, object, 0); |
|
460 lua_setfield(L, -2, "name"); |
|
461 } |
|
462 |
|
463 luasec_push_asn1_string(L, X509_NAME_ENTRY_get_data(entry)); |
|
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) |
|
505 { |
|
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); |
|
519 lua_rawseti(L, -2, lua_objlen(L, -2)+1); |
|
520 |
|
521 lua_pop(L, 1); |
|
522 break; |
|
523 } |
|
524 case GEN_DNS: |
|
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 } |
|
536 } |
|
537 |
|
538 lua_pop(L, 1); /* array */ |
|
539 i++; /* Next extension */ |
|
540 } |
|
541 lua_pop(L, 1); /* ret.extensions */ |
|
542 |
|
543 return 1; |
432 return 1; |
544 } |
433 } |
545 |
434 |
546 static int meth_getfinished(lua_State *L) |
435 static int meth_getfinished(lua_State *L) |
547 { |
436 { |