summary refs log tree commit diff
diff options
context:
space:
mode:
authorPeter Dettman <peter.dettman@bouncycastle.org>2019-08-02 15:34:54 +0700
committerPeter Dettman <peter.dettman@bouncycastle.org>2019-08-02 15:34:54 +0700
commitfe33e6090225fd173df691e307b034dd712f4e07 (patch)
treee6152f508adb3bb89cfabe6af826f76e6a6950e9
parentSHA-256 performance tweak (diff)
downloadBouncyCastle.NET-ed25519-fe33e6090225fd173df691e307b034dd712f4e07.tar.xz
Refactor Equals/GetHashCode in X509 objects
- cache public key in X509Certificate
-rw-r--r--crypto/src/x509/X509Certificate.cs61
-rw-r--r--crypto/src/x509/X509Crl.cs47
-rw-r--r--crypto/src/x509/X509CrlEntry.cs33
3 files changed, 107 insertions, 34 deletions
diff --git a/crypto/src/x509/X509Certificate.cs b/crypto/src/x509/X509Certificate.cs
index 6f2f40411..2e627dbab 100644
--- a/crypto/src/x509/X509Certificate.cs
+++ b/crypto/src/x509/X509Certificate.cs
@@ -32,8 +32,11 @@ namespace Org.BouncyCastle.X509
 		private readonly BasicConstraints basicConstraints;
 		private readonly bool[] keyUsage;
 
-		private bool hashValueSet;
-		private int hashValue;
+        private readonly object cacheLock = new object();
+        private AsymmetricKeyParameter publicKeyValue;
+
+		private volatile bool hashValueSet;
+        private volatile int hashValue;
 
 		protected X509Certificate()
 		{
@@ -387,7 +390,24 @@ namespace Org.BouncyCastle.X509
 		/// <returns>The public key parameters.</returns>
 		public virtual AsymmetricKeyParameter GetPublicKey()
 		{
-			return PublicKeyFactory.CreateKey(c.SubjectPublicKeyInfo);
+            // Cache the public key to support repeated-use optimizations
+            lock (cacheLock)
+            {
+                if (null != publicKeyValue)
+                    return publicKeyValue;
+            }
+
+			AsymmetricKeyParameter temp = PublicKeyFactory.CreateKey(c.SubjectPublicKeyInfo);
+
+            lock (cacheLock)
+            {
+                if (null == publicKeyValue)
+                {
+                    publicKeyValue = temp;
+                }
+
+                return publicKeyValue;
+            }
 		}
 
 		/// <summary>
@@ -399,35 +419,40 @@ namespace Org.BouncyCastle.X509
 			return c.GetDerEncoded();
 		}
 
-		public override bool Equals(
-			object obj)
+        public override bool Equals(object other)
 		{
-			if (obj == this)
+			if (this == other)
 				return true;
 
-			X509Certificate other = obj as X509Certificate;
-
-			if (other == null)
+			X509Certificate that = other as X509Certificate;
+			if (null == that)
 				return false;
 
-			return c.Equals(other.c);
+            if (this.hashValueSet && that.hashValueSet)
+            {
+                if (this.hashValue != that.hashValue)
+                    return false;
+            }
+            else if (!this.c.Signature.Equals(that.c.Signature))
+            {
+                return false;
+            }
+
+			return this.c.Equals(that.c);
 
 			// NB: May prefer this implementation of Equals if more than one certificate implementation in play
-//			return Arrays.AreEqual(this.GetEncoded(), other.GetEncoded());
+            //return Arrays.AreEqual(this.GetEncoded(), that.GetEncoded());
 		}
 
 		public override int GetHashCode()
 		{
-			lock (this)
+			if (!hashValueSet)
 			{
-				if (!hashValueSet)
-				{
-					hashValue = c.GetHashCode();
-					hashValueSet = true;
-				}
+				hashValue = this.c.GetHashCode();
+				hashValueSet = true;
 			}
 
-			return hashValue;
+            return hashValue;
 		}
 
 //		public void setBagAttribute(
diff --git a/crypto/src/x509/X509Crl.cs b/crypto/src/x509/X509Crl.cs
index ecfb14132..8903e69d0 100644
--- a/crypto/src/x509/X509Crl.cs
+++ b/crypto/src/x509/X509Crl.cs
@@ -6,6 +6,7 @@ using Org.BouncyCastle.Asn1;
 using Org.BouncyCastle.Asn1.Utilities;
 using Org.BouncyCastle.Asn1.X509;
 using Org.BouncyCastle.Crypto;
+using Org.BouncyCastle.Crypto.Operators;
 using Org.BouncyCastle.Math;
 using Org.BouncyCastle.Security;
 using Org.BouncyCastle.Security.Certificates;
@@ -14,7 +15,6 @@ using Org.BouncyCastle.Utilities.Collections;
 using Org.BouncyCastle.Utilities.Date;
 using Org.BouncyCastle.Utilities.Encoders;
 using Org.BouncyCastle.X509.Extension;
-using Org.BouncyCastle.Crypto.Operators;
 
 namespace Org.BouncyCastle.X509
 {
@@ -36,6 +36,9 @@ namespace Org.BouncyCastle.X509
 		private readonly byte[] sigAlgParams;
 		private readonly bool isIndirect;
 
+        private volatile bool hashValueSet;
+        private volatile int hashValue;
+
 		public X509Crl(
 			CertificateList c)
 		{
@@ -229,27 +232,41 @@ namespace Org.BouncyCastle.X509
 			return Arrays.Clone(sigAlgParams);
 		}
 
-		public override bool Equals(
-			object obj)
+		public override bool Equals(object other)
 		{
-			if (obj == this)
-				return true;
+            if (this == other)
+                return true;
 
-			X509Crl other = obj as X509Crl;
+            X509Crl that = other as X509Crl;
+            if (null == that)
+                return false;
 
-			if (other == null)
-				return false;
+            if (this.hashValueSet && that.hashValueSet)
+            {
+                if (this.hashValue != that.hashValue)
+                    return false;
+            }
+            else if (!this.c.Signature.Equals(that.c.Signature))
+            {
+                return false;
+            }
 
-			return c.Equals(other.c);
+            return this.c.Equals(that.c);
 
-			// NB: May prefer this implementation of Equals if more than one certificate implementation in play
-			//return Arrays.AreEqual(this.GetEncoded(), other.GetEncoded());
+            // NB: May prefer this implementation of Equals if more than one CRL implementation in play
+			//return Arrays.AreEqual(this.GetEncoded(), that.GetEncoded());
 		}
 
-		public override int GetHashCode()
-		{
-			return c.GetHashCode();
-		}
+        public override int GetHashCode()
+        {
+            if (!hashValueSet)
+            {
+                hashValue = this.c.GetHashCode();
+                hashValueSet = true;
+            }
+
+            return hashValue;
+        }
 
 		/**
 		 * Returns a string representation of this CRL.
diff --git a/crypto/src/x509/X509CrlEntry.cs b/crypto/src/x509/X509CrlEntry.cs
index caca29470..9e3608c18 100644
--- a/crypto/src/x509/X509CrlEntry.cs
+++ b/crypto/src/x509/X509CrlEntry.cs
@@ -1,6 +1,5 @@
 using System;
 using System.Collections;
-using System.IO;
 using System.Text;
 
 using Org.BouncyCastle.Asn1;
@@ -27,6 +26,9 @@ namespace Org.BouncyCastle.X509
 		private X509Name	previousCertificateIssuer;
 		private X509Name	certificateIssuer;
 
+        private volatile bool hashValueSet;
+        private volatile int hashValue;
+
 		public X509CrlEntry(
 			CrlEntry c)
 		{
@@ -132,6 +134,35 @@ namespace Org.BouncyCastle.X509
 			get { return c.Extensions != null; }
 		}
 
+        public override bool Equals(object other)
+        {
+            if (this == other)
+                return true;
+
+            X509CrlEntry that = other as X509CrlEntry;
+            if (null == that)
+                return false;
+
+            if (this.hashValueSet && that.hashValueSet)
+            {
+                if (this.hashValue != that.hashValue)
+                    return false;
+            }
+
+            return this.c.Equals(that.c);
+        }
+
+        public override int GetHashCode()
+        {
+            if (!hashValueSet)
+            {
+                hashValue = this.c.GetHashCode();
+                hashValueSet = true;
+            }
+
+            return hashValue;
+        }
+
 		public override string ToString()
 		{
 			StringBuilder buf = new StringBuilder();