Add X509_up_ref and use it internally.
Avoid needing to manually increment the reference count and using the right
lock, both here and in Chromium.
Change-Id: If116ebc224cfb1c4711f7e2c06f1fd2c97af21dd
Reviewed-on: https://boringssl-review.googlesource.com/1415
Reviewed-by: Adam Langley <agl@google.com>
diff --git a/crypto/x509/x509_cmp.c b/crypto/x509/x509_cmp.c
index e626fcf..57e6167 100644
--- a/crypto/x509/x509_cmp.c
+++ b/crypto/x509/x509_cmp.c
@@ -508,8 +508,7 @@
ret = sk_X509_dup(chain);
for (i = 0; i < sk_X509_num(ret); i++)
{
- X509 *x = sk_X509_value(ret, i);
- CRYPTO_add(&x->references, 1, CRYPTO_LOCK_X509);
+ X509_up_ref(sk_X509_value(ret, i));
}
return ret;
}
diff --git a/crypto/x509/x509_lu.c b/crypto/x509/x509_lu.c
index 63b81c3..05d1598 100644
--- a/crypto/x509/x509_lu.c
+++ b/crypto/x509/x509_lu.c
@@ -413,7 +413,7 @@
switch (a->type)
{
case X509_LU_X509:
- CRYPTO_add(&a->data.x509->references,1,CRYPTO_LOCK_X509);
+ X509_up_ref(a->data.x509);
break;
case X509_LU_CRL:
CRYPTO_add(&a->data.crl->references,1,CRYPTO_LOCK_X509_CRL);
@@ -532,8 +532,7 @@
{
obj = sk_X509_OBJECT_value(ctx->ctx->objs, idx);
x = obj->data.x509;
- CRYPTO_add(&x->references, 1, CRYPTO_LOCK_X509);
- if (!sk_X509_push(sk, x))
+ if (!sk_X509_push(sk, X509_up_ref(x)))
{
CRYPTO_w_unlock(CRYPTO_LOCK_X509_STORE);
X509_free(x);
diff --git a/crypto/x509/x509_vfy.c b/crypto/x509/x509_vfy.c
index fa5565b..18bb772 100644
--- a/crypto/x509/x509_vfy.c
+++ b/crypto/x509/x509_vfy.c
@@ -177,7 +177,7 @@
break;
}
if (i < sk_X509_num(certs))
- CRYPTO_add(&xtmp->references,1,CRYPTO_LOCK_X509);
+ X509_up_ref(xtmp);
else
xtmp = NULL;
sk_X509_pop_free(certs, X509_free);
@@ -211,7 +211,7 @@
OPENSSL_PUT_ERROR(X509, X509_verify_cert, ERR_R_MALLOC_FAILURE);
goto end;
}
- CRYPTO_add(&ctx->cert->references,1,CRYPTO_LOCK_X509);
+ X509_up_ref(ctx->cert);
ctx->last_untrusted=1;
}
@@ -494,7 +494,7 @@
*issuer = find_issuer(ctx, ctx->other_ctx, x);
if (*issuer)
{
- CRYPTO_add(&(*issuer)->references,1,CRYPTO_LOCK_X509);
+ X509_up_ref(*issuer);
return 1;
}
else
diff --git a/crypto/x509/x_x509.c b/crypto/x509/x_x509.c
index 712cff4..5cda3c7 100644
--- a/crypto/x509/x_x509.c
+++ b/crypto/x509/x_x509.c
@@ -136,6 +136,12 @@
IMPLEMENT_ASN1_FUNCTIONS(X509)
IMPLEMENT_ASN1_DUP_FUNCTION(X509)
+X509 *X509_up_ref(X509 *x)
+ {
+ CRYPTO_add(&x->references, 1, CRYPTO_LOCK_X509);
+ return x;
+ }
+
int X509_get_ex_new_index(long argl, void *argp, CRYPTO_EX_new *new_func,
CRYPTO_EX_dup *dup_func, CRYPTO_EX_free *free_func)
{
diff --git a/crypto/x509v3/pcy_tree.c b/crypto/x509v3/pcy_tree.c
index dbaa498..35567a7 100644
--- a/crypto/x509v3/pcy_tree.c
+++ b/crypto/x509v3/pcy_tree.c
@@ -258,8 +258,7 @@
level++;
x = sk_X509_value(certs, i);
cache = policy_cache_set(x);
- CRYPTO_add(&x->references, 1, CRYPTO_LOCK_X509);
- level->cert = x;
+ level->cert = X509_up_ref(x);
if (!cache->anyPolicy)
level->flags |= X509_V_FLAG_INHIBIT_ANY;
diff --git a/include/openssl/x509.h b/include/openssl/x509.h
index d07b2f5..058bbff 100644
--- a/include/openssl/x509.h
+++ b/include/openssl/x509.h
@@ -806,6 +806,10 @@
DECLARE_ASN1_FUNCTIONS(X509_CERT_PAIR)
+/* X509_up_ref adds one to the reference count of |x| and returns
+ * |x|. */
+OPENSSL_EXPORT X509 *X509_up_ref(X509 *x);
+
OPENSSL_EXPORT int X509_get_ex_new_index(long argl, void *argp, CRYPTO_EX_new *new_func,
CRYPTO_EX_dup *dup_func, CRYPTO_EX_free *free_func);
OPENSSL_EXPORT int X509_set_ex_data(X509 *r, int idx, void *arg);
diff --git a/ssl/s3_clnt.c b/ssl/s3_clnt.c
index 1185873..fc1567f 100644
--- a/ssl/s3_clnt.c
+++ b/ssl/s3_clnt.c
@@ -1180,18 +1180,16 @@
goto f_err;
}
sc->peer_cert_type=i;
- CRYPTO_add(&x->references,1,CRYPTO_LOCK_X509);
/* Why would the following ever happen?
* We just created sc a couple of lines ago. */
if (sc->peer_pkeys[i].x509 != NULL)
X509_free(sc->peer_pkeys[i].x509);
- sc->peer_pkeys[i].x509=x;
- sc->peer_key= &(sc->peer_pkeys[i]);
+ sc->peer_pkeys[i].x509 = X509_up_ref(x);
+ sc->peer_key = &(sc->peer_pkeys[i]);
if (s->session->peer != NULL)
X509_free(s->session->peer);
- CRYPTO_add(&x->references,1,CRYPTO_LOCK_X509);
- s->session->peer=x;
+ s->session->peer = X509_up_ref(x);
s->session->verify_result = s->verify_result;
diff --git a/ssl/ssl_cert.c b/ssl/ssl_cert.c
index c3994c4..7d398d9 100644
--- a/ssl/ssl_cert.c
+++ b/ssl/ssl_cert.c
@@ -261,8 +261,7 @@
CERT_PKEY *rpk = ret->pkeys + i;
if (cpk->x509 != NULL)
{
- rpk->x509 = cpk->x509;
- CRYPTO_add(&rpk->x509->references, 1, CRYPTO_LOCK_X509);
+ rpk->x509 = X509_up_ref(cpk->x509);
}
if (cpk->privatekey != NULL)
@@ -365,14 +364,12 @@
if (cert->verify_store)
{
- CRYPTO_add(&cert->verify_store->references, 1, CRYPTO_LOCK_X509_STORE);
- ret->verify_store = cert->verify_store;
+ ret->verify_store = X509_up_ref(cert->verify_store);
}
if (cert->chain_store)
{
- CRYPTO_add(&cert->chain_store->references, 1, CRYPTO_LOCK_X509_STORE);
- ret->chain_store = cert->chain_store;
+ ret->chain_store = X509_up_ref(cert->chain_store);
}
ret->ciphers_raw = NULL;
@@ -529,7 +526,7 @@
{
if (!ssl_cert_add0_chain_cert(c, x))
return 0;
- CRYPTO_add(&x->references, 1, CRYPTO_LOCK_X509);
+ X509_up_ref(x);
return 1;
}
@@ -1214,7 +1211,7 @@
X509_STORE_free(*pstore);
*pstore = store;
if (ref && store)
- CRYPTO_add(&store->references, 1, CRYPTO_LOCK_X509_STORE);
+ X509_up_ref(store);
return 1;
}
diff --git a/ssl/ssl_lib.c b/ssl/ssl_lib.c
index 9eace73..182b9eb 100644
--- a/ssl/ssl_lib.c
+++ b/ssl/ssl_lib.c
@@ -942,11 +942,10 @@
else
r=s->session->peer;
- if (r == NULL) return(r);
+ if (r == NULL)
+ return NULL;
- CRYPTO_add(&r->references,1,CRYPTO_LOCK_X509);
-
- return(r);
+ return X509_up_ref(r);
}
STACK_OF(X509) *SSL_get_peer_cert_chain(const SSL *s)
diff --git a/ssl/ssl_rsa.c b/ssl/ssl_rsa.c
index 05163d4..7933863 100644
--- a/ssl/ssl_rsa.c
+++ b/ssl/ssl_rsa.c
@@ -443,8 +443,7 @@
if (c->pkeys[i].x509 != NULL)
X509_free(c->pkeys[i].x509);
- CRYPTO_add(&x->references,1,CRYPTO_LOCK_X509);
- c->pkeys[i].x509=x;
+ c->pkeys[i].x509 = X509_up_ref(x);
c->key= &(c->pkeys[i]);
c->valid=0;