Skip to content

Commit 838aaae

Browse files
olszomalmtrojnar
authored andcommitted
libp11 PKCS#11 provider support
1 parent e8f19a6 commit 838aaae

File tree

6 files changed

+348
-299
lines changed

6 files changed

+348
-299
lines changed

CMakeLists.txt

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,8 +27,15 @@ set(PACKAGE_BUGREPORT "[email protected]")
2727
set(CMAKE_C_STANDARD 11)
2828
set(CMAKE_C_STANDARD_REQUIRED ON)
2929

30+
if(WIN32)
31+
add_definitions(-DUSE_WIN32)
32+
endif()
33+
3034
# load CMake library modules
3135
include(FindOpenSSL)
36+
if(OPENSSL_VERSION VERSION_LESS "1.1.1")
37+
message(FATAL_ERROR "OpenSSL version must be at least 1.1.1")
38+
endif()
3239
if(OPENSSL_VERSION VERSION_LESS "3.0.0")
3340
include(FindCURL)
3441
endif(OPENSSL_VERSION VERSION_LESS "3.0.0")

NEWS.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
- added the "-engineCtrl" option to control hardware and CNG engines
77
- improved unauthenticated blob support (thanks to Asger Hautop Drewsen)
88
- added the '-blobFile' option to specify a file containing the blob content
9+
- added PKCS#11 provider support (requires OpenSSL 3.0)
910

1011
### 2.9 (2024.06.29)
1112

README.md

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -131,17 +131,28 @@ To sign a CAB file containing java class files:
131131
```
132132
Only the 'low' parameter is currently supported.
133133

134-
If you want to use PKCS11 token, you should indicate PKCS11 engine and module.
134+
If you want to use a PKCS#11 token, you should specify the PKCS#11 engine and module.
135135
An example of using osslsigncode with SoftHSM:
136136
```
137137
osslsigncode sign \
138-
-pkcs11engine /usr/lib64/engines-1.1/pkcs11.so \
138+
-engine /usr/lib64/engines-1.1/pkcs11.so \
139139
-pkcs11module /usr/lib64/pkcs11/libsofthsm2.so \
140140
-pkcs11cert 'pkcs11:token=softhsm-token;object=cert' \
141141
-key 'pkcs11:token=softhsm-token;object=key' \
142142
-in yourapp.exe -out yourapp-signed.exe
143143
```
144144

145+
Since OpenSSL 3.0, you can use a PKCS#11 token with the PKCS#11 provider.
146+
An example of using osslsigncode with OpenSC:
147+
```
148+
osslsigncode sign \
149+
-provider /usr/lib64/ossl-modules/pkcs11prov.so \
150+
-pkcs11module /usr/lib64/opensc-pkcs11.so \
151+
-pkcs11cert 'pkcs11:token=my-token;object=cert' \
152+
-key 'pkcs11:token=my-token;object=key' \
153+
-in yourapp.exe -out yourapp-signed.exe
154+
```
155+
145156
You can use a certificate and key stored in the Windows Certificate Store with
146157
the CNG engine version 1.1 or later. For more information, refer to
147158

@@ -156,7 +167,7 @@ placed in the same directory as the `osslsigncode.exe` executable.
156167
Below is an example of how to use osslsigncode with the CNG engine:
157168
```
158169
osslsigncode sign \
159-
-pkcs11engine cng \
170+
-engine cng \
160171
-pkcs11cert osslsigncode_cert \
161172
-key osslsigncode_cert \
162173
-engineCtrl store_flags:0 \

helpers.c

Lines changed: 39 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -165,73 +165,76 @@ int data_write_pkcs7(FILE_FORMAT_CTX *ctx, BIO *outdata, PKCS7 *p7)
165165
PKCS7 *pkcs7_create(FILE_FORMAT_CTX *ctx)
166166
{
167167
int i, signer = -1;
168-
PKCS7 *p7;
169168
PKCS7_SIGNER_INFO *si = NULL;
170169
STACK_OF(X509) *chain = NULL;
170+
PKCS7 *p7 = PKCS7_new();
171+
172+
if (!p7)
173+
return NULL;
171174

172-
p7 = PKCS7_new();
173175
PKCS7_set_type(p7, NID_pkcs7_signed);
174176
PKCS7_content_new(p7, NID_pkcs7_data);
175-
if (ctx->options->cert != NULL) {
176-
/*
177-
* the private key and corresponding certificate are parsed from the PKCS12
178-
* structure or loaded from the security token, so we may omit to check
179-
* the consistency of a private key with the public key in an X509 certificate
180-
*/
181-
si = PKCS7_add_signature(p7, ctx->options->cert, ctx->options->pkey,
182-
ctx->options->md);
183-
if (si == NULL)
184-
return NULL; /* FAILED */
185-
} else {
186-
/* find the signer's certificate located somewhere in the whole certificate chain */
187-
for (i=0; i<sk_X509_num(ctx->options->certs); i++) {
188-
X509 *signcert = sk_X509_value(ctx->options->certs, i);
189-
if (X509_check_private_key(signcert, ctx->options->pkey)) {
190-
si = PKCS7_add_signature(p7, signcert, ctx->options->pkey, ctx->options->md);
191-
signer = i;
192-
break;
193-
}
194-
}
195-
if (si == NULL) {
196-
fprintf(stderr, "Failed to checking the consistency of a private key: %s\n",
197-
ctx->options->keyfile);
198-
fprintf(stderr, " with a public key in any X509 certificate: %s\n\n",
199-
ctx->options->certfile);
200-
return NULL; /* FAILED */
177+
178+
/* find the signer's certificate located somewhere in the whole certificate chain */
179+
for (i=0; i<sk_X509_num(ctx->options->certs); i++) {
180+
X509 *signcert = sk_X509_value(ctx->options->certs, i);
181+
182+
if (X509_check_private_key(signcert, ctx->options->pkey)) {
183+
si = PKCS7_add_signature(p7, signcert, ctx->options->pkey, ctx->options->md);
184+
signer = i;
185+
if (signer > 0)
186+
printf("Warning: For optimal performance, consider placing the signer certificate at the beginning of the certificate chain.\n");
187+
break;
201188
}
202189
}
190+
if (!si) {
191+
fprintf(stderr, "Failed to checking the consistency of a private key: %s\n",
192+
ctx->options->keyfile);
193+
fprintf(stderr, " with a public key in any X509 certificate: %s\n\n",
194+
#if !defined(OPENSSL_NO_ENGINE) || OPENSSL_VERSION_NUMBER>=0x30000000L
195+
ctx->options->certfile ? ctx->options->certfile : ctx->options->p11cert);
196+
#else
197+
ctx->options->certfile);
198+
#endif /* !defined(OPENSSL_NO_ENGINE) || OPENSSL_VERSION_NUMBER>=0x30000000L */
199+
goto err;
200+
}
201+
203202
if (!pkcs7_signer_info_add_signing_time(si, ctx)) {
204-
return NULL; /* FAILED */
203+
goto err;
205204
}
206205
if (!pkcs7_signer_info_add_purpose(si, ctx)) {
207-
return NULL; /* FAILED */
206+
goto err;
208207
}
209208
if ((ctx->options->desc || ctx->options->url) &&
210209
!pkcs7_signer_info_add_spc_sp_opus_info(si, ctx)) {
211210
fprintf(stderr, "Couldn't allocate memory for opus info\n");
212-
return NULL; /* FAILED */
211+
goto err;
213212
}
214213
if ((ctx->options->nested_number >= 0) &&
215214
!pkcs7_signer_info_add_sequence_number(si, ctx)) {
216-
return NULL; /* FAILED */
215+
goto err;
217216
}
218217
/* create X509 chain sorted in ascending order by their DER encoding */
219218
chain = X509_chain_get_sorted(ctx, signer);
220-
if (chain == NULL) {
219+
if (!chain) {
221220
fprintf(stderr, "Failed to create a sorted certificate chain\n");
222-
return NULL; /* FAILED */
221+
goto err;
223222
}
224223
/* add sorted certificate chain */
225224
for (i=0; i<sk_X509_num(chain); i++) {
226-
PKCS7_add_certificate(p7, sk_X509_value(chain, i));
225+
(void)PKCS7_add_certificate(p7, sk_X509_value(chain, i));
227226
}
228227
/* add crls */
229228
if (ctx->options->crls) {
230229
for (i=0; i<sk_X509_CRL_num(ctx->options->crls); i++)
231-
PKCS7_add_crl(p7, sk_X509_CRL_value(ctx->options->crls, i));
230+
(void)PKCS7_add_crl(p7, sk_X509_CRL_value(ctx->options->crls, i));
232231
}
233232
sk_X509_free(chain);
234233
return p7; /* OK */
234+
235+
err:
236+
PKCS7_free(p7);
237+
return NULL; /* FAILED */
235238
}
236239

237240
/*
@@ -732,11 +735,6 @@ static STACK_OF(X509) *X509_chain_get_sorted(FILE_FORMAT_CTX *ctx, int signer)
732735
int i;
733736
STACK_OF(X509) *chain = sk_X509_new(X509_compare);
734737

735-
/* add the signer's certificate */
736-
if (ctx->options->cert != NULL && !sk_X509_push(chain, ctx->options->cert)) {
737-
sk_X509_free(chain);
738-
return NULL;
739-
}
740738
if (signer != -1 && !sk_X509_push(chain, sk_X509_value(ctx->options->certs, signer))) {
741739
sk_X509_free(chain);
742740
return NULL;

0 commit comments

Comments
 (0)