/** * @param string $original_alg * @return bool * @throws InvalidJWKAlgorithm * @throws JWSInvalidJWKException * @throws JWSInvalidPayloadException * @throws JWSNotSupportedAlgorithm */ public function verify($original_alg) { if (is_null($this->jwk)) { throw new JWSInvalidJWKException(); } if ($this->jwk->getKeyUse()->getString() !== JSONWebKeyPublicKeyUseValues::Signature) { throw new JWSInvalidJWKException(sprintf('use %s not supported ', $this->jwk->getKeyUse()->getString())); } if (is_null($this->jwk->getAlgorithm())) { throw new InvalidJWKAlgorithm('algorithm intended for use with the key is not set! '); } if (!is_null($this->jwk->getId()) && !is_null($this->header->getKeyID()) && $this->header->getKeyID()->getValue() != $this->jwk->getId()->getValue()) { throw new JWSInvalidJWKException(sprintf('original kid %s - current kid %s', $this->header->getKeyID()->getValue(), $this->jwk->getId()->getValue())); } $alg = DigitalSignatures_MACs_Registry::getInstance()->get($original_alg); if (is_null($alg)) { throw new JWSNotSupportedAlgorithm(sprintf('algo %s', $original_alg)); } $former_alg = $this->header->getAlgorithm()->getString(); if ($former_alg != $original_alg) { throw new JWSNotSupportedAlgorithm(sprintf('former alg %s - original alg %s', $former_alg, $original_alg)); } if ($this->jwk->getAlgorithm()->getValue() !== $original_alg) { throw new InvalidJWKAlgorithm(sprintf('mismatch between algorithm intended for use with the key %s and the cryptographic algorithm used to secure the JWS %s', $this->jwk->getAlgorithm()->getValue(), $original_alg)); } $secured_input_bytes = JOSEHeaderSerializer::serialize($this->header) . IBasicJWT::SegmentSeparator . $this->getEncodedPayload(); // use public key / secret $key = $this->jwk->getKey(JSONWebKeyKeyOperationsValues::VerifyDigitalSignatureOrMAC); return $alg->verify($key, $secured_input_bytes, $this->signature); }
/** * @param EncryptionAlgorithm $alg * @return null|Key * @throws JWEInvalidCompactFormatException * @throws InvalidKeyTypeAlgorithmException * @throws \Exception */ private function decryptJWEEncryptedKey(EncryptionAlgorithm $alg) { $key_management_mode = $this->getKeyManagementMode($alg); $recipient_private_key = $this->jwk->getKey(JSONWebKeyKeyOperationsValues::DecryptContentAndValidateDecryption); if ($alg->getKeyType() !== $recipient_private_key->getAlgorithm()) { throw new InvalidKeyTypeAlgorithmException(sprintf('key should be for alg %s, %s instead.', $alg->getKeyType(), $recipient_private_key->getAlgorithm())); } switch ($key_management_mode) { /** * When Key Wrapping, Key Encryption, or Key Agreement with Key * Wrapping are employed, decrypt the JWE Encrypted Key to produce * the CEK. The CEK MUST have a length equal to that required for * the content encryption algorithm */ case KeyManagementModeValues::KeyEncryption: case KeyManagementModeValues::KeyWrapping: case KeyManagementModeValues::KeyAgreementWithKeyWrapping: return ContentEncryptionKeyFactory::fromRaw($alg->decrypt($recipient_private_key, $this->enc_cek), $alg); break; /** * When Direct Key Agreement or Direct Encryption are employed, * verify that the JWE Encrypted Key value is an empty octetsequence. * When Direct Encryption is employed, let the CEK be the shared * symmetric key. */ /** * When Direct Key Agreement or Direct Encryption are employed, * verify that the JWE Encrypted Key value is an empty octetsequence. * When Direct Encryption is employed, let the CEK be the shared * symmetric key. */ case KeyManagementModeValues::DirectEncryption: if (!empty($this->enc_cek)) { throw new JWEInvalidCompactFormatException('JWE Encrypted Key value is not an empty octetsequence.'); } return $recipient_private_key; break; case KeyManagementModeValues::DirectKeyAgreement: if (!empty($this->enc_cek)) { throw new JWEInvalidCompactFormatException('JWE Encrypted Key value is not an empty octetsequence.'); } throw new \Exception('unsupported Key Management Mode!'); break; } return null; }