forked from I2P_Developers/i2p.i2p
KeyStoreUtil:
- Overwrite check in createKeys() - New getCert(), getKey() SU3File: - Store generated keys in keystore - Get private key for signing from keystore
This commit is contained in:
@ -6,6 +6,7 @@ import java.io.InputStream;
|
||||
import java.io.IOException;
|
||||
import java.security.GeneralSecurityException;
|
||||
import java.security.KeyStore;
|
||||
import java.security.PrivateKey;
|
||||
import java.security.cert.Certificate;
|
||||
import java.security.cert.CertificateException;
|
||||
import java.security.cert.CertificateEncodingException;
|
||||
@ -252,7 +253,7 @@ public class KeyStoreUtil {
|
||||
* @param alias the name of the key
|
||||
* @param cname e.g. randomstuff.console.i2p.net
|
||||
* @param ou e.g. console
|
||||
* @param keqPW the key password
|
||||
* @param keyPW the key password, must be at least 6 characters
|
||||
*
|
||||
* @return success
|
||||
* @since 0.8.3, consolidated from RouterConsoleRUnner and SSLClientListenerRunner in 0.9.9
|
||||
@ -276,16 +277,26 @@ public class KeyStoreUtil {
|
||||
* @param validDays e.g. 3652 (10 years)
|
||||
* @param keyAlg e.g. DSA , RSA, EC
|
||||
* @param keySize e.g. 1024
|
||||
* @param keqPW the key password
|
||||
* @param keyPW the key password, must be at least 6 characters
|
||||
*
|
||||
* @return success
|
||||
* @since 0.8.3, consolidated from RouterConsoleRUnner and SSLClientListenerRunner in 0.9.9
|
||||
*/
|
||||
public static boolean createKeys(File ks, String ksPW, String alias, String cname, String ou,
|
||||
int validDays, String keyAlg, int keySize, String keyPW) {
|
||||
if (!ks.exists()) {
|
||||
if (ks.exists()) {
|
||||
try {
|
||||
if (getCert(ks, ksPW, alias) != null) {
|
||||
error("Not overwriting key " + alias + ", already exists in " + ks, null);
|
||||
return false;
|
||||
}
|
||||
} catch (Exception e) {
|
||||
error("Not overwriting key \"" + alias + "\", already exists in " + ks, e);
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
File dir = ks.getParentFile();
|
||||
if (!dir.exists()) {
|
||||
if (dir != null && !dir.exists()) {
|
||||
File sdir = new SecureDirectory(dir.getAbsolutePath());
|
||||
if (!sdir.mkdir()) {
|
||||
error("Can't create directory " + dir, null);
|
||||
@ -319,11 +330,57 @@ public class KeyStoreUtil {
|
||||
for (int i = 0; i < args.length; i++) {
|
||||
buf.append('"').append(args[i]).append("\" ");
|
||||
}
|
||||
error("Failed to create SSL keystore using command line:" + buf, null);
|
||||
error("Failed to create SSL keystore using command line: " + buf, null);
|
||||
}
|
||||
return success;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a private key out of a keystore
|
||||
*
|
||||
* @param ks path to the keystore
|
||||
* @param ksPW the keystore password, may be null
|
||||
* @param alias the name of the key
|
||||
* @param keyPW the key password, must be at least 6 characters
|
||||
* @return the key or null if not found
|
||||
*/
|
||||
public static PrivateKey getPrivateKey(File ks, String ksPW, String alias, String keyPW)
|
||||
throws GeneralSecurityException, IOException {
|
||||
InputStream fis = null;
|
||||
try {
|
||||
KeyStore keyStore = KeyStore.getInstance(KeyStore.getDefaultType());
|
||||
fis = new FileInputStream(ks);
|
||||
char[] pwchars = ksPW != null ? ksPW.toCharArray() : null;
|
||||
keyStore.load(fis, pwchars);
|
||||
char[] keypwchars = keyPW.toCharArray();
|
||||
return (PrivateKey) keyStore.getKey(alias, keypwchars);
|
||||
} finally {
|
||||
if (fis != null) try { fis.close(); } catch (IOException ioe) {}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a cert out of a keystore
|
||||
*
|
||||
* @param ks path to the keystore
|
||||
* @param ksPW the keystore password, may be null
|
||||
* @param alias the name of the key
|
||||
* @return the certificate or null if not found
|
||||
*/
|
||||
public static Certificate getCert(File ks, String ksPW, String alias)
|
||||
throws GeneralSecurityException, IOException {
|
||||
InputStream fis = null;
|
||||
try {
|
||||
KeyStore keyStore = KeyStore.getInstance(KeyStore.getDefaultType());
|
||||
fis = new FileInputStream(ks);
|
||||
char[] pwchars = ksPW != null ? ksPW.toCharArray() : null;
|
||||
keyStore.load(fis, pwchars);
|
||||
return keyStore.getCertificate(alias);
|
||||
} finally {
|
||||
if (fis != null) try { fis.close(); } catch (IOException ioe) {}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Pull the cert back OUT of the keystore and save it as ascii
|
||||
* so the clients can get to it.
|
||||
@ -338,19 +395,13 @@ public class KeyStoreUtil {
|
||||
public static boolean exportCert(File ks, String ksPW, String alias, File certFile) {
|
||||
InputStream fis = null;
|
||||
try {
|
||||
KeyStore keyStore = KeyStore.getInstance(KeyStore.getDefaultType());
|
||||
fis = new FileInputStream(ks);
|
||||
char[] pwchars = ksPW != null ? ksPW.toCharArray() : null;
|
||||
keyStore.load(fis, pwchars);
|
||||
Certificate cert = keyStore.getCertificate(alias);
|
||||
Certificate cert = getCert(ks, ksPW, alias);
|
||||
if (cert != null)
|
||||
return CertUtil.saveCert(cert, certFile);
|
||||
} catch (GeneralSecurityException gse) {
|
||||
error("Error saving ASCII SSL keys", gse);
|
||||
} catch (IOException ioe) {
|
||||
error("Error saving ASCII SSL keys", ioe);
|
||||
} finally {
|
||||
if (fis != null) try { fis.close(); } catch (IOException ioe) {}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
@ -503,8 +503,15 @@ public class SU3File {
|
||||
private static final boolean signCLI(SigType type, String inputFile, String signedFile,
|
||||
String privateKeyFile, String version, String signerName) {
|
||||
try {
|
||||
String keypw = "";
|
||||
while (keypw.length() < 6) {
|
||||
System.out.print("Enter password for key \"" + signerName + "\": ");
|
||||
keypw = DataHelper.readLine(System.in).trim();
|
||||
if (keypw.length() > 0 && keypw.length() < 6)
|
||||
System.out.println("Key password must be at least 6 characters");
|
||||
}
|
||||
File pkfile = new File(privateKeyFile);
|
||||
PrivateKey pk = SigUtil.importJavaPrivateKey(pkfile, type);
|
||||
PrivateKey pk = KeyStoreUtil.getPrivateKey(pkfile,KeyStoreUtil.DEFAULT_KEYSTORE_PASSWORD, signerName, keypw);
|
||||
SigningPrivateKey spk = SigUtil.fromJavaKey(pk, type);
|
||||
SU3File file = new SU3File(signedFile);
|
||||
file.write(new File(inputFile), CONTENT_ROUTER, version, signerName, spk);
|
||||
@ -568,45 +575,45 @@ public class SU3File {
|
||||
*/
|
||||
private static final boolean genKeysCLI(SigType type, String publicKeyFile, String privateKeyFile) {
|
||||
File pubFile = new File(publicKeyFile);
|
||||
File privFile = new File(privateKeyFile);
|
||||
if (pubFile.exists()) {
|
||||
System.out.println("Error: Not overwriting file " + publicKeyFile);
|
||||
return false;
|
||||
}
|
||||
if (privFile.exists()) {
|
||||
System.out.println("Error: Not overwriting file " + privateKeyFile);
|
||||
File ksFile = new File(privateKeyFile);
|
||||
String alias = "";
|
||||
String keypw = "";
|
||||
try {
|
||||
while (alias.length() == 0) {
|
||||
System.out.print("Enter key name (example@mail.i2p): ");
|
||||
alias = DataHelper.readLine(System.in).trim();
|
||||
}
|
||||
while (keypw.length() < 6) {
|
||||
System.out.print("Enter new key password: ");
|
||||
keypw = DataHelper.readLine(System.in).trim();
|
||||
if (keypw.length() > 0 && keypw.length() < 6)
|
||||
System.out.println("Key password must be at least 6 characters");
|
||||
}
|
||||
} catch (IOException ioe) {
|
||||
return false;
|
||||
}
|
||||
FileOutputStream fileOutputStream = null;
|
||||
I2PAppContext context = I2PAppContext.getGlobalContext();
|
||||
try {
|
||||
// inefficiently go from Java to I2P to Java formats
|
||||
SimpleDataStructure signingKeypair[] = context.keyGenerator().generateSigningKeys(type);
|
||||
SigningPublicKey signingPublicKey = (SigningPublicKey) signingKeypair[0];
|
||||
SigningPrivateKey signingPrivateKey = (SigningPrivateKey) signingKeypair[1];
|
||||
PublicKey pubkey = SigUtil.toJavaKey(signingPublicKey);
|
||||
PrivateKey privkey = SigUtil.toJavaKey(signingPrivateKey);
|
||||
|
||||
fileOutputStream = new SecureFileOutputStream(pubFile);
|
||||
fileOutputStream.write(pubkey.getEncoded());
|
||||
fileOutputStream.close();
|
||||
fileOutputStream = null;
|
||||
|
||||
fileOutputStream = new SecureFileOutputStream(privFile);
|
||||
fileOutputStream.write(privkey.getEncoded());
|
||||
|
||||
System.out.println("\r\n" + type + " Private key written to: " + privateKeyFile);
|
||||
System.out.println(type + " Public key written to: " + publicKeyFile);
|
||||
System.out.println("\r\nPublic key: " + signingPublicKey.toBase64() + "\r\n");
|
||||
} catch (Exception e) {
|
||||
int keylen = type.getPubkeyLen() * 8;
|
||||
if (type.getBaseAlgorithm() == SigAlgo.EC) {
|
||||
keylen /= 2;
|
||||
if (keylen == 528)
|
||||
keylen = 521;
|
||||
}
|
||||
boolean success = KeyStoreUtil.createKeys(ksFile, KeyStoreUtil.DEFAULT_KEYSTORE_PASSWORD, alias,
|
||||
"cn", "ou", 3652, type.getBaseAlgorithm().getName(),
|
||||
keylen, keypw);
|
||||
if (!success) {
|
||||
System.err.println("Error writing keys:");
|
||||
return false;
|
||||
}
|
||||
File outfile = new File(publicKeyFile);
|
||||
success = KeyStoreUtil.exportCert(ksFile, KeyStoreUtil.DEFAULT_KEYSTORE_PASSWORD, alias, outfile);
|
||||
if (!success) {
|
||||
System.err.println("Error writing keys:");
|
||||
e.printStackTrace();
|
||||
return false;
|
||||
} finally {
|
||||
if (fileOutputStream != null)
|
||||
try {
|
||||
fileOutputStream.close();
|
||||
} catch (IOException ioe) {}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
Reference in New Issue
Block a user