@JRubyMethod( name = {"export", "to_pem", "to_s"}, rest = true) public IRubyObject export(IRubyObject[] args) { StringWriter w = new StringWriter(); org.jruby.runtime.Arity.checkArgumentCount(getRuntime(), args, 0, 2); CipherSpec ciph = null; char[] passwd = null; if (args.length > 0 && !args[0].isNil()) { org.jruby.ext.openssl.Cipher c = (org.jruby.ext.openssl.Cipher) args[0]; ciph = new CipherSpec(c.getCipher(), c.getName(), c.getKeyLen() * 8); if (args.length > 1 && !args[1].isNil()) { passwd = args[1].toString().toCharArray(); } } try { if (privKey != null) { PEMInputOutput.writeDSAPrivateKey(w, privKey, ciph, passwd); } else { PEMInputOutput.writeDSAPublicKey(w, pubKey); } w.close(); return getRuntime().newString(w.toString()); } catch (NoClassDefFoundError ncdfe) { throw newDSAError(getRuntime(), OpenSSLReal.bcExceptionMessage(ncdfe)); } catch (IOException ioe) { throw newDSAError(getRuntime(), ioe.getMessage()); } }
@JRubyMethod(name = "read", meta = true, required = 1, optional = 1) public static IRubyObject read( final ThreadContext context, IRubyObject recv, IRubyObject[] args) { final Ruby runtime = context.runtime; final IRubyObject data; final char[] pass; switch (args.length) { case 1: data = args[0]; pass = null; break; default: data = args[0]; pass = args[1].isNil() ? null : args[1].toString().toCharArray(); } final byte[] input = OpenSSLImpl.readX509PEM(context, data); KeyPair key = null; // d2i_PrivateKey_bio try { key = readPrivateKey(input); } catch (IOException ioe) { // ignore } catch (GeneralSecurityException gse) { // ignore } // PEM_read_bio_PrivateKey if (key == null) { try { key = PEMInputOutput.readPrivateKey( new InputStreamReader(new ByteArrayInputStream(input)), pass); } catch (IOException ioe) { // ignore } } if (key != null) { if (key.getPublic().getAlgorithm().equals("RSA")) { return new PKeyRSA( runtime, _PKey(runtime).getClass("RSA"), (RSAPrivateCrtKey) key.getPrivate(), (RSAPublicKey) key.getPublic()); } else if (key.getPublic().getAlgorithm().equals("DSA")) { return new PKeyDSA( runtime, _PKey(runtime).getClass("DSA"), (DSAPrivateKey) key.getPrivate(), (DSAPublicKey) key.getPublic()); } } PublicKey pubKey = null; // d2i_PUBKEY_bio try { pubKey = readPublicKey(input); } catch (IOException ioe) { // ignore } catch (GeneralSecurityException gse) { // ignore } // PEM_read_bio_PUBKEY if (pubKey == null) { try { pubKey = PEMInputOutput.readPubKey(new InputStreamReader(new ByteArrayInputStream(input))); } catch (IOException ioe) { // ignore } } if (pubKey != null) { if (pubKey.getAlgorithm().equals("RSA")) { return new PKeyRSA(runtime, _PKey(runtime).getClass("RSA"), (RSAPublicKey) pubKey); } else if (key.getPublic().getAlgorithm().equals("DSA")) { return new PKeyDSA(runtime, _PKey(runtime).getClass("DSA"), (DSAPublicKey) pubKey); } } throw runtime.newArgumentError("Could not parse PKey"); }
@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; }