From f34e33ed2b89d788309b96ef04b256ad1126258e Mon Sep 17 00:00:00 2001 From: Armin Novak Date: Wed, 20 Nov 2019 08:32:19 +0100 Subject: [PATCH] Cleaned up code for makecert. --- winpr/tools/makecert/makecert.c | 605 ++++++++++++++++------------------------ 1 file changed, 244 insertions(+), 361 deletions(-) diff --git a/winpr/tools/makecert/makecert.c b/winpr/tools/makecert/makecert.c index 984e644..304e47e 100644 --- a/winpr/tools/makecert/makecert.c +++ b/winpr/tools/makecert/makecert.c @@ -21,6 +21,7 @@ #include #include +#include #include #include #include @@ -66,150 +67,58 @@ struct _MAKECERT_CONTEXT int duration_months; }; -static COMMAND_LINE_ARGUMENT_A args[] = { - /* Custom Options */ - - { "rdp", COMMAND_LINE_VALUE_FLAG, NULL, NULL, NULL, -1, NULL, - "Unsupported - Generate certificate with required options for RDP usage." }, - { "silent", COMMAND_LINE_VALUE_FLAG, NULL, NULL, NULL, -1, NULL, - "Silently generate certificate without verbose output." }, - { "live", COMMAND_LINE_VALUE_FLAG, NULL, NULL, NULL, -1, NULL, - "Generate certificate live in memory when used as a library." }, - { "format", COMMAND_LINE_VALUE_REQUIRED, "", NULL, NULL, -1, NULL, - "Specify certificate file format" }, - { "path", COMMAND_LINE_VALUE_REQUIRED, "", NULL, NULL, -1, NULL, - "Specify certificate file output path" }, - { "p", COMMAND_LINE_VALUE_REQUIRED, "", NULL, NULL, -1, NULL, - "Specify certificate export password" }, - - /* Basic Options */ - - { "n", COMMAND_LINE_VALUE_REQUIRED, "", NULL, NULL, -1, NULL, - "Specifies the subject's certificate name. This name must conform to the X.500 standard. " - "The simplest method is to specify the name in double quotes, preceded by CN=; for example, " - "-n \"CN=myName\"." }, - { "pe", COMMAND_LINE_VALUE_FLAG, NULL, NULL, NULL, -1, NULL, - "Unsupported - Marks the generated private key as exportable. This allows the private key to " - "be included in the certificate." }, - { "sk", COMMAND_LINE_VALUE_REQUIRED, "", NULL, NULL, -1, NULL, - "Unsupported - Specifies the subject's key container location, which contains the private " - "key. " - "If a key container does not exist, it will be created." }, - { "sr", COMMAND_LINE_VALUE_REQUIRED, "", NULL, NULL, -1, NULL, - "Unsupported - Specifies the subject's certificate store location. location can be either " - "currentuser (the default) or localmachine." }, - { "ss", COMMAND_LINE_VALUE_REQUIRED, "", NULL, NULL, -1, NULL, - "Unsupported - Specifies the subject's certificate store name that stores the output " - "certificate." }, - { "#", COMMAND_LINE_VALUE_REQUIRED, "", NULL, NULL, -1, NULL, - "Specifies a serial number from 1 to 2,147,483,647. The default is a unique value generated " - "by Makecert.exe." }, - { "$", COMMAND_LINE_VALUE_REQUIRED, "", NULL, NULL, -1, NULL, - "Unsupported - Specifies the signing authority of the certificate, which must be set to " - "either commercial " - "(for certificates used by commercial software publishers) or individual (for certificates " - "used by individual software publishers)." }, - - /* Extended Options */ - - { "a", COMMAND_LINE_VALUE_REQUIRED, "", NULL, NULL, -1, NULL, - "Specifies the signature algorithm. algorithm must be md5, sha1, sha256 (the default), " - "sha384, or sha512." }, - { "b", COMMAND_LINE_VALUE_REQUIRED, "", NULL, NULL, -1, NULL, - "Unsupported - Specifies the start of the validity period. Defaults to the current date." }, - { "crl", COMMAND_LINE_VALUE_FLAG, NULL, NULL, NULL, -1, NULL, - "Unsupported - Generates a certificate relocation list (CRL) instead of a certificate." }, - { "cy", COMMAND_LINE_VALUE_REQUIRED, "", NULL, NULL, -1, NULL, - "Unsupported - Specifies the certificate type. Valid values are end for end-entity and " - "authority for certification authority." }, - { "e", COMMAND_LINE_VALUE_REQUIRED, "", NULL, NULL, -1, NULL, - "Unsupported - Specifies the end of the validity period. Defaults to 12/31/2039 11:59:59 " - "GMT." }, - { "eku", COMMAND_LINE_VALUE_REQUIRED, "", NULL, NULL, -1, NULL, - "Unsupported - Inserts a list of comma-separated, enhanced key usage object identifiers " - "(OIDs) into the certificate." }, - { "h", COMMAND_LINE_VALUE_REQUIRED, "", NULL, NULL, -1, NULL, - "Unsupported - Specifies the maximum height of the tree below this certificate." }, - { "ic", COMMAND_LINE_VALUE_REQUIRED, "", NULL, NULL, -1, NULL, - "Unsupported - Specifies the issuer's certificate file." }, - { "ik", COMMAND_LINE_VALUE_REQUIRED, "", NULL, NULL, -1, NULL, - "Unsupported - Specifies the issuer's key container name." }, - { "iky", COMMAND_LINE_VALUE_REQUIRED, "", NULL, NULL, -1, NULL, - "Unsupported - Specifies the issuer's key type, which must be one of the following: " - "signature (which indicates that the key is used for a digital signature), " - "exchange (which indicates that the key is used for key encryption and key exchange), " - "or an integer that represents a provider type. " - "By default, you can pass 1 for an exchange key or 2 for a signature key." }, - { "in", COMMAND_LINE_VALUE_REQUIRED, "", NULL, NULL, -1, NULL, - "Unsupported - Specifies the issuer's certificate common name." }, - { "ip", COMMAND_LINE_VALUE_REQUIRED, "", NULL, NULL, -1, NULL, - "Unsupported - Specifies the issuer's CryptoAPI provider name. For information about the " - "CryptoAPI provider name, see the –sp option." }, - { "ir", COMMAND_LINE_VALUE_REQUIRED, "", NULL, NULL, -1, NULL, - "Unsupported - Specifies the location of the issuer's certificate store. location can be " - "either currentuser (the default) or localmachine." }, - { "is", COMMAND_LINE_VALUE_REQUIRED, "", NULL, NULL, -1, NULL, - "Unsupported - Specifies the issuer's certificate store name." }, - { "iv", COMMAND_LINE_VALUE_REQUIRED, "", NULL, NULL, -1, NULL, - "Unsupported - Specifies the issuer's .pvk private key file." }, - { "iy", COMMAND_LINE_VALUE_REQUIRED, "", NULL, NULL, -1, NULL, - "Unsupported - Specifies the issuer's CryptoAPI provider type. For information about the " - "CryptoAPI provider type, see the –sy option." }, - { "l", COMMAND_LINE_VALUE_REQUIRED, "", NULL, NULL, -1, NULL, - "Unsupported - Links to policy information (for example, to a URL)." }, - { "len", COMMAND_LINE_VALUE_REQUIRED, "", NULL, NULL, -1, NULL, - "Specifies the generated key length, in bits." }, - { "m", COMMAND_LINE_VALUE_REQUIRED, "", NULL, NULL, -1, NULL, - "Specifies the duration, in months, of the certificate validity period." }, - { "y", COMMAND_LINE_VALUE_REQUIRED, "", NULL, NULL, -1, NULL, - "Specifies the duration, in years, of the certificate validity period." }, - { "nscp", COMMAND_LINE_VALUE_FLAG, NULL, NULL, NULL, -1, NULL, - "Unsupported - Includes the Netscape client-authorization extension." }, - { "r", COMMAND_LINE_VALUE_FLAG, NULL, NULL, NULL, -1, NULL, - "Unsupported - Creates a self-signed certificate." }, - { "sc", COMMAND_LINE_VALUE_REQUIRED, "", NULL, NULL, -1, NULL, - "Unsupported - Specifies the subject's certificate file." }, - { "sky", COMMAND_LINE_VALUE_REQUIRED, "", NULL, NULL, -1, NULL, - "Unsupported - Specifies the subject's key type, which must be one of the following: " - "signature (which indicates that the key is used for a digital signature), " - "exchange (which indicates that the key is used for key encryption and key exchange), " - "or an integer that represents a provider type. " - "By default, you can pass 1 for an exchange key or 2 for a signature key." }, - { "sp", COMMAND_LINE_VALUE_REQUIRED, "", NULL, NULL, -1, NULL, - "Unsupported - Specifies the subject's CryptoAPI provider name, which must be defined in the " - "registry subkeys of " - "HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Cryptography\\Defaults\\Provider. If both –sp and " - "–sy are present, " - "the type of the CryptoAPI provider must correspond to the Type value of the provider's " - "subkey." }, - { "sv", COMMAND_LINE_VALUE_REQUIRED, "", NULL, NULL, -1, NULL, - "Unsupported - Specifies the subject's .pvk private key file. The file is created if none " - "exists." }, - { "sy", COMMAND_LINE_VALUE_REQUIRED, "", NULL, NULL, -1, NULL, - "Unsupported - Specifies the subject's CryptoAPI provider type, which must be defined in the " - "registry subkeys of " - "HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Cryptography\\Defaults\\Provider Types. If both " - "–sy and –sp are present, " - "the name of the CryptoAPI provider must correspond to the Name value of the provider type " - "subkey." }, - { "tbs", COMMAND_LINE_VALUE_REQUIRED, "", NULL, NULL, -1, NULL, - "Unsupported - Specifies the certificate or CRL file to be signed." }, - - /* Help */ - - { "?", COMMAND_LINE_VALUE_FLAG | COMMAND_LINE_PRINT_HELP, NULL, NULL, NULL, -1, "help", - "print help" }, - { "!", COMMAND_LINE_VALUE_FLAG | COMMAND_LINE_PRINT_HELP, NULL, NULL, NULL, -1, "help-ext", - "print extended help" }, - { NULL, 0, NULL, NULL, NULL, -1, NULL, NULL } -}; +static char* makecert_read_str(BIO* bio, size_t* pOffset) +{ + int status = -1; + size_t offset = 0; + size_t length = 0; + char* x509_str = NULL; + + while (offset >= length) + { + size_t new_len; + char* new_str; + new_len = length * 2; + if (new_len == 0) + new_len = 2048; + new_str = (char*)realloc(x509_str, new_len); + + if (!new_str || (new_len > INT_MAX)) + { + status = -1; + break; + } + + length = new_len; + x509_str = new_str; + status = BIO_read(bio, &x509_str[offset], (int)length - 1); -static int makecert_print_command_line_help(int argc, char** argv) + if (status < 0) + break; + + offset += (size_t)status; + } + + if (status < 0) + { + free(x509_str); + if (pOffset) + *pOffset = 0; + return NULL; + } + + x509_str[offset] = '\0'; + if (pOffset) + *pOffset = offset + 1; + return x509_str; +} + +static int makecert_print_command_line_help(COMMAND_LINE_ARGUMENT_A* args, int argc, char** argv) { char* str; COMMAND_LINE_ARGUMENT_A* arg; - if (!argv) + if (!argv || (argc < 1)) return -1; printf("Usage: %s [options] [output file]\n", argv[0]); @@ -262,8 +171,7 @@ static int x509_add_ext(X509* cert, int nid, char* value) if (!cert || !value) return 0; - X509V3_set_ctx_nodb(&ctx); - X509V3_set_ctx(&ctx, cert, cert, NULL, NULL, 0); + X509V3_set_ctx_nodb(&ctx) X509V3_set_ctx(&ctx, cert, cert, NULL, NULL, 0); ext = X509V3_EXT_conf_nid(NULL, &ctx, nid, value); if (!ext) @@ -275,7 +183,7 @@ static int x509_add_ext(X509* cert, int nid, char* value) } #endif -static char* x509_name_parse(char* name, char* txt, int* length) +static char* x509_name_parse(char* name, char* txt, size_t* length) { char* p; char* entry; @@ -294,7 +202,7 @@ static char* x509_name_parse(char* name, char* txt, int* length) if (!p) *length = strlen(entry); else - *length = p - entry; + *length = (size_t)(p - entry); return entry; } @@ -359,7 +267,8 @@ static int command_line_pre_filter(MAKECERT_CONTEXT* context, int index, int arg return 0; } -static int makecert_context_parse_arguments(MAKECERT_CONTEXT* context, int argc, char** argv) +static int makecert_context_parse_arguments(MAKECERT_CONTEXT* context, + COMMAND_LINE_ARGUMENT_A* args, int argc, char** argv) { int status; DWORD flags; @@ -380,7 +289,7 @@ static int makecert_context_parse_arguments(MAKECERT_CONTEXT* context, int argc, if (status & COMMAND_LINE_STATUS_PRINT_HELP) { - makecert_print_command_line_help(argc, argv); + makecert_print_command_line_help(args, argc, argv); return 0; } @@ -470,7 +379,7 @@ static int makecert_context_parse_arguments(MAKECERT_CONTEXT* context, int argc, if ((errno != 0) || (val < 0) || (val > INT32_MAX)) return -1; - context->duration_years = strtol(arg->Value, NULL, 0); + context->duration_years = (int)val; } CommandLineSwitchCase(arg, "m") { @@ -484,7 +393,7 @@ static int makecert_context_parse_arguments(MAKECERT_CONTEXT* context, int argc, if ((errno != 0) || (val < 1) || (val > 12)) return -1; - context->duration_months = val; + context->duration_months = (int)val; } CommandLineSwitchDefault(arg) { @@ -517,14 +426,14 @@ int makecert_context_output_certificate_file(MAKECERT_CONTEXT* context, char* pa #ifdef WITH_OPENSSL FILE* fp = NULL; int status; - int length; - int offset; + size_t length; + size_t offset; char* filename = NULL; char* fullpath = NULL; char* ext; int ret = -1; BIO* bio = NULL; - BYTE* x509_str = NULL; + char* x509_str = NULL; if (!context || !path) return -1; @@ -606,46 +515,11 @@ int makecert_context_output_certificate_file(MAKECERT_CONTEXT* context, char* pa if (status != 1) goto out_fail; - offset = 0; - length = 2048; - x509_str = (BYTE*)malloc(length); + x509_str = makecert_read_str(bio, &offset); if (!x509_str) goto out_fail; - status = BIO_read(bio, x509_str, length); - - if (status < 0) - goto out_fail; - - offset += status; - - while (offset >= length) - { - int new_len; - BYTE* new_str; - new_len = length * 2; - new_str = (BYTE*)realloc(x509_str, new_len); - - if (!new_str) - { - status = -1; - break; - } - - length = new_len; - x509_str = new_str; - status = BIO_read(bio, &x509_str[offset], length); - - if (status < 0) - break; - - offset += status; - } - - if (status < 0) - goto out_fail; - length = offset; if (fwrite((void*)x509_str, length, 1, fp) != 1) @@ -661,49 +535,14 @@ int makecert_context_output_certificate_file(MAKECERT_CONTEXT* context, char* pa if (!PEM_write_bio_X509(bio, context->x509)) goto out_fail; - offset = 0; - length = 2048; - x509_str = (BYTE*)malloc(length); + x509_str = makecert_read_str(bio, &offset); if (!x509_str) goto out_fail; - status = BIO_read(bio, x509_str, length); - - if (status < 0) - goto out_fail; - - offset += status; - - while (offset >= length) - { - int new_len; - BYTE* new_str; - new_len = length * 2; - new_str = (BYTE*)realloc(x509_str, new_len); - - if (!new_str) - { - status = -1; - break; - } - - length = new_len; - x509_str = new_str; - status = BIO_read(bio, &x509_str[offset], length); - - if (status < 0) - break; - - offset += status; - } - - if (status < 0) - goto out_fail; - length = offset; - if (fwrite((void*)x509_str, length, 1, fp) != 1) + if (fwrite(x509_str, length, 1, fp) != 1) goto out_fail; free(x509_str); @@ -723,43 +562,8 @@ int makecert_context_output_certificate_file(MAKECERT_CONTEXT* context, char* pa if (status < 0) goto out_fail; - offset = 0; - length = 2048; - - if (!(x509_str = (BYTE*)malloc(length))) - goto out_fail; - - status = BIO_read(bio, x509_str, length); - - if (status < 0) - goto out_fail; - - offset += status; - - while (offset >= length) - { - int new_len; - BYTE* new_str; - new_len = length * 2; - new_str = (BYTE*)realloc(x509_str, new_len); - - if (!new_str) - { - status = -1; - break; - } - - length = new_len; - x509_str = new_str; - status = BIO_read(bio, &x509_str[offset], length); - - if (status < 0) - break; - - offset += status; - } - - if (status < 0) + x509_str = makecert_read_str(bio, &offset); + if (x509_str) goto out_fail; length = offset; @@ -790,14 +594,13 @@ int makecert_context_output_private_key_file(MAKECERT_CONTEXT* context, char* pa { #ifdef WITH_OPENSSL FILE* fp = NULL; - int status; - int length; - int offset; + size_t length; + size_t offset; char* filename = NULL; char* fullpath = NULL; int ret = -1; BIO* bio = NULL; - BYTE* x509_str = NULL; + char* x509_str = NULL; if (!context->crtFormat) return 1; @@ -842,46 +645,11 @@ int makecert_context_output_private_key_file(MAKECERT_CONTEXT* context, char* pa if (!PEM_write_bio_PrivateKey(bio, context->pkey, NULL, NULL, 0, NULL, NULL)) goto out_fail; - offset = 0; - length = 2048; - x509_str = (BYTE*)malloc(length); + x509_str = makecert_read_str(bio, &offset); if (!x509_str) goto out_fail; - status = BIO_read(bio, x509_str, length); - - if (status < 0) - goto out_fail; - - offset += status; - - while (offset >= length) - { - int new_len; - BYTE* new_str; - new_len = length * 2; - new_str = (BYTE*)realloc(x509_str, new_len); - - if (!new_str) - { - status = -1; - break; - } - - length = new_len; - x509_str = new_str; - status = BIO_read(bio, &x509_str[offset], length); - - if (status < 0) - break; - - offset += status; - } - - if (status < 0) - goto out_fail; - length = offset; if (fwrite((void*)x509_str, length, 1, fp) != 1) @@ -905,16 +673,166 @@ out_fail: int makecert_context_process(MAKECERT_CONTEXT* context, int argc, char** argv) { + COMMAND_LINE_ARGUMENT_A args[] = { + /* Custom Options */ + + { "rdp", COMMAND_LINE_VALUE_FLAG, NULL, NULL, NULL, -1, NULL, + "Unsupported - Generate certificate with required options for RDP usage." }, + { "silent", COMMAND_LINE_VALUE_FLAG, NULL, NULL, NULL, -1, NULL, + "Silently generate certificate without verbose output." }, + { "live", COMMAND_LINE_VALUE_FLAG, NULL, NULL, NULL, -1, NULL, + "Generate certificate live in memory when used as a library." }, + { "format", COMMAND_LINE_VALUE_REQUIRED, "", NULL, NULL, -1, NULL, + "Specify certificate file format" }, + { "path", COMMAND_LINE_VALUE_REQUIRED, "", NULL, NULL, -1, NULL, + "Specify certificate file output path" }, + { "p", COMMAND_LINE_VALUE_REQUIRED, "", NULL, NULL, -1, NULL, + "Specify certificate export password" }, + + /* Basic Options */ + + { "n", COMMAND_LINE_VALUE_REQUIRED, "", NULL, NULL, -1, NULL, + "Specifies the subject's certificate name. This name must conform to the X.500 standard. " + "The simplest method is to specify the name in double quotes, preceded by CN=; for " + "example, " + "-n \"CN=myName\"." }, + { "pe", COMMAND_LINE_VALUE_FLAG, NULL, NULL, NULL, -1, NULL, + "Unsupported - Marks the generated private key as exportable. This allows the private " + "key to " + "be included in the certificate." }, + { "sk", COMMAND_LINE_VALUE_REQUIRED, "", NULL, NULL, -1, NULL, + "Unsupported - Specifies the subject's key container location, which contains the " + "private " + "key. " + "If a key container does not exist, it will be created." }, + { "sr", COMMAND_LINE_VALUE_REQUIRED, "", NULL, NULL, -1, NULL, + "Unsupported - Specifies the subject's certificate store location. location can be " + "either " + "currentuser (the default) or localmachine." }, + { "ss", COMMAND_LINE_VALUE_REQUIRED, "", NULL, NULL, -1, NULL, + "Unsupported - Specifies the subject's certificate store name that stores the output " + "certificate." }, + { "#", COMMAND_LINE_VALUE_REQUIRED, "", NULL, NULL, -1, NULL, + "Specifies a serial number from 1 to 2,147,483,647. The default is a unique value " + "generated " + "by Makecert.exe." }, + { "$", COMMAND_LINE_VALUE_REQUIRED, "", NULL, NULL, -1, NULL, + "Unsupported - Specifies the signing authority of the certificate, which must be set to " + "either commercial " + "(for certificates used by commercial software publishers) or individual (for " + "certificates " + "used by individual software publishers)." }, + + /* Extended Options */ + + { "a", COMMAND_LINE_VALUE_REQUIRED, "", NULL, NULL, -1, NULL, + "Specifies the signature algorithm. algorithm must be md5, sha1, sha256 (the default), " + "sha384, or sha512." }, + { "b", COMMAND_LINE_VALUE_REQUIRED, "", NULL, NULL, -1, NULL, + "Unsupported - Specifies the start of the validity period. Defaults to the current " + "date." }, + { "crl", COMMAND_LINE_VALUE_FLAG, NULL, NULL, NULL, -1, NULL, + "Unsupported - Generates a certificate relocation list (CRL) instead of a certificate." }, + { "cy", COMMAND_LINE_VALUE_REQUIRED, "", NULL, NULL, -1, NULL, + "Unsupported - Specifies the certificate type. Valid values are end for end-entity and " + "authority for certification authority." }, + { "e", COMMAND_LINE_VALUE_REQUIRED, "", NULL, NULL, -1, NULL, + "Unsupported - Specifies the end of the validity period. Defaults to 12/31/2039 11:59:59 " + "GMT." }, + { "eku", COMMAND_LINE_VALUE_REQUIRED, "", NULL, NULL, -1, NULL, + "Unsupported - Inserts a list of comma-separated, enhanced key usage object identifiers " + "(OIDs) into the certificate." }, + { "h", COMMAND_LINE_VALUE_REQUIRED, "", NULL, NULL, -1, NULL, + "Unsupported - Specifies the maximum height of the tree below this certificate." }, + { "ic", COMMAND_LINE_VALUE_REQUIRED, "", NULL, NULL, -1, NULL, + "Unsupported - Specifies the issuer's certificate file." }, + { "ik", COMMAND_LINE_VALUE_REQUIRED, "", NULL, NULL, -1, NULL, + "Unsupported - Specifies the issuer's key container name." }, + { "iky", COMMAND_LINE_VALUE_REQUIRED, "", NULL, NULL, -1, NULL, + "Unsupported - Specifies the issuer's key type, which must be one of the following: " + "signature (which indicates that the key is used for a digital signature), " + "exchange (which indicates that the key is used for key encryption and key exchange), " + "or an integer that represents a provider type. " + "By default, you can pass 1 for an exchange key or 2 for a signature key." }, + { "in", COMMAND_LINE_VALUE_REQUIRED, "", NULL, NULL, -1, NULL, + "Unsupported - Specifies the issuer's certificate common name." }, + { "ip", COMMAND_LINE_VALUE_REQUIRED, "", NULL, NULL, -1, NULL, + "Unsupported - Specifies the issuer's CryptoAPI provider name. For information about the " + "CryptoAPI provider name, see the –sp option." }, + { "ir", COMMAND_LINE_VALUE_REQUIRED, "", NULL, NULL, -1, NULL, + "Unsupported - Specifies the location of the issuer's certificate store. location can be " + "either currentuser (the default) or localmachine." }, + { "is", COMMAND_LINE_VALUE_REQUIRED, "", NULL, NULL, -1, NULL, + "Unsupported - Specifies the issuer's certificate store name." }, + { "iv", COMMAND_LINE_VALUE_REQUIRED, "", NULL, NULL, -1, NULL, + "Unsupported - Specifies the issuer's .pvk private key file." }, + { "iy", COMMAND_LINE_VALUE_REQUIRED, "", NULL, NULL, -1, NULL, + "Unsupported - Specifies the issuer's CryptoAPI provider type. For information about the " + "CryptoAPI provider type, see the –sy option." }, + { "l", COMMAND_LINE_VALUE_REQUIRED, "", NULL, NULL, -1, NULL, + "Unsupported - Links to policy information (for example, to a URL)." }, + { "len", COMMAND_LINE_VALUE_REQUIRED, "", NULL, NULL, -1, NULL, + "Specifies the generated key length, in bits." }, + { "m", COMMAND_LINE_VALUE_REQUIRED, "", NULL, NULL, -1, NULL, + "Specifies the duration, in months, of the certificate validity period." }, + { "y", COMMAND_LINE_VALUE_REQUIRED, "", NULL, NULL, -1, NULL, + "Specifies the duration, in years, of the certificate validity period." }, + { "nscp", COMMAND_LINE_VALUE_FLAG, NULL, NULL, NULL, -1, NULL, + "Unsupported - Includes the Netscape client-authorization extension." }, + { "r", COMMAND_LINE_VALUE_FLAG, NULL, NULL, NULL, -1, NULL, + "Unsupported - Creates a self-signed certificate." }, + { "sc", COMMAND_LINE_VALUE_REQUIRED, "", NULL, NULL, -1, NULL, + "Unsupported - Specifies the subject's certificate file." }, + { "sky", COMMAND_LINE_VALUE_REQUIRED, "", NULL, NULL, -1, NULL, + "Unsupported - Specifies the subject's key type, which must be one of the following: " + "signature (which indicates that the key is used for a digital signature), " + "exchange (which indicates that the key is used for key encryption and key exchange), " + "or an integer that represents a provider type. " + "By default, you can pass 1 for an exchange key or 2 for a signature key." }, + { "sp", COMMAND_LINE_VALUE_REQUIRED, "", NULL, NULL, -1, NULL, + "Unsupported - Specifies the subject's CryptoAPI provider name, which must be defined in " + "the " + "registry subkeys of " + "HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Cryptography\\Defaults\\Provider. If both –sp " + "and " + "–sy are present, " + "the type of the CryptoAPI provider must correspond to the Type value of the provider's " + "subkey." }, + { "sv", COMMAND_LINE_VALUE_REQUIRED, "", NULL, NULL, -1, NULL, + "Unsupported - Specifies the subject's .pvk private key file. The file is created if " + "none " + "exists." }, + { "sy", COMMAND_LINE_VALUE_REQUIRED, "", NULL, NULL, -1, NULL, + "Unsupported - Specifies the subject's CryptoAPI provider type, which must be defined in " + "the " + "registry subkeys of " + "HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Cryptography\\Defaults\\Provider Types. If " + "both " + "–sy and –sp are present, " + "the name of the CryptoAPI provider must correspond to the Name value of the provider " + "type " + "subkey." }, + { "tbs", COMMAND_LINE_VALUE_REQUIRED, "", NULL, NULL, -1, NULL, + "Unsupported - Specifies the certificate or CRL file to be signed." }, + + /* Help */ + + { "?", COMMAND_LINE_VALUE_FLAG | COMMAND_LINE_PRINT_HELP, NULL, NULL, NULL, -1, "help", + "print help" }, + { "!", COMMAND_LINE_VALUE_FLAG | COMMAND_LINE_PRINT_HELP, NULL, NULL, NULL, -1, "help-ext", + "print extended help" }, + { NULL, 0, NULL, NULL, NULL, -1, NULL, NULL } + }; #ifdef WITH_OPENSSL - int length; + size_t length; char* entry; - unsigned long key_length; + int key_length; long serial = 0; X509_NAME* name = NULL; const EVP_MD* md = NULL; COMMAND_LINE_ARGUMENT_A* arg; int ret; - ret = makecert_context_parse_arguments(context, argc, argv); + ret = makecert_context_parse_arguments(context, args, argc, argv); if (ret < 1) { @@ -961,10 +879,11 @@ int makecert_context_process(MAKECERT_CONTEXT* context, int argc, char** argv) if (arg->Flags & COMMAND_LINE_VALUE_PRESENT) { - key_length = strtoul(arg->Value, NULL, 0); + unsigned long val = strtoul(arg->Value, NULL, 0); - if (errno != 0) + if ((errno != 0) || (val > INT_MAX)) return -1; + key_length = (int)val; } #if (OPENSSL_VERSION_NUMBER < 0x10100000L) || defined(LIBRESSL_VERSION_NUMBER) @@ -1039,43 +958,43 @@ int makecert_context_process(MAKECERT_CONTEXT* context, int argc, char** argv) if (entry) X509_NAME_add_entry_by_txt(name, "C", MBSTRING_UTF8, (const unsigned char*)entry, - length, -1, 0); + (int)length, -1, 0); entry = x509_name_parse(arg->Value, "ST", &length); if (entry) X509_NAME_add_entry_by_txt(name, "ST", MBSTRING_UTF8, (const unsigned char*)entry, - length, -1, 0); + (int)length, -1, 0); entry = x509_name_parse(arg->Value, "L", &length); if (entry) X509_NAME_add_entry_by_txt(name, "L", MBSTRING_UTF8, (const unsigned char*)entry, - length, -1, 0); + (int)length, -1, 0); entry = x509_name_parse(arg->Value, "O", &length); if (entry) X509_NAME_add_entry_by_txt(name, "O", MBSTRING_UTF8, (const unsigned char*)entry, - length, -1, 0); + (int)length, -1, 0); entry = x509_name_parse(arg->Value, "OU", &length); if (entry) X509_NAME_add_entry_by_txt(name, "OU", MBSTRING_UTF8, (const unsigned char*)entry, - length, -1, 0); + (int)length, -1, 0); entry = context->common_name; length = strlen(entry); - X509_NAME_add_entry_by_txt(name, "CN", MBSTRING_UTF8, (const unsigned char*)entry, length, - -1, 0); + X509_NAME_add_entry_by_txt(name, "CN", MBSTRING_UTF8, (const unsigned char*)entry, + (int)length, -1, 0); } else { entry = context->common_name; length = strlen(entry); - X509_NAME_add_entry_by_txt(name, "CN", MBSTRING_UTF8, (const unsigned char*)entry, length, - -1, 0); + X509_NAME_add_entry_by_txt(name, "CN", MBSTRING_UTF8, (const unsigned char*)entry, + (int)length, -1, 0); } X509_set_issuer_name(context->x509, name); @@ -1108,9 +1027,7 @@ int makecert_context_process(MAKECERT_CONTEXT* context, int argc, char** argv) { BIO* bio; int status; - int length; - int offset; - BYTE* x509_str; + char* x509_str; bio = BIO_new(BIO_s_mem()); if (!bio) @@ -1124,54 +1041,13 @@ int makecert_context_process(MAKECERT_CONTEXT* context, int argc, char** argv) return -1; } - offset = 0; - length = 2048; - - if (!(x509_str = (BYTE*)malloc(length + 1))) - { - BIO_free_all(bio); - return -1; - } - - status = BIO_read(bio, x509_str, length); - - if (status < 0) + x509_str = makecert_read_str(bio, NULL); + if (!x509_str) { BIO_free_all(bio); - free(x509_str); return -1; } - offset += status; - - while (offset >= length) - { - int new_len; - BYTE* new_str; - new_len = length * 2; - new_str = (BYTE*)realloc(x509_str, new_len); - - if (!new_str) - { - status = -1; - break; - } - - x509_str = new_str; - status = BIO_read(bio, &x509_str[offset], new_len); - - if (status < 0) - break; - - length = length + new_len; - offset += status; - } - - if (status < 0) - return -1; - - length = offset; - x509_str[length] = '\0'; printf("%s", x509_str); free(x509_str); BIO_free_all(bio); @@ -1183,7 +1059,14 @@ int makecert_context_process(MAKECERT_CONTEXT* context, int argc, char** argv) if (!context->live) { - makecert_context_output_certificate_file(context, context->output_path); + if (!PathFileExistsA(context->output_path)) + { + if (!CreateDirectoryA(context->output_path, NULL)) + return -1; + } + + if (makecert_context_output_certificate_file(context, context->output_path) != 1) + return -1; if (context->crtFormat) { -- 2.7.4