/** Read a Key Pair */ private static KeyPair readKeyPair( BufferedReader _in, char[] passwd, String type, String endMarker) throws Exception { boolean isEncrypted = false; String line = null; String dekInfo = null; StringBuffer buf = new StringBuffer(); while ((line = _in.readLine()) != null) { if (line.startsWith("Proc-Type: 4,ENCRYPTED")) { isEncrypted = true; } else if (line.startsWith("DEK-Info:")) { dekInfo = line.substring(10); } else if (line.indexOf(endMarker) != -1) { break; } else { buf.append(line.trim()); } } byte[] keyBytes = null; byte[] decoded = Base64.decode(buf.toString()); if (isEncrypted) { keyBytes = decrypt(decoded, dekInfo, passwd); } else { keyBytes = decoded; } return org.jruby.ext.openssl.impl.PKey.readPrivateKey(keyBytes, type); }
@JRubyMethod public IRubyObject to_der() { try { byte[] bytes = org.jruby.ext.openssl.impl.PKey.toDerDSAKey(pubKey, privKey); return RubyString.newString(getRuntime(), bytes); } catch (NoClassDefFoundError ncdfe) { throw newDSAError(getRuntime(), OpenSSLReal.bcExceptionMessage(ncdfe)); } catch (IOException ioe) { throw newDSAError(getRuntime(), ioe.getMessage()); } }
/** c: PEM_read_PrivateKey + PEM_read_bio_PrivateKey CAUTION: KeyPair#getPublic() may be null. */ public static KeyPair readPrivateKey(Reader in, char[] password) throws IOException { BufferedReader _in = makeBuffered(in); String line; while ((line = _in.readLine()) != null) { if (line.indexOf(BEF_G + PEM_STRING_RSA) != -1) { try { return readKeyPair(_in, password, "RSA", BEF_E + PEM_STRING_RSA); } catch (Exception e) { throw new IOException("problem creating RSA private key: " + e.toString()); } } else if (line.indexOf(BEF_G + PEM_STRING_DSA) != -1) { try { return readKeyPair(_in, password, "DSA", BEF_E + PEM_STRING_DSA); } catch (Exception e) { throw new IOException("problem creating DSA private key: " + e.toString()); } } else if (line.indexOf(BEF_G + PEM_STRING_ECPRIVATEKEY) != -1) { throw new IOException("EC private key not supported"); } else if (line.indexOf(BEF_G + PEM_STRING_PKCS8INF) != -1) { try { byte[] bytes = readBytes(_in, BEF_E + PEM_STRING_PKCS8INF); PrivateKeyInfo info = new PrivateKeyInfo((ASN1Sequence) new ASN1InputStream(bytes).readObject()); String type = getPrivateKeyTypeFromObjectId(info.getAlgorithmId().getObjectId()); return org.jruby.ext.openssl.impl.PKey.readPrivateKey( info.getPrivateKey().getDEREncoded(), type); } catch (Exception e) { throw new IOException("problem creating private key: " + e.toString()); } } else if (line.indexOf(BEF_G + PEM_STRING_PKCS8) != -1) { try { byte[] bytes = readBytes(_in, BEF_E + PEM_STRING_PKCS8); org.bouncycastle.asn1.pkcs.EncryptedPrivateKeyInfo eIn = new org.bouncycastle.asn1.pkcs.EncryptedPrivateKeyInfo( (ASN1Sequence) new ASN1InputStream(bytes).readObject()); AlgorithmIdentifier algId = eIn.getEncryptionAlgorithm(); PrivateKey privKey; if (algId.getAlgorithm().toString().equals("1.2.840.113549.1.5.13")) { // PBES2 privKey = derivePrivateKeyPBES2(eIn, algId, password); } else { privKey = derivePrivateKeyPBES1(eIn, algId, password); } return new KeyPair(null, privKey); } catch (Exception e) { throw new IOException("problem creating private key: " + e.toString()); } } } return null; }
public static DHParameterSpec readDHParameters(Reader _in) throws IOException { BufferedReader in = makeBuffered(_in); String line; StringBuilder buf = new StringBuilder(); while ((line = in.readLine()) != null) { if (line.indexOf(BEF_G + PEM_STRING_DHPARAMS) >= 0) { do { buf.append(line.trim()); } while (line.indexOf(BEF_E + PEM_STRING_DHPARAMS) < 0 && (line = in.readLine()) != null); break; } } Matcher m = DH_PARAM_PATTERN.matcher(buf.toString()); if (m.find()) { try { byte[] decoded = Base64.decode(m.group(DH_PARAM_GROUP)); return org.jruby.ext.openssl.impl.PKey.readDHParameter(decoded); } catch (Exception e) { } } return null; }
@JRubyMethod(rest = true, visibility = Visibility.PRIVATE) public IRubyObject initialize(IRubyObject[] args) { IRubyObject arg; IRubyObject pass = null; char[] passwd = null; if (org.jruby.runtime.Arity.checkArgumentCount(getRuntime(), args, 0, 2) == 0) { privKey = null; pubKey = null; } else { arg = args[0]; if (args.length > 1) { pass = args[1]; } if (arg instanceof RubyFixnum) { int keysize = RubyNumeric.fix2int(arg); dsaGenerate(this, keysize); } else { if (pass != null && !pass.isNil()) { passwd = pass.toString().toCharArray(); } arg = OpenSSLImpl.to_der_if_possible(arg); RubyString str = arg.convertToString(); Object val = null; KeyFactory fact = null; try { fact = KeyFactory.getInstance("DSA"); } catch (NoSuchAlgorithmException e) { throw getRuntime().newLoadError("unsupported key algorithm (DSA)"); } // TODO: ugly NoClassDefFoundError catching for no BC env. How can we remove this? if (null == val) { // PEM_read_bio_DSAPrivateKey try { val = PEMInputOutput.readDSAPrivateKey(new StringReader(str.toString()), passwd); } catch (NoClassDefFoundError e) { val = null; } catch (Exception e) { val = null; } } if (null == val) { // PEM_read_bio_DSAPublicKey try { val = PEMInputOutput.readDSAPublicKey(new StringReader(str.toString()), passwd); } catch (NoClassDefFoundError e) { val = null; } catch (Exception e) { val = null; } } if (null == val) { // PEM_read_bio_DSA_PUBKEY try { val = PEMInputOutput.readDSAPubKey(new StringReader(str.toString())); } catch (NoClassDefFoundError e) { val = null; } catch (Exception e) { val = null; } } if (null == val) { // d2i_DSAPrivateKey_bio try { val = org.jruby.ext.openssl.impl.PKey.readDSAPrivateKey(str.getBytes()); } catch (NoClassDefFoundError e) { val = null; } catch (Exception e) { val = null; } } if (null == val) { // d2i_DSA_PUBKEY_bio try { val = org.jruby.ext.openssl.impl.PKey.readDSAPublicKey(str.getBytes()); } catch (NoClassDefFoundError e) { val = null; } catch (Exception e) { val = null; } } if (null == val) { try { val = fact.generatePrivate(new PKCS8EncodedKeySpec(str.getBytes())); } catch (Exception e) { val = null; } } if (null == val) { try { val = fact.generatePublic(new X509EncodedKeySpec(str.getBytes())); } catch (Exception e) { val = null; } } if (null == val) { throw newDSAError(getRuntime(), "Neither PUB key nor PRIV key:"); } if (val instanceof KeyPair) { PrivateKey privateKey = ((KeyPair) val).getPrivate(); PublicKey publicKey = ((KeyPair) val).getPublic(); if (privateKey instanceof DSAPrivateKey) { privKey = (DSAPrivateKey) privateKey; pubKey = (DSAPublicKey) publicKey; } else { throw newDSAError(getRuntime(), "Neither PUB key nor PRIV key:"); } } else if (val instanceof DSAPrivateKey) { privKey = (DSAPrivateKey) val; } else if (val instanceof DSAPublicKey) { pubKey = (DSAPublicKey) val; privKey = null; } else { throw newDSAError(getRuntime(), "Neither PUB key nor PRIV key:"); } } } return this; }