Esempio n. 1
0
 /**
  * @param string $input
  * @return array
  * @throws InvalidJWTException
  */
 public static function deserialize($input)
 {
     $e_parts = explode(IBasicJWT::SegmentSeparator, $input);
     if (count($e_parts) < 2) {
         throw new InvalidJWTException(sprintf('%s has only 2 or less encoded parts!'));
     }
     $e_header = $e_parts[0];
     $e_payload = $e_parts[1];
     $e_signature = count($e_parts) > 2 ? $e_parts[2] : '';
     $header = JOSEHeaderSerializer::deserialize($e_header);
     $payload = $header->getType()->getString() === 'JWT' ? JWTClaimSetSerializer::deserialize($e_payload) : JWTRawSerializer::deserialize($e_payload);
     $signature = !empty($e_signature) ? JWTRawSerializer::deserialize($e_signature) : '';
     return array($header, $payload, $signature);
 }
Esempio n. 2
0
 /**
  * https://tools.ietf.org/html/rfc7516#section-9
  * @param string $compact_serialization
  * @return IBasicJWT
  * @throws InvalidJWKType
  * @throws InvalidCompactSerializationException
  */
 public static function build($compact_serialization)
 {
     $segments = explode(IBasicJWT::SegmentSeparator, $compact_serialization);
     // JWSs have three segments separated by two period ('.') characters.
     // JWEs have five segments separated by four period ('.') characters.
     switch (count($segments)) {
         case 3:
             // JWS or unsecured one
             $header = JOSEHeaderSerializer::deserialize($segments[0]);
             if ($header->getAlgorithm()->getString() === 'none' && empty($segments[2])) {
                 return UnsecuredJWT::fromCompactSerialization($compact_serialization);
             }
             return JWSFactory::build(new JWS_CompactFormatSpecification($compact_serialization));
             break;
         case 5:
             // JWE
             return JWEFactory::build(new JWE_CompactFormatSpecification($compact_serialization));
             break;
         default:
             throw new InvalidCompactSerializationException();
             break;
     }
     return null;
 }
Esempio n. 3
0
 /**
  * @return $this
  * @throws InvalidJWKAlgorithm
  * @throws InvalidKeyTypeAlgorithmException
  * @throws JWEInvalidCompactFormatException
  * @throws JWEInvalidRecipientKeyException
  * @throws JWEUnsupportedContentEncryptionAlgorithmException
  * @throws JWEUnsupportedKeyManagementAlgorithmException
  * @throws \Exception
  */
 private function decrypt()
 {
     if (is_null($this->jwk)) {
         throw new JWEInvalidRecipientKeyException();
     }
     if (!$this->should_decrypt) {
         return $this;
     }
     if ($this->jwk->getAlgorithm()->getValue() !== $this->header->getAlgorithm()->getString()) {
         throw new InvalidJWKAlgorithm(sprintf('mismatch between algorithm intended for use with the key %s and the cryptographic algorithm used to encrypt or determine the value of the CEK %s', $this->jwk->getAlgorithm()->getValue(), $this->header->getAlgorithm()->getString()));
     }
     $key_management_algorithm = KeyManagementAlgorithms_Registry::getInstance()->get($this->header->getAlgorithm()->getString());
     if (is_null($key_management_algorithm)) {
         throw new JWEUnsupportedKeyManagementAlgorithmException(sprintf('alg %s', $this->header->getAlgorithm()->getString()));
     }
     $content_encryption_algorithm = ContentEncryptionAlgorithms_Registry::getInstance()->get($this->header->getEncryptionAlgorithm()->getString());
     if (is_null($content_encryption_algorithm)) {
         throw new JWEUnsupportedContentEncryptionAlgorithmException(sprintf('enc %s', $this->header->getEncryptionAlgorithm()->getString()));
     }
     $this->cek = $this->decryptJWEEncryptedKey($key_management_algorithm);
     // We encrypt the payload and get the tag
     $jwt_shared_protected_header = JOSEHeaderSerializer::serialize($this->header);
     /**
      * Decrypt the JWE Cipher Text using the CEK, the JWE Initialization
      * Vector, the Additional Authenticated Data value, and the JWE
      * Authentication Tag (which is the Authentication Tag input to the
      * calculation) using the specified content encryption algorithm,
      * returning the decrypted plaintext and validating the JWE
      * Authentication Tag in the manner specified for the algorithm,
      * rejecting the input without emitting any decrypted output if the
      * JWE Authentication Tag is incorrect.
      */
     $plain_text = $content_encryption_algorithm->decrypt($this->cipher_text, $this->cek->getEncoded(), $this->iv, $jwt_shared_protected_header, $this->tag);
     $zip = $this->header->getCompressionAlgorithm();
     /**
      * If a "zip" parameter was included, uncompress the decrypted
      * plaintext using the specified compression algorithm.
      */
     if (!is_null($zip)) {
         $compression__algorithm = CompressionAlgorithms_Registry::getInstance()->get($zip->getValue());
         $plain_text = $compression__algorithm->uncompress($plain_text);
     }
     $this->setPayload(JWSPayloadFactory::build($plain_text));
     $this->should_decrypt = false;
     return $this;
 }
Esempio n. 4
0
 /**
  * @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);
 }