Merge pull request #3901 from akallabeth/openssl_1_1_no_legacy

Fixed OpenSSL 1.1 no legacy compile issues.
This commit is contained in:
Norbert Federa 2017-04-11 15:00:30 +02:00 committed by GitHub
commit 736675aa01
6 changed files with 293 additions and 195 deletions

View File

@ -388,7 +388,14 @@ BOOL x509_verify_certificate(CryptoCert cert, char* certificate_store_path)
if (cert_ctx == NULL)
goto end;
#if OPENSSL_VERSION_NUMBER < 0x10100000L
OpenSSL_add_all_algorithms();
#else
OPENSSL_init_crypto(OPENSSL_INIT_ADD_ALL_CIPHERS \
| OPENSSL_INIT_ADD_ALL_DIGESTS \
| OPENSSL_INIT_LOAD_CONFIG, NULL);
#endif
lookup = X509_STORE_add_lookup(cert_ctx, X509_LOOKUP_file());
if (lookup == NULL)

View File

@ -34,7 +34,7 @@ WINPR_API int makecert_context_set_output_file_name(MAKECERT_CONTEXT* context, c
WINPR_API int makecert_context_output_certificate_file(MAKECERT_CONTEXT* context, char* path);
WINPR_API int makecert_context_output_private_key_file(MAKECERT_CONTEXT* context, char* path);
WINPR_API MAKECERT_CONTEXT* makecert_context_new();
WINPR_API MAKECERT_CONTEXT* makecert_context_new(void);
WINPR_API void makecert_context_free(MAKECERT_CONTEXT* context);
#ifdef __cplusplus

View File

@ -25,6 +25,7 @@
#include <winpr/crypto.h>
#ifdef WITH_OPENSSL
#include <openssl/crypto.h>
#include <openssl/rand.h>
#endif
@ -54,17 +55,5 @@ int winpr_RAND(BYTE* output, size_t len)
int winpr_RAND_pseudo(BYTE* output, size_t len)
{
#if defined(WITH_OPENSSL)
if (RAND_pseudo_bytes(output, len) != 1)
return -1;
#elif defined(WITH_MBEDTLS) && defined(MBEDTLS_HAVEGE_C)
mbedtls_havege_state hs;
mbedtls_havege_init(&hs);
if (mbedtls_havege_random(&hs, output, len) != 0)
return -1;
mbedtls_havege_free(&hs);
#endif
return 0;
return winpr_RAND(output, len);
}

View File

@ -76,7 +76,7 @@ int schannel_openssl_client_init(SCHANNEL_OPENSSL* context)
{
int status;
long options = 0;
context->ctx = SSL_CTX_new(TLSv1_client_method());
context->ctx = SSL_CTX_new(SSLv23_client_method());
if (!context->ctx)
{
@ -198,7 +198,7 @@ int schannel_openssl_server_init(SCHANNEL_OPENSSL* context)
{
int status;
long options = 0;
context->ctx = SSL_CTX_new(TLSv1_server_method());
context->ctx = SSL_CTX_new(SSLv23_server_method());
if (!context->ctx)
{

View File

@ -255,11 +255,20 @@ static BOOL CALLBACK _winpr_openssl_initialize(PINIT_ONCE once, PVOID param, PVO
}
#endif
/* SSL_load_error_strings() is void */
#if (OPENSSL_VERSION_NUMBER < 0x10100000L)
SSL_load_error_strings();
/* SSL_library_init() always returns "1" */
SSL_library_init();
OpenSSL_add_all_digests();
OpenSSL_add_all_ciphers();
#else
if (OPENSSL_init_ssl(OPENSSL_INIT_LOAD_SSL_STRINGS |
OPENSSL_INIT_LOAD_CRYPTO_STRINGS |
OPENSSL_INIT_ADD_ALL_CIPHERS |
OPENSSL_INIT_ADD_ALL_DIGESTS |
OPENSSL_INIT_ENGINE_ALL_BUILTIN, NULL) != 1)
return FALSE;
#endif
g_winpr_openssl_initialized_by_winpr = TRUE;
return TRUE;
}
@ -287,9 +296,11 @@ BOOL winpr_CleanupSSL(DWORD flags)
#ifdef WINPR_OPENSSL_LOCKING_REQUIRED
_winpr_openssl_cleanup_locking();
#endif
#if (OPENSSL_VERSION_NUMBER < 0x10100000L)
CRYPTO_cleanup_all_ex_data();
ERR_free_strings();
EVP_cleanup();
#endif
flags |= WINPR_SSL_CLEANUP_THREAD;
}

View File

@ -24,8 +24,10 @@
#include <winpr/crypto.h>
#ifdef WITH_OPENSSL
#include <openssl/crypto.h>
#include <openssl/conf.h>
#include <openssl/pem.h>
#include <openssl/rsa.h>
#include <openssl/pkcs12.h>
#include <openssl/x509v3.h>
#endif
@ -66,149 +68,190 @@ 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."
{
"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."
{
"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."
{
"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, "<crt|pem|pfx>", NULL, NULL, -1, NULL,
"Specify certificate file format"
{
"format", COMMAND_LINE_VALUE_REQUIRED, "<crt|pem|pfx>", NULL, NULL, -1, NULL,
"Specify certificate file format"
},
{ "path", COMMAND_LINE_VALUE_REQUIRED, "<path>", NULL, NULL, -1, NULL,
"Specify certificate file output path"
{
"path", COMMAND_LINE_VALUE_REQUIRED, "<path>", NULL, NULL, -1, NULL,
"Specify certificate file output path"
},
{ "p", COMMAND_LINE_VALUE_REQUIRED, "<password>", NULL, NULL, -1, NULL,
"Specify certificate export password"
{
"p", COMMAND_LINE_VALUE_REQUIRED, "<password>", NULL, NULL, -1, NULL,
"Specify certificate export password"
},
/* Basic Options */
{ "n", COMMAND_LINE_VALUE_REQUIRED, "<name>", 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\"."
{
"n", COMMAND_LINE_VALUE_REQUIRED, "<name>", 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."
{
"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, "<keyname>", 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."
{
"sk", COMMAND_LINE_VALUE_REQUIRED, "<keyname>", 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, "<location>", NULL, NULL, -1, NULL,
"Unsupported - Specifies the subject's certificate store location. location can be either currentuser (the default) or localmachine."
{
"sr", COMMAND_LINE_VALUE_REQUIRED, "<location>", 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, "<store>", NULL, NULL, -1, NULL,
"Unsupported - Specifies the subject's certificate store name that stores the output certificate."
{
"ss", COMMAND_LINE_VALUE_REQUIRED, "<store>", NULL, NULL, -1, NULL,
"Unsupported - Specifies the subject's certificate store name that stores the output certificate."
},
{ "#", COMMAND_LINE_VALUE_REQUIRED, "<number>", 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, "<number>", 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, "<authority>", 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)."
{
"$", COMMAND_LINE_VALUE_REQUIRED, "<authority>", 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, "<algorithm>", NULL, NULL, -1, NULL,
"Specifies the signature algorithm. algorithm must be md5, sha1, sha256 (the default), sha384, or sha512."
{
"a", COMMAND_LINE_VALUE_REQUIRED, "<algorithm>", NULL, NULL, -1, NULL,
"Specifies the signature algorithm. algorithm must be md5, sha1, sha256 (the default), sha384, or sha512."
},
{ "b", COMMAND_LINE_VALUE_REQUIRED, "<mm/dd/yyyy>", NULL, NULL, -1, NULL,
"Unsupported - Specifies the start of the validity period. Defaults to the current date."
{
"b", COMMAND_LINE_VALUE_REQUIRED, "<mm/dd/yyyy>", 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."
{
"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, "<certType>", NULL, NULL, -1, NULL,
"Unsupported - Specifies the certificate type. Valid values are end for end-entity and authority for certification authority."
{
"cy", COMMAND_LINE_VALUE_REQUIRED, "<certType>", 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, "<mm/dd/yyyy>", NULL, NULL, -1, NULL,
"Unsupported - Specifies the end of the validity period. Defaults to 12/31/2039 11:59:59 GMT."
{
"e", COMMAND_LINE_VALUE_REQUIRED, "<mm/dd/yyyy>", 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, "<oid[,oid…]>", NULL, NULL, -1, NULL,
"Unsupported - Inserts a list of comma-separated, enhanced key usage object identifiers (OIDs) into the certificate."
{
"eku", COMMAND_LINE_VALUE_REQUIRED, "<oid[,oid…]>", 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, "<number>", NULL, NULL, -1, NULL,
"Unsupported - Specifies the maximum height of the tree below this certificate."
{
"h", COMMAND_LINE_VALUE_REQUIRED, "<number>", NULL, NULL, -1, NULL,
"Unsupported - Specifies the maximum height of the tree below this certificate."
},
{ "ic", COMMAND_LINE_VALUE_REQUIRED, "<file>", NULL, NULL, -1, NULL,
"Unsupported - Specifies the issuer's certificate file."
{
"ic", COMMAND_LINE_VALUE_REQUIRED, "<file>", NULL, NULL, -1, NULL,
"Unsupported - Specifies the issuer's certificate file."
},
{ "ik", COMMAND_LINE_VALUE_REQUIRED, "<keyName>", NULL, NULL, -1, NULL,
"Unsupported - Specifies the issuer's key container name."
{
"ik", COMMAND_LINE_VALUE_REQUIRED, "<keyName>", NULL, NULL, -1, NULL,
"Unsupported - Specifies the issuer's key container name."
},
{ "iky", COMMAND_LINE_VALUE_REQUIRED, "<keyType>", 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."
{
"iky", COMMAND_LINE_VALUE_REQUIRED, "<keyType>", 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, "<name>", NULL, NULL, -1, NULL,
"Unsupported - Specifies the issuer's certificate common name."
{
"in", COMMAND_LINE_VALUE_REQUIRED, "<name>", NULL, NULL, -1, NULL,
"Unsupported - Specifies the issuer's certificate common name."
},
{ "ip", COMMAND_LINE_VALUE_REQUIRED, "<provider>", NULL, NULL, -1, NULL,
"Unsupported - Specifies the issuer's CryptoAPI provider name. For information about the CryptoAPI provider name, see the sp option."
{
"ip", COMMAND_LINE_VALUE_REQUIRED, "<provider>", 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, "<location>", NULL, NULL, -1, NULL,
"Unsupported - Specifies the location of the issuer's certificate store. location can be either currentuser (the default) or localmachine."
{
"ir", COMMAND_LINE_VALUE_REQUIRED, "<location>", 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, "<store>", NULL, NULL, -1, NULL,
"Unsupported - Specifies the issuer's certificate store name."
{
"is", COMMAND_LINE_VALUE_REQUIRED, "<store>", NULL, NULL, -1, NULL,
"Unsupported - Specifies the issuer's certificate store name."
},
{ "iv", COMMAND_LINE_VALUE_REQUIRED, "<pvkFile>", NULL, NULL, -1, NULL,
"Unsupported - Specifies the issuer's .pvk private key file."
{
"iv", COMMAND_LINE_VALUE_REQUIRED, "<pvkFile>", NULL, NULL, -1, NULL,
"Unsupported - Specifies the issuer's .pvk private key file."
},
{ "iy", COMMAND_LINE_VALUE_REQUIRED, "<type>", NULL, NULL, -1, NULL,
"Unsupported - Specifies the issuer's CryptoAPI provider type. For information about the CryptoAPI provider type, see the sy option."
{
"iy", COMMAND_LINE_VALUE_REQUIRED, "<type>", 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, "<link>", NULL, NULL, -1, NULL,
"Unsupported - Links to policy information (for example, to a URL)."
{
"l", COMMAND_LINE_VALUE_REQUIRED, "<link>", NULL, NULL, -1, NULL,
"Unsupported - Links to policy information (for example, to a URL)."
},
{ "len", COMMAND_LINE_VALUE_REQUIRED, "<number>", NULL, NULL, -1, NULL,
"Specifies the generated key length, in bits."
{
"len", COMMAND_LINE_VALUE_REQUIRED, "<number>", NULL, NULL, -1, NULL,
"Specifies the generated key length, in bits."
},
{ "m", COMMAND_LINE_VALUE_REQUIRED, "<number>", NULL, NULL, -1, NULL,
"Specifies the duration, in months, of the certificate validity period."
{
"m", COMMAND_LINE_VALUE_REQUIRED, "<number>", NULL, NULL, -1, NULL,
"Specifies the duration, in months, of the certificate validity period."
},
{ "y", COMMAND_LINE_VALUE_REQUIRED, "<number>", NULL, NULL, -1, NULL,
"Specifies the duration, in years, of the certificate validity period."
{
"y", COMMAND_LINE_VALUE_REQUIRED, "<number>", 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."
{
"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."
{
"r", COMMAND_LINE_VALUE_FLAG, NULL, NULL, NULL, -1, NULL,
"Unsupported - Creates a self-signed certificate."
},
{ "sc", COMMAND_LINE_VALUE_REQUIRED, "<file>", NULL, NULL, -1, NULL,
"Unsupported - Specifies the subject's certificate file."
{
"sc", COMMAND_LINE_VALUE_REQUIRED, "<file>", NULL, NULL, -1, NULL,
"Unsupported - Specifies the subject's certificate file."
},
{ "sky", COMMAND_LINE_VALUE_REQUIRED, "<keyType>", 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."
{
"sky", COMMAND_LINE_VALUE_REQUIRED, "<keyType>", 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, "<provider>", 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."
{
"sp", COMMAND_LINE_VALUE_REQUIRED, "<provider>", 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, "<pvkFile>", NULL, NULL, -1, NULL,
"Unsupported - Specifies the subject's .pvk private key file. The file is created if none exists."
{
"sv", COMMAND_LINE_VALUE_REQUIRED, "<pvkFile>", 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, "<type>", 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."
{
"sy", COMMAND_LINE_VALUE_REQUIRED, "<type>", 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, "<file>", NULL, NULL, -1, NULL,
"Unsupported - Specifies the certificate or CRL file to be signed."
{
"tbs", COMMAND_LINE_VALUE_REQUIRED, "<file>", NULL, NULL, -1, NULL,
"Unsupported - Specifies the certificate or CRL file to be signed."
},
/* Help */
@ -218,15 +261,16 @@ static COMMAND_LINE_ARGUMENT_A args[] =
{ NULL, 0, NULL, NULL, NULL, -1, NULL, NULL }
};
int makecert_print_command_line_help(int argc, char** argv)
static int makecert_print_command_line_help(int argc, char** argv)
{
char* str;
int length;
COMMAND_LINE_ARGUMENT_A* arg;
if (!argv)
return -1;
printf("Usage: %s [options] [output file]\n", argv[0]);
printf("\n");
arg = args;
do
@ -243,10 +287,12 @@ int makecert_print_command_line_help(int argc, char** argv)
if (arg->Format)
{
length = strlen(arg->Name) + strlen(arg->Format) + 2;
size_t length = strlen(arg->Name) + strlen(arg->Format) + 2;
str = malloc(length + 1);
if (!str)
return -1;
sprintf_s(str, length + 1, "%s %s", arg->Name, arg->Format);
printf("%-20s", str);
free(str);
@ -265,13 +311,15 @@ int makecert_print_command_line_help(int argc, char** argv)
}
#ifdef WITH_OPENSSL
int x509_add_ext(X509* cert, int nid, char* value)
static int x509_add_ext(X509* cert, int nid, char* value)
{
X509V3_CTX ctx;
X509_EXTENSION* ext;
X509V3_set_ctx_nodb(&ctx);
if (!cert || !value)
return 0;
X509V3_set_ctx_nodb(&ctx);
X509V3_set_ctx(&ctx, cert, cert, NULL, NULL, 0);
ext = X509V3_EXT_conf_nid(NULL, &ctx, nid, value);
@ -280,23 +328,24 @@ int x509_add_ext(X509* cert, int nid, char* value)
X509_add_ext(cert, ext, -1);
X509_EXTENSION_free(ext);
return 1;
}
#endif
char* x509_name_parse(char* name, char* txt, int* length)
static char* x509_name_parse(char* name, char* txt, int* length)
{
char* p;
char* entry;
if (!name || !txt || !length)
return NULL;
p = strstr(name, txt);
if (!p)
return NULL;
entry = p + strlen(txt) + 1;
p = strchr(entry, '=');
if (!p)
@ -307,16 +356,17 @@ char* x509_name_parse(char* name, char* txt, int* length)
return entry;
}
char* x509_get_default_name()
static char* x509_get_default_name(void)
{
CHAR* computerName = NULL;
DWORD nSize = 0;
if (GetComputerNameExA(ComputerNamePhysicalDnsFullyQualified, NULL, &nSize) ||
GetLastError() != ERROR_MORE_DATA)
GetLastError() != ERROR_MORE_DATA)
goto fallback;
computerName = (CHAR*)calloc(nSize, 1);
if (!computerName)
goto fallback;
@ -324,15 +374,15 @@ char* x509_get_default_name()
goto fallback;
return computerName;
fallback:
free(computerName);
if (GetComputerNameExA(ComputerNamePhysicalNetBIOS, NULL, &nSize) ||
GetLastError() != ERROR_MORE_DATA)
GetLastError() != ERROR_MORE_DATA)
return NULL;
computerName = (CHAR*)calloc(nSize, 1);
if (!computerName)
return NULL;
@ -345,15 +395,20 @@ fallback:
return computerName;
}
int command_line_pre_filter(MAKECERT_CONTEXT* context, int index, int argc, LPCSTR* argv)
static int command_line_pre_filter(MAKECERT_CONTEXT* context, int index, int argc, LPCSTR* argv)
{
if (!context || !argv || (index < 0) || (argc < 0))
return -1;
if (index == (argc - 1))
{
if (argv[index][0] != '-')
{
context->output_file = _strdup(argv[index]);
if (!context->output_file)
return -1;
return 1;
}
}
@ -361,22 +416,23 @@ int command_line_pre_filter(MAKECERT_CONTEXT* context, int index, int argc, LPCS
return 0;
}
int makecert_context_parse_arguments(MAKECERT_CONTEXT* context, int argc, char** argv)
static int makecert_context_parse_arguments(MAKECERT_CONTEXT* context, int argc, char** argv)
{
int status;
DWORD flags;
COMMAND_LINE_ARGUMENT_A* arg;
if (!context || !argv || (argc < 0))
return -1;
/**
* makecert -r -pe -n "CN=%COMPUTERNAME%" -eku 1.3.6.1.5.5.7.3.1 -ss my -sr LocalMachine
* -sky exchange -sp "Microsoft RSA SChannel Cryptographic Provider" -sy 12
*/
CommandLineClearArgumentsA(args);
flags = COMMAND_LINE_SEPARATOR_SPACE | COMMAND_LINE_SIGIL_DASH;
status = CommandLineParseArgumentsA(argc, (const char**) argv, args, flags, context,
(COMMAND_LINE_PRE_FILTER_FN_A) command_line_pre_filter, NULL);
(COMMAND_LINE_PRE_FILTER_FN_A) command_line_pre_filter, NULL);
if (status & COMMAND_LINE_STATUS_PRINT_HELP)
{
@ -393,7 +449,6 @@ int makecert_context_parse_arguments(MAKECERT_CONTEXT* context, int argc, char**
CommandLineSwitchStart(arg)
/* Basic Options */
CommandLineSwitchCase(arg, "silent")
{
context->silent = TRUE;
@ -434,6 +489,7 @@ int makecert_context_parse_arguments(MAKECERT_CONTEXT* context, int argc, char**
continue;
context->output_path = _strdup(arg->Value);
if (!context->output_path)
return -1;
}
@ -443,6 +499,7 @@ int makecert_context_parse_arguments(MAKECERT_CONTEXT* context, int argc, char**
continue;
context->password = _strdup(arg->Value);
if (!context->password)
return -1;
}
@ -452,6 +509,7 @@ int makecert_context_parse_arguments(MAKECERT_CONTEXT* context, int argc, char**
continue;
context->common_name = _strdup(arg->Value);
if (!context->common_name)
return -1;
}
@ -469,25 +527,30 @@ int makecert_context_parse_arguments(MAKECERT_CONTEXT* context, int argc, char**
context->duration_months = atoi(arg->Value);
}
CommandLineSwitchDefault(arg)
{
}
CommandLineSwitchEnd(arg)
}
while ((arg = CommandLineFindNextArgumentA(arg)) != NULL);
return 1;
}
int makecert_context_set_output_file_name(MAKECERT_CONTEXT* context, char* name)
{
if (!context)
return -1;
free(context->output_file);
context->output_file = _strdup(name);
context->output_file = NULL;
if (name)
context->output_file = _strdup(name);
if (!context->output_file)
return -1;
return 1;
}
@ -504,9 +567,13 @@ int makecert_context_output_certificate_file(MAKECERT_CONTEXT* context, char* pa
BIO* bio = NULL;
BYTE* x509_str = NULL;
if (!context || !path)
return -1;
if (!context->output_file)
{
context->output_file = _strdup(context->default_name);
if (!context->output_file)
return -1;
}
@ -514,11 +581,12 @@ int makecert_context_output_certificate_file(MAKECERT_CONTEXT* context, char* pa
/*
* Output Certificate File
*/
length = strlen(context->output_file);
filename = malloc(length + 8);
if (!filename)
return -1;
strcpy(filename, context->output_file);
if (context->crtFormat)
@ -540,23 +608,30 @@ int makecert_context_output_certificate_file(MAKECERT_CONTEXT* context, char* pa
if (fp)
{
if (context->pfxFormat)
{
if (!context->password)
{
context->password = _strdup("password");
if (!context->password)
goto out_fail;
printf("Using default export password \"password\"\n");
}
#if OPENSSL_VERSION_NUMBER < 0x10100000L
OpenSSL_add_all_algorithms();
OpenSSL_add_all_ciphers();
OpenSSL_add_all_digests();
#else
OPENSSL_init_crypto(OPENSSL_INIT_ADD_ALL_CIPHERS \
| OPENSSL_INIT_ADD_ALL_DIGESTS \
| OPENSSL_INIT_LOAD_CONFIG, NULL);
#endif
context->pkcs12 = PKCS12_create(context->password, context->default_name,
context->pkey, context->x509, NULL, 0, 0, 0, 0, 0);
context->pkey, context->x509, NULL, 0, 0, 0, 0, 0);
if (!context->pkcs12)
goto out_fail;
@ -566,12 +641,14 @@ int makecert_context_output_certificate_file(MAKECERT_CONTEXT* context, char* pa
goto out_fail;
status = i2d_PKCS12_bio(bio, context->pkcs12);
if (status != 1)
goto out_fail;
offset = 0;
length = 2048;
x509_str = (BYTE*) malloc(length);
if (!x509_str)
goto out_fail;
@ -585,10 +662,10 @@ int makecert_context_output_certificate_file(MAKECERT_CONTEXT* context, char* pa
while (offset >= length)
{
int new_len;
BYTE *new_str;
BYTE* new_str;
new_len = length * 2;
new_str = (BYTE*) realloc(x509_str, new_len);
if (!new_str)
{
status = -1;
@ -597,7 +674,6 @@ int makecert_context_output_certificate_file(MAKECERT_CONTEXT* context, char* pa
length = new_len;
x509_str = new_str;
status = BIO_read(bio, &x509_str[offset], length);
if (status < 0)
@ -608,11 +684,11 @@ int makecert_context_output_certificate_file(MAKECERT_CONTEXT* context, char* pa
if (status < 0)
goto out_fail;
length = offset;
if (fwrite((void*) x509_str, length, 1, fp) != 1)
goto out_fail;
}
else
{
@ -627,6 +703,7 @@ int makecert_context_output_certificate_file(MAKECERT_CONTEXT* context, char* pa
offset = 0;
length = 2048;
x509_str = (BYTE*) malloc(length);
if (!x509_str)
goto out_fail;
@ -640,10 +717,10 @@ int makecert_context_output_certificate_file(MAKECERT_CONTEXT* context, char* pa
while (offset >= length)
{
int new_len;
BYTE *new_str;
BYTE* new_str;
new_len = length * 2;
new_str = (BYTE*) realloc(x509_str, new_len);
if (!new_str)
{
status = -1;
@ -652,7 +729,6 @@ int makecert_context_output_certificate_file(MAKECERT_CONTEXT* context, char* pa
length = new_len;
x509_str = new_str;
status = BIO_read(bio, &x509_str[offset], length);
if (status < 0)
@ -682,11 +758,13 @@ int makecert_context_output_certificate_file(MAKECERT_CONTEXT* context, char* pa
goto out_fail;
status = PEM_write_bio_PrivateKey(bio, context->pkey, NULL, NULL, 0, NULL, NULL);
if (status < 0)
goto out_fail;
offset = 0;
length = 2048;
if (!(x509_str = (BYTE*) malloc(length)))
goto out_fail;
@ -700,10 +778,10 @@ int makecert_context_output_certificate_file(MAKECERT_CONTEXT* context, char* pa
while (offset >= length)
{
int new_len;
BYTE *new_str;
BYTE* new_str;
new_len = length * 2;
new_str = (BYTE*) realloc(x509_str, new_len);
if (!new_str)
{
status = -1;
@ -712,7 +790,6 @@ int makecert_context_output_certificate_file(MAKECERT_CONTEXT* context, char* pa
length = new_len;
x509_str = new_str;
status = BIO_read(bio, &x509_str[offset], length);
if (status < 0)
@ -730,19 +807,20 @@ int makecert_context_output_certificate_file(MAKECERT_CONTEXT* context, char* pa
goto out_fail;
}
}
}
ret = 1;
out_fail:
if (bio)
BIO_free(bio);
if (fp)
fclose(fp);
free(x509_str);
free(filename);
free(fullpath);
return ret;
#else
return 1;
@ -768,6 +846,7 @@ int makecert_context_output_private_key_file(MAKECERT_CONTEXT* context, char* pa
if (!context->output_file)
{
context->output_file = _strdup(context->default_name);
if (!context->output_file)
return -1;
}
@ -775,11 +854,12 @@ int makecert_context_output_private_key_file(MAKECERT_CONTEXT* context, char* pa
/**
* Output Private Key File
*/
length = strlen(context->output_file);
filename = malloc(length + 8);
if (!filename)
return -1;
strcpy(filename, context->output_file);
strcpy(&filename[length], ".key");
@ -792,6 +872,7 @@ int makecert_context_output_private_key_file(MAKECERT_CONTEXT* context, char* pa
goto out_fail;
fp = fopen(fullpath, "w+");
if (!fp)
goto out_fail;
@ -806,6 +887,7 @@ int makecert_context_output_private_key_file(MAKECERT_CONTEXT* context, char* pa
offset = 0;
length = 2048;
x509_str = (BYTE*) malloc(length);
if (!x509_str)
goto out_fail;
@ -819,10 +901,10 @@ int makecert_context_output_private_key_file(MAKECERT_CONTEXT* context, char* pa
while (offset >= length)
{
int new_len;
BYTE *new_str;
BYTE* new_str;
new_len = length * 2;
new_str = (BYTE*) realloc(x509_str, new_len);
if (!new_str)
{
status = -1;
@ -831,7 +913,6 @@ int makecert_context_output_private_key_file(MAKECERT_CONTEXT* context, char* pa
length = new_len;
x509_str = new_str;
status = BIO_read(bio, &x509_str[offset], length);
if (status < 0)
@ -849,16 +930,17 @@ int makecert_context_output_private_key_file(MAKECERT_CONTEXT* context, char* pa
goto out_fail;
ret = 1;
out_fail:
if (fp)
fclose(fp);
if (bio)
BIO_free(bio);
free(x509_str);
free(filename);
free(fullpath);
return ret;
#else
return 1;
@ -876,8 +958,8 @@ int makecert_context_process(MAKECERT_CONTEXT* context, int argc, char** argv)
const EVP_MD* md = NULL;
COMMAND_LINE_ARGUMENT_A* arg;
int ret;
ret = makecert_context_parse_arguments(context, argc, argv);
if (ret < 1)
{
return ret;
@ -886,19 +968,22 @@ int makecert_context_process(MAKECERT_CONTEXT* context, int argc, char** argv)
if (!context->default_name && !context->common_name)
{
context->default_name = x509_get_default_name();
if (!context->default_name)
return -1;
}
else
{
context->default_name = _strdup(context->common_name);
if (!context->default_name)
return -1;
}
if (!context->common_name)
{
context->common_name = _strdup(context->default_name);
if (!context->common_name)
return -1;
}
@ -916,7 +1001,6 @@ int makecert_context_process(MAKECERT_CONTEXT* context, int argc, char** argv)
return -1;
key_length = 2048;
arg = CommandLineFindArgumentA(args, "len");
if (arg->Flags & COMMAND_LINE_VALUE_PRESENT)
@ -924,15 +1008,30 @@ int makecert_context_process(MAKECERT_CONTEXT* context, int argc, char** argv)
key_length = atoi(arg->Value);
}
#if (OPENSSL_VERSION_NUMBER < 0x10100000L)
context->rsa = RSA_generate_key(key_length, RSA_F4, NULL, NULL);
#else
{
BIGNUM* rsa = BN_secure_new();
int rc;
if (!rsa)
return -1;
BN_set_word(rsa, RSA_F4);
rc = RSA_generate_key_ex(context->rsa, key_length, rsa, NULL);
BN_clear_free(rsa);
if (rc != 1)
return -1;
}
#endif
if (!EVP_PKEY_assign_RSA(context->pkey, context->rsa))
return -1;
context->rsa = NULL;
X509_set_version(context->x509, 2);
arg = CommandLineFindArgumentA(args, "#");
if (arg->Flags & COMMAND_LINE_VALUE_PRESENT)
@ -941,22 +1040,25 @@ int makecert_context_process(MAKECERT_CONTEXT* context, int argc, char** argv)
serial = (long) GetTickCount64();
ASN1_INTEGER_set(X509_get_serialNumber(context->x509), serial);
X509_gmtime_adj(X509_get_notBefore(context->x509), 0);
if (context->duration_months)
{
X509_gmtime_adj(X509_get_notAfter(context->x509), (long) (60 * 60 * 24 * 31 * context->duration_months));
}
else if (context->duration_years)
{
X509_gmtime_adj(X509_get_notAfter(context->x509), (long) (60 * 60 * 24 * 365 * context->duration_years));
}
ASN1_TIME* before;
ASN1_TIME* after;
#if (OPENSSL_VERSION_NUMBER < 0x10100000L)
before = X509_get_notBefore(context->x509);
after = X509_get_notAfter(context->x509);
#else
before = X509_getm_notBefore(context->x509);
after = X509_getm_notAfter(context->x509);
#endif
X509_gmtime_adj(before, 0);
if (context->duration_months)
X509_gmtime_adj(after, (long)(60 * 60 * 24 * 31 * context->duration_months));
else if (context->duration_years)
X509_gmtime_adj(after, (long)(60 * 60 * 24 * 365 * context->duration_years));
}
X509_set_pubkey(context->x509, context->pkey);
name = X509_get_subject_name(context->x509);
arg = CommandLineFindArgumentA(args, "n");
if (arg->Flags & COMMAND_LINE_VALUE_PRESENT)
@ -988,23 +1090,18 @@ int makecert_context_process(MAKECERT_CONTEXT* context, int argc, char** argv)
entry = context->common_name;
length = strlen(entry);
X509_NAME_add_entry_by_txt(name, "CN", MBSTRING_UTF8, (const unsigned char*) entry, 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_set_issuer_name(context->x509, name);
x509_add_ext(context->x509, NID_ext_key_usage, "serverAuth");
arg = CommandLineFindArgumentA(args, "a");
md = EVP_sha256();
if (arg->Flags & COMMAND_LINE_VALUE_PRESENT)
@ -1035,22 +1132,22 @@ int makecert_context_process(MAKECERT_CONTEXT* context, int argc, char** argv)
int length;
int offset;
BYTE* x509_str;
bio = BIO_new(BIO_s_mem());
if (!bio)
return -1;
status = X509_print(bio, context->x509);
if (status < 0)
{
BIO_free(bio);
return -1;
}
offset = 0;
length = 2048;
if (!(x509_str = (BYTE*) malloc(length + 1)))
{
BIO_free(bio);
@ -1071,10 +1168,10 @@ int makecert_context_process(MAKECERT_CONTEXT* context, int argc, char** argv)
while (offset >= length)
{
int new_len;
BYTE *new_str;
BYTE* new_str;
new_len = length * 2;
new_str = (BYTE*) realloc(x509_str, new_len);
if (!new_str)
{
status = -1;
@ -1082,10 +1179,8 @@ int makecert_context_process(MAKECERT_CONTEXT* context, int argc, char** argv)
}
x509_str = new_str;
status = BIO_read(bio, &x509_str[offset], new_len);
if (status < 0)
break;
@ -1098,9 +1193,7 @@ int makecert_context_process(MAKECERT_CONTEXT* context, int argc, char** argv)
length = offset;
x509_str[length] = '\0';
printf("%s", x509_str);
free(x509_str);
BIO_free(bio);
}
@ -1119,15 +1212,14 @@ int makecert_context_process(MAKECERT_CONTEXT* context, int argc, char** argv)
return -1;
}
}
#endif
return 0;
}
MAKECERT_CONTEXT* makecert_context_new()
MAKECERT_CONTEXT* makecert_context_new(void)
{
MAKECERT_CONTEXT* context = NULL;
context = (MAKECERT_CONTEXT*) calloc(1, sizeof(MAKECERT_CONTEXT));
MAKECERT_CONTEXT* context = (MAKECERT_CONTEXT*) calloc(1, sizeof(MAKECERT_CONTEXT));
if (context)
{
@ -1143,18 +1235,17 @@ void makecert_context_free(MAKECERT_CONTEXT* context)
if (context)
{
free(context->password);
free(context->default_name);
free(context->common_name);
free(context->output_file);
free(context->output_path);
#ifdef WITH_OPENSSL
X509_free(context->x509);
EVP_PKEY_free(context->pkey);
#if (OPENSSL_VERSION_NUMBER < 0x10100000L)
CRYPTO_cleanup_all_ex_data();
#endif
#endif
free(context);
}
}