From c786ca873c2798dbc86aa500f014f500a158a1f2 Mon Sep 17 00:00:00 2001 From: olszomal Date: Fri, 17 Apr 2020 14:48:32 +0200 Subject: [PATCH 1/6] don't overwrite an existing file --- osslsigncode.c | 39 +++++++++++++++++++++++++++++++++++---- 1 file changed, 35 insertions(+), 4 deletions(-) diff --git a/osslsigncode.c b/osslsigncode.c index fb4d6bb..461ecba 100644 --- a/osslsigncode.c +++ b/osslsigncode.c @@ -58,6 +58,10 @@ */ +#ifdef __MINGW32__ +#define HAVE_WINDOWS_H +#endif /* __MINGW32__ */ + #ifdef HAVE_CONFIG_H #include "config.h" #endif /* HAVE_CONFIG_H */ @@ -2708,10 +2712,18 @@ static int msi_extract_signature_to_file(GsfInfile *infile, char *outfile) ret = 1; goto out; } - /* Create outdata file */ + /* Create outdata DER file */ +#ifdef WIN32 + if (!access(options->outfile, R_OK)) { + /* outdata file exists */ + printf("Failed to create file: %s\n", outfile); + ret = 1; + goto out; + } +#endif outdata = BIO_new_file(outfile, FILE_CREATE_MODE); if (outdata == NULL) { - printf("Unable to create %s\n\n", outfile); + printf("Failed to create file: %s\n", outfile); ret = 1; goto out; } @@ -2790,9 +2802,17 @@ static int msi_extract_file(GsfInfile *ole, GLOBAL_OPTIONS *options) fprintf(stderr, "Unable to extract existing signature\n"); return 1; /* FAILED */ } + /* Create outdata PEM file */ +#ifdef WIN32 + if (!access(options->outfile, R_OK)) { + /* outdata file exists */ + fprintf(stderr, "Failed to create file: %s\n", outfile); + return 1; /* FAILED */ + } +#endif outdata = BIO_new_file(options->outfile, FILE_CREATE_MODE); if (outdata == NULL) { - fprintf(stderr, "Unable to create %s\n", options->outfile); + fprintf(stderr, "Failed to create file: %s\n", options->outfile); return 1; /* FAILED */ } ret = !PEM_write_bio_PKCS7(outdata, sig); @@ -4575,9 +4595,15 @@ static PKCS7 *msi_presign_file(file_type_t type, cmd_type_t cmd, FILE_HEADER *he if (cmd == CMD_ADD) sig = *cursig; } + /* Create outdata MSI file */ + if (!access(options->outfile, R_OK)) { + /* outdata file exists */ + fprintf(stderr, "Failed to create file: %s\n", options->outfile); + return NULL; /* FAILED */ + } gsfparams->sink = gsf_output_stdio_new(options->outfile, NULL); if (!gsfparams->sink) { - fprintf(stderr, "Error opening output file %s\n", options->outfile); + fprintf(stderr, "Failed to create file: %s\n", options->outfile); return NULL; /* FAILED */ } gsfparams->outole = gsf_outfile_msole_new(gsfparams->sink); @@ -4981,6 +5007,11 @@ int main(int argc, char **argv) if ((type == FILE_TYPE_CAB || type == FILE_TYPE_PE) && (cmd != CMD_VERIFY)) { /* Create outdata file */ +#ifdef WIN32 + if (!access(options.outfile, R_OK)) + /* outdata file exists */ + DO_EXIT_1("Failed to create file: %s\n", options.outfile); +#endif outdata = BIO_new_file(options.outfile, FILE_CREATE_MODE); if (outdata == NULL) DO_EXIT_1("Failed to create file: %s\n", options.outfile); From dfad489090fed9f6584cf7529db2c1bbb495c79d Mon Sep 17 00:00:00 2001 From: olszomal Date: Fri, 17 Apr 2020 15:41:33 +0200 Subject: [PATCH 2/6] CAfile/untrusted file must exist to verify the signature --- osslsigncode.c | 23 ++++++++++++++++------- 1 file changed, 16 insertions(+), 7 deletions(-) diff --git a/osslsigncode.c b/osslsigncode.c index 461ecba..007db5f 100644 --- a/osslsigncode.c +++ b/osslsigncode.c @@ -1799,7 +1799,7 @@ static int load_file_lookup(X509_STORE *store, char *certs, int purpose) if (!lookup) return 0; /* FAILED */ if (!X509_load_cert_file(lookup, certs, X509_FILETYPE_PEM)) { - fprintf(stderr, "Error: no certificate found in %s\n", certs); + fprintf(stderr, "\nError: no certificate found\n"); return 0; /* FAILED */ } param = X509_STORE_get0_param(store); @@ -2092,10 +2092,11 @@ static int verify_timestamp(PKCS7 *p7, PKCS7 *tmstamp_p7, GLOBAL_OPTIONS *option PKCS7_SIGNER_INFO *si; int ret = 1, verok = 0; - printf("TSA's certificates file: %s\n", options->untrusted); store = X509_STORE_new(); - if (!load_file_lookup(store, options->untrusted, X509_PURPOSE_TIMESTAMP_SIGN)) { - printf("\nUse the \"-untrusted\" option to add the CA cert bundle to verify timestamp server.\n"); + if (load_file_lookup(store, options->untrusted, X509_PURPOSE_TIMESTAMP_SIGN)) + printf("TSA's certificates file: %s\n", options->untrusted); + else { + printf("Use the \"-untrusted\" option to add the CA cert bundle to verify timestamp server.\n"); ret = 0; /* FAILED */ } if (ret) @@ -4725,7 +4726,7 @@ static cmd_type_t get_command(char **argv) return CMD_SIGN; } -static void main_configure(int argc, char **argv, cmd_type_t *cmd, GLOBAL_OPTIONS *options) +static int main_configure(int argc, char **argv, cmd_type_t *cmd, GLOBAL_OPTIONS *options) { int i; char *failarg = NULL; @@ -4743,7 +4744,7 @@ static void main_configure(int argc, char **argv, cmd_type_t *cmd, GLOBAL_OPTION options->signing_time = INVALID_TIME; options->jp = -1; - if ((*cmd == CMD_VERIFY || *cmd == CMD_ATTACH)) { + if (*cmd == CMD_VERIFY || *cmd == CMD_ATTACH) { options->cafile = get_cafile(); options->untrusted = get_cafile(); } @@ -4913,6 +4914,13 @@ static void main_configure(int argc, char **argv, cmd_type_t *cmd, GLOBAL_OPTION fprintf(stderr, "Unknown option: %s\n", failarg); usage(argv0, "all"); } + + if ((*cmd == CMD_VERIFY || *cmd == CMD_ATTACH) && access(options->cafile, R_OK)) { + printf("Use the \"-CAfile\" option to add one or more trusted CA certificates to verify the signature.\n"); + return 0; /* FAILED */ + } + + return 1; } int main(int argc, char **argv) @@ -4943,7 +4951,8 @@ int main(int argc, char **argv) DO_EXIT_0("Failed to add objects\n"); /* commands and options initialization */ - main_configure(argc, argv, &cmd, &options); + if (!main_configure(argc, argv, &cmd, &options)) + goto err_cleanup; if (!read_password(&options)) goto err_cleanup; /* read key and certificates */ From 82afda3ef97fd0e358612c0317e0f26d10ca9774 Mon Sep 17 00:00:00 2001 From: olszomal Date: Wed, 22 Apr 2020 10:26:32 +0200 Subject: [PATCH 3/6] msi support for Windows --- osslsigncode.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/osslsigncode.c b/osslsigncode.c index 007db5f..f58b08c 100644 --- a/osslsigncode.c +++ b/osslsigncode.c @@ -2688,7 +2688,7 @@ out: * msi_extract_signature_to_file extracts the MSI DigitalSignaure from infile * to a file at the path given by outfile. */ -static int msi_extract_signature_to_file(GsfInfile *infile, char *outfile) +static int msi_extract_signature_to_file(GsfInfile *infile, GLOBAL_OPTIONS *options) { char hexbuf[EVP_MAX_MD_SIZE*2+1]; GsfInput *sig = NULL; @@ -2717,14 +2717,14 @@ static int msi_extract_signature_to_file(GsfInfile *infile, char *outfile) #ifdef WIN32 if (!access(options->outfile, R_OK)) { /* outdata file exists */ - printf("Failed to create file: %s\n", outfile); + printf("Failed to create file: %s\n", options->outfile); ret = 1; goto out; } #endif - outdata = BIO_new_file(outfile, FILE_CREATE_MODE); + outdata = BIO_new_file(options->outfile, FILE_CREATE_MODE); if (outdata == NULL) { - printf("Failed to create file: %s\n", outfile); + printf("Failed to create file: %s\n", options->outfile); ret = 1; goto out; } @@ -2807,7 +2807,7 @@ static int msi_extract_file(GsfInfile *ole, GLOBAL_OPTIONS *options) #ifdef WIN32 if (!access(options->outfile, R_OK)) { /* outdata file exists */ - fprintf(stderr, "Failed to create file: %s\n", outfile); + fprintf(stderr, "Failed to create file: %s\n", options->outfile); return 1; /* FAILED */ } #endif @@ -2819,7 +2819,7 @@ static int msi_extract_file(GsfInfile *ole, GLOBAL_OPTIONS *options) ret = !PEM_write_bio_PKCS7(outdata, sig); BIO_free_all(outdata); } else - ret = msi_extract_signature_to_file(ole, options->outfile); + ret = msi_extract_signature_to_file(ole, options); return ret; } From 56a1413cb54f8c372492319ca346696831ef6b38 Mon Sep 17 00:00:00 2001 From: olszomal Date: Tue, 5 May 2020 14:48:48 +0200 Subject: [PATCH 4/6] how to use PKCS11 token --- README.md | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/README.md b/README.md index a0d6bd7..7966e7e 100644 --- a/README.md +++ b/README.md @@ -93,6 +93,18 @@ To sign a CAB file containing java class files: ``` Only the 'low' parameter is currently supported. +If you want to use PKCS11 token, you should indicate PKCS11 engine and module. +An example of using osslsigncode with SoftHSM: +``` + osslsigncode sign \ + -pkcs11engine /usr/lib64/engines-1.1/pkcs11.so \ + -pkcs11module /usr/lib64/pkcs11/libsofthsm2.so \ + -certs \ + -key 'pkcs11:token=softhsm-token;object=key' \ + -in yourapp.exe -out yourapp-signed.exe +``` +osslsigncode currently does not support reading certificates from engines. + You can check that the signed file is correct by right-clicking on it in Windows and choose Properties --> Digital Signatures, and then choose the signature from the list, and click on From 8d78e075282a4d8844a2739639578f4a5c049f2b Mon Sep 17 00:00:00 2001 From: olszomal Date: Tue, 5 May 2020 14:58:49 +0200 Subject: [PATCH 5/6] Windows install notes --- INSTALL.W32.md | 101 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 101 insertions(+) create mode 100644 INSTALL.W32.md diff --git a/INSTALL.W32.md b/INSTALL.W32.md new file mode 100644 index 0000000..172d5b7 --- /dev/null +++ b/INSTALL.W32.md @@ -0,0 +1,101 @@ +# osslsigncode Windows install notes + +### Building osslsigncode source with MSYS2 MinGW 64-bit and MSYS2 packages: + +1) Download and install MSYS2 from https://msys2.github.io/ and follow installation instructions. + Once up and running install even mingw-w64-x86_64-gcc, mingw-w64-x86_64-curl, mingw-w64-x86_64-libgsf. +``` + pacman -S mingw-w64-x86_64-gcc mingw-w64-x86_64-curl mingw-w64-x86_64-libgsf +``` + mingw-w64-x86_64-openssl and mingw-w64-x86_64-zlib packages are installed with dependencies. + +2) Run "MSYS2 MinGW 64-bit" and build 64-bit Windows executables. +``` + cd osslsigncode-folder + x86_64-w64-mingw32-gcc osslsigncode.c -o osslsigncode.exe \ + -lcrypto -lssl -lcurl -lgsf-1 -lgobject-2.0 -lglib-2.0 -lxml2 \ + -I 'C:/msys64/mingw64/include/libgsf-1' \ + -I 'C:/msys64/mingw64/include/glib-2.0' \ + -I 'C:/msys64/mingw64/lib/glib-2.0/include' \ + -D 'PACKAGE_STRING="osslsigncode 2.1.0"' \ + -D 'PACKAGE_BUGREPORT="Michal.Trojnara@stunnel.org"' \ + -D ENABLE_CURL \ + -D WITH_GSF +``` + +3) Run "Command prompt" and include "c:\msys64\mingw64\bin" folder as part of the path. +``` + path=%path%;c:\msys64\mingw64\bin + cd osslsigncode-folder + + osslsigncode.exe -v + osslsigncode 2.1.0, using: + OpenSSL 1.1.1g 21 Apr 2020 + libcurl/7.70.0 OpenSSL/1.1.1g (Schannel) zlib/1.2.11 brotli/1.0.7 libidn2/2.3.0 + libpsl/0.21.0 (+libidn2/2.3.0) libssh2/1.9.0 nghttp2/1.40.0 libgsf 1.14.46 +``` + + +### Building OpenSSL, Curl and osslsigncode sources with MSYS2 MinGW 64-bit: + +1) Download and install MSYS2 from https://msys2.github.io/ and follow installation instructions. + Once up and running install even: perl make autoconf automake libtool pkg-config. +``` + pacman -S perl make autoconf automake libtool pkg-config +``` + Make sure there are no curl, brotli, libpsl, libidn2 and nghttp2 packages installed: +``` + pacman -R mingw-w64-x86_64-curl \ + mingw-w64-x86_64-brotli \ + mingw-w64-x86_64-libpsl \ + mingw-w64-x86_64-libidn2 \ + mingw-w64-x86_64-nghttp2 +``` + + Run "MSYS2 MinGW 64-bit" in the administrator mode. + +2) Build and install OpenSSL. +``` + cd openssl-(version) + ./config --prefix='C:/OpenSSL' --openssldir='C:/OpenSSL' + make && make install +``` + 3) Build and install curl. +``` + cd curl-(version) + ./buildconf + ./configure --prefix='C:/curl' --with-ssl='C:/OpenSSL' \ + --disable-ftp --disable-tftp --disable-file --disable-dict \ + --disable-telnet --disable-imap --disable-smb --disable-smtp \ + --disable-gopher --disable-pop --disable-pop3 --disable-rtsp \ + --disable-ldap --disable-ldaps --disable-unix-sockets --disable-pthreads + make && make install +``` + +3) Build 64-bit Windows executables. +``` + cd osslsigncode-folder + x86_64-w64-mingw32-gcc osslsigncode.c -o osslsigncode.exe \ + -L 'C:/OpenSSL/lib/' -lcrypto -lssl \ + -I 'C:/OpenSSL/include/' \ + -L 'C:/curl/lib' -lcurl \ + -I 'C:/curl/include' \ + -D 'PACKAGE_STRING="osslsigncode 2.1.0"' \ + -D 'PACKAGE_BUGREPORT="Michal.Trojnara@stunnel.org"' \ + -D ENABLE_CURL +``` + +4) Run "Command prompt" and copy required libraries. +``` + cd osslsigncode-folder + copy C:\OpenSSL\bin\libssl-1_1-x64.dll + copy C:\OpenSSL\bin\libcrypto-1_1-x64.dll + copy C:\curl\bin\libcurl-4.dll + copy C:\msys64\mingw64\bin\zlib1.dll + + osslsigncode.exe -v + osslsigncode 2.1.0, using: + OpenSSL 1.1.1g 21 Apr 2020 + libcurl/7.70.0 OpenSSL/1.1.1g zlib/1.2.11 + no libgsf available +``` From 6cb3ae863ec3d5306d56caf2ad772b423d37a5a7 Mon Sep 17 00:00:00 2001 From: olszomal Date: Fri, 8 May 2020 14:26:27 +0200 Subject: [PATCH 6/6] print timestamp error --- osslsigncode.c | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/osslsigncode.c b/osslsigncode.c index f58b08c..d92c841 100644 --- a/osslsigncode.c +++ b/osslsigncode.c @@ -1948,8 +1948,11 @@ static int pkcs7_print_attributes(PKCS7_SIGNED *p7_signed, PKCS7 **tmstamp_p7, if (value == NULL) return 0; /* FAILED */ *tmstamp_p7 = find_countersignature(p7_signed, value->data, value->length, timestamp_time); - if (tmstamp_p7 == NULL) + if (*tmstamp_p7 == NULL) { + printf("Error: Authenticode Timestamp could not be decoded correctly\n"); + ERR_print_errors_fp(stdout); return 0; /* FAILED */ + } } else if (!strcmp(object_txt, SPC_RFC3161_OBJID)) { /* 1.3.6.1.4.1.311.3.3.1 */ printf("\nRFC3161 Timestamp\nPolicy OID: %s\n", object_txt); @@ -1957,8 +1960,11 @@ static int pkcs7_print_attributes(PKCS7_SIGNED *p7_signed, PKCS7 **tmstamp_p7, if (value == NULL) return 0; /* FAILED */ *tmstamp_p7 = find_rfc3161(value->data, value->length, timestamp_time); - if (tmstamp_p7 == NULL) + if (*tmstamp_p7 == NULL) { + printf("Error: RFC3161 Timestamp could not be decoded correctly\n"); + ERR_print_errors_fp(stdout); return 0; /* FAILED */ + } } else if (!strcmp(object_txt, SPC_UNAUTHENTICATED_DATA_BLOB_OBJID)) { /* 1.3.6.1.4.1.42921.1.2.1 */ printf("\nUnauthenticated Data Blob\nPolicy OID: %s\n", object_txt); @@ -2188,11 +2194,11 @@ static int verify_pkcs7(PKCS7 *p7, GLOBAL_OPTIONS *options) int ret = 0, leafok = 0; if (!find_signer(p7, options->leafhash, &leafok)) - printf("Find signers error"); /* FAILED */ + printf("Find signers error\n"); if (!print_certs(p7)) - printf("Print certs error"); /* FAILED */ + printf("Print certs error\n"); if (!pkcs7_print_attributes(p7->d.sign, &tmstamp_p7, ×tamp_time, options->verbose)) - ret = 1; /* FAILED */ + printf("Print attributes error\n"); if (options->leafhash != NULL) { printf("Leaf hash match: %s\n", leafok ? "ok" : "failed"); if (!leafok) @@ -2202,7 +2208,7 @@ static int verify_pkcs7(PKCS7 *p7, GLOBAL_OPTIONS *options) if (options->crlfile) printf("CRLfile: %s\n", options->crlfile); if (!tmstamp_p7) - printf("\nFile is not timestamped\n"); + printf("\nTimestamp is not available\n"); else if (!verify_timestamp(p7, tmstamp_p7, options)) timestamp_time = NULL;