Skip to content

Commit ab5d342

Browse files
committed
[fix] work-around CSR failing with EC key (#294)
1 parent 3518d8e commit ab5d342

File tree

3 files changed

+45
-24
lines changed

3 files changed

+45
-24
lines changed

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

Lines changed: 16 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,6 @@
4242
import org.bouncycastle.asn1.ASN1Encoding;
4343
import org.bouncycastle.asn1.ASN1Set;
4444
import org.bouncycastle.asn1.ASN1ObjectIdentifier;
45-
import org.bouncycastle.asn1.ASN1Sequence;
4645
import org.bouncycastle.asn1.pkcs.Attribute;
4746
import org.bouncycastle.asn1.x500.X500Name;
4847

@@ -61,6 +60,7 @@
6160
import org.jruby.runtime.Visibility;
6261

6362
import org.jruby.ext.openssl.impl.PKCS10Request;
63+
6464
import static org.jruby.ext.openssl.OpenSSL.*;
6565
import static org.jruby.ext.openssl.PKey._PKey;
6666
import static org.jruby.ext.openssl.X509._X509;
@@ -319,7 +319,7 @@ public IRubyObject sign(final ThreadContext context,
319319
request = null; getRequest().sign( privateKey, digAlg );
320320
}
321321
catch (InvalidKeyException e) {
322-
debug(runtime, "X509Request#sign failed", e);
322+
debug(runtime, "X509Request#sign invalid key:", e);
323323
throw newRequestError(runtime, e);
324324
}
325325
catch (Exception e) {
@@ -344,23 +344,25 @@ private Attribute newAttributeImpl(final ThreadContext context,
344344

345345
@JRubyMethod
346346
public IRubyObject verify(final ThreadContext context, IRubyObject key) {
347-
final Ruby runtime = context.runtime; final PublicKey publicKey;
347+
final Ruby runtime = context.runtime;
348348
try {
349-
publicKey = ( (PKey) key.callMethod(context, "public_key") ).getPublicKey();
350-
return runtime.newBoolean( getRequest().verify(publicKey) );
349+
if (!(key instanceof PKey)) { // due PKeyEC
350+
key = key.callMethod(context, "public_key");
351+
if (!(key instanceof PKey)) {
352+
throw context.runtime.newTypeError(key, _PKey(runtime));
353+
}
354+
}
355+
boolean signatureValid = getRequest().verify( ((PKey) key).getPublicKey() );
356+
return runtime.newBoolean(signatureValid);
351357
}
352358
catch (InvalidKeyException e) {
353-
debug(runtime, "X509::Request#verify invalid key", e);
359+
debug(runtime, "X509Request#verify invalid key:", e);
354360
throw newRequestError(runtime, "invalid key supplied", e);
355361
}
356-
//catch (IOException e) {
357-
// debug(runtime, "X509::Request.verify failed", e);
358-
// return runtime.getFalse();
359-
//}
360-
//catch (RuntimeException e) {
361-
// debug(runtime, "X509::Request.verify failed", e);
362-
// return runtime.getFalse();
363-
//}
362+
catch (RuntimeException e) {
363+
debugStackTrace(runtime, "X509Request#verify", e);
364+
return context.nil;
365+
}
364366
}
365367

366368
@JRubyMethod

src/main/java/org/jruby/ext/openssl/impl/PKCS10Request.java

Lines changed: 17 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,8 @@
5151
import org.bouncycastle.asn1.DLSequence;
5252
import org.bouncycastle.asn1.pkcs.CertificationRequestInfo;
5353
import org.bouncycastle.asn1.x500.X500Name;
54+
import org.bouncycastle.asn1.x9.X9ObjectIdentifiers;
55+
import org.bouncycastle.operator.DefaultAlgorithmNameFinder;
5456
import org.bouncycastle.pkcs.PKCS10CertificationRequest;
5557
import org.bouncycastle.pkcs.PKCS10CertificationRequestBuilder;
5658
import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo;
@@ -136,16 +138,14 @@ public PKCS10CertificationRequest sign(final PrivateKey privateKey,
136138
final String digestAlg)
137139
throws NoSuchAlgorithmException, InvalidKeyException {
138140
String sigAlg = digestAlg + "WITH" + getPublicKeyAlgorithm();
139-
return sign( privateKey,
140-
new DefaultSignatureAlgorithmIdentifierFinder().find( sigAlg )
141-
);
141+
return sign(privateKey, new DefaultSignatureAlgorithmIdentifierFinder().find(sigAlg));
142142
}
143143

144144
// verify
145145

146146
public boolean verify(final PublicKey publicKey) throws InvalidKeyException {
147147
if ( signedRequest == null ) {
148-
if ( true ) throw new IllegalStateException("no signed request");
148+
assert false : "no signed request";
149149
return false;
150150
}
151151

@@ -206,16 +206,23 @@ public void setPublicKey(final PublicKey publicKey) {
206206
resetSignedRequest();
207207
}
208208

209+
/**
210+
* @return e.g. "RSA" or "ECDSA"
211+
*/
209212
private String getPublicKeyAlgorithm() {
210-
//if ( publicKeyAlgorithm == null ) {
211-
// throw new IllegalStateException("no public key info");
212-
//}
213-
//return publicKeyAlgorithm;
214213
if ( publicKeyInfo == null ) {
215214
throw new IllegalStateException("no public key info");
216215
}
217-
AlgorithmIdentifier algId = publicKeyInfo.getAlgorithm();
218-
return ASN1Registry.oid2sym( algId.getAlgorithm() );
216+
217+
final AlgorithmIdentifier algId = publicKeyInfo.getAlgorithm();
218+
// NOTE: BC's DefaultAlgorithmNameFinder does not handle the EC oid
219+
if (X9ObjectIdentifiers.id_ecPublicKey.equals(algId.getAlgorithm())) {
220+
return "ECDSA";
221+
}
222+
// e.g. PKCSObjectIdentifiers.rsaEncryption -> "RSA"
223+
final String algName = new DefaultAlgorithmNameFinder().getAlgorithmName(algId);
224+
assert algId.getAlgorithm().getId() != algName : "could not resolve name for oid: " + algId.getAlgorithm();
225+
return algName;
219226
}
220227

221228
public PublicKey generatePublicKey() throws NoSuchAlgorithmException,

src/test/ruby/x509/test_x509req.rb

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,18 @@ def test_csr_request_extensions
2828
assert_equal 0, csr.version
2929
end
3030

31+
def test_csr_request_ec_key
32+
key = OpenSSL::PKey::EC.generate('secp384r1')
33+
34+
csr = OpenSSL::X509::Request.new
35+
csr.public_key = key
36+
csr.subject = OpenSSL::X509::Name.new([['CN', 'foo.bar.cat', OpenSSL::ASN1::UTF8STRING]])
37+
csr.version = 2
38+
csr.sign key, OpenSSL::Digest::SHA256.new # does not raise
39+
40+
assert_true csr.verify(key)
41+
end
42+
3143
def test_version
3244
csr = OpenSSL::X509::Request.new
3345
assert_equal 0, csr.version

0 commit comments

Comments
 (0)