Wrep\Notificato\Apns\Certificate::parseCertificate PHP Method

parseCertificate() private method

Parse and validate the certificate and private key, also extracts usefull data and sets it on this object Also throws exceptions if the certificate/private key doesn't seem to be a valid APNS cert
private parseCertificate ( )
    private function parseCertificate()
    {
        $now = new \DateTime();
        // Parse the certificate
        $certificateData = openssl_x509_parse(file_get_contents($this->getPemFile()));
        if (false == $certificateData) {
            throw new InvalidCertificateException('Unable to parse certificate "' . $this->getPemFile() . '", are you sure this is a valid PEM certificate?');
        }
        // Validate the "valid from" timestamp
        if (isset($certificateData['validFrom_time_t'])) {
            $validFrom = new \DateTime('@' . $certificateData['validFrom_time_t']);
            if ($validFrom > $now) {
                throw new InvalidCertificateException('Certificate "' . $this->getPemFile() . '" not yet valid, valid from ' . $validFrom->format(\DateTime::ISO8601) . '.');
            }
            $this->validFrom = $validFrom;
        } else {
            throw new InvalidCertificateException('Certificate "' . $this->getPemFile() . '" has no valid from timestamp.');
        }
        // Validate the "valid to" timestamp
        if (isset($certificateData['validTo_time_t'])) {
            $validTo = new \DateTime('@' . $certificateData['validTo_time_t']);
            if ($validTo < $now) {
                throw new InvalidCertificateException('Certificate "' . $this->getPemFile() . '" expired, was valid until ' . $validTo->format(\DateTime::ISO8601) . '.');
            }
            $this->validTo = $validTo;
        } else {
            throw new InvalidCertificateException('Certificate "' . $this->getPemFile() . '" has no valid to timestamp.');
        }
        // Check if the certificate was issued by Apple
        if (!isset($certificateData['issuer']) || !isset($certificateData['issuer']['O']) || 'Apple Inc.' != $certificateData['issuer']['O']) {
            throw new InvalidCertificateException('Certificate "' . $this->getPemFile() . '" does not list Apple Inc. as the issuer.');
        }
        // Check if the there is an environment hidden in the certificate
        if (isset($certificateData['subject']) && isset($certificateData['subject']['CN'])) {
            $this->description = $certificateData['subject']['CN'];
            if (null === $this->endpointEnv) {
                if (strpos($certificateData['subject']['CN'], 'Pass Type ID') === 0 || strpos($certificateData['subject']['CN'], 'Apple Push Services') === 0 || strpos($certificateData['subject']['CN'], 'Apple Production IOS Push Services') === 0 || strpos($certificateData['subject']['CN'], 'Apple Production Mac Push Services') === 0) {
                    // Passbook Pass certificate & APNS Production/hybrid certs, should be on production
                    $this->endpointEnv = self::ENDPOINT_ENV_PRODUCTION;
                } else {
                    if (strpos($certificateData['subject']['CN'], 'Apple Development IOS Push Services') === 0 || strpos($certificateData['subject']['CN'], 'Apple Development Mac Push Services') === 0) {
                        // APNS Development, should always be on sandbox
                        $this->endpointEnv = self::ENDPOINT_ENV_SANDBOX;
                    } else {
                        throw new InvalidCertificateException('Could not detect APNS environment based on the CN string "' . $certificateData['subject']['CN'] . '" in certificate "' . $this->getPemFile() . '".');
                    }
                }
            }
        } else {
            throw new InvalidCertificateException('No APNS environment information found in certificate "' . $this->getPemFile() . '".');
        }
        // Validate the private key by loading it
        $privateKey = openssl_pkey_get_private('file://' . $this->getPemFile(), $this->getPassphrase());
        if (false === $privateKey) {
            throw new InvalidCertificateException('Could not extract the private key from certificate "' . $this->getPemFile() . '", please check if the given passphrase is correct and if it contains a private key.');
        }
        // If a passphrase is given, the private key may not be loaded without it
        if ($this->getPassphrase() != null) {
            // Try to load the private key without the passphrase (should fail)
            $privateKey = openssl_pkey_get_private('file://' . $this->getPemFile());
            if (false !== $privateKey) {
                throw new InvalidCertificateException('Passphrase given, but the private key in "' . $this->getPemFile() . '" is not encrypted, please make sure you are using the correct certificate/passphrase combination.');
            }
        }
    }