/libraries/fabrik/vendor/aws/aws-sdk-php/src/CloudFront/Signer.php

https://github.com/trob/fabrik · PHP · 123 lines · 74 code · 12 blank · 37 comment · 11 complexity · 36ac0b55544e9955f61ce05f3b425fc4 MD5 · raw file

  1. <?php
  2. namespace Aws\CloudFront;
  3. /**
  4. * @internal
  5. */
  6. class Signer
  7. {
  8. private $keyPairId;
  9. private $pkHandle;
  10. /**
  11. * A signer for creating the signature values used in CloudFront signed URLs
  12. * and signed cookies.
  13. *
  14. * @param $keyPairId string ID of the key pair
  15. * @param $privateKey string Path to the private key used for signing
  16. * @param $passphrase string Passphrase to private key file, if one exists
  17. *
  18. * @throws \RuntimeException if the openssl extension is missing
  19. * @throws \InvalidArgumentException if the private key cannot be found.
  20. */
  21. public function __construct($keyPairId, $privateKey, $passphrase = "")
  22. {
  23. if (!extension_loaded('openssl')) {
  24. //@codeCoverageIgnoreStart
  25. throw new \RuntimeException('The openssl extension is required to '
  26. . 'sign CloudFront urls.');
  27. //@codeCoverageIgnoreEnd
  28. }
  29. $this->keyPairId = $keyPairId;
  30. if (!$this->pkHandle = openssl_pkey_get_private($privateKey, $passphrase)) {
  31. if (!file_exists($privateKey)) {
  32. throw new \InvalidArgumentException("PK file not found: $privateKey");
  33. } else {
  34. $this->pkHandle = openssl_pkey_get_private("file://$privateKey", $passphrase);
  35. if (!$this->pkHandle) {
  36. throw new \InvalidArgumentException(openssl_error_string());
  37. }
  38. }
  39. }
  40. }
  41. public function __destruct()
  42. {
  43. if (PHP_MAJOR_VERSION < 8) {
  44. $this->pkHandle && openssl_pkey_free($this->pkHandle);
  45. } else {
  46. $this->pkHandle;
  47. }
  48. }
  49. /**
  50. * Create the values used to construct signed URLs and cookies.
  51. *
  52. * @param string $resource The CloudFront resource to which
  53. * this signature will grant access.
  54. * Not used when a custom policy is
  55. * provided.
  56. * @param string|integer|null $expires UTC Unix timestamp used when
  57. * signing with a canned policy.
  58. * Not required when passing a
  59. * custom $policy.
  60. * @param string $policy JSON policy. Use this option when
  61. * creating a signature for a custom
  62. * policy.
  63. *
  64. * @return array The values needed to construct a signed URL or cookie
  65. * @throws \InvalidArgumentException when not provided either a policy or a
  66. * resource and a expires
  67. *
  68. * @link http://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/private-content-signed-cookies.html
  69. */
  70. public function getSignature($resource = null, $expires = null, $policy = null)
  71. {
  72. $signatureHash = [];
  73. if ($policy) {
  74. $policy = preg_replace('/\s/s', '', $policy);
  75. $signatureHash['Policy'] = $this->encode($policy);
  76. } elseif ($resource && $expires) {
  77. $expires = (int) $expires; // Handle epoch passed as string
  78. $policy = $this->createCannedPolicy($resource, $expires);
  79. $signatureHash['Expires'] = $expires;
  80. } else {
  81. throw new \InvalidArgumentException('Either a policy or a resource'
  82. . ' and an expiration time must be provided.');
  83. }
  84. $signatureHash['Signature'] = $this->encode($this->sign($policy));
  85. $signatureHash['Key-Pair-Id'] = $this->keyPairId;
  86. return $signatureHash;
  87. }
  88. private function createCannedPolicy($resource, $expiration)
  89. {
  90. return json_encode([
  91. 'Statement' => [
  92. [
  93. 'Resource' => $resource,
  94. 'Condition' => [
  95. 'DateLessThan' => ['AWS:EpochTime' => $expiration],
  96. ],
  97. ],
  98. ],
  99. ], JSON_UNESCAPED_SLASHES);
  100. }
  101. private function sign($policy)
  102. {
  103. $signature = '';
  104. openssl_sign($policy, $signature, $this->pkHandle);
  105. return $signature;
  106. }
  107. private function encode($policy)
  108. {
  109. return strtr(base64_encode($policy), '+=/', '-_~');
  110. }
  111. }