411 lua_pushboolean(L, 0); |
411 lua_pushboolean(L, 0); |
412 lua_pushstring(L, X509_verify_cert_error_string(result)); |
412 lua_pushstring(L, X509_verify_cert_error_string(result)); |
413 return 2; |
413 return 2; |
414 } |
414 } |
415 |
415 |
416 /** |
416 static void luasec_push_cert(lua_State *L, X509 *cert) |
417 * Return the peer certificate. |
417 { |
418 */ |
418 if (cert == NULL) { |
419 static int meth_getpeercertificate(lua_State *L) |
|
420 { |
|
421 X509 *peer; |
|
422 p_ssl ssl = (p_ssl)luaL_checkudata(L, 1, "SSL:Connection"); |
|
423 peer = SSL_get_peer_certificate(ssl->ssl); |
|
424 if (peer == NULL) { |
|
425 /* No client certificate available */ |
|
426 lua_pushnil(L); |
419 lua_pushnil(L); |
427 } |
420 } |
428 else |
421 else |
429 { |
422 { |
430 /* Push metatabled peer */ |
423 luasec_push_x509(L, cert); |
431 luasec_push_x509(L, peer); |
424 } |
432 } |
425 } |
|
426 |
|
427 /** |
|
428 * Return the nth certificate of the peer's chain. |
|
429 */ |
|
430 static int meth_getpeercertificate(lua_State *L) |
|
431 { |
|
432 p_ssl ssl = (p_ssl)luaL_checkudata(L, 1, "SSL:Connection"); |
|
433 int n = luaL_optint(L, 2, 1); /* Default to the first cert */ |
|
434 STACK_OF(X509) *certs; |
|
435 X509 *cert; |
|
436 |
|
437 /* This function is 1-based, but OpenSSL is 0-based */ |
|
438 --n; |
|
439 if (n < 0) { |
|
440 lua_pushnil(L); |
|
441 lua_pushliteral(L, "n must be positive"); |
|
442 return 2; |
|
443 } |
|
444 |
|
445 if (n == 0) { |
|
446 luasec_push_cert(L, SSL_get_peer_certificate(ssl->ssl)); |
|
447 return 1; |
|
448 } |
|
449 |
|
450 /* |
|
451 * In a server-context, the stack doesn't contain the peer cert, so |
|
452 * adjust accordingly. |
|
453 */ |
|
454 if (ssl->ssl->server) |
|
455 --n; |
|
456 |
|
457 certs = SSL_get_peer_cert_chain(ssl->ssl); |
|
458 if (n >= sk_X509_num(certs)) { |
|
459 lua_pushnil(L); |
|
460 lua_pushliteral(L, "no certificate at this index"); |
|
461 return 2; |
|
462 } |
|
463 cert = sk_X509_value(certs, n); |
|
464 /* Locking...the same as in SSL_get_peer_certificate */ |
|
465 CRYPTO_add(&cert->references, 1, CRYPTO_LOCK_X509); |
|
466 luasec_push_cert(L, cert); |
|
467 return 1; |
|
468 } |
|
469 |
|
470 static int meth_getpeerchain(lua_State *L) |
|
471 { |
|
472 p_ssl ssl = (p_ssl)luaL_checkudata(L, 1, "SSL:Connection"); |
|
473 STACK_OF(X509) *certs; |
|
474 int n_certs, i; |
|
475 |
|
476 lua_newtable(L); |
|
477 |
|
478 if (ssl->ssl->server) { |
|
479 luasec_push_cert(L, SSL_get_peer_certificate(ssl->ssl)); |
|
480 lua_rawseti(L, -2, 1); |
|
481 } |
|
482 |
|
483 certs = SSL_get_peer_cert_chain(ssl->ssl); |
|
484 n_certs = sk_X509_num(certs); |
|
485 for (i = 0; i < n_certs; ++i) { |
|
486 X509 *cert = sk_X509_value(certs, i); |
|
487 /* Locking...the same as in SSL_get_peer_certificate */ |
|
488 CRYPTO_add(&cert->references, 1, CRYPTO_LOCK_X509); |
|
489 luasec_push_cert(L, cert); |
|
490 lua_rawseti(L, -2, lua_objlen(L, -2)+1); |
|
491 } |
|
492 |
433 return 1; |
493 return 1; |
434 } |
494 } |
435 |
495 |
436 static int meth_getfinished(lua_State *L) |
496 static int meth_getfinished(lua_State *L) |
437 { |
497 { |
484 {"send", meth_send}, |
544 {"send", meth_send}, |
485 {"settimeout", meth_settimeout}, |
545 {"settimeout", meth_settimeout}, |
486 {"want", meth_want}, |
546 {"want", meth_want}, |
487 {"compression", meth_compression}, |
547 {"compression", meth_compression}, |
488 {"getpeercertificate",meth_getpeercertificate}, |
548 {"getpeercertificate",meth_getpeercertificate}, |
|
549 {"getpeerchain", meth_getpeerchain}, |
489 {"getpeerchainvalid", meth_getpeerchainvalid}, |
550 {"getpeerchainvalid", meth_getpeerchainvalid}, |
490 {"getfinished", meth_getfinished}, |
551 {"getfinished", meth_getfinished}, |
491 {"getpeerfinished", meth_getpeerfinished}, |
552 {"getpeerfinished", meth_getpeerfinished}, |
492 {NULL, NULL} |
553 {NULL, NULL} |
493 }; |
554 }; |