Skip to content

Commit 55b9e86

Browse files
committed
Start adding support for missing features
Signed-off-by: Samuel Giddins <segiddins@segiddins.me>
1 parent 97798e0 commit 55b9e86

File tree

8 files changed

+202
-48
lines changed

8 files changed

+202
-48
lines changed

src/main/java/org/jruby/ext/openssl/ASN1.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -281,8 +281,9 @@ private static void defaultObjects(final Ruby runtime) {
281281
addObject(runtime, 184, "AES-256-CBC", "aes-256-cbc","2.16.840.1.101.3.4.1.42");
282282
addObject(runtime, 185, "AES-256-OFB", "aes-256-ofb","2.16.840.1.101.3.4.1.43");
283283
addObject(runtime, 186, "AES-256-CFB", "aes-256-cfb","2.16.840.1.101.3.4.1.44");
284+
addObject(runtime, 187, "Ed25519", "ed25519", "1.3.101.112");
285+
addObject(runtime, 188, "X25519", "x25519", "1.3.101.110");
284286
addObject(runtime, 672, "SHA256", "sha256", "2.16.840.1.101.3.4.2.1");
285-
286287
addObject(runtime, 660, "street", "streetAddress", "2.5.4.9");
287288
addObject(runtime, 391, "DC", "domainComponent", "0.9.2342.19200300.100.1.25");
288289
//addObject(runtime, 509, null, "generationQualifier", "2.5.4.44");

src/main/java/org/jruby/ext/openssl/PKey.java

Lines changed: 68 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,12 +40,17 @@
4040
import java.security.spec.InvalidKeySpecException;
4141
import java.security.spec.PKCS8EncodedKeySpec;
4242
import java.security.spec.X509EncodedKeySpec;
43+
import java.util.ArrayList;
44+
45+
import javax.crypto.spec.DHParameterSpec;
4346

4447
import org.bouncycastle.asn1.ASN1InputStream;
4548
import org.bouncycastle.asn1.ASN1Primitive;
4649
import org.bouncycastle.asn1.ASN1Sequence;
4750
import org.jruby.Ruby;
4851
import org.jruby.RubyClass;
52+
import org.jruby.RubyException;
53+
import org.jruby.RubyInteger;
4954
import org.jruby.RubyModule;
5055
import org.jruby.RubyObject;
5156
import org.jruby.RubyString;
@@ -124,13 +129,16 @@ public static IRubyObject read(final ThreadContext context, IRubyObject recv, IR
124129
pass = args[1].isNil() ? null : args[1].toString().toCharArray();
125130
}
126131

132+
ArrayList<Exception> exceptions = new ArrayList<>();
133+
127134
final RubyString str = readInitArg(context, data);
128135
KeyPair keyPair;
129136
// d2i_PrivateKey_bio
130137
try {
131138
keyPair = readPrivateKey(str, pass);
132139
} catch (IOException e) {
133140
debugStackTrace(runtime, "PKey readPrivateKey", e); /* ignore */
141+
exceptions.add(e);
134142
keyPair = null;
135143
}
136144
// PEM_read_bio_PrivateKey
@@ -154,12 +162,14 @@ public static IRubyObject read(final ThreadContext context, IRubyObject recv, IR
154162
if (pubKey != null) return new PKeyRSA(runtime, (RSAPublicKey) pubKey);
155163
} catch (IOException e) {
156164
debugStackTrace(runtime, "PKey readRSAPublicKey", e); /* ignore */
165+
exceptions.add(e);
157166
}
158167
try {
159168
pubKey = PEMInputOutput.readDSAPublicKey(new StringReader(str.toString()), null);
160169
if (pubKey != null) return new PKeyDSA(runtime, (DSAPublicKey) pubKey);
161170
} catch (IOException e) {
162171
debugStackTrace(runtime, "PKey readDSAPublicKey", e); /* ignore */
172+
exceptions.add(e);
163173
}
164174

165175
final byte[] input = StringHelper.readX509PEM(context, str);
@@ -168,14 +178,27 @@ public static IRubyObject read(final ThreadContext context, IRubyObject recv, IR
168178
pubKey = org.jruby.ext.openssl.impl.PKey.readPublicKey(input);
169179
} catch (IOException e) {
170180
debugStackTrace(runtime, "PKey readPublicKey", e); /* ignore */
181+
exceptions.add(e);
171182
}
172183
// PEM_read_bio_PUBKEY
173184
if (pubKey == null) {
174185
try {
175186
pubKey = PEMInputOutput.readPubKey(new StringReader(str.toString()));
176187
} catch (IOException e) {
177188
debugStackTrace(runtime, "PKey readPubKey", e); /* ignore */
189+
exceptions.add(e);
190+
}
191+
}
192+
193+
if (pubKey == null) {
194+
try {
195+
final PKeyDH dh = new PKeyDH(runtime, str);
196+
return dh;
197+
} catch (Exception e) {
198+
debugStackTrace(runtime, "PKey read DH", e); /* ignore */
199+
exceptions.add(e);
178200
}
201+
179202
}
180203

181204
if (pubKey instanceof RSAPublicKey) {
@@ -188,14 +211,35 @@ public static IRubyObject read(final ThreadContext context, IRubyObject recv, IR
188211
return new PKeyEC(runtime, pubKey);
189212
}
190213

191-
throw newPKeyError(runtime, "Could not parse PKey: unsupported");
214+
exceptions.stream().forEach(Throwable::printStackTrace);
215+
216+
throw newPKeyError(runtime, "Could not parse PKey: unsupported " + pubKey + " " + exceptions);
192217
}
193218

194219
private static String getAlgorithm(final KeyPair key) {
195220
if ( key.getPrivate() != null ) return key.getPrivate().getAlgorithm();
196221
if ( key.getPublic() != null ) return key.getPublic().getAlgorithm();
197222
return null;
198223
}
224+
225+
@JRubyMethod(name = "generate_key", meta = true, required = 1, optional = 1)
226+
public static IRubyObject generateKey(final ThreadContext context, IRubyObject recv, IRubyObject[] args) {
227+
if (!(args[0] instanceof RubyString)) {
228+
throw context.getRuntime().newNotImplementedError("generate_key not implemented for " + args[0].getMetaClass().getName());
229+
}
230+
231+
232+
throw context.getRuntime().newNotImplementedError("generate_key not implemented for " + args[0].inspect());
233+
}
234+
235+
@JRubyMethod(name = "generate_parameters", meta = true, required = 1, optional = 1)
236+
public static IRubyObject generateParameters(final ThreadContext context, IRubyObject recv, IRubyObject[] args) {
237+
if (!(args[0] instanceof RubyString)) {
238+
throw context.getRuntime().newArgumentError("generate_parameters requires a string argument");
239+
}
240+
241+
throw context.getRuntime().newNotImplementedError("generate_parameters not implemented for " + args[0].inspect() + " " + args[1].inspect());
242+
}
199243
}
200244

201245
public PKey(Ruby runtime, RubyClass type) {
@@ -222,6 +266,8 @@ public IRubyObject initialize(ThreadContext context) {
222266

223267
public abstract RubyString to_pem(ThreadContext context, final IRubyObject[] args) ;
224268

269+
public abstract RubyString oid() ;
270+
225271
@JRubyMethod(name = "sign")
226272
public IRubyObject sign(IRubyObject digest, IRubyObject data) {
227273
final Ruby runtime = getRuntime();
@@ -246,6 +292,27 @@ public ASN1Primitive toASN1PublicInfo() throws IOException {
246292
return data;
247293
}
248294

295+
@JRubyMethod(name = "inspect")
296+
public IRubyObject inspect() {
297+
final Ruby runtime = getRuntime();
298+
final StringBuilder result = new StringBuilder();
299+
result.append("#<").append(getMetaClass().getName()).append(" ");
300+
result.append("oid=").append(this.oid().asJavaString());
301+
result.append(">");
302+
return runtime.newString(result.toString());
303+
}
304+
305+
@JRubyMethod(name = "compare?", required = 1)
306+
public IRubyObject compare(ThreadContext context, IRubyObject other) {
307+
if (other instanceof PKey) {
308+
final PKey otherKey = (PKey) other;
309+
if (this.getAlgorithm().equals(otherKey.getAlgorithm())) {
310+
return context.runtime.newBoolean(this.to_der().equals(otherKey.to_der()));
311+
}
312+
}
313+
return context.runtime.getFalse();
314+
}
315+
249316
@Override
250317
public Object toJava(final Class target) {
251318
if (PrivateKey.class.isAssignableFrom(target)) {

src/main/java/org/jruby/ext/openssl/PKeyDH.java

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,15 @@ static void createPKeyDH(final Ruby runtime, final RubyModule PKey, final RubyCl
8686
DH.defineAnnotatedMethods(PKeyDH.class);
8787
}
8888

89+
public PKeyDH(Ruby runtime, RubyString str) {
90+
super(runtime, _DH(runtime));
91+
this.initialize(runtime.getCurrentContext(), new IRubyObject[] { str });
92+
}
93+
94+
static RubyClass _DH(final Ruby runtime) {
95+
return _PKey(runtime).getClass("DH");
96+
}
97+
8998
public static RaiseException newDHError(Ruby runtime, String message) {
9099
return Utils.newError(runtime, _PKey(runtime).getClass("DHError"), message);
91100
}
@@ -431,6 +440,12 @@ public synchronized IRubyObject set_priv_key(IRubyObject arg) {
431440
return arg;
432441
}
433442

443+
@Override
444+
@JRubyMethod
445+
public RubyString oid() {
446+
return getRuntime().newString("DH");
447+
}
448+
434449
@JRubyMethod
435450
public IRubyObject set_key(final ThreadContext context, IRubyObject pub_key, IRubyObject priv_key) {
436451
set_pub_key(pub_key);

src/main/java/org/jruby/ext/openssl/PKeyDSA.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -467,7 +467,7 @@ public IRubyObject sysverify(IRubyObject data, IRubyObject sign) {
467467
}
468468

469469
@JRubyMethod
470-
public IRubyObject oid() {
470+
public RubyString oid() {
471471
return getRuntime().newString("DSA");
472472
}
473473

src/main/java/org/jruby/ext/openssl/PKeyEC.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -551,7 +551,7 @@ public IRubyObject dh_compute_key(final ThreadContext context, final IRubyObject
551551
}
552552

553553
@JRubyMethod
554-
public IRubyObject oid() {
554+
public RubyString oid() {
555555
return getRuntime().newString("id-ecPublicKey");
556556
}
557557

src/main/java/org/jruby/ext/openssl/PKeyRSA.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -574,8 +574,9 @@ private RubyString doCipherRSA(final Ruby runtime,
574574
}
575575
}
576576

577+
@Override
577578
@JRubyMethod
578-
public IRubyObject oid() {
579+
public RubyString oid() {
579580
return getRuntime().newString("rsaEncryption");
580581
}
581582

0 commit comments

Comments
 (0)