There is no need to make a deep copy of the certificate that was deserialized as part of the d2i_CMS_ContentInfo() call. We can as well keep a reference to it.
While X509_dup() can actually fail, X509_up_ref() can't. It seems cleaner to have a check. Index: cms.c =================================================================== RCS file: /cvs/src/usr.sbin/rpki-client/cms.c,v retrieving revision 1.20 diff -u -p -r1.20 cms.c --- cms.c 31 May 2022 18:41:43 -0000 1.20 +++ cms.c 10 Aug 2022 14:33:02 -0000 @@ -222,7 +222,11 @@ cms_parse_validate(X509 **xp, const char "want 1 signer, have %d", fn, sk_X509_num(certs)); goto out; } - *xp = X509_dup(sk_X509_value(certs, 0)); + *xp = sk_X509_value(certs, 0); + if (!X509_up_ref(*xp)) { + *xp = NULL; + goto out; + } /* Cache X509v3 extensions, see X509_check_ca(3). */ if (X509_check_purpose(*xp, -1, -1) <= 0) {