Commit:    1c7cabb2ca405e6763d7044015f9cb063941a838
Author:    Tjerk Meesters <datib...@php.net>         Mon, 23 Sep 2013 23:29:17 
+0800
Parents:   2bfc5a253b4ee76f9930692f2d088371c38dd65f
Branches:  master

Link:       
http://git.php.net/?p=php-src.git;a=commitdiff;h=1c7cabb2ca405e6763d7044015f9cb063941a838

Log:
add md5 and sha1 fingerprint tests

Changed paths:
  M  ext/openssl/openssl.c
  A  ext/openssl/tests/openssl_peer_fingerprint.phpt


Diff:
diff --git a/ext/openssl/openssl.c b/ext/openssl/openssl.c
index 9da10fc..c8588e2 100644
--- a/ext/openssl/openssl.c
+++ b/ext/openssl/openssl.c
@@ -1,4 +1,5 @@
 /*
+                       
    +----------------------------------------------------------------------+
    | PHP Version 5                                                        |
    +----------------------------------------------------------------------+
@@ -1672,6 +1673,33 @@ PHP_FUNCTION(openssl_x509_export)
 }
 /* }}} */
 
+int php_openssl_x509_fingerprint(X509 *peer, const char *method, int raw, char 
**out, int *out_len)
+{
+       unsigned char md[EVP_MAX_MD_SIZE];
+       const EVP_MD *mdtype;
+       int n;
+
+       if (!(mdtype = EVP_get_digestbyname(method))) {
+               php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unknown signature 
algorithm");
+               return 0;
+       } else if (!X509_digest(peer, mdtype, md, &n)) {
+               php_error_docref(NULL TSRMLS_CC, E_ERROR, "Could not generate 
signature");
+               return 0;
+       }
+
+       if (raw) {
+               *out_len = n;
+               *out = estrndup(md, n);
+       } else {
+               *out_len = n * 2;
+               *out = emalloc(*out_len + 1);
+
+               make_digest_ex(*out, md, n);
+       }
+
+       return 1;
+}
+
 PHP_FUNCTION(openssl_x509_fingerprint)
 {
        X509 *cert;
@@ -1681,9 +1709,8 @@ PHP_FUNCTION(openssl_x509_fingerprint)
        char *method = "sha1";
        int method_len;
 
-       const EVP_MD *mdtype;
-       unsigned char md[EVP_MAX_MD_SIZE];
-       unsigned int n;
+       char *fingerprint;
+       char *fingerprint_len;
 
        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "Z|sb", &zcert, 
&method, &method_len, &raw_output) == FAILURE) {
                return;
@@ -1695,23 +1722,10 @@ PHP_FUNCTION(openssl_x509_fingerprint)
                RETURN_FALSE;
        }
 
-       mdtype = EVP_get_digestbyname(method);
-       if (!mdtype) {
-               php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unknown signature 
algorithm");
-               RETVAL_FALSE;
-       } else if (!X509_digest(cert, mdtype, md, &n)) {
-               php_error_docref(NULL TSRMLS_CC, E_ERROR, "Out of memory");
-               RETVAL_FALSE;
+       if (php_openssl_x509_fingerprint(cert, method, raw_output, 
&fingerprint, &fingerprint_len)) {
+               RETVAL_STRINGL(fingerprint, fingerprint_len, 0);
        } else {
-               if (raw_output) {
-                       RETVAL_STRINGL(md, n, 1);
-               } else {
-                       int digest_str_len = n * 2;
-                       char *digest_str = emalloc(digest_str_len + 1);
-
-                       make_digest_ex(digest_str, md, n);
-                       RETVAL_STRINGL(digest_str, digest_str_len, 0);
-               }
+               RETVAL_FALSE;
        }
 
        if (certresource == -1 && cert) {
@@ -4919,6 +4933,33 @@ int php_openssl_apply_verification_policy(SSL *ssl, X509 
*peer, php_stream *stre
 
        /* if the cert passed the usual checks, apply our own local policies 
now */
 
+       if (GET_VER_OPT("peer_fingerprint") && Z_TYPE_PP(val) == IS_STRING) {
+               char *fingerprint;
+               int fingerprint_len;
+               const char *method = NULL;
+
+               switch (Z_STRLEN_PP(val)) {
+                       case 32:
+                               method = "md5";
+                               break;
+
+                       case 40:
+                               method = "sha1";
+                               break;
+               }
+
+               if (method && php_openssl_x509_fingerprint(peer, method, 0, 
&fingerprint, &fingerprint_len)) {
+                       int match = strcmp(Z_STRVAL_PP(val), fingerprint) == 0;
+
+                       efree(fingerprint);
+
+                       if (!match) {
+                               php_error_docref(NULL TSRMLS_CC, E_WARNING, 
"Peer fingerprint `%s` not matched", Z_STRVAL_PP(val));
+                               return FAILURE;
+                       }
+               }
+       }
+
        name = X509_get_subject_name(peer);
 
        /* Does the common name match ? (used primarily for https://) */
diff --git a/ext/openssl/tests/openssl_peer_fingerprint.phpt 
b/ext/openssl/tests/openssl_peer_fingerprint.phpt
new file mode 100644
index 0000000..a6be676
--- /dev/null
+++ b/ext/openssl/tests/openssl_peer_fingerprint.phpt
@@ -0,0 +1,44 @@
+--TEST--
+Testing peer fingerprint on connection
+--SKIPIF--
+<?php 
+if (!extension_loaded("openssl")) die("skip");
+if (!function_exists('pcntl_fork')) die("skip no fork");
+--FILE--
+<?php
+$context = stream_context_create();
+
+stream_context_set_option($context, 'ssl', 'local_cert', __DIR__ . 
"/bug54992.pem");
+stream_context_set_option($context, 'ssl', 'allow_self_signed', true);
+$server = stream_socket_server('ssl://127.0.0.1:64321', $errno, $errstr,
+       STREAM_SERVER_BIND|STREAM_SERVER_LISTEN, $context);
+
+
+$pid = pcntl_fork();
+if ($pid == -1) {
+       die('could not fork');
+} else if ($pid) {
+       $contextC = stream_context_create(
+               array(
+                       'ssl' => array(
+                               'verify_peer'           => true,
+                               'cafile'                => __DIR__ . 
'/bug54992-ca.pem',
+                               'capture_peer_cert'     => true,
+                               'peer_fingerprint'      => 
'81cafc260aa8d82956ebc6212a362ece',
+                       )
+               )
+       );
+       // should be: 81cafc260aa8d82956ebc6212a362ecc
+       var_dump(stream_socket_client("ssl://127.0.0.1:64321", $errno, $errstr, 
1,
+               STREAM_CLIENT_CONNECT, $contextC));
+} else {
+       @pcntl_wait($status);
+       @stream_socket_accept($server, 1);
+}
+--EXPECTF--
+Warning: stream_socket_client(): Peer fingerprint 
`81cafc260aa8d82956ebc6212a362ece` not matched in %s on line %d
+
+Warning: stream_socket_client(): Failed to enable crypto in %s on line %d
+
+Warning: stream_socket_client(): unable to connect to ssl://127.0.0.1:64321 
(Unknown error) in %s on line %d
+bool(false)


--
PHP CVS Mailing List (http://www.php.net/)
To unsubscribe, visit: http://www.php.net/unsub.php

Reply via email to