Skip to content

Commit db5b4c4

Browse files
authored
Add the "-engineCtrl" option to control hardware and CNG engines (#405)
Documentation updated for CNG engine 1.1 compatibility.
1 parent 4ee4297 commit db5b4c4

File tree

4 files changed

+84
-0
lines changed

4 files changed

+84
-0
lines changed

NEWS.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22

33
### 2.10 (unreleased)
44

5+
- added compatiblity with the CNG engine version 1.1 or later
6+
- added the "-engineCtrl" option to control hardware and CNG engines
57
- improved unauthenticated blob support (thanks to Asger Hautop Drewsen)
68
- added the '-blobFile' option to specify a file containing the blob content
79

README.md

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -142,6 +142,29 @@ An example of using osslsigncode with SoftHSM:
142142
-in yourapp.exe -out yourapp-signed.exe
143143
```
144144

145+
You can use a certificate and key stored in the Windows Certificate Store with
146+
the CNG engine version 1.1 or later. For more information, refer to
147+
148+
https://www.stunnel.org/cng-engine.html
149+
150+
A non-commercial edition of CNG engine is available for testing, personal,
151+
educational, or research purposes.
152+
153+
To use the CNG engine with osslsigncode, ensure that the `cng.dll` library is
154+
placed in the same directory as the `osslsigncode.exe` executable.
155+
156+
Below is an example of how to use osslsigncode with the CNG engine:
157+
```
158+
osslsigncode sign \
159+
-pkcs11engine cng \
160+
-pkcs11cert osslsigncode_cert \
161+
-key osslsigncode_cert \
162+
-engineCtrl store_flags:0 \
163+
-engineCtrl store_name:MY \
164+
-engineCtrl PIN:yourpass \
165+
-in yourapp.exe -out yourapp-signed.exe
166+
```
167+
145168
You can check that the signed file is correct by right-clicking
146169
on it in Windows and choose Properties --> Digital Signatures,
147170
and then choose the signature from the list, and click on

osslsigncode.c

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -206,6 +206,14 @@ ASN1_SEQUENCE(MsCtlContent) = {
206206

207207
IMPLEMENT_ASN1_FUNCTIONS(MsCtlContent)
208208

209+
210+
ASN1_SEQUENCE(EngineControl) = {
211+
ASN1_SIMPLE(EngineControl, cmd, ASN1_OCTET_STRING),
212+
ASN1_SIMPLE(EngineControl, param, ASN1_OCTET_STRING)
213+
} ASN1_SEQUENCE_END(EngineControl)
214+
215+
IMPLEMENT_ASN1_FUNCTIONS(EngineControl)
216+
209217
/* Prototypes */
210218
static ASN1_INTEGER *create_nonce(int bits);
211219
static char *clrdp_url_get_x509(X509 *cert);
@@ -224,6 +232,7 @@ static int PKCS7_compare(const PKCS7 *const *a, const PKCS7 *const *b);
224232
static PKCS7 *pkcs7_get_sigfile(FILE_FORMAT_CTX *ctx);
225233
static void print_cert(X509 *cert, int i);
226234
static int x509_store_load_crlfile(X509_STORE *store, char *cafile, char *crlfile);
235+
static void engine_control_set(GLOBAL_OPTIONS *options, const char *arg);
227236

228237

229238
/*
@@ -3433,6 +3442,7 @@ static void free_options(GLOBAL_OPTIONS *options)
34333442
options->xcerts = NULL;
34343443
sk_X509_CRL_pop_free(options->crls, X509_CRL_free);
34353444
options->crls = NULL;
3445+
sk_EngineControl_pop_free(options->engine_ctrls, EngineControl_free);
34363446
}
34373447

34383448
/*
@@ -3459,6 +3469,7 @@ static void usage(const char *argv0, const char *cmd)
34593469
printf("%1s[ sign ] ( -pkcs12 <pkcs12file>\n", "");
34603470
printf("%13s | ( -certs <certfile> | -spc <certfile> ) -key <keyfile>\n", "");
34613471
printf("%13s | [ -pkcs11engine <engine> ] [ -login ] -pkcs11module <module>\n", "");
3472+
printf("%13s | [ -engineCtrl <command[:parameter]> ]\n", "");
34623473
printf("%15s ( -pkcs11cert <pkcs11 cert id> | -certs <certfile> ) -key <pkcs11 key id> )\n", "");
34633474
#if OPENSSL_VERSION_NUMBER>=0x30000000L
34643475
printf("%12s[ -nolegacy ]\n", "");
@@ -3596,6 +3607,7 @@ static void help_for(const char *argv0, const char *cmd)
35963607
const char *cmds_pkcs11cert[] = {"sign", NULL};
35973608
const char *cmds_pkcs11engine[] = {"sign", NULL};
35983609
const char *cmds_pkcs11module[] = {"sign", NULL};
3610+
const char *cmds_engineCtrl[] = {"sign", NULL};
35993611
const char *cmds_login[] = {"sign", NULL};
36003612
const char *cmds_pkcs12[] = {"sign", NULL};
36013613
const char *cmds_readpass[] = {"sign", NULL};
@@ -3734,6 +3746,8 @@ static void help_for(const char *argv0, const char *cmd)
37343746
printf("%-24s= PKCS#11 engine\n", "-pkcs11engine");
37353747
if (on_list(cmd, cmds_pkcs11module))
37363748
printf("%-24s= PKCS#11 module\n", "-pkcs11module");
3749+
if (on_list(cmd, cmds_engineCtrl))
3750+
printf("%-24s= control hardware engine\n", "-engineCtrl");
37373751
if (on_list(cmd, cmds_login))
37383752
printf("%-24s= force login to the token\n", "-login");
37393753
if (on_list(cmd, cmds_pkcs12))
@@ -4191,6 +4205,8 @@ static ENGINE *engine_pkcs11(void)
41914205
*/
41924206
static int read_token(GLOBAL_OPTIONS *options, ENGINE *engine)
41934207
{
4208+
int i;
4209+
41944210
if (options->p11module && !ENGINE_ctrl_cmd_string(engine, "MODULE_PATH", options->p11module, 0)) {
41954211
fprintf(stderr, "Failed to set pkcs11 engine MODULE_PATH to '%s'\n", options->p11module);
41964212
ENGINE_free(engine);
@@ -4211,6 +4227,20 @@ static int read_token(GLOBAL_OPTIONS *options, ENGINE *engine)
42114227
ENGINE_free(engine);
42124228
return 0; /* FAILED */
42134229
}
4230+
for (i = 0; i < sk_EngineControl_num(options->engine_ctrls); i++) {
4231+
EngineControl *engine_ctrl = sk_EngineControl_value(options->engine_ctrls, i);
4232+
const u_char *cmd = ASN1_STRING_get0_data(engine_ctrl->cmd);
4233+
const u_char *param = ASN1_STRING_get0_data(engine_ctrl->param);
4234+
4235+
if (param)
4236+
printf("Executing engine control command %s:%s\n", cmd, param);
4237+
else
4238+
printf("Executing engine control command %s\n", cmd);
4239+
4240+
if(!ENGINE_ctrl_cmd_string(engine, (const char *)cmd, (const char *)param, 0)) {
4241+
fprintf(stderr, "Failed to execute the engine control command\n");
4242+
}
4243+
}
42144244
/*
42154245
* ENGINE_init() returned a functional reference, so free the structural
42164246
* reference from ENGINE_by_id().
@@ -4479,6 +4509,7 @@ static int main_configure(int argc, char **argv, GLOBAL_OPTIONS *options)
44794509
/* Use legacy PKCS#12 container with RC2-40-CBC private key and certificate encryption algorithm */
44804510
options->legacy = 1;
44814511
#endif /* OPENSSL_VERSION_NUMBER>=0x30000000L */
4512+
options->engine_ctrls = sk_EngineControl_new_null();
44824513

44834514
if (cmd == CMD_HELP) {
44844515
return 0; /* FAILED */
@@ -4553,6 +4584,12 @@ static int main_configure(int argc, char **argv, GLOBAL_OPTIONS *options)
45534584
return 0; /* FAILED */
45544585
}
45554586
options->p11module = *(++argv);
4587+
} else if (!strcmp(*argv, "-engineCtrl")) {
4588+
if (--argc < 1) {
4589+
usage(argv0, "all");
4590+
return 0; /* FAILED */
4591+
}
4592+
engine_control_set(options, *(++argv));
45564593
} else if ((cmd == CMD_SIGN) && !strcmp(*argv, "-login")) {
45574594
options->login = 1;
45584595
#endif /* OPENSSL_NO_ENGINE */
@@ -4860,6 +4897,19 @@ static int main_configure(int argc, char **argv, GLOBAL_OPTIONS *options)
48604897
return 1; /* OK */
48614898
}
48624899

4900+
static void engine_control_set(GLOBAL_OPTIONS *options, const char *arg)
4901+
{
4902+
EngineControl *engine_ctrl = EngineControl_new();
4903+
char *tmp_str=strchr(arg, ':');
4904+
4905+
if(tmp_str) {
4906+
*tmp_str++='\0';
4907+
ASN1_STRING_set(engine_ctrl->param, tmp_str, (int)strlen(tmp_str));
4908+
}
4909+
ASN1_STRING_set(engine_ctrl->cmd, arg, (int)strlen(arg));
4910+
sk_EngineControl_push(options->engine_ctrls, engine_ctrl);
4911+
}
4912+
48634913
int main(int argc, char **argv)
48644914
{
48654915
FILE_FORMAT_CTX *ctx = NULL;

osslsigncode.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -244,6 +244,14 @@ typedef enum {
244244

245245
typedef unsigned char u_char;
246246

247+
typedef struct {
248+
ASN1_OCTET_STRING *cmd;
249+
ASN1_OCTET_STRING *param;
250+
} EngineControl;
251+
252+
DECLARE_ASN1_FUNCTIONS(EngineControl)
253+
DEFINE_STACK_OF(EngineControl)
254+
247255
typedef struct {
248256
char *infile;
249257
char *outfile;
@@ -307,6 +315,7 @@ typedef struct {
307315
char *tsa_keyfile;
308316
time_t tsa_time;
309317
int nested_number;
318+
STACK_OF(EngineControl) *engine_ctrls;
310319
} GLOBAL_OPTIONS;
311320

312321
/*

0 commit comments

Comments
 (0)