IDEMPIERE-4611 Replace dependency to sun.security.tools.keytool with … (#486)
* IDEMPIERE-4611 Replace dependency to sun.security.tools.keytool with Bouncy Castle * IDEMPIERE-4611 Replace dependency to sun.security.tools.keytool with Bouncy Castle Fix error with State
This commit is contained in:
parent
da6d6b83aa
commit
3965dd68fe
|
@ -3,13 +3,12 @@
|
|||
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER">
|
||||
<attributes>
|
||||
<attribute name="module" value="true"/>
|
||||
<attribute name="add-exports" value="java.base/sun.security.tools.keytool=ALL-UNNAMED"/>
|
||||
</attributes>
|
||||
<accessrules>
|
||||
<accessrule kind="accessible" pattern="sun/security/tools/*"/>
|
||||
</accessrules>
|
||||
</classpathentry>
|
||||
<classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
|
||||
<classpathentry kind="src" path="src/"/>
|
||||
<classpathentry kind="src" path="src"/>
|
||||
<classpathentry kind="output" path="target/classes"/>
|
||||
</classpath>
|
||||
|
|
|
@ -11,6 +11,11 @@ Require-Capability: osgi.ee;filter:="(&(osgi.ee=JavaSE)(version>=11))"
|
|||
Import-Package: javax.mail;version="1.5",
|
||||
javax.mail.internet;version="1.5",
|
||||
org.apache.tools.ant,
|
||||
org.bouncycastle.asn1.x500;version="1.66.0",
|
||||
org.bouncycastle.cert;version="1.66.0",
|
||||
org.bouncycastle.cert.jcajce;version="1.66.0",
|
||||
org.bouncycastle.operator;version="1.66.0",
|
||||
org.bouncycastle.operator.jcajce;version="1.66.0",
|
||||
org.eclipse.ant.core,
|
||||
org.eclipse.core.runtime;version="3.4.0",
|
||||
org.eclipse.equinox.app,
|
||||
|
|
|
@ -19,22 +19,38 @@ package org.compiere.install;
|
|||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.math.BigInteger;
|
||||
import java.net.InetAddress;
|
||||
import java.nio.file.Files;
|
||||
import java.security.Key;
|
||||
import java.security.KeyPair;
|
||||
import java.security.KeyPairGenerator;
|
||||
import java.security.KeyStore;
|
||||
import java.security.KeyStore.PasswordProtection;
|
||||
import java.security.KeyStore.PrivateKeyEntry;
|
||||
import java.security.PrivateKey;
|
||||
import java.security.SecureRandom;
|
||||
import java.security.cert.Certificate;
|
||||
import java.util.ArrayList;
|
||||
import java.security.cert.X509Certificate;
|
||||
import java.time.Instant;
|
||||
import java.time.temporal.ChronoUnit;
|
||||
import java.util.Date;
|
||||
import java.util.StringTokenizer;
|
||||
import java.util.logging.Level;
|
||||
|
||||
import javax.swing.JFrame;
|
||||
|
||||
import org.bouncycastle.asn1.x500.X500Name;
|
||||
import org.bouncycastle.cert.X509CertificateHolder;
|
||||
import org.bouncycastle.cert.jcajce.JcaX509CertificateConverter;
|
||||
import org.bouncycastle.cert.jcajce.JcaX509v3CertificateBuilder;
|
||||
import org.bouncycastle.operator.ContentSigner;
|
||||
import org.bouncycastle.operator.jcajce.JcaContentSignerBuilder;
|
||||
import org.compiere.Adempiere;
|
||||
import org.compiere.util.CLogMgt;
|
||||
import org.compiere.util.CLogger;
|
||||
|
||||
import sun.security.tools.keytool.Main;
|
||||
//import sun.security.tools.keytool.Main;
|
||||
|
||||
/**
|
||||
* Class to manage SSL KeyStore
|
||||
|
@ -236,7 +252,6 @@ public class KeyStoreMgt
|
|||
//
|
||||
try
|
||||
{
|
||||
genkey (alias, m_password, m_file.getAbsolutePath(), dname);
|
||||
selfcert (alias, m_password, m_file.getAbsolutePath(), dname);
|
||||
}
|
||||
catch (Exception e)
|
||||
|
@ -355,7 +370,7 @@ public class KeyStoreMgt
|
|||
if (l != null && l.length() > 0)
|
||||
dname.append(", L=").append(escapeCommas(l)); // locality
|
||||
if (s != null && s.length() > 0)
|
||||
dname.append(", S=").append(escapeCommas(s)); // state
|
||||
dname.append(", ST=").append(escapeCommas(s)); // state
|
||||
dname.append(", C=").append(escapeCommas(c)); // country
|
||||
return dname.toString();
|
||||
} // getDname
|
||||
|
@ -382,91 +397,72 @@ public class KeyStoreMgt
|
|||
} // escapeCommas
|
||||
|
||||
/**
|
||||
* Generate Key
|
||||
* @param alias adempiere
|
||||
* @param password password
|
||||
* @param fileName key store file name (may have spaces)
|
||||
* @param dname distinguished name
|
||||
*/
|
||||
public static void genkey (String alias, char[] password, String fileName, String dname)
|
||||
{
|
||||
StringBuilder cmd = new StringBuilder ("-genkey -keyalg rsa");
|
||||
cmd.append(" -alias ").append(alias);
|
||||
cmd.append(" -dname \"").append(dname).append("\"");
|
||||
cmd.append(" -keypass ").append(password).append(" -validity 999");
|
||||
if (fileName.indexOf(' ') != -1)
|
||||
cmd.append(" -keystore \"").append(fileName).append("\" -storepass ").append(password);
|
||||
else
|
||||
cmd.append(" -keystore ").append(fileName).append(" -storepass ").append(password);
|
||||
keytool (cmd.toString());
|
||||
} // genkey
|
||||
|
||||
/**
|
||||
* Generate Key
|
||||
* @param alias adempiere
|
||||
* Generate Key and Cert
|
||||
* @param alias keystore alias
|
||||
* @param password password
|
||||
* @param fileName key store file name (may have spaces)
|
||||
* @param dname distinguished name
|
||||
*/
|
||||
public static void selfcert (String alias, char[] password, String fileName, String dname)
|
||||
{
|
||||
StringBuilder cmd = new StringBuilder ("-selfcert");
|
||||
cmd.append(" -alias ").append(alias);
|
||||
cmd.append(" -dname \"").append(dname).append("\"");
|
||||
cmd.append(" -keypass ").append(password).append(" -validity 999");
|
||||
if (fileName.indexOf(' ') != -1)
|
||||
cmd.append(" -keystore \"").append(fileName).append("\" -storepass ").append(password);
|
||||
else
|
||||
cmd.append(" -keystore ").append(fileName).append(" -storepass ").append(password);
|
||||
keytool (cmd.toString());
|
||||
try
|
||||
{
|
||||
File storeFile = new File(fileName);
|
||||
if (storeFile.exists())
|
||||
return;
|
||||
|
||||
CertificateKeyPair certKeyPair = createCertificate(dname);
|
||||
KeyStore keyStore = KeyStore.getInstance("JKS");
|
||||
keyStore.load(null, null);
|
||||
PasswordProtection protParam = new KeyStore.PasswordProtection(password);
|
||||
KeyStore.Entry entry = new PrivateKeyEntry(certKeyPair.keyPair.getPrivate(),
|
||||
new Certificate[] { certKeyPair.cert });
|
||||
keyStore.setEntry(alias, entry, protParam);
|
||||
try (OutputStream fos = Files.newOutputStream(storeFile.toPath()))
|
||||
{
|
||||
keyStore.store(fos, password);
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
} // selfcert
|
||||
|
||||
/**
|
||||
* Submit Command to Key Tool
|
||||
* @param cmd command
|
||||
*
|
||||
* @param dname
|
||||
* @return pair of key and cert
|
||||
* @throws Exception
|
||||
*/
|
||||
public static void keytool(String cmd)
|
||||
{
|
||||
if (log.isLoggable(Level.INFO)) log.info("keytool " + cmd);
|
||||
ArrayList<String> list = new ArrayList<String>();
|
||||
StringTokenizer st = new StringTokenizer(cmd, " ");
|
||||
String quoteBuffer = null;
|
||||
while (st.hasMoreTokens())
|
||||
{
|
||||
String token = st.nextToken();
|
||||
// System.out.println("= " + token + " = quoteBuffer=" + quoteBuffer + " - Size=" + list.size() );
|
||||
if (quoteBuffer == null)
|
||||
{
|
||||
if (token.startsWith("\""))
|
||||
quoteBuffer = token.substring(1);
|
||||
else
|
||||
list.add(token);
|
||||
}
|
||||
else
|
||||
quoteBuffer += " " + token;
|
||||
if (token.endsWith("\""))
|
||||
{
|
||||
String str = quoteBuffer.substring(0, quoteBuffer.length()-1);
|
||||
// System.out.println(" Buffer= " + str );
|
||||
list.add(str);
|
||||
quoteBuffer = null;
|
||||
}
|
||||
} // all tokens
|
||||
private static CertificateKeyPair createCertificate(String dname) throws Exception {
|
||||
// Generate the key-pair with the official Java API's
|
||||
KeyPairGenerator keyGen = KeyPairGenerator.getInstance("RSA");
|
||||
keyGen.initialize(2048, new SecureRandom());
|
||||
KeyPair certKeyPair = keyGen.generateKeyPair();
|
||||
X500Name dnName = new X500Name(dname);
|
||||
BigInteger serialNumber = BigInteger.valueOf(System.currentTimeMillis());
|
||||
Instant validFrom = Instant.now();
|
||||
Instant validUntil = validFrom.plus(999, ChronoUnit.DAYS);
|
||||
|
||||
//
|
||||
String[] args = new String[list.size()];
|
||||
list.toArray(args);
|
||||
// System.out.println(" args #" + args.length);
|
||||
//vpj-cd add support java 6
|
||||
try
|
||||
{
|
||||
Main.main(args);;
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
e.printStackTrace();
|
||||
}
|
||||
} // ketyool
|
||||
// If there is no issuer, we self-sign our certificate.
|
||||
X500Name issuerName = dnName;
|
||||
PrivateKey issuerKey = certKeyPair.getPrivate();
|
||||
|
||||
// The cert builder to build up our certificate information
|
||||
JcaX509v3CertificateBuilder builder = new JcaX509v3CertificateBuilder(
|
||||
issuerName,
|
||||
serialNumber,
|
||||
Date.from(validFrom), Date.from(validUntil),
|
||||
dnName, certKeyPair.getPublic());
|
||||
|
||||
// Finally, sign the certificate:
|
||||
ContentSigner signer = new JcaContentSignerBuilder("SHA256WithRSA").build(issuerKey);
|
||||
X509CertificateHolder certHolder = builder.build(signer);
|
||||
X509Certificate cert = new JcaX509CertificateConverter().getCertificate(certHolder);
|
||||
|
||||
return new CertificateKeyPair(certKeyPair, cert);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Keystore File Name
|
||||
|
@ -484,6 +480,15 @@ public class KeyStoreMgt
|
|||
return fileName;
|
||||
} // getKeystoreFileName
|
||||
|
||||
private static class CertificateKeyPair {
|
||||
private KeyPair keyPair;
|
||||
private X509Certificate cert;
|
||||
|
||||
private CertificateKeyPair(KeyPair keyPair, X509Certificate cert) {
|
||||
this.keyPair = keyPair;
|
||||
this.cert = cert;
|
||||
}
|
||||
}
|
||||
|
||||
/**************************************************************************
|
||||
* Test
|
||||
|
|
Loading…
Reference in New Issue