src/ssl.c

changeset 37
8904bda2369f
parent 34
510432315106
child 38
4ecd7b0e67ea
equal deleted inserted replaced
36:96f23601ce7a 37:8904bda2369f
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 };

mercurial