Convert reference counts in crypto/

This change converts the reference counts in crypto/ to use
|CRYPTO_refcount_t|. The reference counts in |X509_PKEY| and |X509_INFO|
were never actually used and so were dropped.

Change-Id: I75d572cdac1f8c1083c482e29c9519282d7fd16c
Reviewed-on: https://boringssl-review.googlesource.com/4772
Reviewed-by: Adam Langley <agl@google.com>
diff --git a/crypto/asn1/tasn_fre.c b/crypto/asn1/tasn_fre.c
index c344ed7..d1317ae 100644
--- a/crypto/asn1/tasn_fre.c
+++ b/crypto/asn1/tasn_fre.c
@@ -143,7 +143,7 @@
 
 		case ASN1_ITYPE_NDEF_SEQUENCE:
 		case ASN1_ITYPE_SEQUENCE:
-		if (asn1_do_lock(pval, -1, it) > 0)
+		if (!asn1_refcount_dec_and_test_zero(pval, it))
 			return;
 		if (asn1_cb)
 			{
diff --git a/crypto/asn1/tasn_new.c b/crypto/asn1/tasn_new.c
index 918aba7..6d69dcb 100644
--- a/crypto/asn1/tasn_new.c
+++ b/crypto/asn1/tasn_new.c
@@ -190,7 +190,7 @@
 			if (!*pval)
 				goto memerr;
 			memset(*pval, 0, it->size);
-			asn1_do_lock(pval, 0, it);
+			asn1_refcount_set_one(pval, it);
 			asn1_enc_init(pval, it);
 			}
 		for (i = 0, tt = it->templates; i < it->tcount; tt++, i++)
diff --git a/crypto/asn1/tasn_utl.c b/crypto/asn1/tasn_utl.c
index 1b9de94..ff3764e 100644
--- a/crypto/asn1/tasn_utl.c
+++ b/crypto/asn1/tasn_utl.c
@@ -64,6 +64,8 @@
 #include <openssl/err.h>
 #include <openssl/thread.h>
 
+#include "../internal.h"
+
 
 /* Utility functions for manipulating fields and offsets */
 
@@ -86,28 +88,32 @@
   return ret;
 }
 
-/* Do reference counting. The value 'op' decides what to do. if it is +1 then
- * the count is incremented. If op is 0 count is set to 1. If op is -1 count is
- * decremented and the return value is the current refrence count or 0 if no
- * reference count exists. */
-int asn1_do_lock(ASN1_VALUE **pval, int op, const ASN1_ITEM *it) {
-  const ASN1_AUX *aux;
-  int *lck, ret;
+static CRYPTO_refcount_t *asn1_get_references(ASN1_VALUE **pval,
+                                              const ASN1_ITEM *it) {
   if (it->itype != ASN1_ITYPE_SEQUENCE &&
       it->itype != ASN1_ITYPE_NDEF_SEQUENCE) {
-    return 0;
+    return NULL;
   }
-  aux = it->funcs;
+  const ASN1_AUX *aux = it->funcs;
   if (!aux || !(aux->flags & ASN1_AFLG_REFCOUNT)) {
-    return 0;
+    return NULL;
   }
-  lck = offset2ptr(*pval, aux->ref_offset);
-  if (op == 0) {
-    *lck = 1;
-    return 1;
+  return offset2ptr(*pval, aux->ref_offset);
+}
+
+void asn1_refcount_set_one(ASN1_VALUE **pval, const ASN1_ITEM *it) {
+  CRYPTO_refcount_t *references = asn1_get_references(pval, it);
+  if (references != NULL) {
+    *references = 1;
   }
-  ret = CRYPTO_add(lck, op, aux->ref_lock);
-  return ret;
+}
+
+int asn1_refcount_dec_and_test_zero(ASN1_VALUE **pval, const ASN1_ITEM *it) {
+  CRYPTO_refcount_t *references = asn1_get_references(pval, it);
+  if (references != NULL) {
+    return CRYPTO_refcount_dec_and_test_zero(references);
+  }
+  return 1;
 }
 
 static ASN1_ENCODING *asn1_get_enc_ptr(ASN1_VALUE **pval, const ASN1_ITEM *it) {
diff --git a/crypto/bio/bio.c b/crypto/bio/bio.c
index 48c1466..3d4c0ec 100644
--- a/crypto/bio/bio.c
+++ b/crypto/bio/bio.c
@@ -64,6 +64,8 @@
 #include <openssl/mem.h>
 #include <openssl/thread.h>
 
+#include "../internal.h"
+
 
 /* BIO_set initialises a BIO structure to have the given type and sets the
  * reference count to one. It returns one on success or zero on error. */
@@ -103,8 +105,7 @@
   BIO *next_bio;
 
   for (; bio != NULL; bio = next_bio) {
-    int refs = CRYPTO_add(&bio->references, -1, CRYPTO_LOCK_BIO);
-    if (refs > 0) {
+    if (!CRYPTO_refcount_dec_and_test_zero(&bio->references)) {
       return 0;
     }
 
@@ -127,7 +128,7 @@
 }
 
 BIO *BIO_up_ref(BIO *bio) {
-  CRYPTO_add(&bio->references, 1, CRYPTO_LOCK_BIO);
+  CRYPTO_refcount_inc(&bio->references);
   return bio;
 }
 
diff --git a/crypto/dh/dh.c b/crypto/dh/dh.c
index d90b113..96b85f3 100644
--- a/crypto/dh/dh.c
+++ b/crypto/dh/dh.c
@@ -116,7 +116,7 @@
     return;
   }
 
-  if (CRYPTO_add(&dh->references, -1, CRYPTO_LOCK_DH) > 0) {
+  if (!CRYPTO_refcount_dec_and_test_zero(&dh->references)) {
     return;
   }
 
@@ -166,8 +166,8 @@
 
 unsigned DH_num_bits(const DH *dh) { return BN_num_bits(dh->p); }
 
-int DH_up_ref(DH *r) {
-  CRYPTO_add(&r->references, 1, CRYPTO_LOCK_DH);
+int DH_up_ref(DH *dh) {
+  CRYPTO_refcount_inc(&dh->references);
   return 1;
 }
 
diff --git a/crypto/dsa/dsa.c b/crypto/dsa/dsa.c
index e8e3d73..65444b1 100644
--- a/crypto/dsa/dsa.c
+++ b/crypto/dsa/dsa.c
@@ -123,7 +123,7 @@
     return;
   }
 
-  if (CRYPTO_add(&dsa->references, -1, CRYPTO_LOCK_DSA) > 0) {
+  if (!CRYPTO_refcount_dec_and_test_zero(&dsa->references)) {
     return;
   }
 
@@ -146,7 +146,7 @@
 }
 
 int DSA_up_ref(DSA *dsa) {
-  CRYPTO_add(&dsa->references, 1, CRYPTO_LOCK_DSA);
+  CRYPTO_refcount_inc(&dsa->references);
   return 1;
 }
 
diff --git a/crypto/ec/ec_key.c b/crypto/ec/ec_key.c
index 348ec46..e5cbfed 100644
--- a/crypto/ec/ec_key.c
+++ b/crypto/ec/ec_key.c
@@ -143,7 +143,7 @@
     return;
   }
 
-  if (CRYPTO_add(&r->references, -1, CRYPTO_LOCK_EC)) {
+  if (!CRYPTO_refcount_dec_and_test_zero(&r->references)) {
     return;
   }
 
@@ -234,7 +234,8 @@
 }
 
 int EC_KEY_up_ref(EC_KEY *r) {
-  return CRYPTO_add(&r->references, 1, CRYPTO_LOCK_EC) > 1;
+  CRYPTO_refcount_inc(&r->references);
+  return 1;
 }
 
 int EC_KEY_is_opaque(const EC_KEY *key) {
diff --git a/crypto/ec/internal.h b/crypto/ec/internal.h
index 0a8bf24..71062c1 100644
--- a/crypto/ec/internal.h
+++ b/crypto/ec/internal.h
@@ -72,6 +72,7 @@
 
 #include <openssl/bn.h>
 #include <openssl/ex_data.h>
+#include <openssl/thread.h>
 
 #if defined(__cplusplus)
 extern "C" {
@@ -331,7 +332,7 @@
   unsigned int enc_flag;
   point_conversion_form_t conv_form;
 
-  int references;
+  CRYPTO_refcount_t references;
   int flags;
 
   ECDSA_METHOD *ecdsa_meth;
diff --git a/crypto/ec/p256-64.c b/crypto/ec/p256-64.c
index 8f824de..fdb942c 100644
--- a/crypto/ec/p256-64.c
+++ b/crypto/ec/p256-64.c
@@ -1601,7 +1601,6 @@
 /* Precomputation for the group generator. */
 typedef struct {
   smallfelem g_pre_comp[2][16][3];
-  int references;
 } NISTP256_PRE_COMP;
 
 /******************************************************************************/
diff --git a/crypto/ec/wnaf.c b/crypto/ec/wnaf.c
index d87a7d9..ae0d73f 100644
--- a/crypto/ec/wnaf.c
+++ b/crypto/ec/wnaf.c
@@ -75,6 +75,7 @@
 #include <openssl/thread.h>
 
 #include "internal.h"
+#include "../internal.h"
 
 
 /* This file implements the wNAF-based interleaving multi-exponentation method
@@ -91,7 +92,7 @@
   EC_POINT **points; /* array with pre-calculated multiples of generator:
                       * 'num' pointers to EC_POINT objects followed by a NULL */
   size_t num; /* numblocks * 2^(w-1) */
-  int references;
+  CRYPTO_refcount_t references;
 } EC_PRE_COMP;
 
 static EC_PRE_COMP *ec_pre_comp_new(void) {
@@ -116,13 +117,13 @@
     return NULL;
   }
 
-  CRYPTO_add(&pre_comp->references, 1, CRYPTO_LOCK_EC_PRE_COMP);
+  CRYPTO_refcount_inc(&pre_comp->references);
   return pre_comp;
 }
 
 void ec_pre_comp_free(EC_PRE_COMP *pre_comp) {
   if (pre_comp == NULL ||
-      CRYPTO_add(&pre_comp->references, -1, CRYPTO_LOCK_EC_PRE_COMP) > 0) {
+      !CRYPTO_refcount_dec_and_test_zero(&pre_comp->references)) {
     return;
   }
 
diff --git a/crypto/evp/evp.c b/crypto/evp/evp.c
index 58fd9a9..c4bfdac 100644
--- a/crypto/evp/evp.c
+++ b/crypto/evp/evp.c
@@ -70,6 +70,7 @@
 #include <openssl/thread.h>
 
 #include "internal.h"
+#include "../internal.h"
 
 
 extern const EVP_PKEY_ASN1_METHOD dsa_asn1_meth;
@@ -106,7 +107,7 @@
     return;
   }
 
-  if (CRYPTO_add(&pkey->references, -1, CRYPTO_LOCK_EVP_PKEY)) {
+  if (!CRYPTO_refcount_dec_and_test_zero(&pkey->references)) {
     return;
   }
 
@@ -115,7 +116,7 @@
 }
 
 EVP_PKEY *EVP_PKEY_up_ref(EVP_PKEY *pkey) {
-  CRYPTO_add(&pkey->references, 1, CRYPTO_LOCK_EVP_PKEY);
+  CRYPTO_refcount_inc(&pkey->references);
   return pkey;
 }
 
diff --git a/crypto/rsa/rsa.c b/crypto/rsa/rsa.c
index 5cc48ed..17059b0 100644
--- a/crypto/rsa/rsa.c
+++ b/crypto/rsa/rsa.c
@@ -121,7 +121,7 @@
     return;
   }
 
-  if (CRYPTO_add(&rsa->references, -1, CRYPTO_LOCK_RSA) > 0) {
+  if (!CRYPTO_refcount_dec_and_test_zero(&rsa->references)) {
     return;
   }
 
@@ -150,7 +150,7 @@
 }
 
 int RSA_up_ref(RSA *rsa) {
-  CRYPTO_add(&rsa->references, 1, CRYPTO_LOCK_RSA);
+  CRYPTO_refcount_inc(&rsa->references);
   return 1;
 }
 
diff --git a/crypto/x509/x509_lu.c b/crypto/x509/x509_lu.c
index 34ef26e..fcae59d 100644
--- a/crypto/x509/x509_lu.c
+++ b/crypto/x509/x509_lu.c
@@ -64,6 +64,8 @@
 #include <openssl/x509.h>
 #include <openssl/x509v3.h>
 
+#include "../internal.h"
+
 
 X509_LOOKUP *X509_LOOKUP_new(X509_LOOKUP_METHOD *method)
 	{
@@ -228,7 +230,6 @@
 
 void X509_STORE_free(X509_STORE *vfy)
 	{
-	int i;
 	size_t j;
 	STACK_OF(X509_LOOKUP) *sk;
 	X509_LOOKUP *lu;
@@ -236,18 +237,12 @@
 	if (vfy == NULL)
 	    return;
 
-	i=CRYPTO_add(&vfy->references,-1,CRYPTO_LOCK_X509_STORE);
+	if (!CRYPTO_refcount_dec_and_test_zero(&vfy->references)) {
+	  return;
+	}
 #ifdef REF_PRINT
 	REF_PRINT("X509_STORE",vfy);
 #endif
-	if (i > 0) return;
-#ifdef REF_CHECK
-	if (i < 0)
-		{
-		fprintf(stderr,"X509_STORE_free, bad reference count\n");
-		abort(); /* ok */
-		}
-#endif
 
 	sk=vfy->get_cert_methods;
 	for (j=0; j<sk_X509_LOOKUP_num(sk); j++)
@@ -415,7 +410,7 @@
 		X509_up_ref(a->data.x509);
 		break;
 	case X509_LU_CRL:
-		CRYPTO_add(&a->data.crl->references,1,CRYPTO_LOCK_X509_CRL);
+		CRYPTO_refcount_inc(&a->data.crl->references);
 		break;
 		}
 	}
@@ -577,7 +572,7 @@
 		{
 		obj = sk_X509_OBJECT_value(ctx->ctx->objs, idx);
 		x = obj->data.crl;
-		CRYPTO_add(&x->references, 1, CRYPTO_LOCK_X509_CRL);
+		CRYPTO_refcount_inc(&x->references);
 		if (!sk_X509_CRL_push(sk, x))
 			{
 			CRYPTO_w_unlock(CRYPTO_LOCK_X509_STORE);
diff --git a/crypto/x509/x509_vfy.c b/crypto/x509/x509_vfy.c
index a0cd9fc..2ba9c84 100644
--- a/crypto/x509/x509_vfy.c
+++ b/crypto/x509/x509_vfy.c
@@ -273,7 +273,7 @@
 					OPENSSL_PUT_ERROR(X509, X509_verify_cert, ERR_R_MALLOC_FAILURE);
 					goto end;
 					}
-				CRYPTO_add(&xtmp->references,1,CRYPTO_LOCK_X509);
+				CRYPTO_refcount_inc(&xtmp->references);
 				(void)sk_X509_delete_ptr(sktmp,xtmp);
 				ctx->last_untrusted++;
 				x=xtmp;
@@ -990,7 +990,7 @@
 		*pissuer = best_crl_issuer;
 		*pscore = best_score;
 		*preasons = best_reasons;
-		CRYPTO_add(&best_crl->references, 1, CRYPTO_LOCK_X509_CRL);
+		CRYPTO_refcount_inc(&best_crl->references);
 		if (*pdcrl)
 			{
 			X509_CRL_free(*pdcrl);
@@ -1097,7 +1097,7 @@
 			{
 			if (check_crl_time(ctx, delta, 0))
 				*pscore |= CRL_SCORE_TIME_DELTA;
-			CRYPTO_add(&delta->references, 1, CRYPTO_LOCK_X509_CRL);
+			CRYPTO_refcount_inc(&delta->references);
 			*dcrl = delta;
 			return;
 			}
diff --git a/crypto/x509/x_info.c b/crypto/x509/x_info.c
index 6807b24..f9e9ab8 100644
--- a/crypto/x509/x_info.c
+++ b/crypto/x509/x_info.c
@@ -77,7 +77,6 @@
         ret->enc_len=0;
         ret->enc_data=NULL;
  
-	ret->references=1;
 	ret->x509=NULL;
 	ret->crl=NULL;
 	ret->x_pkey=NULL;
@@ -86,23 +85,8 @@
 
 void X509_INFO_free(X509_INFO *x)
 	{
-	int i;
-
 	if (x == NULL) return;
 
-	i=CRYPTO_add(&x->references,-1,CRYPTO_LOCK_X509_INFO);
-#ifdef REF_PRINT
-	REF_PRINT("X509_INFO",x);
-#endif
-	if (i > 0) return;
-#ifdef REF_CHECK
-	if (i < 0)
-		{
-		fprintf(stderr,"X509_INFO_free, bad reference count\n");
-		abort();
-		}
-#endif
-
 	if (x->x509 != NULL) X509_free(x->x509);
 	if (x->crl != NULL) X509_CRL_free(x->crl);
 	if (x->x_pkey != NULL) X509_PKEY_free(x->x_pkey);
diff --git a/crypto/x509/x_pkey.c b/crypto/x509/x_pkey.c
index 5acbe5b..5bc6415 100644
--- a/crypto/x509/x_pkey.c
+++ b/crypto/x509/x_pkey.c
@@ -73,7 +73,6 @@
 		goto err;
 		}
 	memset(ret, 0, sizeof(X509_PKEY));
-	ret->references=1;
 
 	ret->enc_algor = X509_ALGOR_new();
 	if (ret->enc_algor == NULL)
@@ -91,13 +90,8 @@
 
 void X509_PKEY_free(X509_PKEY *x)
 	{
-	int i;
-
 	if (x == NULL) return;
 
-	i=CRYPTO_add(&x->references,-1,CRYPTO_LOCK_X509_PKEY);
-	if (i > 0) return;
-
 	if (x->enc_algor != NULL) X509_ALGOR_free(x->enc_algor);
 	if (x->enc_pkey != NULL) M_ASN1_OCTET_STRING_free(x->enc_pkey);
 	if (x->dec_pkey != NULL)EVP_PKEY_free(x->dec_pkey);
diff --git a/crypto/x509/x_x509.c b/crypto/x509/x_x509.c
index 234494d..289e5fc 100644
--- a/crypto/x509/x_x509.c
+++ b/crypto/x509/x_x509.c
@@ -142,7 +142,7 @@
 
 X509 *X509_up_ref(X509 *x)
 	{
-	CRYPTO_add(&x->references, 1, CRYPTO_LOCK_X509);
+	CRYPTO_refcount_inc(&x->references);
 	return x;
 	}
 
diff --git a/include/openssl/asn1t.h b/include/openssl/asn1t.h
index 6c91134..2945fa8 100644
--- a/include/openssl/asn1t.h
+++ b/include/openssl/asn1t.h
@@ -894,7 +894,8 @@
 
 const ASN1_TEMPLATE *asn1_do_adb(ASN1_VALUE **pval, const ASN1_TEMPLATE *tt, int nullerr);
 
-int asn1_do_lock(ASN1_VALUE **pval, int op, const ASN1_ITEM *it);
+void asn1_refcount_set_one(ASN1_VALUE **pval, const ASN1_ITEM *it);
+int asn1_refcount_dec_and_test_zero(ASN1_VALUE **pval, const ASN1_ITEM *it);
 
 void asn1_enc_init(ASN1_VALUE **pval, const ASN1_ITEM *it);
 void asn1_enc_free(ASN1_VALUE **pval, const ASN1_ITEM *it);
diff --git a/include/openssl/bio.h b/include/openssl/bio.h
index b70b42f..c0c430a 100644
--- a/include/openssl/bio.h
+++ b/include/openssl/bio.h
@@ -64,6 +64,7 @@
 #include <openssl/err.h> /* for ERR_print_errors_fp */
 #include <openssl/ex_data.h>
 #include <openssl/stack.h>
+#include <openssl/thread.h>
 
 #if defined(__cplusplus)
 extern "C" {
@@ -784,7 +785,7 @@
   /* num is a BIO-specific value. For example, in fd BIOs it's used to store a
    * file descriptor. */
   int num;
-  int references;
+  CRYPTO_refcount_t references;
   void *ptr;
   /* next_bio points to the next |BIO| in a chain. This |BIO| owns a reference
    * to |next_bio|. */
diff --git a/include/openssl/dh.h b/include/openssl/dh.h
index c61e53f..17574d5 100644
--- a/include/openssl/dh.h
+++ b/include/openssl/dh.h
@@ -253,7 +253,7 @@
   BIGNUM *counter;
 
   int flags;
-  int references;
+  CRYPTO_refcount_t references;
   CRYPTO_EX_DATA ex_data;
 };
 
diff --git a/include/openssl/dsa.h b/include/openssl/dsa.h
index 2271915..7274e4c 100644
--- a/include/openssl/dsa.h
+++ b/include/openssl/dsa.h
@@ -354,7 +354,7 @@
   /* Normally used to cache montgomery values */
   CRYPTO_MUTEX method_mont_p_lock;
   BN_MONT_CTX *method_mont_p;
-  int references;
+  CRYPTO_refcount_t references;
   CRYPTO_EX_DATA ex_data;
   DSA_METHOD *meth;
   /* functional reference if 'meth' is ENGINE-provided */
diff --git a/include/openssl/engine.h b/include/openssl/engine.h
index da242f6..d3d278a 100644
--- a/include/openssl/engine.h
+++ b/include/openssl/engine.h
@@ -93,7 +93,7 @@
 /* openssl_method_common_st contains the common part of all method structures.
  * This must be the first member of all method structures. */
 struct openssl_method_common_st {
-  int references;
+  int references;  /* dummy – not used. */
   char is_static;
 };
 
diff --git a/include/openssl/evp.h b/include/openssl/evp.h
index 54ad4be..234754d 100644
--- a/include/openssl/evp.h
+++ b/include/openssl/evp.h
@@ -59,6 +59,8 @@
 
 #include <openssl/base.h>
 
+#include <openssl/thread.h>
+
 /* OpenSSL included digest and cipher functions in this header so we include
  * them for users that still expect that.
  *
@@ -678,7 +680,7 @@
     ENGINE **pengine, const char *name, size_t len);
 
 struct evp_pkey_st {
-  int references;
+  CRYPTO_refcount_t references;
 
   /* type contains one of the EVP_PKEY_* values or NID_undef and determines
    * which element (if any) of the |pkey| union is valid. */
diff --git a/include/openssl/rsa.h b/include/openssl/rsa.h
index 2e24231..9b415d7 100644
--- a/include/openssl/rsa.h
+++ b/include/openssl/rsa.h
@@ -475,7 +475,7 @@
   BIGNUM *iqmp;
   /* be careful using this if the RSA structure is shared */
   CRYPTO_EX_DATA ex_data;
-  int references;
+  CRYPTO_refcount_t references;
   int flags;
 
   CRYPTO_MUTEX lock;
diff --git a/include/openssl/x509.h b/include/openssl/x509.h
index ef1d7fb..69c7da6 100644
--- a/include/openssl/x509.h
+++ b/include/openssl/x509.h
@@ -73,13 +73,14 @@
 #include <openssl/cipher.h>
 #include <openssl/dh.h>
 #include <openssl/dsa.h>
-#include <openssl/ec.h>
 #include <openssl/ecdh.h>
 #include <openssl/ecdsa.h>
+#include <openssl/ec.h>
 #include <openssl/evp.h>
 #include <openssl/rsa.h>
 #include <openssl/sha.h>
 #include <openssl/stack.h>
+#include <openssl/thread.h>
 
 #ifdef  __cplusplus
 extern "C" {
@@ -204,7 +205,7 @@
 	X509_REQ_INFO *req_info;
 	X509_ALGOR *sig_alg;
 	ASN1_BIT_STRING *signature;
-	int references;
+	CRYPTO_refcount_t references;
 	} X509_REQ;
 
 typedef struct x509_cinf_st
@@ -243,7 +244,7 @@
 	X509_ALGOR *sig_alg;
 	ASN1_BIT_STRING *signature;
 	int valid;
-	int references;
+	CRYPTO_refcount_t references;
 	char *name;
 	CRYPTO_EX_DATA ex_data;
 	/* These contain copies of various extension values */
@@ -420,7 +421,7 @@
 	X509_CRL_INFO *crl;
 	X509_ALGOR *sig_alg;
 	ASN1_BIT_STRING *signature;
-	int references;
+	CRYPTO_refcount_t references;
 	int flags;
 	/* Copies of various extensions */
 	AUTHORITY_KEYID *akid;
@@ -457,8 +458,6 @@
 
 	/* expanded version of 'enc_algor' */
 	EVP_CIPHER_INFO cipher;
-
-	int references;
 	} X509_PKEY;
 
 #ifndef OPENSSL_NO_EVP
@@ -472,7 +471,6 @@
 	int enc_len;
 	char *enc_data;
 
-	int references;
 	} X509_INFO;
 
 DECLARE_STACK_OF(X509_INFO)
diff --git a/include/openssl/x509_vfy.h b/include/openssl/x509_vfy.h
index 299cad7..32ba134 100644
--- a/include/openssl/x509_vfy.h
+++ b/include/openssl/x509_vfy.h
@@ -67,6 +67,7 @@
 
 #include <openssl/bio.h>
 #include <openssl/lhash.h>
+#include <openssl/thread.h>
 
 #ifdef  __cplusplus
 extern "C" {
@@ -202,7 +203,7 @@
 	STACK_OF(X509_CRL) * (*lookup_crls)(X509_STORE_CTX *ctx, X509_NAME *nm);
 	int (*cleanup)(X509_STORE_CTX *ctx);
 
-	int references;
+	CRYPTO_refcount_t references;
 	} /* X509_STORE */;
 
 OPENSSL_EXPORT int X509_STORE_set_depth(X509_STORE *store, int depth);
diff --git a/ssl/ssl_cert.c b/ssl/ssl_cert.c
index 770912b..6cb3785 100644
--- a/ssl/ssl_cert.c
+++ b/ssl/ssl_cert.c
@@ -128,6 +128,7 @@
 
 #include "../crypto/dh/internal.h"
 #include "../crypto/directory.h"
+#include "../crypto/internal.h"
 #include "internal.h"
 
 
@@ -269,12 +270,12 @@
   ret->cert_cb_arg = cert->cert_cb_arg;
 
   if (cert->verify_store) {
-    CRYPTO_add(&cert->verify_store->references, 1, CRYPTO_LOCK_X509_STORE);
+    CRYPTO_refcount_inc(&cert->verify_store->references);
     ret->verify_store = cert->verify_store;
   }
 
   if (cert->chain_store) {
-    CRYPTO_add(&cert->chain_store->references, 1, CRYPTO_LOCK_X509_STORE);
+    CRYPTO_refcount_inc(&cert->chain_store->references);
     ret->chain_store = cert->chain_store;
   }
 
@@ -977,7 +978,7 @@
   *pstore = store;
 
   if (ref && store) {
-    CRYPTO_add(&store->references, 1, CRYPTO_LOCK_X509_STORE);
+    CRYPTO_refcount_inc(&store->references);
   }
   return 1;
 }