/** * @param IJWKSpecification $spec * @return IJWK * @throws InvalidJWKAlgorithm * @throws JWKInvalidSpecException */ public static function build(IJWKSpecification $spec) { if (is_null($spec)) { throw new \InvalidArgumentException('missing spec param'); } $algorithm = DigitalSignatures_MACs_Registry::getInstance()->get($spec->getAlg()); if (is_null($algorithm)) { $algorithm = ContentEncryptionAlgorithms_Registry::getInstance()->get($spec->getAlg()); } if (is_null($algorithm)) { $algorithm = KeyManagementAlgorithms_Registry::getInstance()->get($spec->getAlg()); } if (is_null($algorithm)) { throw new InvalidJWKAlgorithm(sprintf('alg %s not supported!', $spec->getAlg())); } if ($algorithm->getKeyType() !== JSONWebKeyTypes::OctetSequence) { throw new InvalidJWKAlgorithm(sprintf('key type %s not supported!', $algorithm->getKeyType())); } if (!$spec instanceof OctetSequenceJWKSpecification) { throw new JWKInvalidSpecException(); } $shared_secret = $spec->getSharedSecret(); $secret_len = strlen($shared_secret); if ($secret_len === 0) { $generator = Utils_Registry::getInstance()->get(Utils_Registry::RandomNumberGeneratorService); $shared_secret = $generator->invoke($algorithm->getMinKeyLen() / 8); } return OctetSequenceJWK::fromSecret(new SymmetricSharedKey($shared_secret), $spec->getAlg(), $spec->getUse()); }
/** * @param IJWKSpecification $spec * @return IJWK * @throws InvalidJWKAlgorithm * @throws InvalidJWKType */ public static function build(IJWKSpecification $spec) { if (is_null($spec)) { throw new \InvalidArgumentException('missing spec param'); } $algorithm = DigitalSignatures_MACs_Registry::getInstance()->get($spec->getAlg()); if (is_null($algorithm)) { $algorithm = KeyManagementAlgorithms_Registry::getInstance()->get($spec->getAlg()); } if (is_null($algorithm)) { throw new InvalidJWKAlgorithm(sprintf('alg %s not supported!', $spec->getAlg())); } if ($algorithm->getKeyType() !== JSONWebKeyTypes::RSA) { throw new InvalidJWKAlgorithm(sprintf('key type %s not supported!', $algorithm->getKeyType())); } if ($spec instanceof RSAJWKPEMPrivateKeySpecification) { $private_key = RSAFacade::getInstance()->buildPrivateKeyFromPEM($spec->getPEM(), $spec->getPrivateKeyPassword()); $public_key = RSAFacade::getInstance()->buildPublicKey($private_key->getModulus(), $private_key->getPublicExponent()); $jwk = RSAJWK::fromKeys(new KeyPair($public_key, $private_key)); $jwk->setAlgorithm($spec->getAlg()); $jwk->setKeyUse($spec->getUse()); return $jwk; } if ($spec instanceof RSAJWKParamsPublicKeySpecification) { $public_key = RSAFacade::getInstance()->buildPublicKey($spec->getModulus()->toBigInt(), $spec->getExponent()->toBigInt()); $jwk = RSAJWK::fromPublicKey($public_key); $jwk->setAlgorithm($spec->getAlg()); $jwk->setKeyUse($spec->getUse()); $jwk->setId($spec->getKeyId()); $jwk->setX509CertificateChain($spec->getX509CertificateChain()); return $jwk; } if ($spec instanceof RSAJWKPEMPublicKeySpecification) { $public_key = RSAFacade::getInstance()->buildPublicKeyFromPEM($spec->getPEM()); $jwk = RSAJWK::fromPublicKey($public_key); $jwk->setAlgorithm($spec->getAlg()); $jwk->setKeyUse($spec->getUse()); return $jwk; } // default ... $keys = RSAFacade::getInstance()->buildKeyPair($algorithm->getMinKeyLen()); $jwk = RSAJWK::fromKeys($keys); $jwk->setAlgorithm($spec->getAlg()); $jwk->setKeyUse($spec->getUse()); return $jwk; }
/** * @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); }