All Downloads are FREE. Search and download functionalities are using the official Maven repository.

uk.gov.ida.saml.security.signature.OutgoingKeySignatureTrustEngine Maven / Gradle / Ivy

The newest version!
package uk.gov.ida.saml.security.signature;

import com.google.common.base.Strings;
import io.prometheus.client.Counter;
import net.shibboleth.utilities.java.support.resolver.CriteriaSet;
import net.shibboleth.utilities.java.support.resolver.ResolverException;
import org.opensaml.security.SecurityException;
import org.opensaml.security.credential.Credential;
import org.opensaml.security.credential.CredentialResolver;
import org.opensaml.security.credential.UsageType;
import org.opensaml.security.criteria.KeyAlgorithmCriterion;
import org.opensaml.security.criteria.UsageCriterion;
import org.opensaml.xmlsec.algorithm.AlgorithmSupport;
import org.opensaml.xmlsec.keyinfo.KeyInfoCredentialResolver;
import org.opensaml.xmlsec.signature.Signature;
import org.opensaml.xmlsec.signature.support.impl.ExplicitKeySignatureTrustEngine;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.annotation.Nonnull;
import javax.annotation.Nullable;

public class OutgoingKeySignatureTrustEngine extends ExplicitKeySignatureTrustEngine {
    /**
     * Constructor.
     *
     * @param resolver        credential resolver used to resolve trusted credentials.
     * @param keyInfoResolver KeyInfo credential resolver used to obtain the (advisory) signing credential from a 
     *                        trusted credential store
     */
    private final Logger log = LoggerFactory.getLogger(OutgoingKeySignatureTrustEngine.class);
    private static Counter outgoingSignatureVerifyingErrorCounter = Counter.build()
            .name("verify_saml_lib_signature_verifying_error_counter")
            .help("Counter to detect errors on the outgoing signature, reports the number of errors")
            .register();


    public OutgoingKeySignatureTrustEngine(@Nonnull CredentialResolver resolver, @Nonnull KeyInfoCredentialResolver keyInfoResolver) {
        super(resolver, keyInfoResolver);
    }

    @Override
    protected boolean doValidate(@Nonnull final Signature signature,
                                 @Nullable final CriteriaSet trustBasisCriteria) throws SecurityException {

        final CriteriaSet criteriaSet = new CriteriaSet();
        criteriaSet.addAll(trustBasisCriteria);
        if (!criteriaSet.contains(UsageCriterion.class)) {
            criteriaSet.add(new UsageCriterion(UsageType.SIGNING));
        }
        final String jcaAlgorithm = AlgorithmSupport.getKeyAlgorithm(signature.getSignatureAlgorithm());
        if (!Strings.isNullOrEmpty(jcaAlgorithm)) {
            criteriaSet.add(new KeyAlgorithmCriterion(jcaAlgorithm), true);
        }

        final Iterable trustedCredentials;
        try {
            trustedCredentials = getCredentialResolver().resolve(criteriaSet);
        } catch (final ResolverException e) {
            throw new SecurityException("Error resolving trusted credentials", e);
        }

        if (validate(signature, trustedCredentials)) {
            return true;
        }

        // If the credentials extracted from Signature's KeyInfo (if any) did not verify the
        // signature and/or establish trust, as a fall back attempt verify the signature with
        // the trusted credentials directly.
        log.debug("Attempting to verify signature using trusted credentials");

        for (final Credential trustedCredential : trustedCredentials) {
            if (verifySignature(signature, trustedCredential)) {
                log.debug("Successfully verified signature using resolved trusted credential");
                return true;
            }
            outgoingSignatureVerifyingErrorCounter.inc();
            log.warn("Failed to verify signature using trusted credentials");
        }
        log.debug("Failed to verify signature using either KeyInfo-derived or directly trusted credentials");
        return false;
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy