summary refs log tree commit diff
path: root/crypto/src/x509/X509Certificate.cs
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 /crypto/src/x509/X509Certificate.cs
parentSHA-256 performance tweak (diff)
downloadBouncyCastle.NET-ed25519-fe33e6090225fd173df691e307b034dd712f4e07.tar.xz
Refactor Equals/GetHashCode in X509 objects
- cache public key in X509Certificate
Diffstat (limited to 'crypto/src/x509/X509Certificate.cs')
-rw-r--r--crypto/src/x509/X509Certificate.cs61
1 files changed, 43 insertions, 18 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(