383 peer = SSL_get_peer_certificate(ssl->ssl); |
383 peer = SSL_get_peer_certificate(ssl->ssl); |
384 if (peer == NULL) { |
384 if (peer == NULL) { |
385 /* No client certificate available */ |
385 /* No client certificate available */ |
386 lua_pushboolean(L, 0); |
386 lua_pushboolean(L, 0); |
387 return 1; |
387 return 1; |
388 } else { |
388 } |
389 char *buffer = NULL; |
389 else |
390 char length = 0; |
390 { |
391 BIO *bp = BIO_new(BIO_s_mem()); /* To memory */ |
391 X509_NAME *subject; |
392 i2d_X509_bio(bp, peer); /* as der */ |
392 int i, n_entries, len; |
393 if ((length = BIO_read(bp, 0, 0)) == 0) { |
393 char buffer[4096]; |
394 BIO_free(bp); |
394 |
395 return 0; |
395 lua_newtable(L); |
|
396 |
|
397 lua_pushboolean(L, (SSL_get_verify_result(ssl->ssl) == X509_V_OK)); |
|
398 lua_setfield(L, -2, "trusted"); |
|
399 |
|
400 subject = X509_get_subject_name(peer); |
|
401 |
|
402 n_entries = X509_NAME_entry_count(subject); |
|
403 |
|
404 lua_newtable(L); /* ret */ |
|
405 lua_newtable(L); /* {} */ |
|
406 lua_pushvalue(L, -1); |
|
407 lua_setfield(L, -3, "subject"); /* ret.subject = {} */ |
|
408 for(i = 0; i <= n_entries; i++) |
|
409 { |
|
410 X509_NAME_ENTRY *entry; |
|
411 ASN1_OBJECT *object; |
|
412 ASN1_STRING *value; |
|
413 int len; |
|
414 |
|
415 entry = X509_NAME_get_entry(subject, i); |
|
416 object = X509_NAME_ENTRY_get_object(entry); |
|
417 |
|
418 /* Get numeric ID as string into buffer */ |
|
419 len = OBJ_obj2txt(buffer, sizeof(buffer), object, 1); |
|
420 |
|
421 if(len == 0) |
|
422 continue; |
|
423 |
|
424 /* Push numeric ID to Lua (e.g. 1.22.3...) */ |
|
425 lua_pushlstring(L, buffer, (len>sizeof(buffer))?sizeof(buffer):(len)); |
|
426 lua_pushvalue(L, -1); /* k */ |
|
427 |
|
428 lua_gettable(L, -4); /* ret.subject[k] */ |
|
429 |
|
430 if(lua_isnil(L, -1)) |
|
431 { |
|
432 lua_pop(L, 1); |
|
433 lua_newtable(L); |
|
434 lua_pushvalue(L, -2); /* k */ |
|
435 lua_pushvalue(L, -2); /* v */ |
|
436 lua_settable(L, -6); /* ret.subject[k] = v */ |
|
437 /* Get short/long name of the entry */ |
|
438 len = OBJ_obj2txt(buffer, sizeof(buffer), object, 0); |
|
439 lua_pushlstring(L, buffer, (len>sizeof(buffer))?sizeof(buffer):(len)); |
|
440 lua_setfield(L, -2, "name"); |
|
441 } |
|
442 |
|
443 value = X509_NAME_ENTRY_get_data(entry); |
|
444 if(value) |
|
445 { |
|
446 lua_pushlstring(L, (char*)ASN1_STRING_data(value), ASN1_STRING_length(value)); |
|
447 lua_rawseti(L, -2, lua_objlen(L, -2)+1); |
|
448 } |
|
449 |
|
450 lua_pop(L, 2); /* k, v */ |
396 } |
451 } |
397 if ((buffer = malloc(length)) == NULL) { |
452 } |
398 BIO_free(bp); |
453 lua_pop(L, 1); /* ret.subject */ |
399 return 0; |
454 return 1; |
400 } |
|
401 if ((length = BIO_read(bp, buffer, length)) > length) { |
|
402 free(buffer); |
|
403 BIO_free(bp); |
|
404 return 0; |
|
405 } |
|
406 lua_pushlstring(L, buffer, length); |
|
407 free(buffer); |
|
408 BIO_free(bp); |
|
409 return 1; |
|
410 } |
|
411 } |
455 } |
412 |
456 |
413 static int meth_getfinished(lua_State *L) |
457 static int meth_getfinished(lua_State *L) |
414 { |
458 { |
415 p_ssl ssl = (p_ssl)luaL_checkudata(L, 1, "SSL:Connection"); |
459 p_ssl ssl = (p_ssl)luaL_checkudata(L, 1, "SSL:Connection"); |