/*
 * Copyright 2018 Scytl Secure Electronic Voting SA
 *
 * All rights reserved
 *
 * See our extended copyright notice in *file 'Copyright.txt' which is part of this source code package
 */
package com.scytl.cryptolib.certificates.service;

import static junitparams.JUnitParamsRunner.$;

import java.security.KeyPair;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.Security;
import java.security.cert.X509Certificate;
import java.text.ParseException;
import java.util.Calendar;
import java.util.Date;

import org.bouncycastle.jce.provider.BouncyCastleProvider;
import org.junit.AfterClass;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.ExpectedException;
import org.junit.runner.RunWith;

import com.scytl.cryptolib.api.exceptions.CryptoLibException;
import com.scytl.cryptolib.api.exceptions.GeneralCryptoLibException;
import com.scytl.cryptolib.asymmetric.utils.AsymmetricTestDataGenerator;
import com.scytl.cryptolib.certificates.bean.CertificateData;
import com.scytl.cryptolib.certificates.bean.RootCertificateData;
import com.scytl.cryptolib.certificates.bean.ValidityDates;
import com.scytl.cryptolib.certificates.bean.X509DistinguishedName;
import com.scytl.cryptolib.certificates.constants.X509CertificateConstants;
import com.scytl.cryptolib.certificates.constants.X509CertificateTestConstants;
import com.scytl.cryptolib.certificates.cryptoapi.CryptoAPIX509Certificate;
import com.scytl.cryptolib.certificates.factory.CryptoX509Certificate;
import com.scytl.cryptolib.certificates.utils.X509CertificateTestDataGenerator;
import com.scytl.cryptolib.commons.configuration.PolicyFromPropertiesHelper;
import com.scytl.cryptolib.primitives.primes.utils.PrimitivesTestDataGenerator;
import com.scytl.cryptolib.primitives.securerandom.constants.SecureRandomConstants;
import com.scytl.cryptolib.test.tools.bean.TestPrivateKey;
import com.scytl.cryptolib.test.tools.bean.TestPublicKey;
import com.scytl.cryptolib.test.tools.bean.TestX509Certificate;
import com.scytl.cryptolib.test.tools.utils.CommonTestDataGenerator;

import junitparams.JUnitParamsRunner;
import junitparams.Parameters;

/**
 * Tests of the certificates service API input validation.
 */
@RunWith(JUnitParamsRunner.class)
public class CertificatesServiceValidationTest {

    private static CertificatesService _certificatesServiceForDefaultPolicy;

    private static String _whiteSpaceString;

    private static KeyPair _rootKeyPair;

    private static PrivateKey _rootPrivateKey;

    private static CertificateData _certificateData;

    private static CryptoAPIX509Certificate _certificate;

    private static TestPublicKey _nullContentPublicKey;

    private static TestPublicKey _emptyContentPublicKey;

    private static TestPrivateKey _nullContentPrivateKey;

    private static TestPrivateKey _emptyContentPrivateKey;

    private static TestX509Certificate _nullContentX509Certificate;

    private static TestX509Certificate _emptyContentX509Certificate;

    private static CertificateData _certificateDataWithNullIssuerDn;

    private static CertificateData _certificateDataWithNullSubjectDn;

    private static CertificateData _certificateDataWithNullSubjectPublicKey;

    private static CertificateData _certificateDataWithNullValidityDates;

    static {
        try {
            setUp();
        } catch (GeneralCryptoLibException e) {
            throw new CryptoLibException("Setup failed for class "
                + CertificatesServiceValidationTest.class.getSimpleName());
        }
    }

    public static void setUp() throws GeneralCryptoLibException {

        Security.addProvider(new BouncyCastleProvider());

        _whiteSpaceString =
            CommonTestDataGenerator
                .getWhiteSpaceString(CommonTestDataGenerator.getInt(1,
                    SecureRandomConstants.MAXIMUM_GENERATED_STRING_LENGTH));

        _certificatesServiceForDefaultPolicy = new CertificatesService();

        _rootKeyPair = AsymmetricTestDataGenerator.getKeyPairForSigning();
        _rootPrivateKey = _rootKeyPair.getPrivate();

        KeyPair keyPair =
            AsymmetricTestDataGenerator.getKeyPairForSigning();

        _certificateData =
            X509CertificateTestDataGenerator.getCertificateData(keyPair);
        _certificate =
             _certificatesServiceForDefaultPolicy
                .createSignX509Certificate(_certificateData,
                    _rootPrivateKey);

        byte[] emptyByteArray = new byte[0];

        _nullContentPublicKey = new TestPublicKey(null);
        _emptyContentPublicKey = new TestPublicKey(emptyByteArray);

        _nullContentPrivateKey = new TestPrivateKey(null);
        _emptyContentPrivateKey = new TestPrivateKey(emptyByteArray);

        _nullContentX509Certificate =
            new TestX509Certificate(_nullContentPublicKey);
        _emptyContentX509Certificate =
            new TestX509Certificate(_emptyContentPublicKey);

        setCertificateDataWithUnsetData(keyPair.getPublic());
    }

    @AfterClass
    public static void tearDown() {

        Security.removeProvider(BouncyCastleProvider.PROVIDER_NAME);
    }

    @Rule
    public ExpectedException thrown = ExpectedException.none();

    @Test
    @Parameters(method = "createCertificatesService")
    public void testCertificatesServiceCreationValidation(String path,
            String errorMsg) throws GeneralCryptoLibException {

        thrown.expect(GeneralCryptoLibException.class);
        thrown.expectMessage(errorMsg);
        new CertificatesService(path);
    }

    public static Object[] createCertificatesService() {

        return $($(null, "Properties file path is null."),
            $("", "Properties file path is blank."),
            $(_whiteSpaceString, "Properties file path is blank."));
    }

    @Test
    @Parameters(method = "createX509DistinguishedName")
    public void testX509DistinguishedNameCreationValidation(
            String commonName, String country, String orgUnit,
            String organization, String locality, String errorMsg)
            throws GeneralCryptoLibException {

        thrown.expect(GeneralCryptoLibException.class);
        thrown.expectMessage(errorMsg);
        new X509DistinguishedName.Builder(commonName, country)
            .addOrganizationalUnit(orgUnit).addOrganization(organization)
            .addLocality(locality).build();
    }

    public static Object[] createX509DistinguishedName()
            throws GeneralCryptoLibException {

        PolicyFromPropertiesHelper config =
            new PolicyFromPropertiesHelper(
                X509CertificateTestConstants.ROOT_CERTIFICATE_PROPERTIES_FILE_PATH);

        String commonName =
            String
                .valueOf(config
                    .getPropertyValue(X509CertificateTestConstants.ISSUER_COMMON_NAME_PROPERTY_NAME));
        String orgUnit =
            String
                .valueOf(config
                    .getPropertyValue(X509CertificateTestConstants.ISSUER_ORGANIZATIONAL_UNIT_PROPERTY_NAME));
        String organization =
            String
                .valueOf(config
                    .getPropertyValue(X509CertificateTestConstants.ISSUER_ORGANIZATION_PROPERTY_NAME));
        String locality =
            String
                .valueOf(config
                    .getPropertyValue(X509CertificateTestConstants.ISSUER_LOCALITY_PROPERTY_NAME));
        String country =
            String
                .valueOf(config
                    .getPropertyValue(X509CertificateTestConstants.ISSUER_COUNTRY_PROPERTY_NAME));

        int attributeMaxLength =
            X509CertificateConstants.X509_DISTINGUISHED_NAME_ATTRIBUTE_MAX_SIZE;
        int attributeOutOfBoundsLength = attributeMaxLength + 1;
        String aboveMaxLengthAttribute =
            PrimitivesTestDataGenerator
                .getString64(attributeOutOfBoundsLength);

        String attributeWithIllegalChar =
            X509CertificateTestDataGenerator
                .getDnAttributeWithIllegalCharacter();
        String countryAttributeWithIllegalChar =
            X509CertificateTestDataGenerator
                .getCountryDnAttributeWithIllegalCharacter();

        return $(
            $(null, country, orgUnit, organization, locality,
                "Common name is null."),
            $("", country, orgUnit, organization, locality,
                "Common name is blank."),
            $(_whiteSpaceString, country, orgUnit, organization, locality,
                "Common name is blank."),
            $(aboveMaxLengthAttribute, country, orgUnit, organization,
                locality,
                "Common name length must be less than or equal to : "
                    + attributeMaxLength + "; Found "
                    + attributeOutOfBoundsLength),
            $(attributeWithIllegalChar, country, orgUnit, organization,
                locality,
                "Common name contains characters that are not ASCII printable."),
            $(commonName, null, orgUnit, organization, locality,
                "Country is null."),
            $(commonName, "", orgUnit, organization, locality,
                "Country is blank."),
            $(commonName, _whiteSpaceString, orgUnit, organization,
                locality, "Country is blank."),
            $(commonName, aboveMaxLengthAttribute, orgUnit, organization,
                locality,
                "Country length must be less than or equal to : " + 2
                    + "; Found " + attributeOutOfBoundsLength),
            $(commonName, countryAttributeWithIllegalChar, orgUnit,
                organization, locality,
                "Country contains characters outside of allowed set "
                    + SecureRandomConstants.ALPHABET_BASE64),
            $(commonName, country, null, organization, locality,
                "Organizational unit is null."),
            $(commonName, country, aboveMaxLengthAttribute, organization,
                locality,
                "Organizational unit length must be less than or equal to : "
                    + attributeMaxLength + "; Found "
                    + attributeOutOfBoundsLength),
            $(commonName, country, attributeWithIllegalChar, organization,
                locality,
                "Organizational unit contains characters that are not ASCII printable."),
            $(commonName, country, orgUnit, null, locality,
                "Organization is null."),
            $(commonName, country, orgUnit, aboveMaxLengthAttribute,
                locality,
                "Organization length must be less than or equal to : "
                    + attributeMaxLength + "; Found "
                    + attributeOutOfBoundsLength),
            $(commonName, country, orgUnit, attributeWithIllegalChar,
                locality,
                "Organization contains characters that are not ASCII printable."),
            $(commonName, country, orgUnit, organization, null,
                "Locality is null."),
            $(commonName, country, orgUnit, organization,
                aboveMaxLengthAttribute,
                "Locality length must be less than or equal to : "
                    + attributeMaxLength + "; Found "
                    + attributeOutOfBoundsLength),
            $(commonName, country, orgUnit, organization,
                attributeWithIllegalChar,
                "Locality contains characters that are not ASCII printable."));
    }

    @Test
    @Parameters(method = "createValidityDates")
    public void testValidityDatesCreationValidation(Date notBefore,
            Date notAfter, String errorMsg)
            throws GeneralCryptoLibException {

        thrown.expect(GeneralCryptoLibException.class);
        thrown.expectMessage(errorMsg);
        new ValidityDates(notBefore, notAfter);
    }

    public static Object[] createValidityDates()
            throws GeneralCryptoLibException, ParseException {

        PolicyFromPropertiesHelper config =
                new PolicyFromPropertiesHelper(
                    X509CertificateTestConstants.ROOT_CERTIFICATE_PROPERTIES_FILE_PATH);

        int numYearsValidity =
            Integer
                .valueOf(config
                    .getPropertyValue(X509CertificateTestConstants.NUMBER_YEARS_VALIDITY_REMAINING_PROPERTY_NAME));

        Date notBefore = new Date(System.currentTimeMillis());
        Calendar calendar = Calendar.getInstance();
        calendar.add(Calendar.YEAR, numYearsValidity);
        Date notAfter = calendar.getTime();

        Date maxDate =
            X509CertificateTestDataGenerator.getMaximumDateOfValidity();
        Date aboveMaxNotBefore =
            X509CertificateTestDataGenerator.getDateAfterMaximum(1);
        Date aboveMaxNotAfter =
            X509CertificateTestDataGenerator.getDateAfterMaximum(2);

        return $(
            $(null, notAfter, "Starting date of validity is null."),
            $(notBefore, null, "Ending date of validity is null."),
            $(notAfter, notBefore,
                "Starting date of validity " + notAfter.toString()
                    + " is not before ending date of validity "
                    + notBefore.toString()),
            $(aboveMaxNotBefore, aboveMaxNotAfter,
                "Starting date of validity " + aboveMaxNotBefore
                    + " is not before maximum date of validity " + maxDate),
            $(notBefore, aboveMaxNotAfter, "Ending date of validity "
                + aboveMaxNotAfter
                + " is not before maximum date of validity " + maxDate));
    }

    @Test
    @Parameters(method = "setRootCertificateDataSubjectDn")
    public void testRootCertificateDataSubjectDnSettingValidation(
            X509DistinguishedName subjectDn, String errorMsg)
            throws GeneralCryptoLibException {

        thrown.expect(GeneralCryptoLibException.class);
        thrown.expectMessage(errorMsg);
        new RootCertificateData().setSubjectDn(subjectDn);
    }

    public static Object[] setRootCertificateDataSubjectDn() {

        return $($(null, "Subject distinguished name is null."));
    }

    @Test
    @Parameters(method = "setRootCertificateDataValidiatyDates")
    public void testRootCertificateDataValidityDatesSettingValidation(
            ValidityDates validityDates, String errorMsg)
            throws GeneralCryptoLibException {

        thrown.expect(GeneralCryptoLibException.class);
        thrown.expectMessage(errorMsg);
        new RootCertificateData().setValidityDates(validityDates);
    }

    public static Object[] setRootCertificateDataValidiatyDates() {

        return $($(null, "Validity dates object is null."));
    }

    @Test
    @Parameters(method = "setRootCertificateDataSubjectPublicKey")
    public void testRootCertificateDataValidityDatesSettingValidation(
            PublicKey subjectPublicKey, String errorMsg)
            throws GeneralCryptoLibException {

        thrown.expect(GeneralCryptoLibException.class);
        thrown.expectMessage(errorMsg);
        new RootCertificateData().setSubjectPublicKey(subjectPublicKey);
    }

    public static Object[] setRootCertificateDataSubjectPublicKey() {

        return $(
            $(null, "Subject public key is null."),
            $(_nullContentPublicKey, "Subject public key content is null."),
            $(_emptyContentPublicKey,
                "Subject public key content is empty."));
    }

    @Test
    @Parameters(method = "setCertificateDataSubjectDn")
    public void testCertificateDataSubjectDnSettingValidation(
            X509DistinguishedName subjectDn, String errorMsg)
            throws GeneralCryptoLibException {

        thrown.expect(GeneralCryptoLibException.class);
        thrown.expectMessage(errorMsg);
        new CertificateData().setSubjectDn(subjectDn);
    }

    public static Object[] setCertificateDataSubjectDn() {

        return $($(null, "Subject distinguished name is null."));
    }

    @Test
    @Parameters(method = "setCertificateDataIssuerDn")
    public void testCertificateDataIssuerDnSettingValidation(
            X509DistinguishedName issuerDn, String errorMsg)
            throws GeneralCryptoLibException {

        thrown.expect(GeneralCryptoLibException.class);
        thrown.expectMessage(errorMsg);
        new CertificateData().setIssuerDn(issuerDn);
    }

    public static Object[] setCertificateDataIssuerDn() {

        return $($(null, "Issuer distinguished name is null."));
    }

    @Test
    @Parameters(method = "setCertificateDataValidiatyDates")
    public void testCertificateDataValidityDatesSettingValidation(
            ValidityDates validityDates, String errorMsg)
            throws GeneralCryptoLibException {

        thrown.expect(GeneralCryptoLibException.class);
        thrown.expectMessage(errorMsg);
        new CertificateData().setValidityDates(validityDates);
    }

    public static Object[] setCertificateDataValidiatyDates() {

        return $($(null, "Validity dates object is null."));
    }

    @Test
    @Parameters(method = "setCertificateDataSubjectPublicKey")
    public void testCertificateDataValidityDatesSettingValidation(
            PublicKey subjectPublicKey, String errorMsg)
            throws GeneralCryptoLibException {

        thrown.expect(GeneralCryptoLibException.class);
        thrown.expectMessage(errorMsg);
        new CertificateData().setSubjectPublicKey(subjectPublicKey);
    }

    public static Object[] setCertificateDataSubjectPublicKey() {

        return $(
            $(null, "Subject public key is null."),
            $(_nullContentPublicKey, "Subject public key content is null."),
            $(_emptyContentPublicKey,
                "Subject public key content is empty."));
    }

    @Test
    @Parameters(method = "createRootAuthorityCertificate")
    public void testRootAuthorityCertificateCreationValidation(
            RootCertificateData rootCertificateData,
            PrivateKey rootPrivateKey, String errorMsg)
            throws GeneralCryptoLibException {

        thrown.expect(GeneralCryptoLibException.class);
        thrown.expectMessage(errorMsg);
        _certificatesServiceForDefaultPolicy
            .createRootAuthorityX509Certificate(rootCertificateData,
                rootPrivateKey);
    }

    public static Object[] createRootAuthorityCertificate()
            throws GeneralCryptoLibException {

        RootCertificateData rootCertificateData =
            X509CertificateTestDataGenerator
                .getRootCertificateData(_rootKeyPair);

        return $(
            $(null, _rootPrivateKey, "Certificate data is null."),
            $(rootCertificateData, null, "Issuer private key is null."),
            $(rootCertificateData, _nullContentPrivateKey,
                "Issuer private key content is null."),
            $(rootCertificateData, _emptyContentPrivateKey,
                "Issuer private key content is empty."),
            $(_certificateDataWithNullSubjectPublicKey, _rootPrivateKey,
                "Subject public key is null."),
            $(_certificateDataWithNullIssuerDn, _rootPrivateKey,
                "Issuer distinguished name is null."),
            $(_certificateDataWithNullSubjectDn, _rootPrivateKey,
                "Subject distinguished name is null."),
            $(_certificateDataWithNullValidityDates, _rootPrivateKey,
                "Validity dates object is null."));
    }

    @Test
    @Parameters(method = "createIntermediateAuthorityCertificate")
    public void testIntermediateAuthorityCertificateCreationValidation(
            CertificateData certificateData, PrivateKey issuerPrivateKey,
            String errorMsg) throws GeneralCryptoLibException {

        thrown.expect(GeneralCryptoLibException.class);
        thrown.expectMessage(errorMsg);
        _certificatesServiceForDefaultPolicy
            .createIntermediateAuthorityX509Certificate(certificateData,
                issuerPrivateKey);
    }

    public static Object[] createIntermediateAuthorityCertificate() {

        return $(
            $(null, _rootPrivateKey, "Certificate data is null."),
            $(_certificateData, null, "Issuer private key is null."),
            $(_certificateData, _nullContentPrivateKey,
                "Issuer private key content is null."),
            $(_certificateData, _emptyContentPrivateKey,
                "Issuer private key content is empty."),
            $(_certificateDataWithNullSubjectPublicKey, _rootPrivateKey,
                "Subject public key is null."),
            $(_certificateDataWithNullIssuerDn, _rootPrivateKey,
                "Issuer distinguished name is null."),
            $(_certificateDataWithNullSubjectDn, _rootPrivateKey,
                "Subject distinguished name is null."),
            $(_certificateDataWithNullValidityDates, _rootPrivateKey,
                "Validity dates object is null."));
    }

    @Test
    @Parameters(method = "createSignCertificate")
    public void testSignCertificateCreationValidation(
            CertificateData certificateData, PrivateKey issuerPrivateKey,
            String errorMsg) throws GeneralCryptoLibException {

        thrown.expect(GeneralCryptoLibException.class);
        thrown.expectMessage(errorMsg);
        _certificatesServiceForDefaultPolicy.createSignX509Certificate(
            certificateData, issuerPrivateKey);
    }

    public static Object[] createSignCertificate() {

        return $(
            $(null, _rootPrivateKey, "Certificate data is null."),
            $(_certificateData, null, "Issuer private key is null."),
            $(_certificateData, _nullContentPrivateKey,
                "Issuer private key content is null."),
            $(_certificateData, _emptyContentPrivateKey,
                "Issuer private key content is empty."),
            $(_certificateDataWithNullSubjectDn, _rootPrivateKey,
                "Subject distinguished name is null."),
            $(_certificateDataWithNullSubjectPublicKey, _rootPrivateKey,
                "Subject public key is null."),
            $(_certificateDataWithNullIssuerDn, _rootPrivateKey,
                "Issuer distinguished name is null."),
            $(_certificateDataWithNullSubjectDn, _rootPrivateKey,
                "Subject distinguished name is null."),
            $(_certificateDataWithNullValidityDates, _rootPrivateKey,
                "Validity dates object is null."));
    }

    @Test
    @Parameters(method = "createEncryptionCertificate")
    public void testEncryptionCertificateCreationValidation(
            CertificateData certificateData, PrivateKey issuerPrivateKey,
            String errorMsg) throws GeneralCryptoLibException {

        thrown.expect(GeneralCryptoLibException.class);
        thrown.expectMessage(errorMsg);
        _certificatesServiceForDefaultPolicy
            .createEncryptionX509Certificate(certificateData,
                issuerPrivateKey);
    }

    public static Object[] createEncryptionCertificate() {

        return $(
            $(null, _rootPrivateKey, "Certificate data is null."),
            $(_certificateData, null, "Issuer private key is null."),
            $(_certificateData, _nullContentPrivateKey,
                "Issuer private key content is null."),
            $(_certificateDataWithNullSubjectPublicKey, _rootPrivateKey,
                "Subject public key is null."),
            $(_certificateDataWithNullIssuerDn, _rootPrivateKey,
                "Issuer distinguished name is null."),
            $(_certificateDataWithNullSubjectDn, _rootPrivateKey,
                "Subject distinguished name is null."),
            $(_certificateDataWithNullValidityDates, _rootPrivateKey,
                "Validity dates object is null."));
    }

    @Test
    @Parameters(method = "createCertificateFromX509Certificate")
    public void testCertificateFromX509CertificateCreationValidation(
            X509Certificate x509Certificate, String errorMsg)
            throws GeneralCryptoLibException {

        thrown.expect(GeneralCryptoLibException.class);
        thrown.expectMessage(errorMsg);
        new CryptoX509Certificate(x509Certificate);
    }

    public static Object[] createCertificateFromX509Certificate() {

        return $(
            $(null, "X509 certificate is null."),
            $(_nullContentX509Certificate,
                "X509 certificate content is null."),
            $(_emptyContentX509Certificate,
                "X509 certificate content is empty."));
    }

    @Test
    @Parameters(method = "verifyCertificate")
    public void testCertificateVerificationValidation(
            PublicKey issuerPublicKey, String errorMsg)
            throws GeneralCryptoLibException {

        thrown.expect(GeneralCryptoLibException.class);
        thrown.expectMessage(errorMsg);
        _certificate.verify(issuerPublicKey);
    }

    public static Object[] verifyCertificate() {

        return $(
            $(null, "Issuer public key is null."),
            $(_nullContentPublicKey, "Issuer public key content is null."),
            $(_emptyContentPublicKey,
                "Issuer public key content is empty."));
    }

    @Test
    @Parameters(method = "checkCertificateDateValidity")
    public void testCertificateDateValidityCheckValidation(Date date,
            String errorMsg) throws GeneralCryptoLibException {

        thrown.expect(GeneralCryptoLibException.class);
        thrown.expectMessage(errorMsg);
        _certificate.checkValidity(date);
    }

    public static Object[] checkCertificateDateValidity() {

        return $($(null, "Date is null."));
    }

    private static void setCertificateDataWithUnsetData(
            final PublicKey publicKey) throws GeneralCryptoLibException {

        X509DistinguishedName issuerDn =
            X509CertificateTestDataGenerator.getRootDistinguishedName();
        X509DistinguishedName subjectDn =
            X509CertificateTestDataGenerator.getDistinguishedName();
        ValidityDates validityDates =
            X509CertificateTestDataGenerator.getRootValidityDates();

        _certificateDataWithNullIssuerDn = new CertificateData();
        _certificateDataWithNullIssuerDn.setSubjectPublicKey(publicKey);
        _certificateDataWithNullIssuerDn.setSubjectDn(subjectDn);
        _certificateDataWithNullIssuerDn.setValidityDates(validityDates);

        _certificateDataWithNullSubjectDn = new CertificateData();
        _certificateDataWithNullSubjectDn.setSubjectPublicKey(publicKey);
        _certificateDataWithNullSubjectDn.setIssuerDn(issuerDn);
        _certificateDataWithNullSubjectDn.setValidityDates(validityDates);

        _certificateDataWithNullSubjectPublicKey = new CertificateData();
        _certificateDataWithNullSubjectPublicKey.setIssuerDn(issuerDn);
        _certificateDataWithNullSubjectPublicKey.setSubjectDn(subjectDn);
        _certificateDataWithNullSubjectPublicKey
            .setValidityDates(validityDates);

        _certificateDataWithNullValidityDates = new CertificateData();
        _certificateDataWithNullValidityDates
            .setSubjectPublicKey(publicKey);
        _certificateDataWithNullValidityDates.setIssuerDn(issuerDn);
        _certificateDataWithNullValidityDates.setSubjectDn(subjectDn);
    }
}
