Start line:  
End line:  

Snippet Preview

Snippet HTML Code

Stack Overflow Questions
BEGIN LICENSE BLOCK ***** Version: CPL 1.0/GPL 2.0/LGPL 2.1 The contents of this file are subject to the Common Public License Version 1.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.eclipse.org/legal/cpl-v10.html Software distributed under the License is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for the specific language governing rights and limitations under the License. Copyright (C) 2006 Ola Bini <ola@ologix.com> Copyright (C) 2007 William N Dortch <bill.dortch@gmail.com> Alternatively, the contents of this file may be used under the terms of either of the GNU General Public License Version 2 or later (the "GPL"), or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), in which case the provisions of the GPL or the LGPL are applicable instead of those above. If you wish to allow use of your version of this file only under the terms of either the GPL or the LGPL, and not to allow others to use your version of this file under the terms of the CPL, indicate your decision by deleting the provisions above and replace them with the notice and other provisions required by the GPL or the LGPL. If you do not delete the provisions above, a recipient may use your version of this file under the terms of any one of the CPL, the GPL or the LGPL. END LICENSE BLOCK ***
  
  package org.jruby.ext.openssl.x509store;
  
  import java.io.Writer;
  import java.io.Reader;
  
  
  
  
  
  
  import  org.bouncycastle.asn1.ASN1Encodable;
  import  org.bouncycastle.asn1.ASN1InputStream;
  import  org.bouncycastle.asn1.ASN1OctetString;
  import  org.bouncycastle.asn1.ASN1OutputStream;
  import  org.bouncycastle.asn1.ASN1EncodableVector;
  import  org.bouncycastle.asn1.ASN1Sequence;
  import  org.bouncycastle.asn1.DERInteger;
  import  org.bouncycastle.asn1.DEROctetString;
  import  org.bouncycastle.asn1.DERUTF8String;
  import  org.bouncycastle.asn1.DERSequence;
  import  org.bouncycastle.asn1.DERTaggedObject;
  import  org.bouncycastle.asn1.DERObjectIdentifier;
  import  org.bouncycastle.asn1.DERObject;
  import  org.bouncycastle.asn1.x509.DSAParameter;
  import  org.bouncycastle.asn1.cms.ContentInfo;
  import  org.bouncycastle.asn1.pkcs.EncryptionScheme;
  import  org.bouncycastle.asn1.pkcs.PBES2Parameters;
  import  org.bouncycastle.asn1.pkcs.PBKDF2Params;
  import  org.bouncycastle.asn1.pkcs.PKCSObjectIdentifiers;
  import  org.bouncycastle.asn1.pkcs.PrivateKeyInfo;
  import  org.bouncycastle.asn1.pkcs.RC2CBCParameter;
  import  org.bouncycastle.asn1.pkcs.RSAPrivateKeyStructure;
  import  org.bouncycastle.asn1.x509.RSAPublicKeyStructure;
  import  org.bouncycastle.crypto.BufferedBlockCipher;
  import  org.bouncycastle.crypto.CipherParameters;
  import  org.bouncycastle.crypto.InvalidCipherTextException;
  import  org.bouncycastle.crypto.PBEParametersGenerator;
  import  org.bouncycastle.crypto.engines.DESedeEngine;
  import  org.bouncycastle.crypto.engines.RC2Engine;
  import  org.bouncycastle.crypto.generators.OpenSSLPBEParametersGenerator;
  import  org.bouncycastle.crypto.generators.PKCS5S2ParametersGenerator;
  import  org.bouncycastle.crypto.modes.CBCBlockCipher;
  import  org.bouncycastle.crypto.paddings.PaddedBufferedBlockCipher;
  import  org.bouncycastle.crypto.params.KeyParameter;
  import  org.bouncycastle.crypto.params.ParametersWithIV;
  import  org.bouncycastle.util.encoders.Base64;
  import  org.bouncycastle.util.encoders.Hex;
  import  org.bouncycastle.cms.CMSSignedData;
  
 
 import  org.bouncycastle.asn1.pkcs.PKCS12PBEParams;
 import  org.bouncycastle.asn1.x509.AlgorithmIdentifier;
Helper class to read and write PEM files correctly.

Author(s):
Ola Bini
 
 @SuppressWarnings("deprecation")
 public class PEMInputOutput {
     public static final String BEF = "-----";
     public static final String AFT = "-----";
     public static final String BEF_G = +"BEGIN ";
     public static final String BEF_E = +"END ";
     public static final String PEM_STRING_X509_OLD="X509 CERTIFICATE";
     public static final String PEM_STRING_X509="CERTIFICATE";
     public static final String PEM_STRING_X509_PAIR="CERTIFICATE PAIR";
     public static final String PEM_STRING_X509_TRUSTED="TRUSTED CERTIFICATE";
     public static final String PEM_STRING_X509_REQ_OLD="NEW CERTIFICATE REQUEST";
     public static final String PEM_STRING_X509_REQ="CERTIFICATE REQUEST";
     public static final String PEM_STRING_X509_CRL="X509 CRL";
     public static final String PEM_STRING_EVP_PKEY="ANY PRIVATE KEY";
     public static final String PEM_STRING_PUBLIC="PUBLIC KEY";
     public static final String PEM_STRING_RSA="RSA PRIVATE KEY";
     public static final String PEM_STRING_RSA_PUBLIC="RSA PUBLIC KEY";
     public static final String PEM_STRING_DSA="DSA PRIVATE KEY";
     public static final String PEM_STRING_DSA_PUBLIC="DSA PUBLIC KEY";
     public static final String PEM_STRING_PKCS7="PKCS7";
     public static final String PEM_STRING_PKCS8="ENCRYPTED PRIVATE KEY";
     public static final String PEM_STRING_PKCS8INF="PRIVATE KEY";
     public static final String PEM_STRING_DHPARAMS="DH PARAMETERS";
     public static final String PEM_STRING_SSL_SESSION="SSL SESSION PARAMETERS";
     public static final String PEM_STRING_DSAPARAMS="DSA PARAMETERS";
     public static final String PEM_STRING_ECDSA_PUBLIC="ECDSA PUBLIC KEY";
     public static final String PEM_STRING_ECPARAMETERS="EC PARAMETERS";
     public static final String PEM_STRING_ECPRIVATEKEY="EC PRIVATE KEY";
     
     private static final Pattern DH_PARAM_PATTERN = Pattern.compile(
             "(-----BEGIN DH PARAMETERS-----)(.*)(-----END DH PARAMETERS-----)",
             .);
     private static final int DH_PARAM_GROUP = 2; // the group above containing encoded params
 
     private static BufferedReader makeBuffered(Reader in) {
         if(in instanceof BufferedReader) {
             return (BufferedReader)in;
         }
         return new BufferedReader(in);
     }
 
     private static BufferedWriter makeBuffered(Writer out) {
         if(out instanceof BufferedWriter) {
             return (BufferedWriter)out;
         }
         return new BufferedWriter(out);
     }

    
c: PEM_X509_INFO_read_bio
 
     public static Object readPEM(Reader in,char[] fthrows IOException {
         BufferedReader _in = makeBuffered(in);
         String  line;
         while ((line = _in.readLine()) != null) {
             if(line.indexOf(+) != -1) {
                 try {
                     return readPublicKey(_in,+);
                 } catch (Exception e) {
                     throw new IOException("problem creating public key: " + e.toString());
                 }
             } else if(line.indexOf(+) != -1) {
                 try {
                     return readKeyPair(_in,f"DSA"+);
                 } catch (Exception e) {
                     throw new IOException("problem creating DSA private key: " + e.toString());
                 }
             } else if(line.indexOf(+) != -1) {
                 try {
                     return readPublicKey(_in,+);
                 } catch (Exception e) {
                     throw new IOException("problem creating RSA public key: " + e.toString());
                 }
             } else if(line.indexOf(+) != -1) {
                 try {
                     return readAuxCertificate(_in,+);
                 } catch (Exception e) {
                     throw new IOException("problem creating X509 Aux certificate: " + e.toString());
                 }
             } else if(line.indexOf(+) != -1) {
                 try {
                     return readAuxCertificate(_in,+);
                 } catch (Exception e) {
                     throw new IOException("problem creating X509 Aux certificate: " + e.toString());
                 }
             } else if(line.indexOf(+) != -1) {
                 try {
                     return readAuxCertificate(_in,+);
                 } catch (Exception e) {
                     throw new IOException("problem creating X509 Aux certificate: " + e.toString());
                 }
             } else if(line.indexOf(+) != -1) {
                 try {
                     return readCRL(_in,+);
                 } catch (Exception e) {
                     throw new IOException("problem creating X509 CRL: " + e.toString());
                 }
             } else if(line.indexOf(+) != -1) {
                 try {
                     return readCertificateRequest(_in,+);
                 } catch (Exception e) {
                     throw new IOException("problem creating X509 REQ: " + e.toString());
                 }
             }
         }
         return null
     }
 
     public static byte[] readX509PEM(Reader inthrows IOException {
         BufferedReader _in = makeBuffered(in);
         String line;
         while ((line = _in.readLine()) != null) {
             if (line.indexOf( + ) != -1) {
                 try {
                     return readBytes(_in + );
                 } catch (Exception e) {
                     throw new IOException("problem reading PEM X509 Aux certificate: " + e.toString());
                 }
             } else if (line.indexOf( + ) != -1) {
                 try {
                     return readBytes(_in + );
                 } catch (Exception e) {
                     throw new IOException("problem reading PEM X509 Aux certificate: " + e.toString());
                 }
             } else if (line.indexOf( + ) != -1) {
                 try {
                     return readBytes(_in + );
                 } catch (Exception e) {
                     throw new IOException("problem reading PEM X509 Aux certificate: " + e.toString());
                 }
             } else if (line.indexOf( + ) != -1) {
                 try {
                     return readBytes(_in + );
                 } catch (Exception e) {
                     throw new IOException("problem reading PEM X509 CRL: " + e.toString());
                 }
             } else if (line.indexOf( + ) != -1) {
                 try {
                     return readBytes(_in + );
                 } catch (Exception e) {
                     throw new IOException("problem reading PEM X509 REQ: " + e.toString());
                 }
             }
         }
         return null;
     }

    
c: PEM_read_PrivateKey + PEM_read_bio_PrivateKey CAUTION: KeyPair#getPublic() may be null.
 
     public static KeyPair readPrivateKey(Reader inchar[] passwordthrows IOException {
         BufferedReader _in = makeBuffered(in);
         String line;
         while ((line = _in.readLine()) != null) {
             if (line.indexOf( + ) != -1) {
                 try {
                     return readKeyPair(_inpassword"RSA" + );
                 } catch (Exception e) {
                     throw new IOException("problem creating RSA private key: " + e.toString());
                 }
             } else if (line.indexOf( + ) != -1) {
                 try {
                     return readKeyPair(_inpassword"DSA" + );
                 } catch (Exception e) {
                     throw new IOException("problem creating DSA private key: " + e.toString());
                 }
             } else if (line.indexOf( + ) != -1) {
                 throw new IOException("EC private key not supported");
             } else if (line.indexOf( + ) != -1) {
                 try {
                     byte[] bytes = readBytes(_in + );
                     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( + ) != -1) {
                 try {
                     byte[] bytes = readBytes(_in + );
                     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(eInalgIdpassword);
                     } else {
                         privKey = derivePrivateKeyPBES1(eInalgIdpassword);
                     }
                     return new KeyPair(nullprivKey);
                 } catch (Exception e) {
                     throw new IOException("problem creating private key: " + e.toString());
                 }
             }
         }
         return null;
     }
 
     private static PrivateKey derivePrivateKeyPBES1(org.bouncycastle.asn1.pkcs.EncryptedPrivateKeyInfo eIn, AlgorithmIdentifier algIdchar[] password)
             throws GeneralSecurityException {
         PKCS12PBEParams pkcs12Params = new PKCS12PBEParams((ASN1Sequence) algId.getParameters());
         PBEParameterSpec pbeParams = new PBEParameterSpec(pkcs12Params.getIV(), pkcs12Params.getIterations().intValue());
 
         String algorithm = ASN1Registry.o2a(algId.getAlgorithm());
         algorithm = (algorithm.split("-"))[0];
         Cipher cipher = OpenSSLReal.getCipherBC(algorithm); // need to use BC for PBEParameterSpec.
 
         SecretKeyFactory fact = OpenSSLReal.getSecretKeyFactoryBC(algorithm); // need to use BC for PKCS12PBEParams.
         SecretKey key = fact.generateSecret(new PBEKeySpec(password));
 
         cipher.init(.keypbeParams);
         // wrappedKeyAlgorithm is unknown ("")
         return (PrivateKeycipher.unwrap(eIn.getEncryptedData(), "".);
     }
 
     private static PrivateKey derivePrivateKeyPBES2(org.bouncycastle.asn1.pkcs.EncryptedPrivateKeyInfo eIn, AlgorithmIdentifier algIdchar[] password)
             throws GeneralSecurityException, InvalidCipherTextException {
         PBES2Parameters pbeParams = new PBES2Parameters((ASN1Sequence) algId.getParameters());
         CipherParameters cipherParams = extractPBES2CipherParams(passwordpbeParams);
 
         EncryptionScheme scheme = pbeParams.getEncryptionScheme();
         BufferedBlockCipher cipher;
         if (scheme.getAlgorithm().equals(PKCSObjectIdentifiers.RC2_CBC)) {
             RC2CBCParameter rc2Params = new RC2CBCParameter((ASN1Sequence) scheme.getObject());
             byte[] iv = rc2Params.getIV();
             CipherParameters param = new ParametersWithIV(cipherParamsiv);
             cipher = new PaddedBufferedBlockCipher(new CBCBlockCipher(new RC2Engine()));
             cipher.init(falseparam);
         } else {
             byte[] iv = ((ASN1OctetString) scheme.getObject()).getOctets();
             CipherParameters param = new ParametersWithIV(cipherParamsiv);
             cipher = new PaddedBufferedBlockCipher(new CBCBlockCipher(new DESedeEngine()));
             cipher.init(falseparam);
         }
 
         byte[] data = eIn.getEncryptedData();
         byte[] out = new byte[cipher.getOutputSize(data.length)];
         int len = cipher.processBytes(data, 0, data.lengthout, 0);
         len += cipher.doFinal(outlen);
         byte[] pkcs8 = new byte[len];
         System.arraycopy(out, 0, pkcs8, 0, len);
         KeyFactory fact = KeyFactory.getInstance("RSA"); // It seems to work for both RSA and DSA.
         return fact.generatePrivate(new PKCS8EncodedKeySpec(pkcs8));
     }
 
     private static CipherParameters extractPBES2CipherParams(char[] password, PBES2Parameters pbeParams) {
         PBKDF2Params pbkdfParams = PBKDF2Params.getInstance(pbeParams.getKeyDerivationFunc().getParameters());
         int keySize = 192;
         if (pbkdfParams.getKeyLength() != null) {
             keySize = pbkdfParams.getKeyLength().intValue() * 8;
         }
         int iterationCount = pbkdfParams.getIterationCount().intValue();
         byte[] salt = pbkdfParams.getSalt();
         PBEParametersGenerator generator = new PKCS5S2ParametersGenerator();
         generator.init(PBEParametersGenerator.PKCS5PasswordToBytes(password), saltiterationCount);
         return generator.generateDerivedParameters(keySize);
     }
 
     // PEM_read_bio_PUBKEY
     public static PublicKey readPubKey(Reader inthrows IOException {
         PublicKey pubKey = readRSAPubKey(in);
         if (pubKey == null) {
             pubKey = readDSAPubKey(in);
         }
         return pubKey;
     }
 
     /*
      * c: PEM_read_bio_DSA_PUBKEY
      */
     public static DSAPublicKey readDSAPubKey(Reader inthrows IOException {
         BufferedReader _in = makeBuffered(in);
         String  line;
         while ((line = _in.readLine()) != null) {
             if(line.indexOf(+) != -1) {
                 try {
                     return (DSAPublicKey)readPublicKey(_in,"DSA",+);
                 } catch (Exception e) {
                     throw new IOException("problem creating DSA public key: " + e.toString());
                 }
             }
         }
         return null;
     }
 
     /*
      * c: PEM_read_bio_DSAPublicKey
      */
     public static DSAPublicKey readDSAPublicKey(Reader inchar[] fthrows IOException {
         BufferedReader _in = makeBuffered(in);
         String  line;
         while ((line = _in.readLine()) != null) {
             if(line.indexOf(+) != -1) {
                 try {
                     return (DSAPublicKey)readPublicKey(_in,"DSA",+);
                 } catch (Exception e) {
                     throw new IOException("problem creating DSA public key: " + e.toString());
                 }
             }
         }
         return null
     }
 
     /*
      * c: PEM_read_bio_DSAPrivateKey
      */
     public static KeyPair readDSAPrivateKey(Reader inchar[] fthrows IOException {
         BufferedReader _in = makeBuffered(in);
         String  line;
         while ((line = _in.readLine()) != null) {
             if(line.indexOf(+) != -1) {
                 try {
                     return readKeyPair(_in,f"DSA"+);
                 } catch (Exception e) {
                     throw new IOException("problem creating DSA private key: " + e.toString());
                 }
             }
         }
         return null
     }

    
reads an RSA public key encoded in an SubjectPublicKeyInfo RSA structure. c: PEM_read_bio_RSA_PUBKEY
 
     public static RSAPublicKey readRSAPubKey(Reader inthrows IOException {
         BufferedReader _in = makeBuffered(in);
         String  line;
         while ((line = _in.readLine()) != null) {
             if(line.indexOf(+) != -1) {
                 try {
                     return readRSAPublicKey(_in,+);
                 } catch (Exception e) {
                     throw new IOException("problem creating RSA public key: " + e.toString());
                 }
             } else if(line.indexOf(+) != -1) {
                 try {
                     return readRSAPublicKey(_in,+);
                 } catch (Exception e) {
                     throw new IOException("problem creating RSA public key: " + e.toString());
                 }
             }
         }
         return null
     }

    
reads an RSA public key encoded in an PKCS#1 RSA structure. c: PEM_read_bio_RSAPublicKey
 
     public static RSAPublicKey readRSAPublicKey(Reader inchar[] fthrows IOException {
         BufferedReader _in = makeBuffered(in);
         String  line;
         while ((line = _in.readLine()) != null) {
             if(line.indexOf(+) != -1) {
                 try {
                     return (RSAPublicKey)readPublicKey(_in,"RSA",+);
                 } catch (Exception e) {
                     throw new IOException("problem creating RSA public key: " + e.toString());
                 }
             } else if(line.indexOf(+) != -1) {
                 try {
                     return (RSAPublicKey)readPublicKey(_in,"RSA",+);
                 } catch (Exception e) {
                     throw new IOException("problem creating RSA public key: " + e.toString());
                 }
             }
         }
         return null
     }

    
c: PEM_read_bio_RSAPrivateKey
 
     public static KeyPair readRSAPrivateKey(Reader inchar[] fthrows IOException {
         BufferedReader _in = makeBuffered(in);
         String  line;
         while ((line = _in.readLine()) != null) {
             if(line.indexOf(+) != -1) {
                 try {
                     return readKeyPair(_in,f"RSA"+);
                 } catch (Exception e) {
                     throw new IOException("problem creating RSA private key: " + e.toString());
                 }
             }
         }
         return null;
     }
     public static CMSSignedData readPKCS7(Reader inchar[] fthrows IOException {
         BufferedReader _in = makeBuffered(in);
         String  line;
         while ((line = _in.readLine()) != null) {
             if(line.indexOf(+) != -1) {
                 try {
                     return readPKCS7(_in,f+);
                 } catch (Exception e) {
                     throw new IOException("problem creating PKCS7: " + e.toString());
                 }
             }
         }
         return null;
     }
     public static X509AuxCertificate readX509Certificate(Reader inchar[] fthrows IOException {
         BufferedReader _in = makeBuffered(in);
         String  line;
         while ((line = _in.readLine()) != null) {
             if(line.indexOf(+) != -1) {
                 try {
                     return new X509AuxCertificate(readCertificate(_in,+));
                 } catch (Exception e) {
                     throw new IOException("problem creating X509 certificate: " + e.toString());
                 }
             } else if(line.indexOf(+) != -1) {
                 try {
                     return new X509AuxCertificate(readCertificate(_in,+));
                 } catch (Exception e) {
                     throw new IOException("problem creating X509 certificate: " + e.toString());
                 }
             } else if(line.indexOf(+) != -1) {
                 try {
                     return new X509AuxCertificate(readCertificate(_in,+));
                 } catch (Exception e) {
                     throw new IOException("problem creating X509 certificate: " + e.toString());
                 }
             }
         }
         return null;
     }
     public static X509AuxCertificate readX509Aux(Reader inchar[] fthrows IOException {
         BufferedReader _in = makeBuffered(in);
         String  line;
         while ((line = _in.readLine()) != null) {
             if(line.indexOf(+) != -1) {
                 try {
                     return readAuxCertificate(_in,+);
                 } catch (Exception e) {
                     throw new IOException("problem creating X509 Aux certificate: " + e.toString());
                 }
             } else if(line.indexOf(+) != -1) {
                 try {
                     return readAuxCertificate(_in,+);
                 } catch (Exception e) {
                     throw new IOException("problem creating X509 Aux certificate: " + e.toString());
                 }
             } else if(line.indexOf(+) != -1) {
                 try {
                     return readAuxCertificate(_in,+);
                 } catch (Exception e) {
                     throw new IOException("problem creating X509 Aux certificate: " + e.toString());
                 }
             }
         }
         return null;
     }
     public static X509CRL readX509CRL(Reader inchar[] fthrows IOException {
         BufferedReader _in = makeBuffered(in);
         String  line;
         while ((line = _in.readLine()) != null) {
             if(line.indexOf(+) != -1) {
                 try {
                     return readCRL(_in,+);
                 } catch (Exception e) {
                     throw new IOException("problem creating X509 CRL: " + e.toString());
                 }
             }
         }
         return null;
     }
     public static PKCS10CertificationRequestExt readX509Request(Reader inchar[] fthrows IOException {
         BufferedReader _in = makeBuffered(in);
         String  line;
         while ((line = _in.readLine()) != null) {
             if(line.indexOf(+) != -1) {
                 try {
                     return readCertificateRequest(_in,+);
                 } catch (Exception e) {
                     throw new IOException("problem creating X509 REQ: " + e.toString());
                 }
             }
         }
         return null;
     }
 
     public static DHParameterSpec readDHParameters(Reader _inthrows IOException {
         BufferedReader in = makeBuffered(_in);
         String line;
         StringBuilder buf = new StringBuilder();
         while ((line = in.readLine()) != null) {
             if (line.indexOf( + ) >= 0) {
                 do {
                     buf.append(line.trim());
                 } while (line.indexOf( + ) < 0 && (line = in.readLine()) != null);
                 break;
             }
         }
         Matcher m = .matcher(buf.toString());
         if (m.find()) {
             try {
                 byte[] decoded = Base64.decode(m.group());
                 return org.jruby.ext.openssl.impl.PKey.readDHParameter(decoded);
             } catch (Exception e) {
             }
         }
         return null;
     }
     
     private static byte[] getEncoded(java.security.Key key) {
         if (key != null) {
             return key.getEncoded();
         }
         return new byte[] { '0', 0 };
     }
 
     private static byte[] getEncoded(ASN1Encodable objthrows IOException {
         if (obj != null) {
             return obj.getEncoded();
         }
         return new byte[] { '0', 0 };
     }
 
     private static byte[] getEncoded(CMSSignedData objthrows IOException {
         if (obj != null) {
             return obj.getEncoded();
         }
         return new byte[] { '0', 0 };
     }
 
     private static byte[] getEncoded(X509Certificate certthrows IOException {
         if (cert != null) {
             try {
                 return cert.getEncoded();
             } catch (GeneralSecurityException gse) {
                 throw new IOException("problem with encoding object in write_X509");
             }
         }
         return new byte[] { '0', 0 };
     }
 
     private static byte[] getEncoded(X509CRL crlthrows IOException {
         if (crl != null) {
             try {
                 return crl.getEncoded();
             } catch (GeneralSecurityException gse) {
                 throw new IOException("problem with encoding object in write_X509_CRL");
             }
         }
         return new byte[] { '0', 0 };
     }
 
     public static void writeDSAPublicKey(Writer _outDSAPublicKey objthrows IOException {
         BufferedWriter out = makeBuffered(_out);
         byte[] encoding = getEncoded(obj);
         out.write( +  + );
         out.newLine();
         writeEncoded(outencoding);
         out.write( +  + );
         out.newLine();
         out.flush();
     }
    
writes an RSA public key encoded in an PKCS#1 RSA structure.
 
     public static void writeRSAPublicKey(Writer _outRSAPublicKey objthrows IOException {
         BufferedWriter out = makeBuffered(_out);
         byte[] encoding = getEncoded(obj);
         out.write( +  + );
         out.newLine();
         writeEncoded(outencoding);
         out.write( +  + );
         out.newLine();
         out.flush();
     }
     public static void writePKCS7(Writer _out, ContentInfo objthrows IOException {
         BufferedWriter out = makeBuffered(_out);
         byte[] encoding = getEncoded(obj);
         out.write( +  + );
         out.newLine();
         writeEncoded(out,encoding);
         out.write( +  + );
         out.newLine();
         out.flush();
     }
     public static void writePKCS7(Writer _out, CMSSignedData objthrows IOException {
         BufferedWriter out = makeBuffered(_out);
         byte[] encoding = getEncoded(obj);
         out.write( +  + );
         out.newLine();
         writeEncoded(out,encoding);
         out.write( +  + );
         out.newLine();
         out.flush();
     }
     public static void writePKCS7(Writer _outbyte[] encodedthrows IOException {
         BufferedWriter out = makeBuffered(_out);
         out.write( +  + );
         out.newLine();
         writeEncoded(out,encoded);
         out.write( +  + );
         out.newLine();
         out.flush();
     }
     public static void writeX509Certificate(Writer _outX509Certificate objthrows IOException {
         BufferedWriter out = makeBuffered(_out);
         byte[] encoding = getEncoded(obj);
         out.write( +  + );
         out.newLine();
         writeEncoded(outencoding);
         out.write( +  + );
         out.newLine();
         out.flush();
     }
     public static void writeX509Aux(Writer _outX509AuxCertificate objthrows IOException {
         BufferedWriter out = makeBuffered(_out);
         byte[] encoding = null;
         try {
             if(obj.getAux() == null) {
                 encoding = obj.getEncoded();
             } else {
                 ByteArrayOutputStream baos = new ByteArrayOutputStream();
                 byte[] ymp = obj.getEncoded();
                 baos.write(ymp,0,ymp.length);
             
                 X509Aux aux = obj.getAux();
                 ASN1EncodableVector a1 = new ASN1EncodableVector();
                 if(aux.trust.size()>0) {
                     ASN1EncodableVector a2 = new ASN1EncodableVector();
                     for(String trust : aux.trust) {
                         a2.add(new DERObjectIdentifier(trust));
                     }
                     a1.add(new DERSequence(a2));
                 }
                 if(aux.reject.size()>0) {
                     ASN1EncodableVector a2 = new ASN1EncodableVector();
                     for(String reject : aux.reject) {
                         a2.add(new DERObjectIdentifier(reject));
                     }
                     a1.add(new DERTaggedObject(0,new DERSequence(a2)));
                 }
                 if(aux.alias != null) {
                     a1.add(new DERUTF8String(aux.alias));
                 }
                 if(aux.keyid != null) {
                     a1.add(new DEROctetString(aux.keyid));
                 }
                 if(aux.other.size()>0) {
                     ASN1EncodableVector a2 = new ASN1EncodableVector();
                     for(DERObject other : aux.other) {
                         a2.add(other);
                     }
                     a1.add(new DERTaggedObject(1,new DERSequence(a2)));
                 }
                 ymp = new DERSequence(a1).getEncoded();
                 baos.write(ymp,0,ymp.length);
                 encoding = baos.toByteArray();
             }
         } catch(CertificateEncodingException e) {
             throw new IOException("problem with encoding object in write_X509_AUX");
         }
         out.write( +  + );
         out.newLine();
         writeEncoded(out,encoding);
         out.write( +  + );
         out.newLine();
         out.flush();
     }
     public static void writeX509CRL(Writer _outX509CRL objthrows IOException {
         BufferedWriter out = makeBuffered(_out);
         byte[] encoding = getEncoded(obj);
         out.write( +  + );
         out.newLine();
         writeEncoded(outencoding);
         out.write( +  + );
         out.newLine();
         out.flush();
     }
     public static void writeX509Request(Writer _outPKCS10CertificationRequestExt objthrows IOException {
         BufferedWriter out = makeBuffered(_out);
         byte[] encoding = getEncoded(obj);
         out.write( +  + );
         out.newLine();
         writeEncoded(out,encoding);
         out.write( +  + );
         out.newLine();
         out.flush();
     }
 
     private static SecureRandom random;
     static {
         try {
              = SecureRandom.getInstance("SHA1PRNG");
         } catch(Exception e) {
              = null;
         }
     }
 
     public static void writeDSAPrivateKey(Writer _outDSAPrivateKey objCipherSpec cipherchar[] passwdthrows IOException {
         BufferedWriter out = makeBuffered(_out);
         PrivateKeyInfo info = new PrivateKeyInfo((ASN1Sequence) new ASN1InputStream(getEncoded(obj)).readObject());
         ByteArrayOutputStream bOut = new ByteArrayOutputStream();
         ASN1OutputStream aOut = new ASN1OutputStream(bOut);
 
         DSAParameter p = DSAParameter.getInstance(info.getAlgorithmId().getParameters());
         ASN1EncodableVector v = new ASN1EncodableVector();
         v.add(new DERInteger(0));
         v.add(new DERInteger(p.getP()));
         v.add(new DERInteger(p.getQ()));
         v.add(new DERInteger(p.getG()));
 
         BigInteger x = obj.getX();
         BigInteger y = p.getG().modPow(xp.getP());
 
         v.add(new DERInteger(y));
         v.add(new DERInteger(x));
 
         aOut.writeObject(new DERSequence(v));
         byte[] encoding = bOut.toByteArray();
 
         if (cipher != null && passwd != null) {
             writePemEncrypted(outencodingcipherpasswd);
         } else {
             writePemPlain(outencoding);
         }
     }
 
     public static void writeRSAPrivateKey(Writer _outRSAPrivateCrtKey objCipherSpec cipherchar[] passwdthrows IOException {
         assert (obj != null);
         BufferedWriter out = makeBuffered(_out);
         RSAPrivateKeyStructure keyStruct = new RSAPrivateKeyStructure(obj.getModulus(), obj.getPublicExponent(), obj.getPrivateExponent(), obj.getPrimeP(),
                 obj.getPrimeQ(), obj.getPrimeExponentP(), obj.getPrimeExponentQ(), obj.getCrtCoefficient());
 
         ByteArrayOutputStream bOut = new ByteArrayOutputStream();
         ASN1OutputStream aOut = new ASN1OutputStream(bOut);
         aOut.writeObject(keyStruct);
         aOut.close();
         byte[] encoding = bOut.toByteArray();
 
         if (cipher != null && passwd != null) {
             writePemEncrypted(outencodingcipherpasswd);
         } else {
             writePemPlain(outencoding);
         }
     }
 
     private static void writePemPlain(BufferedWriter outString pemHeaderbyte[] encodingthrows IOException {
         out.write( + pemHeader + );
         out.newLine();
         writeEncoded(outencoding);
         out.write( + pemHeader + );
         out.newLine();
         out.flush();
     }
 
     private static void writePemEncrypted(BufferedWriter outString pemHeaderbyte[] encodingCipherSpec cipherchar[] passwdthrows IOException {
         Cipher c = cipher.getCipher();
         byte[] iv = new byte[c.getBlockSize()];
         .nextBytes(iv);
         byte[] salt = new byte[8];
         System.arraycopy(iv, 0, salt, 0, 8);
         OpenSSLPBEParametersGenerator pGen = new OpenSSLPBEParametersGenerator();
         pGen.init(PBEParametersGenerator.PKCS5PasswordToBytes(passwd), salt);
         KeyParameter param = (KeyParameter) pGen.generateDerivedParameters(cipher.getKeyLenInBits());
         SecretKey secretKey = new SecretKeySpec(param.getKey(), org.jruby.ext.openssl.Cipher.Algorithm.getAlgorithmBase(c));
         byte[] encData = null;
         try {
             c.init(.secretKeynew IvParameterSpec(iv));
             encData = c.doFinal(encoding);
         } catch (GeneralSecurityException gse) {
             throw new IOException("exception using cipher: " + gse.toString());
         }
         out.write( + pemHeader + );
         out.newLine();
         out.write("Proc-Type: 4,ENCRYPTED");
         out.newLine();
         out.write("DEK-Info: " + cipher.getOsslName() + ",");
         writeHexEncoded(outiv);
         out.newLine();
         out.newLine();
         writeEncoded(outencData);
         out.write( + pemHeader + );
         out.flush();
     }
     
     public static void writeDHParameters(Writer _outDHParameterSpec paramsthrows IOException {
         BufferedWriter out = makeBuffered(_out);
         ByteArrayOutputStream bOut = new ByteArrayOutputStream();
         ASN1OutputStream aOut = new ASN1OutputStream(bOut);
 
         ASN1EncodableVector v = new ASN1EncodableVector();
 
         BigInteger value;
         if ((value = params.getP()) != null) {
             v.add(new DERInteger(value));
         }
         if ((value = params.getG()) != null) {
             v.add(new DERInteger(value));
         }
 
         aOut.writeObject(new DERSequence(v));
         byte[] encoding = bOut.toByteArray();
 
         out.write( +  + );
         out.newLine();
         writeEncoded(out,encoding);
         out.write( +  + );
         out.newLine();
         out.flush();
     }
 
     private static String getPrivateKeyTypeFromObjectId(DERObjectIdentifier oid) {
         if (ASN1Registry.obj2nid(oid) == .) {
             return "RSA";
         } else {
             return "DSA";
         }
     }
 
     private static byte[] readBytes(BufferedReader inString endMarkerthrows IOException {
         String          line;
         StringBuffer    buf = new StringBuffer();
   
         while ((line = in.readLine()) != null) {
             if (line.indexOf(endMarker) != -1) {
                 break;
             }
             buf.append(line.trim());
         }
 
         if (line == null) {
             throw new IOException(endMarker + " not found");
         }
 
         return Base64.decode(buf.toString());
     }
 
     private static RSAPublicKey readRSAPublicKey(BufferedReader inString endMarkerthrows IOException {
         Object asnObject = new ASN1InputStream(readBytes(inendMarker)).readObject();
         ASN1Sequence sequence = (ASN1Sequence) asnObject;
         RSAPublicKeyStructure rsaPubStructure = new RSAPublicKeyStructure(sequence);
         RSAPublicKeySpec keySpec = new RSAPublicKeySpec(
                     rsaPubStructure.getModulus(), 
                     rsaPubStructure.getPublicExponent());
 
         try {
             KeyFactory keyFact = KeyFactory.getInstance("RSA");
             return (RSAPublicKeykeyFact.generatePublic(keySpec);
         } catch (NoSuchAlgorithmException e) { 
                 // ignore
         } catch (InvalidKeySpecException e) { 
                 // ignore
         }
 
         return  null;
     }
 
     private static PublicKey readPublicKey(byte[] inputString algString endMarkerthrows IOException {
         KeySpec keySpec = new X509EncodedKeySpec(input);
         try {
             KeyFactory keyFact = KeyFactory.getInstance(alg);
             PublicKey pubKey = keyFact.generatePublic(keySpec);
             return pubKey;
         } catch (NoSuchAlgorithmException e) {
             // ignore
         } catch (InvalidKeySpecException e) {
             // ignore
         }
         return null;
     }
 
     private static PublicKey readPublicKey(BufferedReader inString algString endMarkerthrows IOException {
         return readPublicKey(readBytes(inendMarker), algendMarker);
     }
 
    private static PublicKey readPublicKey(BufferedReader inString endMarkerthrows IOException {
        byte[] input = readBytes(inendMarker);
        String[] algs = { "RSA""DSA" };
        for (int i = 0; i < algs.lengthi++) {
            PublicKey key = readPublicKey(inputalgs[i], endMarker);
            if (key != null) {
                return key;
            }
        }
        return null;
    }

    
Read a Key Pair