Skip to content

Commit

Permalink
[fix] DSA key compatibility when set_pqg
Browse files Browse the repository at this point in the history
  • Loading branch information
kares committed Dec 6, 2024
1 parent f4c86f3 commit 4193da0
Show file tree
Hide file tree
Showing 4 changed files with 83 additions and 30 deletions.
7 changes: 0 additions & 7 deletions lib/jopenssl/_compat23.rb
Original file line number Diff line number Diff line change
Expand Up @@ -33,13 +33,6 @@ def set_key(pub_key, priv_key)
self
end

def set_pqg(p, q, g)
self.p = p
self.q = q
self.g = g
self
end

end

end
Expand Down
80 changes: 58 additions & 22 deletions src/main/java/org/jruby/ext/openssl/PKeyDSA.java
Original file line number Diff line number Diff line change
Expand Up @@ -450,11 +450,11 @@ private IRubyObject toBN(BigInteger value) {
}

private synchronized BigInteger getP() {
if (dsa_p != null) return dsa_p;

DSAKey key = getDsaKey();
if (key != null) {
return key.getParams().getP();
}
return dsa_p;
if (key != null) return key.getParams().getP();
return null;
}

@JRubyMethod(name = "p")
Expand All @@ -468,11 +468,11 @@ public synchronized IRubyObject set_p(IRubyObject p) {
}

private synchronized BigInteger getQ() {
if (dsa_q != null) return dsa_q;

DSAKey key = getDsaKey();
if (key != null) {
return key.getParams().getQ();
}
return dsa_q;
if (key != null) return key.getParams().getQ();
return null;
}

@JRubyMethod(name = "q")
Expand All @@ -486,11 +486,11 @@ public synchronized IRubyObject set_q(IRubyObject q) {
}

private synchronized BigInteger getG() {
if (dsa_g != null) return dsa_g;

DSAKey key = getDsaKey();
if (key != null) {
return key.getParams().getG();
}
return dsa_g;
if (key != null) return key.getParams().getG();
return null;
}

@JRubyMethod(name = "g")
Expand All @@ -503,6 +503,15 @@ public synchronized IRubyObject set_g(IRubyObject g) {
return setKeySpecComponent(SPEC_G, g);
}

@JRubyMethod
public IRubyObject set_pqg(IRubyObject p, IRubyObject q, IRubyObject g) {
this.dsa_p = BN.getBigInteger(p);
this.dsa_q = BN.getBigInteger(q);
this.dsa_g = BN.getBigInteger(g);
generateKeyInternal();
return this;
}

@JRubyMethod(name = "priv_key")
public synchronized IRubyObject get_priv_key() {
DSAPrivateKey key;
Expand Down Expand Up @@ -533,7 +542,6 @@ public synchronized IRubyObject set_pub_key(IRubyObject pub_key) {

private IRubyObject setKeySpecComponent(final int index, final IRubyObject value) {
final BigInteger val = BN.getBigInteger(value);

switch (index) {
case SPEC_X: this.dsa_x = val; break;
case SPEC_Y: this.dsa_y = val; break;
Expand All @@ -542,19 +550,49 @@ private IRubyObject setKeySpecComponent(final int index, final IRubyObject value
case SPEC_G: this.dsa_g = val; break;
}

generateKeyInternal();
return value;
}

private BigInteger getX() {
if (dsa_x != null) return dsa_x;

DSAPrivateKey key;
if ((key = this.privateKey) != null) {
return key.getX();
}
return null;
}

private BigInteger getY() {
if (dsa_y != null) return dsa_y;

DSAPublicKey key;
if ((key = this.publicKey) != null) {
return key.getY();
}
return null;
}

private void generateKeyInternal() {
// Don't access the dsa_p, dsa_q and dsa_g fields directly. They may
// have already been consumed and cleared.
BigInteger _dsa_p = getP();
BigInteger _dsa_q = getQ();
BigInteger _dsa_g = getG();
final BigInteger dsa_p = getP();
final BigInteger dsa_q = getQ();
final BigInteger dsa_g = getG();

final BigInteger dsa_x = getX();
final BigInteger dsa_y = getY();

if ( dsa_x != null && _dsa_p != null && _dsa_q != null && _dsa_g != null ) {
if ( dsa_x != null && dsa_p != null && dsa_q != null && dsa_g != null ) {
// we now have all private key components. create the key :
DSAPrivateKeySpec spec = new DSAPrivateKeySpec(dsa_x, _dsa_p, _dsa_q, _dsa_g);
DSAPrivateKeySpec spec = new DSAPrivateKeySpec(dsa_x, dsa_p, dsa_q, dsa_g);
try {
this.privateKey = (DSAPrivateKey) SecurityHelper.getKeyFactory("DSA").generatePrivate(spec);
}
catch (InvalidKeySpecException e) {
e.printStackTrace();

throw newDSAError(getRuntime(), "invalid keyspec", e);
}
catch (NoSuchAlgorithmException e) {
Expand All @@ -564,9 +602,9 @@ private IRubyObject setKeySpecComponent(final int index, final IRubyObject value
this.dsa_x = this.dsa_p = this.dsa_q = this.dsa_g = null;
}

if ( dsa_y != null && _dsa_p != null && _dsa_q != null && _dsa_g != null ) {
if ( dsa_y != null && dsa_p != null && dsa_q != null && dsa_g != null ) {
// we now have all public key components. create the key :
DSAPublicKeySpec spec = new DSAPublicKeySpec(dsa_y, _dsa_p, _dsa_q, _dsa_g);
DSAPublicKeySpec spec = new DSAPublicKeySpec(dsa_y, dsa_p, dsa_q, dsa_g);
try {
this.publicKey = (DSAPublicKey) SecurityHelper.getKeyFactory("DSA").generatePublic(spec);
}
Expand All @@ -579,8 +617,6 @@ private IRubyObject setKeySpecComponent(final int index, final IRubyObject value
// clear out the specValues
this.dsa_y = this.dsa_p = this.dsa_q = this.dsa_g = null;
}

return value;
}

private static final int SPEC_X = 0;
Expand Down
14 changes: 13 additions & 1 deletion src/test/ruby/dsa/test_dsa.rb
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,18 @@ def setup
super
end

def test_dup
key = Fixtures.pkey("dsa1024")
key2 = key.dup
assert_equal key.params, key2.params

# PKey is immutable in OpenSSL >= 3.0
#if !openssl?(3, 0, 0)
key2.set_pqg(key2.p, key2.q, key2.g + 1)
assert_not_equal key.params, key2.params
#end
end

def test_dsa_param_accessors
key_file = File.join(File.dirname(__FILE__), 'private_key.pem')
key = OpenSSL::PKey::DSA.new(File.read(key_file))
Expand Down Expand Up @@ -65,7 +77,7 @@ def test_dsa_sys_sign_verify
doc = 'Sign ME!'
digest = OpenSSL::Digest::SHA1.digest(doc)
sig = dsa.syssign(digest)
puts sig.inspect if $VERBOSE
#puts sig.inspect if $VERBOSE
assert dsa.sysverify(digest, sig).eql?(true)
end

Expand Down
12 changes: 12 additions & 0 deletions src/test/ruby/fixtures/pkey/dsa1024
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
-----BEGIN DSA PRIVATE KEY-----
MIIBugIBAAKBgQCH9aAoXvWWThIjkA6D+nI1F9ksF9iDq594rkiGNOT9sPDOdB+n
D+qeeeeloRlj19ymCSADPI0ZLRgkchkAEnY2RnqnhHOjVf/roGgRbW+iQDMbQ9wa
/pvc6/fAbsu1goE1hBYjm98/sZEeXavj8tR56IXnjF1b6Nx0+sgeUKFKEQIVAMiz
4BJUFeTtddyM4uadBM7HKLPRAoGAZdLBSYNGiij7vAjesF5mGUKTIgPd+JKuBEDx
OaBclsgfdoyoF/TMOkIty+PVlYD+//Vl2xnoUEIRaMXHwHfm0r2xUX++oeRaSScg
YizJdUxe5jvBuBszGPRc/mGpb9YvP0sB+FL1KmuxYmdODfCe51zl8uM/CVhouJ3w
DjmRGscCgYAuFlfC7p+e8huCKydfcv/beftqjewiOPpQ3u5uI6KPCtCJPpDhs3+4
IihH2cPsAlqwGF4tlibW1+/z/OZ1AZinPK3y7b2jSJASEaPeEltVzB92hcd1khk2
jTYcmSsV4VddplOPK9czytR/GbbibxsrhhgZUbd8LPbvIgaiadJ1PgIUBnJ/5vN2
CVArsEzlPUCbohPvZnE=
-----END DSA PRIVATE KEY-----

0 comments on commit 4193da0

Please sign in to comment.