/************************************************************************* * * * CESeCore: CE Security Core * * * * This software is free software; you can redistribute it and/or * * modify it under the terms of the GNU Lesser General Public * * License as published by the Free Software Foundation; either * * version 2.1 of the License, or any later version. * * * * See terms of license at gnu.org. * * * *************************************************************************/ package org.cesecore.certificates.certificateprofile; import java.io.Serializable; import java.security.PublicKey; import java.util.ArrayList; import java.util.Arrays; import java.util.Calendar; import java.util.Collection; import java.util.Collections; import java.util.HashMap; import java.util.Iterator; import java.util.LinkedHashMap; import java.util.LinkedHashSet; import java.util.List; import java.util.Map; import java.util.Map.Entry; import java.util.Set; import java.util.StringTokenizer; import org.apache.commons.lang.ArrayUtils; import org.apache.commons.lang.StringUtils; import org.apache.log4j.Logger; import org.bouncycastle.asn1.ocsp.OCSPObjectIdentifiers; import org.bouncycastle.asn1.x509.Extension; import org.bouncycastle.asn1.x509.KeyPurposeId; import org.cesecore.certificates.ca.ApprovalRequestType; import org.cesecore.certificates.certificate.CertificateConstants; import org.cesecore.certificates.certificate.IllegalKeyException; import org.cesecore.certificates.util.AlgorithmConstants; import org.cesecore.certificates.util.AlgorithmTools; import org.cesecore.certificates.util.DNFieldExtractor; import org.cesecore.certificates.util.DnComponents; import org.cesecore.internal.InternalResources; import org.cesecore.internal.UpgradeableDataHashMap; import org.cesecore.keys.util.KeyTools; import org.cesecore.util.CertTools; import org.cesecore.util.ValidityDate; /** * CertificateProfile is a basic class used to customize a certificate configuration or be inherited by fixed certificate profiles. * * @version $Id: CertificateProfile.java 29578 2018-08-07 12:19:15Z jekaterina_b_helmes $ */ public class CertificateProfile extends UpgradeableDataHashMap implements Serializable, Cloneable { private static final Logger log = Logger.getLogger(CertificateProfile.class); /** Internal localization of logs and errors */ private static final InternalResources intres = InternalResources.getInstance(); // Public Constants public static final float LATEST_VERSION = (float) 46.0; public static final String ROOTCAPROFILENAME = "ROOTCA"; public static final String SUBCAPROFILENAME = "SUBCA"; public static final String ENDUSERPROFILENAME = "ENDUSER"; public static final String OCSPSIGNERPROFILENAME = "OCSPSIGNER"; public static final String SERVERPROFILENAME = "SERVER"; public static final String HARDTOKENAUTHPROFILENAME = "HARDTOKEN_AUTH"; public static final String HARDTOKENAUTHENCPROFILENAME = "HARDTOKEN_AUTHENC"; public static final String HARDTOKENENCPROFILENAME = "HARDTOKEN_ENC"; public static final String HARDTOKENSIGNPROFILENAME = "HARDTOKEN_SIGN"; public static final List FIXED_PROFILENAMES = new ArrayList<>(); static { FIXED_PROFILENAMES.add(ROOTCAPROFILENAME); FIXED_PROFILENAMES.add(SUBCAPROFILENAME); FIXED_PROFILENAMES.add(ENDUSERPROFILENAME); FIXED_PROFILENAMES.add(OCSPSIGNERPROFILENAME); FIXED_PROFILENAMES.add(SERVERPROFILENAME); FIXED_PROFILENAMES.add(HARDTOKENAUTHPROFILENAME); FIXED_PROFILENAMES.add(HARDTOKENAUTHENCPROFILENAME); FIXED_PROFILENAMES.add(HARDTOKENENCPROFILENAME); FIXED_PROFILENAMES.add(HARDTOKENSIGNPROFILENAME); } /** * Determines if a de-serialized file is compatible with this class. * * Maintainers must change this value if and only if the new version of this class is not compatible with old versions. See Sun docs for details. * */ private static final long serialVersionUID = -8069608639716545206L; /** Microsoft Template Constants */ public static final String MSTEMPL_DOMAINCONTROLLER = "DomainController"; public static final String[] AVAILABLE_MSTEMPLATES = { MSTEMPL_DOMAINCONTROLLER }; public static final String TRUE = "true"; public static final String FALSE = "false"; /** * Determines the access rights in CV Certificates. CV Certificates is used by EU EAC ePassports and is issued by a CVC CA. DG3 is access to * fingerprints and DG4 access to iris. */ public static final int CVC_ACCESS_NONE = 0; public static final int CVC_ACCESS_DG3 = 1; public static final int CVC_ACCESS_DG4 = 2; public static final int CVC_ACCESS_DG3DG4 = 3; // For signature terminals (defined in version 2.10 of the EAC specification) public static final int CVC_ACCESS_SIGN = 16; public static final int CVC_ACCESS_QUALSIGN = 32; public static final int CVC_ACCESS_SIGN_AND_QUALSIGN = 48; /** * CVC terminal types. Controls which set of roles and access rights are available. */ public static final int CVC_TERMTYPE_IS = 0; /** Authentication terminal */ public static final int CVC_TERMTYPE_AT = 1; /** Signature terminal */ public static final int CVC_TERMTYPE_ST = 2; /** Accreditation Body DV for signature terminals. ABs accredits CSPs */ public static final int CVC_SIGNTERM_DV_AB = 0; /** Certification Service Provider DV for signature terminals */ public static final int CVC_SIGNTERM_DV_CSP = 1; /** Supported certificate versions. */ public static final String VERSION_X509V3 = "X509v3"; public static final String CUSTOMPROFILENAME = "CUSTOM"; /** Constant indicating that any CA can be used with this certificate profile. */ public static final int ANYCA = -1; /** Constant indicating that any elliptic curve may be used with this profile. */ public static final String ANY_EC_CURVE = "ANY_EC_CURVE"; /** Constant holding the default available bit lengths for certificate profiles */ public static final int[] DEFAULTBITLENGTHS = { 0, 192, 224, 239, 256, 384, 512, 521, 1024, 1536, 2048, 3072, 4096, 6144, 8192 }; public static final byte[] DEFAULT_CVC_RIGHTS_AT = { 0, 0, 0, 0, 0 }; /** Constants for validity and private key usage period. */ public static final String DEFAULT_CERTIFICATE_VALIDITY = "2y"; /** Constant for default validity for fixed profiles is 25 years including 6 or 7 leap days. */ public static final String DEFAULT_CERTIFICATE_VALIDITY_FOR_FIXED_CA = "25y7d"; /** Constant for default validity offset (for backward compatibility': -10m'!) */ public static final String DEFAULT_CERTIFICATE_VALIDITY_OFFSET = "-10m"; public static final long DEFAULT_PRIVATE_KEY_USAGE_PERIOD_OFFSET = 0; public static final long DEFAULT_PRIVATE_KEY_USAGE_PERIOD_LENGTH = 730 * 24 * 3600; // Profile fields protected static final String CERTVERSION = "certversion"; @Deprecated protected static final String VALIDITY = "validity"; protected static final String ENCODED_VALIDITY = "encodedvalidity"; protected static final String USE_CERTIFICATE_VALIDITY_OFFSET = "usecertificatevalidityoffset"; protected static final String CERTIFICATE_VALIDITY_OFFSET = "certificatevalidityoffset"; protected static final String USE_EXPIRATION_RESTRICTION_FOR_WEEKDAYS = "useexpirationrestrictionforweekdays"; protected static final String EXPIRATION_RESTRICTION_FOR_WEEKDAYS_BEFORE = "expirationrestrictionforweekdaysbefore"; protected static final String EXPIRATION_RESTRICTION_WEEKDAYS = "expirationrestrictionweekdays"; protected static final String ALLOWVALIDITYOVERRIDE = "allowvalidityoverride"; protected static final String ALLOWKEYUSAGEOVERRIDE = "allowkeyusageoverride"; protected static final String ALLOWBACKDATEDREVOCATION = "allowbackdatedrevokation"; protected static final String ALLOWEXTENSIONOVERRIDE = "allowextensionoverride"; protected static final String ALLOWDNOVERRIDE = "allowdnoverride"; protected static final String ALLOWDNOVERRIDEBYEEI = "allowdnoverridebyeei"; protected static final String ALLOWCERTSNOVERIDE = "allowcertsnoverride"; protected static final String AVAILABLEKEYALGORITHMS = "availablekeyalgorithms"; protected static final String AVAILABLEECCURVES = "availableeccurves"; protected static final String AVAILABLEBITLENGTHS = "availablebitlengths"; protected static final String MINIMUMAVAILABLEBITLENGTH = "minimumavailablebitlength"; protected static final String MAXIMUMAVAILABLEBITLENGTH = "maximumavailablebitlength"; public static final String TYPE = "type"; protected static final String AVAILABLECAS = "availablecas"; protected static final String USEDPUBLISHERS = "usedpublishers"; protected static final String USECNPOSTFIX = "usecnpostfix"; protected static final String CNPOSTFIX = "cnpostfix"; protected static final String USESUBJECTDNSUBSET = "usesubjectdnsubset"; protected static final String SUBJECTDNSUBSET = "subjectdnsubset"; protected static final String USESUBJECTALTNAMESUBSET = "usesubjectaltnamesubset"; protected static final String SUBJECTALTNAMESUBSET = "subjectaltnamesubset"; protected static final String USEDCERTIFICATEEXTENSIONS = "usedcertificateextensions"; /** * @deprecated since 6.8.0, where approval settings and profiles became interlinked. */ @Deprecated protected static final String APPROVALSETTINGS = "approvalsettings"; /** * @deprecated since 6.6.0, use the appropriate approval profile instead * Needed for a while in order to be able to import old statedumps from 6.5 and earlier */ @Deprecated public static final String NUMOFREQAPPROVALS = "numofreqapprovals"; /** * @deprecated since 6.8.0, where approval settings and profiles became interlinked. */ @Deprecated protected static final String APPROVALPROFILE = "approvalProfile"; protected static final String APPROVALS = "approvals"; protected static final String SIGNATUREALGORITHM = "signaturealgorithm"; protected static final String USECERTIFICATESTORAGE = "usecertificatestorage"; protected static final String STORECERTIFICATEDATA = "storecertificatedata"; protected static final String STORESUBJECTALTNAME = "storesubjectaltname"; // // CRL extensions protected static final String USECRLNUMBER = "usecrlnumber"; protected static final String CRLNUMBERCRITICAL = "crlnumbercritical"; // // Certificate extensions protected static final String USEBASICCONSTRAINTS = "usebasicconstrants"; protected static final String BASICCONSTRAINTSCRITICAL = "basicconstraintscritical"; protected static final String USEPATHLENGTHCONSTRAINT = "usepathlengthconstraint"; protected static final String PATHLENGTHCONSTRAINT = "pathlengthconstraint"; protected static final String USEKEYUSAGE = "usekeyusage"; protected static final String KEYUSAGECRITICAL = "keyusagecritical"; protected static final String KEYUSAGE = "keyusage"; protected static final String USESUBJECTKEYIDENTIFIER = "usesubjectkeyidentifier"; protected static final String SUBJECTKEYIDENTIFIERCRITICAL = "subjectkeyidentifiercritical"; protected static final String USEAUTHORITYKEYIDENTIFIER = "useauthoritykeyidentifier"; protected static final String AUTHORITYKEYIDENTIFIERCRITICAL = "authoritykeyidentifiercritical"; protected static final String USESUBJECTALTERNATIVENAME = "usesubjectalternativename"; protected static final String SUBJECTALTERNATIVENAMECRITICAL = "subjectalternativenamecritical"; protected static final String USEISSUERALTERNATIVENAME = "useissueralternativename"; protected static final String ISSUERALTERNATIVENAMECRITICAL = "issueralternativenamecritical"; protected static final String USECRLDISTRIBUTIONPOINT = "usecrldistributionpoint"; protected static final String USEDEFAULTCRLDISTRIBUTIONPOINT = "usedefaultcrldistributionpoint"; protected static final String CRLDISTRIBUTIONPOINTCRITICAL = "crldistributionpointcritical"; protected static final String CRLDISTRIBUTIONPOINTURI = "crldistributionpointuri"; protected static final String CRLISSUER = "crlissuer"; protected static final String USEFRESHESTCRL = "usefreshestcrl"; protected static final String USECADEFINEDFRESHESTCRL = "usecadefinedfreshestcrl"; protected static final String FRESHESTCRLURI = "freshestcrluri"; protected static final String USECERTIFICATEPOLICIES = "usecertificatepolicies"; protected static final String CERTIFICATEPOLICIESCRITICAL = "certificatepoliciescritical"; /** Policy containing oid, User Notice and Cps Url */ protected static final String CERTIFICATE_POLICIES = "certificatepolicies"; protected static final String USEEXTENDEDKEYUSAGE = "useextendedkeyusage"; protected static final String EXTENDEDKEYUSAGE = "extendedkeyusage"; protected static final String EXTENDEDKEYUSAGECRITICAL = "extendedkeyusagecritical"; protected static final String USEDOCUMENTTYPELIST = "usedocumenttypelist"; protected static final String DOCUMENTTYPELISTCRITICAL = "documenttypelistcritical"; protected static final String DOCUMENTTYPELIST = "documenttypelist"; protected static final String USEOCSPNOCHECK = "useocspnocheck"; protected static final String USEAUTHORITYINFORMATIONACCESS = "useauthorityinformationaccess"; protected static final String USEOCSPSERVICELOCATOR = "useocspservicelocator"; protected static final String USEDEFAULTCAISSUER = "usedefaultcaissuer"; protected static final String USEDEFAULTOCSPSERVICELOCATOR = "usedefaultocspservicelocator"; protected static final String OCSPSERVICELOCATORURI = "ocspservicelocatoruri"; protected static final String USECAISSUERS = "usecaissuersuri"; protected static final String CAISSUERS = "caissuers"; protected static final String USELDAPDNORDER = "useldapdnorder"; protected static final String USEMICROSOFTTEMPLATE = "usemicrosofttemplate"; protected static final String MICROSOFTTEMPLATE = "microsofttemplate"; protected static final String USECARDNUMBER = "usecardnumber"; protected static final String USEQCSTATEMENT = "useqcstatement"; protected static final String USEPKIXQCSYNTAXV2 = "usepkixqcsyntaxv2"; protected static final String QCSTATEMENTCRITICAL = "useqcstatementcritical"; protected static final String QCSTATEMENTRANAME = "useqcstatementraname"; protected static final String QCSSEMANTICSID = "useqcsematicsid"; protected static final String USEQCETSIQCCOMPLIANCE = "useqcetsiqccompliance"; protected static final String USEQCETSIVALUELIMIT = "useqcetsivaluelimit"; protected static final String QCETSIVALUELIMIT = "qcetsivaluelimit"; protected static final String QCETSIVALUELIMITEXP = "qcetsivaluelimitexp"; protected static final String QCETSIVALUELIMITCURRENCY = "qcetsivaluelimitcurrency"; protected static final String USEQCETSIRETENTIONPERIOD = "useqcetsiretentionperiod"; protected static final String QCETSIRETENTIONPERIOD = "qcetsiretentionperiod"; protected static final String USEQCETSISIGNATUREDEVICE = "useqcetsisignaturedevice"; protected static final String USEQCETSITYPE = "useqcetsitype"; protected static final String QCETSITYPE = "qcetsitype"; protected static final String QCETSIPDS = "qcetsipds"; /** @deprecated since EJBCA 6.6.1. It was only used in 6.6.0, and is needed to handle upgrades from that version * PDS URLs are now handled in QCETSIPDS */ @Deprecated protected static final String QCETSIPDSURL = "qcetsipdsurl"; /** @deprecated since EJBCA 6.6.1. It was only used in 6.6.0, and is needed to handle upgrades from that version * PDS URLs are now handled in QCETSIPDS */ @Deprecated protected static final String QCETSIPDSLANG = "qcetsipdslang"; protected static final String USEQCCUSTOMSTRING = "useqccustomstring"; protected static final String QCCUSTOMSTRINGOID = "qccustomstringoid"; protected static final String QCCUSTOMSTRINGTEXT = "qccustomstringtext"; protected static final String USENAMECONSTRAINTS = "usenameconstraints"; protected static final String NAMECONSTRAINTSCRITICAL = "nameconstraintscritical"; protected static final String USESUBJECTDIRATTRIBUTES = "usesubjectdirattributes"; protected static final String CVCTERMINALTYPE = "cvctermtype"; protected static final String CVCACCESSRIGHTS = "cvcaccessrights"; protected static final String CVCLONGACCESSRIGHTS = "cvclongaccessrights"; protected static final String CVCSIGNTERMDVTYPE = "cvcsigntermdvtype"; protected static final String USEPRIVKEYUSAGEPERIOD = "useprivkeyusageperiod"; protected static final String USEPRIVKEYUSAGEPERIODNOTBEFORE = "useprivkeyusageperiodnotbefore"; protected static final String USEPRIVKEYUSAGEPERIODNOTAFTER = "useprivkeyusageperiodnotafter"; protected static final String PRIVKEYUSAGEPERIODSTARTOFFSET = "privkeyusageperiodstartoffset"; protected static final String PRIVKEYUSAGEPERIODLENGTH = "privkeyusageperiodlength"; protected static final String USECERTIFICATETRANSPARENCYINCERTS = "usecertificatetransparencyincerts"; protected static final String USECERTIFICATETRANSPARENCYINOCSP = "usecertificatetransparencyinocsp"; protected static final String USECERTIFICATETRANSPARENCYINPUBLISHERS = "usecertificatetransparencyinpublisher"; /* Certificate Transparency */ protected static final String CTSUBMITEXISTING = "ctsubmitexisting"; protected static final String CTLOGS = "ctlogs"; protected static final String CTLABELS = "ctlabels"; @Deprecated protected static final String CT_MIN_TOTAL_SCTS = "ctminscts"; // This key is the same as in previous versions @Deprecated protected static final String CT_MIN_TOTAL_SCTS_OCSP = "ctminsctsocsp"; // This key is also the same as in previous versions @Deprecated protected static final String CT_MAX_SCTS = "ctmaxscts"; // Only used to fetch old value after upgrade, replaced by CT_MAX_NON_MANDATORY_SCTS and CT_MAX_MANDATORY_SCTS @Deprecated protected static final String CT_MAX_SCTS_OCSP = "ctmaxsctsocsp"; // Only used to fetch old value after upgrade, replaced by CT_MAX_NONMANDATORY_SCTS_OCSP and CT_MAX_MANDATORY_SCTS /* All deprecated below were removed in 6.10.1. Keep for upgrade purposes or move keys to UpgradeSessionBean */ @Deprecated protected static final String CT_MIN_MANDATORY_SCTS = "ctminmandatoryscts"; @Deprecated protected static final String CT_MAX_MANDATORY_SCTS = "ctmaxmandatoryscts"; @Deprecated protected static final String CT_MIN_MANDATORY_SCTS_OCSP = "ctminmandatorysctsocsp"; @Deprecated protected static final String CT_MAX_MANDATORY_SCTS_OCSP = "ctmaxmandatorysctsocsp"; @Deprecated protected static final String CT_MIN_NONMANDATORY_SCTS = "ctminnonmandatoryscts"; @Deprecated protected static final String CT_MAX_NONMANDATORY_SCTS = "ctmaxnonmandatoryscts"; @Deprecated protected static final String CT_MIN_NONMANDATORY_SCTS_OCSP = "ctminnonmandatorysctsocsp"; @Deprecated protected static final String CT_MAX_NONMANDATORY_SCTS_OCSP = "ctmaxnonmandatorysctsocsp"; protected static final String CT_SCTS_MIN = "ctsctsmin"; protected static final String CT_SCTS_MAX = "ctsctsmax"; protected static final String CT_SCTS_MIN_OCSP = "ctsctsminocsp"; protected static final String CT_SCTS_MAX_OCSP = "ctsctsmaxocsp"; protected static final String CT_NUMBER_OF_SCTS_BY_VALIDITY = "ctnumberofsctsbyvalidity"; protected static final String CT_NUMBER_OF_SCTS_BY_CUSTOM = "ctnumberofsctsbycustom"; protected static final String CT_MAX_NUMBER_OF_SCTS_BY_VALIDITY = "ctmaxnumberofsctsbyvalidity"; protected static final String CT_MAX_NUMBER_OF_SCTS_BY_CUSTOM = "ctmaxnumberofsctsbycustom"; protected static final String CTMAXRETRIES = "ctmaxretries"; protected static final String USERSINGLEACTIVECERTIFICATECONSTRAINT = "usesingleactivecertificateconstraint"; protected static final String USECUSTOMDNORDER = "usecustomdnorder"; protected static final String USECUSTOMDNORDERLDAP = "usecustomdnorderldap"; protected static final String CUSTOMDNORDER = "customdnorder"; protected static final String OVERRIDABLEEXTENSIONOIDS = "overridableextensionoids"; protected static final String NONOVERRIDABLEEXTENSIONOIDS = "nonoverridableextensionoids"; /** * OID for creating Smartcard Number Certificate Extension SEIS Cardnumber Extension according to SS 614330/31 */ public static final String OID_CARDNUMBER = "1.2.752.34.2.1"; /** Constants holding the use properties for certificate extensions */ protected static final HashMap useStandardCertificateExtensions = new HashMap<>(); { useStandardCertificateExtensions.put(USEBASICCONSTRAINTS, Extension.basicConstraints.getId()); useStandardCertificateExtensions.put(USEKEYUSAGE, Extension.keyUsage.getId()); useStandardCertificateExtensions.put(USESUBJECTKEYIDENTIFIER, Extension.subjectKeyIdentifier.getId()); useStandardCertificateExtensions.put(USEAUTHORITYKEYIDENTIFIER, Extension.authorityKeyIdentifier.getId()); useStandardCertificateExtensions.put(USESUBJECTALTERNATIVENAME, Extension.subjectAlternativeName.getId()); useStandardCertificateExtensions.put(USEISSUERALTERNATIVENAME, Extension.issuerAlternativeName.getId()); useStandardCertificateExtensions.put(USECRLDISTRIBUTIONPOINT, Extension.cRLDistributionPoints.getId()); useStandardCertificateExtensions.put(USEFRESHESTCRL, Extension.freshestCRL.getId()); useStandardCertificateExtensions.put(USECERTIFICATEPOLICIES, Extension.certificatePolicies.getId()); useStandardCertificateExtensions.put(USEEXTENDEDKEYUSAGE, Extension.extendedKeyUsage.getId()); useStandardCertificateExtensions.put(USEDOCUMENTTYPELIST, "2.23.136.1.1.6.2"); useStandardCertificateExtensions.put(USEQCSTATEMENT, Extension.qCStatements.getId()); useStandardCertificateExtensions.put(USENAMECONSTRAINTS, Extension.nameConstraints.getId()); useStandardCertificateExtensions.put(USESUBJECTDIRATTRIBUTES, Extension.subjectDirectoryAttributes.getId()); useStandardCertificateExtensions.put(USEAUTHORITYINFORMATIONACCESS, Extension.authorityInfoAccess.getId()); useStandardCertificateExtensions.put(USEPRIVKEYUSAGEPERIOD, Extension.privateKeyUsagePeriod.getId()); useStandardCertificateExtensions.put(USEOCSPNOCHECK, OCSPObjectIdentifiers.id_pkix_ocsp_nocheck.getId()); useStandardCertificateExtensions.put(USEMICROSOFTTEMPLATE, CertTools.OID_MSTEMPLATE); useStandardCertificateExtensions.put(USECARDNUMBER, OID_CARDNUMBER); } // Old values used to upgrade from v22 to v23 protected static final String CERTIFICATEPOLICYID = "certificatepolicyid"; /** Policy Notice Url to CPS field alias in the data structure */ protected static final String POLICY_NOTICE_CPS_URL = "policynoticecpsurl"; /** Policy Notice User Notice field alias in the data structure */ protected static final String POLICY_NOTICE_UNOTICE_TEXT = "policynoticeunoticetext"; // Public Methods /** * Creates a new instance of CertificateProfile. The default contructor creates a basic CertificateProfile * that is the same as an End User certificateProfile, except that there are _no_ key usages. this means that a certificate * issued with a default profile should not be usable for anything. Should be used for testing and where you want to create your own * CertificateProfile for specific purposes. * */ public CertificateProfile() { setCommonDefaults(); } /** * Creates a new instance of CertificateProfile * * These settings are general for all sub-profiles, only differing values are overridden in the sub-profiles. If changing any present value here * you must therefore go through all sub-profiles and add an override there. I.e. only add new values here, don't change any present settings. * * @param type * one of CertificateProfileConstants.CERTPROFILE_FIXED_XX, for example CertificateConstants.CERTPROFILE_NO_PROFILE, CERTPROFILE_NO_ENDUSER, etc */ public CertificateProfile(int type) { setCommonDefaults(); setDefaultValues(type); } private void setCommonDefaults() { setType(CertificateConstants.CERTTYPE_ENDENTITY); setCertificateVersion(VERSION_X509V3); setEncodedValidity(DEFAULT_CERTIFICATE_VALIDITY); setUseCertificateValidityOffset(false); setCertificateValidityOffset(DEFAULT_CERTIFICATE_VALIDITY_OFFSET); setUseExpirationRestrictionForWeekdays(false); setExpirationRestrictionForWeekdaysExpireBefore(true); setDefaultExpirationRestrictionWeekdays(); setAllowValidityOverride(false); setAllowExtensionOverride(false); setAllowDNOverride(false); setAllowDNOverrideByEndEntityInformation(false); setAllowBackdatedRevocation(false); setUseCertificateStorage(true); setStoreCertificateData(true); setStoreSubjectAlternativeName(true); // New profiles created after EJBCA 6.6.0 will store SAN by default setUseBasicConstraints(true); setBasicConstraintsCritical(true); setUseSubjectKeyIdentifier(true); setSubjectKeyIdentifierCritical(false); setUseAuthorityKeyIdentifier(true); setAuthorityKeyIdentifierCritical(false); setUseSubjectAlternativeName(true); setSubjectAlternativeNameCritical(false); setUseIssuerAlternativeName(true); setIssuerAlternativeNameCritical(false); setUseCRLDistributionPoint(false); setUseDefaultCRLDistributionPoint(false); setCRLDistributionPointCritical(false); setCRLDistributionPointURI(""); setUseFreshestCRL(false); setUseCADefinedFreshestCRL(false); setFreshestCRLURI(""); setCRLIssuer(null); setUseCertificatePolicies(false); setCertificatePoliciesCritical(false); ArrayList policies = new ArrayList<>(); setCertificatePolicies(policies); setAvailableKeyAlgorithmsAsList(AlgorithmTools.getAvailableKeyAlgorithms()); setAvailableEcCurvesAsList(Arrays.asList(ANY_EC_CURVE)); setAvailableBitLengths(DEFAULTBITLENGTHS); setSignatureAlgorithm(null); setUseKeyUsage(true); setKeyUsage(new boolean[9]); setAllowKeyUsageOverride(false); setKeyUsageCritical(true); setUseExtendedKeyUsage(false); setExtendedKeyUsage(new ArrayList()); setExtendedKeyUsageCritical(false); setUseDocumentTypeList(false); setDocumentTypeListCritical(false); setDocumentTypeList(new ArrayList()); ArrayList availablecas = new ArrayList<>(); availablecas.add(Integer.valueOf(ANYCA)); setAvailableCAs(availablecas); setPublisherList(new ArrayList()); setUseOcspNoCheck(false); setUseLdapDnOrder(true); setUseCustomDnOrder(false); setUseMicrosoftTemplate(false); setMicrosoftTemplate(""); setUseCardNumber(false); setUseCNPostfix(false); setCNPostfix(""); setUseSubjectDNSubSet(false); setSubjectDNSubSet(new ArrayList()); setUseSubjectAltNameSubSet(false); setSubjectAltNameSubSet(new ArrayList()); setUsePathLengthConstraint(false); setPathLengthConstraint(0); setUseQCStatement(false); setUsePkixQCSyntaxV2(false); setQCStatementCritical(false); setQCStatementRAName(null); setQCSemanticsId(null); setUseQCEtsiQCCompliance(false); setUseQCEtsiSignatureDevice(false); setUseQCEtsiValueLimit(false); setQCEtsiValueLimit(0); setQCEtsiValueLimitExp(0); setQCEtsiValueLimitCurrency(null); setUseQCEtsiRetentionPeriod(false); setQCEtsiRetentionPeriod(0); setUseQCCustomString(false); setQCCustomStringOid(null); setQCCustomStringText(null); setQCEtsiPds(null); setQCEtsiType(null); setUseCertificateTransparencyInCerts(false); setUseCertificateTransparencyInOCSP(false); setUseCertificateTransparencyInPublishers(false); setUseSubjectDirAttributes(false); setUseNameConstraints(false); setUseAuthorityInformationAccess(false); setCaIssuers(new ArrayList()); setUseDefaultCAIssuer(false); setUseDefaultOCSPServiceLocator(false); setOCSPServiceLocatorURI(""); // Default to have access to fingerprint and iris setCVCAccessRights(CertificateProfile.CVC_ACCESS_DG3DG4); setUsedCertificateExtensions(new ArrayList()); setApprovals(new LinkedHashMap()); // PrivateKeyUsagePeriod extension setUsePrivateKeyUsagePeriodNotBefore(false); setUsePrivateKeyUsagePeriodNotAfter(false); setPrivateKeyUsagePeriodStartOffset(DEFAULT_PRIVATE_KEY_USAGE_PERIOD_OFFSET); setPrivateKeyUsagePeriodLength(DEFAULT_PRIVATE_KEY_USAGE_PERIOD_LENGTH); setSingleActiveCertificateConstraint(false); setOverridableExtensionOIDs(new LinkedHashSet()); setNonOverridableExtensionOIDs(new LinkedHashSet()); } /** * @param type * one of CertificateProfileConstants.CERTPROFILE_FIXED_XX, for example CertificateConstants.CERTPROFILE_FIXED_ROOTCA */ private void setDefaultValues(int type) { if (type == CertificateProfileConstants.CERTPROFILE_FIXED_ROOTCA) { setType(CertificateConstants.CERTTYPE_ROOTCA); setAllowValidityOverride(true); setUseKeyUsage(true); setKeyUsage(new boolean[9]); setKeyUsage(CertificateConstants.DIGITALSIGNATURE, true); setKeyUsage(CertificateConstants.KEYCERTSIGN, true); setKeyUsage(CertificateConstants.CRLSIGN, true); setKeyUsageCritical(true); setEncodedValidity(DEFAULT_CERTIFICATE_VALIDITY_FOR_FIXED_CA); } else if (type == CertificateProfileConstants.CERTPROFILE_FIXED_SUBCA) { setType(CertificateConstants.CERTTYPE_SUBCA); setAllowValidityOverride(true); setUseKeyUsage(true); setKeyUsage(new boolean[9]); setKeyUsage(CertificateConstants.DIGITALSIGNATURE, true); setKeyUsage(CertificateConstants.KEYCERTSIGN, true); setKeyUsage(CertificateConstants.CRLSIGN, true); setKeyUsageCritical(true); setEncodedValidity(DEFAULT_CERTIFICATE_VALIDITY_FOR_FIXED_CA); } else if (type == CertificateProfileConstants.CERTPROFILE_FIXED_ENDUSER) { setType(CertificateConstants.CERTTYPE_ENDENTITY); // Standard key usages for end users are: digitalSignature | nonRepudiation, and/or (keyEncipherment or keyAgreement) // Default key usage is digitalSignature | nonRepudiation | keyEncipherment // Create an array for KeyUsage according to X509Certificate.getKeyUsage() setUseKeyUsage(true); setKeyUsage(new boolean[9]); setKeyUsage(CertificateConstants.DIGITALSIGNATURE, true); setKeyUsage(CertificateConstants.NONREPUDIATION, true); setKeyUsage(CertificateConstants.KEYENCIPHERMENT, true); setKeyUsageCritical(true); setUseExtendedKeyUsage(true); ArrayList eku = new ArrayList<>(); eku.add(KeyPurposeId.id_kp_clientAuth.getId()); eku.add(KeyPurposeId.id_kp_emailProtection.getId()); setExtendedKeyUsage(eku); setExtendedKeyUsageCritical(false); } else if (type == CertificateProfileConstants.CERTPROFILE_FIXED_OCSPSIGNER) { setType(CertificateConstants.CERTTYPE_ENDENTITY); // Default key usage for an OCSP signer is digitalSignature // Create an array for KeyUsage acoording to X509Certificate.getKeyUsage() setUseKeyUsage(true); setKeyUsage(new boolean[9]); setKeyUsage(CertificateConstants.DIGITALSIGNATURE, true); setKeyUsageCritical(true); setUseExtendedKeyUsage(true); ArrayList eku = new ArrayList<>(); eku.add(KeyPurposeId.id_kp_OCSPSigning.getId()); setExtendedKeyUsage(eku); setExtendedKeyUsageCritical(false); setUseOcspNoCheck(true); } else if (type == CertificateProfileConstants.CERTPROFILE_FIXED_SERVER) { setType(CertificateConstants.CERTTYPE_ENDENTITY); // Standard key usages for server are: digitalSignature | (keyEncipherment or keyAgreement) // Default key usage is digitalSignature | keyEncipherment // Create an array for KeyUsage acoording to X509Certificate.getKeyUsage() setUseKeyUsage(true); setKeyUsage(new boolean[9]); setKeyUsage(CertificateConstants.DIGITALSIGNATURE, true); setKeyUsage(CertificateConstants.KEYENCIPHERMENT, true); setKeyUsageCritical(true); setUseExtendedKeyUsage(true); ArrayList eku = new ArrayList<>(); eku.add(KeyPurposeId.id_kp_serverAuth.getId()); setExtendedKeyUsage(eku); setExtendedKeyUsageCritical(false); } else if (type == CertificateProfileConstants.CERTPROFILE_FIXED_HARDTOKENAUTH) { setType(CertificateConstants.CERTTYPE_ENDENTITY); setUseKeyUsage(true); setKeyUsage(new boolean[9]); setKeyUsage(CertificateConstants.DIGITALSIGNATURE, true); setKeyUsageCritical(true); setUseExtendedKeyUsage(true); ArrayList eku = new ArrayList<>(); eku.add(KeyPurposeId.id_kp_clientAuth.getId()); eku.add(KeyPurposeId.id_kp_smartcardlogon.getId()); setExtendedKeyUsage(eku); setExtendedKeyUsageCritical(false); } else if (type == CertificateProfileConstants.CERTPROFILE_FIXED_HARDTOKENAUTHENC) { setType(CertificateConstants.CERTTYPE_ENDENTITY); setUseKeyUsage(true); setKeyUsage(new boolean[9]); setKeyUsage(CertificateConstants.KEYENCIPHERMENT, true); setKeyUsage(CertificateConstants.DIGITALSIGNATURE, true); setKeyUsageCritical(true); setUseExtendedKeyUsage(true); ArrayList eku = new ArrayList<>(); eku.add(KeyPurposeId.id_kp_clientAuth.getId()); eku.add(KeyPurposeId.id_kp_emailProtection.getId()); eku.add(KeyPurposeId.id_kp_smartcardlogon.getId()); setExtendedKeyUsage(eku); setExtendedKeyUsageCritical(false); } else if (type == CertificateProfileConstants.CERTPROFILE_FIXED_HARDTOKENENC) { setType(CertificateConstants.CERTTYPE_ENDENTITY); setUseKeyUsage(true); setKeyUsage(new boolean[9]); setKeyUsage(CertificateConstants.KEYENCIPHERMENT, true); setKeyUsageCritical(true); setUseExtendedKeyUsage(true); ArrayList eku = new ArrayList<>(); eku.add(KeyPurposeId.id_kp_emailProtection.getId()); setExtendedKeyUsage(eku); setExtendedKeyUsageCritical(false); } else if (type == CertificateProfileConstants.CERTPROFILE_FIXED_HARDTOKENSIGN) { setType(CertificateConstants.CERTTYPE_ENDENTITY); setUseKeyUsage(true); setKeyUsage(new boolean[9]); setKeyUsage(CertificateConstants.NONREPUDIATION, true); setKeyUsageCritical(true); setUseExtendedKeyUsage(true); ArrayList eku = new ArrayList<>(); eku.add(KeyPurposeId.id_kp_emailProtection.getId()); setExtendedKeyUsage(eku); setExtendedKeyUsageCritical(false); } } // Public Methods. /** Returns the version of the certificate, should be one of the VERSION_ constants defined in CertificateProfile class. */ public String getCertificateVersion() { return (String) data.get(CERTVERSION); } /** * Returns the version of the certificate, should be one of the VERSION_ constants defined in CertificateProfile class. */ public void setCertificateVersion(String version) { data.put(CERTVERSION, version); } /** * @see ValidityDate#getDateBeforeVersion661(long, java.util.Date) * @return a long that is used to provide the end date of certificates for this profile, interpreted by ValidityDate#getDate * @deprecated since since EJBCA 6.6.1 */ @Deprecated public long getValidity() { return ((Long) data.get(VALIDITY)).longValue(); } /** * Gets the encoded validity. * @return the validity as ISO8601 date or relative time. * @See {@link org.cesecore.util.ValidityDate ValidityDate} * @See {@link org.cesecore.util.SimpleTime SimpleTime} */ @SuppressWarnings("deprecation") public String getEncodedValidity() { String result = (String) data.get(ENCODED_VALIDITY); if (StringUtils.isBlank(result)) { result = ValidityDate.getStringBeforeVersion661(getValidity()); setEncodedValidity(result); } return result; } /** * Sets the encoded validity . * @param encodedValidity the validity as ISO8601 date or relative time. * @See {@link org.cesecore.util.ValidityDate ValidityDate} * @See {@link org.cesecore.util.SimpleTime SimpleTime} */ public void setEncodedValidity(String encodedValidity) { data.put(ENCODED_VALIDITY, encodedValidity); } /** * Gets the certificate validity offset. * @return true if we should overwrite the default certificate validity offset with the one specified in the certificate profile. * @see {@link #setCertificateValidityOffset(String)} */ public boolean getUseCertificateValidityOffset() { // Extra null check to handle in-development upgrades if (data.get(USE_CERTIFICATE_VALIDITY_OFFSET) != null) { return Boolean.valueOf((Boolean) data.get(USE_CERTIFICATE_VALIDITY_OFFSET)); } else { return false; } } /** * Use certificate validity offset. * @param enabled */ public void setUseCertificateValidityOffset(boolean enabled) { data.put(USE_CERTIFICATE_VALIDITY_OFFSET, Boolean.valueOf(enabled)); } /** * Gets the certificate validity offset. * @return the offset as simple time string with seconds precision (i.e. '-10m') * @see #link{org.cesecore.util.SimpleTime} */ public String getCertificateValidityOffset() { return (String) data.get(CERTIFICATE_VALIDITY_OFFSET); } /** * Sets the certificate not before offset. * @param simpleTime the offset as simple time string with seconds precision. * @see org.cesecore.util.SimpleTime */ public void setCertificateValidityOffset(String simpleTime) { data.put(CERTIFICATE_VALIDITY_OFFSET, simpleTime); } /** * @return true if we should apply restrictions that certificate expiration can only occur on week days specified by setExpirationRestrictionWeekday * @see #setExpirationRestrictionWeekdays(boolean[]) */ public boolean getUseExpirationRestrictionForWeekdays() { return Boolean.valueOf((Boolean) data.get(USE_EXPIRATION_RESTRICTION_FOR_WEEKDAYS)); } /** * Use validity expiration restriction. * @param enabled */ public void setUseExpirationRestrictionForWeekdays(boolean enabled) { data.put(USE_EXPIRATION_RESTRICTION_FOR_WEEKDAYS, Boolean.valueOf(enabled)); } /** * @return true if we should roll back expiration or false of we should roll forward expiration to match week days specified by setExpirationRestrictionWeekday * @see #setExpirationRestrictionWeekdays(boolean[]) */ public boolean getExpirationRestrictionForWeekdaysExpireBefore() { return Boolean.valueOf((Boolean) data.get(EXPIRATION_RESTRICTION_FOR_WEEKDAYS_BEFORE)); } /** * Sets if the certificate validity shall expire earlier as requested if a the expiration * restriction was applied? * * @param enabled true, otherwise false. */ public void setExpirationRestrictionForWeekdaysExpireBefore(boolean enabled) { data.put(EXPIRATION_RESTRICTION_FOR_WEEKDAYS_BEFORE, Boolean.valueOf(enabled)); } /** * @param weekday (see java.util.Calendar.MONDAY - SUNDAY) * @return true if the weekday is selected as validity expiration restriction. */ @SuppressWarnings("unchecked") public boolean getExpirationRestrictionWeekday(int weekday) { return ((ArrayList) data.get(EXPIRATION_RESTRICTION_WEEKDAYS)).get(weekday-1).booleanValue(); } /** * Include a weekday as validity expiration restriction. * @param weekday (see java.util.Calendar.MONDAY - SUNDAY) * @param enabled */ @SuppressWarnings("unchecked") public void setExpirationRestrictionWeekday(int weekday, boolean enabled) { ((ArrayList) data.get(EXPIRATION_RESTRICTION_WEEKDAYS)).set(weekday-1, Boolean.valueOf(enabled)); } /** * Gets a copy of the List where validity restriction for weekdays are stored. * * @return boolean array. */ @SuppressWarnings("unchecked") public boolean[] getExpirationRestrictionWeekdays() { final ArrayList list = (ArrayList) data.get(EXPIRATION_RESTRICTION_WEEKDAYS); final boolean[] result = new boolean[list.size()]; for (int i = 0; i < list.size(); i++) { result[i] = list.get(i).booleanValue(); } return result; } private void setExpirationRestrictionWeekdays(boolean[] weekdays) { final ArrayList list = new ArrayList(weekdays.length); for (int i = 0; i < weekdays.length; i++) { list.add(Boolean.valueOf(weekdays[i])); } data.put(EXPIRATION_RESTRICTION_WEEKDAYS, list); } private void setDefaultExpirationRestrictionWeekdays() { setExpirationRestrictionWeekdays(new boolean[7]); setExpirationRestrictionWeekday(Calendar.MONDAY, true); setExpirationRestrictionWeekday(Calendar.FRIDAY, true); setExpirationRestrictionWeekday(Calendar.SATURDAY, true); setExpirationRestrictionWeekday(Calendar.SUNDAY, true); } /** * If validity override is allowed, a certificate can have a shorter validity than the one specified in the certificate profile, but never longer. * A certificate created with validity override can hava a starting point in the future. * * @return true if validity override is allowed */ public boolean getAllowValidityOverride() { return ((Boolean) data.get(ALLOWVALIDITYOVERRIDE)).booleanValue(); } /** * If validity override is allowed, a certificate can have a shorter validity than the one specified in the certificate profile, but never longer. * A certificate created with validity override can hava a starting point in the future. */ public void setAllowValidityOverride(boolean allowvalidityoverride) { data.put(ALLOWVALIDITYOVERRIDE, Boolean.valueOf(allowvalidityoverride)); } /** * If extension override is allowed, the X509 certificate extension created in a certificate can come from the request sent by the user. If the * request contains an extension than will be used instead of the one defined in the profile. If the request does not contain an extension, the * one defined in the profile will be used. */ public boolean getAllowExtensionOverride() { Object d = data.get(ALLOWEXTENSIONOVERRIDE); if (d == null) { return false; } return ((Boolean) d).booleanValue(); } /** @see #getAllowExtensionOverride() */ public void setAllowExtensionOverride(boolean allowextensionoverride) { data.put(ALLOWEXTENSIONOVERRIDE, Boolean.valueOf(allowextensionoverride)); } /** * If DN override is allowed, the X509 subject DN extension created in a certificate can * come directly from the CSR in the request sent by the user. This is instead of the normal way where the user's * registered DN is used. */ public boolean getAllowDNOverride() { Object d = data.get(ALLOWDNOVERRIDE); if (d == null) { return false; } return ((Boolean) d).booleanValue(); } /** @see #getAllowDNOverride() */ public void setAllowDNOverride(boolean allowdnoverride) { data.put(ALLOWDNOVERRIDE, Boolean.valueOf(allowdnoverride)); } /** * If DN override by End Entity Information is allowed, the X509 subject DN extension created in a certificate can * come directly from the request meta information sent by the user. This is instead of the normal way where the * user's registered DN is used. */ public boolean getAllowDNOverrideByEndEntityInformation() { Object d = data.get(ALLOWDNOVERRIDEBYEEI); if (d == null) { return false; } return ((Boolean) d).booleanValue(); } /** @see #getAllowDNOverrideByEndEntityInformation() */ public void setAllowDNOverrideByEndEntityInformation(final boolean value) { data.put(ALLOWDNOVERRIDEBYEEI, Boolean.valueOf(value)); } /** * If override is allowed the serial number could be specified. * * @return true if allowed */ public boolean getAllowCertSerialNumberOverride() { Object d = data.get(ALLOWCERTSNOVERIDE); if (d == null) { return false; } return ((Boolean) d).booleanValue(); } /** * @see #getAllowDNOverride() * @param allowdnoverride * new value */ public void setAllowCertSerialNumberOverride(boolean allowdnoverride) { data.put(ALLOWCERTSNOVERIDE, Boolean.valueOf(allowdnoverride)); } public boolean getUseBasicConstraints() { return ((Boolean) data.get(USEBASICCONSTRAINTS)).booleanValue(); } public void setUseBasicConstraints(boolean usebasicconstraints) { data.put(USEBASICCONSTRAINTS, Boolean.valueOf(usebasicconstraints)); } public boolean getBasicConstraintsCritical() { return ((Boolean) data.get(BASICCONSTRAINTSCRITICAL)).booleanValue(); } public void setBasicConstraintsCritical(boolean basicconstraintscritical) { data.put(BASICCONSTRAINTSCRITICAL, Boolean.valueOf(basicconstraintscritical)); } public boolean getUseKeyUsage() { return ((Boolean) data.get(USEKEYUSAGE)).booleanValue(); } public void setUseKeyUsage(boolean usekeyusage) { data.put(USEKEYUSAGE, Boolean.valueOf(usekeyusage)); } public boolean getKeyUsageCritical() { return ((Boolean) data.get(KEYUSAGECRITICAL)).booleanValue(); } public void setKeyUsageCritical(boolean keyusagecritical) { data.put(KEYUSAGECRITICAL, Boolean.valueOf(keyusagecritical)); } public boolean getUseSubjectKeyIdentifier() { return ((Boolean) data.get(USESUBJECTKEYIDENTIFIER)).booleanValue(); } public void setUseSubjectKeyIdentifier(boolean usesubjectkeyidentifier) { data.put(USESUBJECTKEYIDENTIFIER, Boolean.valueOf(usesubjectkeyidentifier)); } public boolean getSubjectKeyIdentifierCritical() { return ((Boolean) data.get(SUBJECTKEYIDENTIFIERCRITICAL)).booleanValue(); } public void setSubjectKeyIdentifierCritical(boolean subjectkeyidentifiercritical) { data.put(SUBJECTKEYIDENTIFIERCRITICAL, Boolean.valueOf(subjectkeyidentifiercritical)); } public boolean getUseAuthorityKeyIdentifier() { return ((Boolean) data.get(USEAUTHORITYKEYIDENTIFIER)).booleanValue(); } public void setUseAuthorityKeyIdentifier(boolean useauthoritykeyidentifier) { data.put(USEAUTHORITYKEYIDENTIFIER, Boolean.valueOf(useauthoritykeyidentifier)); } public boolean getAuthorityKeyIdentifierCritical() { return ((Boolean) data.get(AUTHORITYKEYIDENTIFIERCRITICAL)).booleanValue(); } public void setAuthorityKeyIdentifierCritical(boolean authoritykeyidentifiercritical) { data.put(AUTHORITYKEYIDENTIFIERCRITICAL, Boolean.valueOf(authoritykeyidentifiercritical)); } public boolean getUseSubjectAlternativeName() { return ((Boolean) data.get(USESUBJECTALTERNATIVENAME)).booleanValue(); } public void setUseSubjectAlternativeName(boolean usesubjectalternativename) { data.put(USESUBJECTALTERNATIVENAME, Boolean.valueOf(usesubjectalternativename)); } public boolean getStoreCertificateData() { // Lazy upgrade for profiles created prior to EJBCA 6.2.10 final Boolean value = (Boolean) data.get(STORECERTIFICATEDATA); if (value == null) { // Default for existing profiles is true setStoreCertificateData(true); return true; } else { return value.booleanValue(); } } public void setStoreCertificateData(boolean storeCertificateData) { data.put(STORECERTIFICATEDATA, Boolean.valueOf(storeCertificateData)); } /** @return true if the CertificateData.subjectAltName column should be populated. */ public boolean getStoreSubjectAlternativeName() { // Lazy upgrade for profiles created prior to EJBCA 6.6.0 final Boolean value = (Boolean) data.get(STORESUBJECTALTNAME); if (value == null) { // Old profiles created before EJBCA 6.6.0 will not store SAN by default. setStoreSubjectAlternativeName(false); return false; } else { return value.booleanValue(); } } public void setStoreSubjectAlternativeName(final boolean storeSubjectAlternativeName) { data.put(STORESUBJECTALTNAME, Boolean.valueOf(storeSubjectAlternativeName)); } public boolean getSubjectAlternativeNameCritical() { return ((Boolean) data.get(SUBJECTALTERNATIVENAMECRITICAL)).booleanValue(); } public void setSubjectAlternativeNameCritical(boolean subjectalternativenamecritical) { data.put(SUBJECTALTERNATIVENAMECRITICAL, Boolean.valueOf(subjectalternativenamecritical)); } public boolean getUseIssuerAlternativeName() { return ((Boolean) data.get(USEISSUERALTERNATIVENAME)).booleanValue(); } public void setUseIssuerAlternativeName(boolean useissueralternativename) { data.put(USEISSUERALTERNATIVENAME, Boolean.valueOf(useissueralternativename)); } public boolean getIssuerAlternativeNameCritical() { return ((Boolean) data.get(ISSUERALTERNATIVENAMECRITICAL)).booleanValue(); } public void setIssuerAlternativeNameCritical(boolean issueralternativenamecritical) { data.put(ISSUERALTERNATIVENAMECRITICAL, Boolean.valueOf(issueralternativenamecritical)); } public boolean getUseCRLDistributionPoint() { return ((Boolean) data.get(USECRLDISTRIBUTIONPOINT)).booleanValue(); } public void setUseCRLDistributionPoint(boolean usecrldistributionpoint) { data.put(USECRLDISTRIBUTIONPOINT, Boolean.valueOf(usecrldistributionpoint)); } public boolean getUseDefaultCRLDistributionPoint() { return ((Boolean) data.get(USEDEFAULTCRLDISTRIBUTIONPOINT)).booleanValue(); } public void setUseDefaultCRLDistributionPoint(boolean usedefaultcrldistributionpoint) { data.put(USEDEFAULTCRLDISTRIBUTIONPOINT, Boolean.valueOf(usedefaultcrldistributionpoint)); } public boolean getCRLDistributionPointCritical() { return ((Boolean) data.get(CRLDISTRIBUTIONPOINTCRITICAL)).booleanValue(); } public void setCRLDistributionPointCritical(boolean crldistributionpointcritical) { data.put(CRLDISTRIBUTIONPOINTCRITICAL, Boolean.valueOf(crldistributionpointcritical)); } public String getCRLDistributionPointURI() { return (String) data.get(CRLDISTRIBUTIONPOINTURI); } public void setCRLDistributionPointURI(String crldistributionpointuri) { if (crldistributionpointuri == null) { data.put(CRLDISTRIBUTIONPOINTURI, ""); } else { data.put(CRLDISTRIBUTIONPOINTURI, crldistributionpointuri); } } public String getCRLIssuer() { return (String) data.get(CRLISSUER); } public void setCRLIssuer(String crlissuer) { if (crlissuer == null) { data.put(CRLISSUER, ""); } else { data.put(CRLISSUER, crlissuer); } } public boolean getUseFreshestCRL() { Object obj = data.get(USEFRESHESTCRL); if (obj == null) { return false; } else { return ((Boolean) obj).booleanValue(); } } public void setUseFreshestCRL(boolean usefreshestcrl) { data.put(USEFRESHESTCRL, Boolean.valueOf(usefreshestcrl)); } public boolean getUseCADefinedFreshestCRL() { Object obj = data.get(USECADEFINEDFRESHESTCRL); if (obj == null) { return false; } else { return ((Boolean) obj).booleanValue(); } } public void setUseCADefinedFreshestCRL(boolean usecadefinedfreshestcrl) { data.put(USECADEFINEDFRESHESTCRL, Boolean.valueOf(usecadefinedfreshestcrl)); } public String getFreshestCRLURI() { return ((String) data.get(FRESHESTCRLURI)); } public void setFreshestCRLURI(String freshestcrluri) { if (freshestcrluri == null) { data.put(FRESHESTCRLURI, ""); } else { data.put(FRESHESTCRLURI, freshestcrluri); } } public boolean getUseCertificatePolicies() { return ((Boolean) data.get(USECERTIFICATEPOLICIES)).booleanValue(); } public void setUseCertificatePolicies(boolean usecertificatepolicies) { data.put(USECERTIFICATEPOLICIES, Boolean.valueOf(usecertificatepolicies)); } public boolean getUseCertificateStorage() { //Lazy upgrade for profiles created prior to EJBCA 6.2.10 Boolean value = (Boolean) data.get(USECERTIFICATESTORAGE); if (value == null) { //Default is true setUseCertificateStorage(true); return true; } else { return value.booleanValue(); } } public void setUseCertificateStorage(boolean useCertificateStorage) { data.put(USECERTIFICATESTORAGE, Boolean.valueOf(useCertificateStorage)); } public boolean getCertificatePoliciesCritical() { return ((Boolean) data.get(CERTIFICATEPOLICIESCRITICAL)).booleanValue(); } public void setCertificatePoliciesCritical(boolean certificatepoliciescritical) { data.put(CERTIFICATEPOLICIESCRITICAL, Boolean.valueOf(certificatepoliciescritical)); } public List getCertificatePolicies() { @SuppressWarnings("unchecked") List l = (List) data.get(CERTIFICATE_POLICIES); if (l == null) { l = new ArrayList(); } else { // Check class name, because we changed this in EJBCA 5 and need to support older versions in the database for 100% upgrade if (l.size() > 0) { try { // Don't remove the unused test object CertificatePolicy test = l.get(0); // NOPMD: we need to actually get the text object, otherwise the cast will not be tried test.getPolicyID(); } catch (ClassCastException e) { if (log.isDebugEnabled()) { log.debug("CertificatePolicy in profile is old class name (< EJBCA 5), post-upgrade has not been run. Converting in code to return new class type."); } @SuppressWarnings("unchecked") List oldl = (List) data.get(CERTIFICATE_POLICIES); // In worst case they can have mixed old and new classes, therefore we use a "normal" iterator so we can verify the cast l = new ArrayList(); for (int i = 0; i < oldl.size(); i++) { try { org.ejbca.core.model.ca.certificateprofiles.CertificatePolicy oldPol = (org.ejbca.core.model.ca.certificateprofiles.CertificatePolicy)oldl.get(i); CertificatePolicy newPol = new CertificatePolicy(oldPol.getPolicyID(), oldPol.getQualifierId(), oldPol.getQualifier()); if (log.isTraceEnabled()) { log.trace("Adding converted policy"); } l.add(newPol); } catch (ClassCastException e2) { // This was already a new class, there are mixed policies here... CertificatePolicy newPol = (CertificatePolicy)oldl.get(i); if (log.isTraceEnabled()) { log.trace("Adding non-converted policy"); } l.add(newPol); } } } } } return l; } @SuppressWarnings("unchecked") public void addCertificatePolicy(CertificatePolicy policy) { if (data.get(CERTIFICATE_POLICIES) == null) { setCertificatePolicies(new ArrayList()); } ((List) data.get(CERTIFICATE_POLICIES)).add(policy); } public void setCertificatePolicies(List policies) { if (policies == null) { data.put(CERTIFICATE_POLICIES, new ArrayList(0)); } else { data.put(CERTIFICATE_POLICIES, policies); } } @SuppressWarnings("unchecked") public void removeCertificatePolicy(CertificatePolicy policy) { if (data.get(CERTIFICATE_POLICIES) != null) { ((List) data.get(CERTIFICATE_POLICIES)).remove(policy); } } /** Type is used when setting BasicConstraints, i.e. to determine if it is a CA or an end entity * @see CertificateConstants.CERTTYPE_ROOTCA, etc */ public int getType() { return ((Integer) data.get(TYPE)).intValue(); } /** Type is used when setting BasicConstraints, i.e. to determine if it is a CA or an end entity * @see CertificateConstants.CERTTYPE_ROOTCA, etc */ public void setType(int type) { data.put(TYPE, Integer.valueOf(type)); } public boolean isTypeSubCA() { return ((Integer) data.get(TYPE)).intValue() == CertificateConstants.CERTTYPE_SUBCA; } public boolean isTypeRootCA() { return ((Integer) data.get(TYPE)).intValue() == CertificateConstants.CERTTYPE_ROOTCA; } public boolean isTypeEndEntity() { return ((Integer) data.get(TYPE)).intValue() == CertificateConstants.CERTTYPE_ENDENTITY; } public String[] getAvailableKeyAlgorithms() { final List availableKeyAlgorithms = getAvailableKeyAlgorithmsAsList(); return availableKeyAlgorithms.toArray(new String[availableKeyAlgorithms.size()]); } @SuppressWarnings("unchecked") public List getAvailableKeyAlgorithmsAsList() { return (ArrayList) data.get(AVAILABLEKEYALGORITHMS); } public void setAvailableKeyAlgorithms(final String[] availableKeyAlgorithms) { setAvailableKeyAlgorithmsAsList(Arrays.asList(availableKeyAlgorithms)); } public void setAvailableKeyAlgorithmsAsList(final List availableKeyAlgorithms) { data.put(AVAILABLEKEYALGORITHMS, new ArrayList<>(availableKeyAlgorithms)); } public String[] getAvailableEcCurves() { final List availableEcCurves = getAvailableEcCurvesAsList(); return availableEcCurves.toArray(new String[availableEcCurves.size()]); } @SuppressWarnings("unchecked") public List getAvailableEcCurvesAsList() { return (ArrayList) data.get(AVAILABLEECCURVES); } public void setAvailableEcCurves(final String[] availableEcCurves) { setAvailableEcCurvesAsList(Arrays.asList(availableEcCurves)); } public void setAvailableEcCurvesAsList(final List availableEcCurves) { data.put(AVAILABLEECCURVES, new ArrayList<>(availableEcCurves)); } public int[] getAvailableBitLengths() { final List availablebitlengths = getAvailableBitLengthsAsList(); final int[] returnval = new int[availablebitlengths.size()]; for (int i = 0; i < availablebitlengths.size(); i++) { returnval[i] = availablebitlengths.get(i).intValue(); } return returnval; } @SuppressWarnings("unchecked") public List getAvailableBitLengthsAsList() { return (ArrayList) data.get(AVAILABLEBITLENGTHS); } public void setAvailableBitLengths(List availablebitlengths) { // Strange values here, but it makes the <> below work for sure int minimumavailablebitlength = 99999999; int maximumavailablebitlength = 0; for (int i = 0; i < availablebitlengths.size(); i++) { if (availablebitlengths.get(i) > maximumavailablebitlength) { maximumavailablebitlength = availablebitlengths.get(i); } if (availablebitlengths.get(i) < minimumavailablebitlength) { minimumavailablebitlength = availablebitlengths.get(i); } } data.put(AVAILABLEBITLENGTHS, availablebitlengths); data.put(MINIMUMAVAILABLEBITLENGTH, Integer.valueOf(minimumavailablebitlength)); data.put(MAXIMUMAVAILABLEBITLENGTH, Integer.valueOf(maximumavailablebitlength)); } public void setAvailableBitLengths(int[] availablebitlengths) { ArrayList availbitlengths = new ArrayList<>(availablebitlengths.length); for (int i = 0; i < availablebitlengths.length; i++) { availbitlengths.add(Integer.valueOf(availablebitlengths[i])); } setAvailableBitLengths(availbitlengths); } public int getMinimumAvailableBitLength() { return ((Integer) data.get(MINIMUMAVAILABLEBITLENGTH)).intValue(); } public int getMaximumAvailableBitLength() { return ((Integer) data.get(MAXIMUMAVAILABLEBITLENGTH)).intValue(); } /** * Returns true if the given combination of keyAlgorithm/keySpecification is allowed by this certificate profile. */ public boolean isKeyTypeAllowed(final String keyAlgorithm, final String keySpecification) { final List availableKeyAlgorithms = getAvailableKeyAlgorithmsAsList(); final List availableBitLengths = getAvailableBitLengthsAsList(); final List availableEcCurves = getAvailableEcCurvesAsList(); if (!availableKeyAlgorithms.contains(keyAlgorithm)) { return false; } if (StringUtils.isNumeric(keySpecification)) { // keySpecification is a bit length (RSA) return availableBitLengths.contains(Integer.parseInt(keySpecification)); } else { // keySpecification is a curve name (EC) return availableEcCurves.contains(keySpecification) || availableEcCurves.contains(CertificateProfile.ANY_EC_CURVE); } } /** * Returns the chosen algorithm to be used for signing the certificates or null if it is to be inherited from the CA (i.e., it is the same as the * algorithm used to sign the CA certificate). * * @see org.cesecore.certificates.util.core.model.AlgorithmConstants.AVAILABLE_SIGALGS * @return JCE identifier for the signature algorithm or null if it is to be inherited from the CA (i.e., it is the same as the algorithm used to * sign the CA certificate). */ public String getSignatureAlgorithm() { // If it's null, it is inherited from issuing CA. return (String) data.get(SIGNATUREALGORITHM); } /** * Sets the algorithm to be used for signing the certificates. A null value means that the signature algorithm is to be inherited from the CA * (i.e., it is the same as the algorithm used to sign the CA certificate). * * @param signAlg * JCE identifier for the signature algorithm or null if it is to be inherited from the CA (i.e., it is the same as the algorithm used * to sign the CA certificate). * @see org.cesecore.certificates.util.core.model.AlgorithmConstants.AVAILABLE_SIGALGS */ public void setSignatureAlgorithm(String signAlg) { data.put(SIGNATUREALGORITHM, signAlg); } public boolean[] getKeyUsage() { @SuppressWarnings("unchecked") ArrayList keyusage = (ArrayList) data.get(KEYUSAGE); boolean[] returnval = new boolean[keyusage.size()]; for (int i = 0; i < keyusage.size(); i++) { returnval[i] = keyusage.get(i).booleanValue(); } return returnval; } /** * @param keyusageconstant * from CertificateConstants.DIGITALSIGNATURE etc * @return true or false if the key usage is set or not. */ @SuppressWarnings("unchecked") public boolean getKeyUsage(int keyusageconstant) { return ((ArrayList) data.get(KEYUSAGE)).get(keyusageconstant).booleanValue(); } public void setKeyUsage(boolean[] keyusage) { ArrayList keyuse = new ArrayList(keyusage.length); for (int i = 0; i < keyusage.length; i++) { keyuse.add(Boolean.valueOf(keyusage[i])); } data.put(KEYUSAGE, keyuse); } /** * @param keyusageconstant * from CertificateConstants.DIGITALSIGNATURE etc * @param value * true or false if the key usage is set or not. */ @SuppressWarnings("unchecked") public void setKeyUsage(int keyusageconstant, boolean value) { ((ArrayList) data.get(KEYUSAGE)).set(keyusageconstant, Boolean.valueOf(value)); } public void setAllowKeyUsageOverride(boolean override) { data.put(ALLOWKEYUSAGEOVERRIDE, Boolean.valueOf(override)); } public boolean getAllowKeyUsageOverride() { return ((Boolean) data.get(ALLOWKEYUSAGEOVERRIDE)).booleanValue(); } public void setAllowBackdatedRevocation(boolean override) { this.data.put(ALLOWBACKDATEDREVOCATION, Boolean.valueOf(override)); } public boolean getAllowBackdatedRevocation() { final Object value = this.data.get(ALLOWBACKDATEDREVOCATION); return value!=null && value instanceof Boolean && ((Boolean)value).booleanValue(); } public void setUseDocumentTypeList(boolean use) { data.put(USEDOCUMENTTYPELIST, Boolean.valueOf(use)); } public boolean getUseDocumentTypeList() { return ((Boolean) data.get(USEDOCUMENTTYPELIST)).booleanValue(); } public void setDocumentTypeListCritical(boolean critical) { data.put(DOCUMENTTYPELISTCRITICAL, Boolean.valueOf(critical)); } public boolean getDocumentTypeListCritical() { return ((Boolean) data.get(DOCUMENTTYPELISTCRITICAL)).booleanValue(); } public void setDocumentTypeList(ArrayList docTypes) { data.put(DOCUMENTTYPELIST, docTypes); } @SuppressWarnings("unchecked") public ArrayList getDocumentTypeList() { return (ArrayList) data.get(DOCUMENTTYPELIST); } public void setUseExtendedKeyUsage(boolean use) { data.put(USEEXTENDEDKEYUSAGE, Boolean.valueOf(use)); } public boolean getUseExtendedKeyUsage() { return ((Boolean) data.get(USEEXTENDEDKEYUSAGE)).booleanValue(); } public void setExtendedKeyUsageCritical(boolean critical) { data.put(EXTENDEDKEYUSAGECRITICAL, Boolean.valueOf(critical)); } public boolean getExtendedKeyUsageCritical() { return ((Boolean) data.get(EXTENDEDKEYUSAGECRITICAL)).booleanValue(); } /** * Extended Key Usage is an arraylist of oid Strings. Usually oids comes from KeyPurposeId in BC. */ public void setExtendedKeyUsage(ArrayList extendedkeyusage) { data.put(EXTENDEDKEYUSAGE, extendedkeyusage); } /** * Extended Key Usage is an arraylist of Strings with eku oids. */ @SuppressWarnings("unchecked") public ArrayList getExtendedKeyUsageOids() { return (ArrayList) data.get(EXTENDEDKEYUSAGE); } public void setExtendedKeyUsageOids(final ArrayList extendedKeyUsageOids) { setExtendedKeyUsage(extendedKeyUsageOids); } public void setUseCustomDnOrder(boolean use) { data.put(USECUSTOMDNORDER, Boolean.valueOf(use)); } public boolean getUseCustomDnOrder() { boolean ret = false; // Default value is false here Object o = data.get(USECUSTOMDNORDER); if (o != null) { ret = ((Boolean) o).booleanValue(); } return ret; } /** Set to true if we should apply the rules for LDAP DN Order (separate flag) * to the custom DN order * @param useldap true or false */ public void setUseCustomDnOrderWithLdap(boolean useldap) { data.put(USECUSTOMDNORDERLDAP, Boolean.valueOf(useldap)); } /** * @return true if we should apply the rules for LDAP DN Order (separate flag), default to false for new usage, where no custom order exists, * and to true for old usage to be backward compatible */ public boolean getUseCustomDnOrderWithLdap() { boolean ret = true; // Default value is true here Object o = data.get(USECUSTOMDNORDERLDAP); if (o != null) { ret = ((Boolean) o).booleanValue(); } else if (getCustomDnOrder().isEmpty()) { // We have not set a value for this checkbox, and we have no custom DN order defined // in this case we default to false (new usage) ret = false; } return ret; } /** Custom DN order is an ArrayList of DN strings * @see DnComponents * @return ArrayList of Strings or an empty ArrayList */ @SuppressWarnings("unchecked") public ArrayList getCustomDnOrder() { if (data.get(CUSTOMDNORDER) == null) { return new ArrayList<>(); } return (ArrayList) data.get(CUSTOMDNORDER); } public void setCustomDnOrder(final ArrayList dnOrder) { data.put(CUSTOMDNORDER, dnOrder); } public boolean getUseLdapDnOrder() { boolean ret = true; // Default value is true here Object o = data.get(USELDAPDNORDER); if (o != null) { ret = ((Boolean) o).booleanValue(); } return ret; } public void setUseLdapDnOrder(boolean use) { data.put(USELDAPDNORDER, Boolean.valueOf(use)); } public boolean getUseMicrosoftTemplate() { return ((Boolean) data.get(USEMICROSOFTTEMPLATE)).booleanValue(); } public void setUseMicrosoftTemplate(boolean use) { data.put(USEMICROSOFTTEMPLATE, Boolean.valueOf(use)); } public String getMicrosoftTemplate() { return (String) data.get(MICROSOFTTEMPLATE); } public void setMicrosoftTemplate(String mstemplate) { data.put(MICROSOFTTEMPLATE, mstemplate); } public boolean getUseCardNumber() { return ((Boolean) data.get(USECARDNUMBER)).booleanValue(); } public void setUseCardNumber(boolean use) { data.put(USECARDNUMBER, Boolean.valueOf(use)); } public boolean getUseCNPostfix() { return ((Boolean) data.get(USECNPOSTFIX)).booleanValue(); } public void setUseCNPostfix(boolean use) { data.put(USECNPOSTFIX, Boolean.valueOf(use)); } public String getCNPostfix() { return (String) data.get(CNPOSTFIX); } public void setCNPostfix(String cnpostfix) { data.put(CNPOSTFIX, cnpostfix); } public boolean getUseSubjectDNSubSet() { return ((Boolean) data.get(USESUBJECTDNSUBSET)).booleanValue(); } public void setUseSubjectDNSubSet(boolean use) { data.put(USESUBJECTDNSUBSET, Boolean.valueOf(use)); } /** * Returns a List of Integer (DNFieldExtractor constants) indicating which subject dn fields that should be used in certificate. * */ @SuppressWarnings("unchecked") public List getSubjectDNSubSet() { return (List) data.get(SUBJECTDNSUBSET); } /** * Should contain a collection of Integer (DNFieldExtractor constants) indicating which subject dn fields that should be used in certificate. * * Will come in as a list of string from the GUI, because JSP doesn't always care about type safety. * */ public void setSubjectDNSubSet(List subjectdns) { List convertedList = new ArrayList<>(); for(String value : subjectdns) { convertedList.add(Integer.valueOf(value)); } data.put(SUBJECTDNSUBSET, convertedList); } /** * Overridable Extension OIDs is an Set of oid Strings. * It is used to list what are the extensions that can be overridden when allow extension override is enabled in the Certificate Profile. * @param Set of oids (strings), or an empty set, should not be null */ public void setOverridableExtensionOIDs(Set overridableextensionoids) { data.put(OVERRIDABLEEXTENSIONOIDS, new LinkedHashSet(overridableextensionoids)); } /** * Overridable Extension OIDs is an Set of oid Strings. * It is used to list what are the extensions that can be overridden when allow extension override is enabled in the Certificate Profile. * @return Set of strings containing oids, or an empty set, never null */ @SuppressWarnings("unchecked") public Set getOverridableExtensionOIDs() { if (data.get(OVERRIDABLEEXTENSIONOIDS) == null) { return new LinkedHashSet(); } return (Set) data.get(OVERRIDABLEEXTENSIONOIDS); } /** * Non Overridable Extension OIDs is a Set of oid Strings. * It is used to list what are the extensions that can not be overridden when allow extension override is enabled in the Certificate Profile.. * @param Set of oids (strings) that are not allowed to be overridden, or empty set to not disallow anything, not null */ public void setNonOverridableExtensionOIDs(Set nonoverridableextensionoids) { data.put(NONOVERRIDABLEEXTENSIONOIDS, new LinkedHashSet(nonoverridableextensionoids)); } /** * Non Overridable Extension OIDs is a Set of oid Strings. * It is used to list what are the extensions that can not be overridde when allow extension override is enabled in the Certificate Profile.. * @return Set of strings containing oids, or an empty set, never null */ @SuppressWarnings("unchecked") public Set getNonOverridableExtensionOIDs() { if (data.get(NONOVERRIDABLEEXTENSIONOIDS) == null) { return new LinkedHashSet(); } return (Set) data.get(NONOVERRIDABLEEXTENSIONOIDS); } /** * Method taking a full user dn and returns a DN only containing the DN fields specified in the subjectdn sub set array. * * @param dn * @return a subset of original DN */ public String createSubjectDNSubSet(String dn) { DNFieldExtractor extractor = new DNFieldExtractor(dn, DNFieldExtractor.TYPE_SUBJECTDN); return constructUserData(extractor, getSubjectDNSubSet(), true); } public boolean getUseSubjectAltNameSubSet() { return ((Boolean) data.get(USESUBJECTALTNAMESUBSET)).booleanValue(); } public void setUseSubjectAltNameSubSet(boolean use) { data.put(USESUBJECTALTNAMESUBSET, Boolean.valueOf(use)); } /** * Returns a List of Integer (DNFieldExtractor constants) indicating which subject altnames fields that should be used in certificate. * */ @SuppressWarnings("unchecked") public List getSubjectAltNameSubSet() { return (List) data.get(SUBJECTALTNAMESUBSET); } /** * Sets a List of Integer (DNFieldExtractor constants) indicating which subject altnames fields that should be used in certificate. * */ public void setSubjectAltNameSubSet(List subjectaltnames) { data.put(SUBJECTALTNAMESUBSET, subjectaltnames); } /** * Method taking a full user dn and returns a AltName only containing the AltName fields specified in the subjectaltname sub set array. * * @param dn * @return a subset of original DN */ public String createSubjectAltNameSubSet(String subjectaltname) { DNFieldExtractor extractor = new DNFieldExtractor(subjectaltname, DNFieldExtractor.TYPE_SUBJECTALTNAME); return constructUserData(extractor, getSubjectAltNameSubSet(), false); } /** * Help method converting a full DN or Subject Alt Name to one usng only specified fields * * @param extractor * @param usefields * @return */ protected static String constructUserData(DNFieldExtractor extractor, Collection usefields, boolean subjectdn) { String retval = ""; if (usefields instanceof List) { Collections.sort((List) usefields); } String dnField = null; for (Integer next : usefields) { dnField = extractor.getFieldString(next.intValue()); if (StringUtils.isNotEmpty(dnField)) { if (retval.length() == 0) { retval += dnField; // first item, don't start with a comma } else { retval += "," + dnField; } } } if (log.isDebugEnabled()) { log.debug("CertificateProfile: constructed DN or AltName: " + retval); } return retval; } /** * Returns a List of caids (Integer), indicating which CAs the profile should be applicable to. * * If it contains the constant ANYCA then the profile is applicable to all CAs */ @SuppressWarnings("unchecked") public List getAvailableCAs() { return (List) data.get(AVAILABLECAS); } /** * Saves the CertificateProfile's list of CAs the cert profile is applicable to. * * @param availablecas * a List of caids (Integer) */ public void setAvailableCAs(List availablecas) { data.put(AVAILABLECAS, availablecas); } @SuppressWarnings("unchecked") public boolean isApplicableToAnyCA() { return ((List) data.get(AVAILABLECAS)).contains(Integer.valueOf(ANYCA)); } /** * Returns a List of publisher id's (Integer) indicating which publishers a certificate created with this profile should be published to. * Never returns null. */ @SuppressWarnings("unchecked") public List getPublisherList() { Object o = data.get(USEDPUBLISHERS); if (o == null) { o = new ArrayList(); } return (List) o; } /** * Saves the CertificateProfile's list of publishers that certificates created with this profile should be published to. * * @param publishers * a List of publisher Ids */ public void setPublisherList(List publisher) { data.put(USEDPUBLISHERS, publisher); } /** * Method indicating that Path Length Constraint should be used in the BasicConstaint */ public boolean getUsePathLengthConstraint() { return ((Boolean) data.get(USEPATHLENGTHCONSTRAINT)).booleanValue(); } /** * Method indicating that Path Length Constraint should be used in the BasicConstaint */ public void setUsePathLengthConstraint(boolean use) { data.put(USEPATHLENGTHCONSTRAINT, Boolean.valueOf(use)); } public int getPathLengthConstraint() { return ((Integer) data.get(PATHLENGTHCONSTRAINT)).intValue(); } public void setPathLengthConstraint(int pathlength) { data.put(PATHLENGTHCONSTRAINT, Integer.valueOf(pathlength)); } public void setCaIssuers(List caIssuers) { data.put(CAISSUERS, caIssuers); } @SuppressWarnings("unchecked") public void addCaIssuer(String caIssuer) { caIssuer = caIssuer.trim(); if (caIssuer.length() < 1) { return; } if (data.get(CAISSUERS) == null) { List caIssuers = new ArrayList<>(); caIssuers.add(caIssuer); this.setCaIssuers(caIssuers); } else { ((List) data.get(CAISSUERS)).add(caIssuer); } } @SuppressWarnings("unchecked") public List getCaIssuers() { if (data.get(CAISSUERS) == null) { return new ArrayList<>(); } else { return (List) data.get(CAISSUERS); } } public void removeCaIssuer(String caIssuer) { if (data.get(CAISSUERS) != null) { ((List) data.get(CAISSUERS)).remove(caIssuer); } } public boolean getUseOcspNoCheck() { if (data.get(USEOCSPNOCHECK) == null) { return false; } else { return ((Boolean) data.get(USEOCSPNOCHECK)).booleanValue(); } } public void setUseOcspNoCheck(boolean useocspnocheck) { data.put(USEOCSPNOCHECK, Boolean.valueOf(useocspnocheck)); } public boolean getUseAuthorityInformationAccess() { return ((Boolean) data.get(USEAUTHORITYINFORMATIONACCESS)).booleanValue(); } public void setUseAuthorityInformationAccess(boolean useauthorityinformationaccess) { data.put(USEAUTHORITYINFORMATIONACCESS, Boolean.valueOf(useauthorityinformationaccess)); } public boolean getUseDefaultCAIssuer() { //Lazy instantiation in case upgrade for some reason fails if(data.get(USEDEFAULTCAISSUER) == null) { data.put(USEDEFAULTCAISSUER, false); } return ((Boolean) data.get(USEDEFAULTCAISSUER)).booleanValue(); } public void setUseDefaultCAIssuer(boolean usedefaultcaissuer) { data.put(USEDEFAULTCAISSUER, Boolean.valueOf(usedefaultcaissuer)); } public boolean getUseDefaultOCSPServiceLocator() { return ((Boolean) data.get(USEDEFAULTOCSPSERVICELOCATOR)).booleanValue(); } public void setUseDefaultOCSPServiceLocator(boolean usedefaultocspservicelocator) { data.put(USEDEFAULTOCSPSERVICELOCATOR, Boolean.valueOf(usedefaultocspservicelocator)); } public String getOCSPServiceLocatorURI() { return (String) data.get(OCSPSERVICELOCATORURI); } public void setOCSPServiceLocatorURI(String ocspservicelocatoruri) { if (ocspservicelocatoruri == null) { data.put(OCSPSERVICELOCATORURI, ""); } else { data.put(OCSPSERVICELOCATORURI, ocspservicelocatoruri); } } public boolean getUseQCStatement() { return ((Boolean) data.get(USEQCSTATEMENT)).booleanValue(); } public void setUseQCStatement(boolean useqcstatement) { data.put(USEQCSTATEMENT, Boolean.valueOf(useqcstatement)); } public boolean getUsePkixQCSyntaxV2() { return ((Boolean) data.get(USEPKIXQCSYNTAXV2)).booleanValue(); } public void setUsePkixQCSyntaxV2(boolean pkixqcsyntaxv2) { data.put(USEPKIXQCSYNTAXV2, Boolean.valueOf(pkixqcsyntaxv2)); } public boolean getQCStatementCritical() { return ((Boolean) data.get(QCSTATEMENTCRITICAL)).booleanValue(); } public void setQCStatementCritical(boolean qcstatementcritical) { data.put(QCSTATEMENTCRITICAL, Boolean.valueOf(qcstatementcritical)); } /** @return String with RAName or empty string */ public String getQCStatementRAName() { return (String) data.get(QCSTATEMENTRANAME); } public void setQCStatementRAName(String qcstatementraname) { if (qcstatementraname == null) { data.put(QCSTATEMENTRANAME, ""); } else { data.put(QCSTATEMENTRANAME, qcstatementraname); } } /** @return String with SemanticsId or empty string */ public String getQCSemanticsId() { return (String) data.get(QCSSEMANTICSID); } public void setQCSemanticsId(String qcsemanticsid) { if (qcsemanticsid == null) { data.put(QCSSEMANTICSID, ""); } else { data.put(QCSSEMANTICSID, qcsemanticsid); } } public boolean getUseQCEtsiQCCompliance() { return ((Boolean) data.get(USEQCETSIQCCOMPLIANCE)).booleanValue(); } public void setUseQCEtsiQCCompliance(boolean useqcetsiqccompliance) { data.put(USEQCETSIQCCOMPLIANCE, Boolean.valueOf(useqcetsiqccompliance)); } public boolean getUseQCEtsiValueLimit() { return ((Boolean) data.get(USEQCETSIVALUELIMIT)).booleanValue(); } public void setUseQCEtsiValueLimit(boolean useqcetsivaluelimit) { data.put(USEQCETSIVALUELIMIT, Boolean.valueOf(useqcetsivaluelimit)); } public int getQCEtsiValueLimit() { return ((Integer) data.get(QCETSIVALUELIMIT)).intValue(); } public void setQCEtsiValueLimit(int qcetsivaluelimit) { data.put(QCETSIVALUELIMIT, Integer.valueOf(qcetsivaluelimit)); } public int getQCEtsiValueLimitExp() { return ((Integer) data.get(QCETSIVALUELIMITEXP)).intValue(); } public void setQCEtsiValueLimitExp(int qcetsivaluelimitexp) { data.put(QCETSIVALUELIMITEXP, Integer.valueOf(qcetsivaluelimitexp)); } /** @return String with Currency or empty string */ public String getQCEtsiValueLimitCurrency() { return (String) data.get(QCETSIVALUELIMITCURRENCY); } public void setQCEtsiValueLimitCurrency(String qcetsivaluelimitcurrency) { if (qcetsivaluelimitcurrency == null) { data.put(QCETSIVALUELIMITCURRENCY, ""); } else { data.put(QCETSIVALUELIMITCURRENCY, qcetsivaluelimitcurrency); } } public boolean getUseQCEtsiRetentionPeriod() { return ((Boolean) data.get(USEQCETSIRETENTIONPERIOD)).booleanValue(); } public void setUseQCEtsiRetentionPeriod(boolean useqcetsiretentionperiod) { data.put(USEQCETSIRETENTIONPERIOD, Boolean.valueOf(useqcetsiretentionperiod)); } public int getQCEtsiRetentionPeriod() { return ((Integer) data.get(QCETSIRETENTIONPERIOD)).intValue(); } public void setQCEtsiRetentionPeriod(int qcetsiretentionperiod) { data.put(QCETSIRETENTIONPERIOD, Integer.valueOf(qcetsiretentionperiod)); } public boolean getUseQCEtsiSignatureDevice() { return ((Boolean) data.get(USEQCETSISIGNATUREDEVICE)).booleanValue(); } public void setUseQCEtsiSignatureDevice(boolean useqcetsisignaturedevice) { data.put(USEQCETSISIGNATUREDEVICE, Boolean.valueOf(useqcetsisignaturedevice)); } /** @return String with Type OID or null (or empty string) if it's not to be used (EN 319 412-05) * 0.4.0.1862.1.6.1 = id-etsi-qct-esign * 0.4.0.1862.1.6.2 = id-etsi-qct-eseal * 0.4.0.1862.1.6.3 = id-etsi-qct-web */ public String getQCEtsiType() { return (String) data.get(QCETSITYPE); } public void setQCEtsiType(String qcetsitype) { data.put(QCETSITYPE, qcetsitype); } /** * Returns the PKI Disclosure Statements (EN 319 412-05) used in this profile, or null if none are present. */ @SuppressWarnings("unchecked") public List getQCEtsiPds() { List result = null; List pdsList = (List)data.get(QCETSIPDS); if (pdsList != null && !pdsList.isEmpty()) { result = new ArrayList<>(pdsList.size()); try { for (final PKIDisclosureStatement pds : pdsList) { result.add((PKIDisclosureStatement) pds.clone()); } } catch (CloneNotSupportedException e) { throw new IllegalStateException(e); } } return result; } /** * Sets the PKI Disclosure Statements (EN 319 412-05). * Both null and empty lists are interpreted as an "none". */ public void setQCEtsiPds(final List pds) { if (pds == null || pds.isEmpty()) { // never store an empty list data.put(QCETSIPDS, null); } else { data.put(QCETSIPDS, new ArrayList<>(pds)); } // Remove old data from EJBCA < 6.6.1 data.remove(QCETSIPDSURL); data.remove(QCETSIPDSLANG); } public boolean getUseQCCustomString() { return ((Boolean) data.get(USEQCCUSTOMSTRING)).booleanValue(); } public void setUseQCCustomString(boolean useqccustomstring) { data.put(USEQCCUSTOMSTRING, Boolean.valueOf(useqccustomstring)); } /** @return String with oid or empty string */ public String getQCCustomStringOid() { return (String) data.get(QCCUSTOMSTRINGOID); } public void setQCCustomStringOid(String qccustomstringoid) { if (qccustomstringoid == null) { data.put(QCCUSTOMSTRINGOID, ""); } else { data.put(QCCUSTOMSTRINGOID, qccustomstringoid); } } /** @return String with custom text or empty string */ public String getQCCustomStringText() { return (String) data.get(QCCUSTOMSTRINGTEXT); } public void setQCCustomStringText(String qccustomstringtext) { if (qccustomstringtext == null) { data.put(QCCUSTOMSTRINGTEXT, ""); } else { data.put(QCCUSTOMSTRINGTEXT, qccustomstringtext); } } public boolean getUseNameConstraints() { Boolean b = (Boolean) data.get(USENAMECONSTRAINTS); return b != null && b.booleanValue(); } public void setUseNameConstraints(boolean use) { data.put(USENAMECONSTRAINTS, Boolean.valueOf(use)); } public boolean getNameConstraintsCritical() { Boolean b = (Boolean) data.get(NAMECONSTRAINTSCRITICAL); return b != null && b.booleanValue(); } public void setNameConstraintsCritical(boolean use) { data.put(NAMECONSTRAINTSCRITICAL, Boolean.valueOf(use)); } public boolean getUseSubjectDirAttributes() { return ((Boolean) data.get(USESUBJECTDIRATTRIBUTES)).booleanValue(); } public void setUseSubjectDirAttributes(boolean use) { data.put(USESUBJECTDIRATTRIBUTES, Boolean.valueOf(use)); } public void setSingleActiveCertificateConstraint(final boolean enabled) { data.put(USERSINGLEACTIVECERTIFICATECONSTRAINT, Boolean.valueOf(enabled)); } public boolean isSingleActiveCertificateConstraint() { Object constraintObject = data.get(USERSINGLEACTIVECERTIFICATECONSTRAINT); if(constraintObject == null) { //For upgrading from versions prior to 6.3.1 setSingleActiveCertificateConstraint(false); return false; } else { return ((Boolean) data.get(USERSINGLEACTIVECERTIFICATECONSTRAINT)).booleanValue(); } } /** * Returns which type of terminals are used in this ca/certificate hierarchy. * The values correspond to the id-roles-1/2/3 OIDs. */ public int getCVCTerminalType() { if (data.get(CVCTERMINALTYPE) == null) { return CertificateProfile.CVC_TERMTYPE_IS; } return ((Integer) data.get(CVCTERMINALTYPE)).intValue(); } public void setCVCTerminalType(int termtype) { data.put(CVCTERMINALTYPE, Integer.valueOf(termtype)); } public boolean isCvcTerminalTypeIs() { return getCVCTerminalType() == CertificateProfile.CVC_TERMTYPE_IS; } public boolean isCvcTerminalTypeAt() { return getCVCTerminalType() == CertificateProfile.CVC_TERMTYPE_AT; } public boolean isCvcTerminalTypeSt() { return getCVCTerminalType() == CertificateProfile.CVC_TERMTYPE_ST; } public int getCVCAccessRights() { if (data.get(CVCACCESSRIGHTS) == null) { return CertificateProfile.CVC_ACCESS_NONE; } return ((Integer) data.get(CVCACCESSRIGHTS)).intValue(); } public void setCVCAccessRights(int access) { data.put(CVCACCESSRIGHTS, Integer.valueOf(access)); } /** * Used for bitmasks that don't fit in an int. * E.g. the 5-byte bitmask for Authentication Terminals */ public byte[] getCVCLongAccessRights() { if (data.get(CVCLONGACCESSRIGHTS) == null) { return null; } @SuppressWarnings("unchecked") List rightsList = (List)data.get(CVCLONGACCESSRIGHTS); return ArrayUtils.toPrimitive(rightsList.toArray(new Byte[0])); } public void setCVCLongAccessRights(byte[] access) { if (access == null) { data.put(CVCLONGACCESSRIGHTS, null); } else { // Convert to List since byte[] doesn't work with database protection data.put(CVCLONGACCESSRIGHTS, new ArrayList<>(Arrays.asList(ArrayUtils.toObject(access)))); } } public int getCVCSignTermDVType() { if (data.get(CVCSIGNTERMDVTYPE) == null) { return CertificateProfile.CVC_SIGNTERM_DV_CSP; } return ((Integer) data.get(CVCSIGNTERMDVTYPE)).intValue(); } public void setCVCSignTermDVType(int type) { data.put(CVCSIGNTERMDVTYPE, Integer.valueOf(type)); } /** * Method returning a list of (Integers) of ids of used CUSTOM certificate extensions. I.e. those custom certificate extensions selected for this * profile. Never null. * * Autoupgradable method */ @SuppressWarnings("unchecked") public List getUsedCertificateExtensions() { if (data.get(USEDCERTIFICATEEXTENSIONS) == null) { return new ArrayList<>(); } return (List) data.get(USEDCERTIFICATEEXTENSIONS); } /** * Method setting a list of used certificate extensions a list of Integers containing CertificateExtension Id is expected * * @param usedCertificateExtensions */ public void setUsedCertificateExtensions(List usedCertificateExtensions) { if (usedCertificateExtensions == null) { data.put(USEDCERTIFICATEEXTENSIONS, new ArrayList()); } else { data.put(USEDCERTIFICATEEXTENSIONS, usedCertificateExtensions); } } /** * Function that looks up in the profile all certificate extensions that we should use if the value is that we should use it, the oid for this * extension is returned in the list * * @return List of oid Strings for standard certificate extensions that should be used */ public List getUsedStandardCertificateExtensions() { ArrayList ret = new ArrayList<>(); Iterator iter = useStandardCertificateExtensions.keySet().iterator(); while (iter.hasNext()) { String s = iter.next(); if ((data.get(s) != null) && ((Boolean) data.get(s)).booleanValue()) { ret.add(useStandardCertificateExtensions.get(s)); if (log.isDebugEnabled()) { log.debug("Using standard certificate extension: " + s); } } else { if (log.isDebugEnabled()) { log.debug("Not using standard certificate extensions: " + s); } } } return ret; } /** * @return a List of Integers (CAInfo.REQ_APPROVAL_ constants) of which action that requires approvals, default none, never null * * @deprecated since 6.8.0. Use getApprovals() instead; */ @SuppressWarnings("unchecked") @Deprecated public List getApprovalSettings() { List approvalSettings = (List) data.get(APPROVALSETTINGS); if (approvalSettings != null) { return approvalSettings; } else { return new ArrayList<>(); } } /** * List of Integers (CAInfo.REQ_APPROVAL_ constants) of which action that requires approvals * * @deprecated since 6.8.0. Use setApprovals() instead; */ @Deprecated public void setApprovalSettings(List approvalSettings) { data.put(APPROVALSETTINGS, approvalSettings); } /** * Returns the number of different administrators that needs to approve an action, default 1. * * @deprecated since 6.6.0, use the appropriate approval profile instead * Needed for a while in order to be able to import old statedumps from 6.5 and earlier */ @Deprecated public int getNumOfReqApprovals() { Integer result = (Integer) data.get(NUMOFREQAPPROVALS); if(result != null) { return result.intValue(); } else { return 1; } } /** * The number of different administrators that needs to approve * * @deprecated since 6.6.0, use the appropriate approval profile instead * Needed for a while in order to be able to import old statedumps from 6.5 and earlier */ @Deprecated public void setNumOfReqApprovals(int numOfReqApprovals) { data.put(NUMOFREQAPPROVALS, Integer.valueOf(numOfReqApprovals)); } /** * @return the id of the approval profile. ID -1 means that no approval profile was set * * @deprecated since 6.8.0. Use getApprovals() instead; */ @Deprecated public int getApprovalProfileID() { Integer approvalProfileId = (Integer) data.get(APPROVALPROFILE); if(approvalProfileId != null) { return approvalProfileId.intValue(); } else { return -1; } } /** * @return the ID of an approval profile * * @deprecated since 6.8.0. Use setApprovals() instead; */ @Deprecated public void setApprovalProfileID(int approvalProfileID) { data.put(APPROVALPROFILE, Integer.valueOf(approvalProfileID)); } public void setApprovals(Map approvals) { if(approvals == null) { approvals = new LinkedHashMap<>(); } // We must store this as a predictable order map in the database, in order for databaseprotection to work data.put(APPROVALS, new LinkedHashMap(approvals)); } /** * @return a map of approvals, mapped as approval setting (as defined in this class) : approval profile ID. Never returns null. */ @SuppressWarnings("unchecked") public Map getApprovals() { if (data.get(APPROVALS) == null) { Map approvals = new LinkedHashMap<>(); int approvalProfileId = getApprovalProfileID(); if(approvalProfileId != -1) { for(int approvalSetting : getApprovalSettings()) { approvals.put(ApprovalRequestType.getFromIntegerValue(approvalSetting), approvalProfileId); } } setApprovals(approvals); } return (Map) data.get(APPROVALS); } /** * @return If the PrivateKeyUsagePeriod extension should be used and with the notBefore component. */ public boolean isUsePrivateKeyUsagePeriodNotBefore() { if (data.get(USEPRIVKEYUSAGEPERIODNOTAFTER) == null) { return false; } return ((Boolean) data.get(USEPRIVKEYUSAGEPERIODNOTBEFORE)).booleanValue(); } /** * Sets if the PrivateKeyUsagePeriod extension should be used and with * the notBefore component. * Setting this to true means that there will be an PrivateKeyUsagePeriod * extension and that it also at least will contain an notBefore component. * Setting this to false means that the extension will not contain an * notBefore component. In that case if there will be an extension depends * on if {@link #isUsePrivateKeyUsagePeriodNotAfter()} is true. * * @param use True if the notBefore component should be used. */ public void setUsePrivateKeyUsagePeriodNotBefore(final boolean use) { data.put(USEPRIVKEYUSAGEPERIODNOTBEFORE, use); data.put(USEPRIVKEYUSAGEPERIOD, use || isUsePrivateKeyUsagePeriodNotAfter()); } /** * @return If the PrivateKeyUsagePeriod extension should be used and with the notAfter component. */ public boolean isUsePrivateKeyUsagePeriodNotAfter() { if (data.get(USEPRIVKEYUSAGEPERIODNOTAFTER) == null) { return false; } return ((Boolean) data.get(USEPRIVKEYUSAGEPERIODNOTAFTER)).booleanValue(); } /** * Sets if the PrivateKeyUsagePeriod extension should be used and with * the notAfter component. * Setting this to true means that there will be an PrivateKeyUsagePeriod * extension and that it also at least will contain an notAfter component. * Setting this to false means that the extension will not contain an * notAfter component. In that case if there will be an extension depends * on if {@link #isUsePrivateKeyUsagePeriodNotBefore()} is true. * * @param use True if the notAfter component should be used. */ public void setUsePrivateKeyUsagePeriodNotAfter(final boolean use) { data.put(USEPRIVKEYUSAGEPERIODNOTAFTER, use); data.put(USEPRIVKEYUSAGEPERIOD, use || isUsePrivateKeyUsagePeriodNotBefore()); } /** * @return How long (in seconds) after the certificate's notBefore date the * PrivateKeyUsagePeriod's notBefore date should be. */ public long getPrivateKeyUsagePeriodStartOffset() { return ((Long) data.get(PRIVKEYUSAGEPERIODSTARTOFFSET)).longValue(); } /** * Sets how long (in seconds) after the certificate's notBefore date the PrivateKeyUsagePeriod's notBefore date should be. * * @param start Offset from certificate issuance. */ public void setPrivateKeyUsagePeriodStartOffset(final long start) { data.put(PRIVKEYUSAGEPERIODSTARTOFFSET, start); } /** * @return The private key usage period (private key validity) length (in seconds). */ public long getPrivateKeyUsagePeriodLength() { return ((Long) data.get(PRIVKEYUSAGEPERIODLENGTH)).longValue(); } /** * Sets the private key usage period (private key validity) length (in seconds). * * @param validity The length. */ public void setPrivateKeyUsagePeriodLength(final long validity) { data.put(PRIVKEYUSAGEPERIODLENGTH, validity); } /** * Whether Certificate Transparency (CT) should be used when generating new certificates. CT is specified in RFC 6962 */ public boolean isUseCertificateTransparencyInCerts() { if (data.get(USECERTIFICATETRANSPARENCYINCERTS) == null) { return false; } return ((Boolean)data.get(USECERTIFICATETRANSPARENCYINCERTS)).booleanValue(); } public void setUseCertificateTransparencyInCerts(boolean use) { data.put(USECERTIFICATETRANSPARENCYINCERTS, use); } /** * Whether Certificate Transparency (CT) should be used in OCSP responses. CT is specified in RFC 6962 */ public boolean isUseCertificateTransparencyInOCSP() { if (data.get(USECERTIFICATETRANSPARENCYINOCSP) == null) { return false; } return ((Boolean)data.get(USECERTIFICATETRANSPARENCYINOCSP)).booleanValue(); } public void setUseCertificateTransparencyInOCSP(boolean use) { data.put(USECERTIFICATETRANSPARENCYINOCSP, use); } /** * Whether Certificate Transparency (CT) should be used in publishers. * You have to create a publisher and enable it in the profile also! */ public boolean isUseCertificateTransparencyInPublishers() { if (data.get(USECERTIFICATETRANSPARENCYINPUBLISHERS) == null) { // Default to being enabled if CT in OCSP was enabled return isUseCertificateTransparencyInOCSP(); } return ((Boolean)data.get(USECERTIFICATETRANSPARENCYINPUBLISHERS)).booleanValue(); } public void setUseCertificateTransparencyInPublishers(boolean use) { data.put(USECERTIFICATETRANSPARENCYINPUBLISHERS, use); } public boolean isCtEnabled() { return isUseCertificateTransparencyInCerts() || isUseCertificateTransparencyInOCSP() || isUseCertificateTransparencyInPublishers(); } public boolean isNumberOfSctByValidity() { if (data.get(CT_NUMBER_OF_SCTS_BY_VALIDITY) == null) { // Default value return true; } return (Boolean)data.get(CT_NUMBER_OF_SCTS_BY_VALIDITY); } public void setNumberOfSctByValidity(boolean use) { data.put(CT_NUMBER_OF_SCTS_BY_VALIDITY, use); } public boolean isNumberOfSctByCustom() { if (data.get(CT_NUMBER_OF_SCTS_BY_CUSTOM) == null) { // Default value return false; } return (Boolean)data.get(CT_NUMBER_OF_SCTS_BY_CUSTOM); } public void setNumberOfSctByCustom(boolean use) { data.put(CT_NUMBER_OF_SCTS_BY_CUSTOM, use); } public boolean isMaxNumberOfSctByValidity() { if (data.get(CT_MAX_NUMBER_OF_SCTS_BY_VALIDITY) == null) { // Default value return false; } return (Boolean)data.get(CT_MAX_NUMBER_OF_SCTS_BY_VALIDITY); } public void setMaxNumberOfSctByValidity(boolean use) { data.put(CT_MAX_NUMBER_OF_SCTS_BY_VALIDITY, use); } public boolean isMaxNumberOfSctByCustom() { if (data.get(CT_MAX_NUMBER_OF_SCTS_BY_CUSTOM) == null) { // Default value return true; } return (Boolean)data.get(CT_MAX_NUMBER_OF_SCTS_BY_CUSTOM); } public void setMaxNumberOfSctByCustom(boolean use) { data.put(CT_MAX_NUMBER_OF_SCTS_BY_CUSTOM, use); } /** * Whether existing certificates should be submitted by the CT publisher and the CT OCSP extension class. */ public boolean isUseCTSubmitExisting() { if (data.get(CTSUBMITEXISTING) == null) { return true; } return ((Boolean)data.get(CTSUBMITEXISTING)).booleanValue(); } public void setUseCTSubmitExisting(boolean use) { data.put(CTSUBMITEXISTING, use); } /** * Gets the IDs of the CT logs that are activated in this profile. */ @SuppressWarnings("unchecked") @Deprecated public Set getEnabledCTLogs() { if (data.get(CTLOGS) == null) { return new LinkedHashSet<>(); } return (Set)data.get(CTLOGS); } /** Sets the enabled CT logs. NOTE: The argument must be a LinkedHashSet, since order is important */ @Deprecated public void setEnabledCTLogs(LinkedHashSet logIds) { data.put(CTLOGS, new LinkedHashSet<>(logIds)); } @SuppressWarnings("unchecked") public Set getEnabledCtLabels() { if (data.get(CTLABELS) == null) { return new LinkedHashSet<>(); } return (Set)data.get(CTLABELS); } public void setEnabledCTLabels(LinkedHashSet ctLabels) { data.put(CTLABELS, ctLabels); } /** *

Number of CT logs to require an SCT from, or it will be considered an error. If zero, CT is completely optional and * ignored if no log servers can be contacted.

*

This value is used for certificates and publishers. For OCSP responses, @see CertificateProfile#getCtMinTotalSctsOcsp *

* @return the total number of SCTs required */ @Deprecated public int getCtMinTotalScts() { if (data.get(CT_MIN_TOTAL_SCTS) == null) { return 0; // setting is OFF } return (Integer) data.get(CT_MIN_TOTAL_SCTS); } /** @param value minimum number of SCTs required in total */ @Deprecated public void setCtMinTotalScts(int value) { data.put(CT_MIN_TOTAL_SCTS, value); } /** @see CertificateProfile#getCtMinTotalScts */ @Deprecated public int getCtMinTotalSctsOcsp() { if (data.get(CT_MIN_TOTAL_SCTS_OCSP) == null) { return getCtMinTotalScts(); } return (Integer) data.get(CT_MIN_TOTAL_SCTS_OCSP); } /** @param value minimum number of SCTs for OCSP responses required in total */ @Deprecated public void setCtMinTotalSctsOcsp(int value) { data.put(CT_MIN_TOTAL_SCTS_OCSP, value); } /** *

Number of SCTs retrieved after which we will stop contacting non-mandatory log servers.

* @return the maximum number of non-mandatory SCTs */ @Deprecated public int getCtMaxNonMandatoryScts() { if (data.get(CT_MAX_NONMANDATORY_SCTS) == null) { if (data.get(CT_MAX_SCTS) == null) { log.info("CT_MAX_NON_MANDATORY_SCTS is null => legacy value is also null, using 1 log as default."); return 1; } log.info("CT_MAX_NON_MANDATORY_SCTS is null => using legacy value: " + data.get(CT_MAX_SCTS)); return (Integer) data.get(CT_MAX_SCTS); } return (Integer) data.get(CT_MAX_NONMANDATORY_SCTS); } /** @param value the maximum number of non-mandatory SCTs */ @Deprecated public void setCtMaxNonMandatoryScts(int value) { data.put(CT_MAX_NONMANDATORY_SCTS, value); } /** @see CertificateProfile#getCtMaxNonMandatoryScts */ @Deprecated public int getCtMaxNonMandatorySctsOcsp() { if (data.get(CT_MAX_NONMANDATORY_SCTS_OCSP) == null) { if (data.get(CT_MAX_SCTS_OCSP) == null) { log.info("CT_MAX_NON_MANDATORY_SCTS_OCSP is null => legacy value is also null, using 1 log as default."); return 1; } log.info("CT_MAX_NON_MANDATORY_SCTS_OCSP is null => using legacy value: " + data.get(CT_MAX_SCTS_OCSP)); return (Integer) data.get(CT_MAX_SCTS_OCSP); } return (Integer) data.get(CT_MAX_NONMANDATORY_SCTS_OCSP); } /** @param value maximum value number of non-mandatory SCTs for OCSP responses */ @Deprecated public void setCtMaxNonMandatorySctsOcsp(int value) { data.put(CT_MAX_NONMANDATORY_SCTS_OCSP, value); } /** *

Number of CT logs marked as "not mandatory" to require an SCT from, or it will be considered an error. Default is zero logs.

*

For publishers, certificates are submitted to all enabled logs.

*/ @Deprecated public int getCtMinNonMandatoryScts() { if (data.get(CT_MIN_NONMANDATORY_SCTS) == null) { return getCtMinTotalScts(); } return (Integer) data.get(CT_MIN_NONMANDATORY_SCTS); } /** @param value minimum number of non-mandatory SCTs */ @Deprecated public void setCtMinNonMandatoryScts(int value) { data.put(CT_MIN_NONMANDATORY_SCTS, value); } /** @see CertificateProfile#getCtMinNonMandatoryScts */ @Deprecated public int getCtMinNonMandatorySctsOcsp() { if (data.get(CT_MIN_NONMANDATORY_SCTS_OCSP) == null) { return getCtMinNonMandatoryScts(); } return (Integer) data.get(CT_MIN_NONMANDATORY_SCTS_OCSP); } /** @param value minimum number of non-mandatory SCTs */ @Deprecated public void setCtMinNonMandatorySctsOcsp(int value) { data.put(CT_MIN_NONMANDATORY_SCTS_OCSP, value); } public int getCtMinScts() { if (data.get(CT_SCTS_MIN) == null) { return getCtMinTotalScts(); } return (Integer) data.get(CT_SCTS_MIN); } public void setCtMinScts(int value) { data.put(CT_SCTS_MIN, value); } public int getCtMaxScts() { if (data.get(CT_SCTS_MAX) == null) { return getCtMinTotalScts(); } return (Integer) data.get(CT_SCTS_MAX); } public void setCtMaxScts(int value) { data.put(CT_SCTS_MAX, value); } public int getCtMinSctsOcsp() { if (data.get(CT_SCTS_MIN_OCSP) == null) { return getCtMinTotalScts(); } return (Integer) data.get(CT_SCTS_MIN_OCSP); } public void setCtMinSctsOcsp(int value) { data.put(CT_SCTS_MIN_OCSP, value); } public int getCtMaxSctsOcsp() { if (data.get(CT_SCTS_MAX_OCSP) == null) { return getCtMinTotalScts(); } return (Integer) data.get(CT_SCTS_MAX_OCSP); } public void setCtMaxSctsOcsp(int value) { data.put(CT_SCTS_MAX_OCSP, value); } /** Number of times to retry connecting to a Certificate Transparency log */ public int getCTMaxRetries() { if (data.get(CTMAXRETRIES) == null) { return 0; } return (Integer)data.get(CTMAXRETRIES); } public void setCTMaxRetries(int numRetries) { data.put(CTMAXRETRIES, numRetries); } /** * Usage only intended for post upgrade! * Removes CT data prior to EJBCA 6.10.1 from certificate profile. * */ public void removeLegacyCtData() { if (data.get(CT_MAX_SCTS) != null) { data.remove(CT_MAX_SCTS); } if (data.get(CT_MAX_SCTS_OCSP) != null) { data.remove(CT_MAX_SCTS_OCSP); } if (data.get(CT_MIN_MANDATORY_SCTS) != null) { data.remove(CT_MIN_MANDATORY_SCTS); } if (data.get(CT_MAX_MANDATORY_SCTS) != null) { data.remove(CT_MAX_MANDATORY_SCTS); } if (data.get(CT_MIN_MANDATORY_SCTS_OCSP) != null) { data.remove(CT_MIN_MANDATORY_SCTS_OCSP); } if (data.get(CT_MAX_MANDATORY_SCTS_OCSP) != null) { data.remove(CT_MAX_MANDATORY_SCTS_OCSP); } if (data.get(CT_MIN_NONMANDATORY_SCTS) != null) { data.remove(CT_MIN_NONMANDATORY_SCTS); } if (data.get(CT_MAX_NONMANDATORY_SCTS) != null) { data.remove(CT_MAX_NONMANDATORY_SCTS); } if (data.get(CT_MIN_NONMANDATORY_SCTS_OCSP) != null) { data.remove(CT_MIN_NONMANDATORY_SCTS_OCSP); } if (data.get(CT_MAX_NONMANDATORY_SCTS_OCSP) != null) { data.remove(CT_MAX_NONMANDATORY_SCTS_OCSP); } } /** * Checks that a public key fulfills the policy in the CertificateProfile * * @param publicKey PublicKey to verify * @throws IllegalKeyException if the PublicKey does not fulfill policy in CertificateProfile */ public void verifyKey(final PublicKey publicKey) throws IllegalKeyException { final String keyAlgorithm = AlgorithmTools.getKeyAlgorithm(publicKey); final int keyLength = KeyTools.getKeyLength(publicKey); if (log.isDebugEnabled()) { log.debug("KeyAlgorithm: " + keyAlgorithm + " KeyLength: " + keyLength); } // Verify that the key algorithm is compliant with the certificate profile if (!getAvailableKeyAlgorithmsAsList().contains(keyAlgorithm)) { if(log.isDebugEnabled()) { log.debug("List of available algorithms " + getAvailableKeyAlgorithmsAsList() + " does not contain the on of the public key: " + keyAlgorithm); } throw new IllegalKeyException(intres.getLocalizedMessage("createcert.illegalkeyalgorithm", keyAlgorithm)); } if (AlgorithmConstants.KEYALGORITHM_ECDSA.equals(keyAlgorithm)) { final List availableEcCurves = getAvailableEcCurvesAsList(); final String keySpecification = AlgorithmTools.getKeySpecification(publicKey); for (final String ecNamedCurveAlias : AlgorithmTools.getEcKeySpecAliases(keySpecification)) { if (availableEcCurves.contains(ecNamedCurveAlias)) { // Curve is allowed, so we don't check key strength return; } } if (!availableEcCurves.contains(ANY_EC_CURVE)) { // Curve will never be allowed by bit length check throw new IllegalKeyException(intres.getLocalizedMessage("createcert.illegaleccurve", keySpecification)); } } // Verify key length that it is compliant with certificate profile if (keyLength == -1) { throw new IllegalKeyException(intres.getLocalizedMessage("createcert.unsupportedkeytype", publicKey.getClass().getName())); } if ((keyLength < (getMinimumAvailableBitLength() - 1)) || (keyLength > (getMaximumAvailableBitLength()))) { throw new IllegalKeyException(intres.getLocalizedMessage("createcert.illegalkeylength", Integer.valueOf(keyLength))); } } /** * Checks that provided caId is allowed. * * @param caId caId to verify * @return Returns true, if caId belongs to availableCas or if any CA is allowed (-1 is in availableCAs list) */ public boolean isCaAllowed(int caId) { List availableCAs = getAvailableCAs(); return availableCAs.contains(-1) || availableCAs.contains(caId); } @Override public CertificateProfile clone() throws CloneNotSupportedException { final CertificateProfile clone = new CertificateProfile(0); // We need to make a deep copy of the hashmap here clone.data = new LinkedHashMap<>(data.size()); for (final Entry entry : data.entrySet()) { Object value = entry.getValue(); if (value instanceof ArrayList) { // We need to make a clone of this object, but the stored immutables can still be referenced value = ((ArrayList)value).clone(); } clone.data.put(entry.getKey(), value); } return clone; } /** Implementation of UpgradableDataHashMap function getLatestVersion */ @Override public float getLatestVersion() { return LATEST_VERSION; } /** * Function setting the current version of the class data. Used for JUnit testing */ protected void setVersion(float version) { data.put(VERSION, Float.valueOf(version)); } /** * Implementation of UpgradableDataHashMap function upgrade. */ @SuppressWarnings("deprecation") @Override public void upgrade() { if (log.isTraceEnabled()) { log.trace(">upgrade: " + getLatestVersion() + ", " + getVersion()); } if (Float.compare(getLatestVersion(), getVersion()) != 0) { // New version of the class, upgrade String msg = intres.getLocalizedMessage("certprofile.upgrade", new Float(getVersion())); log.info(msg); if (data.get(ALLOWKEYUSAGEOVERRIDE) == null) { data.put(ALLOWKEYUSAGEOVERRIDE, Boolean.TRUE); } if (data.get(USEEXTENDEDKEYUSAGE) == null) { data.put(USEEXTENDEDKEYUSAGE, Boolean.FALSE); } if (data.get(EXTENDEDKEYUSAGE) == null) { data.put(EXTENDEDKEYUSAGE, new ArrayList()); } if (data.get(EXTENDEDKEYUSAGECRITICAL) == null) { data.put(EXTENDEDKEYUSAGECRITICAL, Boolean.FALSE); } if (data.get(AVAILABLECAS) == null) { ArrayList availablecas = new ArrayList<>(); availablecas.add(Integer.valueOf(ANYCA)); data.put(AVAILABLECAS, availablecas); } if (data.get(USEDPUBLISHERS) == null) { data.put(USEDPUBLISHERS, new ArrayList()); } if ( (data.get(USEOCSPSERVICELOCATOR) == null) && (data.get(USEAUTHORITYINFORMATIONACCESS) == null) ) { // Only set this flag if we have not already set the new flag USEAUTHORITYINFORMATIONACCESS // setUseOCSPServiceLocator(false); data.put(USEOCSPSERVICELOCATOR, Boolean.FALSE); setOCSPServiceLocatorURI(""); } if (data.get(USEMICROSOFTTEMPLATE) == null) { setUseMicrosoftTemplate(false); setMicrosoftTemplate(""); } if (data.get(USECNPOSTFIX) == null) { setUseCNPostfix(false); setCNPostfix(""); } if (data.get(USESUBJECTDNSUBSET) == null) { setUseSubjectDNSubSet(false); setSubjectDNSubSet(new ArrayList()); setUseSubjectAltNameSubSet(false); setSubjectAltNameSubSet(new ArrayList()); } if (data.get(USEPATHLENGTHCONSTRAINT) == null) { setUsePathLengthConstraint(false); setPathLengthConstraint(0); } if (data.get(USEQCSTATEMENT) == null) { setUseQCStatement(false); setUsePkixQCSyntaxV2(false); setQCStatementCritical(false); setQCStatementRAName(null); setQCSemanticsId(null); setUseQCEtsiQCCompliance(false); setUseQCEtsiSignatureDevice(false); setUseQCEtsiValueLimit(false); setUseQCEtsiRetentionPeriod(false); setQCEtsiRetentionPeriod(0); setQCEtsiValueLimit(0); setQCEtsiValueLimitExp(0); setQCEtsiValueLimitCurrency(null); } if (data.get(USEDEFAULTCRLDISTRIBUTIONPOINT) == null) { setUseDefaultCRLDistributionPoint(false); setUseDefaultOCSPServiceLocator(false); } if (data.get(USEQCCUSTOMSTRING) == null) { setUseQCCustomString(false); setQCCustomStringOid(null); setQCCustomStringText(null); } if (data.get(USESUBJECTDIRATTRIBUTES) == null) { setUseSubjectDirAttributes(false); } if (data.get(ALLOWVALIDITYOVERRIDE) == null) { setAllowValidityOverride(false); } if (data.get(CRLISSUER) == null) { setCRLIssuer(null); // v20 } if (data.get(USEOCSPNOCHECK) == null) { setUseOcspNoCheck(false); // v21 } if (data.get(USEFRESHESTCRL) == null) { setUseFreshestCRL(false); // v22 setUseCADefinedFreshestCRL(false); setFreshestCRLURI(null); } if (data.get(CERTIFICATE_POLICIES) == null) { // v23 if (data.get(CERTIFICATEPOLICYID) != null) { String ids = (String) data.get(CERTIFICATEPOLICYID); String unotice = null; String cpsuri = null; if (data.get(POLICY_NOTICE_UNOTICE_TEXT) != null) { unotice = (String) data.get(POLICY_NOTICE_UNOTICE_TEXT); } if (data.get(POLICY_NOTICE_CPS_URL) != null) { cpsuri = (String) data.get(POLICY_NOTICE_CPS_URL); } // Only the first policy could have user notice and cpsuri in the old scheme StringTokenizer tokenizer = new StringTokenizer(ids, ";", false); if (tokenizer.hasMoreTokens()) { String id = tokenizer.nextToken(); CertificatePolicy newpolicy = null; if (StringUtils.isNotEmpty(unotice)) { newpolicy = new CertificatePolicy(id, CertificatePolicy.id_qt_unotice, unotice); addCertificatePolicy(newpolicy); } if (StringUtils.isNotEmpty(cpsuri)) { newpolicy = new CertificatePolicy(id, CertificatePolicy.id_qt_cps, cpsuri); addCertificatePolicy(newpolicy); } // If it was a lonely policy id if (newpolicy == null) { newpolicy = new CertificatePolicy(id, null, null); addCertificatePolicy(newpolicy); } } while (tokenizer.hasMoreTokens()) { String id = tokenizer.nextToken(); CertificatePolicy newpolicy = new CertificatePolicy(id, null, null); addCertificatePolicy(newpolicy); } } } if ( (data.get(USECAISSUERS) == null) && (data.get(USEAUTHORITYINFORMATIONACCESS) == null) ) { // Only set this flag if we have not already set the new flag USEAUTHORITYINFORMATIONACCESS // setUseCaIssuers(false); // v24 data.put(USECAISSUERS, Boolean.FALSE); // v24 setCaIssuers(new ArrayList()); } if ( ((data.get(USEOCSPSERVICELOCATOR) != null) || (data.get(USECAISSUERS) != null)) && (data.get(USEAUTHORITYINFORMATIONACCESS) == null) ) { // Only do this if we have not already set the new flag USEAUTHORITYINFORMATIONACCESS boolean ocsp = false; if ((data.get(USEOCSPSERVICELOCATOR) != null)) { ocsp = ((Boolean) data.get(USEOCSPSERVICELOCATOR)).booleanValue(); } boolean caissuers = false; if ((data.get(USECAISSUERS) != null)) { caissuers = ((Boolean) data.get(USECAISSUERS)).booleanValue(); } if (ocsp || caissuers) { setUseAuthorityInformationAccess(true); // v25 } else { setUseAuthorityInformationAccess(false); // v25 } } else if (data.get(USEAUTHORITYINFORMATIONACCESS) == null) { setUseAuthorityInformationAccess(false); } if (data.get(ALLOWEXTENSIONOVERRIDE) == null) { setAllowExtensionOverride(false); // v26 } if (data.get(USEQCETSIRETENTIONPERIOD) == null) { setUseQCEtsiRetentionPeriod(false); // v27 setQCEtsiRetentionPeriod(0); } if (data.get(CVCACCESSRIGHTS) == null) { setCVCAccessRights(CertificateProfile.CVC_ACCESS_NONE); // v28 } if (data.get(USELDAPDNORDER) == null) { setUseLdapDnOrder(true); // v29, default value is true } if (data.get(USECARDNUMBER) == null) { // v30, default value is false setUseCardNumber(false); } if (data.get(ALLOWDNOVERRIDE) == null) { setAllowDNOverride(false); // v31 } if (data.get(NUMOFREQAPPROVALS) == null) { // v 33 setNumOfReqApprovals(1); } if (data.get(APPROVALSETTINGS) == null) { // v 33 setApprovalSettings(new ArrayList()); } if (data.get(SIGNATUREALGORITHM) == null) { // v 34 setSignatureAlgorithm(null); } if (data.get(USEPRIVKEYUSAGEPERIODNOTBEFORE) == null) { // v 35 setUsePrivateKeyUsagePeriodNotBefore(false); } if (data.get(USEPRIVKEYUSAGEPERIODNOTAFTER) == null) { // v 35 setUsePrivateKeyUsagePeriodNotAfter(false); } if (data.get(PRIVKEYUSAGEPERIODSTARTOFFSET) == null) { // v 35 setPrivateKeyUsagePeriodStartOffset(DEFAULT_PRIVATE_KEY_USAGE_PERIOD_OFFSET); } if (data.get(PRIVKEYUSAGEPERIODLENGTH) == null) { // v 35 setPrivateKeyUsagePeriodLength(DEFAULT_PRIVATE_KEY_USAGE_PERIOD_LENGTH); } if(data.get(USEISSUERALTERNATIVENAME) == null) { // v 36 setUseIssuerAlternativeName(false); } if(data.get(ISSUERALTERNATIVENAMECRITICAL) == null) { // v 36 setIssuerAlternativeNameCritical(false); } if(data.get(USEDOCUMENTTYPELIST) == null) { // v 37 setUseDocumentTypeList(false); } if(data.get(DOCUMENTTYPELISTCRITICAL) == null) { // v 37 setDocumentTypeListCritical(false); } if(data.get(DOCUMENTTYPELIST) == null) { // v 37 setDocumentTypeList(new ArrayList()); } if(data.get(AVAILABLEKEYALGORITHMS) == null) { // v 39 // Make some intelligent guesses what key algorithm this profile is used for final List availableKeyAlgorithms = AlgorithmTools.getAvailableKeyAlgorithms(); if (getMinimumAvailableBitLength()>521) { availableKeyAlgorithms.remove(AlgorithmConstants.KEYALGORITHM_ECDSA); availableKeyAlgorithms.remove(AlgorithmConstants.KEYALGORITHM_DSTU4145); availableKeyAlgorithms.remove(AlgorithmConstants.KEYALGORITHM_ECGOST3410); } if (getMinimumAvailableBitLength()>1024 || getMaximumAvailableBitLength()<1024) { availableKeyAlgorithms.remove(AlgorithmConstants.KEYALGORITHM_DSA); } if (getMaximumAvailableBitLength()<1024) { availableKeyAlgorithms.remove(AlgorithmConstants.KEYALGORITHM_RSA); } setAvailableKeyAlgorithmsAsList(availableKeyAlgorithms); } if (data.get(AVAILABLEECCURVES) == null) { // v 40 setAvailableEcCurves(new String[]{ ANY_EC_CURVE }); } if(data.get(APPROVALPROFILE) == null) { // v41 setApprovalProfileID(-1); } // v42. ETSI QC Type and PDS specified in EN 319 412-05. // Nothing to set though, since null values means to not use the new values // v43, ECA-5304. if (data.get(USEDEFAULTCAISSUER) == null) { setUseDefaultCAIssuer(false); } // v44. ECA-5141 // 'encodedValidity' is derived by the former long value! if(null == data.get(ENCODED_VALIDITY)) { if (data.get(VALIDITY) != null) { // avoid NPE if this is a very raw profile setEncodedValidity(ValidityDate.getStringBeforeVersion661(getValidity())); } // Don't upgrade to anything is there was nothing to upgrade } // v44. ECA-5330 // initialize fields for expiration restriction for weekdays. use is false because of backward compatibility, the before restriction default is true if(null == data.get(USE_EXPIRATION_RESTRICTION_FOR_WEEKDAYS)) { setUseExpirationRestrictionForWeekdays(false); } if(null == data.get(EXPIRATION_RESTRICTION_WEEKDAYS)) { setDefaultExpirationRestrictionWeekdays(); } if(null == data.get(EXPIRATION_RESTRICTION_FOR_WEEKDAYS_BEFORE)) { setExpirationRestrictionForWeekdaysExpireBefore(true); } // v44. ECA-3554 // initialize default certificate not before offset (default '-10m' because of backward compatibility). if(null == data.get(USE_CERTIFICATE_VALIDITY_OFFSET)) { setUseCertificateValidityOffset(false); } if(null == data.get(CERTIFICATE_VALIDITY_OFFSET)) { setCertificateValidityOffset(DEFAULT_CERTIFICATE_VALIDITY_OFFSET); } // v45: Multiple ETSI QC PDS values (ECA-5478) if (!data.containsKey(QCETSIPDS)) { final String url = (String) data.get(QCETSIPDSURL); final String lang = (String) data.get(QCETSIPDSLANG); if (StringUtils.isNotEmpty(url)) { final List pdsList = new ArrayList<>(); pdsList.add(new PKIDisclosureStatement(url, lang)); data.put(QCETSIPDS, pdsList); } else { data.put(QCETSIPDS, null); } } // v46: approvals changed type to LinkedHashMap setApprovals(getApprovals()); data.put(VERSION, new Float(LATEST_VERSION)); } log.trace("