Search in sources :

Example 6 with Pair

use of io.jans.util.Pair in project jans by JanssenProject.

the class TocService method parseTOC.

private Pair<LocalDate, Map<String, JsonNode>> parseTOC(String mdsTocRootCertsFolder, Path path) throws IOException, ParseException {
    try (BufferedReader reader = Files.newBufferedReader(path)) {
        JWSObject jwsObject = JWSObject.parse(reader.readLine());
        List<String> certificateChain = jwsObject.getHeader().getX509CertChain().stream().map(c -> base64Service.encodeToString(c.decode())).collect(Collectors.toList());
        JWSAlgorithm algorithm = jwsObject.getHeader().getAlgorithm();
        try {
            JWSVerifier verifier = resolveVerifier(algorithm, mdsTocRootCertsFolder, certificateChain);
            if (!jwsObject.verify(verifier)) {
                log.warn("Unable to verify JWS object using algorithm {} for file {}", algorithm, path);
                return new Pair<LocalDate, Map<String, JsonNode>>(null, Collections.emptyMap());
            }
        } catch (Exception e) {
            log.warn("Unable to verify JWS object using algorithm {} for file {} {}", algorithm, path, e);
            return new Pair<LocalDate, Map<String, JsonNode>>(null, Collections.emptyMap());
        }
        String jwtPayload = jwsObject.getPayload().toString();
        JsonNode toc = dataMapperService.readTree(jwtPayload);
        log.debug("Legal header {}", toc.get("legalHeader"));
        ArrayNode entries = (ArrayNode) toc.get("entries");
        int numberOfEntries = toc.get("no").asInt();
        log.debug("Property 'no' value: {}. Number of entries: {}", numberOfEntries, entries.size());
        Iterator<JsonNode> iter = entries.elements();
        Map<String, JsonNode> tocEntries = new HashMap<>();
        while (iter.hasNext()) {
            JsonNode tocEntry = iter.next();
            if (tocEntry.hasNonNull("aaguid")) {
                String aaguid = tocEntry.get("aaguid").asText();
                log.info("Added TOC entry {} from {} with status {}", aaguid, path, tocEntry.get("statusReports").findValue("status"));
                tocEntries.put(aaguid, tocEntry);
            }
        }
        String nextUpdateText = toc.get("nextUpdate").asText();
        LocalDate nextUpdateDate = LocalDate.parse(nextUpdateText);
        this.digester = resolveDigester(algorithm);
        return new Pair<LocalDate, Map<String, JsonNode>>(nextUpdateDate, tocEntries);
    }
}
Also used : X509Certificate(java.security.cert.X509Certificate) Base64Service(io.jans.fido2.service.Base64Service) MessageDigest(java.security.MessageDigest) ApplicationInitialized(io.jans.service.cdi.event.ApplicationInitialized) CertificateService(io.jans.fido2.service.CertificateService) JOSEException(com.nimbusds.jose.JOSEException) HashMap(java.util.HashMap) JWSObject(com.nimbusds.jose.JWSObject) ArrayList(java.util.ArrayList) Inject(javax.inject.Inject) DirectoryStream(java.nio.file.DirectoryStream) Fido2RuntimeException(io.jans.fido2.exception.Fido2RuntimeException) Map(java.util.Map) Observes(javax.enterprise.event.Observes) ECDSAVerifier(com.nimbusds.jose.crypto.ECDSAVerifier) DataMapperService(io.jans.fido2.service.DataMapperService) JsonNode(com.fasterxml.jackson.databind.JsonNode) CertificateVerifier(io.jans.fido2.service.verifier.CertificateVerifier) ParseException(java.text.ParseException) Path(java.nio.file.Path) StringHelper(io.jans.util.StringHelper) AppConfiguration(io.jans.fido2.model.conf.AppConfiguration) JWSVerifier(com.nimbusds.jose.JWSVerifier) Logger(org.slf4j.Logger) ISO_DATE(java.time.format.DateTimeFormatter.ISO_DATE) Iterator(java.util.Iterator) Files(java.nio.file.Files) IOException(java.io.IOException) JWSAlgorithm(com.nimbusds.jose.JWSAlgorithm) Collectors(java.util.stream.Collectors) ArrayNode(com.fasterxml.jackson.databind.node.ArrayNode) Pair(io.jans.util.Pair) List(java.util.List) Stream(java.util.stream.Stream) LocalDate(java.time.LocalDate) Fido2Configuration(io.jans.fido2.model.conf.Fido2Configuration) ApplicationScoped(javax.enterprise.context.ApplicationScoped) BufferedReader(java.io.BufferedReader) DigestUtils(org.apache.commons.codec.digest.DigestUtils) ECPublicKey(java.security.interfaces.ECPublicKey) Collections(java.util.Collections) FileSystems(java.nio.file.FileSystems) HashMap(java.util.HashMap) JWSVerifier(com.nimbusds.jose.JWSVerifier) JsonNode(com.fasterxml.jackson.databind.JsonNode) JWSAlgorithm(com.nimbusds.jose.JWSAlgorithm) LocalDate(java.time.LocalDate) JOSEException(com.nimbusds.jose.JOSEException) Fido2RuntimeException(io.jans.fido2.exception.Fido2RuntimeException) ParseException(java.text.ParseException) IOException(java.io.IOException) BufferedReader(java.io.BufferedReader) ArrayNode(com.fasterxml.jackson.databind.node.ArrayNode) JWSObject(com.nimbusds.jose.JWSObject) HashMap(java.util.HashMap) Map(java.util.Map) Pair(io.jans.util.Pair)

Example 7 with Pair

use of io.jans.util.Pair in project jans by JanssenProject.

the class SubFilterGenerator method build.

/**
 * Computes a filter based on an atomic (non-divisible) SCIM expression described by the set of parameters passed.
 * If the filter cannot be built, null is returned.
 * @param subAttribute The name of the json property upon which the search is acting. If the search is targetted
 *                     directly upon an attribute, this is null
 * @param attribute The attribute of interest. If the attribute contains json contents, the search can be focused on
 *                  a sub-attribute inside it
 * @param compValue The comparison value (it's found after the operator, e.g "hi" in displayName co "hi")
 * @param attrType The attribute definition type of the attribute
 * @param type See compvalue in ScimFilter.g4 grammar file
 * @param operator The operator
 * @param multiValued Whether the attribute referenced in parameter is multivalued or not (null tries to handle both)
 * @return The filter built after processing this atomic expression (accompanied with an error string if any)
 */
public Pair<Filter, String> build(String subAttribute, String attribute, String compValue, Type attrType, CompValueType type, ScimOperator operator, Boolean multiValued) {
    log.debug("Preparing subfilter with attribute={}, subAttribute={}, compValue={}, attrType={}, multiValued={}", attribute, subAttribute, compValue, attrType, multiValued);
    Filter filth = null;
    error = null;
    if (type.equals(CompValueType.NULL)) {
        if (subAttribute == null) {
            // attribute=*
            // attribute IS NOT MISSING
            filth = Filter.createPresenceFilter(attribute).multiValued(multiValued);
            filth = negateIf(filth, operator.equals(ScimOperator.EQUAL));
        } else {
            // attribute=*"subattribute":null*
            // attribute LIKE "%\"subattribute\":null%"
            String sub = String.format("\"%s\":null", subAttribute);
            filth = Filter.createSubstringFilter(attribute, null, new String[] { sub }, null).multiValued(multiValued);
            filth = negateIf(filth, operator.equals(ScimOperator.NOT_EQUAL));
        }
    } else if (Type.STRING.equals(attrType) || Type.REFERENCE.equals(attrType)) {
        // Drop double quotes
        compValue = compValue.substring(1, compValue.length() - 1);
        filth = getSubFilterString(subAttribute, attribute, StringEscapeUtils.unescapeJson(compValue), operator, multiValued);
    } else if (Type.INTEGER.equals(attrType) || Type.DECIMAL.equals(attrType)) {
        filth = getSubFilterNumeric(subAttribute, attribute, compValue, operator, attrType, multiValued);
    } else if (Type.BOOLEAN.equals(attrType)) {
        filth = getSubFilterBoolean(subAttribute, attribute, compValue, operator, multiValued);
    } else if (Type.DATETIME.equals(attrType)) {
        compValue = compValue.substring(1, compValue.length() - 1);
        // Dates do not have characters to escape...
        filth = getSubFilterDateTime(subAttribute, attribute, compValue, operator, multiValued);
    }
    log.trace("getSubFilter. {}", Optional.ofNullable(filth).map(Filter::toString).orElse(null));
    return new Pair<>(filth, error);
}
Also used : Filter(io.jans.orm.search.filter.Filter) Pair(io.jans.util.Pair)

Example 8 with Pair

use of io.jans.util.Pair in project jans by JanssenProject.

the class IntrospectionWebService method getAuthorizationGrant.

/**
 * @return we return pair of authorization grant or otherwise true - if it's basic client authentication or false if it is not
 * @throws UnsupportedEncodingException when encoding is not supported
 */
private Pair<AuthorizationGrant, Boolean> getAuthorizationGrant(String authorization, String accessToken) throws UnsupportedEncodingException {
    AuthorizationGrant grant = tokenService.getBearerAuthorizationGrant(authorization);
    if (grant != null) {
        final String authorizationAccessToken = tokenService.getBearerToken(authorization);
        final AbstractToken accessTokenObject = grant.getAccessToken(authorizationAccessToken);
        if (accessTokenObject != null && accessTokenObject.isValid()) {
            return new Pair<>(grant, false);
        } else {
            log.error("Access token is not valid: {}", authorizationAccessToken);
            return EMPTY;
        }
    }
    grant = tokenService.getBasicAuthorizationGrant(authorization);
    if (grant != null) {
        return new Pair<>(grant, false);
    }
    if (tokenService.isBasicAuthToken(authorization)) {
        return isBasicTokenValid(authorization, accessToken);
    }
    return EMPTY;
}
Also used : AbstractToken(io.jans.as.server.model.common.AbstractToken) AuthorizationGrant(io.jans.as.server.model.common.AuthorizationGrant) Pair(io.jans.util.Pair)

Example 9 with Pair

use of io.jans.util.Pair in project jans by JanssenProject.

the class PublicOpKeyService method getPublicKey.

public PublicKey getPublicKey(String jwkSetUrl, String keyId, SignatureAlgorithm signatureAlgorithm, Use use) {
    // Get keys from cache if present
    Optional<PublicKey> cachedKey = getCachedKey(jwkSetUrl, keyId);
    if (cachedKey.isPresent()) {
        LOG.debug("Taken public key from cache. jwks_url: {}, kid : {} ", jwkSetUrl, keyId);
        return cachedKey.get();
    }
    // Request jwks from OP
    JwkClient jwkClient = opClientFactory.createJwkClient(jwkSetUrl);
    jwkClient.setExecutor(new ApacheHttpClient43Engine(httpService.getHttpClient()));
    JwkResponse jwkResponse = jwkClient.exec();
    if (jwkResponse == null || jwkResponse.getStatus() != 200) {
        LOG.error("Failed to fetch public key from OP. Obtained Response : {}", (jwkResponse == null ? jwkResponse : jwkResponse.getStatus()));
        throw new RuntimeException("Failed to fetch public key from OP. Obtained Response : " + (jwkResponse == null ? jwkResponse : jwkResponse.getStatus()));
    }
    if (!Strings.isNullOrEmpty(keyId)) {
        PublicKey publicKey = jwkResponse.getPublicKey(keyId);
        if (publicKey != null) {
            cache.put((new Pair<>(jwkSetUrl, keyId)), publicKey);
            return publicKey;
        }
    } else {
        JSONWebKeySet jsonWebKeySet = jwkResponse.getJwks();
        List<PublicKey> pks = Lists.newArrayList();
        for (JSONWebKey key : jsonWebKeySet.getKeys()) {
            if (key.getKty() == null)
                continue;
            if (signatureAlgorithm.getFamily().toString().equals(key.getKty().toString()) && (use == null || use == key.getUse())) {
                pks.add(getPublicKey(key));
            }
        }
        if (pks.size() > 1) {
            LOG.error("Multiple matching keys found in issuer's jwks_uri for algorithm : {}. `kid` must be provided in this case.", signatureAlgorithm.getName());
            throw new RuntimeException("Multiple matching keys found in issuer's jwks_uri for algorithm : " + signatureAlgorithm.getName() + ". `kid` must be provided in this case.");
        }
        if (pks.size() == 1) {
            if (!Strings.isNullOrEmpty(pks.get(0).getKeyId())) {
                cache.put((new Pair<>(jwkSetUrl, pks.get(0).getKeyId())), pks.get(0));
            }
            return pks.get(0);
        }
    }
    LOG.error("Failed to fetch public key from OP.");
    throw new RuntimeException("Failed to fetch public key from OP.");
}
Also used : JSONWebKey(io.jans.as.model.jwk.JSONWebKey) JwkResponse(io.jans.as.client.JwkResponse) JSONWebKeySet(io.jans.as.model.jwk.JSONWebKeySet) PublicKey(io.jans.as.model.crypto.PublicKey) RSAPublicKey(io.jans.as.model.crypto.signature.RSAPublicKey) ECDSAPublicKey(io.jans.as.model.crypto.signature.ECDSAPublicKey) ApacheHttpClient43Engine(org.jboss.resteasy.client.jaxrs.engines.ApacheHttpClient43Engine) JwkClient(io.jans.as.client.JwkClient) Pair(io.jans.util.Pair)

Example 10 with Pair

use of io.jans.util.Pair in project jans by JanssenProject.

the class SearchResourcesWebService method computeResults.

/**
 * Here we reuse every single POST search found in other web services, but handle serialization differently to a more
 * manual approach for performance reasons. In the end, this saves us 3 deserializations and 3 serializations of
 * multiple results packs.
 * Result set as a whole will not be sorted by sortBy param but every group of resources (by resource type) will be
 * sorted as such
 * @param searchRequest
 * @param resources
 * @return
 */
private Pair<Integer, Integer> computeResults(SearchRequest searchRequest, List<JsonNode> resources) throws Exception {
    int i;
    int totalInPage = 0, totalResults = 0, skip = 0;
    boolean resultsAvailable = false;
    Integer startIndex_ = searchRequest.getStartIndex();
    JsonNode tree = null;
    // Move forward to skip the searches that might have no results and find the first one starting at index = searchRequest.getStartIndex()
    for (i = 0; i < NUM_RESOURCE_TYPES && !resultsAvailable; i++) {
        tree = getListResponseTree(i, searchRequest);
        if (tree != null) {
            totalResults += tree.get("totalResults").asInt();
            if (totalResults > 0) {
                if (totalResults >= startIndex_) {
                    // when null, it means searchRequest.getCount() was zero or empty page
                    resultsAvailable = tree.get("itemsPerPage") != null;
                    if (searchRequest.getStartIndex() == 1)
                        skip = startIndex_ - (totalResults - tree.get("totalResults").asInt()) - 1;
                }
                // Adjust startindex of subsequent searches to 1
                searchRequest.setStartIndex(1);
            }
        }
    }
    if (resultsAvailable) {
        // Accumulate till we have searchRequest.getCount() results or exhaust data
        Iterator<JsonNode> iterator = tree.get("Resources").elements();
        while (iterator.hasNext() && totalInPage < searchRequest.getCount()) {
            if (skip == 0) {
                totalInPage++;
                resources.add(iterator.next());
            } else {
                skip--;
                iterator.next();
            }
        }
        while (i < NUM_RESOURCE_TYPES && totalInPage < searchRequest.getCount()) {
            resultsAvailable = false;
            tree = getListResponseTree(i, searchRequest);
            if (tree != null) {
                totalResults += tree.get("totalResults").asInt();
                if (tree.get("totalResults").asInt() > 0)
                    resultsAvailable = tree.get("itemsPerPage") != null;
            }
            if (resultsAvailable) {
                for (iterator = tree.get("Resources").elements(); iterator.hasNext() && totalInPage < searchRequest.getCount(); totalInPage++) resources.add(iterator.next());
            }
            i++;
        }
        // Continue the remainder of searches to just compute final value for totalResults
        while (i < NUM_RESOURCE_TYPES) {
            tree = getListResponseTree(i, searchRequest);
            if (tree != null)
                totalResults += tree.get("totalResults").asInt();
            i++;
        }
    }
    // Revert startIndex to original
    searchRequest.setStartIndex(startIndex_);
    return new Pair<>(totalInPage, totalResults);
}
Also used : JsonNode(com.fasterxml.jackson.databind.JsonNode) Pair(io.jans.util.Pair)

Aggregations

Pair (io.jans.util.Pair)10 AuthorizationGrant (io.jans.as.server.model.common.AuthorizationGrant)3 JsonNode (com.fasterxml.jackson.databind.JsonNode)2 ArrayNode (com.fasterxml.jackson.databind.node.ArrayNode)1 JOSEException (com.nimbusds.jose.JOSEException)1 JWSAlgorithm (com.nimbusds.jose.JWSAlgorithm)1 JWSObject (com.nimbusds.jose.JWSObject)1 JWSVerifier (com.nimbusds.jose.JWSVerifier)1 ECDSAVerifier (com.nimbusds.jose.crypto.ECDSAVerifier)1 JwkClient (io.jans.as.client.JwkClient)1 JwkResponse (io.jans.as.client.JwkResponse)1 SimpleUser (io.jans.as.common.model.common.SimpleUser)1 User (io.jans.as.common.model.common.User)1 PublicKey (io.jans.as.model.crypto.PublicKey)1 ECDSAPublicKey (io.jans.as.model.crypto.signature.ECDSAPublicKey)1 RSAPublicKey (io.jans.as.model.crypto.signature.RSAPublicKey)1 InvalidJwtException (io.jans.as.model.exception.InvalidJwtException)1 JSONWebKey (io.jans.as.model.jwk.JSONWebKey)1 JSONWebKeySet (io.jans.as.model.jwk.JSONWebKeySet)1 AbstractToken (io.jans.as.server.model.common.AbstractToken)1