From 48fa6a458ccfd68fb5f5c40aae4efb72934e2eb1 Mon Sep 17 00:00:00 2001 From: Eric Blankenhorn Date: Sun, 4 Aug 2019 14:20:42 -0500 Subject: [PATCH] Adding compatibility API phase 1 --- doc/dox_comments/header_files/ssl.h | 39 ++++++ src/ssl.c | 203 +++++++++++++++++++++++++++- tests/api.c | 170 +++++++++++++++++++++++ wolfcrypt/src/asn.c | 7 +- wolfcrypt/src/pkcs12.c | 163 +++++++++++++++++++++- wolfssl/openssl/ssl.h | 5 + wolfssl/ssl.h | 14 +- wolfssl/wolfcrypt/asn.h | 4 + wolfssl/wolfcrypt/pkcs12.h | 2 + 9 files changed, 598 insertions(+), 9 deletions(-) diff --git a/doc/dox_comments/header_files/ssl.h b/doc/dox_comments/header_files/ssl.h index 48aa0d50f..d0c6cb555 100644 --- a/doc/dox_comments/header_files/ssl.h +++ b/doc/dox_comments/header_files/ssl.h @@ -6123,6 +6123,45 @@ WOLFSSL_API int wolfSSL_connect_cert(WOLFSSL* ssl); WOLFSSL_API WC_PKCS12* wolfSSL_d2i_PKCS12_bio(WOLFSSL_BIO* bio, WC_PKCS12** pkcs12); +/*! + \ingroup openSSL + + \brief wolfSSL_i2d_PKCS12_bio (i2d_PKCS12_bio) copies in the cert + information from the structure WC_PKCS12 to WOLFSSL_BIO. + + \return 1 for success. + \return Failure 0. + + \param bio WOLFSSL_BIO structure to write PKCS12 buffer to. + \param pkcs12 WC_PKCS12 structure for PKCS12 structure as input. + + _Example_ + \code + WC_PKCS12 pkcs12; + FILE *f; + byte buffer[5300]; + char file[] = "./test.p12"; + int bytes; + WOLFSSL_BIO* bio; + pkcs12 = wc_PKCS12_new(); + f = fopen(file, "rb"); + bytes = (int)fread(buffer, 1, sizeof(buffer), f); + fclose(f); + //convert the DER file into an internal structure + wc_d2i_PKCS12(buffer, bytes, pkcs12); + bio = wolfSSL_BIO_new(wolfSSL_BIO_s_mem()); + //convert PKCS12 structure into bio + wolfSSL_i2d_PKCS12_bio(bio, pkcs12); + wc_PKCS12_free(pkcs) + //use bio + \endcode + + \sa wolfSSL_PKCS12_parse + \sa wc_PKCS12_free +*/ +WOLFSSL_API WC_PKCS12* wolfSSL_i2d_PKCS12_bio(WOLFSSL_BIO* bio, + WC_PKCS12* pkcs12); + /*! \ingroup openSSL diff --git a/src/ssl.c b/src/ssl.c index 5a00c7c66..119308ec7 100644 --- a/src/ssl.c +++ b/src/ssl.c @@ -18709,6 +18709,39 @@ WC_PKCS12* wolfSSL_d2i_PKCS12_bio(WOLFSSL_BIO* bio, WC_PKCS12** pkcs12) } +/* Converts the PKCS12 to DER format and outputs it into bio. + * + * bio is the structure to hold output DER + * pkcs12 structure to create DER from + * + * return 1 for success or 0 if an error occurs + */ +int wolfSSL_i2d_PKCS12_bio(WOLFSSL_BIO *bio, WC_PKCS12 *pkcs12) +{ + int ret = WOLFSSL_FAILURE; + + WOLFSSL_ENTER("wolfSSL_i2d_PKCS12_bio"); + + if ((bio != NULL) && (pkcs12 != NULL)) { + word32 certSz = 0; + byte *certDer = NULL; + + certSz = wc_i2d_PKCS12(pkcs12, &certDer); + if ((certSz > 0) && (certDer != NULL)) { + if (wolfSSL_BIO_write(bio, certDer, certSz) == (int)certSz) { + ret = SSL_SUCCESS; + } + } + + if (certDer != NULL) { + XFREE(certDer, NULL, DYNAMIC_TYPE_PKCS); + } + } + + return ret; +} + + /* helper function to get DER buffer from WOLFSSL_EVP_PKEY */ static int wolfSSL_i2d_PrivateKey(WOLFSSL_EVP_PKEY* key, unsigned char** der) { @@ -18718,7 +18751,6 @@ static int wolfSSL_i2d_PrivateKey(WOLFSSL_EVP_PKEY* key, unsigned char** der) } - /* Creates a new WC_PKCS12 structure * * pass password to use @@ -19789,6 +19821,36 @@ WOLFSSL_X509_VERIFY_PARAM* wolfSSL_get0_param(WOLFSSL* ssl) return ssl->param; } +/* Set the host flag in the X509_VERIFY_PARAM structure */ +void wolfSSL_X509_VERIFY_PARAM_set_hostflags(WOLFSSL_X509_VERIFY_PARAM* param, + unsigned int flags) +{ + if (param != NULL) { + param->hostFlags = flags; + } +} + +/* Sets the expected IP address to ipasc. + * + * param is a pointer to the X509_VERIFY_PARAM structure + * ipasc is a NULL-terminated string with N.N.N.N for IPv4 and + * HH:HH ... HH:HH for IPv6. + * + * return 1 for success and 0 for failure*/ +int wolfSSL_X509_VERIFY_PARAM_set1_ip_asc(WOLFSSL_X509_VERIFY_PARAM *param, + const char *ipasc) +{ + int ret = WOLFSSL_FAILURE; + + if (param != NULL) { + XSTRNCPY(param->ipasc, ipasc, WOLFSSL_MAX_IPSTR-1); + param->ipasc[WOLFSSL_MAX_IPSTR-1] = '\0'; + ret = WOLFSSL_SUCCESS; + } + + return ret; +} + #ifndef NO_WOLFSSL_STUB void wolfSSL_X509_OBJECT_free_contents(WOLFSSL_X509_OBJECT* obj) { @@ -19806,6 +19868,85 @@ int wolfSSL_X509_cmp_current_time(const WOLFSSL_ASN1_TIME* asnTime) } #endif +/* return -1 if asnTime is earlier than or equal to cmpTime, and 1 otherwise + * return 0 on error + */ +int wolfSSL_X509_cmp_time(const WOLFSSL_ASN1_TIME* asnTime, time_t* cmpTime) +{ + int ret = WOLFSSL_FAILURE, i = 0; + time_t tmpTime, *pTime = &tmpTime; + byte data_ptr[MAX_TIME_STRING_SZ], inv = 0; + struct tm ts, *tmpTs = NULL, *ct; +#if defined(NEED_TMP_TIME) + /* for use with gmtime_r */ + struct tm tmpTimeStorage; + tmpTs = &tmpTimeStorage; +#else + (void)tmpTs; +#endif + + + if (asnTime != NULL) { + if (cmpTime == NULL) { + /* Use current time */ + *pTime = XTIME(0); + } + else { + pTime = cmpTime; + } + + /* Convert ASN1_time to time_t */ + XMEMSET(&ts, 0, sizeof(struct tm)); + + /* Check type */ + if (asnTime->data[0] == ASN_UTC_TIME) { + /* 2-digit year */ + i += 2; /* Skip type and size */ + XMEMCPY(data_ptr, &asnTime->data[i], ASN_UTC_TIME_SIZE); + ts.tm_year = (data_ptr[i] - '0') * 10; i++; + ts.tm_year += data_ptr[i] - '0'; i++; + if (ts.tm_year < 70) { + ts.tm_year += 100; + } + } + else if (asnTime->data[0] == ASN_GENERALIZED_TIME) { + /* 4-digit year */ + i += 2; /* Skip type and size */ + XMEMCPY(data_ptr, &asnTime->data[i], ASN_GENERALIZED_TIME_SIZE); + ts.tm_year = (data_ptr[i] - '0') * 1000; i++; + ts.tm_year += (data_ptr[i] - '0') * 100; i++; + ts.tm_year += (data_ptr[i] - '0') * 10; i++; + ts.tm_year += data_ptr[i] - '0'; i++; + ts.tm_year -= 1900; + } + else { + /* Invalid type */ + inv = 1; + } + + if (inv != 1) { + ts.tm_mon = (data_ptr[i] - '0') * 10; i++; + ts.tm_mon += (data_ptr[i] - '0') - 1; i++; /* January is 0 not 1 */ + ts.tm_mday = (data_ptr[i] - '0') * 10; i++; + ts.tm_mday += (data_ptr[i] - '0'); i++; + ts.tm_hour = (data_ptr[i] - '0') * 10; i++; + ts.tm_hour += (data_ptr[i] - '0'); i++; + ts.tm_min = (data_ptr[i] - '0') * 10; i++; + ts.tm_min += (data_ptr[i] - '0'); i++; + ts.tm_sec = (data_ptr[i] - '0') * 10; i++; + ts.tm_sec += (data_ptr[i] - '0'); + + /* Convert to time struct*/ + ct = XGMTIME(pTime, tmpTs); + + /* DAteGreaterThan returns 1 for >; 0 for <= */ + ret = DateGreaterThan(&ts, ct) ? 1 : -1; + } + } + + return ret; +} + #ifndef NO_WOLFSSL_STUB int wolfSSL_sk_X509_REVOKED_num(WOLFSSL_X509_REVOKED* revoked) { @@ -19867,6 +20008,65 @@ void wolfSSL_ASN1_INTEGER_free(WOLFSSL_ASN1_INTEGER* in) } +/* sets the value of WOLFSSL_ASN1_INTEGER a to the long value v. */ +int wolfSSL_ASN1_INTEGER_set(WOLFSSL_ASN1_INTEGER *a, long v) +{ + int ret = WOLFSSL_SUCCESS; /* return 1 for success and 0 for failure */ + int j; + unsigned int i = 0; + unsigned char tmp[sizeof(long)+1] = {0}; + + if (a != NULL) { + /* dynamically create data buffer, +2 for type and length */ + a->data = (unsigned char*)XMALLOC((sizeof(long)+1) + 2, NULL, + DYNAMIC_TYPE_OPENSSL); + if (a->data == NULL) { + wolfSSL_ASN1_INTEGER_free(a); + ret = WOLFSSL_FAILURE; + } + else { + a->dataMax = (int)(sizeof(long)+1) + 2; + a->isDynamic = 1; + } + } + else { + /* Invalid parameter */ + ret = WOLFSSL_FAILURE; + } + + + if (ret != WOLFSSL_FAILURE) { + /* Set type */ + a->data[i++] = ASN_INTEGER; + + /* Check for negative */ + if (v < 0) { + a->negative = 1; + v *= -1; + } + + /* Create char buffer */ + for (j = 0; j < (int)sizeof(long); j++) { + if (v == 0) { + break; + } + tmp[j] = (unsigned char)(v & 0xff); + v >>= 8; + } + + /* Set length */ + a->data[i++] = (unsigned char)((j == 0) ? ++j : j); + + /* Copy to data */ + for (; j > 0; j--) { + a->data[i++] = tmp[j-1]; + } + } + + return ret; +} + + WOLFSSL_ASN1_INTEGER* wolfSSL_X509_get_serialNumber(WOLFSSL_X509* x509) { WOLFSSL_ASN1_INTEGER* a; @@ -20070,7 +20270,6 @@ long wolfSSL_ASN1_INTEGER_get(const WOLFSSL_ASN1_INTEGER* i) } #endif - void* wolfSSL_X509_STORE_CTX_get_ex_data(WOLFSSL_X509_STORE_CTX* ctx, int idx) { WOLFSSL_ENTER("wolfSSL_X509_STORE_CTX_get_ex_data"); diff --git a/tests/api.c b/tests/api.c index 7cc0d1471..5323dfe4f 100644 --- a/tests/api.c +++ b/tests/api.c @@ -4358,6 +4358,27 @@ static void test_wolfSSL_PKCS12(void) PKCS12_free(pkcs12); #endif /* HAVE_ECC */ + /* Test i2d_PKCS12_bio */ + f = XFOPEN(file, "rb"); + AssertTrue((f != XBADFILE)); + AssertNotNull(pkcs12 = d2i_PKCS12_fp(f, NULL)); + XFCLOSE(f); + + bio = BIO_new(BIO_s_mem()); + AssertNotNull(bio); + + ret = i2d_PKCS12_bio(bio, pkcs12); + AssertIntEQ(ret, 1); + + ret = i2d_PKCS12_bio(NULL, pkcs12); + AssertIntEQ(ret, 0); + + ret = i2d_PKCS12_bio(bio, NULL); + AssertIntEQ(ret, 0); + + PKCS12_free(pkcs12); + BIO_free(bio); + (void)x509; (void)subject; (void)order; @@ -20627,6 +20648,31 @@ static void test_wolfSSL_ASN1_TIME_adj(void) } +static void test_wolfSSL_X509_cmp_time(void) +{ +#if defined(OPENSSL_EXTRA) && !defined(NO_ASN1_TIME) \ +&& !defined(USER_TIME) && !defined(TIME_OVERRIDES) + + printf(testingFmt, "wolfSSL_X509_cmp_time()"); + + WOLFSSL_ASN1_TIME asn_time; + time_t t; + + AssertIntEQ(0, wolfSSL_X509_cmp_time(NULL, &t)); + XMEMSET(&asn_time, 0, sizeof(WOLFSSL_ASN1_TIME)); + AssertIntEQ(0, wolfSSL_X509_cmp_time(&asn_time, &t)); + + asn_time.data[0] = ASN_UTC_TIME; + asn_time.data[1] = ASN_UTC_TIME_SIZE; + XMEMCPY(&asn_time.data[2], "000222211515Z", 13); + AssertIntEQ(-1, wolfSSL_X509_cmp_time(&asn_time, NULL)); + + + printf(resultFmt, passed); +#endif +} + + static void test_wolfSSL_X509(void) { #if defined(OPENSSL_EXTRA) && !defined(NO_CERTS) && !defined(NO_FILESYSTEM)\ @@ -20686,6 +20732,49 @@ static void test_wolfSSL_X509(void) } +static void test_wolfSSL_X509_VERIFY_PARAM(void) +{ +#if defined(OPENSSL_EXTRA) + WOLFSSL_X509_VERIFY_PARAM *param; + int ret; + char testIPv4[] = "127.0.0.1"; + char testIPv6[] = "0001:0000:0000:0000:0000:0000:0000:0000/32"; + + printf(testingFmt, "wolfSSL_X509()"); + + /* Initializer function is not ported */ + /* param = wolfSSL_X509_VERIFY_PARAM_new(); */ + + param = (WOLFSSL_X509_VERIFY_PARAM *)XMALLOC( + sizeof(WOLFSSL_X509_VERIFY_PARAM), NULL, DYNAMIC_TYPE_OPENSSL); + AssertNotNull(param); + + XMEMSET(param, 0, sizeof(WOLFSSL_X509_VERIFY_PARAM )); + + wolfSSL_X509_VERIFY_PARAM_set_hostflags(NULL, 0x00); + + wolfSSL_X509_VERIFY_PARAM_set_hostflags(param, 0x01); + AssertIntEQ(0x01, param->hostFlags); + + ret = wolfSSL_X509_VERIFY_PARAM_set1_ip_asc(NULL, testIPv4); + AssertIntEQ(0, ret); + + ret = wolfSSL_X509_VERIFY_PARAM_set1_ip_asc(param, testIPv4); + AssertIntEQ(1, ret); + AssertIntEQ(0, XSTRNCMP(param->ipasc, testIPv4, WOLFSSL_MAX_IPSTR)); + + ret = wolfSSL_X509_VERIFY_PARAM_set1_ip_asc(param, testIPv6); + AssertIntEQ(1, ret); + AssertIntEQ(0, XSTRNCMP(param->ipasc, testIPv6, WOLFSSL_MAX_IPSTR)); + + XFREE(param, NULL, DYNAMIC_TYPE_OPENSSL); + + printf(resultFmt, passed); + +#endif +} + + static void test_wolfSSL_RAND(void) { #if defined(OPENSSL_EXTRA) @@ -24791,6 +24880,84 @@ static void test_wolfSSL_X509_NAME_ENTRY_get_object() #endif } +static void test_wolfSSL_ASN1_INTEGER_set() +{ +#if defined(OPENSSL_EXTRA) && !defined(NO_ASN) + ASN1_INTEGER *a; + long val; + int ret; + + printf(testingFmt, "wolfSSL_ASN1_INTEGER_set"); + + a = wolfSSL_ASN1_INTEGER_new(); + val = 0; + ret = ASN1_INTEGER_set(NULL, val); + AssertIntEQ(ret, 0); + wolfSSL_ASN1_INTEGER_free(a); + + /* 0 */ + a = wolfSSL_ASN1_INTEGER_new(); + val = 0; + ret = ASN1_INTEGER_set(a, val); + AssertIntEQ(ret, 1); + wolfSSL_ASN1_INTEGER_free(a); + + /* 40 */ + a = wolfSSL_ASN1_INTEGER_new(); + val = 40; + ret = ASN1_INTEGER_set(a, val); + AssertIntEQ(ret, 1); + wolfSSL_ASN1_INTEGER_free(a); + + /* -40 */ + a = wolfSSL_ASN1_INTEGER_new(); + val = -40; + ret = ASN1_INTEGER_set(a, val); + AssertIntEQ(ret, 1); + AssertIntEQ(a->negative, 1); + wolfSSL_ASN1_INTEGER_free(a); + + /* 128 */ + a = wolfSSL_ASN1_INTEGER_new(); + val = 128; + ret = ASN1_INTEGER_set(a, val); + AssertIntEQ(ret, 1); + wolfSSL_ASN1_INTEGER_free(a); + + /* -128 */ + a = wolfSSL_ASN1_INTEGER_new(); + val = -128; + ret = ASN1_INTEGER_set(a, val); + AssertIntEQ(ret, 1); + AssertIntEQ(a->negative, 1); + wolfSSL_ASN1_INTEGER_free(a); + + /* 200 */ + a = wolfSSL_ASN1_INTEGER_new(); + val = 200; + ret = ASN1_INTEGER_set(a, val); + AssertIntEQ(ret, 1); + wolfSSL_ASN1_INTEGER_free(a); + + /* 2147483648 */ + a = wolfSSL_ASN1_INTEGER_new(); + val = 2147483648; + ret = ASN1_INTEGER_set(a, val); + AssertIntEQ(ret, 1); + wolfSSL_ASN1_INTEGER_free(a); + + /* -2147483648 */ + a = wolfSSL_ASN1_INTEGER_new(); + val = -2147483648; + ret = ASN1_INTEGER_set(a, val); + AssertIntEQ(a->negative, 1); + AssertIntEQ(ret, 1); + wolfSSL_ASN1_INTEGER_free(a); + + printf(resultFmt, passed); +#endif +} + static void test_wolfSSL_i2c_ASN1_INTEGER() { #if defined(OPENSSL_EXTRA) && !defined(NO_ASN) @@ -25218,10 +25385,12 @@ void ApiTest(void) test_wolfSSL_BIO(); test_wolfSSL_ASN1_STRING(); test_wolfSSL_X509(); + test_wolfSSL_X509_VERIFY_PARAM(); test_wolfSSL_RAND(); test_wolfSSL_BUF(); test_wolfSSL_set_tlsext_status_type(); test_wolfSSL_ASN1_TIME_adj(); + test_wolfSSL_X509_cmp_time(); test_wolfSSL_CTX_set_client_CA_list(); test_wolfSSL_CTX_add_client_CA(); test_wolfSSL_CTX_set_srp_username(); @@ -25258,6 +25427,7 @@ void ApiTest(void) test_wolfSSL_OpenSSL_add_all_algorithms(); test_wolfSSL_ASN1_STRING_print_ex(); test_wolfSSL_ASN1_TIME_to_generalizedtime(); + test_wolfSSL_ASN1_INTEGER_set(); test_wolfSSL_i2c_ASN1_INTEGER(); test_wolfSSL_X509_check_ca(); test_wolfSSL_DC_cert(); diff --git a/wolfcrypt/src/asn.c b/wolfcrypt/src/asn.c index 9e68151cb..45ea341bb 100644 --- a/wolfcrypt/src/asn.c +++ b/wolfcrypt/src/asn.c @@ -693,7 +693,7 @@ WOLFSSL_LOCAL int GetMyVersion(const byte* input, word32* inOutIdx, #ifndef NO_PWDBASED /* Get small count integer, 32 bits or less */ -int GetShortInt(const byte* input, word32* inOutIdx, int* number, word32 maxIdx) +WOLFSSL_LOCAL int GetShortInt(const byte* input, word32* inOutIdx, int* number, word32 maxIdx) { word32 idx = *inOutIdx; word32 len; @@ -726,8 +726,7 @@ int GetShortInt(const byte* input, word32* inOutIdx, int* number, word32 maxIdx) /* Set small integer, 32 bits or less. DER encoding with no leading 0s * returns total amount written including ASN tag and length byte on success */ -static int SetShortInt(byte* input, word32* inOutIdx, word32 number, - word32 maxIdx) +WOLFSSL_LOCAL int SetShortInt(byte* input, word32* inOutIdx, word32 number, word32 maxIdx) { word32 idx = *inOutIdx; word32 len = 0; @@ -5428,7 +5427,7 @@ int GetAsnTimeString(void* currTime, byte* buf, word32 len) #if defined(USE_WOLF_VALIDDATE) /* to the second */ -static int DateGreaterThan(const struct tm* a, const struct tm* b) +WOLFSSL_LOCAL int DateGreaterThan(const struct tm* a, const struct tm* b) { if (a->tm_year > b->tm_year) return 1; diff --git a/wolfcrypt/src/pkcs12.c b/wolfcrypt/src/pkcs12.c index d3877842b..08c5aacb4 100644 --- a/wolfcrypt/src/pkcs12.c +++ b/wolfcrypt/src/pkcs12.c @@ -629,7 +629,7 @@ int wc_d2i_PKCS12(const byte* der, word32 derSz, WC_PKCS12* pkcs12) printf("version = %d\n", version); #endif - if (version != 3) { + if (version != WC_PKCS12_VERSION_DEFAULT) { WOLFSSL_MSG("PKCS12 unsupported version!"); return ASN_VERSION_E; } @@ -670,6 +670,167 @@ int wc_d2i_PKCS12(const byte* der, word32 derSz, WC_PKCS12* pkcs12) return ret; } +/* Convert WC_PKCS12 struct to allocated DER buffer. + * pkcs12 : non-null pkcs12 pointer + * der : pointer-pointer to der buffer. If NULL space will be + * allocated for der, which must be freed by application. + * return size of DER on success and negative on failure. + */ +int wc_i2d_PKCS12(WC_PKCS12* pkcs12, byte** der) +{ + int ret = 0; + word32 seqSz, verSz, totalSz = 0, idx = 0, sdBufSz = 0; + byte *buf = NULL; + byte ver[MAX_VERSION_SZ]; + byte seq[MAX_SEQ_SZ]; + byte *sdBuf = NULL; + + if ((pkcs12 == NULL) || (pkcs12->safe == NULL) || (der == NULL)) { + ret = BAD_FUNC_ARG; + } + + /* Create the MAC portion */ + if ((ret == 0) && (pkcs12->signData != NULL)) { + MacData *mac = (MacData*)pkcs12->signData; + word32 aSz = (2 + (2 + 5) + (2)); + word32 bSz = (2 + mac->digestSz); + word32 cSz = (2 + mac->saltSz); + word32 dSz = (2 + sizeof(short int)); + word32 innerSz = aSz + bSz; + word32 outerSz = 2 + innerSz + cSz + dSz; + + sdBufSz = 2 + outerSz; + sdBuf = (byte*)XMALLOC(sdBufSz, pkcs12->heap, DYNAMIC_TYPE_PKCS); + if (sdBuf == NULL) { + ret = MEMORY_E; + } + + if (ret == 0) { + idx += SetSequence(outerSz, sdBuf); + idx += SetSequence(innerSz, &sdBuf[idx]); + + /* Set Algorithm Identifier */ + { + word32 algoIdSz; + + algoIdSz = SetAlgoID(mac->oid, &sdBuf[idx], oidHashType, 0); + if (algoIdSz == 0) { + ret = ALGO_ID_E; + } + else { + idx += algoIdSz; + } + } + } + + if (ret == 0) { + /* Octet string holding digest */ + sdBuf[idx++] = ASN_OCTET_STRING; + idx += SetLength(mac->digestSz, &sdBuf[idx]); + XMEMCPY(&sdBuf[idx], mac->digest, mac->digestSz); + idx += mac->digestSz; + + /* Set salt */ + sdBuf[idx++] = ASN_OCTET_STRING; + idx += SetLength(mac->saltSz, &sdBuf[idx]); + XMEMCPY(&sdBuf[idx], mac->salt, mac->saltSz); + idx += mac->saltSz; + + /* MAC iterations */ + { + int tmpSz; + word32 tmpIdx = 0; + byte ar[MAX_LENGTH_SZ + 2]; + tmpSz = SetShortInt(ar, &tmpIdx, mac->itt, MAX_LENGTH_SZ + 2); + XMEMCPY(&sdBuf[idx], ar, tmpSz); + } + + totalSz += sdBufSz; + } + } + + /* Calculate size of der */ + if (ret == 0) { + totalSz += pkcs12->safe->dataSz; + + totalSz += 4; /* Octet string */ + + totalSz += 4; /* Element */ + + totalSz += 2 + sizeof(WC_PKCS12_DATA_OID); + + totalSz += 4; /* Seq */ + + verSz = SetMyVersion(WC_PKCS12_VERSION_DEFAULT, ver, FALSE); + totalSz += verSz; + + seqSz = SetSequence(totalSz, seq); + totalSz += seqSz; + + if (*der == NULL) { + /* Allocate if requested */ + buf = (byte*)XMALLOC(totalSz, NULL, DYNAMIC_TYPE_PKCS); + if (buf == NULL) { + ret = MEMORY_E; + } + } + else { + buf = *der; + } + } + + if (ret == 0) { + idx = 0; + + /* Copy parts to buf */ + XMEMCPY(&buf[idx], seq, seqSz); + idx += seqSz; + + XMEMCPY(&buf[idx], ver, verSz); + idx += verSz; + + seqSz = SetSequence(totalSz - sdBufSz - idx - 4, seq); + XMEMCPY(&buf[idx], seq, seqSz); + idx += seqSz; + + /* OID */ + idx += SetObjectId(sizeof(WC_PKCS12_DATA_OID), &buf[idx]); + XMEMCPY(&buf[idx], WC_PKCS12_DATA_OID, sizeof(WC_PKCS12_DATA_OID)); + idx += sizeof(WC_PKCS12_DATA_OID); + + /* Element */ + buf[idx++] = 0xA0; + idx += SetLength(totalSz - sdBufSz - idx - 3, &buf[idx]); + + /* Octet string */ + idx += SetOctetString(totalSz - sdBufSz - idx - 4, &buf[idx]); + + XMEMCPY(&buf[idx], pkcs12->safe->data, pkcs12->safe->dataSz); + idx += pkcs12->safe->dataSz; + + if (pkcs12->signData != NULL) { + XMEMCPY(&buf[idx], sdBuf, sdBufSz); + } + + if (*der == NULL) { + /* Point to start of data allocated for DER */ + *der = buf; + } + else { + /* Increment pointer to byte past DER */ + *der = &buf[totalSz]; + } + + /* Return size of der */ + ret = totalSz; + } + + XFREE(sdBuf, pkcs12->heap, DYNAMIC_TYPE_PKCS); + /* Allocation of buf was the last time ret could be a failure, + * so no need to free here */ + + return ret; +} /* helper function to free WC_DerCertList */ void wc_FreeCertList(WC_DerCertList* list, void* heap) diff --git a/wolfssl/openssl/ssl.h b/wolfssl/openssl/ssl.h index 74501c3ca..9dea8037d 100644 --- a/wolfssl/openssl/ssl.h +++ b/wolfssl/openssl/ssl.h @@ -340,6 +340,7 @@ typedef WOLFSSL_X509_VERIFY_PARAM X509_VERIFY_PARAM; #define X509_NAME_print_ex wolfSSL_X509_NAME_print_ex #define X509_NAME_digest wolfSSL_X509_NAME_digest #define X509_cmp_current_time wolfSSL_X509_cmp_current_time +#define X509_cmp_time wolfSSL_X509_cmp_time #define sk_X509_NAME_pop_free wolfSSL_sk_X509_NAME_pop_free #define sk_X509_NAME_num wolfSSL_sk_X509_NAME_num @@ -381,7 +382,9 @@ typedef WOLFSSL_X509_VERIFY_PARAM X509_VERIFY_PARAM; #define X509_STORE_get_by_subject wolfSSL_X509_STORE_get_by_subject #define X509_STORE_CTX_get1_issuer wolfSSL_X509_STORE_CTX_get1_issuer #define X509_STORE_CTX_set_time wolfSSL_X509_STORE_CTX_set_time +#define X509_VERIFY_PARAM_set_hostflags wolfSSL_X509_VERIFY_PARAM_set_hostflags #define X509_VERIFY_PARAM_set1_host wolfSSL_X509_VERIFY_PARAM_set1_host +#define X509_VERIFY_PARAM_set1_ip_asc wolfSSL_X509_VERIFY_PARAM_set1_ip_asc #define X509_LOOKUP_add_dir wolfSSL_X509_LOOKUP_add_dir #define X509_LOOKUP_load_file wolfSSL_X509_LOOKUP_load_file @@ -478,6 +481,7 @@ typedef WOLFSSL_ASN1_BIT_STRING ASN1_BIT_STRING; #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_set wolfSSL_ASN1_INTEGER_set #define ASN1_INTEGER_to_BN wolfSSL_ASN1_INTEGER_to_BN #define ASN1_STRING_data wolfSSL_ASN1_STRING_data @@ -616,6 +620,7 @@ typedef WOLFSSL_ASN1_BIT_STRING ASN1_BIT_STRING; #define d2i_PKCS12_bio wolfSSL_d2i_PKCS12_bio #define d2i_PKCS12_fp wolfSSL_d2i_PKCS12_fp +#define i2d_PKCS12_bio wolfSSL_i2d_PKCS12_bio #define d2i_RSAPublicKey wolfSSL_d2i_RSAPublicKey #define d2i_RSAPrivateKey wolfSSL_d2i_RSAPrivateKey diff --git a/wolfssl/ssl.h b/wolfssl/ssl.h index 710b6942b..b6ae3d414 100644 --- a/wolfssl/ssl.h +++ b/wolfssl/ssl.h @@ -166,7 +166,7 @@ typedef struct WOLFSSL_X509_LOOKUP WOLFSSL_X509_LOOKUP; typedef struct WOLFSSL_X509_LOOKUP_METHOD WOLFSSL_X509_LOOKUP_METHOD; typedef struct WOLFSSL_CRL WOLFSSL_X509_CRL; typedef struct WOLFSSL_X509_STORE WOLFSSL_X509_STORE; -typedef struct WOLFSSL_X509_VERIFY_PARAM WOLFSSL_X509_VERIFY_PARAM; +typedef struct WOLFSSL_X509_VERIFY_PARAM WOLFSSL_X509_VERIFY_PARAM; typedef struct WOLFSSL_BIO WOLFSSL_BIO; typedef struct WOLFSSL_BIO_METHOD WOLFSSL_BIO_METHOD; typedef struct WOLFSSL_X509_EXTENSION WOLFSSL_X509_EXTENSION; @@ -319,10 +319,13 @@ struct WOLFSSL_X509_STORE { #define WOLFSSL_NO_CHECK_TIME 0x200000 #define WOLFSSL_NO_WILDCARDS 0x4 #define WOLFSSL_HOST_NAME_MAX 256 +#define WOLFSSL_MAX_IPSTR 46 /* max ip size IPv4 mapped IPv6 */ struct WOLFSSL_X509_VERIFY_PARAM { time_t check_time; unsigned long flags; char hostName[WOLFSSL_HOST_NAME_MAX]; + unsigned int hostFlags; + char ipasc[WOLFSSL_MAX_IPSTR]; }; #endif @@ -1013,15 +1016,20 @@ WOLFSSL_API WOLFSSL_EVP_PKEY* wolfSSL_d2i_PrivateKey_EVP(WOLFSSL_EVP_PKEY** key, WOLFSSL_API WOLFSSL_EVP_PKEY* wolfSSL_PKEY_new_ex(void* heap); WOLFSSL_API WOLFSSL_EVP_PKEY* wolfSSL_PKEY_new(void); WOLFSSL_API int wolfSSL_X509_cmp_current_time(const WOLFSSL_ASN1_TIME*); +WOLFSSL_API int wolfSSL_X509_cmp_time(const WOLFSSL_ASN1_TIME* asnTime, + time_t *cmpTime); WOLFSSL_API int wolfSSL_sk_X509_REVOKED_num(WOLFSSL_X509_REVOKED*); #ifdef OPENSSL_EXTRA WOLFSSL_API void wolfSSL_X509_STORE_CTX_set_time(WOLFSSL_X509_STORE_CTX*, unsigned long flags, time_t t); +WOLFSSL_API void wolfSSL_X509_VERIFY_PARAM_set_hostflags( + WOLFSSL_X509_VERIFY_PARAM* param, unsigned int flags); WOLFSSL_API int wolfSSL_X509_VERIFY_PARAM_set1_host(WOLFSSL_X509_VERIFY_PARAM* pParam, const char* name, unsigned int nameSz); - +WOLFSSL_API int wolfSSL_X509_VERIFY_PARAM_set1_ip_asc( + WOLFSSL_X509_VERIFY_PARAM *param, const char *ipasc); #endif WOLFSSL_API WOLFSSL_X509_REVOKED* wolfSSL_X509_CRL_get_REVOKED(WOLFSSL_X509_CRL*); WOLFSSL_API WOLFSSL_X509_REVOKED* wolfSSL_sk_X509_REVOKED_value( @@ -1029,6 +1037,7 @@ WOLFSSL_API WOLFSSL_X509_REVOKED* wolfSSL_sk_X509_REVOKED_value( 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_INTEGER_set(WOLFSSL_ASN1_INTEGER *a, long v); WOLFSSL_API int wolfSSL_ASN1_TIME_print(WOLFSSL_BIO*, const WOLFSSL_ASN1_TIME*); @@ -1657,6 +1666,7 @@ WOLFSSL_API int wolfSSL_connect_cert(WOLFSSL* ssl); typedef struct WC_PKCS12 WC_PKCS12; WOLFSSL_API WC_PKCS12* wolfSSL_d2i_PKCS12_bio(WOLFSSL_BIO* bio, WC_PKCS12** pkcs12); +WOLFSSL_API int wolfSSL_i2d_PKCS12_bio(WOLFSSL_BIO *bio, WC_PKCS12 *pkcs12); #ifndef NO_FILESYSTEM WOLFSSL_API WOLFSSL_X509_PKCS12* wolfSSL_d2i_PKCS12_fp(XFILE fp, WOLFSSL_X509_PKCS12** pkcs12); diff --git a/wolfssl/wolfcrypt/asn.h b/wolfssl/wolfcrypt/asn.h index 2714791a4..6bd669f8c 100644 --- a/wolfssl/wolfcrypt/asn.h +++ b/wolfssl/wolfcrypt/asn.h @@ -1005,6 +1005,7 @@ WOLFSSL_LOCAL int GetAsnTimeString(void* currTime, byte* buf, word32 len); #endif WOLFSSL_LOCAL int ExtractDate(const unsigned char* date, unsigned char format, wolfssl_tm* certTime, int* idx); +WOLFSSL_LOCAL int DateGreaterThan(const struct tm* a, const struct tm* b); WOLFSSL_LOCAL int ValidateDate(const byte* date, byte format, int dateType); WOLFSSL_LOCAL int wc_OBJ_sn2nid(const char *sn); @@ -1014,6 +1015,9 @@ WOLFSSL_ASN_API int SetName(byte* output, word32 outputSz, CertName* name); #endif WOLFSSL_LOCAL int GetShortInt(const byte* input, word32* inOutIdx, int* number, word32 maxIdx); +WOLFSSL_LOCAL int SetShortInt(byte* input, word32* inOutIdx, word32 number, + word32 maxIdx); + WOLFSSL_LOCAL char* GetSigName(int oid); WOLFSSL_LOCAL int GetLength(const byte* input, word32* inOutIdx, int* len, word32 maxIdx); diff --git a/wolfssl/wolfcrypt/pkcs12.h b/wolfssl/wolfcrypt/pkcs12.h index e19749b25..3e5750797 100644 --- a/wolfssl/wolfcrypt/pkcs12.h +++ b/wolfssl/wolfcrypt/pkcs12.h @@ -42,12 +42,14 @@ typedef struct WC_DerCertList { /* dereferenced in ssl.c */ /* default values for creating PKCS12 */ enum { WC_PKCS12_ITT_DEFAULT = 2048, + WC_PKCS12_VERSION_DEFAULT = 3, WC_PKCS12_MAC_DEFAULT = 1, }; WOLFSSL_API WC_PKCS12* wc_PKCS12_new(void); WOLFSSL_API void wc_PKCS12_free(WC_PKCS12* pkcs12); WOLFSSL_API int wc_d2i_PKCS12(const byte* der, word32 derSz, WC_PKCS12* pkcs12); +WOLFSSL_API int wc_i2d_PKCS12(WC_PKCS12* pkcs12, byte** der); WOLFSSL_API int wc_PKCS12_parse(WC_PKCS12* pkcs12, const char* psw, byte** pkey, word32* pkeySz, byte** cert, word32* certSz, WC_DerCertList** ca);