adding method to retreve ssl connection information...

Issue #12 resolved
Mathieu CARBONNEAUX created an issue

when the connection open in ssl mode there no way to know information about the ssl handcheck done....

the idea is to add method to retreve this information on the ssl connection...

in using this function: https://www.openssl.org/docs/ssl/SSL_get_current_cipher.html

sample of use: http://alvinalexander.com/java/jwarehouse/apache-tomcat-6.0.16/native/connector/src/sslinfo.c.shtml

i've already done this in adding this method to EventBufferEvent:

  • sslGetCurrentCipher
  • sslGetCurrentVersion
  • sslGetCurrentCipherName
  • sslGetCurrentProtocol

after connection (idealy in EventBufferEvent::CONNECTED event) you can call this method:

printf("Cipher:%s\n",$buffer->sslGetCurrentCipher());
printf("CipherVersion:%s\n",$buffer->sslGetCurrentVersion());
printf("CipherName:%s\n",$buffer->sslGetCurrentCipherName());
printf("CipherProtocol:%s\n",$buffer->sslGetCurrentProtocol());

they print information like this:

Cipher:AES128-GCM-SHA256       TLSv1.2 Kx=RSA      Au=RSA  Enc=AESGCM(128) Mac=AEAD
CipherVersion:TLSv1/SSLv3
CipherName:AES128-GCM-SHA256
CipherProtocol:TLSv1.2

the patch to add this method:

diff --git a/classes/buffer_event.c b/classes/buffer_event.c
index 41bc7ca..a974f5b 100644
--- a/classes/buffer_event.c
+++ b/classes/buffer_event.c
@@ -1183,6 +1183,119 @@ PHP_METHOD(EventBufferEvent, sslError)
 }
 /* }}} */

+/* {{{ proto string EventBufferEvent::sslGetCurrentVersion(void);
+ *
+ * Returns the current Cipher Version of the connexion as SSL_get_cipher_version does.
+ * returns FALSE, if there is no more error to return. */
+PHP_METHOD(EventBufferEvent, sslGetCurrentVersion)
+{
+       zval               *zbevent  = getThis();
+       php_event_bevent_t *bev;
+       char                buf[512];
+       struct ssl_st*      e;
+
+       if (zend_parse_parameters_none() == FAILURE) {
+               return;
+       }
+
+       PHP_EVENT_FETCH_BEVENT(bev, zbevent);
+       _ret_if_invalid_bevent_ptr(bev);
+
+       e = bufferevent_openssl_get_ssl(bev->bevent);
+       if (e) {
+           RETURN_STRING(SSL_get_cipher_version(e),1);
+       }
+
+       RETVAL_FALSE;
+}
+/* }}} */
+
+/* {{{ proto string EventBufferEvent::sslGetCurrentCipherName(void);
+ *
+ * Returns the current Cipher Name of the connexion as SSL_get_cipher_name does.
+ * returns FALSE, if there is no more error to return. */
+PHP_METHOD(EventBufferEvent, sslGetCurrentCipherName)
+{
+       zval               *zbevent  = getThis();
+       php_event_bevent_t *bev;
+       char                buf[512];
+       struct ssl_st*      e;
+
+       if (zend_parse_parameters_none() == FAILURE) {
+               return;
+       }
+
+       PHP_EVENT_FETCH_BEVENT(bev, zbevent);
+       _ret_if_invalid_bevent_ptr(bev);
+
+       e = bufferevent_openssl_get_ssl(bev->bevent);
+       if (e) {
+           RETURN_STRING(SSL_get_cipher_name(e),1);
+       }
+
+       RETVAL_FALSE;
+}
+/* }}} */
+
+/* {{{ proto string EventBufferEvent::sslGetCurrentProtocol(void);
+ *
+ * Returns the current Protocol of the connexion as SSL_get_version does.
+ * returns FALSE, if there is no more error to return. */
+PHP_METHOD(EventBufferEvent, sslGetCurrentProtocol)
+{
+       zval               *zbevent  = getThis();
+       php_event_bevent_t *bev;
+       char                buf[512];
+       struct ssl_st*      e;
+
+       if (zend_parse_parameters_none() == FAILURE) {
+               return;
+       }
+
+       PHP_EVENT_FETCH_BEVENT(bev, zbevent);
+       _ret_if_invalid_bevent_ptr(bev);
+
+       e = bufferevent_openssl_get_ssl(bev->bevent);
+       if (e) {
+           RETURN_STRING(SSL_get_version(e),1);
+       }
+
+       RETVAL_FALSE;
+}
+/* }}} */
+
+/* {{{ proto string EventBufferEvent::sslGetCurrentCipher(void);
+ *
+ * Returns the current Cipher of the connexion as SSL_get_current_cipher/SSL_CIPHER_description does.
+ * returns FALSE, if there is no more error to return. */
+PHP_METHOD(EventBufferEvent, sslGetCurrentCipher)
+{
+       zval               *zbevent  = getThis();
+       php_event_bevent_t *bev;
+       char                buf[512];
+       struct ssl_st*      e;
+
+       if (zend_parse_parameters_none() == FAILURE) {
+               return;
+       }
+
+       PHP_EVENT_FETCH_BEVENT(bev, zbevent);
+       _ret_if_invalid_bevent_ptr(bev);
+
+       e = bufferevent_openssl_get_ssl(bev->bevent);
+       if (e) {
+               SSL_CIPHER *cipher = SSL_get_current_cipher(e);
+                if (cipher) {
+                    char buf[256];
+                    char *desc = SSL_CIPHER_description(cipher, buf, 256);
+                   RETURN_STRING(buf,1);
+                }
+       }
+
+       RETVAL_FALSE;
+}
+/* }}} */
+
 /* {{{ proto void EventBufferEvent::sslRenegotiate(void);
  *
  * Tells a bufferevent to begin SSL renegotiation.
diff --git a/src/fe.c b/src/fe.c
index 98c6da5..942508e 100644
--- a/src/fe.c
+++ b/src/fe.c
@@ -576,6 +576,10 @@ const zend_function_entry php_event_bevent_ce_functions[] = {/* {{{ */
        PHP_ME(EventBufferEvent, sslFilter,      arginfo_bufferevent_ssl_filter, ZEND_ACC_PUBLIC  | ZEND_ACC_STATIC)
        PHP_ME(EventBufferEvent, sslSocket,      arginfo_bufferevent_ssl_socket, ZEND_ACC_PUBLIC  | ZEND_ACC_STATIC)
        PHP_ME(EventBufferEvent, sslError,       arginfo_event__void,            ZEND_ACC_PUBLIC)
+       PHP_ME(EventBufferEvent, sslGetCurrentCipher,       arginfo_event__void,            ZEND_ACC_PUBLIC)
+       PHP_ME(EventBufferEvent, sslGetCurrentVersion,       arginfo_event__void,            ZEND_ACC_PUBLIC)
+       PHP_ME(EventBufferEvent, sslGetCurrentCipherName,       arginfo_event__void,            ZEND_ACC_PUBLIC)
+       PHP_ME(EventBufferEvent, sslGetCurrentProtocol,       arginfo_event__void,            ZEND_ACC_PUBLIC)
        PHP_ME(EventBufferEvent, sslRenegotiate, arginfo_event__void,            ZEND_ACC_PUBLIC)
 #endif

diff --git a/src/fe.h b/src/fe.h
index 5d93049..8266c13 100644
--- a/src/fe.h
+++ b/src/fe.h
@@ -86,6 +86,10 @@ PHP_METHOD(EventBufferEvent, setTimeouts);
 PHP_METHOD(EventBufferEvent, sslFilter);
 PHP_METHOD(EventBufferEvent, sslSocket);
 PHP_METHOD(EventBufferEvent, sslError);
+PHP_METHOD(EventBufferEvent, sslGetCurrentCipher);
+PHP_METHOD(EventBufferEvent, sslGetCurrentVersion);
+PHP_METHOD(EventBufferEvent, sslGetCurrentCipherName);
+PHP_METHOD(EventBufferEvent, sslGetCurrentProtocol);
 PHP_METHOD(EventBufferEvent, sslRenegotiate);
 #endif

Comments (4)

  1. Ruslan Osmanov repo owner

    Oh, I was waiting for day when someone starts to pull/feature-request the SSL stuff "built-in", because PHP has no such kinda thing in its streams API so far. (I'd've exported a stream resource, if it had had corresponding API.)

    Well, it'll be merged, soon.

    Thanks for contributing.

  2. Mathieu CARBONNEAUX reporter

    i've made a pull request to add this patch !

    i while do the rest of the ssl conexion information method later!

  3. Ruslan Osmanov repo owner

    The methods are added to master with slightly modified names, however: - sslGetCipherInfo - sslGetCipherName - sslGetCipherVersion - sslGetProtocol

  4. Log in to comment