Read back private key to verify after keygen

Validate cert after reading from file
   Validate CN in cert
   Javadoc fixes
This commit is contained in:
zzz
2013-09-16 15:48:54 +00:00
parent 79dc95dd66
commit 87d98781a9
4 changed files with 48 additions and 7 deletions

View File

@ -11,10 +11,14 @@ import java.security.KeyStore;
import java.security.cert.Certificate;
import java.security.cert.CertificateException;
import java.security.cert.CertificateEncodingException;
import java.security.cert.CertificateExpiredException;
import java.security.cert.CertificateNotYetValidException;
import java.security.cert.CertificateFactory;
import java.security.cert.X509Certificate;
import java.util.Locale;
import javax.naming.InvalidNameException;
import javax.naming.ldap.LdapName;
import javax.naming.ldap.Rdn;
import javax.security.auth.x500.X500Principal;
import net.i2p.I2PAppContext;
import net.i2p.data.Base64;
@ -65,6 +69,25 @@ public class CertUtil {
}
}
/**
* Get a value out of the subject distinguished name
* @param type e.g. "CN"
* @return value or null if not found
*/
public static String getSubjectValue(X509Certificate cert, String type) {
type = type.toUpperCase(Locale.US);
X500Principal p = cert.getSubjectX500Principal();
String subj = p.getName();
try {
LdapName name = new LdapName(subj);
for (Rdn rdn : name.getRdns()) {
if (type.equals(rdn.getType().toUpperCase(Locale.US)))
return (String) rdn.getValue();
}
} catch (InvalidNameException ine) {}
return null;
}
private static void error(String msg, Throwable t) {
log(I2PAppContext.getGlobalContext(), Log.ERROR, msg, t);
}

View File

@ -358,7 +358,7 @@ public class DSAEngine {
* which may be different than the ones defined in SigType.
*
* @param hash SHA1Hash, Hash, Hash384, or Hash512
* @param pubKey Java key
* @param privKey Java key
* @param type returns a Signature of this type
* @return null on error
* @since 0.9.9

View File

@ -28,15 +28,19 @@ class DirKeyRing implements KeyRing {
_base = baseDir;
}
/**
* Cert must be in the file (escaped keyName).crt,
* and have a CN == keyName
*/
public PublicKey getKey(String keyName, String scope, SigType type)
throws GeneralSecurityException, IOException {
keyName = keyName.replace("@", "_at_");
File test = new File(keyName);
String fileName = keyName.replace("@", "_at_").replace("<", "_").replace(">", "_");
File test = new File(fileName);
if (test.getParent() != null)
throw new IOException("bad key name");
File sd = new File(_base, scope);
//File td = new File(sd, Integer.toString(type.getCode()));
File kd = new File(sd, keyName + ".crt");
File kd = new File(sd, fileName + ".crt");
if (!kd.exists())
return null;
InputStream fis = null;
@ -44,6 +48,10 @@ class DirKeyRing implements KeyRing {
fis = new FileInputStream(kd);
CertificateFactory cf = CertificateFactory.getInstance("X.509");
X509Certificate cert = (X509Certificate)cf.generateCertificate(fis);
cert.checkValidity();
String cn = CertUtil.getSubjectValue(cert, "CN");
if (!keyName.equals(cn))
throw new GeneralSecurityException("CN mismatch: " + cn);
return cert.getPublicKey();
} finally {
try { if (fis != null) fis.close(); } catch (IOException foo) {}

View File

@ -319,9 +319,19 @@ public class KeyStoreUtil {
"-keysize", Integer.toString(keySize),
"-keypass", keyPW
};
// TODO pipe key password to process; requires ShellCommand enhancements
boolean success = (new ShellCommand()).executeSilentAndWaitTimed(args, 240);
if (success) {
success = ks.exists();
if (success) {
try {
success = getPrivateKey(ks, ksPW, alias, keyPW) != null;
} catch (Exception e) {
success = false;
}
}
if (!success)
error("Key gen failed for unknown reasons", null);
}
if (success) {
SecureFileOutputStream.setPerms(ks);
@ -407,7 +417,7 @@ public class KeyStoreUtil {
}
/**
* Pull the cert back OUT of the keystore and save it as ascii
* Pull the cert back OUT of the keystore and save it in Base64-encoded X.509 format
* so the clients can get to it.
*
* @param ks path to the keystore