summaryrefslogtreecommitdiffstats
path: root/functions/json.php
blob: e25b885f23d0db32917904721592946475da2f43 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
<?php
// Copyright (C) 2015 Remy van Elst

// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.

// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU Affero General Public License for more details.

// You should have received a copy of the GNU Affero General Public License
// along with this program.  If not, see <http://www.gnu.org/licenses/>.

function check_json($host,$ip,$port,$fastcheck=0) {
  global $timeout;
  global $max_chain_length;
  global $ct_urls;
  $old_error_reporting = error_reporting();
  error_reporting(0);
  $data = [];
  $stream = stream_context_create (array("ssl" => 
    array("capture_peer_cert" => true,
    "capture_peer_cert_chain" => true,
    "verify_peer" => false,
    "peer_name" => $host,
    "verify_peer_name" => false,
    "allow_self_signed" => true,
    "capture_session_meta" => true,
    "sni_enabled" => true)));
  if (filter_var($ip, FILTER_VALIDATE_IP, FILTER_FLAG_IPV6 )) {
    $connect_ip = "[" . $ip . "]";
  } else {
    $connect_ip = $ip;
  }
  $read_stream = stream_socket_client("ssl://$connect_ip:$port", $errno, $errstr, $timeout, STREAM_CLIENT_CONNECT, $stream);
  if ( $read_stream === false ) {
    $data["error"] = ["Failed to connect: " . htmlspecialchars($errstr)];
    return $data;
  } else {
    $context = stream_context_get_params($read_stream);
    $context_meta = stream_context_get_options($read_stream)['ssl']['session_meta'];
    $cert_data = openssl_x509_parse($context["options"]["ssl"]["peer_certificate"]);
    $chain_data = $context["options"]["ssl"]["peer_certificate_chain"];
    $chain_length = count($chain_data);
    if (isset($chain_data) && $chain_length < $max_chain_length) {
      $chain_length = count($chain_data);
      $chain_arr_keys  = ($chain_data);
      foreach(array_keys($chain_arr_keys) as $key) {
        $curr = $chain_data[$key];
        $next = $chain_data[$key+1];
        $prev = $chain_data[$key-1];
        $chain_key = (string)$key+1;
        $include_chain = false;
        if ($key == 0) {
          $data["connection"] = ssl_conn_metadata_json($host, $ip, $port, $read_stream, $chain_data, $fastcheck);
          $data["chain"][$chain_key] = cert_parse_json($curr, $next, $host, true, $port, $include_chain);
        } else {
          $data["chain"][$chain_key] = cert_parse_json($curr, $next, null, false, $port, $include_chain);
        }
        // certificate transparency
        $data["certificate_transparency"] = [];
        if($fastcheck == 0) {
          foreach ($ct_urls as $ct_url) {
            $submitToCT = submitCertToCT($data["chain"], $ct_url);
            $ct_result = json_decode($submitToCT, TRUE);
            if ($ct_result === null
              && json_last_error() !== JSON_ERROR_NONE) {
              $result_ct = array('result' => $submitToCT);
              $data["certificate_transparency"][$ct_url] = $result_ct;
            } else {
             $data["certificate_transparency"][$ct_url] = $ct_result;
            }
          }
        }
      } 
    } else {
      $data["error"] = ["Chain too long."];
      return $data;
    }
  }
  error_reporting($old_error_reporting);
  return $data;
}

?>