List of usage examples for org.bouncycastle.asn1 ASN1EncodableVector ASN1EncodableVector
public ASN1EncodableVector()
From source file:org.cesecore.certificates.certificate.certextensions.standard.SubjectDirectoryAttributes.java
License:Open Source License
@Override public ASN1Encodable getValue(final EndEntityInformation subject, final CA ca, final CertificateProfile certProfile, final PublicKey userPublicKey, final PublicKey caPublicKey, CertificateValidity val) { ASN1Encodable ret = null;//from w w w . j a v a2s. c o m final String dirAttrString = subject.getExtendedinformation() != null ? subject.getExtendedinformation().getSubjectDirectoryAttributes() : null; if (StringUtils.isNotEmpty(dirAttrString)) { // Subject Directory Attributes is a sequence of Attribute final Collection<Attribute> attr = SubjectDirAttrExtension.getSubjectDirectoryAttributes(dirAttrString); final ASN1EncodableVector vec = new ASN1EncodableVector(); final Iterator<Attribute> iter = attr.iterator(); while (iter.hasNext()) { vec.add(iter.next()); } if (vec.size() > 0) { ret = new DERSequence(vec); } } if (ret == null) { if (log.isDebugEnabled()) { log.debug("No directory attributes trying to create SubjectDirectoryAttributes extension: " + dirAttrString); } } return ret; }
From source file:org.cesecore.certificates.certificate.request.RequestMessageTest.java
License:Open Source License
private PKCS10CertificationRequest createP10(final String subjectDN) throws IOException, OperatorCreationException { // Create a P10 with extensions, in this case altNames with a DNS name ASN1EncodableVector altnameattr = new ASN1EncodableVector(); altnameattr.add(PKCSObjectIdentifiers.pkcs_9_at_extensionRequest); // AltNames/*from w w w.j a va 2 s .co m*/ // String[] namearray = altnames.split(","); GeneralNames san = CertTools.getGeneralNamesFromAltName("dNSName=foo1.bar.com"); ExtensionsGenerator extgen = new ExtensionsGenerator(); extgen.addExtension(Extension.subjectAlternativeName, false, san); Extensions exts = extgen.generate(); altnameattr.add(new DERSet(exts)); // Add a challenge password as well ASN1EncodableVector pwdattr = new ASN1EncodableVector(); pwdattr.add(PKCSObjectIdentifiers.pkcs_9_at_challengePassword); ASN1EncodableVector pwdvalues = new ASN1EncodableVector(); pwdvalues.add(new DERUTF8String("foo123")); pwdattr.add(new DERSet(pwdvalues)); // Complete the Attribute section of the request, the set (Attributes) // contains one sequence (Attribute) ASN1EncodableVector v = new ASN1EncodableVector(); v.add(new DERSequence(altnameattr)); v.add(new DERSequence(pwdattr)); DERSet attributes = new DERSet(v); // Create the PKCS10 X500Name dn = new X500Name(subjectDN); PKCS10CertificationRequest basicpkcs10 = CertTools.genPKCS10CertificationRequest("SHA1WithRSA", dn, keyPair.getPublic(), attributes, keyPair.getPrivate(), null); return basicpkcs10; }
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) *///from w w w .j ava 2 s .c o m 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.cesecore.util.CertTools.java
License:Open Source License
public static X509Certificate genSelfCertForPurpose(String dn, long validity, String policyId, PrivateKey privKey, PublicKey pubKey, String sigAlg, boolean isCA, int keyusage, Date privateKeyNotBefore, Date privateKeyNotAfter, String provider, boolean ldapOrder, List<Extension> additionalExtensions) throws CertificateParsingException, IOException, OperatorCreationException { // Create self signed certificate Date firstDate = new Date(); // Set back startdate ten minutes to avoid some problems with wrongly set clocks. firstDate.setTime(firstDate.getTime() - (10 * 60 * 1000)); Date lastDate = new Date(); // validity in days = validity*24*60*60*1000 milliseconds lastDate.setTime(lastDate.getTime() + (validity * (24 * 60 * 60 * 1000))); // Transform the PublicKey to be sure we have it in a format that the X509 certificate generator handles, it might be // a CVC public key that is passed as parameter PublicKey publicKey = null;//from w ww . j a va2 s.c o m if (pubKey instanceof RSAPublicKey) { RSAPublicKey rsapk = (RSAPublicKey) pubKey; RSAPublicKeySpec rSAPublicKeySpec = new RSAPublicKeySpec(rsapk.getModulus(), rsapk.getPublicExponent()); try { publicKey = KeyFactory.getInstance("RSA").generatePublic(rSAPublicKeySpec); } catch (InvalidKeySpecException e) { log.error("Error creating RSAPublicKey from spec: ", e); publicKey = pubKey; } catch (NoSuchAlgorithmException e) { throw new IllegalStateException("RSA was not a known algorithm", e); } } else if (pubKey instanceof ECPublicKey) { ECPublicKey ecpk = (ECPublicKey) pubKey; try { ECPublicKeySpec ecspec = new ECPublicKeySpec(ecpk.getW(), ecpk.getParams()); // will throw NPE if key is "implicitlyCA" final String algo = ecpk.getAlgorithm(); if (algo.equals(AlgorithmConstants.KEYALGORITHM_ECGOST3410)) { try { publicKey = KeyFactory.getInstance("ECGOST3410").generatePublic(ecspec); } catch (NoSuchAlgorithmException e) { throw new IllegalStateException("ECGOST3410 was not a known algorithm", e); } } else if (algo.equals(AlgorithmConstants.KEYALGORITHM_DSTU4145)) { try { publicKey = KeyFactory.getInstance("DSTU4145").generatePublic(ecspec); } catch (NoSuchAlgorithmException e) { throw new IllegalStateException("DSTU4145 was not a known algorithm", e); } } else { try { publicKey = KeyFactory.getInstance("EC").generatePublic(ecspec); } catch (NoSuchAlgorithmException e) { throw new IllegalStateException("EC was not a known algorithm", e); } } } catch (InvalidKeySpecException e) { log.error("Error creating ECPublicKey from spec: ", e); publicKey = pubKey; } catch (NullPointerException e) { log.debug("NullPointerException, probably it is implicitlyCA generated keys: " + e.getMessage()); publicKey = pubKey; } } else { log.debug("Not converting key of class. " + pubKey.getClass().getName()); publicKey = pubKey; } // Serialnumber is random bits, where random generator is initialized with Date.getTime() when this // bean is created. byte[] serno = new byte[8]; SecureRandom random; try { random = SecureRandom.getInstance("SHA1PRNG"); } catch (NoSuchAlgorithmException e) { throw new IllegalStateException("SHA1PRNG was not a known algorithm", e); } random.setSeed(new Date().getTime()); random.nextBytes(serno); SubjectPublicKeyInfo pkinfo; try { pkinfo = new SubjectPublicKeyInfo((ASN1Sequence) ASN1Primitive.fromByteArray(publicKey.getEncoded())); } catch (IOException e) { throw new IllegalArgumentException("Provided public key could not be read to ASN1Primitive", e); } X509v3CertificateBuilder certbuilder = new X509v3CertificateBuilder( CertTools.stringToBcX500Name(dn, ldapOrder), new BigInteger(serno).abs(), firstDate, lastDate, CertTools.stringToBcX500Name(dn, ldapOrder), pkinfo); // Basic constranits is always critical and MUST be present at-least in CA-certificates. BasicConstraints bc = new BasicConstraints(isCA); certbuilder.addExtension(Extension.basicConstraints, true, bc); // Put critical KeyUsage in CA-certificates if (isCA || keyusage != 0) { X509KeyUsage ku = new X509KeyUsage(keyusage); certbuilder.addExtension(Extension.keyUsage, true, ku); } if ((privateKeyNotBefore != null) || (privateKeyNotAfter != null)) { final ASN1EncodableVector v = new ASN1EncodableVector(); if (privateKeyNotBefore != null) { v.add(new DERTaggedObject(false, 0, new DERGeneralizedTime(privateKeyNotBefore))); } if (privateKeyNotAfter != null) { v.add(new DERTaggedObject(false, 1, new DERGeneralizedTime(privateKeyNotAfter))); } certbuilder.addExtension(Extension.privateKeyUsagePeriod, false, new DERSequence(v)); } // Subject and Authority key identifier is always non-critical and MUST be present for certificates to verify in Firefox. try { if (isCA) { ASN1InputStream sAsn1InputStream = new ASN1InputStream( new ByteArrayInputStream(publicKey.getEncoded())); ASN1InputStream aAsn1InputStream = new ASN1InputStream( new ByteArrayInputStream(publicKey.getEncoded())); try { SubjectPublicKeyInfo spki = new SubjectPublicKeyInfo( (ASN1Sequence) sAsn1InputStream.readObject()); X509ExtensionUtils x509ExtensionUtils = new BcX509ExtensionUtils(); SubjectKeyIdentifier ski = x509ExtensionUtils.createSubjectKeyIdentifier(spki); SubjectPublicKeyInfo apki = new SubjectPublicKeyInfo( (ASN1Sequence) aAsn1InputStream.readObject()); AuthorityKeyIdentifier aki = new AuthorityKeyIdentifier(apki); certbuilder.addExtension(Extension.subjectKeyIdentifier, false, ski); certbuilder.addExtension(Extension.authorityKeyIdentifier, false, aki); } finally { sAsn1InputStream.close(); aAsn1InputStream.close(); } } } catch (IOException e) { // do nothing } // CertificatePolicies extension if supplied policy ID, always non-critical if (policyId != null) { PolicyInformation pi = new PolicyInformation(new ASN1ObjectIdentifier(policyId)); DERSequence seq = new DERSequence(pi); certbuilder.addExtension(Extension.certificatePolicies, false, seq); } // Add any additional if (additionalExtensions != null) { for (final Extension extension : additionalExtensions) { certbuilder.addExtension(extension.getExtnId(), extension.isCritical(), extension.getParsedValue()); } } final ContentSigner signer = new BufferingContentSigner( new JcaContentSignerBuilder(sigAlg).setProvider(provider).build(privKey), 20480); final X509CertificateHolder certHolder = certbuilder.build(signer); final X509Certificate selfcert = (X509Certificate) CertTools.getCertfromByteArray(certHolder.getEncoded()); return selfcert; }
From source file:org.cesecore.util.CertTools.java
License:Open Source License
/** * From an altName string as defined in getSubjectAlternativeName * /*from www . j a v a 2 s . c o m*/ * @param altName * @return ASN.1 GeneralNames * @see #getSubjectAlternativeName */ public static GeneralNames getGeneralNamesFromAltName(final String altName) { if (log.isTraceEnabled()) { log.trace(">getGeneralNamesFromAltName: " + altName); } final ASN1EncodableVector vec = new ASN1EncodableVector(); for (final String email : CertTools.getEmailFromDN(altName)) { vec.add(new GeneralName(1, /*new DERIA5String(iter.next())*/email)); } for (final String dns : CertTools.getPartsFromDN(altName, CertTools.DNS)) { vec.add(new GeneralName(2, new DERIA5String(dns))); } final String directoryName = getDirectoryStringFromAltName(altName); if (directoryName != null) { //final X500Name x500DirectoryName = new X500Name(directoryName); final X500Name x500DirectoryName = new X500Name(LDAPDN.unescapeRDN(directoryName)); final GeneralName gn = new GeneralName(4, x500DirectoryName); vec.add(gn); } for (final String uri : CertTools.getPartsFromDN(altName, CertTools.URI)) { vec.add(new GeneralName(6, new DERIA5String(uri))); } for (final String uri : CertTools.getPartsFromDN(altName, CertTools.URI1)) { vec.add(new GeneralName(6, new DERIA5String(uri))); } for (final String uri : CertTools.getPartsFromDN(altName, CertTools.URI2)) { vec.add(new GeneralName(6, new DERIA5String(uri))); } for (final String addr : CertTools.getPartsFromDN(altName, CertTools.IPADDR)) { final byte[] ipoctets = StringTools.ipStringToOctets(addr); if (ipoctets.length > 0) { final GeneralName gn = new GeneralName(7, new DEROctetString(ipoctets)); vec.add(gn); } else { log.error("Cannot parse/encode ip address, ignoring: " + addr); } } // UPN is an OtherName see method getUpn... for asn.1 definition for (final String upn : CertTools.getPartsFromDN(altName, CertTools.UPN)) { final ASN1EncodableVector v = new ASN1EncodableVector(); v.add(new ASN1ObjectIdentifier(CertTools.UPN_OBJECTID)); v.add(new DERTaggedObject(true, 0, new DERUTF8String(upn))); vec.add(GeneralName.getInstance(new DERTaggedObject(false, 0, new DERSequence(v)))); } // PermanentIdentifier is an OtherName see method getPermananentIdentifier... for asn.1 definition for (final String permanentIdentifier : CertTools.getPartsFromDN(altName, CertTools.PERMANENTIDENTIFIER)) { final String[] values = getPermanentIdentifierValues(permanentIdentifier); final ASN1EncodableVector v = new ASN1EncodableVector(); // this is the OtherName v.add(new ASN1ObjectIdentifier(CertTools.PERMANENTIDENTIFIER_OBJECTID)); // First the PermanentIdentifier sequence final ASN1EncodableVector piSeq = new ASN1EncodableVector(); if (values[0] != null) { piSeq.add(new DERUTF8String(values[0])); } if (values[1] != null) { piSeq.add(new ASN1ObjectIdentifier(values[1])); } v.add(new DERTaggedObject(true, 0, new DERSequence(piSeq))); // GeneralName gn = new GeneralName(new DERSequence(v), 0); final ASN1Primitive gn = new DERTaggedObject(false, 0, new DERSequence(v)); vec.add(gn); } for (final String guid : CertTools.getPartsFromDN(altName, CertTools.GUID)) { final ASN1EncodableVector v = new ASN1EncodableVector(); byte[] guidbytes = Hex.decode(guid); if (guidbytes != null) { v.add(new ASN1ObjectIdentifier(CertTools.GUID_OBJECTID)); v.add(new DERTaggedObject(true, 0, new DEROctetString(guidbytes))); final ASN1Primitive gn = new DERTaggedObject(false, 0, new DERSequence(v)); vec.add(gn); } else { log.error("Cannot decode hexadecimal guid, ignoring: " + guid); } } // Krb5PrincipalName is an OtherName, see method getKrb5Principal...for ASN.1 definition for (final String principalString : CertTools.getPartsFromDN(altName, CertTools.KRB5PRINCIPAL)) { // Start by parsing the input string to separate it in different parts if (log.isDebugEnabled()) { log.debug("principalString: " + principalString); } // The realm is the last part moving back until an @ final int index = principalString.lastIndexOf('@'); String realm = ""; if (index > 0) { realm = principalString.substring(index + 1); } if (log.isDebugEnabled()) { log.debug("realm: " + realm); } // Now we can have several principals separated by / final ArrayList<String> principalarr = new ArrayList<String>(); int jndex = 0; int bindex = 0; while (jndex < index) { // Loop and add all strings separated by / jndex = principalString.indexOf('/', bindex); if (jndex == -1) { jndex = index; } String s = principalString.substring(bindex, jndex); if (log.isDebugEnabled()) { log.debug("adding principal name: " + s); } principalarr.add(s); bindex = jndex + 1; } // Now we must construct the rather complex asn.1... final ASN1EncodableVector v = new ASN1EncodableVector(); // this is the OtherName v.add(new ASN1ObjectIdentifier(CertTools.KRB5PRINCIPAL_OBJECTID)); // First the Krb5PrincipalName sequence final ASN1EncodableVector krb5p = new ASN1EncodableVector(); // The realm is the first tagged GeneralString krb5p.add(new DERTaggedObject(true, 0, new DERGeneralString(realm))); // Second is the sequence of principal names, which is at tagged position 1 in the krb5p final ASN1EncodableVector principals = new ASN1EncodableVector(); // According to rfc4210 the type NT-UNKNOWN is 0, and according to some other rfc this type should be used... principals.add(new DERTaggedObject(true, 0, new ASN1Integer(0))); // The names themselves are yet another sequence final Iterator<String> i = principalarr.iterator(); final ASN1EncodableVector names = new ASN1EncodableVector(); while (i.hasNext()) { String principalName = (String) i.next(); names.add(new DERGeneralString(principalName)); } principals.add(new DERTaggedObject(true, 1, new DERSequence(names))); krb5p.add(new DERTaggedObject(true, 1, new DERSequence(principals))); v.add(new DERTaggedObject(true, 0, new DERSequence(krb5p))); final ASN1Primitive gn = new DERTaggedObject(false, 0, new DERSequence(v)); vec.add(gn); } // To support custom OIDs in altNames, they must be added as an OtherName of plain type UTF8String for (final String oid : CertTools.getCustomOids(altName)) { for (final String oidValue : CertTools.getPartsFromDN(altName, oid)) { final ASN1EncodableVector v = new ASN1EncodableVector(); v.add(new ASN1ObjectIdentifier(oid)); v.add(new DERTaggedObject(true, 0, new DERUTF8String(oidValue))); final ASN1Primitive gn = new DERTaggedObject(false, 0, new DERSequence(v)); vec.add(gn); } } if (vec.size() > 0) { return GeneralNames.getInstance(new DERSequence(vec)); } return null; }
From source file:org.cesecore.util.CertToolsTest.java
License:Open Source License
private DERSequence permanentIdentifier(String identifierValue, String assigner) { DERSequence result;/*from w w w . j a v a2 s . c o m*/ ASN1EncodableVector v = new ASN1EncodableVector(); // this is the OtherName v.add(new ASN1ObjectIdentifier(CertTools.PERMANENTIDENTIFIER_OBJECTID)); // First the PermanentIdentifier sequence ASN1EncodableVector piSeq = new ASN1EncodableVector(); if (identifierValue != null) { piSeq.add(new DERUTF8String(identifierValue)); } if (assigner != null) { piSeq.add(new ASN1ObjectIdentifier(assigner)); } v.add(new DERTaggedObject(true, 0, new DERSequence(piSeq))); result = new DERSequence(v); log.info(ASN1Dump.dumpAsString(result)); return result; }
From source file:org.cryptoworkshop.ximix.client.connection.signing.ECDSASigningService.java
License:Apache License
public MessageReply generateSig(SignatureCreateMessage ecdsaCreate) throws ServiceConnectionException, IOException { Participant[] participants = new Participant[ecdsaCreate.getNodesToUse().size()]; int index = 0; for (String name : ecdsaCreate.getNodesToUse()) { MessageReply seqRep = sendMessage(name, Type.FETCH_SEQUENCE_NO, new KeyIDMessage(ecdsaCreate.getKeyID())); // TODO: need to drop out people who don't reply. participants[index] = new Participant( BigIntegerMessage.getInstance(seqRep.getPayload()).getValue().intValue(), name); index++;//w ww.j av a 2 s . co m } FetchPublicKeyMessage fetchMessage = new FetchPublicKeyMessage(ecdsaCreate.getKeyID()); MessageReply reply = connection.sendMessage(ClientMessage.Type.FETCH_PUBLIC_KEY, fetchMessage); ECDomainParameters domainParams = ((ECPublicKeyParameters) PublicKeyFactory .createKey(SubjectPublicKeyInfo.getInstance(reply.getPayload()))).getParameters(); BigInteger n = domainParams.getN(); BigInteger e = calculateE(n, ecdsaCreate.getMessage()); // TODO: need to take into account node failure during startup. reply = sendMessage(participants[0].getName(), Type.FETCH_SIG_ID, DERNull.INSTANCE); SigID sigID = new SigID(IDMessage.getInstance(reply.getPayload()).getID()); BigInteger r, s; do // generate s { ECDSAInitialiseMessage initialiseMessage = new ECDSAInitialiseMessage(sigID.getID(), ecdsaCreate.getKeyID(), ecdsaCreate.getThreshold(), domainParams.getN(), participants); sendInitialiseMessage(Type.INIT_K_AND_P, initialiseMessage); sendInitialiseMessage(Type.INIT_A, initialiseMessage); sendInitialiseMessage(Type.INIT_B, initialiseMessage); sendInitialiseMessage(Type.INIT_C, initialiseMessage); sendInitialiseMessage(Type.INIT_R, initialiseMessage); sendInitialiseMessage(Type.INIT_MU, initialiseMessage); MessageReply seqRep = sendMessage(participants[0].getName(), Type.FETCH_R, new IDMessage(sigID.getID())); r = BigIntegerMessage.getInstance(seqRep.getPayload()).getValue(); s = accumulateBigInteger(participants, Type.PRIVATE_KEY_SIGN, new ECDSAPartialCreateMessage(sigID.getID(), ecdsaCreate.getKeyID(), e, participants), n); } while (s.equals(BigInteger.ZERO)); ASN1EncodableVector v = new ASN1EncodableVector(); v.add(new ASN1Integer(r)); v.add(new ASN1Integer(s)); return new MessageReply(MessageReply.Type.OKAY, new DERSequence(v)); }
From source file:org.cryptoworkshop.ximix.client.connection.signing.message.BLSPartialCreateMessage.java
License:Apache License
@Override public ASN1Primitive toASN1Primitive() { ASN1EncodableVector v = new ASN1EncodableVector(); v.add(new DERUTF8String(keyID)); v.add(h);/*from w ww. ja v a 2 s . c o m*/ v.add(MessageUtils.toASN1Sequence(nodesToUse)); return new DERSequence(v); }
From source file:org.cryptoworkshop.ximix.client.connection.signing.message.ECDSAFetchMessage.java
License:Apache License
@Override public ASN1Primitive toASN1Primitive() { ASN1EncodableVector v = new ASN1EncodableVector(); v.add(new DERUTF8String(sigID)); v.add(new DERUTF8String(keyID)); v.add(MessageUtils.toASN1Sequence(nodesToUse)); return new DERSequence(v); }
From source file:org.cryptoworkshop.ximix.client.connection.signing.message.ECDSAInitialiseMessage.java
License:Apache License
@Override public ASN1Primitive toASN1Primitive() { ASN1EncodableVector v = new ASN1EncodableVector(); v.add(new DERUTF8String(sigID)); v.add(new DERUTF8String(keyID)); v.add(new ASN1Integer(threshold)); v.add(new ASN1Integer(n)); v.add(MessageUtils.toASN1Sequence(nodesToUse)); return new DERSequence(v); }