List of usage examples for org.bouncycastle.asn1.x509 Attribute Attribute
public Attribute(ASN1ObjectIdentifier attrType, ASN1Set attrValues)
From source file:com.peterphi.std.crypto.keygen.CaHelper.java
License:Open Source License
public static PKCS10CertificationRequest generateCertificateRequest(X509Certificate cert, PrivateKey signingKey) throws Exception { ASN1EncodableVector attributes = new ASN1EncodableVector(); Set<String> nonCriticalExtensionOIDs = cert.getNonCriticalExtensionOIDs(); for (String nceoid : nonCriticalExtensionOIDs) { byte[] derBytes = cert.getExtensionValue(nceoid); ByteArrayInputStream bis = new ByteArrayInputStream(derBytes); ASN1InputStream dis = new ASN1InputStream(bis); try {//from www . j av a2s . c o m DERObject derObject = dis.readObject(); DERSet value = new DERSet(derObject); Attribute attr = new Attribute(new DERObjectIdentifier(nceoid), value); attributes.add(attr); } finally { IOUtils.closeQuietly(dis); } } PKCS10CertificationRequest certificationRequest = new PKCS10CertificationRequest(getSignatureAlgorithm(), cert.getSubjectX500Principal(), cert.getPublicKey(), new DERSet(attributes), signingKey); return certificationRequest; }
From source file:de.brendamour.jpasskit.signing.PKAbstractSIgningUtil.java
License:Apache License
protected byte[] signManifestUsingContent(PKSigningInformation signingInformation, CMSTypedData content) throws PKSigningException { if (signingInformation == null || !signingInformation.isValid()) { throw new IllegalArgumentException("Signing information not valid"); }/*from w w w.j a v a2 s . c o m*/ try { CMSSignedDataGenerator generator = new CMSSignedDataGenerator(); ContentSigner sha1Signer = new JcaContentSignerBuilder("SHA1withRSA") .setProvider(BouncyCastleProvider.PROVIDER_NAME) .build(signingInformation.getSigningPrivateKey()); final ASN1EncodableVector signedAttributes = new ASN1EncodableVector(); final Attribute signingAttribute = new Attribute(CMSAttributes.signingTime, new DERSet(new DERUTCTime(new Date()))); signedAttributes.add(signingAttribute); // Create the signing table final AttributeTable signedAttributesTable = new AttributeTable(signedAttributes); // Create the table table generator that will added to the Signer builder final DefaultSignedAttributeTableGenerator signedAttributeGenerator = new DefaultSignedAttributeTableGenerator( signedAttributesTable); generator.addSignerInfoGenerator( new JcaSignerInfoGeneratorBuilder(new JcaDigestCalculatorProviderBuilder() .setProvider(BouncyCastleProvider.PROVIDER_NAME).build()) .setSignedAttributeGenerator(signedAttributeGenerator) .build(sha1Signer, signingInformation.getSigningCert())); List<X509Certificate> certList = new ArrayList<X509Certificate>(); certList.add(signingInformation.getAppleWWDRCACert()); certList.add(signingInformation.getSigningCert()); JcaCertStore certs = new JcaCertStore(certList); generator.addCertificates(certs); CMSSignedData sigData = generator.generate(content, false); return sigData.getEncoded(); } catch (Exception e) { throw new PKSigningException("Error when signing manifest", e); } }
From source file:org.cesecore.certificates.util.cert.SubjectDirAttrExtension.java
License:Open Source License
/** * From subjectDirAttributes string as defined in getSubjectDirAttribute * @param dirAttr string of SubjectDirectoryAttributes * @return A Collection of ASN.1 Attribute (org.bouncycastle.asn1.x509), or an empty Collection, never null * @see #getSubjectDirectoryAttributes(Certificate) */// www . java 2 s. c om public static Collection<Attribute> getSubjectDirectoryAttributes(String dirAttr) { ArrayList<Attribute> ret = new ArrayList<Attribute>(); Attribute attr = null; String value = CertTools.getPartFromDN(dirAttr, "countryOfResidence"); if (!StringUtils.isEmpty(value)) { ASN1EncodableVector vec = new ASN1EncodableVector(); vec.add(new DERPrintableString(value)); attr = new Attribute(new ASN1ObjectIdentifier(id_pda_countryOfResidence), new DERSet(vec)); ret.add(attr); } value = CertTools.getPartFromDN(dirAttr, "countryOfCitizenship"); if (!StringUtils.isEmpty(value)) { ASN1EncodableVector vec = new ASN1EncodableVector(); vec.add(new DERPrintableString(value)); attr = new Attribute(new ASN1ObjectIdentifier(id_pda_countryOfCitizenship), new DERSet(vec)); ret.add(attr); } value = CertTools.getPartFromDN(dirAttr, "gender"); if (!StringUtils.isEmpty(value)) { ASN1EncodableVector vec = new ASN1EncodableVector(); vec.add(new DERPrintableString(value)); attr = new Attribute(new ASN1ObjectIdentifier(id_pda_gender), new DERSet(vec)); ret.add(attr); } value = CertTools.getPartFromDN(dirAttr, "placeOfBirth"); if (!StringUtils.isEmpty(value)) { ASN1EncodableVector vec = new ASN1EncodableVector(); X509DefaultEntryConverter conv = new X509DefaultEntryConverter(); ASN1Primitive obj = conv.getConvertedValue(new ASN1ObjectIdentifier(id_pda_placeOfBirth), value); vec.add(obj); attr = new Attribute(new ASN1ObjectIdentifier(id_pda_placeOfBirth), new DERSet(vec)); ret.add(attr); } // dateOfBirth that is a GeneralizedTime // The correct format for this is YYYYMMDD, it will be padded to YYYYMMDD120000Z value = CertTools.getPartFromDN(dirAttr, "dateOfBirth"); if (!StringUtils.isEmpty(value)) { if (value.length() == 8) { value += "120000Z"; // standard format according to rfc3739 ASN1EncodableVector vec = new ASN1EncodableVector(); vec.add(new DERGeneralizedTime(value)); attr = new Attribute(new ASN1ObjectIdentifier(id_pda_dateOfBirth), new DERSet(vec)); ret.add(attr); } else { log.error("Wrong length of data for 'dateOfBirth', should be of format YYYYMMDD, skipping..."); } } return ret; }
From source file:org.ejbca.util.cert.SubjectDirAttrExtension.java
License:Open Source License
/** * From subjectDirAttributes string as defined in getSubjectDirAttribute * @param dirAttr string of SubjectDirectoryAttributes * @return A Collection of ASN.1 Attribute (org.bouncycastle.asn1.x509), or an empty Collection, never null * @see #getSubjectDirectoryAttributes(Certificate) *//*from w w w . j av a 2 s. com*/ public static Collection<Attribute> getSubjectDirectoryAttributes(String dirAttr) { ArrayList<Attribute> ret = new ArrayList<Attribute>(); Attribute attr = null; String value = CertTools.getPartFromDN(dirAttr, "countryOfResidence"); if (!StringUtils.isEmpty(value)) { ASN1EncodableVector vec = new ASN1EncodableVector(); vec.add(new DERPrintableString(value)); attr = new Attribute(new DERObjectIdentifier(id_pda_countryOfResidence), new DERSet(vec)); ret.add(attr); } value = CertTools.getPartFromDN(dirAttr, "countryOfCitizenship"); if (!StringUtils.isEmpty(value)) { ASN1EncodableVector vec = new ASN1EncodableVector(); vec.add(new DERPrintableString(value)); attr = new Attribute(new DERObjectIdentifier(id_pda_countryOfCitizenship), new DERSet(vec)); ret.add(attr); } value = CertTools.getPartFromDN(dirAttr, "gender"); if (!StringUtils.isEmpty(value)) { ASN1EncodableVector vec = new ASN1EncodableVector(); vec.add(new DERPrintableString(value)); attr = new Attribute(new DERObjectIdentifier(id_pda_gender), new DERSet(vec)); ret.add(attr); } value = CertTools.getPartFromDN(dirAttr, "placeOfBirth"); if (!StringUtils.isEmpty(value)) { ASN1EncodableVector vec = new ASN1EncodableVector(); X509DefaultEntryConverter conv = new X509DefaultEntryConverter(); DERObject obj = conv.getConvertedValue(new DERObjectIdentifier(id_pda_placeOfBirth), value); vec.add(obj); attr = new Attribute(new DERObjectIdentifier(id_pda_placeOfBirth), new DERSet(vec)); ret.add(attr); } // dateOfBirth that is a GeneralizedTime // The correct format for this is YYYYMMDD, it will be padded to YYYYMMDD120000Z value = CertTools.getPartFromDN(dirAttr, "dateOfBirth"); if (!StringUtils.isEmpty(value)) { if (value.length() == 8) { value += "120000Z"; // standard format according to rfc3739 ASN1EncodableVector vec = new ASN1EncodableVector(); vec.add(new DERGeneralizedTime(value)); attr = new Attribute(new DERObjectIdentifier(id_pda_dateOfBirth), new DERSet(vec)); ret.add(attr); } else { log.error("Wrong length of data for 'dateOfBirth', should be of format YYYYMMDD, skipping..."); } } return ret; }
From source file:org.glite.slcs.pki.bouncycastle.PKCS10.java
License:eu-egee.org license
/** * //from w w w .j ava 2s .c o m * @param subject * @param publicKey * @param privateKey * @param x509Extensions * @throws GeneralSecurityException */ public PKCS10(String subject, PublicKey publicKey, PrivateKey privateKey, X509Extensions x509Extensions) throws GeneralSecurityException { // subject DN X509PrincipalUtil util = new X509PrincipalUtil(); X509Principal principal = util.createX509Principal(subject); LOG.debug("X509Principal: " + principal); // extensions ASN1Set attributes = new DERSet(); if (x509Extensions != null) { // PKCS9 extensions DERSet extensions = new DERSet(x509Extensions); Attribute attribute = new Attribute(PKCSObjectIdentifiers.pkcs_9_at_extensionRequest, extensions); attributes = new DERSet(attribute); } // create CSR bcPKCS10_ = new PKCS10CertificationRequest(SIGNATURE_ALGORITHM, principal, publicKey, attributes, privateKey); // verify if (!bcPKCS10_.verify()) { LOG.error("Failed to verify the PKCS#10"); throw new GeneralSecurityException("PKCS#10 verification failed"); } }
From source file:org.qipki.crypto.x509.X509GeneratorImpl.java
License:Open Source License
@SuppressWarnings({ "UseOfObsoleteCollectionType", "unchecked" }) private DERSet generateSANAttribute(GeneralNames subGeneralNames) { if (subGeneralNames == null) { return new DERSet(); }// w w w.j av a 2 s . co m Vector oids = new Vector(); Vector values = new Vector(); oids.add(X509Extensions.SubjectAlternativeName); values.add(new X509Extension(false, new DEROctetString(subGeneralNames))); X509Extensions extensions = new X509Extensions(oids, values); Attribute attribute = new Attribute(PKCSObjectIdentifiers.pkcs_9_at_extensionRequest, new DERSet(extensions)); return new DERSet(attribute); }
From source file:org.signserver.module.tsa.MSAuthCodeTimeStampSigner.java
License:Open Source License
/** * The main method performing the actual timestamp operation. * Expects the signRequest to be a GenericSignRequest contining a * TimeStampRequest/*from w w w.j ava 2 s .com*/ * * @param signRequest * @param requestContext * @return the sign response * @see org.signserver.server.IProcessable#processData(org.signserver.common.ProcessRequest, org.signserver.common.RequestContext) */ public ProcessResponse processData(final ProcessRequest signRequest, final RequestContext requestContext) throws IllegalRequestException, CryptoTokenOfflineException, SignServerException { // Log values final LogMap logMap = LogMap.getInstance(requestContext); try { final ISignRequest sReq = (ISignRequest) signRequest; final byte[] requestbytes = (byte[]) sReq.getRequestData(); if (requestbytes == null || requestbytes.length == 0) { LOG.error("Request must contain data"); throw new IllegalRequestException("Request must contain data"); } // Check that the request contains a valid TimeStampRequest object. if (!(signRequest instanceof GenericSignRequest)) { final IllegalRequestException exception = new IllegalRequestException( "Recieved request wasn't an expected GenericSignRequest. "); LOG.error("Received request wasn't an expected GenericSignRequest"); throw exception; } if (!((sReq.getRequestData() instanceof TimeStampRequest) || (sReq.getRequestData() instanceof byte[]))) { final IllegalRequestException exception = new IllegalRequestException( "Recieved request data wasn't an expected TimeStampRequest. "); LOG.error("Received request data wasn't an expected TimeStampRequest"); throw exception; } if (!validChain) { LOG.error("Certificate chain not correctly configured"); throw new CryptoTokenOfflineException("Certificate chain not correctly configured"); } ASN1Primitive asn1obj = ASN1Primitive.fromByteArray(Base64.decode(requestbytes)); ASN1Sequence asn1seq = ASN1Sequence.getInstance(asn1obj); if (asn1seq.size() != 2) { LOG.error("Wrong structure, should be an ASN1Sequence with 2 elements"); throw new IllegalRequestException("Wrong structure, should be an ASN1Sequence with 2 elements"); } ASN1ObjectIdentifier oid = ASN1ObjectIdentifier.getInstance(asn1seq.getObjectAt(0)); ASN1Sequence asn1seq1 = ASN1Sequence.getInstance(asn1seq.getObjectAt(1)); final ContentInfo ci = new ContentInfo(asn1seq1); if (!oid.getId().equals(msOID)) { LOG.error("Invalid OID in request: " + oid.getId()); throw new IllegalRequestException("Invalid OID in request: " + oid.getId()); } if (asn1seq1.size() != 2) { LOG.error( "Wrong structure, should be an ASN1Sequence with 2 elements as the value of element 0 in the outer ASN1Sequence"); throw new IllegalRequestException( "Wrong structure, should be an ASN1Sequence with 2 elements as the value of element 0 in the outer ASN1Sequence"); } oid = ASN1ObjectIdentifier.getInstance(asn1seq1.getObjectAt(0)); if (!oid.getId().equals(dataOID)) { throw new IllegalRequestException("Wrong contentType OID: " + oid.getId()); } ASN1TaggedObject tag = ASN1TaggedObject.getInstance(asn1seq1.getObjectAt(1)); if (tag.getTagNo() != 0) { throw new IllegalRequestException("Wrong tag no (should be 0): " + tag.getTagNo()); } ASN1OctetString octets = ASN1OctetString.getInstance(tag.getObject()); byte[] content = octets.getOctets(); final ITimeSource timeSrc; final Date date; byte[] der; ICryptoInstance crypto = null; try { crypto = acquireCryptoInstance(ICryptoToken.PURPOSE_SIGN, signRequest, requestContext); // get signing cert certificate chain and private key List<Certificate> certList = this.getSigningCertificateChain(crypto); if (certList == null) { throw new SignServerException("Null certificate chain. This signer needs a certificate."); } Certificate[] certs = (Certificate[]) certList.toArray(new Certificate[certList.size()]); // Sign X509Certificate x509cert = (X509Certificate) certs[0]; timeSrc = getTimeSource(); if (LOG.isDebugEnabled()) { LOG.debug("TimeSource: " + timeSrc.getClass().getName()); } date = timeSrc.getGenTime(); if (date == null) { throw new ServiceUnavailableException("Time source is not available"); } ASN1EncodableVector signedAttributes = new ASN1EncodableVector(); signedAttributes.add(new Attribute(CMSAttributes.signingTime, new DERSet(new Time(date)))); if (includeSigningCertificateAttribute) { try { final DERInteger serial = new DERInteger(x509cert.getSerialNumber()); final X509CertificateHolder certHolder = new X509CertificateHolder(x509cert.getEncoded()); final X500Name issuer = certHolder.getIssuer(); final GeneralName name = new GeneralName(issuer); final GeneralNames names = new GeneralNames(name); final IssuerSerial is = new IssuerSerial(names, ASN1Integer.getInstance(serial)); final ESSCertID essCertid = new ESSCertID( MessageDigest.getInstance("SHA-1").digest(x509cert.getEncoded()), is); signedAttributes.add(new Attribute(PKCSObjectIdentifiers.id_aa_signingCertificate, new DERSet(new SigningCertificate(essCertid)))); } catch (NoSuchAlgorithmException e) { LOG.error("Can't find SHA-1 implementation: " + e.getMessage()); throw new SignServerException("Can't find SHA-1 implementation", e); } } AttributeTable signedAttributesTable = new AttributeTable(signedAttributes); DefaultSignedAttributeTableGenerator signedAttributeGenerator = new DefaultSignedAttributeTableGenerator( signedAttributesTable); final String provider = cryptoToken.getProvider(ICryptoToken.PROVIDERUSAGE_SIGN); SignerInfoGeneratorBuilder signerInfoBuilder = new SignerInfoGeneratorBuilder( new JcaDigestCalculatorProviderBuilder().setProvider("BC").build()); signerInfoBuilder.setSignedAttributeGenerator(signedAttributeGenerator); JcaContentSignerBuilder contentSigner = new JcaContentSignerBuilder(signatureAlgo); contentSigner.setProvider(provider); final SignerInfoGenerator sig = signerInfoBuilder.build(contentSigner.build(crypto.getPrivateKey()), new X509CertificateHolder(x509cert.getEncoded())); JcaCertStore cs = new JcaCertStore(certList); CMSTypedData cmspba = new CMSProcessableByteArray(content); CMSSignedData cmssd = MSAuthCodeCMSUtils.generate(cmspba, true, Arrays.asList(sig), MSAuthCodeCMSUtils.getCertificatesFromStore(cs), Collections.emptyList(), ci); der = ASN1Primitive.fromByteArray(cmssd.getEncoded()).getEncoded(); } finally { releaseCryptoInstance(crypto, requestContext); } // Log values logMap.put(ITimeStampLogger.LOG_TSA_TIME, String.valueOf(date.getTime())); logMap.put(ITimeStampLogger.LOG_TSA_TIMESOURCE, timeSrc.getClass().getSimpleName()); final String archiveId = createArchiveId(requestbytes, (String) requestContext.get(RequestContext.TRANSACTION_ID)); final GenericSignResponse signResponse; byte[] signedbytes = Base64.encode(der, false); logMap.put(ITimeStampLogger.LOG_TSA_TIMESTAMPRESPONSE_ENCODED, new String(signedbytes)); final Collection<? extends Archivable> archivables = Arrays.asList( new DefaultArchivable(Archivable.TYPE_REQUEST, REQUEST_CONTENT_TYPE, requestbytes, archiveId), new DefaultArchivable(Archivable.TYPE_RESPONSE, RESPONSE_CONTENT_TYPE, signedbytes, archiveId)); if (signRequest instanceof GenericServletRequest) { signResponse = new GenericServletResponse(sReq.getRequestID(), signedbytes, getSigningCertificate(signRequest, requestContext), archiveId, archivables, RESPONSE_CONTENT_TYPE); } else { signResponse = new GenericSignResponse(sReq.getRequestID(), signedbytes, getSigningCertificate(signRequest, requestContext), archiveId, archivables); } // The client can be charged for the request requestContext.setRequestFulfilledByWorker(true); return signResponse; } catch (IOException e) { final IllegalRequestException exception = new IllegalRequestException("IOException: " + e.getMessage(), e); LOG.error("IOException: ", e); logMap.put(ITimeStampLogger.LOG_TSA_EXCEPTION, exception.getMessage()); throw exception; } catch (CMSException e) { final SignServerException exception = new SignServerException(e.getMessage(), e); LOG.error("CMSException: ", e); logMap.put(ITimeStampLogger.LOG_TSA_EXCEPTION, exception.getMessage()); throw exception; } catch (OperatorCreationException e) { final SignServerException exception = new SignServerException(e.getMessage(), e); LOG.error("OperatorCreationException: ", e); logMap.put(ITimeStampLogger.LOG_TSA_EXCEPTION, exception.getMessage()); throw exception; } catch (CertificateEncodingException e) { final SignServerException exception = new SignServerException(e.getMessage(), e); LOG.error("CertificateEncodingException: ", e); logMap.put(ITimeStampLogger.LOG_TSA_EXCEPTION, exception.getMessage()); throw exception; } catch (ArrayIndexOutOfBoundsException e) { // the BC base64 decoder doesn't check the the base64 input length... final IllegalRequestException exception = new IllegalRequestException( "ArrayIndexOutOfBoundsException: " + e.getMessage(), e); LOG.error("ArrayIndexOutOfBoundsException: ", e); logMap.put(ITimeStampLogger.LOG_TSA_EXCEPTION, exception.getMessage()); throw exception; } }
From source file:org.xipki.commons.security.shell.p12.P12ComplexCertRequestGenCmd.java
License:Open Source License
@Override protected List<Extension> getAdditionalExtensions() throws BadInputException { List<Extension> extensions = new LinkedList<>(); // extension admission (Germany standard commonpki) ASN1EncodableVector vec = new ASN1EncodableVector(); DirectoryString[] dummyItems = new DirectoryString[] { new DirectoryString("dummy") }; ProfessionInfo pi = new ProfessionInfo(null, dummyItems, null, "aaaab", null); Admissions admissions = new Admissions(null, null, new ProfessionInfo[] { pi }); vec.add(admissions);/*w w w. j a v a2 s . c o m*/ AdmissionSyntax adSyn = new AdmissionSyntax(null, new DERSequence(vec)); try { extensions.add(new Extension(ObjectIdentifiers.id_extension_admission, false, adSyn.getEncoded())); } catch (IOException ex) { throw new BadInputException(ex.getMessage(), ex); } // extension subjectDirectoryAttributes (RFC 3739) Vector<Attribute> attrs = new Vector<>(); ASN1GeneralizedTime dateOfBirth = new ASN1GeneralizedTime("19800122120000Z"); attrs.add(new Attribute(ObjectIdentifiers.DN_DATE_OF_BIRTH, new DERSet(dateOfBirth))); DERPrintableString gender = new DERPrintableString("M"); attrs.add(new Attribute(ObjectIdentifiers.DN_GENDER, new DERSet(gender))); DERUTF8String placeOfBirth = new DERUTF8String("Berlin"); attrs.add(new Attribute(ObjectIdentifiers.DN_PLACE_OF_BIRTH, new DERSet(placeOfBirth))); String[] countryOfCitizenshipList = new String[] { "DE", "FR" }; for (String country : countryOfCitizenshipList) { DERPrintableString val = new DERPrintableString(country); attrs.add(new Attribute(ObjectIdentifiers.DN_COUNTRY_OF_CITIZENSHIP, new DERSet(val))); } String[] countryOfResidenceList = new String[] { "DE" }; for (String country : countryOfResidenceList) { DERPrintableString val = new DERPrintableString(country); attrs.add(new Attribute(ObjectIdentifiers.DN_COUNTRY_OF_RESIDENCE, new DERSet(val))); } SubjectDirectoryAttributes subjectDirAttrs = new SubjectDirectoryAttributes(attrs); try { extensions .add(new Extension(Extension.subjectDirectoryAttributes, false, subjectDirAttrs.getEncoded())); } catch (IOException ex) { throw new BadInputException(ex.getMessage(), ex); } return extensions; }
From source file:org.xipki.pki.ca.certprofile.XmlX509Certprofile.java
License:Open Source License
@Override public ExtensionValues getExtensions(final Map<ASN1ObjectIdentifier, ExtensionControl> extensionOccurences, final X500Name requestedSubject, final X500Name grantedSubject, final Extensions requestedExtensions, final Date notBefore, final Date notAfter) throws CertprofileException, BadCertTemplateException { ExtensionValues values = new ExtensionValues(); if (CollectionUtil.isEmpty(extensionOccurences)) { return values; }// www. j ava 2s . c o m ParamUtil.requireNonNull("requestedSubject", requestedSubject); ParamUtil.requireNonNull("notBefore", notBefore); ParamUtil.requireNonNull("notAfter", notAfter); Set<ASN1ObjectIdentifier> occurences = new HashSet<>(extensionOccurences.keySet()); // AuthorityKeyIdentifier // processed by the CA // SubjectKeyIdentifier // processed by the CA // KeyUsage // processed by the CA // CertificatePolicies ASN1ObjectIdentifier type = Extension.certificatePolicies; if (certificatePolicies != null) { if (occurences.remove(type)) { values.addExtension(type, certificatePolicies); } } // Policy Mappings type = Extension.policyMappings; if (policyMappings != null) { if (occurences.remove(type)) { values.addExtension(type, policyMappings); } } // SubjectAltName type = Extension.subjectAlternativeName; if (occurences.contains(type)) { GeneralNames genNames = createRequestedSubjectAltNames(requestedSubject, grantedSubject, requestedExtensions); if (genNames != null) { ExtensionValue value = new ExtensionValue(extensionControls.get(type).isCritical(), genNames); values.addExtension(type, value); occurences.remove(type); } } // IssuerAltName // processed by the CA // Subject Directory Attributes type = Extension.subjectDirectoryAttributes; if (occurences.contains(type) && subjectDirAttrsControl != null) { Extension extension = (requestedExtensions == null) ? null : requestedExtensions.getExtension(type); if (extension == null) { throw new BadCertTemplateException( "no SubjectDirecotryAttributes extension is contained in the request"); } ASN1GeneralizedTime dateOfBirth = null; String placeOfBirth = null; String gender = null; List<String> countryOfCitizenshipList = new LinkedList<>(); List<String> countryOfResidenceList = new LinkedList<>(); Map<ASN1ObjectIdentifier, List<ASN1Encodable>> otherAttrs = new HashMap<>(); Vector<?> reqSubDirAttrs = SubjectDirectoryAttributes.getInstance(extension.getParsedValue()) .getAttributes(); final int n = reqSubDirAttrs.size(); for (int i = 0; i < n; i++) { Attribute attr = (Attribute) reqSubDirAttrs.get(i); ASN1ObjectIdentifier attrType = attr.getAttrType(); ASN1Encodable attrVal = attr.getAttributeValues()[0]; if (ObjectIdentifiers.DN_DATE_OF_BIRTH.equals(attrType)) { dateOfBirth = ASN1GeneralizedTime.getInstance(attrVal); } else if (ObjectIdentifiers.DN_PLACE_OF_BIRTH.equals(attrType)) { placeOfBirth = DirectoryString.getInstance(attrVal).getString(); } else if (ObjectIdentifiers.DN_GENDER.equals(attrType)) { gender = DERPrintableString.getInstance(attrVal).getString(); } else if (ObjectIdentifiers.DN_COUNTRY_OF_CITIZENSHIP.equals(attrType)) { String country = DERPrintableString.getInstance(attrVal).getString(); countryOfCitizenshipList.add(country); } else if (ObjectIdentifiers.DN_COUNTRY_OF_RESIDENCE.equals(attrType)) { String country = DERPrintableString.getInstance(attrVal).getString(); countryOfResidenceList.add(country); } else { List<ASN1Encodable> otherAttrVals = otherAttrs.get(attrType); if (otherAttrVals == null) { otherAttrVals = new LinkedList<>(); otherAttrs.put(attrType, otherAttrVals); } otherAttrVals.add(attrVal); } } Vector<Attribute> attrs = new Vector<>(); for (ASN1ObjectIdentifier attrType : subjectDirAttrsControl.getTypes()) { if (ObjectIdentifiers.DN_DATE_OF_BIRTH.equals(attrType)) { if (dateOfBirth != null) { String timeStirng = dateOfBirth.getTimeString(); if (!SubjectDnSpec.PATTERN_DATE_OF_BIRTH.matcher(timeStirng).matches()) { throw new BadCertTemplateException("invalid dateOfBirth " + timeStirng); } attrs.add(new Attribute(attrType, new DERSet(dateOfBirth))); continue; } } else if (ObjectIdentifiers.DN_PLACE_OF_BIRTH.equals(attrType)) { if (placeOfBirth != null) { ASN1Encodable attrVal = new DERUTF8String(placeOfBirth); attrs.add(new Attribute(attrType, new DERSet(attrVal))); continue; } } else if (ObjectIdentifiers.DN_GENDER.equals(attrType)) { if (gender != null && !gender.isEmpty()) { char ch = gender.charAt(0); if (!(gender.length() == 1 && (ch == 'f' || ch == 'F' || ch == 'm' || ch == 'M'))) { throw new BadCertTemplateException("invalid gender " + gender); } ASN1Encodable attrVal = new DERPrintableString(gender); attrs.add(new Attribute(attrType, new DERSet(attrVal))); continue; } } else if (ObjectIdentifiers.DN_COUNTRY_OF_CITIZENSHIP.equals(attrType)) { if (!countryOfCitizenshipList.isEmpty()) { for (String country : countryOfCitizenshipList) { if (!SubjectDnSpec.isValidCountryAreaCode(country)) { throw new BadCertTemplateException("invalid countryOfCitizenship code " + country); } ASN1Encodable attrVal = new DERPrintableString(country); attrs.add(new Attribute(attrType, new DERSet(attrVal))); } continue; } } else if (ObjectIdentifiers.DN_COUNTRY_OF_RESIDENCE.equals(attrType)) { if (!countryOfResidenceList.isEmpty()) { for (String country : countryOfResidenceList) { if (!SubjectDnSpec.isValidCountryAreaCode(country)) { throw new BadCertTemplateException("invalid countryOfResidence code " + country); } ASN1Encodable attrVal = new DERPrintableString(country); attrs.add(new Attribute(attrType, new DERSet(attrVal))); } continue; } } else if (otherAttrs.containsKey(attrType)) { for (ASN1Encodable attrVal : otherAttrs.get(attrType)) { attrs.add(new Attribute(attrType, new DERSet(attrVal))); } continue; } throw new BadCertTemplateException( "could not process type " + attrType.getId() + " in extension SubjectDirectoryAttributes"); } SubjectDirectoryAttributes subjDirAttrs = new SubjectDirectoryAttributes(attrs); ExtensionValue extValue = new ExtensionValue(extensionControls.get(type).isCritical(), subjDirAttrs); values.addExtension(type, extValue); occurences.remove(type); } // Basic Constraints // processed by the CA // Name Constraints type = Extension.nameConstraints; if (nameConstraints != null) { if (occurences.remove(type)) { values.addExtension(type, nameConstraints); } } // PolicyConstrains type = Extension.policyConstraints; if (policyConstraints != null) { if (occurences.remove(type)) { values.addExtension(type, policyConstraints); } } // ExtendedKeyUsage // processed by CA // CRL Distribution Points // processed by the CA // Inhibit anyPolicy type = Extension.inhibitAnyPolicy; if (inhibitAnyPolicy != null) { if (occurences.remove(type)) { values.addExtension(type, inhibitAnyPolicy); } } // Freshest CRL // processed by the CA // Authority Information Access // processed by the CA // Subject Information Access // processed by the CA // Admission type = ObjectIdentifiers.id_extension_admission; if (occurences.contains(type) && admission != null) { if (admission.isInputFromRequestRequired()) { Extension extension = (requestedExtensions == null) ? null : requestedExtensions.getExtension(type); if (extension == null) { throw new BadCertTemplateException("No Admission extension is contained in the request"); } Admissions[] reqAdmissions = org.bouncycastle.asn1.isismtt.x509.AdmissionSyntax .getInstance(extension.getParsedValue()).getContentsOfAdmissions(); final int n = reqAdmissions.length; List<List<String>> reqRegNumsList = new ArrayList<>(n); for (int i = 0; i < n; i++) { Admissions reqAdmission = reqAdmissions[i]; ProfessionInfo[] reqPis = reqAdmission.getProfessionInfos(); List<String> reqNums = new ArrayList<>(reqPis.length); reqRegNumsList.add(reqNums); for (ProfessionInfo reqPi : reqPis) { String reqNum = reqPi.getRegistrationNumber(); reqNums.add(reqNum); } } values.addExtension(type, admission.getExtensionValue(reqRegNumsList)); occurences.remove(type); } else { values.addExtension(type, admission.getExtensionValue(null)); occurences.remove(type); } } // OCSP Nocheck // processed by the CA // restriction type = ObjectIdentifiers.id_extension_restriction; if (restriction != null) { if (occurences.remove(type)) { values.addExtension(type, restriction); } } // AdditionalInformation type = ObjectIdentifiers.id_extension_additionalInformation; if (additionalInformation != null) { if (occurences.remove(type)) { values.addExtension(type, additionalInformation); } } // ValidityModel type = ObjectIdentifiers.id_extension_validityModel; if (validityModel != null) { if (occurences.remove(type)) { values.addExtension(type, validityModel); } } // PrivateKeyUsagePeriod type = Extension.privateKeyUsagePeriod; if (occurences.contains(type)) { Date tmpNotAfter; if (privateKeyUsagePeriod == null) { tmpNotAfter = notAfter; } else { tmpNotAfter = privateKeyUsagePeriod.add(notBefore); if (tmpNotAfter.after(notAfter)) { tmpNotAfter = notAfter; } } ASN1EncodableVector vec = new ASN1EncodableVector(); vec.add(new DERTaggedObject(false, 0, new DERGeneralizedTime(notBefore))); vec.add(new DERTaggedObject(false, 1, new DERGeneralizedTime(tmpNotAfter))); ExtensionValue extValue = new ExtensionValue(extensionControls.get(type).isCritical(), new DERSequence(vec)); values.addExtension(type, extValue); occurences.remove(type); } // QCStatements type = Extension.qCStatements; if (occurences.contains(type) && (qcStatments != null || qcStatementsOption != null)) { if (qcStatments != null) { values.addExtension(type, qcStatments); occurences.remove(type); } else if (requestedExtensions != null && qcStatementsOption != null) { // extract the euLimit data from request Extension extension = requestedExtensions.getExtension(type); if (extension == null) { throw new BadCertTemplateException("No QCStatement extension is contained in the request"); } ASN1Sequence seq = ASN1Sequence.getInstance(extension.getParsedValue()); Map<String, int[]> qcEuLimits = new HashMap<>(); final int n = seq.size(); for (int i = 0; i < n; i++) { QCStatement stmt = QCStatement.getInstance(seq.getObjectAt(i)); if (!ObjectIdentifiers.id_etsi_qcs_QcLimitValue.equals(stmt.getStatementId())) { continue; } MonetaryValue monetaryValue = MonetaryValue.getInstance(stmt.getStatementInfo()); int amount = monetaryValue.getAmount().intValue(); int exponent = monetaryValue.getExponent().intValue(); Iso4217CurrencyCode currency = monetaryValue.getCurrency(); String currencyS = currency.isAlphabetic() ? currency.getAlphabetic().toUpperCase() : Integer.toString(currency.getNumeric()); qcEuLimits.put(currencyS, new int[] { amount, exponent }); } ASN1EncodableVector vec = new ASN1EncodableVector(); for (QcStatementOption m : qcStatementsOption) { if (m.getStatement() != null) { vec.add(m.getStatement()); continue; } MonetaryValueOption monetaryOption = m.getMonetaryValueOption(); String currencyS = monetaryOption.getCurrencyString(); int[] limit = qcEuLimits.get(currencyS); if (limit == null) { throw new BadCertTemplateException( "no EuLimitValue is specified for currency '" + currencyS + "'"); } int amount = limit[0]; Range2Type range = monetaryOption.getAmountRange(); if (amount < range.getMin() || amount > range.getMax()) { throw new BadCertTemplateException("amount for currency '" + currencyS + "' is not within [" + range.getMin() + ", " + range.getMax() + "]"); } int exponent = limit[1]; range = monetaryOption.getExponentRange(); if (exponent < range.getMin() || exponent > range.getMax()) { throw new BadCertTemplateException("exponent for currency '" + currencyS + "' is not within [" + range.getMin() + ", " + range.getMax() + "]"); } MonetaryValue monetaryVale = new MonetaryValue(monetaryOption.getCurrency(), amount, exponent); QCStatement qcStatment = new QCStatement(m.getStatementId(), monetaryVale); vec.add(qcStatment); } ExtensionValue extValue = new ExtensionValue(extensionControls.get(type).isCritical(), new DERSequence(vec)); values.addExtension(type, extValue); occurences.remove(type); } else { throw new RuntimeException("should not reach here"); } } // BiometricData type = Extension.biometricInfo; if (occurences.contains(type) && biometricInfo != null) { Extension extension = (requestedExtensions == null) ? null : requestedExtensions.getExtension(type); if (extension == null) { throw new BadCertTemplateException("no biometricInfo extension is contained in the request"); } ASN1Sequence seq = ASN1Sequence.getInstance(extension.getParsedValue()); final int n = seq.size(); if (n < 1) { throw new BadCertTemplateException("biometricInfo extension in request contains empty sequence"); } ASN1EncodableVector vec = new ASN1EncodableVector(); for (int i = 0; i < n; i++) { BiometricData bd = BiometricData.getInstance(seq.getObjectAt(i)); TypeOfBiometricData bdType = bd.getTypeOfBiometricData(); if (!biometricInfo.isTypePermitted(bdType)) { throw new BadCertTemplateException( "biometricInfo[" + i + "].typeOfBiometricData is not permitted"); } ASN1ObjectIdentifier hashAlgo = bd.getHashAlgorithm().getAlgorithm(); if (!biometricInfo.isHashAlgorithmPermitted(hashAlgo)) { throw new BadCertTemplateException("biometricInfo[" + i + "].hashAlgorithm is not permitted"); } int expHashValueSize; try { expHashValueSize = AlgorithmUtil.getHashOutputSizeInOctets(hashAlgo); } catch (NoSuchAlgorithmException ex) { throw new CertprofileException("should not happen, unknown hash algorithm " + hashAlgo); } byte[] hashValue = bd.getBiometricDataHash().getOctets(); if (hashValue.length != expHashValueSize) { throw new BadCertTemplateException( "biometricInfo[" + i + "].biometricDataHash has incorrect length"); } DERIA5String sourceDataUri = bd.getSourceDataUri(); switch (biometricInfo.getSourceDataUriOccurrence()) { case FORBIDDEN: sourceDataUri = null; break; case REQUIRED: if (sourceDataUri == null) { throw new BadCertTemplateException("biometricInfo[" + i + "].sourceDataUri is not specified in request but is required"); } break; case OPTIONAL: break; default: throw new BadCertTemplateException("could not reach here, unknown tripleState"); } AlgorithmIdentifier newHashAlg = new AlgorithmIdentifier(hashAlgo, DERNull.INSTANCE); BiometricData newBiometricData = new BiometricData(bdType, newHashAlg, new DEROctetString(hashValue), sourceDataUri); vec.add(newBiometricData); } ExtensionValue extValue = new ExtensionValue(extensionControls.get(type).isCritical(), new DERSequence(vec)); values.addExtension(type, extValue); occurences.remove(type); } // TlsFeature type = ObjectIdentifiers.id_pe_tlsfeature; if (tlsFeature != null) { if (occurences.remove(type)) { values.addExtension(type, tlsFeature); } } // AuthorizationTemplate type = ObjectIdentifiers.id_xipki_ext_authorizationTemplate; if (authorizationTemplate != null) { if (occurences.remove(type)) { values.addExtension(type, authorizationTemplate); } } // SMIME type = ObjectIdentifiers.id_smimeCapabilities; if (smimeCapabilities != null) { if (occurences.remove(type)) { values.addExtension(type, smimeCapabilities); } } // constant extensions if (constantExtensions != null) { for (ASN1ObjectIdentifier m : constantExtensions.keySet()) { if (!occurences.remove(m)) { continue; } ExtensionValue extensionValue = constantExtensions.get(m); if (extensionValue != null) { values.addExtension(m, extensionValue); } } } return values; }