forked from I2P_Developers/i2p.i2p
SelfSigned: Add support for CRL generation
This commit is contained in:
@ -15,7 +15,9 @@ import java.security.PublicKey;
|
|||||||
import java.security.cert.Certificate;
|
import java.security.cert.Certificate;
|
||||||
import java.security.cert.CertificateFactory;
|
import java.security.cert.CertificateFactory;
|
||||||
import java.security.cert.CertificateEncodingException;
|
import java.security.cert.CertificateEncodingException;
|
||||||
|
import java.security.cert.CRLException;
|
||||||
import java.security.cert.X509Certificate;
|
import java.security.cert.X509Certificate;
|
||||||
|
import java.security.cert.X509CRL;
|
||||||
import java.security.spec.PKCS8EncodedKeySpec;
|
import java.security.spec.PKCS8EncodedKeySpec;
|
||||||
import java.security.spec.KeySpec;
|
import java.security.spec.KeySpec;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
@ -327,4 +329,72 @@ public final class CertUtil {
|
|||||||
try { in.close(); } catch (IOException foo) {}
|
try { in.close(); } catch (IOException foo) {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Write a CRL to a file in base64 format.
|
||||||
|
*
|
||||||
|
* @return success
|
||||||
|
* @since 0.9.25
|
||||||
|
*/
|
||||||
|
public static boolean saveCRL(X509CRL crl, File file) {
|
||||||
|
OutputStream os = null;
|
||||||
|
try {
|
||||||
|
os = new SecureFileOutputStream(file);
|
||||||
|
exportCRL(crl, os);
|
||||||
|
return true;
|
||||||
|
} catch (CRLException ce) {
|
||||||
|
error("Error writing X509 CRL " + file.getAbsolutePath(), ce);
|
||||||
|
return false;
|
||||||
|
} catch (IOException ioe) {
|
||||||
|
error("Error writing X509 CRL " + file.getAbsolutePath(), ioe);
|
||||||
|
return false;
|
||||||
|
} finally {
|
||||||
|
try { if (os != null) os.close(); } catch (IOException foo) {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Writes a CRL in base64 format.
|
||||||
|
* Does NOT close the stream. Throws on all errors.
|
||||||
|
*
|
||||||
|
* @throws CRLException if the crl does not support encoding
|
||||||
|
* @since 0.9.25
|
||||||
|
*/
|
||||||
|
private static void exportCRL(X509CRL crl, OutputStream out)
|
||||||
|
throws IOException, CRLException {
|
||||||
|
byte[] buf = crl.getEncoded();
|
||||||
|
if (buf == null)
|
||||||
|
throw new CRLException("encoding unsupported for this CRL");
|
||||||
|
PrintWriter wr = new PrintWriter(new OutputStreamWriter(out, "UTF-8"));
|
||||||
|
wr.println("-----BEGIN X509 CRL-----");
|
||||||
|
String b64 = Base64.encode(buf, true); // true = use standard alphabet
|
||||||
|
for (int i = 0; i < b64.length(); i += LINE_LENGTH) {
|
||||||
|
wr.println(b64.substring(i, Math.min(i + LINE_LENGTH, b64.length())));
|
||||||
|
}
|
||||||
|
wr.println("-----END X509 CRL-----");
|
||||||
|
wr.flush();
|
||||||
|
if (wr.checkError())
|
||||||
|
throw new IOException("Failed write to " + out);
|
||||||
|
}
|
||||||
|
|
||||||
|
/****
|
||||||
|
public static final void main(String[] args) {
|
||||||
|
if (args.length < 2) {
|
||||||
|
System.out.println("Usage: [loadcert | loadcrl | loadprivatekey] file");
|
||||||
|
System.exit(1);
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
File f = new File(args[1]);
|
||||||
|
if (args[0].equals("loadcert")) {
|
||||||
|
loadCert(f);
|
||||||
|
} else if (args[0].equals("loadcrl")) {
|
||||||
|
} else {
|
||||||
|
}
|
||||||
|
|
||||||
|
} catch (Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
System.exit(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
****/
|
||||||
}
|
}
|
||||||
|
@ -3,9 +3,8 @@ package net.i2p.crypto;
|
|||||||
import java.io.ByteArrayInputStream;
|
import java.io.ByteArrayInputStream;
|
||||||
import java.io.ByteArrayOutputStream;
|
import java.io.ByteArrayOutputStream;
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
|
import java.io.FileOutputStream;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.ObjectInputStream;
|
|
||||||
import java.io.ObjectOutputStream;
|
|
||||||
import java.math.BigInteger;
|
import java.math.BigInteger;
|
||||||
import java.security.GeneralSecurityException;
|
import java.security.GeneralSecurityException;
|
||||||
import java.security.MessageDigest;
|
import java.security.MessageDigest;
|
||||||
@ -13,6 +12,7 @@ import java.security.PrivateKey;
|
|||||||
import java.security.PublicKey;
|
import java.security.PublicKey;
|
||||||
import java.security.cert.CertificateFactory;
|
import java.security.cert.CertificateFactory;
|
||||||
import java.security.cert.X509Certificate;
|
import java.security.cert.X509Certificate;
|
||||||
|
import java.security.cert.X509CRL;
|
||||||
import java.security.spec.X509EncodedKeySpec;
|
import java.security.spec.X509EncodedKeySpec;
|
||||||
import java.text.SimpleDateFormat;
|
import java.text.SimpleDateFormat;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
@ -35,6 +35,7 @@ import net.i2p.data.SigningPublicKey;
|
|||||||
import net.i2p.data.SimpleDataStructure;
|
import net.i2p.data.SimpleDataStructure;
|
||||||
import net.i2p.util.HexDump;
|
import net.i2p.util.HexDump;
|
||||||
import net.i2p.util.RandomSource;
|
import net.i2p.util.RandomSource;
|
||||||
|
import net.i2p.util.SecureFileOutputStream;
|
||||||
import net.i2p.util.SystemVersion;
|
import net.i2p.util.SystemVersion;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -60,6 +61,8 @@ public final class SelfSignedGenerator {
|
|||||||
private static final String OID_OU = "2.5.4.11";
|
private static final String OID_OU = "2.5.4.11";
|
||||||
// Subject Key Identifier
|
// Subject Key Identifier
|
||||||
private static final String OID_SKI = "2.5.29.14";
|
private static final String OID_SKI = "2.5.29.14";
|
||||||
|
// CRL number
|
||||||
|
private static final String OID_CRLNUM = "2.5.29.20";
|
||||||
|
|
||||||
private static final Map<String, String> OIDS;
|
private static final Map<String, String> OIDS;
|
||||||
static {
|
static {
|
||||||
@ -77,6 +80,7 @@ public final class SelfSignedGenerator {
|
|||||||
* rv[0] is a Java PublicKey
|
* rv[0] is a Java PublicKey
|
||||||
* rv[1] is a Java PrivateKey
|
* rv[1] is a Java PrivateKey
|
||||||
* rv[2] is a Java X509Certificate
|
* rv[2] is a Java X509Certificate
|
||||||
|
* rv[3] is a Java X509CRL
|
||||||
*/
|
*/
|
||||||
public static Object[] generate(String cname, String ou, String o, String l, String st, String c,
|
public static Object[] generate(String cname, String ou, String o, String l, String st, String c,
|
||||||
int validDays, SigType type) throws GeneralSecurityException {
|
int validDays, SigType type) throws GeneralSecurityException {
|
||||||
@ -96,6 +100,7 @@ public final class SelfSignedGenerator {
|
|||||||
case RSA_SHA384_3072:
|
case RSA_SHA384_3072:
|
||||||
case RSA_SHA512_4096:
|
case RSA_SHA512_4096:
|
||||||
case EdDSA_SHA512_Ed25519:
|
case EdDSA_SHA512_Ed25519:
|
||||||
|
case EdDSA_SHA512_Ed25519ph:
|
||||||
oid = type.getOID();
|
oid = type.getOID();
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
@ -152,14 +157,81 @@ public final class SelfSignedGenerator {
|
|||||||
} catch (IllegalArgumentException iae) {
|
} catch (IllegalArgumentException iae) {
|
||||||
throw new GeneralSecurityException("cert error", iae);
|
throw new GeneralSecurityException("cert error", iae);
|
||||||
}
|
}
|
||||||
|
X509CRL crl = generateCRL(cert, validDays, 1, sigoid, jpriv);
|
||||||
|
|
||||||
// some simple tests
|
// some simple tests
|
||||||
PublicKey cpub = cert.getPublicKey();
|
PublicKey cpub = cert.getPublicKey();
|
||||||
cert.verify(cpub);
|
cert.verify(cpub);
|
||||||
if (!cpub.equals(jpub))
|
if (!cpub.equals(jpub))
|
||||||
throw new GeneralSecurityException("pubkey mismatch");
|
throw new GeneralSecurityException("pubkey mismatch");
|
||||||
|
// todo crl tests
|
||||||
|
|
||||||
|
Object[] rv = { jpub, jpriv, cert, crl };
|
||||||
|
return rv;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Generate a CRL for the given cert, signed with the given private key
|
||||||
|
*/
|
||||||
|
private static X509CRL generateCRL(X509Certificate cert, int validDays, int crlNum,
|
||||||
|
byte[] sigoid, PrivateKey jpriv) throws GeneralSecurityException {
|
||||||
|
|
||||||
|
SigningPrivateKey priv = SigUtil.fromJavaKey(jpriv);
|
||||||
|
|
||||||
|
byte[] tbs = genTBSCRL(cert, validDays, crlNum, sigoid);
|
||||||
|
int tbslen = tbs.length;
|
||||||
|
|
||||||
|
Signature sig = DSAEngine.getInstance().sign(tbs, priv);
|
||||||
|
if (sig == null)
|
||||||
|
throw new GeneralSecurityException("sig failed");
|
||||||
|
byte[] sigbytes= SigUtil.toJavaSig(sig);
|
||||||
|
|
||||||
|
int seqlen = tbslen + sigoid.length + spaceFor(sigbytes.length + 1);
|
||||||
|
int totlen = spaceFor(seqlen);
|
||||||
|
byte[] cb = new byte[totlen];
|
||||||
|
int idx = 0;
|
||||||
|
|
||||||
|
// construct the whole encoded cert
|
||||||
|
cb[idx++] = 0x30;
|
||||||
|
idx = intToASN1(cb, idx, seqlen);
|
||||||
|
|
||||||
|
// TBS cert
|
||||||
|
System.arraycopy(tbs, 0, cb, idx, tbs.length);
|
||||||
|
idx += tbs.length;
|
||||||
|
|
||||||
|
// sig algo
|
||||||
|
System.arraycopy(sigoid, 0, cb, idx, sigoid.length);
|
||||||
|
idx += sigoid.length;
|
||||||
|
|
||||||
|
// sig (bit string)
|
||||||
|
cb[idx++] = 0x03;
|
||||||
|
idx = intToASN1(cb, idx, sigbytes.length + 1);
|
||||||
|
cb[idx++] = 0;
|
||||||
|
System.arraycopy(sigbytes, 0, cb, idx, sigbytes.length);
|
||||||
|
|
||||||
|
/****
|
||||||
|
if (DEBUG) {
|
||||||
|
System.out.println("CRL Sig OID");
|
||||||
|
System.out.println(HexDump.dump(sigoid));
|
||||||
|
System.out.println("CRL Signature");
|
||||||
|
System.out.println(HexDump.dump(sigbytes));
|
||||||
|
System.out.println("Whole CRL");
|
||||||
|
System.out.println(HexDump.dump(cb));
|
||||||
|
}
|
||||||
|
****/
|
||||||
|
|
||||||
|
ByteArrayInputStream bais = new ByteArrayInputStream(cb);
|
||||||
|
|
||||||
|
X509CRL rv;
|
||||||
|
try {
|
||||||
|
CertificateFactory cf = CertificateFactory.getInstance("X.509");
|
||||||
|
// wow, unlike for x509Certificates, there's no validation here at all
|
||||||
|
// ASN.1 errors don't cause any exceptions
|
||||||
|
rv = (X509CRL)cf.generateCRL(bais);
|
||||||
|
} catch (IllegalArgumentException iae) {
|
||||||
|
throw new GeneralSecurityException("cert error", iae);
|
||||||
|
}
|
||||||
|
|
||||||
Object[] rv = { jpub, jpriv, cert };
|
|
||||||
return rv;
|
return rv;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -230,6 +302,88 @@ public final class SelfSignedGenerator {
|
|||||||
return rv;
|
return rv;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param crlNum 0-255 because lazy
|
||||||
|
* @return ASN.1 encoded object
|
||||||
|
*/
|
||||||
|
private static byte[] genTBSCRL(X509Certificate cert, int validDays,
|
||||||
|
int crlNum, byte[] sigalg) throws GeneralSecurityException {
|
||||||
|
// a0 ???, int = 2
|
||||||
|
byte[] version = { 2, 1, 1 };
|
||||||
|
byte[] issuer = cert.getIssuerX500Principal().getEncoded();
|
||||||
|
|
||||||
|
byte[] serial = cert.getSerialNumber().toByteArray();
|
||||||
|
if (serial.length > 255)
|
||||||
|
throw new IllegalArgumentException();
|
||||||
|
long now = System.currentTimeMillis();
|
||||||
|
long then = now + (validDays * 24L * 60 * 60 * 1000);
|
||||||
|
// used for CRL time and revocation time
|
||||||
|
byte[] nowbytes = getDate(now);
|
||||||
|
// used for next CRL time
|
||||||
|
byte[] thenbytes = getDate(then);
|
||||||
|
|
||||||
|
byte[] extbytes = getCRLExtensions(crlNum);
|
||||||
|
|
||||||
|
int revlen = 2 + serial.length + nowbytes.length;
|
||||||
|
int revseqlen = spaceFor(revlen);
|
||||||
|
int revsseqlen = spaceFor(revseqlen);
|
||||||
|
|
||||||
|
|
||||||
|
int len = version.length + sigalg.length + issuer.length + nowbytes.length +
|
||||||
|
thenbytes.length + revsseqlen + extbytes.length;
|
||||||
|
|
||||||
|
int totlen = spaceFor(len);
|
||||||
|
byte[] rv = new byte[totlen];
|
||||||
|
int idx = 0;
|
||||||
|
rv[idx++] = 0x30;
|
||||||
|
idx = intToASN1(rv, idx, len);
|
||||||
|
System.arraycopy(version, 0, rv, idx, version.length);
|
||||||
|
idx += version.length;
|
||||||
|
System.arraycopy(sigalg, 0, rv, idx, sigalg.length);
|
||||||
|
idx += sigalg.length;
|
||||||
|
System.arraycopy(issuer, 0, rv, idx, issuer.length);
|
||||||
|
idx += issuer.length;
|
||||||
|
System.arraycopy(nowbytes, 0, rv, idx, nowbytes.length);
|
||||||
|
idx += nowbytes.length;
|
||||||
|
System.arraycopy(thenbytes, 0, rv, idx, thenbytes.length);
|
||||||
|
idx += thenbytes.length;
|
||||||
|
// the certs
|
||||||
|
rv[idx++] = 0x30;
|
||||||
|
idx = intToASN1(rv, idx, revseqlen);
|
||||||
|
// the cert
|
||||||
|
rv[idx++] = 0x30;
|
||||||
|
idx = intToASN1(rv, idx, revlen);
|
||||||
|
rv[idx++] = 0x02;
|
||||||
|
rv[idx++] = (byte) serial.length;
|
||||||
|
System.arraycopy(serial, 0, rv, idx, serial.length);
|
||||||
|
idx += serial.length;
|
||||||
|
System.arraycopy(nowbytes, 0, rv, idx, nowbytes.length);
|
||||||
|
idx += nowbytes.length;
|
||||||
|
// extensions
|
||||||
|
System.arraycopy(extbytes, 0, rv, idx, extbytes.length);
|
||||||
|
|
||||||
|
if (DEBUG) {
|
||||||
|
System.out.println("version");
|
||||||
|
System.out.println(HexDump.dump(version));
|
||||||
|
System.out.println("sigalg");
|
||||||
|
System.out.println(HexDump.dump(sigalg));
|
||||||
|
System.out.println("issuer");
|
||||||
|
System.out.println(HexDump.dump(issuer));
|
||||||
|
System.out.println("now");
|
||||||
|
System.out.println(HexDump.dump(nowbytes));
|
||||||
|
System.out.println("then");
|
||||||
|
System.out.println(HexDump.dump(thenbytes));
|
||||||
|
System.out.println("serial");
|
||||||
|
System.out.println(HexDump.dump(serial));
|
||||||
|
System.out.println("extensions");
|
||||||
|
System.out.println(HexDump.dump(extbytes));
|
||||||
|
System.out.println("TBS CRL");
|
||||||
|
System.out.println(HexDump.dump(rv));
|
||||||
|
}
|
||||||
|
return rv;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param val the length of the value, 65535 max
|
* @param val the length of the value, 65535 max
|
||||||
* @return the length of the TLV
|
* @return the length of the TLV
|
||||||
@ -246,30 +400,38 @@ public final class SelfSignedGenerator {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* Sequence of two UTCDates
|
||||||
* @return 32 bytes ASN.1 encoded object
|
* @return 32 bytes ASN.1 encoded object
|
||||||
*/
|
*/
|
||||||
private static byte[] getValidity(int validDays) {
|
private static byte[] getValidity(int validDays) {
|
||||||
ByteArrayOutputStream baos = new ByteArrayOutputStream(32);
|
byte[] rv = new byte[32];
|
||||||
baos.write(0x30);
|
rv[0] = 0x30;
|
||||||
// len to be filled in later
|
rv[1] = 30;
|
||||||
baos.write(0);
|
|
||||||
long now = System.currentTimeMillis();
|
long now = System.currentTimeMillis();
|
||||||
long then = now + (validDays * 24L * 60 * 60 * 1000);
|
long then = now + (validDays * 24L * 60 * 60 * 1000);
|
||||||
|
byte[] nowbytes = getDate(now);
|
||||||
|
byte[] thenbytes = getDate(then);
|
||||||
|
System.arraycopy(nowbytes, 0, rv, 2, 15);
|
||||||
|
System.arraycopy(thenbytes, 0, rv, 17, 15);
|
||||||
|
return rv;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A single UTCDate
|
||||||
|
* @return 15 bytes ASN.1 encoded object
|
||||||
|
*/
|
||||||
|
private static byte[] getDate(long now) {
|
||||||
// UTCDate format (HH 0-23)
|
// UTCDate format (HH 0-23)
|
||||||
SimpleDateFormat fmt = new SimpleDateFormat("yyMMddHHmmss");
|
SimpleDateFormat fmt = new SimpleDateFormat("yyMMddHHmmss");
|
||||||
fmt.setTimeZone(TimeZone.getTimeZone("GMT"));
|
fmt.setTimeZone(TimeZone.getTimeZone("GMT"));
|
||||||
byte[] nowbytes = DataHelper.getASCII(fmt.format(new Date(now)));
|
byte[] nowbytes = DataHelper.getASCII(fmt.format(new Date(now)));
|
||||||
byte[] thenbytes = DataHelper.getASCII(fmt.format(new Date(then)));
|
if (nowbytes.length != 12)
|
||||||
baos.write(0x17);
|
throw new IllegalArgumentException();
|
||||||
baos.write(nowbytes.length + 1);
|
byte[] rv = new byte[15];
|
||||||
baos.write(nowbytes, 0, nowbytes.length);
|
rv[0] = 0x17;
|
||||||
baos.write('Z');
|
rv[1] = 13;
|
||||||
baos.write(0x17);
|
System.arraycopy(nowbytes, 0, rv, 2, 12);
|
||||||
baos.write(thenbytes.length + 1);
|
rv[14] = (byte) 'Z';
|
||||||
baos.write(thenbytes, 0, thenbytes.length);
|
|
||||||
baos.write('Z');
|
|
||||||
byte[] rv = baos.toByteArray();
|
|
||||||
rv[1] = (byte) (rv.length - 2);
|
|
||||||
return rv;
|
return rv;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -307,7 +469,7 @@ public final class SelfSignedGenerator {
|
|||||||
idx = intToASN1(rv, idx, extlen);
|
idx = intToASN1(rv, idx, extlen);
|
||||||
System.arraycopy(oid, 0, rv, idx, oid.length);
|
System.arraycopy(oid, 0, rv, idx, oid.length);
|
||||||
idx += oid.length;
|
idx += oid.length;
|
||||||
// don't know why we wrap the int in another int
|
// don't know why we wrap the octet string in an octet string
|
||||||
rv[idx++] = (byte) 0x04;
|
rv[idx++] = (byte) 0x04;
|
||||||
idx = intToASN1(rv, idx, wraplen);
|
idx = intToASN1(rv, idx, wraplen);
|
||||||
rv[idx++] = (byte) 0x04;
|
rv[idx++] = (byte) 0x04;
|
||||||
@ -316,6 +478,38 @@ public final class SelfSignedGenerator {
|
|||||||
return rv;
|
return rv;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param crlNum 0-255 because lazy
|
||||||
|
* @return 16 bytes ASN.1 encoded object
|
||||||
|
*/
|
||||||
|
private static byte[] getCRLExtensions(int crlNum) {
|
||||||
|
if (crlNum < 0 || crlNum > 255)
|
||||||
|
throw new IllegalArgumentException();
|
||||||
|
byte[] oid = getEncodedOID(OID_CRLNUM);
|
||||||
|
int extlen = oid.length + 5;
|
||||||
|
int extslen = spaceFor(extlen);
|
||||||
|
int seqlen = spaceFor(extslen);
|
||||||
|
int totlen = spaceFor(seqlen);
|
||||||
|
byte[] rv = new byte[totlen];
|
||||||
|
int idx = 0;
|
||||||
|
rv[idx++] = (byte) 0xa0;
|
||||||
|
idx = intToASN1(rv, idx, seqlen);
|
||||||
|
rv[idx++] = (byte) 0x30;
|
||||||
|
idx = intToASN1(rv, idx, extslen);
|
||||||
|
rv[idx++] = (byte) 0x30;
|
||||||
|
idx = intToASN1(rv, idx, extlen);
|
||||||
|
System.arraycopy(oid, 0, rv, idx, oid.length);
|
||||||
|
idx += oid.length;
|
||||||
|
// don't know why we wrap the int in an octet string
|
||||||
|
rv[idx++] = (byte) 0x04;
|
||||||
|
rv[idx++] = (byte) 3;
|
||||||
|
rv[idx++] = (byte) 0x02;
|
||||||
|
rv[idx++] = (byte) 1;
|
||||||
|
rv[idx++] = (byte) crlNum;
|
||||||
|
return rv;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 0x30 len 0x06 len encodedbytes... 0x05 0
|
* 0x30 len 0x06 len encodedbytes... 0x05 0
|
||||||
* @return ASN.1 encoded object
|
* @return ASN.1 encoded object
|
||||||
@ -378,6 +572,7 @@ public final class SelfSignedGenerator {
|
|||||||
test("test5", SigType.RSA_SHA384_3072);
|
test("test5", SigType.RSA_SHA384_3072);
|
||||||
test("test6", SigType.RSA_SHA512_4096);
|
test("test6", SigType.RSA_SHA512_4096);
|
||||||
test("test7", SigType.EdDSA_SHA512_Ed25519);
|
test("test7", SigType.EdDSA_SHA512_Ed25519);
|
||||||
|
test("test8", SigType.EdDSA_SHA512_Ed25519ph);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
@ -388,6 +583,7 @@ public final class SelfSignedGenerator {
|
|||||||
PublicKey jpub = (PublicKey) rv[0];
|
PublicKey jpub = (PublicKey) rv[0];
|
||||||
PrivateKey jpriv = (PrivateKey) rv[1];
|
PrivateKey jpriv = (PrivateKey) rv[1];
|
||||||
X509Certificate cert = (X509Certificate) rv[2];
|
X509Certificate cert = (X509Certificate) rv[2];
|
||||||
|
X509CRL crl = (X509CRL) rv[3];
|
||||||
File ks = new File(name + ".ks");
|
File ks = new File(name + ".ks");
|
||||||
List<X509Certificate> certs = new ArrayList<X509Certificate>(1);
|
List<X509Certificate> certs = new ArrayList<X509Certificate>(1);
|
||||||
certs.add(cert);
|
certs.add(cert);
|
||||||
@ -396,6 +592,14 @@ public final class SelfSignedGenerator {
|
|||||||
File cf = new File(name + ".crt");
|
File cf = new File(name + ".crt");
|
||||||
CertUtil.saveCert(cert, cf);
|
CertUtil.saveCert(cert, cf);
|
||||||
System.out.println("Certificate saved to " + cf);
|
System.out.println("Certificate saved to " + cf);
|
||||||
|
File pf = new File(name + ".priv");
|
||||||
|
FileOutputStream pfs = new SecureFileOutputStream(pf);
|
||||||
|
KeyStoreUtil.exportPrivateKey(ks, "changeit", "foo", "foobar", pfs);
|
||||||
|
pfs.close();
|
||||||
|
System.out.println("Private key saved to " + pf);
|
||||||
|
File cr = new File(name + ".crl");
|
||||||
|
CertUtil.saveCRL(crl, cr);
|
||||||
|
System.out.println("CRL saved to " + cr);
|
||||||
}
|
}
|
||||||
****/
|
****/
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user