]> granicus.if.org Git - php/commitdiff
merge from branch: peer certificate capture context options.
authorWez Furlong <wez@php.net>
Sun, 30 Apr 2006 23:45:14 +0000 (23:45 +0000)
committerWez Furlong <wez@php.net>
Sun, 30 Apr 2006 23:45:14 +0000 (23:45 +0000)
ext/openssl/openssl.c
ext/openssl/xp_ssl.c

index c926dcb09ae976a0d3fa6e8b4d1425b399721d5d..15238a70b13566c508648f308c06ffc1ea49a8b4 100644 (file)
@@ -156,6 +156,11 @@ static int le_x509;
 static int le_csr;
 static int ssl_stream_data_index;
 
+int php_openssl_get_x509_list_id(void)
+{
+       return le_x509;
+}
+
 /* {{{ resource destructors */
 static void php_pkey_free(zend_rsrc_list_entry *rsrc TSRMLS_DC)
 {
index ed6bae4fc606a91ff70a2f8818245a52fbcc378f..4a5e302a41a0da44ae7ac6b4715b750e8d9a09d5 100644 (file)
@@ -33,6 +33,7 @@
 
 int php_openssl_apply_verification_policy(SSL *ssl, X509 *peer, php_stream *stream TSRMLS_DC);
 SSL *php_SSL_new_from_context(SSL_CTX *ctx, php_stream *stream TSRMLS_DC);
+int php_openssl_get_x509_list_id(void);
 
 /* This implementation is very closely tied to the that of the native
  * sockets implemented in the core.
@@ -414,9 +415,63 @@ static inline int php_openssl_enable_crypto(php_stream *stream,
                                SSL_shutdown(sslsock->ssl_handle);
                        } else {        
                                sslsock->ssl_active = 1;
+
+                               /* allow the script to capture the peer cert
+                                * and/or the certificate chain */
+                               if (stream->context) {
+                                       zval **val, *zcert;
+
+                                       if (SUCCESS == php_stream_context_get_option(
+                                                               stream->context, "ssl",
+                                                               "capture_peer_cert", &val) &&
+                                                       zval_is_true(*val)) {
+                                               MAKE_STD_ZVAL(zcert);
+                                               ZVAL_RESOURCE(zcert, zend_list_insert(peer_cert, 
+                                                                       php_openssl_get_x509_list_id()));
+                                               php_stream_context_set_option(stream->context,
+                                                               "ssl", "peer_certificate",
+                                                               zcert);
+                                               peer_cert = NULL;
+                                       }
+
+                                       if (SUCCESS == php_stream_context_get_option(
+                                                               stream->context, "ssl",
+                                                               "capture_peer_cert_chain", &val) &&
+                                                       zval_is_true(*val)) {
+                                               zval *arr;
+                                               STACK_OF(X509) *chain;
+
+                                               MAKE_STD_ZVAL(arr);
+                                               chain = SSL_get_peer_cert_chain(
+                                                                       sslsock->ssl_handle);
+
+                                               if (chain) {
+                                                       int i;
+                                                       array_init(arr);
+
+                                                       for (i = 0; i < sk_X509_num(chain); i++) {
+                                                               X509 *mycert = X509_dup(
+                                                                               sk_X509_value(chain, i));
+                                                               MAKE_STD_ZVAL(zcert);
+                                                               ZVAL_RESOURCE(zcert,
+                                                                               zend_list_insert(mycert,
+                                                                                       php_openssl_get_x509_list_id()));
+                                                               add_next_index_zval(arr, zcert);
+                                                       }
+                                               } else {
+                                                       ZVAL_NULL(arr);
+                                               }
+
+                                               php_stream_context_set_option(stream->context,
+                                                               "ssl", "peer_certificate_chain",
+                                                               arr);
+                                       }
+                               }
                        }
 
-                       X509_free(peer_cert);
+                       if (peer_cert) {
+                               X509_free(peer_cert);
+                       }
                } else  {
                        n = errno == EAGAIN ? 0 : -1;
                }