From d8c63b8e6687f54cd3b1cd0a85726506a1a40166 Mon Sep 17 00:00:00 2001 From: David Garske Date: Fri, 5 Aug 2016 14:15:47 -0700 Subject: [PATCH] Various improvements to support openssl compatibility. * Fixed bug with "wolfSSL_get_cipher_name_internal" for loop using incorrect max length for "cipher_name_idx" (this caused fault when library built with NO_ERROR_STRINGS and calling it). * Adds new "GetCipherNameInternal" function to get cipher name using internal "cipherSuite" index only (for scenario where WOLFSSL object does not exist). * Implements API's for "wolf_OBJ_nid2sn" and "wolf_OBJ_sn2nid". Uses the ecc.c "ecc_sets" table to locate NID (ECC ID and NID are same). * Added "WOLFSSL*" to HandShakeInfo. * Allowed "SetName" to be exposed. * Added "wolfSSL_X509_load_certificate_buffer". Refactor "wolfSSL_X509_load_certificate_file" to use new function (no duplicate code). --- src/internal.c | 95 +++++++++++++++++++++++------------------ src/ssl.c | 63 +++++++++++++++++---------- wolfcrypt/src/asn.c | 2 +- wolfssl/callbacks.h | 2 + wolfssl/internal.h | 5 ++- wolfssl/ssl.h | 4 +- wolfssl/wolfcrypt/asn.h | 3 ++ 7 files changed, 106 insertions(+), 68 deletions(-) diff --git a/src/internal.c b/src/internal.c index 6af1597ee..0fba76ab6 100755 --- a/src/internal.c +++ b/src/internal.c @@ -12315,50 +12315,60 @@ int GetCipherNamesSize(void) } /* gets cipher name in the format DHE-RSA-... rather then TLS_DHE... */ -const char* wolfSSL_get_cipher_name_internal(WOLFSSL* ssl) +const char* GetCipherNameInternal(const char* cipherName, int cipherSuite) { - const char* fullName; - const char* first; - WOLFSSL_CIPHER* cipher; + const char* result = NULL; + const char* first; int i; + if (cipherName == NULL) { + WOLFSSL_MSG("Bad argument"); + return NULL; + } + + first = (XSTRSTR(cipherName, "CHACHA")) ? "CHACHA" + : (XSTRSTR(cipherName, "EC")) ? "EC" + : (XSTRSTR(cipherName, "CCM")) ? "CCM" + : NULL; /* normal */ + + for (i = 0; i < (int)(sizeof(cipher_name_idx)/sizeof(int)); i++) { + if (cipher_name_idx[i] == cipherSuite) { + const char* nameFound = cipher_names[i]; + + /* extra sanity check on returned cipher name */ + if (nameFound == NULL) { + continue; + } + + /* if first is null then not any */ + if (first == NULL) { + if ( !XSTRSTR(nameFound, "CHACHA") && + !XSTRSTR(nameFound, "EC") && + !XSTRSTR(nameFound, "CCM")) { + result = nameFound; + break; + } + } + else if (XSTRSTR(nameFound, first)) { + result = nameFound; + break; + } + } + } + + return result; +} + +const char* wolfSSL_get_cipher_name_internal(WOLFSSL* ssl) +{ if (ssl == NULL) { WOLFSSL_MSG("Bad argument"); return NULL; } - cipher = wolfSSL_get_current_cipher(ssl); - fullName = wolfSSL_CIPHER_get_name(cipher); - if (fullName) { - first = (XSTRSTR(fullName, "CHACHA")) ? "CHACHA" - : (XSTRSTR(fullName, "EC")) ? "EC" - : (XSTRSTR(fullName, "CCM")) ? "CCM" - : NULL; /* normal */ - - for (i = 0; i < (int)sizeof(cipher_name_idx); i++) { - if (cipher_name_idx[i] == ssl->options.cipherSuite) { - const char* nameFound = cipher_names[i]; - - /* extra sanity check on returned cipher name */ - if (nameFound == NULL) { - continue; - } - - /* if first is null then not any */ - if (first == NULL) { - if (!XSTRSTR(nameFound, "CHACHA") && - !XSTRSTR(nameFound, "EC") && !XSTRSTR(nameFound, "CCM")) { - return cipher_names[i]; - } - } - else if (XSTRSTR(nameFound, first)) { - return cipher_names[i]; - } - } - } - } - - return NULL; /* error or not found */ + return GetCipherNameInternal( + wolfSSL_CIPHER_get_name(&ssl->cipher), + ssl->options.cipherSuite); } @@ -12478,10 +12488,11 @@ static void PickHashSigAlgo(WOLFSSL* ssl, #ifdef WOLFSSL_CALLBACKS /* Initialisze HandShakeInfo */ - void InitHandShakeInfo(HandShakeInfo* info) + void InitHandShakeInfo(HandShakeInfo* info, WOLFSSL* ssl) { int i; + info->ssl = ssl; info->cipherName[0] = 0; for (i = 0; i < MAX_PACKETS_HANDSHAKE; i++) info->packetNames[i][0] = 0; @@ -12490,22 +12501,22 @@ static void PickHashSigAlgo(WOLFSSL* ssl, } /* Set Final HandShakeInfo parameters */ - void FinishHandShakeInfo(HandShakeInfo* info, const WOLFSSL* ssl) + void FinishHandShakeInfo(HandShakeInfo* info) { int i; int sz = sizeof(cipher_name_idx)/sizeof(int); for (i = 0; i < sz; i++) - if (ssl->options.cipherSuite == (byte)cipher_name_idx[i]) { - if (ssl->options.cipherSuite0 == ECC_BYTE) + if (info->ssl->options.cipherSuite == (byte)cipher_name_idx[i]) { + if (info->ssl->options.cipherSuite0 == ECC_BYTE) continue; /* ECC suites at end */ XSTRNCPY(info->cipherName, cipher_names[i], MAX_CIPHERNAME_SZ); break; } /* error max and min are negative numbers */ - if (ssl->error <= MIN_PARAM_ERR && ssl->error >= MAX_PARAM_ERR) - info->negotiationError = ssl->error; + if (info->ssl->error <= MIN_PARAM_ERR && info->ssl->error >= MAX_PARAM_ERR) + info->negotiationError = info->ssl->error; } diff --git a/src/ssl.c b/src/ssl.c index a44bcb8ec..2b7dd0756 100644 --- a/src/ssl.c +++ b/src/ssl.c @@ -8290,7 +8290,7 @@ int wolfSSL_set_compression(WOLFSSL* ssl) if (hsCb) { ssl->hsInfoOn = 1; - InitHandShakeInfo(&ssl->handShakeInfo); + InitHandShakeInfo(&ssl->handShakeInfo, ssl); } if (toCb) { ssl->toInfoOn = 1; @@ -8378,7 +8378,7 @@ int wolfSSL_set_compression(WOLFSSL* ssl) ssl->toInfoOn = 0; } if (hsCb) { - FinishHandShakeInfo(&ssl->handShakeInfo, ssl); + FinishHandShakeInfo(&ssl->handShakeInfo); (hsCb)(&ssl->handShakeInfo); ssl->hsInfoOn = 0; } @@ -11345,9 +11345,6 @@ WOLFSSL_X509* wolfSSL_X509_load_certificate_file(const char* fname, int format) XFILE file; WOLFSSL_X509* x509 = NULL; - DerBuffer* der = NULL; - - WOLFSSL_ENTER("wolfSSL_X509_load_certificate"); /* Check the inputs */ if ((fname == NULL) || @@ -11385,6 +11382,26 @@ WOLFSSL_X509* wolfSSL_X509_load_certificate_file(const char* fname, int format) XFCLOSE(file); + x509 = wolfSSL_X509_load_certificate_buffer(fileBuffer, (int)sz, format); + + if (dynamic) + XFREE(fileBuffer, NULL, DYNAMIC_TYPE_FILE); + + return x509; +} + +#endif /* NO_FILESYSTEM */ + + +WOLFSSL_X509* wolfSSL_X509_load_certificate_buffer( + const unsigned char* buf, int sz, int format) +{ + int ret; + WOLFSSL_X509* x509 = NULL; + DerBuffer* der = NULL; + + WOLFSSL_ENTER("wolfSSL_X509_load_certificate_ex"); + if (format == SSL_FILETYPE_PEM) { int ecc = 0; #ifdef WOLFSSL_SMALL_STACK @@ -11397,9 +11414,6 @@ WOLFSSL_X509* wolfSSL_X509_load_certificate_file(const char* fname, int format) info = (EncryptedInfo*)XMALLOC(sizeof(EncryptedInfo), NULL, DYNAMIC_TYPE_TMP_BUFFER); if (info == NULL) { - if (dynamic) - XFREE(fileBuffer, NULL, DYNAMIC_TYPE_FILE); - return NULL; } #endif @@ -11408,7 +11422,7 @@ WOLFSSL_X509* wolfSSL_X509_load_certificate_file(const char* fname, int format) info->ctx = NULL; info->consumed = 0; - if (PemToDer(fileBuffer, sz, CERT_TYPE, &der, NULL, info, &ecc) != 0) { + if (PemToDer(buf, sz, CERT_TYPE, &der, NULL, info, &ecc) != 0) { FreeDer(&der); } @@ -11419,13 +11433,10 @@ WOLFSSL_X509* wolfSSL_X509_load_certificate_file(const char* fname, int format) else { ret = AllocDer(&der, (word32)sz, CERT_TYPE, NULL); if (ret == 0) { - XMEMCPY(der->buffer, fileBuffer, sz); + XMEMCPY(der->buffer, buf, sz); } } - if (dynamic) - XFREE(fileBuffer, NULL, DYNAMIC_TYPE_FILE); - /* At this point we want `der` to have the certificate in DER format */ /* ready to be decoded. */ if (der != NULL && der->buffer != NULL) { @@ -11466,8 +11477,6 @@ WOLFSSL_X509* wolfSSL_X509_load_certificate_file(const char* fname, int format) return x509; } -#endif /* NO_FILESYSTEM */ - #endif /* KEEP_PEER_CERT || SESSION_CERTS */ /* OPENSSL_EXTRA is needed for wolfSSL_X509_d21 function @@ -17870,11 +17879,16 @@ void* wolfSSL_GetRsaDecCtx(WOLFSSL* ssl) } const char * wolf_OBJ_nid2sn(int n) { - (void)n; + int i; WOLFSSL_ENTER("wolf_OBJ_nid2sn"); - WOLFSSL_STUB("wolf_OBJ_nid2sn"); - - return 0; + + /* find based on NID and return name */ + for (i = 0; i < ecc_sets[i].size; i++) { + if (n == ecc_sets[i].id) { + return ecc_sets[i].name; + } + } + return NULL; } int wolf_OBJ_obj2nid(const WOLFSSL_ASN1_OBJECT *o) { @@ -17886,11 +17900,16 @@ void* wolfSSL_GetRsaDecCtx(WOLFSSL* ssl) } int wolf_OBJ_sn2nid(const char *sn) { - (void)sn; + int i; WOLFSSL_ENTER("wolf_OBJ_osn2nid"); - WOLFSSL_STUB("wolf_OBJ_osn2nid"); - return 0; + /* find based on name and return NID */ + for (i = 0; i < ecc_sets[i].size; i++) { + if (XSTRNCMP(sn, ecc_sets[i].name, ECC_MAXNAME) == 0) { + return ecc_sets[i].id; + } + } + return -1; } diff --git a/wolfcrypt/src/asn.c b/wolfcrypt/src/asn.c index b151f16a9..98d6375ef 100644 --- a/wolfcrypt/src/asn.c +++ b/wolfcrypt/src/asn.c @@ -6762,7 +6762,7 @@ static int SetAltNames(byte *out, word32 outSz, byte *input, word32 length) /* encode CertName into output, return total bytes written */ -static int SetName(byte* output, word32 outputSz, CertName* name) +int SetName(byte* output, word32 outputSz, CertName* name) { int totalBytes = 0, i, idx; #ifdef WOLFSSL_SMALL_STACK diff --git a/wolfssl/callbacks.h b/wolfssl/callbacks.h index 23681db76..9f3be0582 100644 --- a/wolfssl/callbacks.h +++ b/wolfssl/callbacks.h @@ -40,8 +40,10 @@ enum { /* CALLBACK CONTSTANTS */ fit here */ }; +struct WOLFSSL; typedef struct handShakeInfo_st { + struct WOLFSSL* ssl; char cipherName[MAX_CIPHERNAME_SZ + 1]; /* negotiated cipher */ char packetNames[MAX_PACKETS_HANDSHAKE][MAX_PACKETNAME_SZ + 1]; /* SSL packet names */ diff --git a/wolfssl/internal.h b/wolfssl/internal.h index ad568279c..ac6f062f8 100644 --- a/wolfssl/internal.h +++ b/wolfssl/internal.h @@ -2894,9 +2894,9 @@ typedef struct EncryptedInfo { #ifdef WOLFSSL_CALLBACKS WOLFSSL_LOCAL - void InitHandShakeInfo(HandShakeInfo*); + void InitHandShakeInfo(HandShakeInfo*, WOLFSSL*); WOLFSSL_LOCAL - void FinishHandShakeInfo(HandShakeInfo*, const WOLFSSL*); + void FinishHandShakeInfo(HandShakeInfo*); WOLFSSL_LOCAL void AddPacketName(const char*, HandShakeInfo*); @@ -3103,6 +3103,7 @@ WOLFSSL_LOCAL void c32to24(word32 in, word24 out); WOLFSSL_LOCAL const char* const* GetCipherNames(void); WOLFSSL_LOCAL int GetCipherNamesSize(void); +WOLFSSL_LOCAL const char* GetCipherNameInternal(const char* cipherName, int cipherSuite); WOLFSSL_LOCAL const char* wolfSSL_get_cipher_name_internal(WOLFSSL* ssl); diff --git a/wolfssl/ssl.h b/wolfssl/ssl.h index 704817d5c..8e5c5a157 100644 --- a/wolfssl/ssl.h +++ b/wolfssl/ssl.h @@ -936,7 +936,7 @@ WOLFSSL_API WOLFSSL_X509* wolfSSL_get_chain_X509(WOLFSSL_X509_CHAIN*, int idx); WOLFSSL_API void wolfSSL_FreeX509(WOLFSSL_X509*); /* get index cert in PEM */ WOLFSSL_API int wolfSSL_get_chain_cert_pem(WOLFSSL_X509_CHAIN*, int idx, - unsigned char* buffer, int inLen, int* outLen); + unsigned char* buf, int inLen, int* outLen); WOLFSSL_API const unsigned char* wolfSSL_get_sessionID(const WOLFSSL_SESSION* s); WOLFSSL_API int wolfSSL_X509_get_serial_number(WOLFSSL_X509*,unsigned char*,int*); WOLFSSL_API char* wolfSSL_X509_get_subjectCN(WOLFSSL_X509*); @@ -959,6 +959,8 @@ WOLFSSL_API WOLFSSL_X509* WOLFSSL_API WOLFSSL_X509* wolfSSL_X509_load_certificate_file(const char* fname, int format); #endif +WOLFSSL_API WOLFSSL_X509* wolfSSL_X509_load_certificate_buffer( + const unsigned char* buf, int sz, int format); #ifdef WOLFSSL_SEP WOLFSSL_API unsigned char* diff --git a/wolfssl/wolfcrypt/asn.h b/wolfssl/wolfcrypt/asn.h index 293adfd4d..5886976b6 100644 --- a/wolfssl/wolfcrypt/asn.h +++ b/wolfssl/wolfcrypt/asn.h @@ -639,6 +639,9 @@ WOLFSSL_LOCAL int ExtractDate(const unsigned char* date, unsigned char format, WOLFSSL_LOCAL int ValidateDate(const byte* date, byte format, int dateType); /* ASN.1 helper functions */ +#ifdef WOLFSSL_CERT_GEN +WOLFSSL_TEST_API int SetName(byte* output, word32 outputSz, CertName* name); +#endif WOLFSSL_LOCAL int GetLength(const byte* input, word32* inOutIdx, int* len, word32 maxIdx); WOLFSSL_LOCAL int GetSequence(const byte* input, word32* inOutIdx, int* len,