diff --git a/src/ssl.c b/src/ssl.c index 119308ec7..a3559d681 100644 --- a/src/ssl.c +++ b/src/ssl.c @@ -76,6 +76,8 @@ #include #include #include + #include + #include /* openssl headers end, wolfssl internal headers next */ #include #include @@ -7182,6 +7184,77 @@ int wolfSSL_check_private_key(const WOLFSSL* ssl) return ret; } +#if defined(OPENSSL_ALL) +/* Returns the number of X509V3 extensions in X509 object, or 0 on failure */ +int wolfSSL_X509_get_ext_count(const WOLFSSL_X509* passedCert) +{ + int extCount = 0; + int length = 0; + int outSz = 0; + const byte* rawCert; + int sz = 0; + word32 idx = 0; + DecodedCert cert; + const byte* input; + + WOLFSSL_ENTER("wolfSSL_X509_get_ext_count()"); + if (passedCert == NULL) { + WOLFSSL_MSG("\tNot passed a certificate"); + return WOLFSSL_FAILURE; + } + + rawCert = wolfSSL_X509_get_der((WOLFSSL_X509*)passedCert, &outSz); + if (rawCert == NULL) { + WOLFSSL_MSG("\tpassedCert has no internal DerBuffer set."); + return WOLFSSL_FAILURE; + } + InitDecodedCert(&cert, rawCert, (word32)outSz, 0); + + if (ParseCert(&cert, CA_TYPE, NO_VERIFY, NULL) < 0) { + WOLFSSL_MSG("\tCertificate parsing failed"); + return WOLFSSL_FAILURE; + } + + input = cert.extensions; + sz = cert.extensionsSz; + + if (input == NULL || sz == 0) { + FreeDecodedCert(&cert); + return WOLFSSL_FAILURE; + } + + if (input[idx++] != ASN_EXTENSIONS) { + WOLFSSL_MSG("\tfail: should be an EXTENSIONS"); + FreeDecodedCert(&cert); + return WOLFSSL_FAILURE; + } + + if (GetLength(input, &idx, &length, sz) < 0) { + WOLFSSL_MSG("\tfail: invalid length"); + FreeDecodedCert(&cert); + return WOLFSSL_FAILURE; + } + + if (GetSequence(input, &idx, &length, sz) < 0) { + WOLFSSL_MSG("\tfail: should be a SEQUENCE (1)"); + FreeDecodedCert(&cert); + return WOLFSSL_FAILURE; + } + + while (idx < (word32)sz) { + if (GetSequence(input, &idx, &length, sz) < 0) { + WOLFSSL_MSG("\tfail: should be a SEQUENCE"); + FreeDecodedCert(&cert); + return WOLFSSL_FAILURE; + } + idx += length; + extCount++; + } + FreeDecodedCert(&cert); + return extCount; +} + +#endif /* OPENSSL_ALL */ /* Looks for the extension matching the passed in nid * @@ -15899,6 +15972,55 @@ void wolfSSL_sk_X509_free(WOLF_STACK_OF(WOLFSSL_X509_NAME)* sk) { #endif /* NO_CERTS && OPENSSL_EXTRA */ +#if defined(OPENSSL_ALL) + +/* Frees all nodes in ACCESS_DESCRIPTION stack +* +* sk stack of nodes to free +* f free function to use, not called with wolfSSL +*/ +void wolfSSL_sk_ACCESS_DESCRIPTION_pop_free(WOLFSSL_STACK* sk, + void f (WOLFSSL_ACCESS_DESCRIPTION*)) +{ + WOLFSSL_STACK* node; + + WOLFSSL_ENTER("wolfSSL_sk_ACCESS_DESCRIPTION_pop_free"); + + (void)f; + if (sk == NULL) { + return; + } + + /* parse through stack freeing each node */ + node = sk->next; + while (sk->num > 1) { + WOLFSSL_STACK* tmp = node; + node = node->next; + + if(tmp->data.access->method) { + wolfSSL_ASN1_OBJECT_free(tmp->data.access->method); + } + if(tmp->data.access->location) { + wolfSSL_GENERAL_NAME_free(tmp->data.access->location); + } + XFREE(tmp, NULL, DYNAMIC_TYPE_ASN1); + sk->num -= 1; + } + + /* free head of stack */ + if (sk->num == 1) { + if(sk->data.access->method) { + wolfSSL_ASN1_OBJECT_free(sk->data.access->method); + } + if(sk->data.access->location) { + wolfSSL_GENERAL_NAME_free(sk->data.access->location); + } + } + XFREE(sk, NULL, DYNAMIC_TYPE_ASN1); +} + +#endif + #ifdef OPENSSL_EXTRA /* Returns the general name at index i from the stack @@ -15955,7 +16077,7 @@ int wolfSSL_sk_GENERAL_NAME_num(WOLFSSL_STACK* sk) * f free function to use, not called with wolfSSL */ void wolfSSL_sk_GENERAL_NAME_pop_free(WOLFSSL_STACK* sk, - void f (WOLFSSL_ASN1_OBJECT*)) + void f (WOLFSSL_GENERAL_NAME*)) { WOLFSSL_STACK* node; @@ -15985,6 +16107,29 @@ void wolfSSL_sk_GENERAL_NAME_pop_free(WOLFSSL_STACK* sk, } + +/* Frees GENERAL_NAME objects. +*/ +void wolfSSL_GENERAL_NAME_free(WOLFSSL_GENERAL_NAME* name) +{ + WOLFSSL_ENTER("wolfSSL_GENERAL_NAME_Free"); + if(name != NULL) { + if (name->d.dNSName != NULL) { + wolfSSL_ASN1_STRING_free(name->d.dNSName); + } + if (name->d.uniformResourceIdentifier != NULL) { + wolfSSL_ASN1_STRING_free(name->d.uniformResourceIdentifier); + } + if (name->d.iPAddress != NULL) { + wolfSSL_ASN1_STRING_free(name->d.iPAddress); + } + if (name->d.registeredID != NULL) { + wolfSSL_ASN1_OBJECT_free(name->d.registeredID); + } + XFREE(name, NULL, DYNAMIC_TYPE_OPENSSL); + } +} + #endif /* OPENSSL_EXTRA */ #ifndef NO_FILESYSTEM @@ -16330,7 +16475,7 @@ void wolfSSL_sk_ASN1_OBJECT_free(WOLF_STACK_OF(WOLFSSL_ASN1_OBJECT)* sk) /* parse through stack freeing each node */ node = sk->next; - while (sk->num > 1) { + while ((node != NULL) && (sk->num > 1)) { WOLFSSL_STACK* tmp = node; node = node->next; @@ -16346,6 +16491,45 @@ void wolfSSL_sk_ASN1_OBJECT_free(WOLF_STACK_OF(WOLFSSL_ASN1_OBJECT)* sk) XFREE(sk, NULL, DYNAMIC_TYPE_ASN1); } +/* Free's all nodes in ASN1_OBJECT stack. + * This is different then wolfSSL_ASN1_OBJECT_free in that it allows for + * choosing the function to use when freeing an ASN1_OBJECT stack. + * + * sk stack to free nodes in + * f X509 free function + */ +void wolfSSL_sk_ASN1_OBJECT_pop_free(WOLF_STACK_OF(WOLFSSL_ASN1_OBJECT)* sk, + void (*func)(WOLFSSL_ASN1_OBJECT*)) +{ + WOLFSSL_STACK* node; + + WOLFSSL_ENTER("wolfSSL_sk_ASN1_OBJECT_pop_free"); + (void)func; + + if ((sk == NULL) || (func == NULL)) { + WOLFSSL_MSG("Parameter error"); + return; + } + + /* parse through stack freeing each node */ + node = sk->next; + while ((node != NULL) && (sk->num > 1)) { + WOLFSSL_STACK* tmp = node; + node = node->next; + + func(tmp->data.obj); + + XFREE(tmp, NULL, DYNAMIC_TYPE_ASN1); + sk->num -= 1; + } + + /* free head of stack */ + if (sk->num == 1) { + func(sk->data.obj); + } + XFREE(sk, NULL, DYNAMIC_TYPE_ASN1); +} + int wolfSSL_ASN1_STRING_to_UTF8(unsigned char **out, WOLFSSL_ASN1_STRING *in) { /* @@ -16574,6 +16758,32 @@ const char* wolfSSL_get_cipher_name_from_suite(const byte cipherSuite0, return GetCipherNameInternal(cipherSuite0, cipherSuite); } +#if defined(OPENSSL_ALL) +/* Free the structure for WOLFSSL_CIPHER stack + * + * sk stack to free nodes in + */ +void wolfSSL_sk_CIPHER_free(WOLF_STACK_OF(WOLFSSL_CIPHER)* sk) +{ + WOLFSSL_STACK* node; + WOLFSSL_STACK* tmp; + WOLFSSL_ENTER("wolfSSL_sk_CIPHER_free"); + + if (sk == NULL) + return; + + /* parse through stack freeing each node */ + node = sk->next; + while (node) { + tmp = node; + node = node->next; + XFREE(tmp, NULL, DYNAMIC_TYPE_OPENSSL); + } + + /* free head of stack */ + XFREE(sk, NULL, DYNAMIC_TYPE_ASN1); +} +#endif #if defined(HAVE_ECC) || !defined(NO_DH) #ifdef HAVE_FFDHE @@ -16924,6 +17134,77 @@ WOLFSSL_EVP_PKEY* wolfSSL_X509_get_pubkey(WOLFSSL_X509* x509) * size of this subset and its memory usage */ #endif /* OPENSSL_EXTRA_X509_SMALL */ +#if defined(OPENSSL_ALL) +/* Takes two WOLFSSL_X509* certificates and performs a Sha hash of each, if the + * has values are the same, then it will do an XMEMCMP to confirm they are + * identical. Returns a 0 when certificates match, returns a negative number + * when certificates are not a match. +*/ +int wolfSSL_X509_cmp(const WOLFSSL_X509 *a, const WOLFSSL_X509 *b) +{ + const byte* derA; + const byte* derB; + int retHashA; + int retHashB; + int outSzA = 0; + int outSzB = 0; + + #ifdef WOLFSSL_PIC32MZ_HASH + byte digestA[PIC32_DIGEST_SIZE]; + byte digestB[PIC32_DIGEST_SIZE]; + #else + byte digestA[WC_SHA_DIGEST_SIZE]; + byte digestB[WC_SHA_DIGEST_SIZE]; + #endif + + if (a == NULL || b == NULL){ + return BAD_FUNC_ARG; + } + + derA = wolfSSL_X509_get_der((WOLFSSL_X509*)a, &outSzA); + if(derA == NULL){ + WOLFSSL_MSG("wolfSSL_X509_get_der - certificate A has failed"); + return WOLFSSL_FATAL_ERROR; + } + derB = wolfSSL_X509_get_der((WOLFSSL_X509*)b, &outSzB); + if(derB == NULL){ + WOLFSSL_MSG("wolfSSL_X509_get_der - certificate B has failed"); + return WOLFSSL_FATAL_ERROR; + } + + retHashA = wc_ShaHash(derA, (word32)outSzA, digestA); + if(retHashA != 0){ + WOLFSSL_MSG("Hash of certificate A has failed"); + return WOLFSSL_FATAL_ERROR; + } + retHashB = wc_ShaHash(derB, (word32)outSzB, digestB); + if(retHashB != 0){ + WOLFSSL_MSG("Hash of certificate B has failed"); + return WOLFSSL_FATAL_ERROR; + } + + if (outSzA == outSzB){ + #ifdef WOLFSSL_PIC32MZ_HASH + if(XMEMCMP(digestA, digestB, PIC32_DIGEST_SIZE) != 0){ + return WOLFSSL_FATAL_ERROR; + } + #else + if(XMEMCMP(digestA, digestB, WC_SHA_DIGEST_SIZE) != 0){ + return WOLFSSL_FATAL_ERROR; + } + #endif + else{ + WOLFSSL_LEAVE("wolfSSL_X509_cmp", 0); + return 0; + } + } + else{ + WOLFSSL_LEAVE("wolfSSL_X509_cmp", WOLFSSL_FATAL_ERROR); + return WOLFSSL_FATAL_ERROR; + } + } +#endif + #if defined(OPENSSL_EXTRA) #if !defined(NO_CERTS) int wolfSSL_X509_ext_isSet_by_NID(WOLFSSL_X509* x509, int nid) @@ -19221,6 +19502,89 @@ WOLFSSL_STACK* wolfSSL_X509_STORE_CTX_get_chain(WOLFSSL_X509_STORE_CTX* ctx) } +/* make shallow copy of the stack, data pointers are copied by reference */ +WOLFSSL_STACK* wolfSSL_sk_X509_dup(WOLFSSL_STACK* sk) +{ + unsigned long i; + WOLFSSL_STACK* dup = NULL; + WOLFSSL_STACK* node = NULL; + WOLFSSL_STACK *dIdx = NULL, *sIdx = sk; + + if (sk == NULL) { + return NULL; + } + + for (i = 0; i < sk->num; i++) { + + node = (WOLFSSL_STACK*)XMALLOC(sizeof(WOLFSSL_STACK), NULL, + DYNAMIC_TYPE_X509); + if (node == NULL) { + if (i != 0) { + wolfSSL_sk_free(dup); + } + WOLFSSL_MSG("Memory error"); + return NULL; + } + XMEMSET(node, 0, sizeof(WOLFSSL_STACK)); + + /* copy sk node to new node, data by reference */ + node->data.x509 = sIdx->data.x509; + node->num = sIdx->num; + + /* insert node into list, progress idx */ + if (i == 0) { + dup = node; + } else { + dIdx->next = node; + } + + dIdx = node; + sIdx = sIdx->next; + } + + return dup; +} + + +/* like X509_STORE_CTX_get_chain(), but return a copy with data reference + counts increased */ +WOLFSSL_STACK* wolfSSL_X509_STORE_CTX_get1_chain(WOLFSSL_X509_STORE_CTX* ctx) +{ + unsigned long i; + WOLFSSL_STACK* ref; + WOLFSSL_STACK* dup; + + if (ctx == NULL) { + return NULL; + } + + /* get chain in ctx */ + ref = wolfSSL_X509_STORE_CTX_get_chain(ctx); + if (ref == NULL) { + return ref; + } + + /* create duplicate of ctx chain */ + dup = wolfSSL_sk_X509_dup(ref); + if (dup == NULL) { + return NULL; + } + + /* increase ref counts of inner data X509 */ + ref = dup; + for (i = 0; i < dup->num && ref != NULL; i++) { + if (wc_LockMutex(&ref->data.x509->refMutex) != 0) { + WOLFSSL_MSG("Failed to lock x509 mutex"); + } + ref->data.x509->refCount++; + wc_UnLockMutex(&ref->data.x509->refMutex); + ref = ref->next; + } + + return dup; +} + + int wolfSSL_X509_STORE_add_cert(WOLFSSL_X509_STORE* store, WOLFSSL_X509* x509) { int result = WOLFSSL_FATAL_ERROR; @@ -22464,6 +22828,102 @@ void* wolfSSL_sk_value(WOLF_STACK_OF(WOLFSSL_ASN1_OBJECT)* sk, int i) return (void*)sk->data.obj; } + +/* Free the structure for ASN1_OBJECT stack */ +void wolfSSL_sk_free(WOLFSSL_STACK* sk) +{ + WOLFSSL_ENTER("wolfSSL_sk_free"); + + if (sk == NULL) { + WOLFSSL_MSG("Error, BAD_FUNC_ARG"); + return; + } + + switch (sk->type) { + #if defined(WOLFSSL_QT) || defined(OPENSSL_ALL) + case STACK_TYPE_X509: + wolfSSL_sk_X509_free(sk); + break; + case STACK_TYPE_CIPHER: + wolfSSL_sk_CIPHER_free(sk); + break; + case STACK_TYPE_GEN_NAME: + wolfSSL_sk_ASN1_OBJECT_free(sk); + break; + case STACK_TYPE_ACCESS_DESCRIPTION: + wolfSSL_sk_ACCESS_DESCRIPTION_pop_free(sk,NULL); + break; + case STACK_TYPE_OBJ: + wolfSSL_sk_ASN1_OBJECT_free(sk); + break; + case STACK_TYPE_NULL: + wolfSSL_sk_GENERIC_free(sk); + break; + #endif + default: + wolfSSL_sk_ASN1_OBJECT_free(sk); + } +} +/* Frees each node in the stack and frees the stack. + * Does not free any internal members of the stack nodes. + */ +void wolfSSL_sk_GENERIC_free(WOLFSSL_STACK* sk) +{ + WOLFSSL_STACK* node; + WOLFSSL_STACK* tmp; + WOLFSSL_ENTER("wolfSSL_sk_GENERIC_free"); + + if (sk == NULL) + return; + + /* parse through stack freeing each node */ + node = sk->next; + while (node) { + tmp = node; + node = node->next; + XFREE(tmp, NULL, DYNAMIC_TYPE_OPENSSL); + } + + /* free head of stack */ + XFREE(sk, NULL, DYNAMIC_TYPE_ASN1); +} + + +/* Free all nodes in a stack */ +void wolfSSL_sk_pop_free(WOLF_STACK_OF(WOLFSSL_ASN1_OBJECT)* sk, + wolfSSL_sk_freefunc func) +{ + int type; + WOLFSSL_ENTER("wolfSSL_sk_pop_free"); + + if (sk == NULL) { + WOLFSSL_MSG("Error, BAD_FUNC_ARG"); + return; + } + type = sk->type; + switch(type) { + #if defined(OPENSSL_ALL) || defined(WOLFSSL_QT) + case STACK_TYPE_ACCESS_DESCRIPTION: + wolfSSL_sk_ACCESS_DESCRIPTION_pop_free(sk, + (void (*)(WOLFSSL_ACCESS_DESCRIPTION*))func); + break; + case STACK_TYPE_X509: + wolfSSL_sk_X509_pop_free(sk,(void (*)(WOLFSSL_X509*))func); + break; + case STACK_TYPE_OBJ: + wolfSSL_sk_ASN1_OBJECT_pop_free(sk, + (void (*)(WOLFSSL_ASN1_OBJECT*))func); + break; + case STACK_TYPE_GEN_NAME: + break; + #endif + default: + wolfSSL_sk_ASN1_OBJECT_pop_free(sk, + (void (*)(WOLFSSL_ASN1_OBJECT*))func); + break; + } +} + #endif /* OPENSSL_EXTRA */ #if defined(OPENSSL_EXTRA) || defined(HAVE_EXT_CACHE) diff --git a/tests/api.c b/tests/api.c index 5323dfe4f..390c7bf34 100644 --- a/tests/api.c +++ b/tests/api.c @@ -294,6 +294,7 @@ #endif #endif #ifdef OPENSSL_EXTRA + #include #include #include #include @@ -23085,6 +23086,75 @@ static void test_wolfSSL_AES_cbc_encrypt() } +static void test_wolfSSL_X509_get_ext_count(void) { +#if !defined(NO_FILESYSTEM) && defined (OPENSSL_ALL) + FILE* f; + WOLFSSL_X509* x509; + int ret = 0; + + AssertNotNull(f = fopen("./certs/server-cert.pem", "rb")); + AssertNotNull(x509 = wolfSSL_PEM_read_X509(f, NULL, NULL, NULL)); + fclose(f); + + printf(testingFmt, "wolfSSL_X509_get_ext_count() valid input"); + AssertIntEQ((ret = wolfSSL_X509_get_ext_count(x509)), 3); + printf(resultFmt, ret == 3 ? passed : failed); + + printf(testingFmt, "wolfSSL_X509_get_ext_count() NULL argument"); + AssertIntEQ((ret = wolfSSL_X509_get_ext_count(NULL)), WOLFSSL_FAILURE); + printf(resultFmt, ret == WOLFSSL_FAILURE ? passed : failed); + + wolfSSL_X509_free(x509); +#endif +} + +static void test_wolfSSL_X509_cmp(void){ +#if defined(OPENSSL_ALL) + FILE* file1; + FILE* file2; + WOLFSSL_X509* cert1; + WOLFSSL_X509* cert2; + int ret = 0; + + AssertNotNull(file1=fopen("./certs/server-cert.pem", "rb")); + AssertNotNull(file2=fopen("./certs/client-cert-3072.pem", "rb")); + + AssertNotNull(cert1 = wolfSSL_PEM_read_X509(file1, NULL, NULL, NULL)); + AssertNotNull(cert2 = wolfSSL_PEM_read_X509(file2, NULL, NULL, NULL)); + fclose(file1); + fclose(file2); + + printf(testingFmt, "wolfSSL_X509_cmp() testing matching certs"); + ret = wolfSSL_X509_cmp(cert1, cert1); + AssertIntEQ(0, wolfSSL_X509_cmp(cert1, cert1)); + printf(resultFmt, ret == 0 ? passed : failed); + + printf(testingFmt, "wolfSSL_X509_cmp() testing mismatched certs"); + ret = wolfSSL_X509_cmp(cert1, cert2); + AssertIntEQ(-1, wolfSSL_X509_cmp(cert1, cert2)); + printf(resultFmt, ret == -1 ? passed : failed); + + printf(testingFmt, "wolfSSL_X509_cmp() testing NULL, valid args"); + ret = wolfSSL_X509_cmp(NULL, cert2); + AssertIntEQ(BAD_FUNC_ARG, wolfSSL_X509_cmp(NULL, cert2)); + printf(resultFmt, ret == BAD_FUNC_ARG ? passed : failed); + + printf(testingFmt, "wolfSSL_X509_cmp() testing valid, NULL args"); + ret = wolfSSL_X509_cmp(cert1, NULL); + AssertIntEQ(BAD_FUNC_ARG, wolfSSL_X509_cmp(cert1, NULL)); + printf(resultFmt, ret == BAD_FUNC_ARG ? passed : failed); + + printf(testingFmt, "wolfSSL_X509_cmp() testing NULL, NULL args"); + ret = wolfSSL_X509_cmp(NULL, NULL); + AssertIntEQ(BAD_FUNC_ARG, wolfSSL_X509_cmp(NULL, NULL)); + printf(resultFmt, ret == BAD_FUNC_ARG ? passed : failed); + + wolfSSL_X509_free(cert1); + wolfSSL_X509_free(cert2); +#endif +} + + static void test_no_op_functions(void) { #if defined(OPENSSL_EXTRA) @@ -25443,6 +25513,10 @@ void ApiTest(void) test_wolfSSL_X509_get_version(); test_wolfSSL_X509_print(); test_wolfSSL_RSA_verify(); + + test_wolfSSL_X509_get_ext_count(); + test_wolfSSL_X509_cmp(); + /* test the no op functions for compatibility */ test_no_op_functions(); diff --git a/wolfssl/internal.h b/wolfssl/internal.h index 05e8c08fc..b8ea513e5 100644 --- a/wolfssl/internal.h +++ b/wolfssl/internal.h @@ -3395,6 +3395,16 @@ typedef struct Arrays { #define MAX_DATE_SZ 32 #endif +#define STACK_TYPE_X509 0 +#define STACK_TYPE_GEN_NAME 1 +#define STACK_TYPE_BIO 2 +#define STACK_TYPE_OBJ 3 +#define STACK_TYPE_STRING 4 +#define STACK_TYPE_CIPHER 5 +#define STACK_TYPE_ACCESS_DESCRIPTION 6 +#define STACK_TYPE_X509_EXT 7 +#define STACK_TYPE_NULL 8 + struct WOLFSSL_STACK { unsigned long num; /* number of nodes in stack * (safety measure for freeing and shortcut for count) */ @@ -3403,9 +3413,13 @@ struct WOLFSSL_STACK { WOLFSSL_X509_NAME* name; WOLFSSL_BIO* bio; WOLFSSL_ASN1_OBJECT* obj; + #if defined(OPENSSL_ALL) + WOLFSSL_ACCESS_DESCRIPTION* access; + #endif char* string; } data; WOLFSSL_STACK* next; + byte type; /* Identifies type of stack. */ }; @@ -3473,6 +3487,10 @@ struct WOLFSSL_X509 { char certPolicies[MAX_CERTPOL_NB][MAX_CERTPOL_SZ]; int certPoliciesNb; #endif /* WOLFSSL_CERT_EXT */ +#if defined(OPENSSL_EXTRA) || defined(OPENSSL_ALL) + wolfSSL_Mutex refMutex; /* ref count mutex */ + int refCount; /* reference count */ +#endif #if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL) #ifdef HAVE_EX_DATA void* ex_data[MAX_EX_DATA]; diff --git a/wolfssl/openssl/ssl.h b/wolfssl/openssl/ssl.h index 9dea8037d..10580376e 100644 --- a/wolfssl/openssl/ssl.h +++ b/wolfssl/openssl/ssl.h @@ -87,11 +87,7 @@ typedef WOLFSSL_ASN1_OBJECT ASN1_OBJECT; typedef WOLFSSL_ASN1_STRING ASN1_STRING; typedef WOLFSSL_dynlock_value CRYPTO_dynlock_value; typedef WOLFSSL_BUF_MEM BUF_MEM; - -/* GENERAL_NAME and BASIC_CONSTRAINTS structs may need implemented as - * compatibility layer expands. For now treating them as an ASN1_OBJECT */ -typedef WOLFSSL_ASN1_OBJECT GENERAL_NAME; -typedef WOLFSSL_ASN1_OBJECT BASIC_CONSTRAINTS; +typedef WOLFSSL_GENERAL_NAME GENERAL_NAME; #define ASN1_UTCTIME WOLFSSL_ASN1_TIME #define ASN1_GENERALIZEDTIME WOLFSSL_ASN1_TIME @@ -265,6 +261,11 @@ typedef WOLFSSL_X509_VERIFY_PARAM X509_VERIFY_PARAM; #define SSL_SESSION_get_master_key wolfSSL_SESSION_get_master_key #define SSL_SESSION_get_master_key_length wolfSSL_SESSION_get_master_key_length +#if defined(OPENSSL_ALL) + #define X509_cmp wolfSSL_X509_cmp + #define X509_get_ext_count wolfSSL_X509_get_ext_count +#endif + #define DSA_dup_DH wolfSSL_DSA_dup_DH #define i2d_X509_bio wolfSSL_i2d_X509_bio @@ -324,6 +325,7 @@ typedef WOLFSSL_X509_VERIFY_PARAM X509_VERIFY_PARAM; #define sk_X509_push wolfSSL_sk_X509_push #define sk_X509_pop wolfSSL_sk_X509_pop #define sk_X509_pop_free wolfSSL_sk_X509_pop_free +#define sk_X509_dup wolfSSL_sk_X509_dup #define sk_X509_free wolfSSL_sk_X509_free #define i2d_X509_NAME wolfSSL_i2d_X509_NAME @@ -366,6 +368,7 @@ typedef WOLFSSL_X509_VERIFY_PARAM X509_VERIFY_PARAM; #define X509_STORE_CTX_new wolfSSL_X509_STORE_CTX_new #define X509_STORE_CTX_free wolfSSL_X509_STORE_CTX_free #define X509_STORE_CTX_get_chain wolfSSL_X509_STORE_CTX_get_chain +#define X509_STORE_CTX_get1_chain wolfSSL_X509_STORE_CTX_get1_chain #define X509_STORE_CTX_get_error wolfSSL_X509_STORE_CTX_get_error #define X509_STORE_CTX_get_error_depth wolfSSL_X509_STORE_CTX_get_error_depth #define X509_STORE_CTX_init wolfSSL_X509_STORE_CTX_init @@ -852,7 +855,7 @@ typedef STACK_OF(WOLFSSL_ASN1_OBJECT) GENERAL_NAMES; #define SSL_SESSION_get_ex_new_index wolfSSL_SESSION_get_ex_new_index #define SSL_SESSION_get_id wolfSSL_SESSION_get_id #define sk_GENERAL_NAME_pop_free wolfSSL_sk_GENERAL_NAME_pop_free -#define GENERAL_NAME_free NULL +#define GENERAL_NAME_free wolfSSL_GENERAL_NAME_free #define SSL3_AL_FATAL 2 #define SSL_TLSEXT_ERR_OK 0 diff --git a/wolfssl/openssl/stack.h b/wolfssl/openssl/stack.h index 374c1fcda..d92baa820 100644 --- a/wolfssl/openssl/stack.h +++ b/wolfssl/openssl/stack.h @@ -1,2 +1,61 @@ -/* stack.h for openssl */ +/* stack.h + * + * Copyright (C) 2006-2019 wolfSSL Inc. + * + * This file is part of wolfSSL. + * + * wolfSSL is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * wolfSSL is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA + */ +/* stack.h for openSSL */ + +#ifndef WOLFSSL_STACK_H_ +#define WOLFSSL_STACK_H_ + +#ifdef __cplusplus + extern "C" { +#endif + +typedef void (*wolfSSL_sk_freefunc)(void *); + +WOLFSSL_API void wolfSSL_sk_free(WOLFSSL_STACK *); +WOLFSSL_API void wolfSSL_sk_GENERIC_free(WOLFSSL_STACK *); +WOLFSSL_API int wolfSSL_sk_GENERIC_push(WOLFSSL_STACK *sk, void *data); +WOLFSSL_API void wolfSSL_sk_pop_free(WOLFSSL_STACK *st, void (*func) (void *)); +WOLFSSL_API WOLFSSL_STACK *wolfSSL_sk_new_null(void); +WOLFSSL_API int wolfSSL_sk_push(WOLFSSL_STACK *st, const void *data); + +WOLFSSL_API +int wolfSSL_sk_CIPHER_push(WOLFSSL_STACK *st,WOLFSSL_CIPHER *cipher); +WOLFSSL_API +WOLFSSL_CIPHER* wolfSSL_sk_CIPHER_pop(WOLF_STACK_OF(WOLFSSL_CIPHER)* sk); +WOLFSSL_API WOLFSSL_STACK* wolfSSL_sk_new_cipher(void); + +#define OPENSSL_sk_free wolfSSL_sk_free +#define OPENSSL_sk_pop_free wolfSSL_sk_pop_free +#define OPENSSL_sk_new_null wolfSSL_sk_new_null +#define OPENSSL_sk_push wolfSSL_sk_push + +/* provides older OpenSSL API compatibility */ +#define sk_free OPENSSL_sk_free +#define sk_pop_free OPENSSL_sk_pop_free +#define sk_new_null OPENSSL_sk_new_null +#define sk_push OPENSSL_sk_push + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/wolfssl/openssl/x509v3.h b/wolfssl/openssl/x509v3.h index 77828a33b..09dde0b5f 100644 --- a/wolfssl/openssl/x509v3.h +++ b/wolfssl/openssl/x509v3.h @@ -1,2 +1,45 @@ -/* x509v3.h for openssl */ +/* x509v3.h + * + * Copyright (C) 2006-2019 wolfSSL Inc. + * + * This file is part of wolfSSL. + * + * wolfSSL is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * wolfSSL is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA + */ +/* x509v3.h for openSSL */ + +#ifndef WOLFSSL_x509v3_H +#define WOLFSSL_x509v3_H + +#include +#include + +#ifdef __cplusplus + extern "C" { +#endif + +struct WOLFSSL_ACCESS_DESCRIPTION { + WOLFSSL_ASN1_OBJECT *method; + WOLFSSL_GENERAL_NAME *location; +}; + +typedef struct WOLFSSL_ACCESS_DESCRIPTION ACCESS_DESCRIPTION; + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/wolfssl/ssl.h b/wolfssl/ssl.h index b6ae3d414..b124ecff6 100644 --- a/wolfssl/ssl.h +++ b/wolfssl/ssl.h @@ -179,6 +179,25 @@ typedef struct WOLFSSL_dynlock_value WOLFSSL_dynlock_value; typedef struct WOLFSSL_DH WOLFSSL_DH; typedef struct WOLFSSL_ASN1_BIT_STRING WOLFSSL_ASN1_BIT_STRING; +typedef struct WOLFSSL_GENERAL_NAME WOLFSSL_GENERAL_NAME; +typedef struct WOLFSSL_ACCESS_DESCRIPTION WOLFSSL_ACCESS_DESCRIPTION; + +#if defined(OPENSSL_ALL) || defined(OPENSSL_EXTRA) + +struct WOLFSSL_GENERAL_NAME { + int type; + struct { /* derefrenced */ + WOLFSSL_ASN1_STRING* rfc822Name; + WOLFSSL_ASN1_STRING* dNSName; + WOLFSSL_ASN1_STRING* uniformResourceIdentifier; + WOLFSSL_ASN1_STRING* iPAddress; + WOLFSSL_ASN1_OBJECT* registeredID; + WOLFSSL_ASN1_STRING* ia5; + } d; +}; + +#endif /* OPENSSL_ALL || OPENSSL_EXTRA*/ + #define WOLFSSL_ASN1_UTCTIME WOLFSSL_ASN1_TIME #define WOLFSSL_ASN1_GENERALIZEDTIME WOLFSSL_ASN1_TIME @@ -791,15 +810,22 @@ WOLFSSL_API const char* wolfSSL_ERR_reason_error_string(unsigned long); #include "wolfssl/wolfcrypt/asn.h" #endif +#if defined(OPENSSL_ALL) +WOLFSSL_API void wolfSSL_sk_ACCESS_DESCRIPTION_pop_free(WOLFSSL_STACK* sk, + void f (WOLFSSL_ACCESS_DESCRIPTION*)); +#endif /* defined(OPENSSL_ALL) */ + WOLFSSL_API int wolfSSL_sk_X509_push(WOLF_STACK_OF(WOLFSSL_X509_NAME)* sk, WOLFSSL_X509* x509); WOLFSSL_API WOLFSSL_X509* wolfSSL_sk_X509_pop(WOLF_STACK_OF(WOLFSSL_X509_NAME)* sk); +WOLFSSL_API WOLFSSL_STACK* wolfSSL_sk_X509_dup(WOLFSSL_STACK* sk); WOLFSSL_API void wolfSSL_sk_X509_free(WOLF_STACK_OF(WOLFSSL_X509_NAME)* sk); WOLFSSL_API WOLFSSL_ASN1_OBJECT* wolfSSL_sk_GENERAL_NAME_value( WOLFSSL_STACK* sk, int i); WOLFSSL_API int wolfSSL_sk_GENERAL_NAME_num(WOLFSSL_STACK* sk); WOLFSSL_API void wolfSSL_sk_GENERAL_NAME_pop_free(WOLFSSL_STACK* sk, - void f (WOLFSSL_ASN1_OBJECT*)); + void f (WOLFSSL_GENERAL_NAME*)); +WOLFSSL_API void wolfSSL_GENERAL_NAME_free(WOLFSSL_GENERAL_NAME* name); WOLFSSL_API WOLFSSL_ASN1_OBJECT* wolfSSL_ASN1_OBJECT_new(void); WOLFSSL_API void wolfSSL_ASN1_OBJECT_free(WOLFSSL_ASN1_OBJECT* obj); WOLFSSL_API int wolfSSL_sk_ASN1_OBJECT_push(WOLF_STACK_OF(WOLFSSL_ASN1_OBJEXT)* sk, @@ -807,6 +833,9 @@ WOLFSSL_API int wolfSSL_sk_ASN1_OBJECT_push(WOLF_STACK_OF(WOLFSSL_ASN1_OBJEXT)* WOLFSSL_API WOLFSSL_ASN1_OBJECT* wolfSSL_sk_ASN1_OBJECT_pop( WOLF_STACK_OF(WOLFSSL_ASN1_OBJECT)* sk); WOLFSSL_API void wolfSSL_sk_ASN1_OBJECT_free(WOLF_STACK_OF(WOLFSSL_ASN1_OBJECT)* sk); +WOLFSSL_API void wolfSSL_sk_ASN1_OBJECT_pop_free( + WOLF_STACK_OF(WOLFSSL_ASN1_OBJECT)* sk, + void (*func)(WOLFSSL_ASN1_OBJECT*)); WOLFSSL_API int wolfSSL_ASN1_STRING_to_UTF8(unsigned char **out, WOLFSSL_ASN1_STRING *in); WOLFSSL_API int wolfSSL_set_ex_data(WOLFSSL*, int, void*); @@ -829,6 +858,7 @@ WOLFSSL_API char* wolfSSL_CIPHER_description(const WOLFSSL_CIPHER*, char*, int); WOLFSSL_API const char* wolfSSL_CIPHER_get_name(const WOLFSSL_CIPHER* cipher); WOLFSSL_API const char* wolfSSL_SESSION_CIPHER_get_name(WOLFSSL_SESSION* session); WOLFSSL_API const char* wolfSSL_get_cipher(WOLFSSL*); +WOLFSSL_API void wolfSSL_sk_CIPHER_free(WOLF_STACK_OF(WOLFSSL_CIPHER)* sk); WOLFSSL_API WOLFSSL_SESSION* wolfSSL_get1_session(WOLFSSL* ssl); /* what's ref count */ @@ -986,6 +1016,8 @@ WOLFSSL_API int wolfSSL_X509_STORE_add_cert( WOLFSSL_X509_STORE*, WOLFSSL_X509*); WOLFSSL_API WOLFSSL_STACK* wolfSSL_X509_STORE_CTX_get_chain( WOLFSSL_X509_STORE_CTX* ctx); +WOLFSSL_API WOLFSSL_STACK* wolfSSL_X509_STORE_CTX_get1_chain( + WOLFSSL_X509_STORE_CTX* ctx); WOLFSSL_API int wolfSSL_X509_STORE_set_flags(WOLFSSL_X509_STORE* store, unsigned long flag); WOLFSSL_API int wolfSSL_X509_STORE_set_default_paths(WOLFSSL_X509_STORE*); @@ -2709,6 +2741,12 @@ WOLFSSL_API int wolfSSL_use_RSAPrivateKey_ASN1(WOLFSSL* ssl, unsigned char* der, #endif WOLFSSL_API int wolfSSL_CTX_use_PrivateKey_ASN1(int pri, WOLFSSL_CTX* ctx, unsigned char* der, long derSz); + +#if defined(OPENSSL_ALL) +WOLFSSL_API int wolfSSL_X509_cmp(const WOLFSSL_X509* a, const WOLFSSL_X509* b); +WOLFSSL_API int wolfSSL_X509_get_ext_count(const WOLFSSL_X509* passed_cert); +#endif + #endif /* NO_CERTS */ WOLFSSL_API WOLFSSL_DH *wolfSSL_DSA_dup_DH(const WOLFSSL_DSA *r);