Skip to content

Commit eb200e5

Browse files
committed
(hopefully) improve mem consumption by default when comparing cert subjects
relates to #86
1 parent 60e9eb1 commit eb200e5

File tree

3 files changed

+40
-6
lines changed

3 files changed

+40
-6
lines changed

src/main/java/org/jruby/ext/openssl/x509store/Certificate.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -47,14 +47,14 @@ public int type() {
4747

4848
@Override
4949
public boolean isName(final Name name) {
50-
return name.equalTo( x509.getSubjectX500Principal() );
50+
return name.equalToCertificateSubject(x509);
5151
}
5252

5353
@Override
5454
public boolean matches(final X509Object other) {
5555
if (other instanceof Certificate) {
5656
final Certificate that = (Certificate) other;
57-
return this.x509.getSubjectX500Principal().equals( that.x509.getSubjectX500Principal() );
57+
return X509AuxCertificate.equalSubjects(this.x509, that.x509);
5858
}
5959
return false;
6060
}

src/main/java/org/jruby/ext/openssl/x509store/Name.java

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,10 +30,14 @@
3030
import java.io.IOException;
3131
import java.security.MessageDigest;
3232
import java.security.NoSuchAlgorithmException;
33+
import java.security.Principal;
34+
import java.security.cert.X509Certificate;
3335
import javax.security.auth.x500.X500Principal;
3436

3537
import org.bouncycastle.asn1.ASN1Encoding;
3638
import org.bouncycastle.asn1.x500.X500Name;
39+
import org.bouncycastle.jce.X509Principal;
40+
import org.bouncycastle.jce.provider.X509CertificateObject;
3741

3842
import org.jruby.ext.openssl.SecurityHelper;
3943

@@ -73,7 +77,7 @@ public static int hash(final X500Name name) throws IOException {
7377

7478
private transient int hash = 0;
7579

76-
public int hash() {
80+
public final int hash() {
7781
try {
7882
return hash == 0 ? hash = hash(name) : hash;
7983
}
@@ -106,6 +110,12 @@ public boolean equalTo(final X500Name name) {
106110
return this.name.equals(name);
107111
}
108112

113+
@SuppressWarnings("deprecation")
114+
final boolean equalTo(final Principal principal) {
115+
// assuming "legacy" non X500Principal impl (from BC)
116+
return new X509Principal(this.name).equals(principal);
117+
}
118+
109119
public boolean equalTo(final X500Principal principal) {
110120
try {
111121
return new X500Principal(this.name.getEncoded(ASN1Encoding.DER)).equals(principal);
@@ -115,4 +125,17 @@ public boolean equalTo(final X500Principal principal) {
115125
}
116126
}
117127

128+
public final boolean equalToCertificateSubject(final X509AuxCertificate wrapper) {
129+
// on Oracle/OpenJDK internal certificates: sun.security.x509.X509CertImpl
130+
// BC: class org.bouncycastle.jcajce.provider.asymmetric.x509.X509CertificateObject
131+
final X509Certificate cert = wrapper.cert;
132+
if ( cert == null ) return equalTo( wrapper.getSubjectX500Principal() );
133+
134+
if ( cert instanceof X509CertificateObject ) {
135+
return equalTo( cert.getSubjectDN() );
136+
}
137+
// otherwise need to take the 'expensive' path :
138+
return equalTo( cert.getSubjectX500Principal() );
139+
}
140+
118141
}// X509_NAME

src/main/java/org/jruby/ext/openssl/x509store/X509AuxCertificate.java

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@
5555
import org.bouncycastle.asn1.DERBitString;
5656
import org.bouncycastle.asn1.DEROctetString;
5757
import org.bouncycastle.asn1.x509.Certificate;
58+
import org.bouncycastle.jce.provider.X509CertificateObject;
5859

5960
import org.jruby.ext.openssl.SecurityHelper;
6061

@@ -68,7 +69,7 @@
6869
public class X509AuxCertificate extends X509Certificate implements Cloneable {
6970
private static final long serialVersionUID = -909543379295427515L;
7071

71-
private final X509Certificate cert;
72+
final X509Certificate cert;
7273

7374
final X509Aux aux;
7475

@@ -235,7 +236,7 @@ public boolean equals(Object other) {
235236
}
236237

237238
@Override
238-
public int hashCode() {
239+
public int hashCode() {
239240
int ret = cert.hashCode();
240241
ret += 3 * (aux == null ? 1 : aux.hashCode());
241242
return ret;
@@ -255,7 +256,7 @@ public void verify(PublicKey key, String sigProvider) throws CertificateExceptio
255256
}
256257

257258
@Override
258-
public Set<String> getCriticalExtensionOIDs() {
259+
public Set<String> getCriticalExtensionOIDs() {
259260
return cert.getCriticalExtensionOIDs();
260261
}
261262

@@ -299,4 +300,14 @@ public Integer getNsCertType() throws CertificateException {
299300
}
300301
}
301302

303+
static boolean equalSubjects(final X509AuxCertificate cert1, final X509AuxCertificate cert2) {
304+
if ( cert1.cert == cert2.cert ) return true;
305+
306+
if ( cert1.cert instanceof X509CertificateObject && cert2.cert instanceof X509CertificateObject ) {
307+
return cert1.cert.getSubjectDN().equals( cert2.cert.getSubjectDN() ); // less expensive on mem
308+
}
309+
// otherwise need to take the 'expensive' path :
310+
return cert1.getSubjectX500Principal().equals( cert2.getSubjectX500Principal() );
311+
}
312+
302313
}// X509AuxCertificate

0 commit comments

Comments
 (0)