private IRubyObject setKeySpecComponent(int index, IRubyObject 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.pubKey != null || this.privKey != null || (vals = this.specValues) != 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[SPEC_Y], vals[SPEC_P], vals[SPEC_Q], vals[SPEC_G]); try { this.pubKey = (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.specValues = null; } else { // first value received, save this.specValues = new BigInteger[4]; this.specValues[index] = bival; } return value; }