Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- //
- // Validate keychainUri is proper (from Amazon)
- //
- function validateKeychainUri($keychainUri){
- $uriParts = parse_url($keychainUri);
- if (strcasecmp($uriParts['host'], 's3.amazonaws.com') != 0)
- fail('The host for the Certificate provided in the header is invalid');
- if (strpos($uriParts['path'], '/echo.api/') !== 0)
- fail('The URL path for the Certificate provided in the header is invalid');
- if (strcasecmp($uriParts['scheme'], 'https') != 0)
- fail('The URL is using an unsupported scheme. Should be https');
- if (array_key_exists('port', $uriParts) && $uriParts['port'] != '443')
- fail('The URL is using an unsupported https port');
- }
- //
- // Fail - die() replacement with error logging
- //
- function fail($message) {
- error_log($message);
- die();
- }
- $applicationIdValidation = 'amzn1.echo-sdk-ams.app.GUID####';
- $userIdValidation = 'amzn1.account.GUID###';
- $echoServiceDomain = 'echo-api.amazon.com';
- // Capture Amazon's POST JSON request:
- $jsonRequest = file_get_contents('php://input');
- $data = json_decode($jsonRequest, true);
- //
- // Parse out key variables
- //
- $sessionId = @$data['session']['sessionId'];
- $applicationId = @$data['session']['application']['applicationId'];
- $userId = @$data['session']['user']['userId'];
- $requestTimestamp = @$data['request']['timestamp'];
- $requestType = $data['request']['type'];
- // Die if applicationId isn't valid
- if ($applicationId != $applicationIdValidation) fail('Invalid Application id: ' . $applicationId);
- // Die if this request isn't coming from Matt Farley's Amazon Account
- if ($userId != $userIdValidation) fail('Invalid User id: ' . $userId);
- // Determine if we need to download a new Signature Certificate Chain from Amazon
- $md5pem = md5($_SERVER['HTTP_SIGNATURECERTCHAINURL']);
- $md5pem = $md5pem . '.pem';
- // If we haven't received a certificate with this URL before, store it as a cached copy
- if (!file_exists($md5pem)) {
- file_put_contents($md5pem, file_get_contents($_SERVER['HTTP_SIGNATURECERTCHAINURL']));
- }
- // Validate proper format of Amazon provided certificate chain url
- validateKeychainUri($_SERVER['HTTP_SIGNATURECERTCHAINURL']);
- // Validate certificate chain and signature
- $pem = file_get_contents($md5pem);
- $ssl_check = openssl_verify($jsonRequest, base64_decode($_SERVER['HTTP_SIGNATURE']), $pem);
- if ($ssl_check != 1)
- fail(openssl_error_string());
- // Parse certificate for validations below
- $parsedCertificate = openssl_x509_parse($pem);
- if (!$parsedCertificate)
- fail('x509 parsing failed');
- // Check that the domain echo-api.amazon.com is present in the Subject Alternative Names (SANs) section of the signing certificate
- if(strpos($parsedCertificate['extensions']['subjectAltName'], $echoServiceDomain) === false)
- fail('subjectAltName Check Failed');
- // Check that the signing certificate has not expired (examine both the Not Before and Not After dates)
- $validFrom = $parsedCertificate['validFrom_time_t'];
- $validTo = $parsedCertificate['validTo_time_t'];
- $time = time();
- if (!($validFrom <= $time && $time <= $validTo))
- fail('certificate expiration check failed');
- // Check the timestamp of the request and ensure it was within the past minute
- if (time() - strtotime($requestTimestamp) > 60)
- fail('timestamp validation failure.. Current time: ' . time() . ' vs. Timestamp: ' . $requestTimestamp);
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement