File manager - Edit - /home/opticamezl/www/newok/cose-lib.tar
Back
src/Verifier.php 0000644 00000000416 15173124756 0007633 0 ustar 00 <?php declare(strict_types=1); /* * The MIT License (MIT) * * Copyright (c) 2014-2019 Spomky-Labs * * This software may be modified and distributed under the terms * of the MIT license. See the LICENSE file for details. */ namespace Cose; class Verifier { } src/Key/OkpKey.php 0000644 00000003222 15173124756 0010010 0 ustar 00 <?php declare(strict_types=1); /* * The MIT License (MIT) * * Copyright (c) 2014-2019 Spomky-Labs * * This software may be modified and distributed under the terms * of the MIT license. See the LICENSE file for details. */ namespace Cose\Key; use Assert\Assertion; class OkpKey extends Key { public const CURVE_X25519 = 4; public const CURVE_X448 = 5; public const CURVE_ED25519 = 6; public const CURVE_ED448 = 7; private const SUPPORTED_CURVES = [ self::CURVE_X25519, self::CURVE_X448, self::CURVE_ED25519, self::CURVE_ED448, ]; public const DATA_CURVE = -1; public const DATA_X = -2; public const DATA_D = -4; public function __construct(array $data) { parent::__construct($data); Assertion::eq($data[self::TYPE], self::TYPE_OKP, 'Invalid OKP key. The key type does not correspond to an OKP key'); Assertion::keyExists($data, self::DATA_CURVE, 'Invalid EC2 key. The curve is missing'); Assertion::keyExists($data, self::DATA_X, 'Invalid OKP key. The x coordinate is missing'); Assertion::inArray((int) $data[self::DATA_CURVE], self::SUPPORTED_CURVES, 'The curve is not supported'); } public function x(): string { return $this->get(self::DATA_X); } public function isPrivate(): bool { return \array_key_exists(self::DATA_D, $this->getData()); } public function d(): string { Assertion::true($this->isPrivate(), 'The key is not private'); return $this->get(self::DATA_D); } public function curve(): int { return (int) $this->get(self::DATA_CURVE); } } src/Key/Key.php 0000644 00000003602 15173124756 0007340 0 ustar 00 <?php declare(strict_types=1); /* * The MIT License (MIT) * * Copyright (c) 2014-2019 Spomky-Labs * * This software may be modified and distributed under the terms * of the MIT license. See the LICENSE file for details. */ namespace Cose\Key; use Assert\Assertion; class Key { public const TYPE = 1; public const TYPE_OKP = 1; public const TYPE_EC2 = 2; public const TYPE_RSA = 3; public const TYPE_OCT = 4; public const KID = 2; public const ALG = 3; public const KEY_OPS = 4; public const BASE_IV = 5; /** * @var array */ private $data; public function __construct(array $data) { Assertion::keyExists($data, self::TYPE, 'Invalid key: the type is not defined'); $this->data = $data; } public static function createFromData(array $data): self { Assertion::keyExists($data, self::TYPE, 'Invalid key: the type is not defined'); switch ($data[self::TYPE]) { case 1: return new OkpKey($data); case 2: return new Ec2Key($data); case 3: return new RsaKey($data); case 4: return new SymmetricKey($data); default: return new self($data); } } /** * @return int|string */ public function type() { return $this->data[self::TYPE]; } public function alg(): int { return (int) $this->get(self::ALG); } public function getData(): array { return $this->data; } public function has(int $key): bool { return \array_key_exists($key, $this->data); } /** * @return mixed */ public function get(int $key) { Assertion::keyExists($this->data, $key, sprintf('The key has no data at index %d', $key)); return $this->data[$key]; } } src/Key/SymmetricKey.php 0000644 00000001375 15173124756 0011242 0 ustar 00 <?php declare(strict_types=1); /* * The MIT License (MIT) * * Copyright (c) 2014-2019 Spomky-Labs * * This software may be modified and distributed under the terms * of the MIT license. See the LICENSE file for details. */ namespace Cose\Key; use Assert\Assertion; class SymmetricKey extends Key { public const DATA_K = -1; public function __construct(array $data) { parent::__construct($data); Assertion::eq($data[self::TYPE], self::TYPE_OCT, 'Invalid symmetric key. The key type does not correspond to a symmetric key'); Assertion::keyExists($data, self::DATA_K, 'Invalid symmetric key. The parameter "k" is missing'); } public function k(): string { return $this->get(self::DATA_K); } } src/Key/RsaKey.php 0000644 00000011372 15173124756 0010011 0 ustar 00 <?php declare(strict_types=1); /* * The MIT License (MIT) * * Copyright (c) 2014-2019 Spomky-Labs * * This software may be modified and distributed under the terms * of the MIT license. See the LICENSE file for details. */ namespace Cose\Key; use Assert\Assertion; use FG\ASN1\Universal\BitString; use FG\ASN1\Universal\Integer; use FG\ASN1\Universal\NullObject; use FG\ASN1\Universal\ObjectIdentifier; use FG\ASN1\Universal\Sequence; class RsaKey extends Key { public const DATA_N = -1; public const DATA_E = -2; public const DATA_D = -3; public const DATA_P = -4; public const DATA_Q = -5; public const DATA_DP = -6; public const DATA_DQ = -7; public const DATA_QI = -8; public const DATA_OTHER = -9; public const DATA_RI = -10; public const DATA_DI = -11; public const DATA_TI = -12; public function __construct(array $data) { parent::__construct($data); Assertion::eq($data[self::TYPE], self::TYPE_RSA, 'Invalid RSA key. The key type does not correspond to a RSA key'); Assertion::keyExists($data, self::DATA_N, 'Invalid RSA key. The modulus is missing'); Assertion::keyExists($data, self::DATA_E, 'Invalid RSA key. The exponent is missing'); } public function n(): string { return $this->get(self::DATA_N); } public function e(): string { return $this->get(self::DATA_E); } public function d(): string { Assertion::true($this->isPrivate(), 'The key is not private.'); return $this->get(self::DATA_D); } public function p(): string { Assertion::true($this->isPrivate(), 'The key is not private.'); return $this->get(self::DATA_P); } public function q(): string { Assertion::true($this->isPrivate(), 'The key is not private.'); return $this->get(self::DATA_Q); } public function dP(): string { Assertion::true($this->isPrivate(), 'The key is not private.'); return $this->get(self::DATA_DP); } public function dQ(): string { Assertion::true($this->isPrivate(), 'The key is not private.'); return $this->get(self::DATA_DQ); } public function QInv(): string { Assertion::true($this->isPrivate(), 'The key is not private.'); return $this->get(self::DATA_QI); } public function other(): array { Assertion::true($this->isPrivate(), 'The key is not private.'); return $this->get(self::DATA_OTHER); } public function rI(): string { Assertion::true($this->isPrivate(), 'The key is not private.'); return $this->get(self::DATA_RI); } public function dI(): string { Assertion::true($this->isPrivate(), 'The key is not private.'); return $this->get(self::DATA_DI); } public function tI(): string { Assertion::true($this->isPrivate(), 'The key is not private.'); return $this->get(self::DATA_TI); } public function hasPrimes(): bool { return $this->has(self::DATA_P) && $this->has(self::DATA_Q); } public function primes(): array { return [ $this->p(), $this->q(), ]; } public function hasExponents(): bool { return $this->has(self::DATA_DP) && $this->has(self::DATA_DQ); } public function exponents(): array { return [ $this->dP(), $this->dQ(), ]; } public function hasCoefficient(): bool { return $this->has(self::DATA_QI); } public function isPublic(): bool { return !$this->isPrivate(); } public function isPrivate(): bool { return \array_key_exists(self::DATA_D, $this->getData()); } public function asPem(): string { Assertion::false($this->isPrivate(), 'Unsupported for private keys.'); $bitSring = new Sequence( new Integer($this->fromBase64ToInteger($this->n())), new Integer($this->fromBase64ToInteger($this->e())) ); $der = new Sequence( new Sequence( new ObjectIdentifier('1.2.840.113549.1.1.1'), new NullObject() ), new BitString(\bin2hex($bitSring->getBinary())) ); return $this->pem('PUBLIC KEY', $der->getBinary()); } private function fromBase64ToInteger(string $value): string { return gmp_strval(gmp_init(current(unpack('H*', $value)), 16), 10); } private function pem(string $type, string $der): string { return sprintf("-----BEGIN %s-----\n", mb_strtoupper($type)). chunk_split(base64_encode($der), 64, "\n"). sprintf("-----END %s-----\n", mb_strtoupper($type)); } } src/Key/Ec2Key.php 0000644 00000010420 15173124756 0007666 0 ustar 00 <?php declare(strict_types=1); /* * The MIT License (MIT) * * Copyright (c) 2014-2019 Spomky-Labs * * This software may be modified and distributed under the terms * of the MIT license. See the LICENSE file for details. */ namespace Cose\Key; use Assert\Assertion; use FG\ASN1\ExplicitlyTaggedObject; use FG\ASN1\Universal\BitString; use FG\ASN1\Universal\Integer; use FG\ASN1\Universal\ObjectIdentifier; use FG\ASN1\Universal\OctetString; use FG\ASN1\Universal\Sequence; class Ec2Key extends Key { public const CURVE_P256 = 1; public const CURVE_P256K = 8; public const CURVE_P384 = 2; public const CURVE_P521 = 3; private const SUPPORTED_CURVES = [ self::CURVE_P256, self::CURVE_P256K, self::CURVE_P384, self::CURVE_P521, ]; public const DATA_CURVE = -1; public const DATA_X = -2; public const DATA_Y = -3; public const DATA_D = -4; private const NAMED_CURVE_OID = [ self::CURVE_P256 => '1.2.840.10045.3.1.7', // NIST P-256 / secp256r1 self::CURVE_P256K => '1.3.132.0.10', // NIST P-256K / secp256k1 self::CURVE_P384 => '1.3.132.0.34', // NIST P-384 / secp384r1 self::CURVE_P521 => '1.3.132.0.35', // NIST P-521 / secp521r1 ]; private const CURVE_KEY_LENGTH = [ self::CURVE_P256 => 32, self::CURVE_P256K => 32, self::CURVE_P384 => 48, self::CURVE_P521 => 66, ]; public function __construct(array $data) { parent::__construct($data); Assertion::eq($data[self::TYPE], self::TYPE_EC2, 'Invalid EC2 key. The key type does not correspond to an EC2 key'); Assertion::keyExists($data, self::DATA_CURVE, 'Invalid EC2 key. The curve is missing'); Assertion::keyExists($data, self::DATA_X, 'Invalid EC2 key. The x coordinate is missing'); Assertion::keyExists($data, self::DATA_Y, 'Invalid EC2 key. The y coordinate is missing'); Assertion::length($data[self::DATA_X], self::CURVE_KEY_LENGTH[$data[self::DATA_CURVE]], 'Invalid length for x coordinate', null, '8bit'); Assertion::length($data[self::DATA_Y], self::CURVE_KEY_LENGTH[$data[self::DATA_CURVE]], 'Invalid length for y coordinate', null, '8bit'); Assertion::inArray((int) $data[self::DATA_CURVE], self::SUPPORTED_CURVES, 'The curve is not supported'); } public function toPublic(): self { $data = $this->getData(); unset($data[self::DATA_D]); return new self($data); } public function x(): string { return $this->get(self::DATA_X); } public function y(): string { return $this->get(self::DATA_Y); } public function isPrivate(): bool { return \array_key_exists(self::DATA_D, $this->getData()); } public function d(): string { Assertion::true($this->isPrivate(), 'The key is not private'); return $this->get(self::DATA_D); } public function curve(): int { return (int) $this->get(self::DATA_CURVE); } public function asPEM(): string { if ($this->isPrivate()) { $der = new Sequence( new Integer(1), new OctetString(bin2hex($this->d())), new ExplicitlyTaggedObject(0, new ObjectIdentifier($this->getCurveOid())), new ExplicitlyTaggedObject(1, new BitString(\bin2hex($this->getUncompressedCoordinates()))) ); return $this->pem('EC PRIVATE KEY', $der->getBinary()); } $der = new Sequence( new Sequence( new ObjectIdentifier('1.2.840.10045.2.1'), new ObjectIdentifier($this->getCurveOid()) ), new BitString(\bin2hex($this->getUncompressedCoordinates())) ); return $this->pem('PUBLIC KEY', $der->getBinary()); } private function getCurveOid(): string { return self::NAMED_CURVE_OID[$this->curve()]; } public function getUncompressedCoordinates(): string { return "\x04".$this->x().$this->y(); } private function pem(string $type, string $der): string { return sprintf("-----BEGIN %s-----\n", mb_strtoupper($type)). chunk_split(base64_encode($der), 64, "\n"). sprintf("-----END %s-----\n", mb_strtoupper($type)); } } src/Algorithms.php 0000644 00000014272 15173124756 0010176 0 ustar 00 <?php declare(strict_types=1); /* * The MIT License (MIT) * * Copyright (c) 2014-2019 Spomky-Labs * * This software may be modified and distributed under the terms * of the MIT license. See the LICENSE file for details. */ namespace Cose; use Assert\Assertion; use Cose\Algorithm\Algorithm; use Cose\Algorithm\Mac; use Cose\Algorithm\Signature\ECDSA; use Cose\Algorithm\Signature\EdDSA; use Cose\Algorithm\Signature\RSA; /** * @see https://www.iana.org/assignments/cose/cose.xhtml#algorithms */ abstract class Algorithms { public const COSE_ALGORITHM_AES_CCM_64_128_256 = 33; public const COSE_ALGORITHM_AES_CCM_64_128_128 = 32; public const COSE_ALGORITHM_AES_CCM_16_128_256 = 31; public const COSE_ALGORITHM_AES_CCM_16_128_128 = 30; public const COSE_ALGORITHM_AES_MAC_256_128 = 26; public const COSE_ALGORITHM_AES_MAC_128_128 = 25; public const COSE_ALGORITHM_CHACHA20_POLY1305 = 24; public const COSE_ALGORITHM_AES_MAC_256_64 = 15; public const COSE_ALGORITHM_AES_MAC_128_64 = 14; public const COSE_ALGORITHM_AES_CCM_64_64_256 = 13; public const COSE_ALGORITHM_AES_CCM_64_64_128 = 12; public const COSE_ALGORITHM_AES_CCM_16_64_256 = 11; public const COSE_ALGORITHM_AES_CCM_16_64_128 = 10; public const COSE_ALGORITHM_HS512 = 7; public const COSE_ALGORITHM_HS384 = 6; public const COSE_ALGORITHM_HS256 = 5; public const COSE_ALGORITHM_HS256_64 = 4; public const COSE_ALGORITHM_A256GCM = 3; public const COSE_ALGORITHM_A192GCM = 2; public const COSE_ALGORITHM_A128GCM = 1; public const COSE_ALGORITHM_A128KW = -3; public const COSE_ALGORITHM_A192KW = -4; public const COSE_ALGORITHM_A256KW = -5; public const COSE_ALGORITHM_DIRECT = -6; public const COSE_ALGORITHM_ES256 = -7; public const COSE_ALGORITHM_EdDSA = -8; public const COSE_ALGORITHM_ED256 = -260; public const COSE_ALGORITHM_ED512 = -261; public const COSE_ALGORITHM_DIRECT_HKDF_SHA_256 = -10; public const COSE_ALGORITHM_DIRECT_HKDF_SHA_512 = -11; public const COSE_ALGORITHM_DIRECT_HKDF_AES_128 = -12; public const COSE_ALGORITHM_DIRECT_HKDF_AES_256 = -13; public const COSE_ALGORITHM_ECDH_ES_HKDF_256 = -25; public const COSE_ALGORITHM_ECDH_ES_HKDF_512 = -26; public const COSE_ALGORITHM_ECDH_SS_HKDF_256 = -27; public const COSE_ALGORITHM_ECDH_SS_HKDF_512 = -28; public const COSE_ALGORITHM_ECDH_ES_A128KW = -29; public const COSE_ALGORITHM_ECDH_ES_A192KW = -30; public const COSE_ALGORITHM_ECDH_ES_A256KW = -31; public const COSE_ALGORITHM_ECDH_SS_A128KW = -32; public const COSE_ALGORITHM_ECDH_SS_A192KW = -33; public const COSE_ALGORITHM_ECDH_SS_A256KW = -34; public const COSE_ALGORITHM_ES384 = -35; public const COSE_ALGORITHM_ES512 = -36; public const COSE_ALGORITHM_PS256 = -37; public const COSE_ALGORITHM_PS384 = -38; public const COSE_ALGORITHM_PS512 = -39; public const COSE_ALGORITHM_RSAES_OAEP = -40; public const COSE_ALGORITHM_RSAES_OAEP_256 = -41; public const COSE_ALGORITHM_RSAES_OAEP_512 = -42; public const COSE_ALGORITHM_ES256K = -43; public const COSE_ALGORITHM_RS256 = -257; public const COSE_ALGORITHM_RS384 = -258; public const COSE_ALGORITHM_RS512 = -259; public const COSE_ALGORITHM_RS1 = -65535; public const COSE_ALGORITHM_MAP = [ self::COSE_ALGORITHM_ES256 => OPENSSL_ALGO_SHA256, self::COSE_ALGORITHM_ES384 => OPENSSL_ALGO_SHA384, self::COSE_ALGORITHM_ES512 => OPENSSL_ALGO_SHA512, self::COSE_ALGORITHM_RS256 => OPENSSL_ALGO_SHA256, self::COSE_ALGORITHM_RS384 => OPENSSL_ALGO_SHA384, self::COSE_ALGORITHM_RS512 => OPENSSL_ALGO_SHA512, self::COSE_ALGORITHM_RS1 => OPENSSL_ALGO_SHA1, ]; public const COSE_HASH_MAP = [ self::COSE_ALGORITHM_ES256K => 'sha256', self::COSE_ALGORITHM_ES256 => 'sha256', self::COSE_ALGORITHM_ES384 => 'sha384', self::COSE_ALGORITHM_ES512 => 'sha512', self::COSE_ALGORITHM_RS256 => 'sha256', self::COSE_ALGORITHM_RS384 => 'sha384', self::COSE_ALGORITHM_RS512 => 'sha512', self::COSE_ALGORITHM_PS256 => 'sha256', self::COSE_ALGORITHM_PS384 => 'sha384', self::COSE_ALGORITHM_PS512 => 'sha512', self::COSE_ALGORITHM_RS1 => 'sha1', ]; public static function getOpensslAlgorithmFor(int $algorithmIdentifier): int { Assertion::keyExists(self::COSE_ALGORITHM_MAP, $algorithmIdentifier, 'The specified algorithm identifier is not supported'); return self::COSE_ALGORITHM_MAP[$algorithmIdentifier]; } public static function getHashAlgorithmFor(int $algorithmIdentifier): string { Assertion::keyExists(self::COSE_HASH_MAP, $algorithmIdentifier, 'The specified algorithm identifier is not supported'); return self::COSE_HASH_MAP[$algorithmIdentifier]; } /** * @deprecated Will be removed in v3.0. Please use the Manager or the ManagerFactory */ public static function getAlgorithm(int $identifier): Algorithm { $algs = static::getAlgorithms(); Assertion::keyExists($algs, $identifier, 'The specified algorithm identifier is not supported'); return $algs[$identifier]; } /** * @deprecated Will be removed in v3.0. Please use the Manager or the ManagerFactory * * @return Algorithm[] */ public static function getAlgorithms(): array { return [ Mac\HS256::identifier() => new Mac\HS256(), Mac\HS384::identifier() => new Mac\HS384(), Mac\HS512::identifier() => new Mac\HS512(), RSA\RS256::identifier() => new RSA\RS256(), RSA\RS384::identifier() => new RSA\RS384(), RSA\RS512::identifier() => new RSA\RS512(), RSA\PS256::identifier() => new RSA\PS256(), RSA\PS384::identifier() => new RSA\PS384(), RSA\PS512::identifier() => new RSA\PS512(), ECDSA\ES256K::identifier() => new ECDSA\ES256K(), ECDSA\ES256::identifier() => new ECDSA\ES256(), ECDSA\ES384::identifier() => new ECDSA\ES384(), ECDSA\ES512::identifier() => new ECDSA\ES512(), EdDSA\ED512::identifier() => new EdDSA\ED512(), ]; } } src/Algorithm/ManagerFactory.php 0000644 00000002046 15173124756 0012711 0 ustar 00 <?php declare(strict_types=1); /* * The MIT License (MIT) * * Copyright (c) 2014-2019 Spomky-Labs * * This software may be modified and distributed under the terms * of the MIT license. See the LICENSE file for details. */ namespace Cose\Algorithm; use Assert\Assertion; class ManagerFactory { /** * @var Algorithm[] */ private $algorithms = []; public function add(string $alias, Algorithm $algorithm): void { $this->algorithms[$alias] = $algorithm; } public function list(): iterable { yield from array_keys($this->algorithms); } public function all(): iterable { yield from array_keys($this->algorithms); } public function create(array $aliases): Manager { $manager = new Manager(); foreach ($aliases as $alias) { Assertion::keyExists($this->algorithms, $alias, sprintf('The algorithm with alias "%s" is not supported', $alias)); $manager->add($this->algorithms[$alias]); } return $manager; } } src/Algorithm/Signature/ECDSA/ECSignature.php 0000644 00000010552 15173124756 0014741 0 ustar 00 <?php declare(strict_types=1); /* * The MIT License (MIT) * * Copyright (c) 2014-2019 Spomky-Labs * * This software may be modified and distributed under the terms * of the MIT license. See the LICENSE file for details. */ namespace Cose\Algorithm\Signature\ECDSA; use InvalidArgumentException; use const STR_PAD_LEFT; /** * @internal */ final class ECSignature { private const ASN1_SEQUENCE = '30'; private const ASN1_INTEGER = '02'; private const ASN1_MAX_SINGLE_BYTE = 128; private const ASN1_LENGTH_2BYTES = '81'; private const ASN1_BIG_INTEGER_LIMIT = '7f'; private const ASN1_NEGATIVE_INTEGER = '00'; private const BYTE_SIZE = 2; public static function toAsn1(string $signature, int $length): string { $signature = bin2hex($signature); if (self::octetLength($signature) !== $length) { throw new InvalidArgumentException('Invalid signature length.'); } $pointR = self::preparePositiveInteger(mb_substr($signature, 0, $length, '8bit')); $pointS = self::preparePositiveInteger(mb_substr($signature, $length, null, '8bit')); $lengthR = self::octetLength($pointR); $lengthS = self::octetLength($pointS); $totalLength = $lengthR + $lengthS + self::BYTE_SIZE + self::BYTE_SIZE; $lengthPrefix = $totalLength > self::ASN1_MAX_SINGLE_BYTE ? self::ASN1_LENGTH_2BYTES : ''; return self::hex2bin( self::ASN1_SEQUENCE .$lengthPrefix.dechex($totalLength) .self::ASN1_INTEGER.dechex($lengthR).$pointR .self::ASN1_INTEGER.dechex($lengthS).$pointS ); } public static function fromAsn1(string $signature, int $length): string { $message = bin2hex($signature); $position = 0; if (self::ASN1_SEQUENCE !== self::readAsn1Content($message, $position, self::BYTE_SIZE)) { throw new InvalidArgumentException('Invalid data. Should start with a sequence.'); } if (self::ASN1_LENGTH_2BYTES === self::readAsn1Content($message, $position, self::BYTE_SIZE)) { $position += self::BYTE_SIZE; } $pointR = self::retrievePositiveInteger(self::readAsn1Integer($message, $position)); $pointS = self::retrievePositiveInteger(self::readAsn1Integer($message, $position)); return self::hex2bin(str_pad($pointR, $length, '0', STR_PAD_LEFT).str_pad($pointS, $length, '0', STR_PAD_LEFT)); } private static function octetLength(string $data): int { return (int) (mb_strlen($data, '8bit') / self::BYTE_SIZE); } private static function preparePositiveInteger(string $data): string { if (mb_substr($data, 0, self::BYTE_SIZE, '8bit') > self::ASN1_BIG_INTEGER_LIMIT) { return self::ASN1_NEGATIVE_INTEGER.$data; } while (self::ASN1_NEGATIVE_INTEGER === mb_substr($data, 0, self::BYTE_SIZE, '8bit') && mb_substr($data, 2, self::BYTE_SIZE, '8bit') <= self::ASN1_BIG_INTEGER_LIMIT) { $data = mb_substr($data, 2, null, '8bit'); } return $data; } private static function readAsn1Content(string $message, int &$position, int $length): string { $content = mb_substr($message, $position, $length, '8bit'); $position += $length; return $content; } private static function readAsn1Integer(string $message, int &$position): string { if (self::ASN1_INTEGER !== self::readAsn1Content($message, $position, self::BYTE_SIZE)) { throw new InvalidArgumentException('Invalid data. Should contain an integer.'); } $length = (int) hexdec(self::readAsn1Content($message, $position, self::BYTE_SIZE)); return self::readAsn1Content($message, $position, $length * self::BYTE_SIZE); } private static function retrievePositiveInteger(string $data): string { while (self::ASN1_NEGATIVE_INTEGER === mb_substr($data, 0, self::BYTE_SIZE, '8bit') && mb_substr($data, 2, self::BYTE_SIZE, '8bit') > self::ASN1_BIG_INTEGER_LIMIT) { $data = mb_substr($data, 2, null, '8bit'); } return $data; } private static function hex2bin(string $data): string { $result = \hex2bin($data); if (false === $result) { throw new InvalidArgumentException('Unable to convert the data'); } return $result; } } src/Algorithm/Signature/ECDSA/ECDSA.php 0000644 00000003057 15173124756 0013411 0 ustar 00 <?php declare(strict_types=1); /* * The MIT License (MIT) * * Copyright (c) 2014-2019 Spomky-Labs * * This software may be modified and distributed under the terms * of the MIT license. See the LICENSE file for details. */ namespace Cose\Algorithm\Signature\ECDSA; use Assert\Assertion; use Cose\Algorithm\Signature\Signature; use Cose\Key\Ec2Key; use Cose\Key\Key; abstract class ECDSA implements Signature { public function __construct() { if (!method_exists($this, 'getSignaturePartLength')) { @trigger_error('The method "getSignaturePartLength" is needed since 2.1 and will be mandatory in v3.0', E_USER_DEPRECATED); } } public function sign(string $data, Key $key): string { $key = $this->handleKey($key); $result = openssl_sign($data, $signature, $key->asPEM(), $this->getHashAlgorithm()); Assertion::true($result, 'Unable to sign the data'); return $signature; } public function verify(string $data, Key $key, string $signature): bool { $key = $this->handleKey($key); $publicKey = $key->toPublic(); return 1 === openssl_verify($data, $signature, $publicKey->asPEM(), $this->getHashAlgorithm()); } private function handleKey(Key $key): Ec2Key { $key = new Ec2Key($key->getData()); Assertion::eq($key->curve(), $this->getCurve(), 'This key cannot be used with this algorithm'); return $key; } abstract protected function getCurve(): int; abstract protected function getHashAlgorithm(): int; } src/Algorithm/Signature/ECDSA/ES512.php 0000644 00000002661 15173124756 0013331 0 ustar 00 <?php declare(strict_types=1); /* * The MIT License (MIT) * * Copyright (c) 2014-2019 Spomky-Labs * * This software may be modified and distributed under the terms * of the MIT license. See the LICENSE file for details. */ namespace Cose\Algorithm\Signature\ECDSA; use Cose\Key\Ec2Key; use Cose\Key\Key; final class ES512 extends ECDSA { public const ID = -36; public static function identifier(): int { return self::ID; } public function sign(string $data, Key $key): string { $signature = parent::sign($data, $key); return ECSignature::fromAsn1($signature, $this->getSignaturePartLength()); } public function verify(string $data, Key $key, string $signature): bool { if (mb_strlen($signature, '8bit') !== $this->getSignaturePartLength()) { @trigger_error('Since v2.1, the method "verify" accepts ASN.1 structures and raw ECDSA signature. In v3.0 and ASN.1 structures will be rejected', E_USER_DEPRECATED); } else { $signature = ECSignature::toAsn1($signature, $this->getSignaturePartLength()); } return parent::verify($data, $key, $signature); } protected function getHashAlgorithm(): int { return OPENSSL_ALGO_SHA512; } protected function getCurve(): int { return Ec2Key::CURVE_P521; } protected function getSignaturePartLength(): int { return 132; } } src/Algorithm/Signature/ECDSA/ES256.php 0000644 00000002642 15173124756 0013335 0 ustar 00 <?php declare(strict_types=1); /* * The MIT License (MIT) * * Copyright (c) 2014-2019 Spomky-Labs * * This software may be modified and distributed under the terms * of the MIT license. See the LICENSE file for details. */ namespace Cose\Algorithm\Signature\ECDSA; use Cose\Key\Ec2Key; use Cose\Key\Key; final class ES256 extends ECDSA { public const ID = -7; public static function identifier(): int { return self::ID; } public function sign(string $data, Key $key): string { $signature = parent::sign($data, $key); return ECSignature::fromAsn1($signature, $this->getSignaturePartLength()); } public function verify(string $data, Key $key, string $signature): bool { if (mb_strlen($signature, '8bit') !== $this->getSignaturePartLength()) { @trigger_error('Since v2.1, the method "verify" will only accept raw ECDSA signature in v3.0 and ASN.1 structures will be rejected', E_USER_DEPRECATED); } else { $signature = ECSignature::toAsn1($signature, $this->getSignaturePartLength()); } return parent::verify($data, $key, $signature); } protected function getHashAlgorithm(): int { return OPENSSL_ALGO_SHA256; } protected function getCurve(): int { return Ec2Key::CURVE_P256; } protected function getSignaturePartLength(): int { return 64; } } src/Algorithm/Signature/ECDSA/ES384.php 0000644 00000002643 15173124756 0013340 0 ustar 00 <?php declare(strict_types=1); /* * The MIT License (MIT) * * Copyright (c) 2014-2019 Spomky-Labs * * This software may be modified and distributed under the terms * of the MIT license. See the LICENSE file for details. */ namespace Cose\Algorithm\Signature\ECDSA; use Cose\Key\Ec2Key; use Cose\Key\Key; final class ES384 extends ECDSA { public const ID = -35; public static function identifier(): int { return self::ID; } public function sign(string $data, Key $key): string { $signature = parent::sign($data, $key); return ECSignature::fromAsn1($signature, $this->getSignaturePartLength()); } public function verify(string $data, Key $key, string $signature): bool { if (mb_strlen($signature, '8bit') !== $this->getSignaturePartLength()) { @trigger_error('Since v2.1, the method "verify" will only accept raw ECDSA signature in v3.0 and ASN.1 structures will be rejected', E_USER_DEPRECATED); } else { $signature = ECSignature::toAsn1($signature, $this->getSignaturePartLength()); } return parent::verify($data, $key, $signature); } protected function getHashAlgorithm(): int { return OPENSSL_ALGO_SHA384; } protected function getCurve(): int { return Ec2Key::CURVE_P384; } protected function getSignaturePartLength(): int { return 96; } } src/Algorithm/Signature/ECDSA/ES256K.php 0000644 00000002645 15173124756 0013453 0 ustar 00 <?php declare(strict_types=1); /* * The MIT License (MIT) * * Copyright (c) 2014-2019 Spomky-Labs * * This software may be modified and distributed under the terms * of the MIT license. See the LICENSE file for details. */ namespace Cose\Algorithm\Signature\ECDSA; use Cose\Key\Ec2Key; use Cose\Key\Key; final class ES256K extends ECDSA { public const ID = -43; public static function identifier(): int { return self::ID; } public function sign(string $data, Key $key): string { $signature = parent::sign($data, $key); return ECSignature::fromAsn1($signature, $this->getSignaturePartLength()); } public function verify(string $data, Key $key, string $signature): bool { if (mb_strlen($signature, '8bit') !== $this->getSignaturePartLength()) { @trigger_error('Since v2.1, the method "verify" will only accept raw ECDSA signature in v3.0 and ASN.1 structures will be rejected', E_USER_DEPRECATED); } else { $signature = ECSignature::toAsn1($signature, $this->getSignaturePartLength()); } return parent::verify($data, $key, $signature); } protected function getHashAlgorithm(): int { return OPENSSL_ALGO_SHA256; } protected function getCurve(): int { return Ec2Key::CURVE_P256K; } protected function getSignaturePartLength(): int { return 64; } } src/Algorithm/Signature/RSA/PSSRSA.php 0000644 00000013601 15173124756 0013407 0 ustar 00 <?php declare(strict_types=1); /* * The MIT License (MIT) * * Copyright (c) 2014-2019 Spomky-Labs * * This software may be modified and distributed under the terms * of the MIT license. See the LICENSE file for details. */ namespace Cose\Algorithm\Signature\RSA; use function ceil; use Cose\Algorithm\Signature\Signature; use Cose\Key\Key; use Cose\Key\RsaKey; use function hash_equals; use InvalidArgumentException; use Jose\Component\Core\Util\BigInteger; use Jose\Component\Core\Util\Hash; use function mb_strlen; use function mb_substr; use function pack; use function random_bytes; use RuntimeException; use function str_pad; use function str_repeat; /** * @internal */ abstract class PSSRSA implements Signature { public function sign(string $data, Key $key): string { $key = $this->handleKey($key); $modulusLength = mb_strlen($key->n(), '8bit'); $em = $this->encodeEMSAPSS($data, 8 * $modulusLength - 1, $this->getHashAlgorithm()); $message = BigInteger::createFromBinaryString($em); $signature = $this->exponentiate($key, $message); return $this->convertIntegerToOctetString($signature, $modulusLength); } public function verify(string $data, Key $key, string $signature): bool { $key = $this->handleKey($key); $modulusLength = mb_strlen($key->n(), '8bit'); if (mb_strlen($signature, '8bit') !== $modulusLength) { throw new InvalidArgumentException('Invalid modulus length'); } $s2 = BigInteger::createFromBinaryString($signature); $m2 = $this->exponentiate($key, $s2); $em = $this->convertIntegerToOctetString($m2, $modulusLength); $modBits = 8 * $modulusLength; return $this->verifyEMSAPSS($data, $em, $modBits - 1, $this->getHashAlgorithm()); } private function handleKey(Key $key): RsaKey { return new RsaKey($key->getData()); } abstract protected function getHashAlgorithm(): Hash; private function convertIntegerToOctetString(BigInteger $x, int $xLen): string { $x = $x->toBytes(); if (mb_strlen($x, '8bit') > $xLen) { throw new RuntimeException('Unable to convert the integer'); } return str_pad($x, $xLen, \chr(0), STR_PAD_LEFT); } /** * MGF1. */ private function getMGF1(string $mgfSeed, int $maskLen, Hash $mgfHash): string { $t = ''; $count = ceil($maskLen / $mgfHash->getLength()); for ($i = 0; $i < $count; ++$i) { $c = pack('N', $i); $t .= $mgfHash->hash($mgfSeed.$c); } return mb_substr($t, 0, $maskLen, '8bit'); } /** * EMSA-PSS-ENCODE. */ private function encodeEMSAPSS(string $message, int $modulusLength, Hash $hash): string { $emLen = ($modulusLength + 1) >> 3; $sLen = $hash->getLength(); $mHash = $hash->hash($message); if ($emLen <= $hash->getLength() + $sLen + 2) { throw new RuntimeException(); } $salt = random_bytes($sLen); $m2 = "\0\0\0\0\0\0\0\0".$mHash.$salt; $h = $hash->hash($m2); $ps = str_repeat(\chr(0), $emLen - $sLen - $hash->getLength() - 2); $db = $ps.\chr(1).$salt; $dbMask = $this->getMGF1($h, $emLen - $hash->getLength() - 1, $hash); $maskedDB = $db ^ $dbMask; $maskedDB[0] = ~\chr(0xFF << ($modulusLength & 7)) & $maskedDB[0]; return $maskedDB.$h.\chr(0xBC); } /** * EMSA-PSS-VERIFY. */ private function verifyEMSAPSS(string $m, string $em, int $emBits, Hash $hash): bool { $emLen = ($emBits + 1) >> 3; $sLen = $hash->getLength(); $mHash = $hash->hash($m); if ($emLen < $hash->getLength() + $sLen + 2) { throw new InvalidArgumentException(); } if ($em[mb_strlen($em, '8bit') - 1] !== \chr(0xBC)) { throw new InvalidArgumentException(); } $maskedDB = mb_substr($em, 0, -$hash->getLength() - 1, '8bit'); $h = mb_substr($em, -$hash->getLength() - 1, $hash->getLength(), '8bit'); $temp = \chr(0xFF << ($emBits & 7)); if ((~$maskedDB[0] & $temp) !== $temp) { throw new InvalidArgumentException(); } $dbMask = $this->getMGF1($h, $emLen - $hash->getLength() - 1, $hash/*MGF*/); $db = $maskedDB ^ $dbMask; $db[0] = ~\chr(0xFF << ($emBits & 7)) & $db[0]; $temp = $emLen - $hash->getLength() - $sLen - 2; if (mb_substr($db, 0, $temp, '8bit') !== str_repeat(\chr(0), $temp)) { throw new InvalidArgumentException(); } if (1 !== \ord($db[$temp])) { throw new InvalidArgumentException(); } $salt = mb_substr($db, $temp + 1, null, '8bit'); // should be $sLen long $m2 = "\0\0\0\0\0\0\0\0".$mHash.$salt; $h2 = $hash->hash($m2); return hash_equals($h, $h2); } /** * Exponentiate with or without Chinese Remainder Theorem. * Operation with primes 'p' and 'q' is appox. 2x faster. */ public function exponentiate(RsaKey $key, BigInteger $c): BigInteger { if ($c->compare(BigInteger::createFromDecimal(0)) < 0 || $c->compare(BigInteger::createFromBinaryString($key->n())) > 0) { throw new RuntimeException(); } if ($key->isPublic() || !$key->hasPrimes() || !$key->hasExponents() || !$key->hasCoefficient()) { return $c->modPow(BigInteger::createFromBinaryString($key->e()), BigInteger::createFromBinaryString($key->n())); } $p = $key->primes()[0]; $q = $key->primes()[1]; $dP = $key->exponents()[0]; $dQ = $key->exponents()[1]; $qInv = BigInteger::createFromBinaryString($key->QInv()); $m1 = $c->modPow($dP, $p); $m2 = $c->modPow($dQ, $q); $h = $qInv->multiply($m1->subtract($m2)->add($p))->mod($p); return $m2->add($h->multiply($q)); } } src/Algorithm/Signature/RSA/PS512.php 0000644 00000001046 15173124756 0013146 0 ustar 00 <?php declare(strict_types=1); /* * The MIT License (MIT) * * Copyright (c) 2014-2019 Spomky-Labs * * This software may be modified and distributed under the terms * of the MIT license. See the LICENSE file for details. */ namespace Cose\Algorithm\Signature\RSA; use Jose\Component\Core\Util\Hash; final class PS512 extends PSSRSA { public const ID = -39; public static function identifier(): int { return self::ID; } protected function getHashAlgorithm(): Hash { return Hash::sha512(); } } src/Algorithm/Signature/RSA/RS384.php 0000644 00000001004 15173124756 0013151 0 ustar 00 <?php declare(strict_types=1); /* * The MIT License (MIT) * * Copyright (c) 2014-2019 Spomky-Labs * * This software may be modified and distributed under the terms * of the MIT license. See the LICENSE file for details. */ namespace Cose\Algorithm\Signature\RSA; final class RS384 extends RSA { public const ID = -258; public static function identifier(): int { return self::ID; } protected function getHashAlgorithm(): int { return OPENSSL_ALGO_SHA384; } } src/Algorithm/Signature/RSA/PS256.php 0000644 00000001046 15173124756 0013153 0 ustar 00 <?php declare(strict_types=1); /* * The MIT License (MIT) * * Copyright (c) 2014-2019 Spomky-Labs * * This software may be modified and distributed under the terms * of the MIT license. See the LICENSE file for details. */ namespace Cose\Algorithm\Signature\RSA; use Jose\Component\Core\Util\Hash; final class PS256 extends PSSRSA { public const ID = -37; public static function identifier(): int { return self::ID; } protected function getHashAlgorithm(): Hash { return Hash::sha256(); } } src/Algorithm/Signature/RSA/RS1.php 0000644 00000001002 15173124756 0012771 0 ustar 00 <?php declare(strict_types=1); /* * The MIT License (MIT) * * Copyright (c) 2014-2019 Spomky-Labs * * This software may be modified and distributed under the terms * of the MIT license. See the LICENSE file for details. */ namespace Cose\Algorithm\Signature\RSA; final class RS1 extends RSA { public const ID = -65535; public static function identifier(): int { return self::ID; } protected function getHashAlgorithm(): int { return OPENSSL_ALGO_SHA1; } } src/Algorithm/Signature/RSA/RS512.php 0000644 00000001004 15173124756 0013142 0 ustar 00 <?php declare(strict_types=1); /* * The MIT License (MIT) * * Copyright (c) 2014-2019 Spomky-Labs * * This software may be modified and distributed under the terms * of the MIT license. See the LICENSE file for details. */ namespace Cose\Algorithm\Signature\RSA; final class RS512 extends RSA { public const ID = -259; public static function identifier(): int { return self::ID; } protected function getHashAlgorithm(): int { return OPENSSL_ALGO_SHA512; } } src/Algorithm/Signature/RSA/RS256.php 0000644 00000001004 15173124756 0013147 0 ustar 00 <?php declare(strict_types=1); /* * The MIT License (MIT) * * Copyright (c) 2014-2019 Spomky-Labs * * This software may be modified and distributed under the terms * of the MIT license. See the LICENSE file for details. */ namespace Cose\Algorithm\Signature\RSA; final class RS256 extends RSA { public const ID = -257; public static function identifier(): int { return self::ID; } protected function getHashAlgorithm(): int { return OPENSSL_ALGO_SHA256; } } src/Algorithm/Signature/RSA/PS384.php 0000644 00000001046 15173124756 0013155 0 ustar 00 <?php declare(strict_types=1); /* * The MIT License (MIT) * * Copyright (c) 2014-2019 Spomky-Labs * * This software may be modified and distributed under the terms * of the MIT license. See the LICENSE file for details. */ namespace Cose\Algorithm\Signature\RSA; use Jose\Component\Core\Util\Hash; final class PS384 extends PSSRSA { public const ID = -38; public static function identifier(): int { return self::ID; } protected function getHashAlgorithm(): Hash { return Hash::sha384(); } } src/Algorithm/Signature/RSA/RSA.php 0000644 00000002225 15173124756 0013021 0 ustar 00 <?php declare(strict_types=1); /* * The MIT License (MIT) * * Copyright (c) 2014-2019 Spomky-Labs * * This software may be modified and distributed under the terms * of the MIT license. See the LICENSE file for details. */ namespace Cose\Algorithm\Signature\RSA; use Assert\Assertion; use Cose\Algorithm\Signature\Signature; use Cose\Key\Key; use Cose\Key\RsaKey; abstract class RSA implements Signature { public function sign(string $data, Key $key): string { $key = $this->handleKey($key); Assertion::true($key->isPrivate(), 'The key is not private'); $result = openssl_sign($data, $signature, $key->asPem(), $this->getHashAlgorithm()); Assertion::true($result, 'Unable to sign the data'); return $signature; } public function verify(string $data, Key $key, string $signature): bool { $key = $this->handleKey($key); return 1 === openssl_verify($data, $signature, $key->asPem(), $this->getHashAlgorithm()); } private function handleKey(Key $key): RsaKey { return new RsaKey($key->getData()); } abstract protected function getHashAlgorithm(): int; } src/Algorithm/Signature/Signature.php 0000644 00000000762 15173124756 0013714 0 ustar 00 <?php declare(strict_types=1); /* * The MIT License (MIT) * * Copyright (c) 2014-2019 Spomky-Labs * * This software may be modified and distributed under the terms * of the MIT license. See the LICENSE file for details. */ namespace Cose\Algorithm\Signature; use Cose\Algorithm\Algorithm; use Cose\Key\Key; interface Signature extends Algorithm { public function sign(string $data, Key $key): string; public function verify(string $data, Key $key, string $signature): bool; } src/Algorithm/Signature/EdDSA/Ed25519.php 0000644 00000000650 15173124756 0013565 0 ustar 00 <?php declare(strict_types=1); /* * The MIT License (MIT) * * Copyright (c) 2014-2019 Spomky-Labs * * This software may be modified and distributed under the terms * of the MIT license. See the LICENSE file for details. */ namespace Cose\Algorithm\Signature\EdDSA; final class Ed25519 extends EdDSA { public const ID = -8; public static function identifier(): int { return self::ID; } } src/Algorithm/Signature/EdDSA/ED256.php 0000644 00000001460 15173124756 0013354 0 ustar 00 <?php declare(strict_types=1); /* * The MIT License (MIT) * * Copyright (c) 2014-2019 Spomky-Labs * * This software may be modified and distributed under the terms * of the MIT license. See the LICENSE file for details. */ namespace Cose\Algorithm\Signature\EdDSA; use Cose\Key\Key; final class ED256 extends EdDSA { public const ID = -260; public static function identifier(): int { return self::ID; } public function sign(string $data, Key $key): string { $hashedData = hash('sha256', $data, true); return parent::sign($hashedData, $key); } public function verify(string $data, Key $key, string $signature): bool { $hashedData = hash('sha256', $data, true); return parent::verify($hashedData, $key, $signature); } } src/Algorithm/Signature/EdDSA/ED512.php 0000644 00000001460 15173124756 0013347 0 ustar 00 <?php declare(strict_types=1); /* * The MIT License (MIT) * * Copyright (c) 2014-2019 Spomky-Labs * * This software may be modified and distributed under the terms * of the MIT license. See the LICENSE file for details. */ namespace Cose\Algorithm\Signature\EdDSA; use Cose\Key\Key; final class ED512 extends EdDSA { public const ID = -261; public static function identifier(): int { return self::ID; } public function sign(string $data, Key $key): string { $hashedData = hash('sha512', $data, true); return parent::sign($hashedData, $key); } public function verify(string $data, Key $key, string $signature): bool { $hashedData = hash('sha512', $data, true); return parent::verify($hashedData, $key, $signature); } } src/Algorithm/Signature/EdDSA/EdDSA.php 0000644 00000003200 15173124756 0013501 0 ustar 00 <?php declare(strict_types=1); /* * The MIT License (MIT) * * Copyright (c) 2014-2019 Spomky-Labs * * This software may be modified and distributed under the terms * of the MIT license. See the LICENSE file for details. */ namespace Cose\Algorithm\Signature\EdDSA; use Assert\Assertion; use Cose\Algorithm\Signature\Signature; use Cose\Algorithms; use Cose\Key\Key; use Cose\Key\OkpKey; use InvalidArgumentException; use function sodium_crypto_sign_detached; use function sodium_crypto_sign_verify_detached; class EdDSA implements Signature { public function sign(string $data, Key $key): string { $key = $this->handleKey($key); Assertion::true($key->isPrivate(), 'The key is not private'); $x = $key->x(); $d = $key->d(); $secret = $d.$x; switch ($key->curve()) { case OkpKey::CURVE_ED25519: return sodium_crypto_sign_detached($data, $secret); default: throw new InvalidArgumentException('Unsupported curve'); } } public function verify(string $data, Key $key, string $signature): bool { $key = $this->handleKey($key); switch ($key->curve()) { case OkpKey::CURVE_ED25519: return sodium_crypto_sign_verify_detached($signature, $data, $key->x()); default: throw new InvalidArgumentException('Unsupported curve'); } } public static function identifier(): int { return Algorithms::COSE_ALGORITHM_EdDSA; } private function handleKey(Key $key): OkpKey { return new OkpKey($key->getData()); } } src/Algorithm/Manager.php 0000644 00000002360 15173124756 0011360 0 ustar 00 <?php declare(strict_types=1); /* * The MIT License (MIT) * * Copyright (c) 2014-2019 Spomky-Labs * * This software may be modified and distributed under the terms * of the MIT license. See the LICENSE file for details. */ namespace Cose\Algorithm; use Assert\Assertion; class Manager { /** * @var Algorithm[] */ private $algorithms = []; public function add(Algorithm $algorithm): void { $identifier = $algorithm::identifier(); $this->algorithms[$identifier] = $algorithm; } /** * @deprecated Will be removed in v3.0. Please use all() instead */ public function getAlgorithms(): iterable { yield from $this->algorithms; } public function list(): iterable { yield from array_keys($this->algorithms); } /** * @return Algorithm[] */ public function all(): iterable { yield from $this->algorithms; } public function has(int $identifier): bool { return \array_key_exists($identifier, $this->algorithms); } public function get(int $identifier): Algorithm { Assertion::true($this->has($identifier), 'Unsupported algorithm'); return $this->algorithms[$identifier]; } } src/Algorithm/Algorithm.php 0000644 00000000513 15173124756 0011732 0 ustar 00 <?php declare(strict_types=1); /* * The MIT License (MIT) * * Copyright (c) 2014-2019 Spomky-Labs * * This software may be modified and distributed under the terms * of the MIT license. See the LICENSE file for details. */ namespace Cose\Algorithm; interface Algorithm { public static function identifier(): int; } src/Algorithm/Mac/HS384.php 0000644 00000001102 15173124756 0011250 0 ustar 00 <?php declare(strict_types=1); /* * The MIT License (MIT) * * Copyright (c) 2014-2019 Spomky-Labs * * This software may be modified and distributed under the terms * of the MIT license. See the LICENSE file for details. */ namespace Cose\Algorithm\Mac; final class HS384 extends Hmac { public const ID = 6; public static function identifier(): int { return self::ID; } protected function getHashAlgorithm(): string { return 'sha384'; } protected function getSignatureLength(): int { return 384; } } src/Algorithm/Mac/Hmac.php 0000644 00000002136 15173124756 0011357 0 ustar 00 <?php declare(strict_types=1); /* * The MIT License (MIT) * * Copyright (c) 2014-2019 Spomky-Labs * * This software may be modified and distributed under the terms * of the MIT license. See the LICENSE file for details. */ namespace Cose\Algorithm\Mac; use Assert\Assertion; use Cose\Key\Key; abstract class Hmac implements Mac { public function hash(string $data, Key $key): string { $this->checKey($key); $signature = hash_hmac($this->getHashAlgorithm(), $data, $key->get(-1), true); return mb_substr($signature, 0, $this->getSignatureLength() / 8, '8bit'); } public function verify(string $data, Key $key, string $signature): bool { return hash_equals($this->hash($data, $key), $signature); } private function checKey(Key $key): void { Assertion::eq($key->type(), 4, 'Invalid key. Must be of type symmetric'); Assertion::true($key->has(-1), 'Invalid key. The value of the key is missing'); } abstract protected function getHashAlgorithm(): string; abstract protected function getSignatureLength(): int; } src/Algorithm/Mac/HS512.php 0000644 00000001102 15173124756 0011241 0 ustar 00 <?php declare(strict_types=1); /* * The MIT License (MIT) * * Copyright (c) 2014-2019 Spomky-Labs * * This software may be modified and distributed under the terms * of the MIT license. See the LICENSE file for details. */ namespace Cose\Algorithm\Mac; final class HS512 extends Hmac { public const ID = 7; public static function identifier(): int { return self::ID; } protected function getHashAlgorithm(): string { return 'sha512'; } protected function getSignatureLength(): int { return 512; } } src/Algorithm/Mac/Mac.php 0000644 00000000746 15173124756 0011214 0 ustar 00 <?php declare(strict_types=1); /* * The MIT License (MIT) * * Copyright (c) 2014-2019 Spomky-Labs * * This software may be modified and distributed under the terms * of the MIT license. See the LICENSE file for details. */ namespace Cose\Algorithm\Mac; use Cose\Algorithm\Algorithm; use Cose\Key\Key; interface Mac extends Algorithm { public function hash(string $data, Key $key): string; public function verify(string $data, Key $key, string $signature): bool; } src/Algorithm/Mac/HS256.php 0000644 00000001102 15173124756 0011246 0 ustar 00 <?php declare(strict_types=1); /* * The MIT License (MIT) * * Copyright (c) 2014-2019 Spomky-Labs * * This software may be modified and distributed under the terms * of the MIT license. See the LICENSE file for details. */ namespace Cose\Algorithm\Mac; final class HS256 extends Hmac { public const ID = 5; public static function identifier(): int { return self::ID; } protected function getHashAlgorithm(): string { return 'sha256'; } protected function getSignatureLength(): int { return 256; } } src/Algorithm/Mac/HS256Truncated64.php 0000644 00000001114 15173124756 0013275 0 ustar 00 <?php declare(strict_types=1); /* * The MIT License (MIT) * * Copyright (c) 2014-2019 Spomky-Labs * * This software may be modified and distributed under the terms * of the MIT license. See the LICENSE file for details. */ namespace Cose\Algorithm\Mac; final class HS256Truncated64 extends Hmac { public const ID = 4; public static function identifier(): int { return self::ID; } protected function getHashAlgorithm(): string { return 'sha256'; } protected function getSignatureLength(): int { return 64; } } LICENSE 0000644 00000002054 15173124756 0005565 0 ustar 00 MIT License Copyright (c) 2018 Spomky-Labs Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
| ver. 1.4 |
Github
|
.
| PHP 8.3.23 | Generation time: 0 |
proxy
|
phpinfo
|
Settings