summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authortb <>2021-11-06 12:31:40 +0000
committertb <>2021-11-06 12:31:40 +0000
commitf01f56497c4c06d0958a4016fdb914ec1d2d496c (patch)
treeecb526e27f4bb483191cc3b3ab9743f35b52f8ec
parentf7a941809fd72aa44a2d525fb2e61ee97b2b3d7c (diff)
downloadopenbsd-f01f56497c4c06d0958a4016fdb914ec1d2d496c.tar.gz
openbsd-f01f56497c4c06d0958a4016fdb914ec1d2d496c.tar.bz2
openbsd-f01f56497c4c06d0958a4016fdb914ec1d2d496c.zip
Start cleaning up X509_STORE_get1_issuer()
Get rid of the last X509_OBJECT_free_contents() call by moving the object from the stack to the heap. I deliberately kept the obj variable to keep obj and pobj separate. Rename the out parameter from issuer to out_issuer to ensure that we only assign it when we have acquired a reference that we can return. Add a new X509 *issuer. In the first part of the function, acquire an extra reference before check_issuer/check_time. In the second part of the function, acquire a reference inside the lock to avoid a race. Deal with ret only in one place. ok jsing
-rw-r--r--src/lib/libcrypto/x509/x509_lu.c52
1 files changed, 37 insertions, 15 deletions
diff --git a/src/lib/libcrypto/x509/x509_lu.c b/src/lib/libcrypto/x509/x509_lu.c
index c47e8f9dd1..f9feaa6349 100644
--- a/src/lib/libcrypto/x509/x509_lu.c
+++ b/src/lib/libcrypto/x509/x509_lu.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: x509_lu.c,v 1.50 2021/11/06 12:27:05 tb Exp $ */ 1/* $OpenBSD: x509_lu.c,v 1.51 2021/11/06 12:31:40 tb Exp $ */
2/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) 2/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
3 * All rights reserved. 3 * All rights reserved.
4 * 4 *
@@ -685,30 +685,46 @@ X509_OBJECT_retrieve_match(STACK_OF(X509_OBJECT) *h, X509_OBJECT *x)
685 * -1 some other error. 685 * -1 some other error.
686 */ 686 */
687int 687int
688X509_STORE_CTX_get1_issuer(X509 **issuer, X509_STORE_CTX *ctx, X509 *x) 688X509_STORE_CTX_get1_issuer(X509 **out_issuer, X509_STORE_CTX *ctx, X509 *x)
689{ 689{
690 X509_NAME *xn; 690 X509_NAME *xn;
691 X509_OBJECT obj, *pobj; 691 X509_OBJECT *obj, *pobj;
692 X509 *issuer = NULL;
692 int i, idx, ret; 693 int i, idx, ret;
693 694
694 *issuer = NULL; 695 *out_issuer = NULL;
696
695 xn = X509_get_issuer_name(x); 697 xn = X509_get_issuer_name(x);
696 if (!X509_STORE_get_by_subject(ctx, X509_LU_X509, xn, &obj)) 698 obj = X509_STORE_CTX_get_obj_by_subject(ctx, X509_LU_X509, xn);
699 if (obj == NULL)
700 return 0;
701
702 if ((issuer = X509_OBJECT_get0_X509(obj)) == NULL) {
703 X509_OBJECT_free(obj);
697 return 0; 704 return 0;
705 }
706 if (!X509_up_ref(issuer)) {
707 X509_OBJECT_free(obj);
708 return -1;
709 }
710
698 /* If certificate matches all OK */ 711 /* If certificate matches all OK */
699 if (ctx->check_issued(ctx, x, obj.data.x509)) { 712 if (ctx->check_issued(ctx, x, issuer)) {
700 if (x509_check_cert_time(ctx, obj.data.x509, -1)) { 713 if (x509_check_cert_time(ctx, issuer, -1)) {
701 *issuer = obj.data.x509; 714 *out_issuer = issuer;
715 X509_OBJECT_free(obj);
702 return 1; 716 return 1;
703 } 717 }
704 } 718 }
705 X509_OBJECT_free_contents(&obj); 719 X509_free(issuer);
720 issuer = NULL;
721 X509_OBJECT_free(obj);
722 obj = NULL;
706 723
707 if (ctx->ctx == NULL) 724 if (ctx->ctx == NULL)
708 return 0; 725 return 0;
709 726
710 /* Else find index of first cert accepted by 'check_issued' */ 727 /* Else find index of first cert accepted by 'check_issued' */
711 ret = 0;
712 CRYPTO_w_lock(CRYPTO_LOCK_X509_STORE); 728 CRYPTO_w_lock(CRYPTO_LOCK_X509_STORE);
713 idx = X509_OBJECT_idx_by_subject(ctx->ctx->objs, X509_LU_X509, xn); 729 idx = X509_OBJECT_idx_by_subject(ctx->ctx->objs, X509_LU_X509, xn);
714 if (idx != -1) /* should be true as we've had at least one match */ { 730 if (idx != -1) /* should be true as we've had at least one match */ {
@@ -722,22 +738,28 @@ X509_STORE_CTX_get1_issuer(X509 **issuer, X509_STORE_CTX *ctx, X509 *x)
722 X509_get_subject_name(pobj->data.x509))) 738 X509_get_subject_name(pobj->data.x509)))
723 break; 739 break;
724 if (ctx->check_issued(ctx, x, pobj->data.x509)) { 740 if (ctx->check_issued(ctx, x, pobj->data.x509)) {
725 *issuer = pobj->data.x509; 741 issuer = pobj->data.x509;
726 ret = 1;
727 /* 742 /*
728 * If times check, exit with match, 743 * If times check, exit with match,
729 * otherwise keep looking. Leave last 744 * otherwise keep looking. Leave last
730 * match in issuer so we return nearest 745 * match in issuer so we return nearest
731 * match if no certificate time is OK. 746 * match if no certificate time is OK.
732 */ 747 */
733 if (x509_check_cert_time(ctx, *issuer, -1)) 748 if (x509_check_cert_time(ctx, issuer, -1))
734 break; 749 break;
735 } 750 }
736 } 751 }
737 } 752 }
753 ret = 0;
754 if (issuer != NULL) {
755 if (!X509_up_ref(issuer)) {
756 ret = -1;
757 } else {
758 *out_issuer = issuer;
759 ret = 1;
760 }
761 }
738 CRYPTO_w_unlock(CRYPTO_LOCK_X509_STORE); 762 CRYPTO_w_unlock(CRYPTO_LOCK_X509_STORE);
739 if (*issuer)
740 CRYPTO_add(&(*issuer)->references, 1, CRYPTO_LOCK_X509);
741 return ret; 763 return ret;
742} 764}
743 765