diff --git a/src/ssl.c b/src/ssl.c index 09b4d26c8..4abd03682 100644 --- a/src/ssl.c +++ b/src/ssl.c @@ -18109,6 +18109,37 @@ WOLFSSL_X509_REVOKED* wolfSSL_sk_X509_REVOKED_value( } #endif +/* Used to create a new WOLFSSL_ASN1_INTEGER structure. + * returns a pointer to new structure on success and NULL on failure + */ +WOLFSSL_ASN1_INTEGER* wolfSSL_ASN1_INTEGER_new(void) +{ + WOLFSSL_ASN1_INTEGER* a; + + a = (WOLFSSL_ASN1_INTEGER*)XMALLOC(sizeof(WOLFSSL_ASN1_INTEGER), NULL, + DYNAMIC_TYPE_OPENSSL); + if (a == NULL) { + return NULL; + } + + XMEMSET(a, 0, sizeof(WOLFSSL_ASN1_INTEGER)); + a->data = a->intData; + a->dataMax = WOLFSSL_ASN1_INTEGER_MAX; + return a; +} + + +/* free's internal elements of WOLFSSL_ASN1_INTEGER and free's "in" itself */ +void wolfSSL_ASN1_INTEGER_free(WOLFSSL_ASN1_INTEGER* in) +{ + if (in != NULL) { + if (in->isDynamic) { + XFREE(in->data, NULL, DYNAMIC_TYPE_OPENSSL); + } + XFREE(in, NULL, DYNAMIC_TYPE_OPENSSL); + } +} + WOLFSSL_ASN1_INTEGER* wolfSSL_X509_get_serialNumber(WOLFSSL_X509* x509) { @@ -18117,19 +18148,25 @@ WOLFSSL_ASN1_INTEGER* wolfSSL_X509_get_serialNumber(WOLFSSL_X509* x509) WOLFSSL_ENTER("wolfSSL_X509_get_serialNumber"); - a = (WOLFSSL_ASN1_INTEGER*)XMALLOC(sizeof(WOLFSSL_ASN1_INTEGER), NULL, - DYNAMIC_TYPE_OPENSSL); + a = wolfSSL_ASN1_INTEGER_new(); if (a == NULL) return NULL; /* Make sure there is space for the data, ASN.1 type and length. */ - if (x509->serialSz > (int)(sizeof(WOLFSSL_ASN1_INTEGER) - 2)) { - XFREE(a, NULL, DYNAMIC_TYPE_OPENSSL); - return NULL; + if (x509->serialSz > (WOLFSSL_ASN1_INTEGER_MAX - 2)) { + /* dynamicly create data buffer, +2 for type and length */ + a->data = (unsigned char*)XMALLOC(x509->serialSz + 2, NULL, + DYNAMIC_TYPE_OPENSSL); + if (a->data == NULL) { + wolfSSL_ASN1_INTEGER_free(a); + return NULL; + } + a->dataMax = x509->serialSz + 2; + a->isDynamic = 1; } a->data[i++] = ASN_INTEGER; - a->data[i++] = (unsigned char)x509->serialSz; + i += SetLength(x509->serialSz, a->data + i); XMEMCPY(&a->data[i], x509->serial, x509->serialSz); return a; @@ -22902,7 +22939,7 @@ WOLFSSL_BIGNUM *wolfSSL_ASN1_INTEGER_to_BN(const WOLFSSL_ASN1_INTEGER *ai, return NULL; } - if ((ret = GetInt(&mpi, ai->data, &idx, sizeof(ai->data))) != 0) { + if ((ret = GetInt(&mpi, ai->data, &idx, ai->dataMax)) != 0) { /* expecting ASN1 format for INTEGER */ WOLFSSL_LEAVE("wolfSSL_ASN1_INTEGER_to_BN", ret); return NULL; diff --git a/tests/api.c b/tests/api.c index 1698e4c57..37b1003b9 100644 --- a/tests/api.c +++ b/tests/api.c @@ -15991,7 +15991,7 @@ static void test_wolfSSL_BN(void) BIGNUM* b; BIGNUM* c; BIGNUM* d; - ASN1_INTEGER ai; + ASN1_INTEGER* ai; unsigned char value[1]; printf(testingFmt, "wolfSSL_BN()"); @@ -16002,12 +16002,14 @@ static void test_wolfSSL_BN(void) value[0] = 0x03; + AssertNotNull(ai = ASN1_INTEGER_new()); /* at the moment hard setting since no set function */ - ai.data[0] = 0x02; /* tag for ASN_INTEGER */ - ai.data[1] = 0x01; /* length of integer */ - ai.data[2] = value[0]; + ai->data[0] = 0x02; /* tag for ASN_INTEGER */ + ai->data[1] = 0x01; /* length of integer */ + ai->data[2] = value[0]; - AssertNotNull(a = ASN1_INTEGER_to_BN(&ai, NULL)); + AssertNotNull(a = ASN1_INTEGER_to_BN(ai, NULL)); + ASN1_INTEGER_free(ai); value[0] = 0x02; AssertNotNull(BN_bin2bn(value, sizeof(value), b)); @@ -17763,6 +17765,40 @@ static void test_wolfSSL_SHA256(void) #endif } +static void test_wolfSSL_X509_get_serialNumber(void) +{ +#if defined(OPENSSL_EXTRA) && !defined(NO_CERTS) && \ + !defined(NO_RSA) + ASN1_INTEGER* a; + BIGNUM* bn; + X509* x509; + + + printf(testingFmt, "wolfSSL_X509_get_serialNumber()"); + + AssertNotNull(x509 = wolfSSL_X509_load_certificate_file(svrCertFile, + SSL_FILETYPE_PEM)); + AssertNotNull(a = X509_get_serialNumber(x509)); + X509_free(x509); + + /* check on value of ASN1 Integer */ + AssertNotNull(bn = ASN1_INTEGER_to_BN(a, NULL)); + AssertIntEQ(BN_get_word(bn), 1); + + BN_free(bn); + ASN1_INTEGER_free(a); + + /* hard test free'ing with dynamic buffer to make sure there is no leaks */ + a = ASN1_INTEGER_new(); + AssertNotNull(a->data = (unsigned char*)XMALLOC(100, NULL, + DYNAMIC_TYPE_OPENSSL)); + a->isDynamic = 1; + ASN1_INTEGER_free(a); + + printf(resultFmt, passed); +#endif +} + static void test_no_op_functions(void) { #if defined(OPENSSL_EXTRA) @@ -18605,6 +18641,7 @@ void ApiTest(void) test_wolfSSL_DH_1536_prime(); test_wolfSSL_AES_ecb_encrypt(); test_wolfSSL_SHA256(); + test_wolfSSL_X509_get_serialNumber(); /* test the no op functions for compatibility */ test_no_op_functions(); diff --git a/wolfssl/openssl/ssl.h b/wolfssl/openssl/ssl.h index 365a5a6ff..e90a5213a 100644 --- a/wolfssl/openssl/ssl.h +++ b/wolfssl/openssl/ssl.h @@ -379,6 +379,8 @@ typedef WOLFSSL_X509_STORE_CTX X509_STORE_CTX; #define ASN1_GENERALIZEDTIME_print wolfSSL_ASN1_GENERALIZEDTIME_print #define ASN1_TIME_adj wolfSSL_ASN1_TIME_adj +#define ASN1_INTEGER_new wolfSSL_ASN1_INTEGER_new +#define ASN1_INTEGER_free wolfSSL_ASN1_INTEGER_free #define ASN1_INTEGER_cmp wolfSSL_ASN1_INTEGER_cmp #define ASN1_INTEGER_get wolfSSL_ASN1_INTEGER_get #define ASN1_INTEGER_to_BN wolfSSL_ASN1_INTEGER_to_BN diff --git a/wolfssl/ssl.h b/wolfssl/ssl.h index 3609c8201..813e8f324 100644 --- a/wolfssl/ssl.h +++ b/wolfssl/ssl.h @@ -182,11 +182,16 @@ typedef struct WOLFSSL_ASN1_BIT_STRING WOLFSSL_ASN1_BIT_STRING; #define WOLFSSL_ASN1_UTCTIME WOLFSSL_ASN1_TIME #define WOLFSSL_ASN1_GENERALIZEDTIME WOLFSSL_ASN1_TIME +#define WOLFSSL_ASN1_INTEGER_MAX 20 struct WOLFSSL_ASN1_INTEGER { /* size can be increased set at 20 for tag, length then to hold at least 16 * byte type */ - unsigned char data[20]; + unsigned char intData[WOLFSSL_ASN1_INTEGER_MAX]; /* ASN_INTEGER | LENGTH | hex of number */ + + unsigned char* data; + unsigned int dataMax; /* max size of data buffer */ + unsigned char isDynamic:1; /* flag for if data pointer dynamic (1 is yes 0 is no) */ }; struct WOLFSSL_ASN1_TIME { @@ -928,6 +933,8 @@ WOLFSSL_API WOLFSSL_X509_REVOKED* wolfSSL_X509_CRL_get_REVOKED(WOLFSSL_X509_CRL* WOLFSSL_API WOLFSSL_X509_REVOKED* wolfSSL_sk_X509_REVOKED_value( WOLFSSL_X509_REVOKED*,int); WOLFSSL_API WOLFSSL_ASN1_INTEGER* wolfSSL_X509_get_serialNumber(WOLFSSL_X509*); +WOLFSSL_API void wolfSSL_ASN1_INTEGER_free(WOLFSSL_ASN1_INTEGER*); +WOLFSSL_API WOLFSSL_ASN1_INTEGER* wolfSSL_ASN1_INTEGER_new(void); WOLFSSL_API int wolfSSL_ASN1_TIME_print(WOLFSSL_BIO*, const WOLFSSL_ASN1_TIME*);