Skip to content

Commit 5bd16b9

Browse files
committed
moved the verification of CRL to non JCE implementation
this was mainly consolidating the verification to one place and using the non-JCE implementation doing - no need for trying all registered secutiry providers ! fixes #19 Sponsored by Lookout Inc.
1 parent 2826d1f commit 5bd16b9

File tree

2 files changed

+44
-71
lines changed

2 files changed

+44
-71
lines changed

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

Lines changed: 42 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -25,10 +25,12 @@
2525

2626
import static org.jruby.ext.openssl.OpenSSL.debugStackTrace;
2727

28+
import java.io.IOException;
2829
import java.lang.reflect.Constructor;
2930
import java.lang.reflect.Field;
3031
import java.lang.reflect.InvocationTargetException;
3132
import java.lang.reflect.Method;
33+
import java.math.BigInteger;
3234
import java.security.InvalidKeyException;
3335
import java.security.KeyFactory;
3436
import java.security.KeyFactorySpi;
@@ -52,8 +54,9 @@
5254
import java.security.cert.CertificateFactory;
5355
import java.security.cert.CertificateFactorySpi;
5456
import java.security.cert.X509CRL;
55-
import java.util.LinkedList;
56-
import java.util.List;
57+
import java.security.interfaces.DSAParams;
58+
import java.security.interfaces.DSAPublicKey;
59+
import java.security.interfaces.RSAPublicKey;
5760
import java.util.Locale;
5861
import java.util.Map;
5962
import java.util.StringTokenizer;
@@ -72,7 +75,19 @@
7275

7376
import org.bouncycastle.asn1.x509.AlgorithmIdentifier;
7477
import org.bouncycastle.asn1.x509.CertificateList;
78+
import org.bouncycastle.cert.CertException;
79+
import org.bouncycastle.cert.X509CRLHolder;
80+
import org.bouncycastle.crypto.params.AsymmetricKeyParameter;
81+
import org.bouncycastle.crypto.params.DSAParameters;
82+
import org.bouncycastle.crypto.params.DSAPublicKeyParameters;
83+
import org.bouncycastle.crypto.params.RSAKeyParameters;
7584
import org.bouncycastle.jce.provider.X509CRLObject;
85+
import org.bouncycastle.operator.ContentVerifierProvider;
86+
import org.bouncycastle.operator.DefaultDigestAlgorithmIdentifierFinder;
87+
import org.bouncycastle.operator.DigestAlgorithmIdentifierFinder;
88+
import org.bouncycastle.operator.OperatorException;
89+
import org.bouncycastle.operator.bc.BcDSAContentVerifierProviderBuilder;
90+
import org.bouncycastle.operator.bc.BcRSAContentVerifierProviderBuilder;
7691

7792
/**
7893
* Java Security (and JCE) helpers.
@@ -562,29 +577,35 @@ static boolean verify(final X509CRL crl, final PublicKey publicKey, final boolea
562577
}
563578
return true;
564579
}
565-
566-
// since we are using JCE here and BC might not be registered as Provider
567-
// we need to find a provider which supports such CRL verification
568-
// if we find a provider we will ignore the collected errors
569-
// otherwise the errors get displayed
570-
// TODO use BC directly for verifing CRL (probably needs quite some refactoring)
571-
List<Exception> errors = new LinkedList<Exception>();
572-
for(Provider p: Security.getProviders()) {
580+
else {
573581
try {
574-
crl.verify(publicKey, p.getName());
575-
return true;
582+
final DigestAlgorithmIdentifierFinder digestAlgFinder = new DefaultDigestAlgorithmIdentifierFinder();
583+
final ContentVerifierProvider verifierProvider;
584+
if ( "DSA".equalsIgnoreCase( publicKey.getAlgorithm() )) {
585+
BigInteger y = ((DSAPublicKey) publicKey).getY();
586+
DSAParams params = ((DSAPublicKey) publicKey).getParams();
587+
DSAParameters parameters = new DSAParameters(params.getP(), params.getQ(), params.getG());
588+
AsymmetricKeyParameter dsaKey = new DSAPublicKeyParameters(y, parameters);
589+
verifierProvider = new BcDSAContentVerifierProviderBuilder(digestAlgFinder).build(dsaKey);
590+
}
591+
else {
592+
BigInteger mod = ((RSAPublicKey) publicKey).getModulus();
593+
BigInteger exp = ((RSAPublicKey) publicKey).getPublicExponent();
594+
AsymmetricKeyParameter rsaKey = new RSAKeyParameters(false, mod, exp);
595+
verifierProvider = new BcRSAContentVerifierProviderBuilder(digestAlgFinder).build(rsaKey);
596+
}
597+
return new X509CRLHolder(crl.getEncoded()).isSignatureValid( verifierProvider );
598+
}
599+
catch (OperatorException e) {
600+
throw new SignatureException(e);
576601
}
577-
catch(SignatureException e) {
578-
return false;
602+
catch (CertException e) {
603+
throw new SignatureException(e);
579604
}
580-
catch(Exception e) {
581-
errors.add(e);
605+
catch (IOException e) {
606+
throw new SignatureException(e);
582607
}
583608
}
584-
for(Exception e: errors) {
585-
debugStackTrace(e);
586-
}
587-
return false;
588609
}
589610

590611
private static Object getCertificateList(final Object crl) { // X509CRLObject
@@ -699,4 +720,4 @@ private static void setField(Object obj, Class<?> fieldOwner, String fieldName,
699720
}
700721
}
701722

702-
}
723+
}

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

Lines changed: 2 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -34,16 +34,12 @@
3434
import java.util.ArrayList;
3535
import java.util.List;
3636
import java.util.Set;
37-
3837
import java.security.GeneralSecurityException;
3938
import java.security.PrivateKey;
4039
import java.security.PublicKey;
4140
import java.security.cert.CRLException;
4241
import java.security.cert.CertificateFactory;
4342
import java.security.cert.X509CRLEntry;
44-
import java.security.interfaces.DSAParams;
45-
import java.security.interfaces.DSAPublicKey;
46-
import java.security.interfaces.RSAPublicKey;
4743
import java.util.Arrays;
4844
import java.util.Collection;
4945
import java.util.Comparator;
@@ -59,22 +55,10 @@
5955
import org.bouncycastle.asn1.x500.X500Name;
6056
import org.bouncycastle.asn1.x509.Extension;
6157
import org.bouncycastle.asn1.x509.Extensions;
62-
import org.bouncycastle.cert.CertException;
6358
import org.bouncycastle.cert.X509CRLHolder;
6459
import org.bouncycastle.cert.X509v2CRLBuilder;
65-
import org.bouncycastle.crypto.params.AsymmetricKeyParameter;
66-
import org.bouncycastle.crypto.params.DSAParameters;
67-
import org.bouncycastle.crypto.params.DSAPublicKeyParameters;
68-
import org.bouncycastle.crypto.params.RSAKeyParameters;
6960
import org.bouncycastle.operator.ContentSigner;
70-
import org.bouncycastle.operator.ContentVerifierProvider;
71-
import org.bouncycastle.operator.DefaultDigestAlgorithmIdentifierFinder;
72-
import org.bouncycastle.operator.DigestAlgorithmIdentifierFinder;
73-
import org.bouncycastle.operator.OperatorException;
74-
import org.bouncycastle.operator.bc.BcDSAContentVerifierProviderBuilder;
75-
import org.bouncycastle.operator.bc.BcRSAContentVerifierProviderBuilder;
7661
import org.bouncycastle.operator.jcajce.JcaContentSignerBuilder;
77-
7862
import org.joda.time.DateTime;
7963
import org.jruby.Ruby;
8064
import org.jruby.RubyArray;
@@ -700,42 +684,10 @@ public IRubyObject verify(final ThreadContext context, final IRubyObject key) {
700684
if ( changed ) return context.runtime.getFalse();
701685
final PublicKey publicKey = ((PKey) key).getPublicKey();
702686
try {
703-
// NOTE: with BC 1.49 this seems to need BC provider installed ;(
704-
// java.security.NoSuchProviderException: no such provider: BC
705-
// at sun.security.jca.GetInstance.getService(GetInstance.java:83)
706-
// at sun.security.jca.GetInstance.getInstance(GetInstance.java:206)
707-
// at java.security.Signature.getInstance(Signature.java:355)
708-
// at org.bouncycastle.jcajce.provider.asymmetric.x509.X509CRLObject.verify(Unknown Source)
709-
// at org.bouncycastle.jcajce.provider.asymmetric.x509.X509CRLObject.verify(Unknown Source)
710-
// at org.jruby.ext.openssl.SecurityHelper.verify(SecurityHelper.java:564)
711-
// at org.jruby.ext.openssl.X509CRL.verify(X509CRL.java:717)
712-
//boolean valid = SecurityHelper.verify(getCRL(), publicKey, true);
713-
714-
final DigestAlgorithmIdentifierFinder digestAlgFinder = new DefaultDigestAlgorithmIdentifierFinder();
715-
final ContentVerifierProvider verifierProvider;
716-
if ( isDSA( (PKey) key ) ) {
717-
BigInteger y = ((DSAPublicKey) publicKey).getY();
718-
DSAParams params = ((DSAPublicKey) publicKey).getParams();
719-
DSAParameters parameters = new DSAParameters(params.getP(), params.getQ(), params.getG());
720-
AsymmetricKeyParameter dsaKey = new DSAPublicKeyParameters(y, parameters);
721-
verifierProvider = new BcDSAContentVerifierProviderBuilder(digestAlgFinder).build(dsaKey);
722-
}
723-
else {
724-
BigInteger mod = ((RSAPublicKey) publicKey).getModulus();
725-
BigInteger exp = ((RSAPublicKey) publicKey).getPublicExponent();
726-
AsymmetricKeyParameter rsaKey = new RSAKeyParameters(false, mod, exp);
727-
verifierProvider = new BcRSAContentVerifierProviderBuilder(digestAlgFinder).build(rsaKey);
728-
}
729-
//final X509CRLHolder crl = getCRLHolder();
730-
//final AlgorithmIdentifier algId = crl.toASN1Structure().getSignatureAlgorithm();
731-
boolean valid = getCRLHolder(false).isSignatureValid( verifierProvider );
687+
boolean valid = SecurityHelper.verify(getCRL(), publicKey, true);
732688
return context.runtime.newBoolean(valid);
733689
}
734-
catch (OperatorException e) {
735-
debug("CRL#verify() failed:", e);
736-
return context.runtime.getFalse();
737-
}
738-
catch (CertException e) {
690+
catch (GeneralSecurityException e) {
739691
debug("CRL#verify() failed:", e);
740692
return context.runtime.getFalse();
741693
}

0 commit comments

Comments
 (0)