PHP Classes

File: src/Fetch.php

Recommend this page to a friend!
  Classes of Scott Arciszewski   Certainty   src/Fetch.php   Download  
File: src/Fetch.php
Role: Class source
Content type: text/plain
Description: Class source
Class: Certainty
Manage SSL certificate authority file used by PHP
Author: By
Last change:
Date: 6 years ago
Size: 4,785 bytes
 

Contents

Class file image Download
<?php
namespace ParagonIE\Certainty;

use
ParagonIE\Certainty\Exception\BundleException;
use
ParagonIE\Certainty\Exception\EncodingException;
use
ParagonIE\Certainty\Exception\FilesystemException;

/**
 * Class Fetch
 * @package ParagonIE\Certainty
 */
class Fetch
{
    const
CHECK_SIGNATURE_BY_DEFAULT = false;
    const
CHECK_CHRONICLE_BY_DEFAULT = false;

   
/**
     * @var string $dataDirectory
     */
   
protected $dataDirectory = '';

   
/**
     * Fetch constructor.
     *
     * You almost certainly want to use RemoteFetch instead.
     *
     * @param string $dataDir Where the certificates and configuration lives
     */
   
public function __construct($dataDir = '')
    {
        if (!empty(
$dataDir) && \is_readable($dataDir)) {
           
$this->dataDirectory = $dataDir;
        } else {
           
$this->dataDirectory = \dirname(__DIR__) . '/data';
        }
    }

   
/**
     * Get the latest bundle. Checks the SHA256 hash of the file versus what
     * is expected. Optionally checks the Ed25519 signature.
     *
     * @param bool|null $checkEd25519Signature Enforce Ed25519 signatures?
     * @param bool|null $checkChronicle Require cert bundles be stored
     * inside a Chronicle instance?
     * @return Bundle
     * @throws BundleException
     */
   
public function getLatestBundle($checkEd25519Signature = null, $checkChronicle = null)
    {
        if (\
is_null($checkEd25519Signature)) {
           
$checkEd25519Signature = (bool) static::CHECK_SIGNATURE_BY_DEFAULT;
        }
        if (\
is_null($checkChronicle)) {
           
$checkChronicle = (bool) static::CHECK_CHRONICLE_BY_DEFAULT;
        }

       
/** @var Bundle $bundle */
       
foreach ($this->listBundles() as $bundle) {
            if (
$bundle->hasCustom()) {
               
$validator = $bundle->getValidator();
            } else {
               
$validator = new Validator();
            }

           
// If the SHA256 doesn't match, fail fast.
           
if ($validator::checkSha256Sum($bundle)) {
               
/** @var bool $valid */
               
$valid = true;
                if (
$checkEd25519Signature) {
                   
$valid = $valid && $validator::checkEd25519Signature($bundle);
                }
                if (
$checkChronicle) {
                   
$valid = $valid && $validator::checkChronicleHash($bundle);
                }
                if (
$valid) {
                    return
$bundle;
                }
            }
        }
        throw new
BundleException('No valid bundles were found in the data directory.');
    }

   
/**
     * Get an array of all of the Bundles, ordered most-recent to oldest.
     *
     * No validation is performed automatically.
     *
     * @param string $customValidator Fully-qualified class name for Validator
     * @return array<int, Bundle>
     */
   
public function getAllBundles($customValidator = '')
    {
        return \
array_values($this->listBundles($customValidator));
    }

   
/**
     * List bundles
     *
     * @param string $customValidator Fully-qualified class name for Validator
     * @return array<int, Bundle>
     * @throws \Exception
     */
   
protected function listBundles($customValidator = '')
    {
        if (!\
file_exists($this->dataDirectory . '/ca-certs.json')) {
            throw new
FilesystemException('ca-certs.json not found in data directory.');
        }
        if (!\
is_readable($this->dataDirectory . '/ca-certs.json')) {
            throw new
FilesystemException('ca-certs.json is not readable.');
        }
       
$contents = \file_get_contents($this->dataDirectory . '/ca-certs.json');
        if (!\
is_string($contents)) {
            throw new
FilesystemException('ca-certs.json could not be read.');
        }
       
$data = \json_decode($contents, true);
        if (!\
is_array($data)) {
            throw new
EncodingException('ca-certs.json is not a valid JSON file.');
        }
       
$bundles = [];
        foreach (
$data as $row) {
            if (!isset(
$row['date'], $row['file'], $row['sha256'], $row['signature'])) {
               
// The necessary keys are not defined.
               
continue;
            }
           
$key = (int) (\preg_replace('/[^0-9]/', '', $row['date']) . '0000');
            while (isset(
$bundles[$key])) {
                ++
$key;
            }
           
$bundles[$key] = new Bundle(
               
$this->dataDirectory . '/' . $row['file'],
               
$row['sha256'],
               
$row['signature'],
                !empty(
$row['custom']) ? $row['custom'] : $customValidator,
                isset(
$row['chronicle']) ? $row['chronicle'] : ''
           
);
        }
        \
krsort($bundles);
        return
$bundles;
    }
}