Skip to content

Commit 1be550a

Browse files
committed
Remove duplicate certs from sorted X509 chain
1 parent b01ffae commit 1be550a

File tree

1 file changed

+33
-0
lines changed

1 file changed

+33
-0
lines changed

helpers.c

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ static int pkcs7_signer_info_add_purpose(PKCS7_SIGNER_INFO *si, FILE_FORMAT_CTX
1717
static int pkcs7_signer_info_add_sequence_number(PKCS7_SIGNER_INFO *si, FILE_FORMAT_CTX *ctx);
1818
static STACK_OF(X509) *X509_chain_get_sorted(FILE_FORMAT_CTX *ctx, int signer);
1919
static int X509_compare(const X509 *const *a, const X509 *const *b);
20+
static void sk_X509_remove_duplicates(STACK_OF(X509) *chain);
2021

2122
/*
2223
* Common functions
@@ -763,6 +764,9 @@ static STACK_OF(X509) *X509_chain_get_sorted(FILE_FORMAT_CTX *ctx, int signer)
763764
}
764765
/* sort certificate chain using the supplied comparison function */
765766
sk_X509_sort(chain);
767+
/* remove duplicates */
768+
sk_X509_remove_duplicates(chain);
769+
766770
return chain;
767771
}
768772

@@ -814,6 +818,35 @@ static int X509_compare(const X509 *const *a, const X509 *const *b)
814818
return ret;
815819
}
816820

821+
/*
822+
* Remove duplicate certificates from a sorted STACK_OF(X509).
823+
*
824+
* This function assumes the stack is sorted according to X.690-compliant
825+
* certificate comparison, so duplicate certificates appear consecutively.
826+
* It iterates through the stack and removes any duplicate certificates
827+
* by comparing each element with its immediate predecessor.
828+
* The stack is modified in place.
829+
*/
830+
static void sk_X509_remove_duplicates(STACK_OF(X509) *chain)
831+
{
832+
int i, n = sk_X509_num(chain);
833+
834+
if (n < 2)
835+
return;
836+
837+
/* start from the second element */
838+
for (i = 1; i < n; ) {
839+
if (!X509_cmp(sk_X509_value(chain, i - 1), sk_X509_value(chain, i))) {
840+
/* duplicate found: remove the certificate at index i */
841+
(void)sk_X509_delete(chain, i);
842+
n--; /* reduce stack size since one element was removed */
843+
/* do not increment i, as next element shifts into index i */
844+
} else {
845+
i++; /* advance only if no removal was done */
846+
}
847+
}
848+
}
849+
817850
/*
818851
Local Variables:
819852
c-basic-offset: 4

0 commit comments

Comments
 (0)