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, 2007 Ola Bini <ola@ologix.com> Copyright (C) 2007 Wiliam 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;
 
 
 import org.jruby.Ruby;

Author(s):
Ola Bini
 
 public class PKeyDSA extends PKey {
     private static final long serialVersionUID = 2359742219218350277L;
 
     private static ObjectAllocator PKEYDSA_ALLOCATOR = new ObjectAllocator() {
         public IRubyObject allocate(Ruby runtimeRubyClass klass) {
             return new PKeyDSA(runtimeklass);
         }
     };
     
     public static void createPKeyDSA(Ruby runtimeRubyModule mPKey) {
         RubyClass cDSA = mPKey.defineClassUnder("DSA",mPKey.getClass("PKey"),);
         RubyClass pkeyError = mPKey.getClass("PKeyError");
         mPKey.defineClassUnder("DSAError",pkeyError,pkeyError.getAllocator());
         
 
         cDSA.defineAnnotatedMethods(PKeyDSA.class);
     }
 
     public static RaiseException newDSAError(Ruby runtimeString message) {
         return Utils.newError(runtime"OpenSSL::PKey::DSAError"message);
     }
 
     public PKeyDSA(Ruby runtimeRubyClass type) {
         super(runtimetype);
     }
 
     public PKeyDSA(Ruby runtimeRubyClass typeDSAPrivateKey privKeyDSAPublicKey pubKey) {
         super(runtimetype);
         this. = privKey;
         this. = pubKey;
     }
 
     public PKeyDSA(Ruby runtimeRubyClass typeDSAPublicKey pubKey) {
         this(runtimetypenullpubKey);
    }
    private DSAPrivateKey privKey;
    private DSAPublicKey pubKey;
    
    // specValues holds individual DSAPublicKeySpec components. this allows
    // a public key to be constructed incrementally, as required by the
    // current implementation of Net::SSH.
    // (see net-ssh-1.1.2/lib/net/ssh/transport/ossl/buffer.rb #read_keyblob)
    private BigInteger[] specValues;
    
    private static final int SPEC_Y = 0;
    private static final int SPEC_P = 1;
    private static final int SPEC_Q = 2;
    private static final int SPEC_G = 3;
    
    @Override
        return ;
    }
    @Override
        return ;
    }
    @Override
    String getAlgorithm() {
        return "DSA";
    }
    @JRubyMethod(name = "generate", meta = true)
    public static IRubyObject generate(IRubyObject recvIRubyObject arg) {
        int keysize = RubyNumeric.fix2int(arg);
        PKeyDSA dsa = new PKeyDSA(recv.getRuntime(), (RubyClassrecv);
        dsaGenerate(dsakeysize);
        return dsa;
    }
    /*
     * c: dsa_generate
     */
    private static void dsaGenerate(PKeyDSA dsaint keysizethrows RaiseException {
        try {
            KeyPairGenerator gen = KeyPairGenerator.getInstance("DSA");
            gen.initialize(keysizenew SecureRandom());
            KeyPair pair = gen.generateKeyPair();
            dsa.privKey = (DSAPrivateKey) (pair.getPrivate());
            dsa.pubKey = (DSAPublicKey) (pair.getPublic());
        } catch (Exception e) {
            throw newDSAError(dsa.getRuntime(), e.getMessage());
        }
    }
    @JRubyMethod(rest = true)
    public IRubyObject initialize(IRubyObject[] args) {
        IRubyObject arg;
        IRubyObject pass = null;
        char[] passwd = null;
        if (org.jruby.runtime.Arity.checkArgumentCount(getRuntime(), args, 0, 2) == 0) {
             = null;
             = null;
        } else {
            arg = args[0];
            if (args.length > 1) {
                pass = args[1];
            }
            if (arg instanceof RubyFixnum) {
                int keysize = RubyNumeric.fix2int(arg);
                dsaGenerate(thiskeysize);
            } 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 = ((KeyPairval).getPrivate();
                    PublicKey publicKey = ((KeyPairval).getPublic();
                    if (privateKey instanceof DSAPrivateKey) {
                         = (DSAPrivateKeyprivateKey;
                         = (DSAPublicKeypublicKey;
                    } else {
                        throw newDSAError(getRuntime(), "Neither PUB key nor PRIV key:");
                    }
                } else if (val instanceof DSAPrivateKey) {
                     = (DSAPrivateKeyval;
                } else if (val instanceof DSAPublicKey) {
                     = (DSAPublicKeyval;
                     = null;
                } else {
                    throw newDSAError(getRuntime(), "Neither PUB key nor PRIV key:");
                }
            }
        }
        return this;
    }
    @JRubyMethod(name="public?")
    public IRubyObject public_p() {
        return  != null ? getRuntime().getTrue() : getRuntime().getFalse();
    }
    @JRubyMethod(name="private?")
    public IRubyObject private_p() {
        return  != null ? getRuntime().getTrue() : getRuntime().getFalse();
    }
    public IRubyObject to_der() {
        try {
            byte[] bytes = org.jruby.ext.openssl.impl.PKey.toDerDSAKey();
            return RubyString.newString(getRuntime(), bytes);
        } catch (NoClassDefFoundError ncdfe) {
            throw newDSAError(getRuntime(), OpenSSLReal.bcExceptionMessage(ncdfe));
        } catch (IOException ioe) {
            throw newDSAError(getRuntime(), ioe.getMessage());
        }
    }
    public IRubyObject to_text() {
        StringBuilder result = new StringBuilder();
        if ( != null) {
            int len = .getParams().getP().bitLength();
            result.append("Private-Key: (").append(len).append(" bit)").append("\n");
            result.append("priv:");
            addSplittedAndFormatted(result.getX());
        }
        result.append("pub:");
        addSplittedAndFormatted(result.getY());
        result.append("P:");
        addSplittedAndFormatted(result.getParams().getP());
        result.append("Q:");
        addSplittedAndFormatted(result.getParams().getQ());
        result.append("G:");
        addSplittedAndFormatted(result.getParams().getG());
        return getRuntime().newString(result.toString());
    }
    public IRubyObject public_key() {
        PKeyDSA val = new PKeyDSA(getRuntime(),getMetaClass().getRealClass());
        val.privKey = null;
        val.pubKey = this.;
        return val;
    }
    @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.Cipherargs[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 ( != null) {
                PEMInputOutput.writeDSAPrivateKey(wciphpasswd);
            } else {
                PEMInputOutput.writeDSAPublicKey(w);
            }
            w.close();
            return getRuntime().newString(w.toString());
        } catch (NoClassDefFoundError ncdfe) {
            throw newDSAError(getRuntime(), OpenSSLReal.bcExceptionMessage(ncdfe));
        } catch (IOException ioe) {
            throw newDSAError(getRuntime(), ioe.getMessage());
        }
    }
    public IRubyObject syssign(IRubyObject arg) {
        // TODO
        return getRuntime().getNil();
    }
    public IRubyObject sysverify(IRubyObject argIRubyObject arg2) {
        // TODO
        return getRuntime().getNil();
    }
    
    @JRubyMethod(name="p")
    public synchronized IRubyObject get_p() {
        // FIXME: return only for public?
        DSAKey key;
        BigInteger param;
        if ((key = this.) != null || (key = this.) != null) {
            if ((param = key.getParams().getP()) != null) {
                return BN.newBN(getRuntime(), param);
            }
        } else if ( != null) {
            if ((param = []) != null) {
                return BN.newBN(getRuntime(), param);
            }
        }
        return getRuntime().getNil();
    }
    
    @JRubyMethod(name="p=")
    public synchronized IRubyObject set_p(IRubyObject p) {
        return setKeySpecComponent(p);
    }
    @JRubyMethod(name="q")
    public synchronized IRubyObject get_q() {
        // FIXME: return only for public?
        DSAKey key;
        BigInteger param;
        if ((key = this.) != null || (key = this.) != null) {
            if ((param = key.getParams().getQ()) != null) {
                return BN.newBN(getRuntime(), param);
            }
        } else if ( != null) {
            if ((param = []) != null) {
                return BN.newBN(getRuntime(), param);
            }
        }
        return getRuntime().getNil();
    }
    @JRubyMethod(name="q=")
    public synchronized IRubyObject set_q(IRubyObject q) {
        return setKeySpecComponent(q);
    }
    @JRubyMethod(name="g")
    public synchronized IRubyObject get_g() {
        // FIXME: return only for public?
        DSAKey key;
        BigInteger param;
        if ((key = this.) != null || (key = this.) != null) {
            if ((param = key.getParams().getG()) != null) {
                return BN.newBN(getRuntime(), param);
            }
        } else if ( != null) {
            if ((param = []) != null) {
                return BN.newBN(getRuntime(), param);
            }
        }
        return getRuntime().getNil();
    }
    
    @JRubyMethod(name="g=")
    public synchronized IRubyObject set_g(IRubyObject g) {
        return setKeySpecComponent(g);
    }
    @JRubyMethod(name="pub_key")
    public synchronized IRubyObject get_pub_key() {
        DSAPublicKey key;
        BigInteger param;
        if ((key = this.) != null) {
            return BN.newBN(getRuntime(), key.getY());
        } else if ( != null) {
            if ((param = []) != null) {
                return BN.newBN(getRuntime(), param);
            }
        }
        return getRuntime().getNil();
    }
    @JRubyMethod(name="priv_key")
    public synchronized IRubyObject get_priv_key() {
        DSAPrivateKey key;
        BigInteger param;
        if ((key = this.) != null) {
            return BN.newBN(getRuntime(), key.getX());
        }
        return getRuntime().getNil();
    }
    
    @JRubyMethod(name="pub_key=")
    public synchronized IRubyObject set_pub_key(IRubyObject pub_key) {
        return setKeySpecComponent(pub_key);
    }
    private IRubyObject setKeySpecComponent(int indexIRubyObject value) {
        BigInteger[] vals;
        // illegal to set if we already have a key for this component
        // FIXME: allow changes after keys are created? MRI doesn't prevent it...
        if (this. != null || this. != null ||
                (vals = this.) != null && vals[index] != null) {
            throw newDSAError(getRuntime(), "illegal modification");
        }
        // get the BigInteger value
        BigInteger bival = BN.getBigInteger(value);
        
        if (vals != null) {
            // we already have some vals stored, store this one, too
            vals[index] = bival;
            // check to see if we have all values yet
            for (int i = vals.length; --i >= 0; ) {
                if (vals[i] == null) {
                    // still missing components, return
                    return value;
                }
            }
            // we now have all components. create the key.
            DSAPublicKeySpec spec = new DSAPublicKeySpec(vals[], vals[], vals[], vals[]);
            try {
                this. = (DSAPublicKey)KeyFactory.getInstance("DSA").generatePublic(spec);
            } catch (InvalidKeySpecException e) {
                throw newDSAError(getRuntime(), "invalid keyspec");
            } catch (NoSuchAlgorithmException e) {
                throw newDSAError(getRuntime(), "unsupported key algorithm (DSA)");
            }
            // clear out the specValues
            this. = null;
        } else {
            // first value received, save
            this. = new BigInteger[4];
            this.[index] = bival;
        }
        return value;
    }
}// PKeyDSA
New to GrepCode? Check out our FAQ X