/* * * Copyright (c) 2013 - 2017 Lijun Liao * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License version 3 * as published by the Free Software Foundation with the addition of the * following permission added to Section 15 as permitted in Section 7(a): * * FOR ANY PART OF THE COVERED WORK IN WHICH THE COPYRIGHT IS OWNED BY * THE AUTHOR LIJUN LIAO. LIJUN LIAO DISCLAIMS THE WARRANTY OF NON INFRINGEMENT * OF THIRD PARTY RIGHTS. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. * * The interactive user interfaces in modified source and object code versions * of this program must display Appropriate Legal Notices, as required under * Section 5 of the GNU Affero General Public License. * * You can be released from the requirements of the license by purchasing * a commercial license. Buying such a license is mandatory as soon as you * develop commercial activities involving the XiPKI software without * disclosing the source code of your own applications. * * For more information, please contact Lijun Liao at this * address: lijun.liao@gmail.com */ package org.xipki.pki.ca.certprofile; import java.io.IOException; import java.io.InputStream; import java.math.BigInteger; import java.net.URL; import java.util.ArrayList; import java.util.Collections; import java.util.HashMap; import java.util.HashSet; import java.util.LinkedList; import java.util.List; import java.util.Map; import java.util.Set; import javax.xml.bind.JAXBContext; import javax.xml.bind.JAXBElement; import javax.xml.bind.JAXBException; import javax.xml.bind.Unmarshaller; import javax.xml.validation.SchemaFactory; import org.bouncycastle.asn1.ASN1Encodable; import org.bouncycastle.asn1.ASN1EncodableVector; import org.bouncycastle.asn1.ASN1Integer; import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.asn1.ASN1Primitive; import org.bouncycastle.asn1.ASN1Sequence; import org.bouncycastle.asn1.ASN1StreamParser; import org.bouncycastle.asn1.DERSequence; import org.bouncycastle.asn1.DERTaggedObject; import org.bouncycastle.asn1.isismtt.x509.NamingAuthority; import org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers; import org.bouncycastle.asn1.x500.DirectoryString; import org.bouncycastle.asn1.x500.X500Name; import org.bouncycastle.asn1.x509.CertPolicyId; import org.bouncycastle.asn1.x509.Extension; import org.bouncycastle.asn1.x509.GeneralName; import org.bouncycastle.asn1.x509.GeneralSubtree; import org.bouncycastle.asn1.x509.NameConstraints; import org.bouncycastle.asn1.x509.PolicyInformation; import org.bouncycastle.asn1.x509.PolicyMappings; import org.bouncycastle.asn1.x509.PolicyQualifierInfo; import org.bouncycastle.asn1.x509.UserNotice; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.xipki.commons.common.util.CollectionUtil; import org.xipki.commons.common.util.ParamUtil; import org.xipki.commons.common.util.StringUtil; import org.xipki.commons.common.util.XmlUtil; import org.xipki.commons.security.KeyUsage; import org.xipki.commons.security.util.X509Util; import org.xipki.pki.ca.api.profile.CertprofileException; import org.xipki.pki.ca.api.profile.DirectoryStringType; import org.xipki.pki.ca.api.profile.ExtensionControl; import org.xipki.pki.ca.api.profile.ExtensionValue; import org.xipki.pki.ca.api.profile.GeneralNameMode; import org.xipki.pki.ca.api.profile.GeneralNameTag; import org.xipki.pki.ca.api.profile.KeyParametersOption; import org.xipki.pki.ca.api.profile.Range; import org.xipki.pki.ca.api.profile.StringType; import org.xipki.pki.ca.api.profile.x509.CertificatePolicyInformation; import org.xipki.pki.ca.api.profile.x509.CertificatePolicyQualifier; import org.xipki.pki.ca.api.profile.x509.ExtKeyUsageControl; import org.xipki.pki.ca.api.profile.x509.KeyUsageControl; import org.xipki.pki.ca.certprofile.commonpki.AdmissionSyntaxOption; import org.xipki.pki.ca.certprofile.commonpki.AdmissionsOption; import org.xipki.pki.ca.certprofile.commonpki.ProfessionInfoOption; import org.xipki.pki.ca.certprofile.commonpki.RegistrationNumberOption; import org.xipki.pki.ca.certprofile.x509.jaxb.AdmissionSyntax; import org.xipki.pki.ca.certprofile.x509.jaxb.AdmissionsType; import org.xipki.pki.ca.certprofile.x509.jaxb.AlgorithmType; import org.xipki.pki.ca.certprofile.x509.jaxb.CertificatePolicies; import org.xipki.pki.ca.certprofile.x509.jaxb.CertificatePolicyInformationType; import org.xipki.pki.ca.certprofile.x509.jaxb.CertificatePolicyInformationType.PolicyQualifiers; import org.xipki.pki.ca.certprofile.x509.jaxb.ConstantExtValue; import org.xipki.pki.ca.certprofile.x509.jaxb.DHParameters; import org.xipki.pki.ca.certprofile.x509.jaxb.DSAParameters; import org.xipki.pki.ca.certprofile.x509.jaxb.ECParameters; import org.xipki.pki.ca.certprofile.x509.jaxb.ECParameters.Curves; import org.xipki.pki.ca.certprofile.x509.jaxb.ExtendedKeyUsage; import org.xipki.pki.ca.certprofile.x509.jaxb.ExtendedKeyUsage.Usage; import org.xipki.pki.ca.certprofile.x509.jaxb.ExtensionType; import org.xipki.pki.ca.certprofile.x509.jaxb.ExtensionsType; import org.xipki.pki.ca.certprofile.x509.jaxb.GeneralNameType; import org.xipki.pki.ca.certprofile.x509.jaxb.GeneralSubtreeBaseType; import org.xipki.pki.ca.certprofile.x509.jaxb.GeneralSubtreesType; import org.xipki.pki.ca.certprofile.x509.jaxb.GostParameters; import org.xipki.pki.ca.certprofile.x509.jaxb.NamingAuthorityType; import org.xipki.pki.ca.certprofile.x509.jaxb.ObjectFactory; import org.xipki.pki.ca.certprofile.x509.jaxb.OidWithDescType; import org.xipki.pki.ca.certprofile.x509.jaxb.PolicyConstraints; import org.xipki.pki.ca.certprofile.x509.jaxb.PolicyIdMappingType; import org.xipki.pki.ca.certprofile.x509.jaxb.ProfessionInfoType; import org.xipki.pki.ca.certprofile.x509.jaxb.ProfessionInfoType.RegistrationNumber; import org.xipki.pki.ca.certprofile.x509.jaxb.RSAPSSParameters; import org.xipki.pki.ca.certprofile.x509.jaxb.RSAParameters; import org.xipki.pki.ca.certprofile.x509.jaxb.RangeType; import org.xipki.pki.ca.certprofile.x509.jaxb.RangesType; import org.xipki.pki.ca.certprofile.x509.jaxb.UsageType; import org.xipki.pki.ca.certprofile.x509.jaxb.X509ProfileType; import org.xipki.pki.ca.certprofile.x509.jaxb.X509ProfileType.KeyAlgorithms; import org.xml.sax.SAXException; /** * @author Lijun Liao * @since 2.0.0 */ public class XmlX509CertprofileUtil { private static final Logger LOG = LoggerFactory.getLogger(XmlX509CertprofileUtil.class); private static final Object JAXB_LOCK = new Object(); private static Unmarshaller jaxbUnmarshaller; private XmlX509CertprofileUtil() { } public static X509ProfileType parse(final InputStream xmlConfStream) throws CertprofileException { ParamUtil.requireNonNull("xmlConfStream", xmlConfStream); synchronized (JAXB_LOCK) { JAXBElement<?> rootElement; try { if (jaxbUnmarshaller == null) { JAXBContext context = JAXBContext.newInstance(ObjectFactory.class); jaxbUnmarshaller = context.createUnmarshaller(); final SchemaFactory schemaFact = SchemaFactory.newInstance( javax.xml.XMLConstants.W3C_XML_SCHEMA_NS_URI); URL url = XmlX509CertprofileUtil.class.getResource("/xsd/certprofile.xsd"); jaxbUnmarshaller.setSchema(schemaFact.newSchema(url)); } rootElement = (JAXBElement<?>) jaxbUnmarshaller.unmarshal(xmlConfStream); } catch (SAXException ex) { throw new CertprofileException("parse profile failed, message: " + ex.getMessage(), ex); } catch (JAXBException ex) { throw new CertprofileException( "parse profile failed, message: " + XmlUtil.getMessage(ex), ex); } try { xmlConfStream.close(); } catch (IOException ex) { LOG.warn("could not close xmlConfStream: {}", ex.getMessage()); } Object rootType = rootElement.getValue(); if (rootType instanceof X509ProfileType) { return (X509ProfileType) rootElement.getValue(); } else { throw new CertprofileException("invalid root element type"); } } } // method parse public static List<CertificatePolicyInformation> buildCertificatePolicies( final CertificatePolicies type) { List<CertificatePolicyInformationType> policyPairs = type.getCertificatePolicyInformation(); List<CertificatePolicyInformation> policies = new ArrayList<CertificatePolicyInformation>(policyPairs.size()); for (CertificatePolicyInformationType policyPair : policyPairs) { List<CertificatePolicyQualifier> qualifiers = null; PolicyQualifiers policyQualifiers = policyPair.getPolicyQualifiers(); if (policyQualifiers != null) { List<JAXBElement<String>> cpsUriOrUserNotice = policyQualifiers.getCpsUriOrUserNotice(); qualifiers = new ArrayList<CertificatePolicyQualifier>(cpsUriOrUserNotice.size()); for (JAXBElement<String> element : cpsUriOrUserNotice) { String elementValue = element.getValue(); CertificatePolicyQualifier qualifier = null; String elementName = element.getName().getLocalPart(); qualifier = "cpsUri".equals(elementName) ? CertificatePolicyQualifier.getInstanceForCpsUri(elementValue) : CertificatePolicyQualifier.getInstanceForUserNotice(elementValue); qualifiers.add(qualifier); } } CertificatePolicyInformation cpi = new CertificatePolicyInformation( policyPair.getPolicyIdentifier().getValue(), qualifiers); policies.add(cpi); } return policies; } // method buildCertificatePolicies public static PolicyMappings buildPolicyMappings( final org.xipki.pki.ca.certprofile.x509.jaxb.PolicyMappings type) { ParamUtil.requireNonNull("type", type); List<PolicyIdMappingType> mappings = type.getMapping(); final int n = mappings.size(); CertPolicyId[] issuerDomainPolicy = new CertPolicyId[n]; CertPolicyId[] subjectDomainPolicy = new CertPolicyId[n]; for (int i = 0; i < n; i++) { PolicyIdMappingType mapping = mappings.get(i); ASN1ObjectIdentifier oid = new ASN1ObjectIdentifier( mapping.getIssuerDomainPolicy().getValue()); issuerDomainPolicy[i] = CertPolicyId.getInstance(oid); oid = new ASN1ObjectIdentifier(mapping.getSubjectDomainPolicy().getValue()); subjectDomainPolicy[i] = CertPolicyId.getInstance(oid); } return new PolicyMappings(issuerDomainPolicy, subjectDomainPolicy); } // method buildPolicyMappings public static NameConstraints buildNameConstrains( final org.xipki.pki.ca.certprofile.x509.jaxb.NameConstraints type) throws CertprofileException { ParamUtil.requireNonNull("type", type); GeneralSubtree[] permitted = buildGeneralSubtrees(type.getPermittedSubtrees()); GeneralSubtree[] excluded = buildGeneralSubtrees(type.getExcludedSubtrees()); return (permitted == null && excluded == null) ? null : new NameConstraints(permitted, excluded); } // method buildNameConstrains private static GeneralSubtree[] buildGeneralSubtrees(final GeneralSubtreesType subtrees) throws CertprofileException { if (subtrees == null || CollectionUtil.isEmpty(subtrees.getBase())) { return null; } List<GeneralSubtreeBaseType> list = subtrees.getBase(); final int n = list.size(); GeneralSubtree[] ret = new GeneralSubtree[n]; for (int i = 0; i < n; i++) { ret[i] = buildGeneralSubtree(list.get(i)); } return ret; } // method buildGeneralSubtrees private static GeneralSubtree buildGeneralSubtree(final GeneralSubtreeBaseType type) throws CertprofileException { ParamUtil.requireNonNull("type", type); GeneralName base = null; if (type.getDirectoryName() != null) { base = new GeneralName(X509Util.reverse( new X500Name(type.getDirectoryName()))); } else if (type.getDnsName() != null) { base = new GeneralName(GeneralName.dNSName, type.getDnsName()); } else if (type.getIpAddress() != null) { base = new GeneralName(GeneralName.iPAddress, type.getIpAddress()); } else if (type.getRfc822Name() != null) { base = new GeneralName(GeneralName.rfc822Name, type.getRfc822Name()); } else if (type.getUri() != null) { base = new GeneralName(GeneralName.uniformResourceIdentifier, type.getUri()); } else { throw new RuntimeException( "should not reach here, unknown child of GeneralSubtreeBaseType"); } Integer min = type.getMinimum(); if (min != null && min < 0) { throw new CertprofileException("negative minimum is not allowed: " + min); } BigInteger minimum = (min == null) ? null : BigInteger.valueOf(min.intValue()); Integer max = type.getMaximum(); if (max != null && max < 0) { throw new CertprofileException("negative maximum is not allowed: " + max); } BigInteger maximum = (max == null) ? null : BigInteger.valueOf(max.intValue()); return new GeneralSubtree(base, minimum, maximum); } // method buildGeneralSubtree public static ASN1Sequence buildPolicyConstrains(final PolicyConstraints type) throws CertprofileException { ParamUtil.requireNonNull("type", type); Integer requireExplicitPolicy = type.getRequireExplicitPolicy(); if (requireExplicitPolicy != null && requireExplicitPolicy < 0) { throw new CertprofileException( "negative requireExplicitPolicy is not allowed: " + requireExplicitPolicy); } Integer inhibitPolicyMapping = type.getInhibitPolicyMapping(); if (inhibitPolicyMapping != null && inhibitPolicyMapping < 0) { throw new CertprofileException( "negative inhibitPolicyMapping is not allowed: " + inhibitPolicyMapping); } if (requireExplicitPolicy == null && inhibitPolicyMapping == null) { return null; } final boolean explicit = false; ASN1EncodableVector vec = new ASN1EncodableVector(); if (requireExplicitPolicy != null) { vec.add(new DERTaggedObject(explicit, 0, new ASN1Integer(BigInteger.valueOf(requireExplicitPolicy)))); } if (inhibitPolicyMapping != null) { vec.add(new DERTaggedObject(explicit, 1, new ASN1Integer(BigInteger.valueOf(inhibitPolicyMapping)))); } return new DERSequence(vec); } //method buildPolicyConstrains public static Set<GeneralNameMode> buildGeneralNameMode(final GeneralNameType name) throws CertprofileException { ParamUtil.requireNonNull("name", name); Set<GeneralNameMode> ret = new HashSet<>(); if (name.getOtherName() != null) { List<OidWithDescType> list = name.getOtherName().getType(); Set<ASN1ObjectIdentifier> set = new HashSet<>(); for (OidWithDescType entry : list) { set.add(new ASN1ObjectIdentifier(entry.getValue())); } ret.add(new GeneralNameMode(GeneralNameTag.otherName, set)); } if (name.getRfc822Name() != null) { ret.add(new GeneralNameMode(GeneralNameTag.rfc822Name)); } if (name.getDnsName() != null) { ret.add(new GeneralNameMode(GeneralNameTag.dNSName)); } if (name.getDirectoryName() != null) { ret.add(new GeneralNameMode(GeneralNameTag.directoryName)); } if (name.getEdiPartyName() != null) { ret.add(new GeneralNameMode(GeneralNameTag.ediPartyName)); } if (name.getUniformResourceIdentifier() != null) { ret.add(new GeneralNameMode(GeneralNameTag.uniformResourceIdentifier)); } if (name.getIpAddress() != null) { ret.add(new GeneralNameMode(GeneralNameTag.iPAddress)); } if (name.getRegisteredID() != null) { ret.add(new GeneralNameMode(GeneralNameTag.registeredID)); } if (ret.isEmpty()) { throw new CertprofileException("GeneralNameType must not be empty"); } return ret; } // method buildGeneralNameMode private static Set<Range> buildParametersMap(final RangesType ranges) { if (ranges == null) { return null; } Set<Range> ret = new HashSet<>(); for (RangeType range : ranges.getRange()) { if (range.getMin() != null || range.getMax() != null) { ret.add(new Range(range.getMin(), range.getMax())); } } return ret; } public static Map<ASN1ObjectIdentifier, KeyParametersOption> buildKeyAlgorithms( final KeyAlgorithms keyAlgos) throws CertprofileException { ParamUtil.requireNonNull("keyAlgos", keyAlgos); Map<ASN1ObjectIdentifier, KeyParametersOption> keyAlgorithms = new HashMap<>(); for (AlgorithmType type : keyAlgos.getAlgorithm()) { List<OidWithDescType> algIds = type.getAlgorithm(); List<ASN1ObjectIdentifier> oids = new ArrayList<>(algIds.size()); for (OidWithDescType algId : algIds) { ASN1ObjectIdentifier oid = new ASN1ObjectIdentifier(algId.getValue()); if (keyAlgorithms.containsKey(oid)) { throw new CertprofileException( "duplicate definition of keyAlgorithm " + oid.getId()); } oids.add(oid); } KeyParametersOption keyParamsOption = convertKeyParametersOption(type); for (ASN1ObjectIdentifier oid : oids) { keyAlgorithms.put(oid, keyParamsOption); } } return CollectionUtil.unmodifiableMap(keyAlgorithms); } // method buildKeyAlgorithms public static Map<ASN1ObjectIdentifier, ExtensionControl> buildExtensionControls( final ExtensionsType extensionsType) throws CertprofileException { ParamUtil.requireNonNull("extensionsType", extensionsType); // Extension controls Map<ASN1ObjectIdentifier, ExtensionControl> controls = new HashMap<>(); for (ExtensionType m : extensionsType.getExtension()) { ASN1ObjectIdentifier oid = new ASN1ObjectIdentifier(m.getType().getValue()); if (controls.containsKey(oid)) { throw new CertprofileException( "duplicated definition of extension " + oid.getId()); } ExtensionControl ctrl = new ExtensionControl(m.isCritical(), m.isRequired(), m.isPermittedInRequest()); controls.put(oid, ctrl); } return Collections.unmodifiableMap(controls); } // method buildExtensionControls public static List<ASN1ObjectIdentifier> toOidList( final List<OidWithDescType> oidWithDescTypes) { if (CollectionUtil.isEmpty(oidWithDescTypes)) { return null; } List<ASN1ObjectIdentifier> oids = new LinkedList<>(); for (OidWithDescType type : oidWithDescTypes) { oids.add(new ASN1ObjectIdentifier(type.getValue())); } return Collections.unmodifiableList(oids); } // method toOidList public static Set<KeyUsageControl> buildKeyUsageOptions( final org.xipki.pki.ca.certprofile.x509.jaxb.KeyUsage extConf) { ParamUtil.requireNonNull("extConf", extConf); List<UsageType> usages = extConf.getUsage(); Set<KeyUsageControl> controls = new HashSet<>(); for (UsageType m : usages) { boolean required = m.isRequired(); switch (m.getValue()) { case CRL_SIGN: controls.add(new KeyUsageControl(KeyUsage.cRLSign, required)); break; case DATA_ENCIPHERMENT: controls.add(new KeyUsageControl(KeyUsage.dataEncipherment, required)); break; case CONTENT_COMMITMENT: controls.add(new KeyUsageControl(KeyUsage.contentCommitment, required)); break; case DECIPHER_ONLY: controls.add(new KeyUsageControl(KeyUsage.decipherOnly, required)); break; case ENCIPHER_ONLY: controls.add(new KeyUsageControl(KeyUsage.encipherOnly, required)); break; case DIGITAL_SIGNATURE: controls.add(new KeyUsageControl(KeyUsage.digitalSignature, required)); break; case KEY_AGREEMENT: controls.add(new KeyUsageControl(KeyUsage.keyAgreement, required)); break; case KEY_CERT_SIGN: controls.add(new KeyUsageControl(KeyUsage.keyCertSign, required)); break; case KEY_ENCIPHERMENT: controls.add(new KeyUsageControl(KeyUsage.keyEncipherment, required)); break; default: throw new RuntimeException( "should not reach here, unknown GeneralSubtreeBaseType " + m.getValue()); } } return Collections.unmodifiableSet(controls); } // method buildKeyUsageOptions public static Set<ExtKeyUsageControl> buildExtKeyUsageOptions(final ExtendedKeyUsage extConf) { ParamUtil.requireNonNull("extConf", extConf); List<Usage> usages = extConf.getUsage(); Set<ExtKeyUsageControl> controls = new HashSet<>(); for (Usage m : usages) { ExtKeyUsageControl usage = new ExtKeyUsageControl( new ASN1ObjectIdentifier(m.getValue()), m.isRequired()); controls.add(usage); } return Collections.unmodifiableSet(controls); } // method buildExtKeyUsageOptions public static Map<ASN1ObjectIdentifier, ExtensionValue> buildConstantExtesions( final ExtensionsType extensionsType) throws CertprofileException { if (extensionsType == null) { return null; } Map<ASN1ObjectIdentifier, ExtensionValue> map = new HashMap<>(); for (ExtensionType m : extensionsType.getExtension()) { ASN1ObjectIdentifier oid = new ASN1ObjectIdentifier(m.getType().getValue()); if (Extension.subjectAlternativeName.equals(oid) || Extension.subjectInfoAccess.equals(oid) || Extension.biometricInfo.equals(oid)) { continue; } if (m.getValue() == null || !(m.getValue().getAny() instanceof ConstantExtValue)) { continue; } ConstantExtValue extConf = (ConstantExtValue) m.getValue().getAny(); byte[] encodedValue = extConf.getValue(); ASN1StreamParser parser = new ASN1StreamParser(encodedValue); ASN1Encodable value; try { value = parser.readObject(); } catch (IOException ex) { throw new CertprofileException("could not parse the constant extension value", ex); } ExtensionValue extension = new ExtensionValue(m.isCritical(), value); map.put(oid, extension); } if (CollectionUtil.isEmpty(map)) { return null; } return Collections.unmodifiableMap(map); } // buildConstantExtesions public static Set<ASN1ObjectIdentifier> toOidSet(final List<OidWithDescType> oidWithDescTypes) { if (CollectionUtil.isEmpty(oidWithDescTypes)) { return null; } Set<ASN1ObjectIdentifier> oids = new HashSet<>(); for (OidWithDescType type : oidWithDescTypes) { oids.add(new ASN1ObjectIdentifier(type.getValue())); } return Collections.unmodifiableSet(oids); } public static AdmissionSyntaxOption buildAdmissionSyntax(final boolean critical, final AdmissionSyntax type) throws CertprofileException { List<AdmissionsOption> admissionsList = new LinkedList<>(); for (AdmissionsType at : type.getContentsOfAdmissions()) { List<ProfessionInfoOption> professionInfos = new LinkedList<>(); for (ProfessionInfoType pi : at.getProfessionInfo()) { NamingAuthority namingAuthorityL3 = null; if (pi.getNamingAuthority() != null) { namingAuthorityL3 = buildNamingAuthority(pi.getNamingAuthority()); } List<OidWithDescType> oidTypes = pi.getProfessionOid(); List<ASN1ObjectIdentifier> oids = null; if (CollectionUtil.isNonEmpty(oidTypes) ) { oids = new LinkedList<>(); for (OidWithDescType k : oidTypes) { oids.add(new ASN1ObjectIdentifier(k.getValue())); } } RegistrationNumber rnType = pi.getRegistrationNumber(); RegistrationNumberOption rno = (rnType == null) ? null : new RegistrationNumberOption(rnType.getRegex(), rnType.getConstant()); ProfessionInfoOption pio = new ProfessionInfoOption(namingAuthorityL3, pi.getProfessionItem(), oids, rno, pi.getAddProfessionInfo()); professionInfos.add(pio); } GeneralName admissionAuthority = null; if (at.getNamingAuthority() != null) { admissionAuthority = GeneralName.getInstance( asn1PrimitivefromByteArray(at.getAdmissionAuthority())); } NamingAuthority namingAuthority = null; if (at.getNamingAuthority() != null) { namingAuthority = buildNamingAuthority(at.getNamingAuthority()); } AdmissionsOption admissionsOption = new AdmissionsOption(admissionAuthority, namingAuthority, professionInfos); admissionsList.add(admissionsOption); } GeneralName admissionAuthority = null; if (type.getAdmissionAuthority() != null) { admissionAuthority = GeneralName.getInstance(type.getAdmissionAuthority()); } return new AdmissionSyntaxOption(critical, admissionAuthority, admissionsList); } private static ASN1Primitive asn1PrimitivefromByteArray(final byte[] encoded) throws CertprofileException { try { return ASN1Primitive.fromByteArray(encoded); } catch (IOException ex) { throw new CertprofileException(ex.getMessage(), ex); } } private static KeyParametersOption convertKeyParametersOption(final AlgorithmType type) throws CertprofileException { ParamUtil.requireNonNull("type", type); if (type.getParameters() == null || type.getParameters().getAny() == null) { return KeyParametersOption.ALLOW_ALL; } Object paramsObj = type.getParameters().getAny(); if (paramsObj instanceof ECParameters) { ECParameters params = (ECParameters) paramsObj; KeyParametersOption.ECParamatersOption option = new KeyParametersOption.ECParamatersOption(); if (params.getCurves() != null) { Curves curves = params.getCurves(); Set<ASN1ObjectIdentifier> curveOids = toOidSet(curves.getCurve()); option.setCurveOids(curveOids); } if (params.getPointEncodings() != null) { List<Byte> bytes = params.getPointEncodings().getPointEncoding(); Set<Byte> pointEncodings = new HashSet<>(bytes); option.setPointEncodings(pointEncodings); } return option; } else if (paramsObj instanceof RSAParameters) { RSAParameters params = (RSAParameters) paramsObj; KeyParametersOption.RSAParametersOption option = new KeyParametersOption.RSAParametersOption(); Set<Range> modulusLengths = buildParametersMap(params.getModulusLength()); option.setModulusLengths(modulusLengths); return option; } else if (paramsObj instanceof RSAPSSParameters) { RSAPSSParameters params = (RSAPSSParameters) paramsObj; KeyParametersOption.RSAPSSParametersOption option = new KeyParametersOption.RSAPSSParametersOption(); Set<Range> modulusLengths = buildParametersMap(params.getModulusLength()); option.setModulusLengths(modulusLengths); return option; } else if (paramsObj instanceof DSAParameters) { DSAParameters params = (DSAParameters) paramsObj; KeyParametersOption.DSAParametersOption option = new KeyParametersOption.DSAParametersOption(); Set<Range> plengths = buildParametersMap(params.getPLength()); option.setPlengths(plengths); Set<Range> qlengths = buildParametersMap(params.getQLength()); option.setQlengths(qlengths); return option; } else if (paramsObj instanceof DHParameters) { DHParameters params = (DHParameters) paramsObj; KeyParametersOption.DHParametersOption option = new KeyParametersOption.DHParametersOption(); Set<Range> plengths = buildParametersMap(params.getPLength()); option.setPlengths(plengths); Set<Range> qlengths = buildParametersMap(params.getQLength()); option.setQlengths(qlengths); return option; } else if (paramsObj instanceof GostParameters) { GostParameters params = (GostParameters) paramsObj; KeyParametersOption.GostParametersOption option = new KeyParametersOption.GostParametersOption(); Set<ASN1ObjectIdentifier> set = toOidSet(params.getPublicKeyParamSet()); option.setPublicKeyParamSets(set); set = toOidSet(params.getDigestParamSet()); option.setDigestParamSets(set); set = toOidSet(params.getEncryptionParamSet()); option.setEncryptionParamSets(set); return option; } else { throw new CertprofileException( "unknown public key parameters type " + paramsObj.getClass().getName()); } } // method convertKeyParametersOption public static final DirectoryStringType convertDirectoryStringType( final org.xipki.pki.ca.certprofile.x509.jaxb.DirectoryStringType jaxbType) { if (jaxbType == null) { return null; } switch (jaxbType) { case BMP_STRING: return DirectoryStringType.bmpString; case PRINTABLE_STRING: return DirectoryStringType.printableString; case TELETEX_STRING: return DirectoryStringType.teletexString; case UTF_8_STRING: return DirectoryStringType.utf8String; default: throw new RuntimeException( "should not reach here, undefined DirectoryStringType " + jaxbType); } } public static final StringType convertStringType( final org.xipki.pki.ca.certprofile.x509.jaxb.StringType jaxbType) { if (jaxbType == null) { return null; } switch (jaxbType) { case BMP_STRING: return StringType.bmpString; case PRINTABLE_STRING: return StringType.printableString; case TELETEX_STRING: return StringType.teletexString; case UTF_8_STRING: return StringType.utf8String; case IA_5_STRING: return StringType.ia5String; default: throw new RuntimeException("should not reach here, undefined StringType " + jaxbType); } } public static org.bouncycastle.asn1.x509.CertificatePolicies createCertificatePolicies( final List<CertificatePolicyInformation> policyInfos) throws CertprofileException { ParamUtil.requireNonEmpty("policyInfos", policyInfos); int size = policyInfos.size(); PolicyInformation[] infos = new PolicyInformation[size]; int idx = 0; for (CertificatePolicyInformation policyInfo : policyInfos) { String policyId = policyInfo.getCertPolicyId(); List<CertificatePolicyQualifier> qualifiers = policyInfo.getQualifiers(); ASN1Sequence policyQualifiers = null; if (CollectionUtil.isNonEmpty(qualifiers)) { policyQualifiers = createPolicyQualifiers(qualifiers); } ASN1ObjectIdentifier policyOid = new ASN1ObjectIdentifier(policyId); infos[idx++] = (policyQualifiers == null) ? new PolicyInformation(policyOid) : new PolicyInformation(policyOid, policyQualifiers); } return new org.bouncycastle.asn1.x509.CertificatePolicies(infos); } private static ASN1Sequence createPolicyQualifiers( final List<CertificatePolicyQualifier> qualifiers) { ParamUtil.requireNonNull("qualifiers", qualifiers); List<PolicyQualifierInfo> qualifierInfos = new ArrayList<>(qualifiers.size()); for (CertificatePolicyQualifier qualifier : qualifiers) { PolicyQualifierInfo qualifierInfo; if (qualifier.getCpsUri() != null) { qualifierInfo = new PolicyQualifierInfo(qualifier.getCpsUri()); } else if (qualifier.getUserNotice() != null) { UserNotice userNotice = new UserNotice(null, qualifier.getUserNotice()); qualifierInfo = new PolicyQualifierInfo(PKCSObjectIdentifiers.id_spq_ets_unotice, userNotice); } else { qualifierInfo = null; } if (qualifierInfo != null) { qualifierInfos.add(qualifierInfo); } //PolicyQualifierId qualifierId } return new DERSequence(qualifierInfos.toArray(new PolicyQualifierInfo[0])); } private static NamingAuthority buildNamingAuthority(final NamingAuthorityType jaxb) { ASN1ObjectIdentifier oid = (jaxb.getOid() == null) ? null : new ASN1ObjectIdentifier(jaxb.getOid().getValue()); String url = StringUtil.isBlank(jaxb.getUrl()) ? null : jaxb.getUrl(); DirectoryString text = StringUtil.isBlank(jaxb.getText()) ? null : new DirectoryString(jaxb.getText()); return new NamingAuthority(oid, url, text); } }