List of usage examples for org.bouncycastle.asn1.x509 V3TBSCertificateGenerator setIssuer
public void setIssuer(X500Name issuer)
From source file:ch.bfh.unicert.certimport.CertificateIssuer.java
License:GNU General Public License
public Certificate createClientCertificate(IdentityData id, String keyStorePath, PublicKey pk, int validity, String applicationIdentifier, String[] roles, String uniBoardWsdlURL, String uniBoardServiceURL, String section) throws CertificateCreationException { X509Certificate caCert;/*from w ww . ja v a 2 s .c om*/ RSAPrivateCrtKey privKey; try { caCert = this.readIssuerCertificate(this.issuerId); privKey = this.readPrivateKey(this.issuerId, this.privKeyPass); } catch (KeyStoreException | NoSuchAlgorithmException | UnrecoverableKeyException ex) { logger.log(Level.SEVERE, null, ex); throw new CertificateCreationException("230 Could not create client certificate. Key error"); } RSAPrivateCrtKeyParameters cipherParams = this.createIssuerCipherParams(privKey); X509Certificate clientCert; Hashtable extension = new Hashtable(); extension.put(new DERObjectIdentifier(ExtensionOID.APPLICATION_IDENTIFIER.getOID()), new X509Extension(DERBoolean.FALSE, CertificateHelper.stringToDER(applicationIdentifier))); String completeRole = ""; for (String role : roles) { completeRole += role + ", "; } completeRole = completeRole.substring(0, completeRole.length() - 2); extension.put(new DERObjectIdentifier(ExtensionOID.ROLE.getOID()), new X509Extension(DERBoolean.FALSE, CertificateHelper.stringToDER(completeRole))); extension.put(new DERObjectIdentifier(ExtensionOID.IDENTITY_PROVIDER.getOID()), new X509Extension(DERBoolean.FALSE, CertificateHelper.stringToDER(id.getIdentityProvider()))); Map<String, String> extensionMap = new HashMap(); if (id.getOtherValues() != null) { for (Entry<ExtensionOID, String> entry : id.getOtherValues().entrySet()) { extension.put(new DERObjectIdentifier(entry.getKey().getOID()), new X509Extension(DERBoolean.FALSE, CertificateHelper.stringToDER(entry.getValue()))); extensionMap.put(entry.getKey().getName(), entry.getValue()); } } try { String x509NameString = ""; x509NameString += "CN=" + id.getCommonName(); if (id.getSurname() != null && !id.getSurname().equals("")) { x509NameString += ", SURNAME=" + id.getSurname(); } if (id.getGivenName() != null && !id.getGivenName().equals("")) { x509NameString += ", GIVENNAME=" + id.getGivenName(); } if (id.getUniqueIdentifier() != null && !id.getUniqueIdentifier().equals("")) { x509NameString += ", UID=" + id.getUniqueIdentifier(); } if (id.getOrganisation() != null && !id.getOrganisation().equals("")) { x509NameString += ", O=" + id.getOrganisation(); } if (id.getOrganisationUnit() != null && !id.getOrganisationUnit().equals("")) { x509NameString += ", OU=" + id.getOrganisationUnit(); } if (id.getCountryName() != null && !id.getCountryName().equals("")) { x509NameString += ", C=" + id.getCountryName(); } if (id.getState() != null && !id.getState().equals("")) { x509NameString += ", ST=" + id.getState(); } if (id.getLocality() != null && !id.getLocality().equals("")) { x509NameString += ", L=" + id.getLocality(); } X509Name x509Name = new X509Name(x509NameString); V3TBSCertificateGenerator certGen = new V3TBSCertificateGenerator(); certGen.setSerialNumber(new DERInteger(BigInteger.valueOf(System.currentTimeMillis()))); certGen.setIssuer(PrincipalUtil.getSubjectX509Principal(caCert)); certGen.setSubject(x509Name); certGen.setExtensions(new X509Extensions(extension)); DERObjectIdentifier sigOID = new DERObjectIdentifier("1.2.840.113549.1.1.5"); AlgorithmIdentifier sigAlgId = new AlgorithmIdentifier(sigOID, new DERNull()); certGen.setSignature(sigAlgId); certGen.setSubjectPublicKeyInfo(new SubjectPublicKeyInfo( (ASN1Sequence) new ASN1InputStream(new ByteArrayInputStream(pk.getEncoded())).readObject())); certGen.setStartDate(new Time(new Date(System.currentTimeMillis()))); certGen.setEndDate(new Time(getExpiryDate(validity).getTime())); TBSCertificateStructure tbsCert = certGen.generateTBSCertificate(); //Sign certificate SHA1Digest digester = new SHA1Digest(); AsymmetricBlockCipher rsa = new PKCS1Encoding(new RSAEngine()); ByteArrayOutputStream bOut = new ByteArrayOutputStream(); DEROutputStream dOut = new DEROutputStream(bOut); dOut.writeObject(tbsCert); byte[] signature; byte[] certBlock = bOut.toByteArray(); // first create digest digester.update(certBlock, 0, certBlock.length); byte[] hash = new byte[digester.getDigestSize()]; digester.doFinal(hash, 0); // then sign it rsa.init(true, cipherParams); DigestInfo dInfo = new DigestInfo(new AlgorithmIdentifier(X509ObjectIdentifiers.id_SHA1, null), hash); byte[] digest = dInfo.getEncoded(ASN1Encodable.DER); signature = rsa.processBlock(digest, 0, digest.length); ASN1EncodableVector v = new ASN1EncodableVector(); v.add(tbsCert); v.add(sigAlgId); v.add(new DERBitString(signature)); // Create CRT data structure clientCert = new X509CertificateObject(new X509CertificateStructure(new DERSequence(v))); clientCert.verify(caCert.getPublicKey()); } catch (IOException | InvalidCipherTextException | CertificateException | NoSuchAlgorithmException | InvalidKeyException | NoSuchProviderException | SignatureException e) { logger.log(Level.SEVERE, "Could not create client certificate: {0}", new Object[] { e.getMessage() }); throw new CertificateCreationException("230 Could not create client certificate"); } Certificate cert = new Certificate(clientCert, id.getCommonName(), id.getUniqueIdentifier(), id.getOrganisation(), id.getOrganisationUnit(), id.getCountryName(), id.getState(), id.getLocality(), id.getSurname(), id.getGivenName(), applicationIdentifier, roles, id.getIdentityProvider(), extensionMap); //post message on UniBoard if corresponding JNDI parameter is defined postOnUniBoard(cert, uniBoardWsdlURL, uniBoardServiceURL, section, (RSAPublicKey) caCert.getPublicKey(), privKey); return cert; }
From source file:ch.bfh.unicert.issuer.CertificateIssuerBean.java
License:GNU General Public License
/** * Actually creates the requestor certificate. * * @param id requestor identity data/*w ww . j a v a 2 s . c o m*/ * @param caCert certificate of the certification authority * @param cipherParams issuer private key parameters used for signing * @param pk public key of the requestor to certify * @param expiry the expiry date * @param applicationIdentifier the application identifier for which te certificate is issued * @param role role for which the certificate is issued * @return the certificate object containing the X509 certificate * @throws CertificateCreationException if an error occurs */ private Certificate createClientCertificate(IdentityData id, X509Certificate caCert, CipherParameters cipherParams, PublicKey pk, Calendar expiry, String applicationIdentifier, String[] roles) throws CertificateCreationException { X509Certificate clientCert; Hashtable extension = new Hashtable(); extension.put(new DERObjectIdentifier(ExtensionOID.APPLICATION_IDENTIFIER.getOID()), new X509Extension(DERBoolean.FALSE, CertificateHelper.stringToDER(applicationIdentifier))); String completeRole = ""; for (String role : roles) { completeRole += role + ", "; } completeRole = completeRole.substring(0, completeRole.length() - 2); extension.put(new DERObjectIdentifier(ExtensionOID.ROLE.getOID()), new X509Extension(DERBoolean.FALSE, CertificateHelper.stringToDER(completeRole))); extension.put(new DERObjectIdentifier(ExtensionOID.IDENTITY_PROVIDER.getOID()), new X509Extension(DERBoolean.FALSE, CertificateHelper.stringToDER(id.getIdentityProvider()))); Map<String, String> extensionMap = new HashMap(); if (id.getOtherValues() != null) { for (Entry<ExtensionOID, String> entry : id.getOtherValues().entrySet()) { extension.put(new DERObjectIdentifier(entry.getKey().getOID()), new X509Extension(DERBoolean.FALSE, CertificateHelper.stringToDER(entry.getValue()))); extensionMap.put(entry.getKey().getName(), entry.getValue()); } } try { String x509NameString = ""; x509NameString += "CN=" + id.getCommonName(); if (id.getSurname() != null && !id.getSurname().equals("")) { x509NameString += ", SURNAME=" + id.getSurname(); } if (id.getGivenName() != null && !id.getGivenName().equals("")) { x509NameString += ", GIVENNAME=" + id.getGivenName(); } if (id.getUniqueIdentifier() != null && !id.getUniqueIdentifier().equals("")) { x509NameString += ", UID=" + id.getUniqueIdentifier(); } if (id.getOrganisation() != null && !id.getOrganisation().equals("")) { x509NameString += ", O=" + id.getOrganisation(); } if (id.getOrganisationUnit() != null && !id.getOrganisationUnit().equals("")) { x509NameString += ", OU=" + id.getOrganisationUnit(); } if (id.getCountryName() != null && !id.getCountryName().equals("")) { x509NameString += ", C=" + id.getCountryName(); } if (id.getState() != null && !id.getState().equals("")) { x509NameString += ", ST=" + id.getState(); } if (id.getLocality() != null && !id.getLocality().equals("")) { x509NameString += ", L=" + id.getLocality(); } X509Name x509Name = new X509Name(x509NameString); V3TBSCertificateGenerator certGen = new V3TBSCertificateGenerator(); certGen.setSerialNumber(new DERInteger(BigInteger.valueOf(System.currentTimeMillis()))); certGen.setIssuer(PrincipalUtil.getSubjectX509Principal(caCert)); certGen.setSubject(x509Name); certGen.setExtensions(new X509Extensions(extension)); DERObjectIdentifier sigOID = new DERObjectIdentifier("1.2.840.113549.1.1.5"); AlgorithmIdentifier sigAlgId = new AlgorithmIdentifier(sigOID, new DERNull()); certGen.setSignature(sigAlgId); certGen.setSubjectPublicKeyInfo(new SubjectPublicKeyInfo( (ASN1Sequence) new ASN1InputStream(new ByteArrayInputStream(pk.getEncoded())).readObject())); certGen.setStartDate(new Time(new Date(System.currentTimeMillis()))); certGen.setEndDate(new Time(expiry.getTime())); TBSCertificateStructure tbsCert = certGen.generateTBSCertificate(); //Sign certificate SHA1Digest digester = new SHA1Digest(); AsymmetricBlockCipher rsa = new PKCS1Encoding(new RSAEngine()); ByteArrayOutputStream bOut = new ByteArrayOutputStream(); DEROutputStream dOut = new DEROutputStream(bOut); dOut.writeObject(tbsCert); byte[] signature; byte[] certBlock = bOut.toByteArray(); // first create digest digester.update(certBlock, 0, certBlock.length); byte[] hash = new byte[digester.getDigestSize()]; digester.doFinal(hash, 0); // then sign it rsa.init(true, cipherParams); DigestInfo dInfo = new DigestInfo(new AlgorithmIdentifier(X509ObjectIdentifiers.id_SHA1, null), hash); byte[] digest = dInfo.getEncoded(ASN1Encodable.DER); signature = rsa.processBlock(digest, 0, digest.length); ASN1EncodableVector v = new ASN1EncodableVector(); v.add(tbsCert); v.add(sigAlgId); v.add(new DERBitString(signature)); // Create CRT data structure clientCert = new X509CertificateObject(new X509CertificateStructure(new DERSequence(v))); clientCert.verify(caCert.getPublicKey()); } catch (IOException | CertificateException | NoSuchAlgorithmException | InvalidKeyException | NoSuchProviderException | InvalidCipherTextException | SignatureException e) { logger.log(Level.SEVERE, "Could not create client certificate: {0}", new Object[] { e.getMessage() }); throw new CertificateCreationException("230 Could not create client certificate"); } return new Certificate(clientCert, id.getCommonName(), id.getUniqueIdentifier(), id.getOrganisation(), id.getOrganisationUnit(), id.getCountryName(), id.getState(), id.getLocality(), id.getSurname(), id.getGivenName(), applicationIdentifier, roles, id.getIdentityProvider(), extensionMap); }
From source file:it.scoppelletti.spaceship.security.FakeCertificateFactory.java
License:Apache License
@SuppressWarnings({ "deprecation", "TryFinallyCanBeTryWithResources" }) public static X509Certificate create(PublicKey publicKey, FakeKeyPairGeneratorSpec spec) throws IOException, CertificateParsingException { ASN1ObjectIdentifier sigAlgOid;/*from ww w . j ava 2 s .co m*/ AlgorithmIdentifier sigAlgId; org.bouncycastle.jce.X509Principal subject; ASN1EncodableVector result; Certificate cert; org.bouncycastle.jce.provider.X509CertificateObject x509Cert; TBSCertificate tbsCertificate; ASN1InputStream publicKeyInfoIn = null; V3TBSCertificateGenerator tbsGenerator; byte[] signature; sigAlgOid = PKCSObjectIdentifiers.sha256WithRSAEncryption; sigAlgId = new AlgorithmIdentifier(sigAlgOid, DERNull.INSTANCE); signature = new byte[1]; tbsGenerator = new V3TBSCertificateGenerator(); try { publicKeyInfoIn = new ASN1InputStream(publicKey.getEncoded()); tbsGenerator.setSubjectPublicKeyInfo(SubjectPublicKeyInfo.getInstance(publicKeyInfoIn.readObject())); } finally { if (publicKeyInfoIn != null) { publicKeyInfoIn.close(); } } subject = new org.bouncycastle.jce.X509Principal(spec.getSubject().getEncoded()); tbsGenerator.setSerialNumber(new ASN1Integer(spec.getSerialNumber())); tbsGenerator.setSubject(subject); tbsGenerator.setIssuer(subject); tbsGenerator.setStartDate(new Time(spec.getStartDate())); tbsGenerator.setEndDate(new Time(spec.getEndDate())); tbsGenerator.setSignature(sigAlgId); tbsCertificate = tbsGenerator.generateTBSCertificate(); result = new ASN1EncodableVector(); result.add(tbsCertificate); result.add(sigAlgId); result.add(new DERBitString(signature)); cert = Certificate.getInstance(new DERSequence(result)); x509Cert = new org.bouncycastle.jce.provider.X509CertificateObject(cert); return x509Cert; }
From source file:org.openconcerto.modules.finance.payment.ebics.crypto.X509CertificateGenerator.java
License:Open Source License
/** * This method implements the public one, but offers an additional parameter which is only used * when creating a new CA, namely the export alias to use. * /*from w w w .ja v a 2 s . c o m*/ * @param commonName @see #createCertificate(String, int, String, String) * @param validityDays @see #createCertificate(String, int, String, String) * @param exportFile @see #createCertificate(String, int, String, String) * @param exportPassword @see #createCertificate(String, int, String, String) * @param exportAlias If this additional parameter is null, a default value will be used as the * "friendly name" in the PKCS12 file. * @return @see #createCertificate(String, int, String, String) * * @see #X509CertificateGenerator(boolean) */ protected boolean createCertificate(String commonName, int validityDays, String exportFile, String exportPassword, String exportAlias) throws IOException, InvalidKeyException, SecurityException, SignatureException, NoSuchAlgorithmException, DataLengthException, CryptoException, KeyStoreException, CertificateException, InvalidKeySpecException { if (commonName == null || exportFile == null || exportPassword == null || validityDays < 1) { throw new IllegalArgumentException("Can not work with null parameter"); } System.out.println("Generating certificate for distinguished common subject name '" + commonName + "', valid for " + validityDays + " days"); SecureRandom sr = new SecureRandom(); // the JCE representation PublicKey pubKey; PrivateKey privKey; // the BCAPI representation RSAPrivateCrtKeyParameters privateKey = null; System.out.println("Creating RSA keypair"); // generate the keypair for the new certificate RSAKeyPairGenerator gen = new RSAKeyPairGenerator(); // TODO: what are these values?? gen.init(new RSAKeyGenerationParameters(BigInteger.valueOf(0x10001), sr, 1024, 80)); AsymmetricCipherKeyPair keypair = gen.generateKeyPair(); System.out .println("Generated keypair, extracting components and creating public structure for certificate"); RSAKeyParameters publicKey = (RSAKeyParameters) keypair.getPublic(); privateKey = (RSAPrivateCrtKeyParameters) keypair.getPrivate(); // used to get proper encoding for the certificate RSAPublicKeyStructure pkStruct = new RSAPublicKeyStructure(publicKey.getModulus(), publicKey.getExponent()); System.out.println("New public key is '" + new String(Hex.encode(pkStruct.getEncoded())) + ", exponent=" + publicKey.getExponent() + ", modulus=" + publicKey.getModulus()); // TODO: these two lines should go away // JCE format needed for the certificate - because getEncoded() is necessary... pubKey = KeyFactory.getInstance("RSA") .generatePublic(new RSAPublicKeySpec(publicKey.getModulus(), publicKey.getExponent())); // and this one for the KeyStore privKey = KeyFactory.getInstance("RSA") .generatePrivate(new RSAPrivateCrtKeySpec(publicKey.getModulus(), publicKey.getExponent(), privateKey.getExponent(), privateKey.getP(), privateKey.getQ(), privateKey.getDP(), privateKey.getDQ(), privateKey.getQInv())); Calendar expiry = Calendar.getInstance(); expiry.add(Calendar.DAY_OF_YEAR, validityDays); X500Name x509Name = new X500Name("CN=" + commonName); V3TBSCertificateGenerator certGen = new V3TBSCertificateGenerator(); certGen.setSerialNumber(new DERInteger(BigInteger.valueOf(System.currentTimeMillis()))); if (caCert != null) { // Attention: this is a catch! Just using // "new X509Name(caCert.getSubjectDN().getName())" will not work! // I don't know why, because the issuerDN strings look similar with both versions. certGen.setIssuer(PrincipalUtil.getSubjectX509Principal(caCert)); } else { // aha, no CA set, which means that we should create a self-signed certificate (called // from createCA) certGen.setIssuer(x509Name); } certGen.setSubject(x509Name); // TODO GM: DERObjectIdentifier sigOID = PKCSObjectIdentifiers.sha1WithRSAEncryption;// DERObjectIdentifier. // X509Util.getAlgorithmOID(CertificateSignatureAlgorithm); AlgorithmIdentifier sigAlgId = new AlgorithmIdentifier(sigOID, new DERNull()); certGen.setSignature(sigAlgId); // certGen.setSubjectPublicKeyInfo(new SubjectPublicKeyInfo(sigAlgId, // pkStruct.toASN1Object())); // TODO: why does the coding above not work? - make me work without PublicKey class certGen.setSubjectPublicKeyInfo(new SubjectPublicKeyInfo( (ASN1Sequence) new ASN1InputStream(new ByteArrayInputStream(pubKey.getEncoded())).readObject())); certGen.setStartDate(new Time(new Date(System.currentTimeMillis()))); certGen.setEndDate(new Time(expiry.getTime())); // These X509v3 extensions are not strictly necessary, but be nice and provide them... Hashtable extensions = new Hashtable(); Vector extOrdering = new Vector(); addExtensionHelper(X509Extension.subjectKeyIdentifier, false, new SubjectKeyIdentifierStructure(pubKey), extOrdering, extensions); if (caCert != null) { // again: only if we have set CA addExtensionHelper(X509Extension.authorityKeyIdentifier, false, new AuthorityKeyIdentifierStructure(caCert), extOrdering, extensions); } else { // but if we create a new self-signed cert, set its capability to be a CA // this is a critical extension (true)! addExtensionHelper(X509Extension.basicConstraints, true, new BasicConstraints(0), extOrdering, extensions); } certGen.setExtensions(new X509Extensions(extOrdering, extensions)); System.out.println("Certificate structure generated, creating SHA1 digest"); // attention: hard coded to be SHA1+RSA! SHA1Digest digester = new SHA1Digest(); AsymmetricBlockCipher rsa = new PKCS1Encoding(new RSAEngine()); TBSCertificateStructure tbsCert = certGen.generateTBSCertificate(); ByteArrayOutputStream bOut = new ByteArrayOutputStream(); DEROutputStream dOut = new DEROutputStream(bOut); dOut.writeObject(tbsCert); // and now sign byte[] signature; byte[] certBlock = bOut.toByteArray(); // first create digest System.out.println("Block to sign is '" + new String(Hex.encode(certBlock)) + "'"); digester.update(certBlock, 0, certBlock.length); byte[] hash = new byte[digester.getDigestSize()]; digester.doFinal(hash, 0); // and sign that if (caCert != null) { rsa.init(true, caPrivateKey); } else { // no CA - self sign System.out.println("No CA has been set, creating self-signed certificate as a new CA"); rsa.init(true, privateKey); } DigestInfo dInfo = new DigestInfo(new AlgorithmIdentifier(X509ObjectIdentifiers.id_SHA1, null), hash); byte[] digest = dInfo.getEncoded(ASN1Encodable.DER); signature = rsa.processBlock(digest, 0, digest.length); System.out.println("SHA1/RSA signature of digest is '" + new String(Hex.encode(signature)) + "'"); // and finally construct the certificate structure ASN1EncodableVector v = new ASN1EncodableVector(); v.add(tbsCert); v.add(sigAlgId); v.add(new DERBitString(signature)); X509CertificateObject clientCert = new X509CertificateObject( new X509CertificateStructure(new DERSequence(v))); System.out.println("Verifying certificate for correct signature with CA public key"); /* * if (caCert != null) { clientCert.verify(caCert.getPublicKey()); } else { * clientCert.verify(pubKey); } */ // and export as PKCS12 formatted file along with the private key and the CA certificate System.out.println("Exporting certificate in PKCS12 format"); PKCS12BagAttributeCarrier bagCert = clientCert; // if exportAlias is set, use that, otherwise a default name bagCert.setBagAttribute(PKCSObjectIdentifiers.pkcs_9_at_friendlyName, new DERBMPString(exportAlias == null ? CertificateExportFriendlyName : exportAlias)); bagCert.setBagAttribute(PKCSObjectIdentifiers.pkcs_9_at_localKeyId, new SubjectKeyIdentifierStructure(pubKey)); // this does not work as in the example /* * PKCS12BagAttributeCarrier bagKey = (PKCS12BagAttributeCarrier)privKey; * bagKey.setBagAttribute( PKCSObjectIdentifiers.pkcs_9_at_localKeyId, new * SubjectKeyIdentifierStructure(tmpKey)); */ JDKPKCS12KeyStore store; store = new JDKPKCS12KeyStore.BCPKCS12KeyStore(); store.engineLoad(null, null); FileOutputStream fOut = new FileOutputStream(exportFile); X509Certificate[] chain; if (caCert != null) { chain = new X509Certificate[2]; // first the client, then the CA certificate - this is the expected order for a // certificate chain chain[0] = clientCert; chain[1] = caCert; } else { // for a self-signed certificate, there is no chain... chain = new X509Certificate[1]; chain[0] = clientCert; } store.engineSetKeyEntry(exportAlias == null ? KeyExportFriendlyName : exportAlias, privKey, exportPassword.toCharArray(), chain); store.engineStore(fOut, exportPassword.toCharArray()); return true; }
From source file:org.openuat.channel.X509CertificateGenerator.java
License:Open Source License
/** This method implements the public one, but offers an additional parameter which is only used when * creating a new CA, namely the export alias to use. * @param commonName @see #createCertificate(String, int, String, String) * @param validityDays @see #createCertificate(String, int, String, String) * @param exportFile @see #createCertificate(String, int, String, String) * @param exportPassword @see #createCertificate(String, int, String, String) * @param exportAlias If this additional parameter is null, a default value will be used as the "friendly name" in the PKCS12 file. * @return @see #createCertificate(String, int, String, String) * /*from ww w . jav a 2s. c o m*/ * @see #X509CertificateGenerator(boolean) */ protected boolean createCertificate(String commonName, int validityDays, String exportFile, String exportPassword, String exportAlias) throws IOException, InvalidKeyException, SecurityException, SignatureException, NoSuchAlgorithmException, DataLengthException, CryptoException, KeyStoreException, CertificateException, InvalidKeySpecException { if (commonName == null || exportFile == null || exportPassword == null || validityDays < 1) { throw new IllegalArgumentException("Can not work with null parameter"); } logger.info("Generating certificate for distinguished common subject name '" + commonName + "', valid for " + validityDays + " days"); SecureRandom sr = new SecureRandom(); // the JCE representation PublicKey pubKey; PrivateKey privKey; // the BCAPI representation RSAPrivateCrtKeyParameters privateKey = null; logger.debug("Creating RSA keypair"); // generate the keypair for the new certificate if (useBCAPI) { RSAKeyPairGenerator gen = new RSAKeyPairGenerator(); // TODO: what are these values?? gen.init(new RSAKeyGenerationParameters(BigInteger.valueOf(0x10001), sr, 1024, 80)); AsymmetricCipherKeyPair keypair = gen.generateKeyPair(); logger.debug("Generated keypair, extracting components and creating public structure for certificate"); RSAKeyParameters publicKey = (RSAKeyParameters) keypair.getPublic(); privateKey = (RSAPrivateCrtKeyParameters) keypair.getPrivate(); // used to get proper encoding for the certificate RSAPublicKeyStructure pkStruct = new RSAPublicKeyStructure(publicKey.getModulus(), publicKey.getExponent()); logger.debug("New public key is '" + new String(Hex.encodeHex(pkStruct.getEncoded())) + ", exponent=" + publicKey.getExponent() + ", modulus=" + publicKey.getModulus()); // TODO: these two lines should go away // JCE format needed for the certificate - because getEncoded() is necessary... pubKey = KeyFactory.getInstance("RSA") .generatePublic(new RSAPublicKeySpec(publicKey.getModulus(), publicKey.getExponent())); // and this one for the KeyStore privKey = KeyFactory.getInstance("RSA") .generatePrivate(new RSAPrivateCrtKeySpec(publicKey.getModulus(), publicKey.getExponent(), privateKey.getExponent(), privateKey.getP(), privateKey.getQ(), privateKey.getDP(), privateKey.getDQ(), privateKey.getQInv())); } else { // this is the JSSE way of key generation KeyPairGenerator keyGen = KeyPairGenerator.getInstance("RSA"); keyGen.initialize(1024, sr); KeyPair keypair = keyGen.generateKeyPair(); privKey = keypair.getPrivate(); pubKey = keypair.getPublic(); } Calendar expiry = Calendar.getInstance(); expiry.add(Calendar.DAY_OF_YEAR, validityDays); X509Name x509Name = new X509Name("CN=" + commonName); V3TBSCertificateGenerator certGen = new V3TBSCertificateGenerator(); certGen.setSerialNumber(new DERInteger(BigInteger.valueOf(System.currentTimeMillis()))); if (caCert != null) { // Attention: this is a catch! Just using "new X509Name(caCert.getSubjectDN().getName())" will not work! // I don't know why, because the issuerDN strings look similar with both versions. certGen.setIssuer(PrincipalUtil.getSubjectX509Principal(caCert)); } else { // aha, no CA set, which means that we should create a self-signed certificate (called from createCA) certGen.setIssuer(x509Name); } certGen.setSubject(x509Name); DERObjectIdentifier sigOID = X509Util.getAlgorithmOID(CertificateSignatureAlgorithm); AlgorithmIdentifier sigAlgId = new AlgorithmIdentifier(sigOID, new DERNull()); certGen.setSignature(sigAlgId); //certGen.setSubjectPublicKeyInfo(new SubjectPublicKeyInfo(sigAlgId, pkStruct.toASN1Object())); // TODO: why does the coding above not work? - make me work without PublicKey class certGen.setSubjectPublicKeyInfo(new SubjectPublicKeyInfo( (ASN1Sequence) new ASN1InputStream(new ByteArrayInputStream(pubKey.getEncoded())).readObject())); certGen.setStartDate(new Time(new Date(System.currentTimeMillis()))); certGen.setEndDate(new Time(expiry.getTime())); // These X509v3 extensions are not strictly necessary, but be nice and provide them... Hashtable extensions = new Hashtable(); Vector extOrdering = new Vector(); addExtensionHelper(X509Extensions.SubjectKeyIdentifier, false, new SubjectKeyIdentifierStructure(pubKey), extOrdering, extensions); if (caCert != null) { // again: only if we have set CA addExtensionHelper(X509Extensions.AuthorityKeyIdentifier, false, new AuthorityKeyIdentifierStructure(caCert), extOrdering, extensions); } else { // but if we create a new self-signed cert, set its capability to be a CA // this is a critical extension (true)! addExtensionHelper(X509Extensions.BasicConstraints, true, new BasicConstraints(0), extOrdering, extensions); } certGen.setExtensions(new X509Extensions(extOrdering, extensions)); logger.debug("Certificate structure generated, creating SHA1 digest"); // attention: hard coded to be SHA1+RSA! SHA1Digest digester = new SHA1Digest(); AsymmetricBlockCipher rsa = new PKCS1Encoding(new RSAEngine()); TBSCertificateStructure tbsCert = certGen.generateTBSCertificate(); ByteArrayOutputStream bOut = new ByteArrayOutputStream(); DEROutputStream dOut = new DEROutputStream(bOut); dOut.writeObject(tbsCert); // and now sign byte[] signature; if (useBCAPI) { byte[] certBlock = bOut.toByteArray(); // first create digest logger.debug("Block to sign is '" + new String(Hex.encodeHex(certBlock)) + "'"); digester.update(certBlock, 0, certBlock.length); byte[] hash = new byte[digester.getDigestSize()]; digester.doFinal(hash, 0); // and sign that if (caCert != null) { rsa.init(true, caPrivateKey); } else { // no CA - self sign logger.info("No CA has been set, creating self-signed certificate as a new CA"); rsa.init(true, privateKey); } DigestInfo dInfo = new DigestInfo(new AlgorithmIdentifier(X509ObjectIdentifiers.id_SHA1, null), hash); byte[] digest = dInfo.getEncoded(ASN1Encodable.DER); signature = rsa.processBlock(digest, 0, digest.length); } else { // or the JCE way Signature sig = Signature.getInstance(sigOID.getId()); if (caCert != null) { PrivateKey caPrivKey = KeyFactory.getInstance("RSA") .generatePrivate(new RSAPrivateCrtKeySpec(caPrivateKey.getModulus(), caPrivateKey.getPublicExponent(), caPrivateKey.getExponent(), caPrivateKey.getP(), caPrivateKey.getQ(), caPrivateKey.getDP(), caPrivateKey.getDQ(), caPrivateKey.getQInv())); sig.initSign(caPrivKey, sr); } else { logger.info("No CA has been set, creating self-signed certificate as a new CA"); sig.initSign(privKey, sr); } sig.update(bOut.toByteArray()); signature = sig.sign(); } logger.debug("SHA1/RSA signature of digest is '" + new String(Hex.encodeHex(signature)) + "'"); // and finally construct the certificate structure ASN1EncodableVector v = new ASN1EncodableVector(); v.add(tbsCert); v.add(sigAlgId); v.add(new DERBitString(signature)); X509CertificateObject clientCert = new X509CertificateObject( new X509CertificateStructure(new DERSequence(v))); logger.debug("Verifying certificate for correct signature with CA public key"); /* if (caCert != null) { clientCert.verify(caCert.getPublicKey()); } else { clientCert.verify(pubKey); }*/ // and export as PKCS12 formatted file along with the private key and the CA certificate logger.debug("Exporting certificate in PKCS12 format"); PKCS12BagAttributeCarrier bagCert = clientCert; // if exportAlias is set, use that, otherwise a default name bagCert.setBagAttribute(PKCSObjectIdentifiers.pkcs_9_at_friendlyName, new DERBMPString(exportAlias == null ? CertificateExportFriendlyName : exportAlias)); bagCert.setBagAttribute(PKCSObjectIdentifiers.pkcs_9_at_localKeyId, new SubjectKeyIdentifierStructure(pubKey)); // this does not work as in the example /*PKCS12BagAttributeCarrier bagKey = (PKCS12BagAttributeCarrier)privKey; bagKey.setBagAttribute( PKCSObjectIdentifiers.pkcs_9_at_localKeyId, new SubjectKeyIdentifierStructure(tmpKey));*/ Object store; if (!useBCAPI) { store = java.security.KeyStore.getInstance("PKCS12"); ((java.security.KeyStore) store).load(null, null); } else { store = new JDKPKCS12KeyStore(null, sigOID, sigOID); ((JDKPKCS12KeyStore) store).engineLoad(null, null); } FileOutputStream fOut = new FileOutputStream(exportFile); X509Certificate[] chain; if (caCert != null) { chain = new X509Certificate[2]; // first the client, then the CA certificate - this is the expected order for a certificate chain chain[0] = clientCert; chain[1] = caCert; } else { // for a self-signed certificate, there is no chain... chain = new X509Certificate[1]; chain[0] = clientCert; } if (!useBCAPI) { ((java.security.KeyStore) store).setKeyEntry(exportAlias == null ? KeyExportFriendlyName : exportAlias, privKey, exportPassword.toCharArray(), chain); ((java.security.KeyStore) store).store(fOut, exportPassword.toCharArray()); } else { ((JDKPKCS12KeyStore) store).engineSetKeyEntry(exportAlias == null ? KeyExportFriendlyName : exportAlias, privKey, exportPassword.toCharArray(), chain); ((JDKPKCS12KeyStore) store).engineStore(fOut, exportPassword.toCharArray()); } return true; }
From source file:org.xipki.security.p11.iaik.IaikP11Slot.java
License:Open Source License
private X509CertificateHolder generateCertificate(final Session session, final byte[] id, final String label, final String subject, final AlgorithmIdentifier signatureAlgId, final PrivateKeyAndPKInfo privateKeyAndPkInfo, Integer keyUsage, List<ASN1ObjectIdentifier> extendedKeyUsage) throws Exception { BigInteger serialNumber = BigInteger.ONE; Date startDate = new Date(); Date endDate = new Date(startDate.getTime() + 20 * YEAR); X500Name x500Name_subject = new X500Name(subject); x500Name_subject = X509Util.sortX509Name(x500Name_subject); V3TBSCertificateGenerator tbsGen = new V3TBSCertificateGenerator(); tbsGen.setSerialNumber(new ASN1Integer(serialNumber)); tbsGen.setSignature(signatureAlgId); tbsGen.setIssuer(x500Name_subject); tbsGen.setStartDate(new Time(startDate)); tbsGen.setEndDate(new Time(endDate)); tbsGen.setSubject(x500Name_subject); tbsGen.setSubjectPublicKeyInfo(privateKeyAndPkInfo.getPublicKeyInfo()); List<Extension> extensions = new ArrayList<>(2); if (keyUsage == null) { keyUsage = KeyUsage.keyCertSign | KeyUsage.cRLSign | KeyUsage.digitalSignature | KeyUsage.keyEncipherment; }/* ww w .j a v a2 s . c om*/ extensions.add(new Extension(Extension.keyUsage, true, new DEROctetString(new KeyUsage(keyUsage)))); if (CollectionUtil.isNotEmpty(extendedKeyUsage)) { KeyPurposeId[] kps = new KeyPurposeId[extendedKeyUsage.size()]; int i = 0; for (ASN1ObjectIdentifier oid : extendedKeyUsage) { kps[i++] = KeyPurposeId.getInstance(oid); } extensions.add(new Extension(Extension.extendedKeyUsage, false, new DEROctetString(new ExtendedKeyUsage(kps)))); } Extensions paramX509Extensions = new Extensions(extensions.toArray(new Extension[0])); tbsGen.setExtensions(paramX509Extensions); TBSCertificate tbsCertificate = tbsGen.generateTBSCertificate(); byte[] encodedTbsCertificate = tbsCertificate.getEncoded(); byte[] signature = null; Digest digest = null; Mechanism sigMechanism = null; ASN1ObjectIdentifier sigAlgID = signatureAlgId.getAlgorithm(); if (sigAlgID.equals(PKCSObjectIdentifiers.sha256WithRSAEncryption)) { sigMechanism = Mechanism.get(PKCS11Constants.CKM_SHA256_RSA_PKCS); session.signInit(sigMechanism, privateKeyAndPkInfo.getPrivateKey()); signature = session.sign(encodedTbsCertificate); } else if (sigAlgID.equals(NISTObjectIdentifiers.dsa_with_sha256)) { digest = new SHA256Digest(); byte[] digestValue = new byte[digest.getDigestSize()]; digest.update(encodedTbsCertificate, 0, encodedTbsCertificate.length); digest.doFinal(digestValue, 0); session.signInit(Mechanism.get(PKCS11Constants.CKM_DSA), privateKeyAndPkInfo.getPrivateKey()); byte[] rawSignature = session.sign(digestValue); signature = convertToX962Signature(rawSignature); } else { if (sigAlgID.equals(X9ObjectIdentifiers.ecdsa_with_SHA1)) { digest = new SHA1Digest(); } else if (sigAlgID.equals(X9ObjectIdentifiers.ecdsa_with_SHA256)) { digest = new SHA256Digest(); } else if (sigAlgID.equals(X9ObjectIdentifiers.ecdsa_with_SHA384)) { digest = new SHA384Digest(); } else if (sigAlgID.equals(X9ObjectIdentifiers.ecdsa_with_SHA512)) { digest = new SHA512Digest(); } else { System.err.println("unknown algorithm ID: " + sigAlgID.getId()); return null; } byte[] digestValue = new byte[digest.getDigestSize()]; digest.update(encodedTbsCertificate, 0, encodedTbsCertificate.length); digest.doFinal(digestValue, 0); session.signInit(Mechanism.get(PKCS11Constants.CKM_ECDSA), privateKeyAndPkInfo.getPrivateKey()); byte[] rawSignature = session.sign(digestValue); signature = convertToX962Signature(rawSignature); } // build DER certificate ASN1EncodableVector v = new ASN1EncodableVector(); v.add(tbsCertificate); v.add(signatureAlgId); v.add(new DERBitString(signature)); DERSequence cert = new DERSequence(v); // build and store PKCS#11 certificate object X509PublicKeyCertificate certTemp = new X509PublicKeyCertificate(); certTemp.getToken().setBooleanValue(true); certTemp.getId().setByteArrayValue(id); certTemp.getLabel().setCharArrayValue(label.toCharArray()); certTemp.getSubject().setByteArrayValue(x500Name_subject.getEncoded()); certTemp.getIssuer().setByteArrayValue(x500Name_subject.getEncoded()); certTemp.getSerialNumber().setByteArrayValue(serialNumber.toByteArray()); certTemp.getValue().setByteArrayValue(cert.getEncoded()); session.createObject(certTemp); return new X509CertificateHolder(Certificate.getInstance(cert)); }