Search in sources :

Example 26 with SignatureAlgorithm

use of io.jans.as.model.crypto.signature.SignatureAlgorithm in project jans by JanssenProject.

the class Validator method createJwsSigner.

public static AbstractJwsSigner createJwsSigner(Jwt idToken, OpenIdConfigurationResponse discoveryResponse, PublicOpKeyService keyService, OpClientFactory opClientFactory, Rp rp, RpServerConfiguration configuration) {
    final String algorithm = idToken.getHeader().getClaimAsString(JwtHeaderName.ALGORITHM);
    final SignatureAlgorithm signatureAlgorithm = SignatureAlgorithm.fromString(algorithm);
    final String jwkUrl = discoveryResponse.getJwksUri();
    String kid = idToken.getHeader().getClaimAsString(JwtHeaderName.KEY_ID);
    if (signatureAlgorithm == null)
        throw new HttpException(ErrorResponseCode.INVALID_ALGORITHM);
    if (Strings.isNullOrEmpty(kid) && (signatureAlgorithm.getFamily() == AlgorithmFamily.RSA || signatureAlgorithm.getFamily() == AlgorithmFamily.EC)) {
        LOG.warn("Warning:`kid` is missing in id_token header. oxd will throw error if RP is unable to determine the key to used for `id_token` validation.");
    }
    if (signatureAlgorithm == SignatureAlgorithm.NONE) {
        if (!configuration.getAcceptIdTokenWithoutSignature()) {
            LOG.error("`ID_TOKEN` without signature is not allowed. To allow `ID_TOKEN` without signature set `accept_id_token_without_signature` field to 'true' in client-api-server.yml.");
            throw new HttpException(ErrorResponseCode.ID_TOKEN_WITHOUT_SIGNATURE_NOT_ALLOWED);
        }
        return new AbstractJwsSigner(signatureAlgorithm) {

            @Override
            public String generateSignature(String signingInput) throws SignatureException {
                return null;
            }

            @Override
            public boolean validateSignature(String signingInput, String signature) throws SignatureException {
                return true;
            }
        };
    } else if (signatureAlgorithm.getFamily() == AlgorithmFamily.RSA) {
        final RSAPublicKey publicKey = (RSAPublicKey) keyService.getPublicKey(jwkUrl, kid, signatureAlgorithm, Use.SIGNATURE);
        return opClientFactory.createRSASigner(signatureAlgorithm, publicKey);
    } else if (signatureAlgorithm.getFamily() == AlgorithmFamily.HMAC) {
        return new HMACSigner(signatureAlgorithm, rp.getClientSecret());
    } else if (signatureAlgorithm.getFamily() == AlgorithmFamily.EC) {
        final ECDSAPublicKey publicKey = (ECDSAPublicKey) keyService.getPublicKey(jwkUrl, kid, signatureAlgorithm, Use.SIGNATURE);
        return new ECDSASigner(signatureAlgorithm, publicKey);
    }
    throw new HttpException(ErrorResponseCode.ALGORITHM_NOT_SUPPORTED);
}
Also used : RSAPublicKey(io.jans.as.model.crypto.signature.RSAPublicKey) HMACSigner(io.jans.as.model.jws.HMACSigner) ECDSASigner(io.jans.as.model.jws.ECDSASigner) SignatureAlgorithm(io.jans.as.model.crypto.signature.SignatureAlgorithm) HttpException(io.jans.ca.server.HttpException) AbstractJwsSigner(io.jans.as.model.jws.AbstractJwsSigner) ECDSAPublicKey(io.jans.as.model.crypto.signature.ECDSAPublicKey)

Example 27 with SignatureAlgorithm

use of io.jans.as.model.crypto.signature.SignatureAlgorithm in project jans by JanssenProject.

the class Validator method validateIdToken.

public void validateIdToken(String nonce) {
    try {
        final String issuer = idToken.getClaims().getClaimAsString(JwtClaimName.ISSUER);
        final String sub = idToken.getClaims().getClaimAsString(JwtClaimName.SUBJECT_IDENTIFIER);
        final String nonceFromToken = idToken.getClaims().getClaimAsString(JwtClaimName.NONCE);
        final String clientId = rp.getClientId();
        // validate nonce
        if (configuration.getFapiEnabled() && Strings.isNullOrEmpty(nonceFromToken)) {
            LOG.error("Nonce is missing from id_token.");
            throw new HttpException(ErrorResponseCode.INVALID_ID_TOKEN_NO_NONCE);
        }
        if (!Strings.isNullOrEmpty(nonce) && !nonceFromToken.endsWith(nonce)) {
            LOG.error("ID Token has invalid nonce. Expected nonce: " + nonce + ", nonce from token is: " + nonceFromToken);
            throw new HttpException(ErrorResponseCode.INVALID_ID_TOKEN_BAD_NONCE);
        }
        // validate audience
        validateAudience(idToken, clientId);
        // validate subject identifier
        if (Strings.isNullOrEmpty(sub)) {
            LOG.error("ID Token is missing `sub` value.");
            throw new HttpException(ErrorResponseCode.NO_SUBJECT_IDENTIFIER);
        }
        // validate id_token issued at date
        final Date issuedAt = idToken.getClaims().getClaimAsDate(JwtClaimName.ISSUED_AT);
        if (issuedAt == null) {
            LOG.error("`ISSUED_AT` date is either invalid or missing from `ID_TOKEN`.");
            throw new HttpException(ErrorResponseCode.INVALID_ID_TOKEN_ISSUED_AT);
        }
        final Date now = new Date();
        if (configuration.getFapiEnabled() && TimeUnit.MILLISECONDS.toHours(now.getTime() - issuedAt.getTime()) > configuration.getIatExpirationInHours()) {
            LOG.error("`ISSUED_AT` date too far in the past. iat : " + issuedAt + " now : " + now + ").");
            throw new HttpException(ErrorResponseCode.INVALID_ID_TOKEN_OLD_ISSUED_AT);
        }
        // validate id_token expire date
        final Date expiresAt = idToken.getClaims().getClaimAsDate(JwtClaimName.EXPIRATION_TIME);
        if (expiresAt == null) {
            LOG.error("EXPIRATION_TIME (`exp`) is either invalid or missing from `ID_TOKEN`.");
            throw new HttpException(ErrorResponseCode.INVALID_ID_TOKEN_EXPIRATION_TIME);
        }
        if (now.after(expiresAt)) {
            LOG.error("ID Token is expired. (" + expiresAt + " is before " + now + ").");
            throw new HttpException(ErrorResponseCode.INVALID_ID_TOKEN_EXPIRED);
        }
        // 1. validate issuer
        if (Strings.isNullOrEmpty(issuer)) {
            LOG.error("Issuer (`iss`) claim is missing from id_token.");
            throw new HttpException(ErrorResponseCode.INVALID_ID_TOKEN_NO_ISSUER);
        }
        if (!issuer.equals(discoveryResponse.getIssuer())) {
            LOG.error("ID Token issuer is invalid. Token issuer: " + issuer + ", discovery issuer: " + discoveryResponse.getIssuer());
            throw new HttpException(ErrorResponseCode.INVALID_ID_TOKEN_BAD_ISSUER);
        }
        // validate signature
        final String algorithm = idToken.getHeader().getClaimAsString(JwtHeaderName.ALGORITHM);
        final SignatureAlgorithm signatureAlgorithm = SignatureAlgorithm.fromString(algorithm);
        // validate algorithm
        if (!Strings.isNullOrEmpty(rp.getIdTokenSignedResponseAlg()) && SignatureAlgorithm.fromString(rp.getIdTokenSignedResponseAlg()) != signatureAlgorithm) {
            LOG.error("The algorithm used to sign the ID Token does not matches with `id_token_signed_response_alg` algorithm set during client registration.Expected: {}, Got: {}", rp.getIdTokenSignedResponseAlg(), algorithm);
            throw new HttpException(ErrorResponseCode.INVALID_ID_TOKEN_INVALID_ALGORITHM);
        }
        if (signatureAlgorithm != SignatureAlgorithm.NONE) {
            boolean signature = jwsSigner.validate(idToken);
            if (!signature) {
                LOG.error("ID Token signature is invalid.");
                throw new HttpException(ErrorResponseCode.INVALID_ID_TOKEN_BAD_SIGNATURE);
            }
        }
    } catch (HttpException e) {
        throw e;
    } catch (Exception e) {
        LOG.error(e.getMessage(), e);
        throw new HttpException(ErrorResponseCode.INVALID_ID_TOKEN_UNKNOWN);
    }
}
Also used : HttpException(io.jans.ca.server.HttpException) SignatureAlgorithm(io.jans.as.model.crypto.signature.SignatureAlgorithm) Date(java.util.Date) HttpException(io.jans.ca.server.HttpException) SignatureException(java.security.SignatureException)

Example 28 with SignatureAlgorithm

use of io.jans.as.model.crypto.signature.SignatureAlgorithm in project jans by JanssenProject.

the class GetRequestObjectUriOperation method execute.

public IOpResponse execute(GetRequestObjectUriParams params) {
    try {
        validate(params);
        final Rp rp = getRp();
        SignatureAlgorithm algo = SignatureAlgorithm.fromString(params.getRequestObjectSigningAlg()) != null ? SignatureAlgorithm.fromString(params.getRequestObjectSigningAlg()) : SignatureAlgorithm.fromString(rp.getRequestObjectSigningAlg());
        if (algo == null) {
            LOG.error("`request_object_signing_alg` is required parameter in request. Please set this parameter if it is not set during client registration.");
            throw new HttpException(ErrorResponseCode.INVALID_ALGORITHM);
        }
        Jwt unsignedJwt = createRequestObject(algo, rp, params);
        // signing request object
        Jwt signedJwt = getKeyGeneratorService().sign(unsignedJwt, rp.getClientSecret(), algo);
        // setting request object in Expired Object
        String requestUriId = UUID.randomUUID().toString();
        getRequestObjectService().put(requestUriId, signedJwt.toString());
        String requestUri = baseRequestUri(params.getRpHostUrl()) + requestUriId;
        LOG.trace("RequestObject created successfully. request_uri : {} ", requestUri);
        GetRequestObjectUriResponse response = new GetRequestObjectUriResponse();
        response.setRequestUri(requestUri);
        return response;
    } catch (HttpException e) {
        throw e;
    } catch (Exception e) {
        LOG.error("Error in creating `request_uri` response ", e);
    }
    throw new HttpException(ErrorResponseCode.FAILED_TO_GET_REQUEST_URI);
}
Also used : Jwt(io.jans.as.model.jwt.Jwt) SignatureAlgorithm(io.jans.as.model.crypto.signature.SignatureAlgorithm) HttpException(io.jans.ca.server.HttpException) GetRequestObjectUriResponse(io.jans.ca.common.response.GetRequestObjectUriResponse) Rp(io.jans.ca.server.service.Rp) HttpException(io.jans.ca.server.HttpException)

Aggregations

SignatureAlgorithm (io.jans.as.model.crypto.signature.SignatureAlgorithm)28 JSONObject (org.json.JSONObject)10 Jwt (io.jans.as.model.jwt.Jwt)8 InvalidJwtException (io.jans.as.model.exception.InvalidJwtException)7 HttpException (io.jans.ca.server.HttpException)7 KeyEncryptionAlgorithm (io.jans.as.model.crypto.encryption.KeyEncryptionAlgorithm)6 WebApplicationException (javax.ws.rs.WebApplicationException)6 Client (io.jans.as.common.model.registration.Client)5 RSAPublicKey (io.jans.as.model.crypto.signature.RSAPublicKey)5 BlockEncryptionAlgorithm (io.jans.as.model.crypto.encryption.BlockEncryptionAlgorithm)4 ECDSAPublicKey (io.jans.as.model.crypto.signature.ECDSAPublicKey)4 Signature (java.security.Signature)4 SignatureException (java.security.SignatureException)4 Date (java.util.Date)4 User (io.jans.as.common.model.common.User)3 AuthenticationMethod (io.jans.as.model.common.AuthenticationMethod)3 CryptoProviderException (io.jans.as.model.exception.CryptoProviderException)3 ECDSASigner (io.jans.as.model.jws.ECDSASigner)3 RegisterRequest (io.jans.as.client.RegisterRequest)2 GrantType (io.jans.as.model.common.GrantType)2