1 | |
---|
2 | import java.io.*; |
---|
3 | import java.math.*; |
---|
4 | import java.util.*; |
---|
5 | |
---|
6 | import java.security.*; |
---|
7 | import java.security.cert.*; |
---|
8 | import javax.security.auth.x500.*; |
---|
9 | |
---|
10 | import org.bouncycastle.asn1.x509.*; |
---|
11 | import org.bouncycastle.x509.*; |
---|
12 | import org.bouncycastle.openssl.*; |
---|
13 | |
---|
14 | import org.bouncycastle.jce.provider.BouncyCastleProvider; |
---|
15 | |
---|
16 | class MakeFedid { |
---|
17 | |
---|
18 | /** |
---|
19 | * Make a self-signed certificate binding the keypair to CN for one year. |
---|
20 | * Cribbed from jabac. |
---|
21 | * @param cn the String with the name in it |
---|
22 | * @param kp the KeyPair to bind |
---|
23 | * @throws InvalidKeyException if none of the Identities can sign the |
---|
24 | * certificate |
---|
25 | * @throws NoSuchAlgorithmException if the credential uses an unknown |
---|
26 | * signature algorithm |
---|
27 | * @throws NoSuchProviderException if the provider of the signature |
---|
28 | * algorithm is unavailable |
---|
29 | * @throws SignatureException if the signature creation fails |
---|
30 | */ |
---|
31 | public static X509Certificate makeID(String cn, KeyPair kp) throws |
---|
32 | CertificateException, NoSuchAlgorithmException,InvalidKeyException, |
---|
33 | NoSuchProviderException, SignatureException, IOException { |
---|
34 | X509V1CertificateGenerator gen = new X509V1CertificateGenerator(); |
---|
35 | |
---|
36 | gen.setIssuerDN(new X500Principal("CN=" + cn)); |
---|
37 | gen.setSubjectDN(new X500Principal("CN=" + cn)); |
---|
38 | gen.setNotAfter(new Date(System.currentTimeMillis() |
---|
39 | + 3600 * 1000 * 24 * 365)); |
---|
40 | gen.setNotBefore(new Date(System.currentTimeMillis())); |
---|
41 | gen.setSerialNumber(BigInteger.valueOf(System.currentTimeMillis())); |
---|
42 | gen.setPublicKey(kp.getPublic()); |
---|
43 | gen.setSignatureAlgorithm("SHA256WithRSAEncryption"); |
---|
44 | return (X509Certificate) gen.generate(kp.getPrivate(), "BC"); |
---|
45 | } |
---|
46 | |
---|
47 | /** |
---|
48 | * Read a key pair from a Reader attached to PEM data. Reads until it |
---|
49 | * finds a KeyPair, as the PEM may have multiple objects in it. |
---|
50 | * @param r the reader |
---|
51 | * @return the KeyPair encoded (if any) |
---|
52 | */ |
---|
53 | public static KeyPair getKeys(Reader r) throws |
---|
54 | CertificateException, NoSuchAlgorithmException,InvalidKeyException, |
---|
55 | NoSuchProviderException, SignatureException, IOException { |
---|
56 | PEMReader pr = new PEMReader(r); |
---|
57 | Object c = null; |
---|
58 | |
---|
59 | while ( ( c= pr.readObject()) != null ){ |
---|
60 | if (c instanceof KeyPair) return (KeyPair) c; |
---|
61 | } |
---|
62 | return null; |
---|
63 | } |
---|
64 | |
---|
65 | /** |
---|
66 | * Write the PEM cert and keypair to the given writer. |
---|
67 | * @param w a Writer to write on |
---|
68 | * @throws IOException if writing fails |
---|
69 | */ |
---|
70 | public static void writeID(Writer w, X509Certificate cert, KeyPair kp) |
---|
71 | throws IOException { |
---|
72 | PEMWriter pw = new PEMWriter(w); |
---|
73 | |
---|
74 | pw.writeObject(kp); |
---|
75 | pw.writeObject(cert); |
---|
76 | pw.flush(); |
---|
77 | } |
---|
78 | |
---|
79 | /** |
---|
80 | * Load the BouncyCastle provider, necessary for some of the crypto. |
---|
81 | */ |
---|
82 | static void loadBouncyCastle() { |
---|
83 | AccessController.doPrivileged(new PrivilegedAction<Object>() { |
---|
84 | public Object run() { |
---|
85 | Security.addProvider(new BouncyCastleProvider()); |
---|
86 | return null; |
---|
87 | } |
---|
88 | }); |
---|
89 | } |
---|
90 | |
---|
91 | |
---|
92 | /** |
---|
93 | * Convert the PEM cert in the first file to a self signed one in the |
---|
94 | * second argument, having the CN in the last argument. This is harmless |
---|
95 | * if the first cert was self signed. |
---|
96 | */ |
---|
97 | public static void main(String args[]) |
---|
98 | throws GeneralSecurityException, IOException { |
---|
99 | String inFile = (args.length > 0) ? args[0] : "./test.pem"; |
---|
100 | String outFile = (args.length > 1) ? args[1] : "./testout.pem"; |
---|
101 | String cn = (args.length > 2) ? args[2] : "dummy"; |
---|
102 | |
---|
103 | loadBouncyCastle(); |
---|
104 | |
---|
105 | KeyPair kp = getKeys(new FileReader(new File(inFile))); |
---|
106 | X509Certificate cert = makeID(cn, kp); |
---|
107 | writeID(new FileWriter(new File(outFile)), cert, kp); |
---|
108 | } |
---|
109 | } |
---|