In our setup we've been sharing a SSL_CTX between different threads
(I'll admit that I don't quite know whether that is allowed) and have
run into the following problem:

X509_STORE_get_by_subject is called to load a CA cert by both thread 1
and thread 2. It checks for the certs existence in the cert store in
both 1 & 2. Since no locks are taken at the X509_STORE_get_by_subject
level, both test return not found and both threads read the credential
and try to add it to the store. Adding is serialized by a lock so one of
these adds will fail with X509_R_CERT_ALREADY_IN_HASH_TABLE, which seems
to cause a handshake failure. The attached patch fixes this, but again,
maybe it's illegal to share SSL_CTX between threads. A better solution
may also be to take the SSL_CTX mutex in either
X509_STORE_get_by_subject or its callers.

/Sam


Index: by_file.c
===================================================================
RCS file: /home/globdev/CVS/globus-packages/gsi/openssl_gpt/crypto/x509/by_file.c,v
retrieving revision 1.1.1.1
diff -u -r1.1.1.1 by_file.c
--- by_file.c	2002/03/01 15:25:50	1.1.1.1
+++ by_file.c	2002/09/19 06:05:59
@@ -163,7 +163,18 @@
 					}
 				}
 			i=X509_STORE_add_cert(ctx->store_ctx,x);
-			if (!i) goto err;
+			if (!i)
+			        { 
+				if ((ERR_GET_REASON(ERR_peek_error()) ==
+				     X509_R_CERT_ALREADY_IN_HASH_TABLE))
+			                {
+			                ERR_clear_error();
+				        }
+				else
+				        {
+					goto err;    
+					}
+				}
 			count++;
 			X509_free(x);
 			x=NULL;
@@ -179,8 +190,19 @@
 			goto err;
 			}
 		i=X509_STORE_add_cert(ctx->store_ctx,x);
-		if (!i) goto err;
-		ret=i;
+		if (!i)
+                        { 
+                        if ((ERR_GET_REASON(ERR_peek_error()) ==
+                             X509_R_CERT_ALREADY_IN_HASH_TABLE))
+                                {
+                                ERR_clear_error();
+                                }
+                        else
+                                {
+                                goto err;    
+                                }
+                        }
+		ret=1;
 		}
 	else
 		{

Reply via email to