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:
hengsin 2020-12-27 22:07:36 +08:00 committed by GitHub
parent da6d6b83aa
commit 3965dd68fe
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 94 additions and 85 deletions

View File

@ -3,13 +3,12 @@
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"> <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER">
<attributes> <attributes>
<attribute name="module" value="true"/> <attribute name="module" value="true"/>
<attribute name="add-exports" value="java.base/sun.security.tools.keytool=ALL-UNNAMED"/>
</attributes> </attributes>
<accessrules> <accessrules>
<accessrule kind="accessible" pattern="sun/security/tools/*"/> <accessrule kind="accessible" pattern="sun/security/tools/*"/>
</accessrules> </accessrules>
</classpathentry> </classpathentry>
<classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/> <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"/> <classpathentry kind="output" path="target/classes"/>
</classpath> </classpath>

View File

@ -11,6 +11,11 @@ Require-Capability: osgi.ee;filter:="(&(osgi.ee=JavaSE)(version>=11))"
Import-Package: javax.mail;version="1.5", Import-Package: javax.mail;version="1.5",
javax.mail.internet;version="1.5", javax.mail.internet;version="1.5",
org.apache.tools.ant, 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.ant.core,
org.eclipse.core.runtime;version="3.4.0", org.eclipse.core.runtime;version="3.4.0",
org.eclipse.equinox.app, org.eclipse.equinox.app,

View File

@ -19,22 +19,38 @@ package org.compiere.install;
import java.io.File; import java.io.File;
import java.io.FileInputStream; import java.io.FileInputStream;
import java.io.InputStream; import java.io.InputStream;
import java.io.OutputStream;
import java.math.BigInteger;
import java.net.InetAddress; import java.net.InetAddress;
import java.nio.file.Files;
import java.security.Key; import java.security.Key;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.KeyStore; 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.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.Date;
import java.util.StringTokenizer;
import java.util.logging.Level; import java.util.logging.Level;
import javax.swing.JFrame; 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.Adempiere;
import org.compiere.util.CLogMgt; import org.compiere.util.CLogMgt;
import org.compiere.util.CLogger; import org.compiere.util.CLogger;
import sun.security.tools.keytool.Main; //import sun.security.tools.keytool.Main;
/** /**
* Class to manage SSL KeyStore * Class to manage SSL KeyStore
@ -236,7 +252,6 @@ public class KeyStoreMgt
// //
try try
{ {
genkey (alias, m_password, m_file.getAbsolutePath(), dname);
selfcert (alias, m_password, m_file.getAbsolutePath(), dname); selfcert (alias, m_password, m_file.getAbsolutePath(), dname);
} }
catch (Exception e) catch (Exception e)
@ -355,7 +370,7 @@ public class KeyStoreMgt
if (l != null && l.length() > 0) if (l != null && l.length() > 0)
dname.append(", L=").append(escapeCommas(l)); // locality dname.append(", L=").append(escapeCommas(l)); // locality
if (s != null && s.length() > 0) 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 dname.append(", C=").append(escapeCommas(c)); // country
return dname.toString(); return dname.toString();
} // getDname } // getDname
@ -382,91 +397,72 @@ public class KeyStoreMgt
} // escapeCommas } // escapeCommas
/** /**
* Generate Key * Generate Key and Cert
* @param alias adempiere * @param alias keystore alias
* @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
* @param password password * @param password password
* @param fileName key store file name (may have spaces) * @param fileName key store file name (may have spaces)
* @param dname distinguished name * @param dname distinguished name
*/ */
public static void selfcert (String alias, char[] password, String fileName, String dname) public static void selfcert (String alias, char[] password, String fileName, String dname)
{ {
StringBuilder cmd = new StringBuilder ("-selfcert"); try
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());
} // selfcert
/**
* Submit Command to Key Tool
* @param cmd command
*/
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(); File storeFile = new File(fileName);
// System.out.println("= " + token + " = quoteBuffer=" + quoteBuffer + " - Size=" + list.size() ); if (storeFile.exists())
if (quoteBuffer == null) return;
{
if (token.startsWith("\"")) CertificateKeyPair certKeyPair = createCertificate(dname);
quoteBuffer = token.substring(1); KeyStore keyStore = KeyStore.getInstance("JKS");
else keyStore.load(null, null);
list.add(token); PasswordProtection protParam = new KeyStore.PasswordProtection(password);
} KeyStore.Entry entry = new PrivateKeyEntry(certKeyPair.keyPair.getPrivate(),
else new Certificate[] { certKeyPair.cert });
quoteBuffer += " " + token; keyStore.setEntry(alias, entry, protParam);
if (token.endsWith("\"")) try (OutputStream fos = Files.newOutputStream(storeFile.toPath()))
{ {
String str = quoteBuffer.substring(0, quoteBuffer.length()-1); keyStore.store(fos, password);
// System.out.println(" Buffer= " + str ); }
list.add(str); }
quoteBuffer = null; catch (Exception e)
} {
} // all tokens throw new RuntimeException(e);
}
// } // selfcert
String[] args = new String[list.size()];
list.toArray(args); /**
// System.out.println(" args #" + args.length); *
//vpj-cd add support java 6 * @param dname
try * @return pair of key and cert
{ * @throws Exception
Main.main(args);; */
} private static CertificateKeyPair createCertificate(String dname) throws Exception {
catch (Exception e) // Generate the key-pair with the official Java API's
{ KeyPairGenerator keyGen = KeyPairGenerator.getInstance("RSA");
e.printStackTrace(); keyGen.initialize(2048, new SecureRandom());
} KeyPair certKeyPair = keyGen.generateKeyPair();
} // ketyool X500Name dnName = new X500Name(dname);
BigInteger serialNumber = BigInteger.valueOf(System.currentTimeMillis());
Instant validFrom = Instant.now();
Instant validUntil = validFrom.plus(999, ChronoUnit.DAYS);
// 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 * Get Keystore File Name
@ -484,6 +480,15 @@ public class KeyStoreMgt
return fileName; return fileName;
} // getKeystoreFileName } // getKeystoreFileName
private static class CertificateKeyPair {
private KeyPair keyPair;
private X509Certificate cert;
private CertificateKeyPair(KeyPair keyPair, X509Certificate cert) {
this.keyPair = keyPair;
this.cert = cert;
}
}
/************************************************************************** /**************************************************************************
* Test * Test