Skip to content

Instantly share code, notes, and snippets.

@samikeijonen
Last active August 29, 2015 14:07
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save samikeijonen/0d596b9b8468bd7e917f to your computer and use it in GitHub Desktop.
Save samikeijonen/0d596b9b8468bd7e917f to your computer and use it in GitHub Desktop.
Stripe errors

It is failing during the checkSslCert() method in the Stripe_ApiRequestor class.

The message that is getting returned with the error is:

Could not connect to Stripe (https://api.stripe.com).  Please check your internet connection and try again.  If this problem persists, you should check Stripe's service status at https://twitter.com/stripestatus. Reason was:

There is supposed to be an error code with it, but there isn’t.

The checkSSL() method looks like this:

/**
   * Preflight the SSL certificate presented by the backend. This isn't 100%
   * bulletproof, in that we're not actually validating the transport used to
   * communicate with Stripe, merely that the first attempt to does not use a
   * revoked certificate.
   *
   * Unfortunately the interface to OpenSSL doesn't make it easy to check the
   * certificate before sending potentially sensitive data on the wire. This
   * approach raises the bar for an attacker significantly.
   */
  private function checkSslCert($url)
  {
    if (version_compare(PHP_VERSION, '5.3.0', '< ')) {
      error_log(
          'Warning: This version of PHP is too old to check SSL certificates '.
          'correctly. Stripe cannot guarantee that the server has a '.
          'certificate which is not blacklisted'
      );
      return true;
    }

    if (strpos(PHP_VERSION, 'hiphop') !== false) {
      error_log(
          'Warning: HHVM does not support Stripe\'s SSL certificate '.
          'verification. (See http://docs.hhvm.com/manual/en/context.ssl.php) '.
          'Stripe cannot guarantee that the server has a certificate which is '.
          'not blacklisted'
      );
      return true;
    }

    $url = parse_url($url);
    $port = isset($url["port"]) ? $url["port"] : 443;
    $url = "ssl://{$url["host"]}:{$port}";

    $sslContext = stream_context_create(
        array('ssl' => array(
          'capture_peer_cert' => true,
          'verify_peer'   => true,
          'cafile'        => $this->caBundle(),
        ))
    );
    $result = stream_socket_client(
        $url, $errno, $errstr, 30, STREAM_CLIENT_CONNECT, $sslContext
    );
    if ($errno !== 0) {
      $apiBase = Stripe::$apiBase;
      throw new Stripe_ApiConnectionError(
          'Could not connect to Stripe (' . $apiBase . ').  Please check your '.
          'internet connection and try again.  If this problem persists, '.
          'you should check Stripe\'s service status at '.
          'https://twitter.com/stripestatus. Reason was: '.$errstr
      );
    }

    $params = stream_context_get_params($result);

    $cert = $params['options']['ssl']['peer_certificate'];

    openssl_x509_export($cert, $pemCert);

    if (self::isBlackListed($pemCert)) {
      throw new Stripe_ApiConnectionError(
          'Invalid server certificate. You tried to connect to a server that '.
          'has a revoked SSL certificate, which means we cannot securely send '.
          'data to that server.  Please email support@stripe.com if you need '.
          'help connecting to the correct API server.'
      );
    }

    return true;
  }

As far as I can tell, it is failing for one of two reasons:

  1. The SSL certificate can’t be verified
  2. The stream_context_create() function isn’t working properly.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment