Skip to content

Commit 798f55b

Browse files
committed
Add -X flag for seperate pkcs11 uri for Certificate
Ex: ldid -K'pkcs11:object=MyKey;type=private' -X'pkcs11:object=MyKey;type=cert' ldid -KCertificates.p12 -XExtractedFromP12.cer -XAppleWWDRCAG3.cer -XAppleIncRootCertificate.cer
1 parent 88b05b3 commit 798f55b

File tree

4 files changed

+124
-54
lines changed

4 files changed

+124
-54
lines changed

PKCS11.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,8 @@ yubico-piv-tool -s 9c -a import-certificate -i cert.crt.pem
1717
yubico-piv-tool -s 9c -a import-key -i key.pem
1818
yubico-piv-tool -s 9c -a set-chuid
1919
```
20-
3. You can use `p11tool --list-privkeys --login` to identify the URI for the slot (make sure that `type` is not in the URI, as seperate URIs for the cert and private key are not currently supported from the command line)
20+
3. You can use `p11tool --list-privkeys --login` and `p11tool --list-certs --login` to help identify the URIs for the private key and certificate
2121

2222
## Sign
23-
1. `ldid -K'pkcs11:model=YubiKey%20YK5;id=%02' -Sents.xml ls.bin`
23+
1. `ldid -K'pkcs11:object=Private%20key%20for%20Digital%20Signature;type=private' -X'pkcs11:object=X.509%20Certificate%20for%20Digital%20Signature;type=cert' -Sents.xml ls.bin`
2424
2. If the correct PKCS#11 module is not being loaded, try setting `PKCS11_MODULE_PATH` in your environment (ex. `export PKCS11_MODULE_PATH="/usr/local/lib/p11-kit-proxy.so"` or `PKCS11_MODULE_PATH="/usr/local/lib/libykcs11.so"`)

docs/ldid.1

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@
2020
.Op Fl H Ns Op Ar sha1 | Ar sha256
2121
.Op Fl h
2222
.Op Fl I Ns Ar name
23-
.Op Fl K Ns Ar file Op Fl U Ns Ar password
23+
.Op Fl K Ns Ar file Oo Fl U Ns Ar password Oc Op Fl X Ns Ar file
2424
.Op Fl M
2525
.Op Fl P Ns Op Ar num
2626
.Op Fl Q Ns Ar requirements
@@ -108,6 +108,8 @@ If the
108108
has a password, you will be prompted for it,
109109
or you can specify from the command line with
110110
.Fl U .
111+
To specify the certificate separate from the private key, use
112+
.Fl X .
111113
.It Fl M
112114
When used with
113115
.Fl S ,
@@ -160,6 +162,18 @@ target is a bundle directory, and not a specific Mach-O file.
160162
.Fl w
161163
can be used on any bundle, not just the root .app, including frameworks,
162164
appexes, and more.
165+
.It Fl X Ns Ar file
166+
Adds
167+
.Ar file
168+
as a certificate to be used when signing.
169+
The first
170+
.Ar file
171+
must be the certificate for the signing key, each additional will be added as part of the chain.
172+
Must be either
173+
.Ar DER
174+
encoded certificate or
175+
.Ar pkcs11:
176+
URI.
163177
.El
164178
.Sh EXAMPLES
165179
To fakesign

ldid.cpp

Lines changed: 106 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,11 @@
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\nYour 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, &params, 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, &params, 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

ldid.hpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -161,6 +161,7 @@ struct Bundle {
161161

162162
class Signer {
163163
public:
164+
virtual ~Signer() {};
164165
virtual operator EVP_PKEY *() const = 0;
165166
virtual operator X509 *() const = 0;
166167
virtual operator STACK_OF(X509) *() const = 0;

0 commit comments

Comments
 (0)