@@ -17,6 +17,7 @@ static int pkcs7_signer_info_add_purpose(PKCS7_SIGNER_INFO *si, FILE_FORMAT_CTX
1717static int pkcs7_signer_info_add_sequence_number (PKCS7_SIGNER_INFO * si , FILE_FORMAT_CTX * ctx );
1818static STACK_OF (X509 ) * X509_chain_get_sorted (FILE_FORMAT_CTX * ctx , int signer );
1919static 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/*
818851Local Variables:
819852 c-basic-offset: 4
0 commit comments