4444#include < sys/stat.h>
4545#include < sys/types.h>
4646
47+ # if SMARTCARD
48+ # define OPENSSL_SUPPRESS_DEPRECATED
49+ /* We need to use engines, which are deprecated */
50+ # endif
51+
4752#include < openssl/opensslv.h>
4853# if OPENSSL_VERSION_MAJOR >= 3
4954# include < openssl/provider.h>
@@ -1867,7 +1872,7 @@ class P12Signer : public ldid::Signer {
18671872 STACK_OF (X509) *ca_;
18681873
18691874 public:
1870- P12Signer (BIO *bio) :
1875+ P12Signer (BIO *bio, std::vector<std::string> certs ) :
18711876 value_ (d2i_PKCS12_bio(bio, NULL )),
18721877 key_ (NULL ),
18731878 cert_ (NULL ),
@@ -1888,7 +1893,7 @@ class P12Signer : public ldid::Signer {
18881893 fprintf (stderr, " ldid: An error occured while parsing: %s\n " , ERR_error_string (ERR_get_error (), NULL ));
18891894 exit (1 );
18901895 }
1891- if (key_ == NULL || cert_ == NULL ) {
1896+ if (key_ == NULL || ( cert_ == NULL && certs. empty ()) ) {
18921897 fprintf (stderr, " ldid: An error occured while parsing: %s\n Your p12 cert might not be valid\n " , ERR_error_string (ERR_get_error (), NULL ));
18931898 exit (1 );
18941899 }
@@ -1899,6 +1904,22 @@ class P12Signer : public ldid::Signer {
18991904 fprintf (stderr, " ldid: An error occured while parsing: %s\n " , ERR_error_string (ERR_get_error (), NULL ));
19001905 exit (1 );
19011906 }
1907+
1908+ if (!certs.empty ()) {
1909+ cert_ = d2i_X509_bio (Buffer (Map (certs[0 ], false )), NULL );
1910+ certs.erase (certs.begin ());
1911+ _foreach (certid, certs) {
1912+ X509 *cert = d2i_X509_bio (Buffer (Map (certid, false )), NULL );
1913+ if (cert == NULL ) {
1914+ fprintf (stderr, " ldid: An error occured while parsing: %s\n " , ERR_error_string (ERR_get_error (), NULL ));
1915+ exit (1 );
1916+ }
1917+ if (sk_X509_push (ca_, cert) == 0 ) {
1918+ fprintf (stderr, " ldid: An error occured while loading: %s\n " , ERR_error_string (ERR_get_error (), NULL ));
1919+ exit (1 );
1920+ }
1921+ }
1922+ }
19021923 }
19031924
19041925 ~P12Signer () {
@@ -1932,16 +1953,63 @@ class P11Signer : public ldid::Signer {
19321953 EVP_PKEY *key_;
19331954 X509 *cert_;
19341955 STACK_OF (X509) *ca_;
1956+ bool supportLoadCert = false ;
1957+
1958+ X509 *loadcert (std::string cert_id) {
1959+ if (cert_id.compare (0 , 7 , " pkcs11:" ) == 0 ) {
1960+ const char *cmd_name = " LOAD_CERT_CTRL" ;
1961+ struct {
1962+ const char *cert_id;
1963+ X509 *cert;
1964+ } params;
1965+
1966+ params.cert_id = cert_id.c_str ();
1967+ params.cert = NULL ;
1968+
1969+ if (!supportLoadCert) {
1970+ if (ENGINE_ctrl (e_, ENGINE_CTRL_GET_CMD_FROM_NAME, 0 , (void *)cmd_name, NULL ) == 0 ) {
1971+ fprintf (stderr, " ldid: Engine does not support loading certificate: %s\n " , ERR_error_string (ERR_get_error (), NULL ));
1972+ exit (1 );
1973+ }
1974+ supportLoadCert = true ;
1975+ }
1976+
1977+ if (ENGINE_ctrl_cmd (e_, cmd_name, 0 , ¶ms, NULL , 1 ) == 0 ) {
1978+ fprintf (stderr, " ldid: Engine cannot load certificate: %s\n " , ERR_error_string (ERR_get_error (), NULL ));
1979+ exit (1 );
1980+ }
1981+
1982+ if (params.cert == NULL ) {
1983+ fprintf (stderr, " ldid: An error occured while loading: %s\n " , ERR_error_string (ERR_get_error (), NULL ));
1984+ exit (1 );
1985+ }
1986+
1987+ return params.cert ;
1988+ } else {
1989+ X509 *cert = d2i_X509_bio (Buffer (Map (cert_id, false )), NULL );
1990+ if (cert == NULL ) {
1991+ fprintf (stderr, " ldid: An error occured while loading: %s\n " , ERR_error_string (ERR_get_error (), NULL ));
1992+ exit (1 );
1993+ }
1994+
1995+ return cert;
1996+ }
1997+ }
19351998
19361999 public:
19372000 P11Signer (std::string uri)
1938- : P11Signer(uri, uri ) {}
2001+ : P11Signer(uri, {} ) {}
19392002
1940- P11Signer (std::string keyuri, std::string certuri ) :
2003+ P11Signer (std::string keyuri, std::vector<std:: string> certs ) :
19412004 key_ (NULL ),
19422005 cert_ (NULL ),
1943- ca_ (NULL )
2006+ ca_ (sk_X509_new_null() )
19442007 {
2008+ if (ca_ == NULL ) {
2009+ fprintf (stderr, " ldid: An error occured while loading: %s\n " , ERR_error_string (ERR_get_error (), NULL ));
2010+ exit (1 );
2011+ }
2012+
19452013 e_ = ENGINE_by_id (" pkcs11" );
19462014 if (!e_) {
19472015 fprintf (stderr, " ldid: An error occured while loading pkcs11 engine: %s\n " , ERR_error_string (ERR_get_error (), NULL ));
@@ -1952,56 +2020,33 @@ class P11Signer : public ldid::Signer {
19522020 fprintf (stderr, " ldid: Failed to initialize pkcs11 engine: %s\n " , ERR_error_string (ERR_get_error (), NULL ));
19532021 exit (1 );
19542022 }
1955- ENGINE_free (e_);
2023+ ENGINE_free (e_); // for ENGINE_by_id()
19562024
19572025 key_ = ENGINE_load_private_key (e_, keyuri.c_str (), NULL , NULL );
19582026 if (key_ == NULL ){
19592027 fprintf (stderr, " ldid: An error occured while loading: %s\n " , ERR_error_string (ERR_get_error (), NULL ));
19602028 exit (1 );
19612029 }
19622030
1963- const char *cmd_name = " LOAD_CERT_CTRL" ;
1964- struct {
1965- const char *cert_id;
1966- X509 *cert;
1967- } params;
1968-
1969- params.cert_id = certuri.c_str ();
1970- params.cert = NULL ;
1971-
1972- if (ENGINE_ctrl (e_, ENGINE_CTRL_GET_CMD_FROM_NAME, 0 , (void *)cmd_name, NULL ) == 0 ) {
1973- fprintf (stderr, " ldid: Engine does not support loading certificate: %s\n " , ERR_error_string (ERR_get_error (), NULL ));
1974- exit (1 );
1975- }
1976-
1977- if (ENGINE_ctrl_cmd (e_, cmd_name, 0 , ¶ms, NULL , 1 ) == 0 ) {
1978- fprintf (stderr, " ldid: Engine cannot load certificate: %s\n " , ERR_error_string (ERR_get_error (), NULL ));
1979- exit (1 );
1980- }
1981-
1982- cert_ = params.cert ;
1983-
1984- if (cert_ == NULL ) {
1985- fprintf (stderr, " ldid: An error occured while loading: %s\n " , ERR_error_string (ERR_get_error (), NULL ));
1986- exit (1 );
1987- }
1988-
1989- if (ca_ == NULL )
1990- ca_ = sk_X509_new_null ();
1991- if (ca_ == NULL ) {
1992- fprintf (stderr, " ldid: An error occured while loading: %s\n " , ERR_error_string (ERR_get_error (), NULL ));
1993- exit (1 );
2031+ if (certs.empty ()) {
2032+ cert_ = loadcert (keyuri);
2033+ } else {
2034+ cert_ = loadcert (certs[0 ]);
2035+ certs.erase (certs.begin ());
2036+ _foreach (certid, certs) {
2037+ if (sk_X509_push (ca_, loadcert (certid)) == 0 ) {
2038+ fprintf (stderr, " ldid: An error occured while loading: %s\n " , ERR_error_string (ERR_get_error (), NULL ));
2039+ exit (1 );
2040+ }
2041+ }
19942042 }
19952043 }
19962044
19972045 ~P11Signer () {
19982046 sk_X509_pop_free (ca_, X509_free);
19992047 X509_free (cert_);
20002048 EVP_PKEY_free (key_);
2001- if (e_) {
2002- ENGINE_finish (e_);
2003- ENGINE_free (e_);
2004- }
2049+ ENGINE_finish (e_); // for ENGINE_init()
20052050 }
20062051
20072052 operator EVP_PKEY *() const {
@@ -3506,6 +3551,7 @@ int main(int argc, char *argv[]) {
35063551 Map entitlements;
35073552 Map requirements;
35083553 std::string key;
3554+ std::vector<std::string> certs;
35093555 ldid::Signer *signer = new NoSigner ();
35103556 ldid::Slots slots;
35113557
@@ -3714,6 +3760,11 @@ int main(int argc, char *argv[]) {
37143760 key = argv[argi] + 2 ;
37153761 break ;
37163762
3763+ case ' X' :
3764+ if (argv[argi][2 ] != ' \0 ' )
3765+ certs.push_back (argv[argi] + 2 );
3766+ break ;
3767+
37173768 case ' T' : break ;
37183769
37193770 case ' u' : {
@@ -3739,14 +3790,16 @@ int main(int argc, char *argv[]) {
37393790 return 0 ;
37403791
37413792 if (!key.empty ()) {
3742- # if SMARTCARD
3793+ delete signer;
37433794 if (key.compare (0 , 7 , " pkcs11:" ) == 0 ) {
3744- signer = new P11Signer (key);
3745- } else
3795+ #if SMARTCARD
3796+ signer = new P11Signer (key, certs);
3797+ #else
3798+ fprintf (stderr, " ldid: Smartcard support is not enabled\n " );
3799+ exit (1 );
37463800#endif
3747- {
3748- signer = new P12Signer (Buffer (Map (key, O_RDONLY)));
3749- }
3801+ } else
3802+ signer = new P12Signer (Buffer (Map (key, O_RDONLY, PROT_READ, MAP_PRIVATE)), certs);
37503803 }
37513804
37523805 size_t filei (0 ), filee (0 );
@@ -4049,15 +4102,17 @@ int main(int argc, char *argv[]) {
40494102 ++filei;
40504103 }
40514104
4052- # if OPENSSL_VERSION_MAJOR >= 3
4053- OSSL_PROVIDER_unload (legacy);
4054- OSSL_PROVIDER_unload (deflt);
4055- # endif
4105+ delete signer;
40564106
40574107# if SMARTCARD
40584108 ENGINE_cleanup ();
40594109# endif
40604110
4111+ # if OPENSSL_VERSION_MAJOR >= 3
4112+ OSSL_PROVIDER_unload (legacy);
4113+ OSSL_PROVIDER_unload (deflt);
4114+ # endif
4115+
40614116 return filee;
40624117}
40634118#endif // LDID_NOTOOLS
0 commit comments