/* * * X509CertToSSHPubKey - generate SSH2 public key file from X.509 certificate * * Kenji URUSHIMA * 18-Mar-2008 * * 1. DESCRIPTION * * OpenSSL and OpenSSH vulnerabilities are announced on May 15, 2008. * http://www.us-cert.gov/current/index.html#debian_openssl_vulnerability * * This tool helps you to check whether the key corresponding to * the in your X.509 certificate is weak using OpenSSH key blacklist or * checking tools. * * 2. REQUIREMENT * * - This works on Sun Java 1.4.x or later. * - This requires 3rd party open source SSH libary from Trilead. * You can download it from http://www.trilead.com/ * - This was tested using Trilead SSH-2 for Java build 213. * * 4. COMPILE * * - add Trilead libery to class path * % export CLASSPATH=$CLASSPATH:./trilead-ssh2-build213.jar * - compile * % javac X509CertToSSHPubKey.java * * 5. GENERATE SSH2 PUBLIC KEY FILE FROM X.509 CERTIFICATE * * - save X.509 certificate as a DER binary or PEM text file. * - run tool * * % java X509CertToSSHPubKey aaa.cer * * Then you can get SSH2 public key file "aaa.cer.ssh.pub" using * the public key in "aaa.cer". * * You can also specify user id for SSH key. * % java X509CertToSSHPubKey aaa.cer bar@bar * * 6. CHECK KEY WEEKNESS * * - You can check key weakness using "dowkd.pl" Perl script. * % dowkd.pl file aaa.cer.ssh.pub * If the key is weak you'll get "weak key" message. * * 7. CONDITIONS * * This is free software with ABSOLUTELY NO WARRANTY. * * 8. CHANGELOG * - 21 May 2008: initial release */ import java.io.FileInputStream; import java.io.FileWriter; import java.math.BigInteger; import java.security.PublicKey; import java.security.cert.Certificate; import java.security.cert.CertificateFactory; import com.trilead.ssh2.signature.RSASHA1Verify; import com.trilead.ssh2.signature.RSAPublicKey; import com.trilead.ssh2.signature.DSASHA1Verify; import com.trilead.ssh2.signature.DSAPublicKey; import sun.misc.BASE64Encoder; // referring classes // java.security.interfaces.RSAPublicKey // java.security.interfaces.DSAPublicKey public class X509CertToSSHPubKey { private static final String DEFAULT_ID = "foo@foo"; public X509CertToSSHPubKey() { } public void convert(String certFile, String sshFile, String sshUserId) { if (sshUserId == null) sshUserId = DEFAULT_ID; // 1. read X.509 Certificate Certificate cert = null; try { FileInputStream fis = new FileInputStream(certFile); CertificateFactory cf = CertificateFactory.getInstance("X.509"); cert = cf.generateCertificate(fis); } catch (Exception ex) { System.out.println("Error: can't read certificate file: " + certFile + " " + ex.getMessage()); System.exit(1); } // 2. check public key type PublicKey pubkey = cert.getPublicKey(); String alg = pubkey.getAlgorithm(); String sshKeyType = null; String key = null; if ("RSA".equals(alg)) { java.security.interfaces.RSAPublicKey rsaPK = (java.security.interfaces.RSAPublicKey)pubkey; BigInteger n = rsaPK.getModulus(); BigInteger e = rsaPK.getPublicExponent(); RSAPublicKey rsaSSHPK = new RSAPublicKey(e, n); byte[] rsaSSHPKbytes = null; try { rsaSSHPKbytes = new RSASHA1Verify().encodeSSHRSAPublicKey(rsaSSHPK); } catch (Exception ex) { System.out.println("Error: can't encode RSA SSH public key: " + ex.getMessage()); System.exit(1); } key = this.getBase64WithoutNewline(rsaSSHPKbytes); sshKeyType = "ssh-rsa"; } else if ("DSA".equals(alg)) { java.security.interfaces.DSAPublicKey dsaPK = (java.security.interfaces.DSAPublicKey)pubkey; BigInteger p = dsaPK.getParams().getP(); BigInteger q = dsaPK.getParams().getQ(); BigInteger g = dsaPK.getParams().getG(); BigInteger y = dsaPK.getY(); DSAPublicKey dsaSSHPK = new DSAPublicKey(p, q, g, y); byte[] dsaSSHPKbytes = null; try { dsaSSHPKbytes = new DSASHA1Verify().encodeSSHDSAPublicKey(dsaSSHPK); } catch (Exception ex) { System.out.println("Error: can't encode DSA SSH public key: " + ex.getMessage()); System.exit(1); } key = this.getBase64WithoutNewline(dsaSSHPKbytes); sshKeyType = "ssh-dss"; } else { System.out.println("Error: unsupported key algorithm: " + alg); System.exit(1); } this.saveSSHPubkeyFile(sshKeyType, key, sshUserId, sshFile); } private void saveSSHPubkeyFile(String header, String key, String id, String sshFile) { try { FileWriter fr = new FileWriter(sshFile); fr.write(header + " " + key + " " + id + "\n"); fr.close(); } catch (Exception ex) { System.out.println("Error: can't write ssh public key: " + sshFile + " " + ex.getMessage()); System.exit(1); } } private String getBase64WithoutNewline(byte[] b) { BASE64Encoder encoder = new BASE64Encoder(); String b64Str = encoder.encode(b); String result = null; result = b64Str.replaceAll("[\r\n]", ""); result = result.replaceAll("[\n]", ""); return result; } public static void main(String[] args) { String certFile = args[0]; String sshFile = args[0] + ".ssh.pub"; String sshUserId = null; if (args.length > 1) sshUserId = args[1]; X509CertToSSHPubKey c2s = new X509CertToSSHPubKey(); c2s.convert(certFile, sshFile, sshUserId); } }