mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2025-10-03 09:49:23 +02:00
GP-1296 Eliminated use of sun.security package and refactored ApplicationKeyManagerUtils
This commit is contained in:
parent
8b2ea61e27
commit
9db26bc7f5
15 changed files with 252 additions and 263 deletions
|
@ -30,5 +30,5 @@
|
||||||
<stringAttribute key="org.eclipse.jdt.launching.MODULE_NAME" value="Framework Utility"/>
|
<stringAttribute key="org.eclipse.jdt.launching.MODULE_NAME" value="Framework Utility"/>
|
||||||
<stringAttribute key="org.eclipse.jdt.launching.PROGRAM_ARGUMENTS" value="ghidra.GhidraRun"/>
|
<stringAttribute key="org.eclipse.jdt.launching.PROGRAM_ARGUMENTS" value="ghidra.GhidraRun"/>
|
||||||
<stringAttribute key="org.eclipse.jdt.launching.PROJECT_ATTR" value="Framework Utility"/>
|
<stringAttribute key="org.eclipse.jdt.launching.PROJECT_ATTR" value="Framework Utility"/>
|
||||||
<stringAttribute key="org.eclipse.jdt.launching.VM_ARGUMENTS" value="-XX:+IgnoreUnrecognizedVMOptions -Djava.system.class.loader=ghidra.GhidraClassLoader -Xshare:off -Dfile.encoding=UTF8 -Duser.country=US -Duser.language=en -Dsun.java2d.pmoffscreen=false -Dsun.java2d.xrender=true -Dsun.java2d.d3d=false -Xdock:name="Ghidra" -Dvisualvm.display.name=Ghidra -Dpython.console.encoding=UTF-8 --add-opens java.base/java.lang=ALL-UNNAMED --add-opens java.base/java.util=ALL-UNNAMED --add-opens java.base/java.net=ALL-UNNAMED --add-opens java.desktop/sun.awt.image=ALL-UNNAMED --add-opens java.base/sun.security.x509=ALL-UNNAMED --add-opens java.base/sun.security.util=ALL-UNNAMED --add-opens java.desktop/sun.awt.X11=ALL-UNNAMED"/>
|
<stringAttribute key="org.eclipse.jdt.launching.VM_ARGUMENTS" value="-XX:+IgnoreUnrecognizedVMOptions -Djava.system.class.loader=ghidra.GhidraClassLoader -Xshare:off -Dfile.encoding=UTF8 -Duser.country=US -Duser.language=en -Dsun.java2d.pmoffscreen=false -Dsun.java2d.xrender=true -Dsun.java2d.d3d=false -Xdock:name="Ghidra" -Dvisualvm.display.name=Ghidra -Dpython.console.encoding=UTF-8 --add-opens java.base/java.lang=ALL-UNNAMED --add-opens java.base/java.util=ALL-UNNAMED --add-opens java.base/java.net=ALL-UNNAMED --add-opens java.desktop/sun.awt.image=ALL-UNNAMED --add-opens java.desktop/sun.awt.X11=ALL-UNNAMED"/>
|
||||||
</launchConfiguration>
|
</launchConfiguration>
|
||||||
|
|
|
@ -9,4 +9,4 @@ MODULE FILE LICENSE: lib/sevenzipjbinding-16.02-2.01.jar LGPL 2.1
|
||||||
MODULE FILE LICENSE: lib/sevenzipjbinding-all-platforms-16.02-2.01.jar LGPL 2.1
|
MODULE FILE LICENSE: lib/sevenzipjbinding-all-platforms-16.02-2.01.jar LGPL 2.1
|
||||||
MODULE FILE LICENSE: lib/AXMLPrinter2.jar Apache License 2.0
|
MODULE FILE LICENSE: lib/AXMLPrinter2.jar Apache License 2.0
|
||||||
MODULE FILE LICENSE: lib/util-1.4.0.jar BSD
|
MODULE FILE LICENSE: lib/util-1.4.0.jar BSD
|
||||||
MODULE FILE LICENSE: lib/bcprov-jdk15on-1.68.jar Bouncy Castle License
|
|
||||||
|
|
|
@ -33,7 +33,6 @@ dependencies {
|
||||||
api ':dex-translator:2.0'
|
api ':dex-translator:2.0'
|
||||||
|
|
||||||
api 'org.ow2.asm:asm-debug-all:4.1'
|
api 'org.ow2.asm:asm-debug-all:4.1'
|
||||||
api 'org.bouncycastle:bcprov-jdk15on:1.68'
|
|
||||||
|
|
||||||
api 'org.smali:baksmali:1.4.0' // TODO: upgrade to 2.2.6
|
api 'org.smali:baksmali:1.4.0' // TODO: upgrade to 2.2.6
|
||||||
api 'org.smali:dexlib:1.4.0'
|
api 'org.smali:dexlib:1.4.0'
|
||||||
|
|
|
@ -35,10 +35,6 @@ dependencies {
|
||||||
runGhidraServer project
|
runGhidraServer project
|
||||||
}
|
}
|
||||||
|
|
||||||
addExports([
|
|
||||||
'java.rmi/sun.rmi.transport.tcp=ALL-UNNAMED'
|
|
||||||
])
|
|
||||||
|
|
||||||
CopySpec yajswCopySpec = copySpec {
|
CopySpec yajswCopySpec = copySpec {
|
||||||
File depsFile = file("${DEPS_DIR}/GhidraServer/${yajswRelease}.zip")
|
File depsFile = file("${DEPS_DIR}/GhidraServer/${yajswRelease}.zip")
|
||||||
File binRepoFile = file("${BIN_REPO}/Ghidra/Features/GhidraServer/${yajswRelease}.zip")
|
File binRepoFile = file("${BIN_REPO}/Ghidra/Features/GhidraServer/${yajswRelease}.zip")
|
||||||
|
|
|
@ -18,6 +18,7 @@ package ghidra.server;
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.net.UnknownHostException;
|
import java.net.UnknownHostException;
|
||||||
|
import java.rmi.server.RemoteServer;
|
||||||
import java.rmi.server.ServerNotActiveException;
|
import java.rmi.server.ServerNotActiveException;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
|
||||||
|
@ -391,7 +392,7 @@ public class RepositoryManager {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
host = sun.rmi.transport.tcp.TCPTransport.getClientHost();
|
host = RemoteServer.getClientHost();
|
||||||
try {
|
try {
|
||||||
host = InetNameLookup.getCanonicalHostName(host);
|
host = InetNameLookup.getCanonicalHostName(host);
|
||||||
}
|
}
|
||||||
|
|
|
@ -139,7 +139,7 @@ public class PKIAuthenticationModule implements AuthenticationModule {
|
||||||
}
|
}
|
||||||
|
|
||||||
ApplicationKeyManagerUtils.validateClient(certChain,
|
ApplicationKeyManagerUtils.validateClient(certChain,
|
||||||
ApplicationKeyManagerUtils.DEFAULT_AUTH_TYPE);
|
ApplicationKeyManagerUtils.RSA_TYPE);
|
||||||
|
|
||||||
byte[] sigBytes = sigCb.getSignature();
|
byte[] sigBytes = sigCb.getSignature();
|
||||||
if (sigBytes != null) {
|
if (sigBytes != null) {
|
||||||
|
|
|
@ -8,3 +8,6 @@ MODULE FILE LICENSE: lib/commons-lang3-3.9.jar Apache License 2.0
|
||||||
MODULE FILE LICENSE: lib/commons-io-2.6.jar Apache License 2.0
|
MODULE FILE LICENSE: lib/commons-io-2.6.jar Apache License 2.0
|
||||||
MODULE FILE LICENSE: lib/commons-text-1.6.jar Apache License 2.0
|
MODULE FILE LICENSE: lib/commons-text-1.6.jar Apache License 2.0
|
||||||
MODULE FILE LICENSE: lib/gson-2.8.6.jar Apache License 2.0
|
MODULE FILE LICENSE: lib/gson-2.8.6.jar Apache License 2.0
|
||||||
|
MODULE FILE LICENSE: lib/bcpkix-jdk15on-1.69.jar Bouncy Castle License
|
||||||
|
MODULE FILE LICENSE: lib/bcprov-jdk15on-1.69.jar Bouncy Castle License
|
||||||
|
MODULE FILE LICENSE: lib/bcutil-jdk15on-1.69.jar Bouncy Castle License
|
||||||
|
|
|
@ -36,14 +36,14 @@ dependencies {
|
||||||
api "org.apache.commons:commons-text:1.6"
|
api "org.apache.commons:commons-text:1.6"
|
||||||
api "commons-io:commons-io:2.6"
|
api "commons-io:commons-io:2.6"
|
||||||
api "com.google.code.gson:gson:2.8.6"
|
api "com.google.code.gson:gson:2.8.6"
|
||||||
|
api 'org.bouncycastle:bcpkix-jdk15on:1.69' // requires bcutil and bcprov
|
||||||
|
api 'org.bouncycastle:bcprov-jdk15on:1.69'
|
||||||
|
api 'org.bouncycastle:bcutil-jdk15on:1.69'
|
||||||
|
|
||||||
compileOnly "junit:junit:4.12"
|
compileOnly "junit:junit:4.12"
|
||||||
}
|
}
|
||||||
|
|
||||||
ext.addExports([
|
ext.addExports([
|
||||||
'java.base/sun.security.x509=ALL-UNNAMED',
|
|
||||||
'java.base/sun.security.provider=ALL-UNNAMED',
|
|
||||||
'java.base/sun.security.util=ALL-UNNAMED',
|
|
||||||
'java.desktop/sun.awt=ALL-UNNAMED'
|
'java.desktop/sun.awt=ALL-UNNAMED'
|
||||||
])
|
])
|
||||||
|
|
||||||
|
|
|
@ -15,8 +15,7 @@
|
||||||
*/
|
*/
|
||||||
package ghidra.net;
|
package ghidra.net;
|
||||||
|
|
||||||
import java.io.FileNotFoundException;
|
import java.io.*;
|
||||||
import java.io.IOException;
|
|
||||||
import java.net.Socket;
|
import java.net.Socket;
|
||||||
import java.security.*;
|
import java.security.*;
|
||||||
import java.security.cert.CertificateException;
|
import java.security.cert.CertificateException;
|
||||||
|
@ -549,8 +548,9 @@ public class ApplicationKeyManagerFactory {
|
||||||
Msg.info(this, "Using self-signed certificate: " + defaultIdentity.getName());
|
Msg.info(this, "Using self-signed certificate: " + defaultIdentity.getName());
|
||||||
char[] pwd = DEFAULT_PASSWORD.toCharArray();
|
char[] pwd = DEFAULT_PASSWORD.toCharArray();
|
||||||
KeyStore selfSignedKeyStore =
|
KeyStore selfSignedKeyStore =
|
||||||
ApplicationKeyManagerUtils.createKeyStore(null, "JKS", pwd, "defaultSigKey",
|
ApplicationKeyManagerUtils.createKeyStore("defaultSigKey",
|
||||||
null, defaultIdentity.getName(), null, SELF_SIGNED_DURATION_DAYS);
|
defaultIdentity.getName(), SELF_SIGNED_DURATION_DAYS, null,
|
||||||
|
new File(newKeystorePath), "JKS", pwd);
|
||||||
keystoreData = new ProtectedKeyStoreData(selfSignedKeyStore, pwd);
|
keystoreData = new ProtectedKeyStoreData(selfSignedKeyStore, pwd);
|
||||||
isSelfSigned = true;
|
isSelfSigned = true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,8 +16,9 @@
|
||||||
package ghidra.net;
|
package ghidra.net;
|
||||||
|
|
||||||
import java.io.*;
|
import java.io.*;
|
||||||
|
import java.math.BigInteger;
|
||||||
import java.security.*;
|
import java.security.*;
|
||||||
import java.security.KeyStore.PrivateKeyEntry;
|
import java.security.KeyStore.*;
|
||||||
import java.security.cert.*;
|
import java.security.cert.*;
|
||||||
import java.security.cert.Certificate;
|
import java.security.cert.Certificate;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
@ -26,10 +27,19 @@ import javax.net.ssl.*;
|
||||||
import javax.security.auth.DestroyFailedException;
|
import javax.security.auth.DestroyFailedException;
|
||||||
import javax.security.auth.x500.X500Principal;
|
import javax.security.auth.x500.X500Principal;
|
||||||
|
|
||||||
|
import org.bouncycastle.asn1.x500.X500Name;
|
||||||
|
import org.bouncycastle.asn1.x500.style.RFC4519Style;
|
||||||
|
import org.bouncycastle.asn1.x509.*;
|
||||||
|
import org.bouncycastle.asn1.x509.Extension;
|
||||||
|
import org.bouncycastle.cert.X509v3CertificateBuilder;
|
||||||
|
import org.bouncycastle.cert.jcajce.JcaX509CertificateConverter;
|
||||||
|
import org.bouncycastle.operator.ContentSigner;
|
||||||
|
import org.bouncycastle.operator.OperatorException;
|
||||||
|
import org.bouncycastle.operator.jcajce.JcaContentSignerBuilder;
|
||||||
|
|
||||||
import generic.random.SecureRandomFactory;
|
import generic.random.SecureRandomFactory;
|
||||||
import ghidra.util.Msg;
|
import ghidra.util.Msg;
|
||||||
import sun.security.provider.X509Factory;
|
import ghidra.util.exception.AssertException;
|
||||||
import sun.security.x509.*;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* <code>ApplicationKeyManagerUtils</code> provides public methods for utilizing
|
* <code>ApplicationKeyManagerUtils</code> provides public methods for utilizing
|
||||||
|
@ -37,20 +47,34 @@ import sun.security.x509.*;
|
||||||
* (i.e., CA certificates), token signing and validation, and the ability to
|
* (i.e., CA certificates), token signing and validation, and the ability to
|
||||||
* generate keystores for testing or when a self-signed certificate will
|
* generate keystores for testing or when a self-signed certificate will
|
||||||
* suffice.
|
* suffice.
|
||||||
* <p>
|
|
||||||
* <b>NOTE:</b> This class makes direct use of classes within the
|
|
||||||
* <code>sun.security.x509</code> package thus breaking portability. While this is
|
|
||||||
* not preferred, the ability to generate X.509 certificates and keystores
|
|
||||||
* appears to be absent from the standard java/javax packages.
|
|
||||||
*/
|
*/
|
||||||
public class ApplicationKeyManagerUtils {
|
public class ApplicationKeyManagerUtils {
|
||||||
|
|
||||||
public static final String DEFAULT_SIGNING_ALGORITHM = "SHA1withRSA";
|
public static final String RSA_TYPE = "RSA";
|
||||||
|
|
||||||
public static final String DEFAULT_AUTH_TYPE = "RSA";
|
private static final int KEY_SIZE = 4096;
|
||||||
|
|
||||||
|
private static final String SIGNING_ALGORITHM = "SHA512withRSA";
|
||||||
|
|
||||||
private static final int MILLISECONDS_PER_DAY = 24 * 60 * 60 * 1000;
|
private static final int MILLISECONDS_PER_DAY = 24 * 60 * 60 * 1000;
|
||||||
|
|
||||||
|
public static final String BEGIN_CERT = "-----BEGIN CERTIFICATE-----";
|
||||||
|
public static final String END_CERT = "-----END CERTIFICATE-----";
|
||||||
|
|
||||||
|
static {
|
||||||
|
/**
|
||||||
|
* Bouncy Castle uses its BCStyle for X500Names which reverses Distingushed Name ordering.
|
||||||
|
* This is resolved by setting the default to RFC4519 style to ensure compatibility with
|
||||||
|
* Java's internal implementation of X500Name.
|
||||||
|
* <p>
|
||||||
|
* Note that this could become an issue if this static default is adjusted elsewhere.
|
||||||
|
* It may be neccessary to set this at the start of all methods which rely on any of the
|
||||||
|
* BC code for X500 certificate processing.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
X500Name.setDefaultStyle(RFC4519Style.INSTANCE);
|
||||||
|
}
|
||||||
|
|
||||||
private ApplicationKeyManagerUtils() {
|
private ApplicationKeyManagerUtils() {
|
||||||
// no instantiation - static methods only
|
// no instantiation - static methods only
|
||||||
}
|
}
|
||||||
|
@ -61,9 +85,9 @@ public class ApplicationKeyManagerUtils {
|
||||||
* @param authorities trusted certificate authorities
|
* @param authorities trusted certificate authorities
|
||||||
* @param token token byte array
|
* @param token token byte array
|
||||||
* @return signed token object
|
* @return signed token object
|
||||||
* @throws NoSuchAlgorithmException
|
* @throws NoSuchAlgorithmException algorithym associated within signing certificate not found
|
||||||
* @throws SignatureException
|
* @throws SignatureException failed to generate SignedToken
|
||||||
* @throws CertificateException
|
* @throws CertificateException error associated with signing certificate
|
||||||
*/
|
*/
|
||||||
public static SignedToken getSignedToken(Principal[] authorities, byte[] token)
|
public static SignedToken getSignedToken(Principal[] authorities, byte[] token)
|
||||||
throws NoSuchAlgorithmException, SignatureException, CertificateException {
|
throws NoSuchAlgorithmException, SignatureException, CertificateException {
|
||||||
|
@ -78,7 +102,7 @@ public class ApplicationKeyManagerUtils {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
X509KeyManager x509KeyManager = (X509KeyManager) keyManager;
|
X509KeyManager x509KeyManager = (X509KeyManager) keyManager;
|
||||||
String alias = x509KeyManager.chooseClientAlias(new String[] { DEFAULT_AUTH_TYPE },
|
String alias = x509KeyManager.chooseClientAlias(new String[] { RSA_TYPE },
|
||||||
authorities, null);
|
authorities, null);
|
||||||
if (alias != null) {
|
if (alias != null) {
|
||||||
privateKey = x509KeyManager.getPrivateKey(alias);
|
privateKey = x509KeyManager.getPrivateKey(alias);
|
||||||
|
@ -131,9 +155,9 @@ public class ApplicationKeyManagerUtils {
|
||||||
* @param token byte array token
|
* @param token byte array token
|
||||||
* @param signature token signature
|
* @param signature token signature
|
||||||
* @return true if signature is my signature
|
* @return true if signature is my signature
|
||||||
* @throws NoSuchAlgorithmException
|
* @throws NoSuchAlgorithmException algorithym associated within signing certificate not found
|
||||||
* @throws SignatureException
|
* @throws SignatureException failed to generate SignedToken
|
||||||
* @throws CertificateException
|
* @throws CertificateException error associated with signing certificate
|
||||||
*/
|
*/
|
||||||
public static boolean isMySignature(Principal[] authorities, byte[] token, byte[] signature)
|
public static boolean isMySignature(Principal[] authorities, byte[] token, byte[] signature)
|
||||||
throws NoSuchAlgorithmException, SignatureException, CertificateException {
|
throws NoSuchAlgorithmException, SignatureException, CertificateException {
|
||||||
|
@ -144,7 +168,9 @@ public class ApplicationKeyManagerUtils {
|
||||||
/**
|
/**
|
||||||
* Returns a list of trusted issuers (i.e., CA certificates) as established
|
* Returns a list of trusted issuers (i.e., CA certificates) as established
|
||||||
* by the {@link ApplicationTrustManagerFactory}.
|
* by the {@link ApplicationTrustManagerFactory}.
|
||||||
* @throws CertificateException
|
* @return array of trusted Certificate Authorities
|
||||||
|
* @throws CertificateException if failed to properly initialize trust manager
|
||||||
|
* due to CA certificate error(s).
|
||||||
*/
|
*/
|
||||||
public static X500Principal[] getTrustedIssuers() throws CertificateException {
|
public static X500Principal[] getTrustedIssuers() throws CertificateException {
|
||||||
|
|
||||||
|
@ -188,7 +214,7 @@ public class ApplicationKeyManagerUtils {
|
||||||
* trusted based upon the active trust managers.
|
* trusted based upon the active trust managers.
|
||||||
* @param certChain X509 certificate chain
|
* @param certChain X509 certificate chain
|
||||||
* @param authType authentication type (i.e., "RSA")
|
* @param authType authentication type (i.e., "RSA")
|
||||||
* @throws CertificateException
|
* @throws CertificateException if certificate validation fails
|
||||||
*/
|
*/
|
||||||
public static void validateClient(X509Certificate[] certChain, String authType)
|
public static void validateClient(X509Certificate[] certChain, String authType)
|
||||||
throws CertificateException {
|
throws CertificateException {
|
||||||
|
@ -222,52 +248,144 @@ public class ApplicationKeyManagerUtils {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Pack order list of certs to create a certificate chain array
|
* Pack ordered list of certs to create a certificate chain array
|
||||||
* @param certs certificates which makeup the ordered certificate chain. Null
|
* @param cert primary certificate
|
||||||
* certificate elements will be skipped.
|
* @param caCerts CA certificate chain.
|
||||||
* @return array of certificates
|
* @return ordered certificate chain
|
||||||
*/
|
*/
|
||||||
private static Certificate[] getCertificateChain(Certificate... certs) {
|
private static Certificate[] makeCertificateChain(Certificate cert, Certificate... caCerts) {
|
||||||
List<Certificate> list = new ArrayList<>();
|
Certificate[] chain = new Certificate[caCerts.length + 1];
|
||||||
for (Certificate cert : certs) {
|
chain[0] = cert;
|
||||||
if (cert != null) {
|
System.arraycopy(caCerts, 0, chain, 1, caCerts.length);
|
||||||
list.add(cert);
|
return chain;
|
||||||
}
|
|
||||||
}
|
|
||||||
Certificate[] chain = new Certificate[list.size()];
|
|
||||||
return list.toArray(chain);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Generate self-signed PKI X509 keystore containing both a signing key/cert
|
* Export X.509 certificates to the specified outFile.
|
||||||
* and an encrypting key/cert. Default certificte extension specifies key usage of
|
* @param certificates certificates to be stored
|
||||||
* Signing which is appropriate for SSL DHE or ECDHE cipher suites.
|
* @param outFile output file
|
||||||
* @param keyFile keystore file or null if not to be stored
|
* @throws IOException if error occurs writing to outFile
|
||||||
* @param keystoreType keystore type (e.g., "JKS", "PKCS12")
|
* @throws CertificateEncodingException if error occurs while encoding certificate data
|
||||||
* @param protectedPassphrase passphrase for protecting key and keystore
|
|
||||||
* @param alias for key/cert
|
|
||||||
* @param certExtensions specifies certificate extensions to be set or null for default
|
|
||||||
* key usage extension. Only a single alias may be specified when
|
|
||||||
* this argument is not null.
|
|
||||||
* @param dn distinguished name for principal key holder
|
|
||||||
* @param caSignerKeyEntry certificate issuer/authority (CA) private key entry or null
|
|
||||||
* for self-signed
|
|
||||||
* @param durationDays number of days from now when certificate shall expire
|
|
||||||
* @return newly generated keystore
|
|
||||||
* @throws KeyStoreException error occurred generating keystore
|
|
||||||
*/
|
*/
|
||||||
public static KeyStore createKeyStore(File keyFile, String keystoreType,
|
public static void exportX509Certificates(Certificate[] certificates, File outFile)
|
||||||
char[] protectedPassphrase, String alias, CertificateExtensions certExtensions,
|
throws IOException, CertificateEncodingException {
|
||||||
String dn, PrivateKeyEntry caSignerKeyEntry, int durationDays)
|
|
||||||
|
try (FileOutputStream fout = new FileOutputStream(outFile);
|
||||||
|
PrintWriter writer = new PrintWriter(fout)) {
|
||||||
|
for (Certificate certificate : certificates) {
|
||||||
|
if (!(certificate instanceof X509Certificate)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
writer.println(BEGIN_CERT);
|
||||||
|
String base64 = Base64.getEncoder().encodeToString(certificate.getEncoded());
|
||||||
|
while (base64.length() != 0) {
|
||||||
|
int endIndex = Math.min(44, base64.length());
|
||||||
|
String line = base64.substring(0, endIndex);
|
||||||
|
writer.println(line);
|
||||||
|
base64 = base64.substring(endIndex);
|
||||||
|
}
|
||||||
|
writer.println(END_CERT);
|
||||||
|
writer.println();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Generate a new {@link X509Certificate} with RSA {@link KeyPair} and create/update a {@link KeyStore}
|
||||||
|
* optionally backed by a keyFile.
|
||||||
|
* @param alias entry alias with keystore
|
||||||
|
* @param dn distinguished name (e.g., "CN=Ghidra Test, O=Ghidra, OU=Test, C=US" )
|
||||||
|
* @param durationDays number of days which generated certificate should remain valid
|
||||||
|
* @param caEntry optional CA private key entry. If null, a self-signed CA certificate will be generated.
|
||||||
|
* @param keyFile optional file to load/store resulting {@link KeyStore} (may be null)
|
||||||
|
* @param keystoreType support keystore type (e.g., "JKS", "PKCS12")
|
||||||
|
* @param protectedPassphrase key and keystore protection password
|
||||||
|
* @return keystore containing newly generated certification with key pair
|
||||||
|
* @throws KeyStoreException if error occurs while updating keystore
|
||||||
|
*/
|
||||||
|
public static final KeyStore createKeyStore(String alias, String dn, int durationDays,
|
||||||
|
PrivateKeyEntry caEntry, File keyFile, String keystoreType, char[] protectedPassphrase)
|
||||||
throws KeyStoreException {
|
throws KeyStoreException {
|
||||||
|
|
||||||
KeyStore keyStore;
|
PasswordProtection pp = new PasswordProtection(protectedPassphrase);
|
||||||
try {
|
|
||||||
keyStore = KeyStore.getInstance(keystoreType);
|
|
||||||
keyStore.load(null);
|
|
||||||
|
|
||||||
addNewKeyPair(keyStore, alias, dn, certExtensions, protectedPassphrase,
|
LoadStoreParameter loadStoreParameter = null;
|
||||||
caSignerKeyEntry, durationDays);
|
if (keyFile != null && keyFile.exists()) {
|
||||||
|
loadStoreParameter = new LoadStoreParameter() {
|
||||||
|
@Override
|
||||||
|
public ProtectionParameter getProtectionParameter() {
|
||||||
|
return pp;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
KeyStore keyStore = KeyStore.getInstance(keystoreType);
|
||||||
|
keyStore.load(loadStoreParameter);
|
||||||
|
|
||||||
|
SecureRandom random = SecureRandomFactory.getSecureRandom();
|
||||||
|
|
||||||
|
KeyPairGenerator rsa = KeyPairGenerator.getInstance(RSA_TYPE);
|
||||||
|
rsa.initialize(KEY_SIZE);
|
||||||
|
|
||||||
|
KeyPair keyPair = rsa.generateKeyPair();
|
||||||
|
PrivateKey issuerKey = keyPair.getPrivate();
|
||||||
|
|
||||||
|
byte[] encodedPublicKey = keyPair.getPublic().getEncoded();
|
||||||
|
SubjectPublicKeyInfo bcPk = SubjectPublicKeyInfo.getInstance(encodedPublicKey);
|
||||||
|
|
||||||
|
X500Name x500Name = new X500Name(dn);
|
||||||
|
X500Name caX500Name = x500Name; // self-signed CA if caEntry is null
|
||||||
|
KeyUsage keyUsage = new KeyUsage(
|
||||||
|
KeyUsage.digitalSignature | KeyUsage.keyEncipherment | KeyUsage.keyCertSign);
|
||||||
|
if (caEntry != null) {
|
||||||
|
// derive CA X500Name from caEntry
|
||||||
|
Certificate caCert = caEntry.getCertificate();
|
||||||
|
if (!(caCert instanceof X509Certificate)) {
|
||||||
|
throw new CertificateException(
|
||||||
|
"Unsupported certificate type: " + caCert.getType());
|
||||||
|
}
|
||||||
|
X509Certificate caX509Cert = (X509Certificate) caCert;
|
||||||
|
caX500Name =
|
||||||
|
new X500Name(caX509Cert.getSubjectDN().getName());
|
||||||
|
keyUsage = new KeyUsage(
|
||||||
|
KeyUsage.digitalSignature | KeyUsage.keyEncipherment);
|
||||||
|
issuerKey = caEntry.getPrivateKey();
|
||||||
|
}
|
||||||
|
Date notBefore = new Date();
|
||||||
|
long durationMs = (long) durationDays * MILLISECONDS_PER_DAY;
|
||||||
|
Date notAfter = new Date(notBefore.getTime() + durationMs);
|
||||||
|
BigInteger serialNumber = new BigInteger(128, random);
|
||||||
|
|
||||||
|
// JcaX509ExtensionUtils x509Utils = new JcaX509ExtensionUtils();
|
||||||
|
|
||||||
|
X509v3CertificateBuilder certificateBuilder = new X509v3CertificateBuilder(caX500Name,
|
||||||
|
serialNumber, notBefore, notAfter, x500Name, bcPk);
|
||||||
|
certificateBuilder
|
||||||
|
// .addExtension(Extension.subjectKeyIdentifier, true, x509Utils.createSubjectKeyIdentifier(bcPk))
|
||||||
|
.addExtension(Extension.keyUsage, true, keyUsage);
|
||||||
|
|
||||||
|
if (caEntry == null) {
|
||||||
|
certificateBuilder
|
||||||
|
.addExtension(Extension.basicConstraints, true, new BasicConstraints(1));
|
||||||
|
// .addExtension(Extension.authorityKeyIdentifier, true, x509Utils.createAuthorityKeyIdentifier(bcPk));
|
||||||
|
}
|
||||||
|
|
||||||
|
ContentSigner contentSigner =
|
||||||
|
new JcaContentSignerBuilder(SIGNING_ALGORITHM).build(issuerKey);
|
||||||
|
|
||||||
|
X509Certificate certificate = new JcaX509CertificateConverter()
|
||||||
|
.getCertificate(certificateBuilder.build(contentSigner));
|
||||||
|
|
||||||
|
Certificate[] chain;
|
||||||
|
if (caEntry == null) {
|
||||||
|
chain = new Certificate[] { certificate };
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
chain = makeCertificateChain(certificate, caEntry.getCertificateChain());
|
||||||
|
}
|
||||||
|
|
||||||
|
keyStore.setKeyEntry(alias, keyPair.getPrivate(), protectedPassphrase, chain);
|
||||||
|
|
||||||
if (keyFile != null) {
|
if (keyFile != null) {
|
||||||
FileOutputStream out = new FileOutputStream(keyFile);
|
FileOutputStream out = new FileOutputStream(keyFile);
|
||||||
|
@ -288,155 +406,57 @@ public class ApplicationKeyManagerUtils {
|
||||||
keyFile.setWritable(false);
|
keyFile.setWritable(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
Msg.debug(ApplicationKeyManagerUtils.class,
|
||||||
catch (GeneralSecurityException | IOException e) {
|
"Certificate Generated (" + alias + "): " + dn);
|
||||||
throw new KeyStoreException("failed to generate/store certificate (" + dn + ")", e);
|
|
||||||
}
|
|
||||||
|
|
||||||
return keyStore;
|
return keyStore;
|
||||||
}
|
}
|
||||||
|
catch (GeneralSecurityException | OperatorException | IOException e) {
|
||||||
/**
|
throw new KeyStoreException("Failed to generate/store certificate (" + dn + ")", e);
|
||||||
* Generate a new keypair/certificate and add it to the specified keyStore.
|
|
||||||
* Default certificate extension specifies key usage of digital-signature which is appropriate
|
|
||||||
* for SSL (i.e., DHE or ECDHE cipher suites) and other authentication uses.
|
|
||||||
* @param keyStore key store
|
|
||||||
* @param generator key pair generator
|
|
||||||
* @param alias keypair/certificate alias
|
|
||||||
* @param dn principal distinguished name
|
|
||||||
* @param certExtensions certificate extensions with key usage
|
|
||||||
* @param protectedPassphrase key protection passphrase
|
|
||||||
* @param caSignerKeyEntry certificate issuer/authority (CA) private key
|
|
||||||
* entry or null for self-signed
|
|
||||||
* @param durationDays number of days from now when certificate shall expire
|
|
||||||
* @throws KeyStoreException error occurred generating keystore
|
|
||||||
*/
|
|
||||||
private static void addNewKeyPair(KeyStore keyStore, String alias, String dn,
|
|
||||||
CertificateExtensions certExtensions, char[] protectedPassphrase,
|
|
||||||
PrivateKeyEntry caSignerKeyEntry, int durationDays)
|
|
||||||
throws GeneralSecurityException, IOException {
|
|
||||||
|
|
||||||
X509Certificate signerCert = null;
|
|
||||||
if (caSignerKeyEntry != null) {
|
|
||||||
Certificate cert = caSignerKeyEntry.getCertificate();
|
|
||||||
if (!(cert instanceof X509Certificate)) {
|
|
||||||
throw new IllegalArgumentException(
|
|
||||||
"Unsupported caSignerKeyEntry - X509 certificate required");
|
|
||||||
}
|
|
||||||
signerCert = (X509Certificate) cert;
|
|
||||||
}
|
|
||||||
|
|
||||||
KeyPairGenerator generator = KeyPairGenerator.getInstance(DEFAULT_AUTH_TYPE);
|
|
||||||
SecureRandom random = SecureRandomFactory.getSecureRandom();
|
|
||||||
generator.initialize(2048, random);
|
|
||||||
|
|
||||||
X509CertInfo certInfo = new X509CertInfo();
|
|
||||||
certInfo.set(X509CertInfo.VERSION, new CertificateVersion(CertificateVersion.V3));
|
|
||||||
|
|
||||||
certInfo.set(X509CertInfo.ALGORITHM_ID,
|
|
||||||
new CertificateAlgorithmId(AlgorithmId.get(DEFAULT_SIGNING_ALGORITHM)));
|
|
||||||
|
|
||||||
certInfo.set(X509CertInfo.SUBJECT + "." + X509CertInfo.DN_NAME, new X500Name(dn)); // requires Java 1.8
|
|
||||||
// certInfo.set(X509CertInfo.SUBJECT, new CertificateSubjectName(new X500Name(dn))); // requires Java 1.7
|
|
||||||
|
|
||||||
Date now = new Date(System.currentTimeMillis());
|
|
||||||
long durationMs = (long) durationDays * (long) MILLISECONDS_PER_DAY;
|
|
||||||
Date end = new Date(now.getTime() + durationMs);
|
|
||||||
certInfo.set(X509CertInfo.VALIDITY, new CertificateValidity(now, end));
|
|
||||||
String issuer = signerCert != null ? signerCert.getSubjectDN().getName() : dn;
|
|
||||||
|
|
||||||
certInfo.set(X509CertInfo.ISSUER + "." + X509CertInfo.DN_NAME, new X500Name(issuer)); // requires Java 1.8
|
|
||||||
// certInfo.set(X509CertInfo.ISSUER, new CertificateIssuerName(new X500Name(issuer))); // requires Java 1.7
|
|
||||||
|
|
||||||
certInfo.set(X509CertInfo.SERIAL_NUMBER,
|
|
||||||
new CertificateSerialNumber(random.nextInt() & 0x7fffffff));
|
|
||||||
KeyPair keyPair = generator.generateKeyPair();
|
|
||||||
certInfo.set(X509CertInfo.KEY, new CertificateX509Key(keyPair.getPublic()));
|
|
||||||
|
|
||||||
if (certExtensions == null) {
|
|
||||||
// If no extensions specified, set default key usage to digital-signature
|
|
||||||
// which is appropriate for SSL and other authentication uses
|
|
||||||
certExtensions = new CertificateExtensions();
|
|
||||||
KeyUsageExtension keyUsage = new KeyUsageExtension();
|
|
||||||
keyUsage.set(KeyUsageExtension.DIGITAL_SIGNATURE, true);
|
|
||||||
certExtensions.set(PKIXExtensions.KeyUsage_Id.toString(), keyUsage);
|
|
||||||
}
|
|
||||||
certInfo.set(X509CertInfo.EXTENSIONS, certExtensions);
|
|
||||||
|
|
||||||
X509CertImpl cert = new X509CertImpl(certInfo);
|
|
||||||
PrivateKey caSignerKey =
|
|
||||||
caSignerKeyEntry != null ? caSignerKeyEntry.getPrivateKey() : keyPair.getPrivate();
|
|
||||||
cert.sign(caSignerKey, DEFAULT_SIGNING_ALGORITHM);
|
|
||||||
keyStore.setKeyEntry(alias, keyPair.getPrivate(), protectedPassphrase,
|
|
||||||
getCertificateChain(cert, signerCert));
|
|
||||||
Msg.debug(ApplicationKeyManagerUtils.class,
|
|
||||||
"Certificate Generated (" + alias + "): " + cert.getSubjectDN());
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Export all X.509 certificates contained within keystore to the specified outFile.
|
|
||||||
* @param keystore
|
|
||||||
* @param outFile output file
|
|
||||||
* @throws IOException
|
|
||||||
* @throws KeyStoreException
|
|
||||||
* @throws CertificateEncodingException
|
|
||||||
*/
|
|
||||||
public static void exportX509Certificates(KeyStore keystore, File outFile)
|
|
||||||
throws IOException, KeyStoreException, CertificateEncodingException {
|
|
||||||
FileOutputStream fout = new FileOutputStream(outFile);
|
|
||||||
PrintWriter writer = new PrintWriter(fout);
|
|
||||||
Enumeration<String> aliases = keystore.aliases();
|
|
||||||
while (aliases.hasMoreElements()) {
|
|
||||||
Certificate certificate = keystore.getCertificate(aliases.nextElement());
|
|
||||||
if (!(certificate instanceof X509Certificate)) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
writer.println(X509Factory.BEGIN_CERT);
|
|
||||||
String base64 = Base64.getEncoder().encodeToString(certificate.getEncoded());
|
|
||||||
while (base64.length() != 0) {
|
|
||||||
int endIndex = Math.min(44, base64.length());
|
|
||||||
String line = base64.substring(0, endIndex);
|
|
||||||
writer.println(line);
|
|
||||||
base64 = base64.substring(endIndex);
|
|
||||||
}
|
|
||||||
writer.println(X509Factory.END_CERT);
|
|
||||||
writer.println();
|
|
||||||
}
|
|
||||||
writer.flush();
|
|
||||||
try {
|
|
||||||
fout.getFD().sync();
|
|
||||||
}
|
|
||||||
catch (SyncFailedException e) {
|
|
||||||
// ignore
|
|
||||||
}
|
|
||||||
writer.close();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Export all X.509 certificates contained within keystore to the specified outFile.
|
|
||||||
* @param keystore
|
|
||||||
* @param outFile output file
|
|
||||||
* @param password keystore password
|
|
||||||
* @throws CertificateException
|
|
||||||
* @throws NoSuchAlgorithmException
|
|
||||||
* @throws FileNotFoundException
|
|
||||||
* @throws KeyStoreException
|
|
||||||
* @throws CertificateEncodingException
|
|
||||||
*/
|
|
||||||
public static void exportKeystore(KeyStore keystore, File outFile, char[] password)
|
|
||||||
throws IOException, KeyStoreException, NoSuchAlgorithmException, CertificateException {
|
|
||||||
|
|
||||||
FileOutputStream out = new FileOutputStream(outFile);
|
|
||||||
try {
|
|
||||||
keystore.store(out, password);
|
|
||||||
out.flush();
|
|
||||||
out.getFD().sync();
|
|
||||||
}
|
|
||||||
catch (SyncFailedException e) {
|
|
||||||
// ignore
|
|
||||||
}
|
}
|
||||||
finally {
|
finally {
|
||||||
out.close();
|
try {
|
||||||
|
pp.destroy();
|
||||||
|
}
|
||||||
|
catch (DestroyFailedException e) {
|
||||||
|
throw new AssertException(e); // unexpected for simple password clearing
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Generate a new {@link X509Certificate} with RSA {@link KeyPair} and create/update a {@link KeyStore}
|
||||||
|
* optionally backed by a keyFile.
|
||||||
|
* @param alias entry alias with keystore
|
||||||
|
* @param dn distinguished name (e.g., "CN=Ghidra Test, O=Ghidra, OU=Test, C=US" )
|
||||||
|
* @param durationDays number of days which generated certificate should remain valid
|
||||||
|
* @param caEntry optional CA private key entry. If null, a self-signed CA certificate will be generated.
|
||||||
|
* @param keyFile optional file to load/store resulting {@link KeyStore} (may be null)
|
||||||
|
* @param keystoreType support keystore type (e.g., "JKS", "PKCS12")
|
||||||
|
* @param protectedPassphrase key and keystore protection password
|
||||||
|
* @return newly generated keystore entry with key pair
|
||||||
|
* @throws KeyStoreException if error occurs while updating keystore
|
||||||
|
*/
|
||||||
|
public static final PrivateKeyEntry createKeyEntry(String alias, String dn, int durationDays,
|
||||||
|
PrivateKeyEntry caEntry, File keyFile, String keystoreType, char[] protectedPassphrase)
|
||||||
|
throws KeyStoreException {
|
||||||
|
|
||||||
|
PasswordProtection pp = new PasswordProtection(protectedPassphrase);
|
||||||
|
try {
|
||||||
|
KeyStore keyStore = createKeyStore(alias, dn, durationDays, caEntry, keyFile,
|
||||||
|
keystoreType, protectedPassphrase);
|
||||||
|
return (PrivateKeyEntry) keyStore.getEntry(alias, pp);
|
||||||
|
}
|
||||||
|
catch (NoSuchAlgorithmException | UnrecoverableEntryException e) {
|
||||||
|
throw new KeyStoreException("Failed to generate/store certificate (" + dn + ")", e);
|
||||||
|
}
|
||||||
|
finally {
|
||||||
|
try {
|
||||||
|
pp.destroy();
|
||||||
|
}
|
||||||
|
catch (DestroyFailedException e) {
|
||||||
|
throw new AssertException(e); // unexpected for simple password clearing
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -70,13 +70,11 @@ public class ApplicationKeyManagerFactoryTest extends AbstractGenericTest {
|
||||||
@Before
|
@Before
|
||||||
public void setUp() throws Exception {
|
public void setUp() throws Exception {
|
||||||
|
|
||||||
KeyStore selfSignedKeyStore = ApplicationKeyManagerUtils.createKeyStore(null, "PKCS12",
|
|
||||||
TEST_PWD.toCharArray(), ALIAS, null, TEST_IDENTITY, null, 2);
|
|
||||||
|
|
||||||
keystoreFile = createTempFile("test-key", ".p12");
|
keystoreFile = createTempFile("test-key", ".p12");
|
||||||
keystoreFile.delete();
|
keystoreFile.delete();
|
||||||
ApplicationKeyManagerUtils.exportKeystore(selfSignedKeyStore, keystoreFile,
|
|
||||||
TEST_PWD.toCharArray());
|
ApplicationKeyManagerUtils.createKeyStore(ALIAS, TEST_IDENTITY, 2, null, keystoreFile,
|
||||||
|
"PKCS12", TEST_PWD.toCharArray());
|
||||||
|
|
||||||
ApplicationKeyManagerFactory.setKeyStorePasswordProvider(passwordProvider);
|
ApplicationKeyManagerFactory.setKeyStorePasswordProvider(passwordProvider);
|
||||||
}
|
}
|
||||||
|
|
|
@ -74,8 +74,6 @@ VMARGS=--add-opens java.base/java.lang=ALL-UNNAMED
|
||||||
VMARGS=--add-opens java.base/java.util=ALL-UNNAMED
|
VMARGS=--add-opens java.base/java.util=ALL-UNNAMED
|
||||||
VMARGS=--add-opens java.base/java.net=ALL-UNNAMED
|
VMARGS=--add-opens java.base/java.net=ALL-UNNAMED
|
||||||
VMARGS=--add-opens java.desktop/sun.awt.image=ALL-UNNAMED
|
VMARGS=--add-opens java.desktop/sun.awt.image=ALL-UNNAMED
|
||||||
VMARGS=--add-opens java.base/sun.security.x509=ALL-UNNAMED
|
|
||||||
VMARGS=--add-opens java.base/sun.security.util=ALL-UNNAMED
|
|
||||||
VMARGS_LINUX=--add-opens java.desktop/sun.awt.X11=ALL-UNNAMED
|
VMARGS_LINUX=--add-opens java.desktop/sun.awt.X11=ALL-UNNAMED
|
||||||
|
|
||||||
# Persistent cache directory used by the application. This directory will be used to store
|
# Persistent cache directory used by the application. This directory will be used to store
|
||||||
|
|
|
@ -66,8 +66,6 @@ dependencies {
|
||||||
// We export them to all "unnamed" modules, which are modules that don't define themselves
|
// We export them to all "unnamed" modules, which are modules that don't define themselves
|
||||||
// as a new Java 9 style module. Ghidra is currently using unnamed modules everywhere.
|
// as a new Java 9 style module. Ghidra is currently using unnamed modules everywhere.
|
||||||
ext.addExports([
|
ext.addExports([
|
||||||
'java.base/sun.security.x509=ALL-UNNAMED',
|
|
||||||
'java.base/sun.security.util=ALL-UNNAMED',
|
|
||||||
'java.desktop/sun.awt=ALL-UNNAMED',
|
'java.desktop/sun.awt=ALL-UNNAMED',
|
||||||
'java.desktop/sun.swing=ALL-UNNAMED',
|
'java.desktop/sun.swing=ALL-UNNAMED',
|
||||||
'java.desktop/sun.java2d=ALL-UNNAMED'
|
'java.desktop/sun.java2d=ALL-UNNAMED'
|
||||||
|
|
|
@ -19,8 +19,6 @@ import java.io.*;
|
||||||
import java.net.*;
|
import java.net.*;
|
||||||
import java.rmi.registry.LocateRegistry;
|
import java.rmi.registry.LocateRegistry;
|
||||||
import java.rmi.registry.Registry;
|
import java.rmi.registry.Registry;
|
||||||
import java.security.KeyStore;
|
|
||||||
import java.security.KeyStore.PasswordProtection;
|
|
||||||
import java.security.KeyStore.PrivateKeyEntry;
|
import java.security.KeyStore.PrivateKeyEntry;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.zip.ZipEntry;
|
import java.util.zip.ZipEntry;
|
||||||
|
@ -49,7 +47,6 @@ import ghidra.util.*;
|
||||||
import ghidra.util.exception.*;
|
import ghidra.util.exception.*;
|
||||||
import ghidra.util.task.TaskMonitor;
|
import ghidra.util.task.TaskMonitor;
|
||||||
import ghidra.util.timer.GTimer;
|
import ghidra.util.timer.GTimer;
|
||||||
import sun.security.x509.*;
|
|
||||||
import utilities.util.FileUtilities;
|
import utilities.util.FileUtilities;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -902,38 +899,23 @@ public class ServerTestUtil {
|
||||||
|
|
||||||
// Generate CA certificate and keystore
|
// Generate CA certificate and keystore
|
||||||
Msg.info(ServerTestUtil.class, "Generating self-signed CA cert: " + caPath);
|
Msg.info(ServerTestUtil.class, "Generating self-signed CA cert: " + caPath);
|
||||||
|
PrivateKeyEntry caEntry =
|
||||||
CertificateExtensions caCertExtensions = new CertificateExtensions();
|
ApplicationKeyManagerUtils.createKeyEntry("test-CA", TEST_PKI_CA_DN, 2, null, null,
|
||||||
BasicConstraintsExtension caBasicConstraints = new BasicConstraintsExtension(true, true, 1);
|
"PKCS12", ApplicationKeyManagerFactory.DEFAULT_PASSWORD.toCharArray());
|
||||||
caCertExtensions.set(PKIXExtensions.BasicConstraints_Id.toString(), caBasicConstraints);
|
ApplicationKeyManagerUtils.exportX509Certificates(caEntry.getCertificateChain(), caFile);
|
||||||
|
|
||||||
KeyUsageExtension caKeyUsage = new KeyUsageExtension();
|
|
||||||
caKeyUsage.set(KeyUsageExtension.KEY_CERTSIGN, true);
|
|
||||||
caCertExtensions.set(PKIXExtensions.KeyUsage_Id.toString(), caKeyUsage);
|
|
||||||
|
|
||||||
KeyStore caKeystore = ApplicationKeyManagerUtils.createKeyStore(null, "PKCS12",
|
|
||||||
ApplicationKeyManagerFactory.DEFAULT_PASSWORD.toCharArray(), "test-CA",
|
|
||||||
caCertExtensions, TEST_PKI_CA_DN, null, 2);
|
|
||||||
ApplicationKeyManagerUtils.exportX509Certificates(caKeystore, caFile);
|
|
||||||
|
|
||||||
PasswordProtection caPass =
|
|
||||||
new PasswordProtection(ApplicationKeyManagerFactory.DEFAULT_PASSWORD.toCharArray());
|
|
||||||
PrivateKeyEntry caPrivateKeyEntry =
|
|
||||||
(PrivateKeyEntry) caKeystore.getEntry("test-CA", caPass);
|
|
||||||
|
|
||||||
// Generate User/Client certificate and keystore
|
// Generate User/Client certificate and keystore
|
||||||
Msg.info(ServerTestUtil.class, "Generating test user key/cert (signed by test-CA, pwd: " +
|
Msg.info(ServerTestUtil.class, "Generating test user key/cert (signed by test-CA, pwd: " +
|
||||||
TEST_PKI_USER_PASSPHRASE + "): " + userKeystorePath);
|
TEST_PKI_USER_PASSPHRASE + "): " + userKeystorePath);
|
||||||
ApplicationKeyManagerUtils.createKeyStore(userKeystoreFile, "PKCS12",
|
ApplicationKeyManagerUtils.createKeyEntry("test-sig", TEST_PKI_USER_DN, 2, caEntry,
|
||||||
TEST_PKI_USER_PASSPHRASE.toCharArray(), "test-sig", null, TEST_PKI_USER_DN,
|
userKeystoreFile, "PKCS12", TEST_PKI_USER_PASSPHRASE.toCharArray());
|
||||||
caPrivateKeyEntry, 2);
|
|
||||||
|
|
||||||
// Generate Server certificate and keystore
|
// Generate Server certificate and keystore
|
||||||
Msg.info(ServerTestUtil.class, "Generating test server key/cert (signed by test-CA, pwd: " +
|
Msg.info(ServerTestUtil.class, "Generating test server key/cert (signed by test-CA, pwd: " +
|
||||||
TEST_PKI_SERVER_PASSPHRASE + "): " + serverKeystorePath);
|
TEST_PKI_SERVER_PASSPHRASE + "): " + serverKeystorePath);
|
||||||
ApplicationKeyManagerUtils.createKeyStore(serverKeystoreFile, "PKCS12",
|
|
||||||
TEST_PKI_SERVER_PASSPHRASE.toCharArray(), "test-sig", null, TEST_PKI_SERVER_DN,
|
ApplicationKeyManagerUtils.createKeyEntry("test-sig", TEST_PKI_SERVER_DN, 2, caEntry,
|
||||||
caPrivateKeyEntry, 2);
|
serverKeystoreFile, "PKCS12", TEST_PKI_SERVER_PASSPHRASE.toCharArray());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -135,10 +135,7 @@ task createJavadocs(type: Javadoc, description: 'Generate javadocs for all proje
|
||||||
|
|
||||||
// Some internal packages are not public and need to be exported.
|
// Some internal packages are not public and need to be exported.
|
||||||
options.addMultilineStringsOption("-add-exports").setValue(["java.desktop/sun.awt.image=ALL-UNNAMED",
|
options.addMultilineStringsOption("-add-exports").setValue(["java.desktop/sun.awt.image=ALL-UNNAMED",
|
||||||
"java.desktop/sun.awt=ALL-UNNAMED",
|
"java.desktop/sun.awt=ALL-UNNAMED"])
|
||||||
"java.base/sun.security.x509=ALL-UNNAMED",
|
|
||||||
"java.base/sun.security.provider=ALL-UNNAMED",
|
|
||||||
"java.base/sun.security.util=ALL-UNNAMED"])
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -197,10 +194,7 @@ task createJsondocs(type: Javadoc, description: 'Generate JSON docs for all proj
|
||||||
|
|
||||||
// Some internal packages are not public and need to be exported.
|
// Some internal packages are not public and need to be exported.
|
||||||
options.addMultilineStringsOption("-add-exports").setValue(["java.desktop/sun.awt.image=ALL-UNNAMED",
|
options.addMultilineStringsOption("-add-exports").setValue(["java.desktop/sun.awt.image=ALL-UNNAMED",
|
||||||
"java.desktop/sun.awt=ALL-UNNAMED",
|
"java.desktop/sun.awt=ALL-UNNAMED"])
|
||||||
"java.base/sun.security.x509=ALL-UNNAMED",
|
|
||||||
"java.base/sun.security.provider=ALL-UNNAMED",
|
|
||||||
"java.base/sun.security.util=ALL-UNNAMED"])
|
|
||||||
|
|
||||||
options.doclet = "JsonDoclet"
|
options.doclet = "JsonDoclet"
|
||||||
doFirst {
|
doFirst {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue