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

com.itextpdf.signatures.validation.v1.SignatureValidationProperties Maven / Gradle / Ivy

There is a newer version: 8.0.5
Show newest version
/*
    This file is part of the iText (R) project.
    Copyright (c) 1998-2024 Apryse Group NV
    Authors: Apryse Software.

    This program is offered under a commercial and under the AGPL license.
    For commercial licensing, contact us at https://itextpdf.com/sales.  For AGPL licensing, see below.

    AGPL licensing:
    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU Affero General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU Affero General Public License for more details.

    You should have received a copy of the GNU Affero General Public License
    along with this program.  If not, see .
 */
package com.itextpdf.signatures.validation.v1;

import java.time.Duration;
import java.util.EnumSet;
import java.util.HashMap;
import java.util.function.Consumer;

import com.itextpdf.signatures.validation.v1.context.CertificateSource;
import com.itextpdf.signatures.validation.v1.context.CertificateSources;
import com.itextpdf.signatures.validation.v1.context.TimeBasedContext;
import com.itextpdf.signatures.validation.v1.context.TimeBasedContexts;
import com.itextpdf.signatures.validation.v1.context.ValidationContext;
import com.itextpdf.signatures.validation.v1.context.ValidatorContext;
import com.itextpdf.signatures.validation.v1.context.ValidatorContexts;
import com.itextpdf.signatures.validation.v1.extensions.BasicConstraintsExtension;
import com.itextpdf.signatures.validation.v1.extensions.CertificateExtension;
import com.itextpdf.signatures.validation.v1.extensions.ExtendedKeyUsageExtension;
import com.itextpdf.signatures.validation.v1.extensions.KeyUsage;
import com.itextpdf.signatures.validation.v1.extensions.KeyUsageExtension;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.function.Function;

public class SignatureValidationProperties {
    public static final boolean DEFAULT_CONTINUE_AFTER_FAILURE = true;
    public static final Duration DEFAULT_FRESHNESS_PRESENT_CRL = Duration.ofDays(30);
    public static final Duration DEFAULT_FRESHNESS_PRESENT_OCSP = Duration.ofDays(24);
    public static final Duration DEFAULT_FRESHNESS_HISTORICAL = Duration.ofMinutes(1);
    public static final OnlineFetching DEFAULT_ONLINE_FETCHING = OnlineFetching.FETCH_IF_NO_OTHER_DATA_AVAILABLE;

    private final HashMap properties = new HashMap<>();

    public SignatureValidationProperties() {
        setContinueAfterFailure(ValidatorContexts.all(),CertificateSources.all(), DEFAULT_CONTINUE_AFTER_FAILURE);
        setRevocationOnlineFetching(ValidatorContexts.all(),CertificateSources.all(), TimeBasedContexts.all(),
                DEFAULT_ONLINE_FETCHING);

        setFreshness(ValidatorContexts.all(),CertificateSources.all(),
                TimeBasedContexts.of(TimeBasedContext.HISTORICAL), DEFAULT_FRESHNESS_HISTORICAL);
        setFreshness(ValidatorContexts.all(),CertificateSources.all(),
                TimeBasedContexts.of(TimeBasedContext.PRESENT),DEFAULT_FRESHNESS_PRESENT_OCSP);
        setFreshness(ValidatorContexts.of(ValidatorContext.CRL_VALIDATOR), CertificateSources.all(),
                TimeBasedContexts.of(TimeBasedContext.PRESENT), DEFAULT_FRESHNESS_PRESENT_CRL);

        setRequiredExtensions(CertificateSources.of(CertificateSource.CRL_ISSUER),
                Collections.singletonList(new KeyUsageExtension(KeyUsage.CRL_SIGN)));
        setRequiredExtensions(CertificateSources.of(CertificateSource.OCSP_ISSUER),
                Collections.singletonList(new ExtendedKeyUsageExtension(
                        Collections.singletonList(ExtendedKeyUsageExtension.OCSP_SIGNING))));
        setRequiredExtensions(CertificateSources.of(CertificateSource.SIGNER_CERT),
                Collections.singletonList(new KeyUsageExtension(KeyUsage.NON_REPUDIATION)));
        List certIssuerRequiredExtensions = new ArrayList<>();
        certIssuerRequiredExtensions.add(new KeyUsageExtension(KeyUsage.KEY_CERT_SIGN));
        certIssuerRequiredExtensions.add(new BasicConstraintsExtension(true));
        setRequiredExtensions(CertificateSources.of(CertificateSource.CERT_ISSUER), certIssuerRequiredExtensions);
        setRequiredExtensions(CertificateSources.of(CertificateSource.TIMESTAMP),
                Collections.singletonList(new ExtendedKeyUsageExtension(
                        Collections.singletonList(ExtendedKeyUsageExtension.TIME_STAMPING))));
    }

    /**
     * Returns the freshness setting for the provided validation context or the default context
     * in milliseconds.
     *
     * @param validationContext the validation context for which to retrieve the freshness setting
     *
     * @return the freshness setting for the provided validation context or the default context in milliseconds
     */
    public Duration getFreshness(ValidationContext validationContext) {
        return this.getParametersValueFor(validationContext.getValidatorContext(),
                validationContext.getCertificateSource(), validationContext.getTimeBasedContext(),
                p -> p.getFreshness());
    }

    /**
     * Sets the freshness setting for the specified validator,
     * time based and certificate source contexts in milliseconds.
     *
     * @param validatorContexts  the validators for which to apply the setting
     * @param certificateSources the certificate sources to
     * @param timeBasedContexts  the date comparison context  for which to apply the setting
     * @param value              the settings value in milliseconds
     *
     * @return this same {@link SignatureValidationProperties} instance.
     */
    public final SignatureValidationProperties setFreshness(ValidatorContexts validatorContexts,
                                                      CertificateSources certificateSources,
                                                      TimeBasedContexts timeBasedContexts, Duration value) {
        setParameterValueFor(validatorContexts.getSet(), certificateSources.getSet(), timeBasedContexts.getSet(),
                p -> p.setFreshness(value));
        return this;
    }

    /**
     * Returns the Continue after failure setting for the provided context or the default context.
     *
     * @param validationContext the context for which to retrieve the Continue after failure setting
     *
     * @return the Continue after failure setting for the provided context or the default context
     */
    public boolean getContinueAfterFailure(ValidationContext validationContext) {
        return this.getParametersValueFor(validationContext.getValidatorContext(),
                validationContext.getCertificateSource(), validationContext.getTimeBasedContext(),
                p -> p.getContinueAfterFailure());
    }

    /**
     * Sets the Continue after failure setting for the provided context.
     *
     * @param validatorContexts  the validators for which to set the Continue after failure setting
     * @param certificateSources the certificateSources for which to set the Continue after failure setting
     * @param value              the Continue after failure setting
     *
     * @return this same {@link SignatureValidationProperties} instance.
     */
    public final SignatureValidationProperties setContinueAfterFailure(ValidatorContexts validatorContexts,
            CertificateSources certificateSources, boolean value) {
        setParameterValueFor(validatorContexts.getSet(), certificateSources.getSet(), TimeBasedContexts.all().getSet(),
                p -> p.setContinueAfterFailure(value));
        return this;
    }

    /**
     * Sets the onlineFetching property representing possible online fetching permissions.
     *
     * @param validationContext the context for which to retrieve the online fetching setting
     *
     * @return the online fetching setting.
     */
    public OnlineFetching getRevocationOnlineFetching(ValidationContext validationContext) {
        return this.getParametersValueFor(validationContext.getValidatorContext(),
                validationContext.getCertificateSource(), validationContext.getTimeBasedContext(),
                p -> p.getOnlineFetching());
    }

    /**
     * Sets the onlineFetching property representing possible online fetching permissions.
     *
     * @param validatorContexts  the validators for which to set this value
     * @param certificateSources the certificate source for which to set this value
     * @param timeBasedContexts  time perspective context, at which validation is happening
     * @param onlineFetching     onlineFetching property value to set
     *
     * @return this same {@link SignatureValidationProperties} instance.
     */
    public final SignatureValidationProperties setRevocationOnlineFetching(ValidatorContexts validatorContexts,
            CertificateSources certificateSources, TimeBasedContexts timeBasedContexts,
            OnlineFetching onlineFetching) {
        setParameterValueFor(validatorContexts.getSet(), certificateSources.getSet(), timeBasedContexts.getSet(),
                p -> p.setOnlineFetching(onlineFetching));
        return this;
    }

    /**
     * Returns required extension for the provided validation context.
     *
     * @param validationContext the validation context for which to retrieve required extensions
     *
     * @return required extensions for the provided validation context
     */
    public List getRequiredExtensions(ValidationContext validationContext) {
        return this.>getParametersValueFor(validationContext.getValidatorContext(),
                validationContext.getCertificateSource(), validationContext.getTimeBasedContext(),
                p -> p.getRequiredExtensions());
    }

    final SignatureValidationProperties setRequiredExtensions(CertificateSources certificateSources,
            List requiredExtensions) {
        // make a defensive copy of  requiredExtensions and already wrap it with unmodifiableList so that we don't have
        // to do this every time it is retrieved. Now we are protected against changes in th passed list and from
        // changes in the returned list
        List copy = Collections.unmodifiableList(
                new ArrayList<>(requiredExtensions));
        setParameterValueFor(ValidatorContexts.all().getSet(), certificateSources.getSet(),
                TimeBasedContexts.all().getSet(), p -> p.setRequiredExtensions(copy));
        return this;
    }

    /**
     * This method executes the setter method for every combination of selected validators and certificateSources
     *
     * @param validatorContexts  the validators to execute the setter on
     * @param certificateSources the certificate sources to execute the setter on
     * @param setter             the setter to execute
     */
    final void setParameterValueFor(EnumSet validatorContexts,
            EnumSet certificateSources, EnumSet timeBasedContexts,
            Consumer setter) {
        for (ValidatorContext validatorContext : validatorContexts) {
            for (CertificateSource certificateSource : certificateSources) {
                for (TimeBasedContext timeBasedContext : timeBasedContexts) {
                    ValidationContext vc = new ValidationContext(validatorContext, certificateSource, timeBasedContext);
                    ContextProperties cProperties = properties.computeIfAbsent(vc, unused -> new ContextProperties());
                    setter.accept(cProperties);
                }
            }
        }
    }

    /**
     * This method executes the getter method to the most granular parameters set down until the getter returns
     * a non-null value
     *
     * @param validatorContext the validator for which the value is to be retrieved
     * @param certSource       the certificate source for which the value is to be retrieved
     * @param getter           the getter to get the value from the parameters set
     * @param               the type of the return value of this method and the getter method
     *
     * @return the first non-null value returned.
     */
     T getParametersValueFor(ValidatorContext validatorContext, CertificateSource certSource,
            TimeBasedContext timeBasedContext, Function getter) {
        // all three match
        ValidationContext c = new ValidationContext(validatorContext, certSource, timeBasedContext);
        if (properties.containsKey(c)) {
            return getter.apply(properties.get(c));
        }
        return null;
    }

    /**
     * Enum representing possible online fetching permissions.
     */
    public enum OnlineFetching {
        /**
         * Permission to always fetch revocation data online.
         */
        ALWAYS_FETCH,
        /**
         * Permission to fetch revocation data online if no other revocation data available.
         */
        FETCH_IF_NO_OTHER_DATA_AVAILABLE,
        /**
         * Forbids fetching revocation data online.
         */
        NEVER_FETCH
    }

    static class ContextProperties {
        private Duration freshness;
        private Boolean continueAfterFailure;
        private OnlineFetching onlineFetching;
        private List requiredExtensions;

        public ContextProperties() {
            // Empty constructor.
        }

        public Boolean getContinueAfterFailure() {
            return continueAfterFailure;
        }

        public void setContinueAfterFailure(Boolean continueAfterFailure) {
            this.continueAfterFailure = continueAfterFailure;
        }

        public Duration getFreshness() {
            return freshness;
        }

        public void setFreshness(Duration value) {
            freshness = value;
        }

        public OnlineFetching getOnlineFetching() {
            return onlineFetching;
        }

        public void setOnlineFetching(OnlineFetching onlineFetching) {
            this.onlineFetching = onlineFetching;
        }

        public List getRequiredExtensions() {
            return requiredExtensions;
        }

        public void setRequiredExtensions(List requiredExtensions) {
            this.requiredExtensions = requiredExtensions;
        }
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy