Skip to content

Commit 3c2ddfc

Browse files
committed
avoid, once again, installing BC provider on boot (due OCSP support)
1 parent bfa3de3 commit 3c2ddfc

7 files changed

Lines changed: 98 additions & 115 deletions

File tree

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -155,7 +155,7 @@ public String getName() {
155155
}
156156

157157
@JRubyMethod(required = 1, optional = 1, visibility = Visibility.PRIVATE)
158-
public IRubyObject initialize(final ThreadContext context, final IRubyObject[] args) {
158+
public IRubyObject initialize(final ThreadContext context, final IRubyObject... args) {
159159
IRubyObject data = context.nil;
160160
if ( args.length > 1 ) data = args[1];
161161
initializeImpl(context.runtime, args[0].asString(), data);

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

Lines changed: 36 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -32,11 +32,13 @@
3232
*/
3333
package org.jruby.ext.openssl;
3434

35-
import java.security.Security;
3635
import java.util.HashMap;
3736
import java.util.Map;
3837

39-
import org.bouncycastle.jce.provider.BouncyCastleProvider;
38+
import org.bouncycastle.operator.jcajce.JcaContentSignerBuilder;
39+
import org.bouncycastle.operator.jcajce.JcaContentVerifierProviderBuilder;
40+
import org.bouncycastle.operator.jcajce.JcaDigestCalculatorProviderBuilder;
41+
4042
import org.jruby.Ruby;
4143
import org.jruby.RubyClass;
4244
import org.jruby.RubyFixnum;
@@ -137,7 +139,7 @@ public class OCSP {
137139
private static final int _V_RESPID_KEY =1;
138140

139141
static {
140-
Map<Integer, String> resMap = new HashMap<Integer, String>();
142+
Map<Integer, String> resMap = new HashMap<>(8, 1);
141143
resMap.put(_RESPONSE_STATUS_SUCCESSFUL, _RESPONSE_STATUS_SUCCESSFUL_STR);
142144
resMap.put(_RESPONSE_STATUS_MALFORMEDREQUEST, _RESPONSE_STATUS_MALFORMEDREQUEST_STR);
143145
resMap.put(_RESPONSE_STATUS_INTERNALERROR, _RESPONSE_STATUS_INTERNALERROR_STR);
@@ -149,7 +151,6 @@ public class OCSP {
149151

150152
static void createOCSP(final Ruby runtime, final RubyModule OpenSSL, final RubyClass OpenSSLError) {
151153
final RubyModule OCSP = OpenSSL.defineModuleUnder("OCSP");
152-
Security.addProvider(new BouncyCastleProvider());
153154
OCSP.defineClassUnder("OCSPError", OpenSSLError, OpenSSLError.getAllocator());
154155

155156
OCSPBasicResponse.createBasicResponse(runtime, OCSP);
@@ -211,4 +212,35 @@ static RubyModule _OCSP(final Ruby runtime) {
211212
return (RubyModule) runtime.getModule("OpenSSL").getConstant("OCSP");
212213
}
213214

215+
static byte[] generateNonce(final Ruby runtime) {
216+
// OSSL currently generates 16 byte nonce by default
217+
return generateNonce(runtime, new byte[16]);
218+
}
219+
220+
static byte[] generateNonce(final Ruby runtime, byte[] bytes) {
221+
OpenSSL.getSecureRandom(runtime).nextBytes(bytes);
222+
return bytes;
223+
}
224+
225+
static JcaContentSignerBuilder newJcaContentSignerBuilder(String alg) {
226+
JcaContentSignerBuilder builder = new JcaContentSignerBuilder(alg);
227+
if (SecurityHelper.isProviderAvailable("BC")) builder.setProvider("BC");
228+
else builder.setProvider( SecurityHelper.getSecurityProvider() );
229+
return builder;
230+
}
231+
232+
static JcaContentVerifierProviderBuilder newJcaContentVerifierProviderBuilder() {
233+
JcaContentVerifierProviderBuilder builder = new JcaContentVerifierProviderBuilder();
234+
if (SecurityHelper.isProviderAvailable("BC")) builder.setProvider("BC");
235+
else builder.setProvider( SecurityHelper.getSecurityProvider() );
236+
return builder;
237+
}
238+
239+
static JcaDigestCalculatorProviderBuilder newJcaDigestCalculatorProviderBuilder() {
240+
JcaDigestCalculatorProviderBuilder builder = new JcaDigestCalculatorProviderBuilder();
241+
if (SecurityHelper.isProviderAvailable("BC")) builder.setProvider("BC");
242+
else builder.setProvider( SecurityHelper.getSecurityProvider() );
243+
return builder;
244+
}
245+
214246
}

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

Lines changed: 40 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,18 @@
3232
*/
3333
package org.jruby.ext.openssl;
3434

35+
import java.io.IOException;
36+
import java.security.MessageDigest;
37+
import java.security.PublicKey;
38+
import java.security.cert.CertificateEncodingException;
39+
import java.security.cert.CertificateParsingException;
40+
import java.util.ArrayList;
41+
import java.util.Arrays;
42+
import java.util.Collections;
43+
import java.util.Date;
44+
import java.util.Iterator;
45+
import java.util.List;
46+
3547
import org.bouncycastle.asn1.ASN1GeneralizedTime;
3648
import org.bouncycastle.asn1.ASN1ObjectIdentifier;
3749
import org.bouncycastle.asn1.DERNull;
@@ -60,6 +72,7 @@
6072
import org.bouncycastle.operator.jcajce.JcaContentSignerBuilder;
6173
import org.bouncycastle.operator.jcajce.JcaContentVerifierProviderBuilder;
6274
import org.bouncycastle.operator.jcajce.JcaDigestCalculatorProviderBuilder;
75+
6376
import org.jruby.Ruby;
6477
import org.jruby.RubyArray;
6578
import org.jruby.RubyBoolean;
@@ -71,7 +84,6 @@
7184
import org.jruby.RubyString;
7285
import org.jruby.RubyTime;
7386
import org.jruby.anno.JRubyMethod;
74-
import org.jruby.exceptions.RaiseException;
7587
import org.jruby.ext.openssl.impl.ASN1Registry;
7688
import org.jruby.ext.openssl.x509store.X509AuxCertificate;
7789
import org.jruby.ext.openssl.x509store.X509Utils;
@@ -82,21 +94,9 @@
8294
import org.jruby.runtime.builtin.IRubyObject;
8395

8496
import static org.jruby.ext.openssl.Digest._Digest;
85-
import static org.jruby.ext.openssl.OCSP._OCSP;
86-
import static org.jruby.ext.openssl.OCSP.newOCSPError;
97+
import static org.jruby.ext.openssl.OCSP.*;
8798
import static org.jruby.ext.openssl.X509._X509;
8899

89-
import java.io.IOException;
90-
import java.security.MessageDigest;
91-
import java.security.PublicKey;
92-
import java.security.cert.CertificateEncodingException;
93-
import java.security.cert.CertificateParsingException;
94-
import java.util.ArrayList;
95-
import java.util.Arrays;
96-
import java.util.Date;
97-
import java.util.Iterator;
98-
import java.util.List;
99-
100100
/*
101101
* An OpenSSL::OCSP::BasicResponse contains the status of a certificate
102102
* check which is created from an OpenSSL::OCSP::Request.
@@ -171,10 +171,10 @@ public OCSPBasicResponse add_nonce(IRubyObject[] args) {
171171

172172
byte[] tmpNonce;
173173
if ( Arity.checkArgumentCount(runtime, args, 0, 1) == 0 ) {
174-
tmpNonce = generateNonce();
174+
tmpNonce = generateNonce(runtime);
175175
}
176176
else {
177-
RubyString input = (RubyString)args[0];
177+
RubyString input = (RubyString) args[0];
178178
tmpNonce = input.getBytes();
179179
}
180180

@@ -270,7 +270,7 @@ public IRubyObject sign(final ThreadContext context, IRubyObject[] args) {
270270
IRubyObject flags = context.nil;
271271
IRubyObject digest = context.nil;
272272
Digest digestInstance = new Digest(runtime, _Digest(runtime));
273-
List<X509CertificateHolder> addlCerts = new ArrayList<X509CertificateHolder>();
273+
List<X509CertificateHolder> addlCerts = new ArrayList<>();
274274

275275
switch (Arity.checkArgumentCount(runtime, args, 2, 5)) {
276276
case 3 :
@@ -289,7 +289,7 @@ public IRubyObject sign(final ThreadContext context, IRubyObject[] args) {
289289
break;
290290
}
291291

292-
if (digest.isNil()) digest = digestInstance.initialize(context, new IRubyObject[] { RubyString.newString(runtime, "SHA1") });
292+
if (digest.isNil()) digest = digestInstance.initialize(context, RubyString.newString(runtime, "SHA1"));
293293
if (!flags.isNil()) flag = RubyFixnum.fix2int(flags);
294294
if (additionalCerts.isNil()) flag |= RubyFixnum.fix2int((RubyFixnum)_OCSP(runtime).getConstant(OCSP_NOCERTS));
295295

@@ -299,22 +299,19 @@ public IRubyObject sign(final ThreadContext context, IRubyObject[] args) {
299299
String keyAlg = signerKey.getAlgorithm();
300300
String digAlg = ((Digest) digest).getShortAlgorithm();
301301

302-
JcaContentSignerBuilder signerBuilder = new JcaContentSignerBuilder(digAlg + "with" + keyAlg);
303-
signerBuilder.setProvider("BC");
304-
ContentSigner contentSigner = null;
302+
JcaContentSignerBuilder signerBuilder = newJcaContentSignerBuilder(digAlg + "with" + keyAlg);
303+
ContentSigner contentSigner;
305304
try {
306305
contentSigner = signerBuilder.build(signerKey.getPrivateKey());
307306
}
308307
catch (OperatorCreationException e) {
309308
throw newOCSPError(runtime, e);
310309
}
311310

312-
BasicOCSPRespBuilder respBuilder = null;
311+
final BasicOCSPRespBuilder respBuilder;
313312
try {
314313
if ((flag & RubyFixnum.fix2int((RubyFixnum)_OCSP(runtime).getConstant(OCSP_RESPID_KEY))) != 0) {
315-
JcaDigestCalculatorProviderBuilder dcpb = new JcaDigestCalculatorProviderBuilder();
316-
dcpb.setProvider("BC");
317-
DigestCalculatorProvider dcp = dcpb.build();
314+
DigestCalculatorProvider dcp = newJcaDigestCalculatorProviderBuilder().build();
318315
DigestCalculator calculator = dcp.get(contentSigner.getAlgorithmIdentifier());
319316
respBuilder = new BasicOCSPRespBuilder(SubjectPublicKeyInfo.getInstance(signerKey.getPublicKey().getEncoded()), calculator);
320317
}
@@ -383,8 +380,7 @@ public IRubyObject verify(final ThreadContext context, IRubyObject[] args) {
383380
flags = RubyFixnum.fix2int(args[2]);
384381
}
385382

386-
JcaContentVerifierProviderBuilder jcacvpb = new JcaContentVerifierProviderBuilder();
387-
jcacvpb.setProvider("BC");
383+
JcaContentVerifierProviderBuilder jcacvpb = newJcaContentVerifierProviderBuilder();
388384
BasicOCSPResp basicOCSPResp = getBasicOCSPResp();
389385

390386
java.security.cert.Certificate signer = findSignerCert(context, asn1BCBasicOCSPResp, convertRubyCerts(certificates), flags);
@@ -405,11 +401,12 @@ public IRubyObject verify(final ThreadContext context, IRubyObject[] args) {
405401
}
406402
}
407403
if ((flags & RubyFixnum.fix2int((RubyFixnum)_OCSP(runtime).getConstant(OCSP_NOVERIFY))) == 0) {
408-
List<X509Cert> untrustedCerts = null;
409-
if ((flags & RubyFixnum.fix2int((RubyFixnum)_OCSP(runtime).getConstant(OCSP_NOCHAIN))) != 0) {
404+
List<X509Cert> untrustedCerts;
405+
if ((flags & RubyFixnum.fix2int((RubyFixnum)_OCSP(runtime).getConstant(OCSP_NOCHAIN))) != 0) {
406+
untrustedCerts = Collections.EMPTY_LIST;
410407
}
411408
else if (basicOCSPResp.getCerts() != null && (certificates != null && !((RubyArray)certificates).isEmpty())) {
412-
untrustedCerts = getCertsFromResp();
409+
untrustedCerts = getCertsFromResp(context);
413410

414411
Iterator<java.security.cert.Certificate> certIt = ((RubyArray)certificates).iterator();
415412
while (certIt.hasNext()) {
@@ -422,14 +419,10 @@ else if (basicOCSPResp.getCerts() != null && (certificates != null && !((RubyArr
422419
}
423420
}
424421
else {
425-
untrustedCerts = getCertsFromResp();
422+
untrustedCerts = getCertsFromResp(context);
426423
}
427424

428-
RubyArray rUntrustedCerts = RubyArray.newEmptyArray(runtime);
429-
if (untrustedCerts != null) {
430-
X509Cert[] rubyCerts = new X509Cert[untrustedCerts.size()];
431-
rUntrustedCerts = RubyArray.newArray(runtime, untrustedCerts.toArray(rubyCerts));
432-
}
425+
RubyArray rUntrustedCerts = RubyArray.newArray(runtime, untrustedCerts);
433426
X509StoreContext ctx;
434427
try {
435428
ctx = X509StoreContext.newStoreContext(context, (X509Store)store, X509Cert.wrap(runtime, signer), rUntrustedCerts);
@@ -563,7 +556,7 @@ private boolean matchIssuerId(X509Cert signerCA, CertificateID certId, List<Sing
563556
}
564557

565558
private CertificateID checkCertIds(List<SingleResp> singleResponses) {
566-
ArrayList<SingleResp> ary = new ArrayList<SingleResp>(singleResponses);
559+
ArrayList<SingleResp> ary = new ArrayList<>(singleResponses);
567560
CertificateID cid = ary.remove(0).getCertID();
568561

569562
for (SingleResp singleResp : ary) {
@@ -580,30 +573,18 @@ public BasicOCSPResponse getASN1BCOCSPResp() {
580573
public byte[] getNonce() {
581574
return this.nonce;
582575
}
583-
584-
private byte[] generateNonce() {
585-
// OSSL currently generates 16 byte nonce by default
586-
return generateNonce(new byte[16]);
587-
}
588-
589-
private byte[] generateNonce(byte[] bytes) {
590-
OpenSSL.getSecureRandom(getRuntime()).nextBytes(bytes);
591-
return bytes;
592-
}
593576

594577
private ASN1GeneralizedTime rubyIntOrTimeToGenTime(IRubyObject intOrTime) {
595578
if (intOrTime.isNil()) return null;
596-
Date retTime = new Date();
579+
Date retTime;
597580
if (intOrTime instanceof RubyInteger) {
598-
retTime.setTime(retTime.getTime() + RubyFixnum.fix2int((RubyFixnum)intOrTime)*1000);
581+
retTime = new Date(System.currentTimeMillis() + RubyFixnum.fix2int(intOrTime)*1000);
599582
}
600583
else if (intOrTime instanceof RubyTime) {
601-
retTime = ((RubyTime)intOrTime).getJavaDate();
584+
retTime = ((RubyTime) intOrTime).getJavaDate();
602585
}
603586
else {
604-
throw Utils.newArgumentError(
605-
getRuntime(), new IllegalArgumentException("Unknown Revocation Time class: " + intOrTime.getClass().getName())
606-
);
587+
throw getRuntime().newArgumentError("Unknown Revocation Time class: " + intOrTime.getMetaClass());
607588
}
608589

609590
return new ASN1GeneralizedTime(retTime);
@@ -684,25 +665,23 @@ private java.security.cert.Certificate findSignerByRespId(final ThreadContext co
684665
return null;
685666
}
686667

687-
private List<X509Cert> getCertsFromResp() {
688-
Ruby runtime = getRuntime();
689-
ThreadContext context = runtime.getCurrentContext();
690-
List<X509Cert> retCerts = new ArrayList<X509Cert>();
691-
List<X509CertificateHolder> respCerts = Arrays.asList(getBasicOCSPResp().getCerts());
692-
for (X509CertificateHolder cert : respCerts) {
668+
private List<X509Cert> getCertsFromResp(ThreadContext context) {
669+
X509CertificateHolder[] certs = getBasicOCSPResp().getCerts();
670+
List<X509Cert> retCerts = new ArrayList<>(certs.length);
671+
for (X509CertificateHolder cert : certs) {
693672
try {
694673
retCerts.add(X509Cert.wrap(context, cert.getEncoded()));
695674
}
696675
catch (IOException e) {
697-
throw newOCSPError(runtime, e);
676+
throw newOCSPError(context.runtime, e);
698677
}
699678
}
700-
701679
return retCerts;
702680
}
703681

704682

705683
private BasicOCSPResp getBasicOCSPResp() {
706684
return new BasicOCSPResp(asn1BCBasicOCSPResp);
707685
}
686+
708687
}

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

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -52,15 +52,13 @@
5252
import org.jruby.RubyObject;
5353
import org.jruby.RubyString;
5454
import org.jruby.anno.JRubyMethod;
55-
import org.jruby.exceptions.RaiseException;
5655
import org.jruby.runtime.ObjectAllocator;
5756
import org.jruby.runtime.ThreadContext;
5857
import org.jruby.runtime.Visibility;
5958
import org.jruby.runtime.builtin.IRubyObject;
6059

61-
import static org.jruby.ext.openssl.OCSP._OCSP;
6260
import static org.jruby.ext.openssl.Digest._Digest;
63-
import static org.jruby.ext.openssl.OCSP.newOCSPError;
61+
import static org.jruby.ext.openssl.OCSP.*;
6462

6563
/**
6664
* An OpenSSL::OCSP::CertificateId identifies a certificate to the

0 commit comments

Comments
 (0)