Skip to content
17 changes: 17 additions & 0 deletions src/bio.c
Original file line number Diff line number Diff line change
Expand Up @@ -2119,6 +2119,23 @@ long wolfSSL_BIO_set_nbio(WOLFSSL_BIO* bio, long on)
return WOLFSSL_SUCCESS;
}

int wolfSSL_BIO_get_new_index(void)
{
static int bio_type_idx = WOLFSSL_BIO_TYPE_START;
int idx;

WOLFSSL_ENTER("wolfSSL_BIO_get_new_index");

idx = bio_type_idx;
if (idx > WOLFSSL_BIO_TYPE_MAX) {
WOLFSSL_MSG("BIO type index space exhausted");
return -1;
}
bio_type_idx++;
Comment thread
julek-wolfssl marked this conversation as resolved.

return idx;
}

/* creates a new custom WOLFSSL_BIO_METHOD */
WOLFSSL_BIO_METHOD *wolfSSL_BIO_meth_new(int type, const char *name)
{
Expand Down
43 changes: 27 additions & 16 deletions src/ssl.c
Original file line number Diff line number Diff line change
Expand Up @@ -5562,12 +5562,7 @@ size_t wolfSSL_get_client_random(const WOLFSSL* ssl, unsigned char* out,

const char* wolfSSLeay_version(int type)
{
(void)type;
#if defined(OPENSSL_VERSION_NUMBER) && OPENSSL_VERSION_NUMBER >= 0x10100000L
return wolfSSL_OpenSSL_version(type);
#else
return wolfSSL_OpenSSL_version();
#endif
}
#endif /* OPENSSL_EXTRA */

Expand Down Expand Up @@ -5899,19 +5894,35 @@ const char* wolfSSL_lib_version(void)
}

#ifdef OPENSSL_EXTRA
#if defined(OPENSSL_VERSION_NUMBER) && OPENSSL_VERSION_NUMBER >= 0x10100000L
const char* wolfSSL_OpenSSL_version(int a)
{
(void)a;
return "wolfSSL " LIBWOLFSSL_VERSION_STRING;
}
/* Signature deliberately does not depend on OPENSSL_VERSION_NUMBER. That macro
* can evaluate differently in the library and in the application (e.g. under
* OPENSSL_COEXIST the library also sees the real OpenSSL headers), which would
* make the caller and the definition disagree on the argument list. */
const char* wolfSSL_OpenSSL_version(int type)
{
WOLFSSL_ENTER("wolfSSL_OpenSSL_version");
switch (type) {
case OPENSSL_VERSION:
return "wolfSSL " LIBWOLFSSL_VERSION_STRING;
case OPENSSL_CFLAGS:
Comment thread
julek-wolfssl marked this conversation as resolved.
return "compiler: information not available";
case OPENSSL_BUILT_ON:
#ifdef HAVE_REPRODUCIBLE_BUILD
return "built on: date not available";
#else
const char* wolfSSL_OpenSSL_version(void)
{
return "wolfSSL " LIBWOLFSSL_VERSION_STRING;
return "built on: " __DATE__ " " __TIME__;
#endif
case OPENSSL_PLATFORM:
return "platform: information not available";
case OPENSSL_DIR:
return "OPENSSLDIR: N/A";
case OPENSSL_ENGINES_DIR:
return "ENGINESDIR: N/A";
default:
return "not available";
Comment thread
Roy-Carter marked this conversation as resolved.
}
}
#endif /* WOLFSSL_QT */
#endif
#endif /* OPENSSL_EXTRA */


/* current library version in hex */
Expand Down
105 changes: 99 additions & 6 deletions tests/api.c
Original file line number Diff line number Diff line change
Expand Up @@ -20119,6 +20119,73 @@ defined(OPENSSL_EXTRA) && defined(WOLFSSL_DH_EXTRA)
return EXPECT_RESULT();
}

static int test_wolfSSL_i2d_PUBKEY_bio(void)
{
EXPECT_DECLS;
/* Guards must match wolfSSL_i2d_PUBKEY_bio() in wolfcrypt/src/evp_pk.c. */
#if defined(OPENSSL_EXTRA) && !defined(WOLFCRYPT_ONLY) && \
!defined(NO_CERTS) && !defined(NO_BIO) && !defined(NO_ASN) && \
!defined(NO_PWDBASED)
BIO* bio = NULL;
EVP_PKEY* pkey = NULL;
EVP_PKEY* pkey2 = NULL;

/* NULL parameter tests */
ExpectIntEQ(wolfSSL_i2d_PUBKEY_bio(NULL, NULL), WOLFSSL_FAILURE);

#if defined(USE_CERT_BUFFERS_2048) && !defined(NO_RSA)
{
const unsigned char* p = client_keypub_der_2048;
/* Load an RSA public key from DER buffer */
ExpectNotNull(pkey = d2i_PUBKEY(NULL, &p,
sizeof_client_keypub_der_2048));

/* Write it to BIO */
ExpectNotNull(bio = BIO_new(BIO_s_mem()));
ExpectIntEQ(i2d_PUBKEY_bio(bio, pkey), WOLFSSL_SUCCESS);

/* Read it back and verify round-trip */
ExpectNotNull(pkey2 = d2i_PUBKEY_bio(bio, NULL));

EVP_PKEY_free(pkey2);
pkey2 = NULL;
EVP_PKEY_free(pkey);
pkey = NULL;
BIO_free(bio);
bio = NULL;
}
#endif

#if defined(USE_CERT_BUFFERS_256) && defined(HAVE_ECC)
{
const unsigned char* p = ecc_clikeypub_der_256;
/* Load an ECC public key from DER buffer */
ExpectNotNull(pkey = d2i_PUBKEY(NULL, &p,
sizeof_ecc_clikeypub_der_256));

/* Write it to BIO */
ExpectNotNull(bio = BIO_new(BIO_s_mem()));
ExpectIntEQ(i2d_PUBKEY_bio(bio, pkey), WOLFSSL_SUCCESS);

/* Read it back and verify round-trip */
ExpectNotNull(pkey2 = d2i_PUBKEY_bio(bio, NULL));

EVP_PKEY_free(pkey2);
pkey2 = NULL;
EVP_PKEY_free(pkey);
pkey = NULL;
BIO_free(bio);
bio = NULL;
}
#endif

(void)pkey;
(void)pkey2;
(void)bio;
#endif
return EXPECT_RESULT();
}

#if (defined(OPENSSL_ALL) || defined(WOLFSSL_ASIO)) && !defined(NO_RSA) && \
!defined(NO_TLS)
static int test_wolfSSL_d2i_PrivateKeys_bio(void)
Expand Down Expand Up @@ -30232,16 +30299,41 @@ static int test_wolfSSL_CTX_set_timeout(void)
static int test_wolfSSL_OpenSSL_version(void)
{
EXPECT_DECLS;
#if defined(OPENSSL_EXTRA)
#if defined(OPENSSL_EXTRA) && !defined(WOLFCRYPT_ONLY)
const char* ver;

#if defined(OPENSSL_VERSION_NUMBER) && OPENSSL_VERSION_NUMBER >= 0x10100000L
ExpectNotNull(ver = OpenSSL_version(0));
ExpectNotNull(ver = OpenSSL_version(OPENSSL_VERSION));
ExpectStrEQ(ver, "wolfSSL " LIBWOLFSSL_VERSION_STRING);

/* Test OPENSSL_CFLAGS type */
ExpectNotNull(ver = OpenSSL_version(OPENSSL_CFLAGS));
ExpectStrEQ(ver, "compiler: information not available");

/* Test OPENSSL_BUILT_ON type */
ExpectNotNull(ver = OpenSSL_version(OPENSSL_BUILT_ON));
#ifdef HAVE_REPRODUCIBLE_BUILD
ExpectStrEQ(ver, "built on: date not available");
#else
ExpectNotNull(ver = OpenSSL_version());
/* __DATE__/__TIME__ differ between translation units, so just check
* the prefix is present. */
ExpectNotNull(XSTRSTR(ver, "built on: "));
#endif
ExpectIntEQ(XMEMCMP(ver, "wolfSSL " LIBWOLFSSL_VERSION_STRING,
XSTRLEN("wolfSSL " LIBWOLFSSL_VERSION_STRING)), 0);

/* Test OPENSSL_PLATFORM type */
ExpectNotNull(ver = OpenSSL_version(OPENSSL_PLATFORM));
ExpectStrEQ(ver, "platform: information not available");

/* Test OPENSSL_DIR type */
ExpectNotNull(ver = OpenSSL_version(OPENSSL_DIR));
ExpectStrEQ(ver, "OPENSSLDIR: N/A");

/* Test OPENSSL_ENGINES_DIR type */
ExpectNotNull(ver = OpenSSL_version(OPENSSL_ENGINES_DIR));
ExpectStrEQ(ver, "ENGINESDIR: N/A");

/* Unknown selector returns the OpenSSL fallback string. */
ExpectNotNull(ver = OpenSSL_version(99));
ExpectStrEQ(ver, "not available");
#endif
return EXPECT_RESULT();
}
Expand Down Expand Up @@ -38210,6 +38302,7 @@ TEST_CASE testCases[] = {
TEST_DECL(test_wolfSSL_d2i_and_i2d_PublicKey_ecc),
#ifndef NO_BIO
TEST_DECL(test_wolfSSL_d2i_PUBKEY),
TEST_DECL(test_wolfSSL_i2d_PUBKEY_bio),
#if defined(OPENSSL_EXTRA) && defined(WOLFSSL_HAVE_MLDSA) && \
defined(WOLFSSL_MLDSA_NO_ASN1) && !defined(WOLFSSL_NO_ML_DSA_44) && \
!defined(WOLFSSL_NO_ML_DSA_65) && !defined(WOLFSSL_MLDSA_NO_VERIFY)
Expand Down
40 changes: 40 additions & 0 deletions tests/api/test_ossl_bio.c
Original file line number Diff line number Diff line change
Expand Up @@ -1899,5 +1899,45 @@ int test_wolfSSL_BIO_get_init(void)
return EXPECT_RESULT();
}

int test_wolfSSL_BIO_get_new_index(void)
{
EXPECT_DECLS;
#if defined(OPENSSL_EXTRA)
int idx1, idx2, idx3;
BIO_METHOD* meth = NULL;
BIO* bio = NULL;

/* Get three consecutive indices - should be unique and in valid range */
idx1 = BIO_get_new_index();
idx2 = BIO_get_new_index();
idx3 = BIO_get_new_index();

ExpectIntGE(idx1, BIO_TYPE_START);
ExpectIntLE(idx1, WOLFSSL_BIO_TYPE_MAX);
ExpectIntGE(idx2, BIO_TYPE_START);
ExpectIntLE(idx2, WOLFSSL_BIO_TYPE_MAX);
ExpectIntGE(idx3, BIO_TYPE_START);
ExpectIntLE(idx3, WOLFSSL_BIO_TYPE_MAX);

/* Each index must be unique */
ExpectIntNE(idx1, idx2);
ExpectIntNE(idx2, idx3);
ExpectIntNE(idx1, idx3);

/* Each consecutive call must return a strictly increasing value */
ExpectIntGT(idx2, idx1);
ExpectIntGT(idx3, idx2);

/* Use returned index with BIO_meth_new */
ExpectNotNull(meth = BIO_meth_new(idx1, "custom_test"));
ExpectNotNull(bio = BIO_new(meth));
ExpectIntEQ(BIO_method_type(bio), idx1);

BIO_free(bio);
BIO_meth_free(meth);
#endif
return EXPECT_RESULT();
}

#endif /* !NO_BIO */

4 changes: 3 additions & 1 deletion tests/api/test_ossl_bio.h
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ int test_wolfSSL_BIO_set_conn_hostname(void);
int test_wolfSSL_BIO_ctrl_pending_chain(void);
int test_wolfSSL_BIO_meth_type_large(void);
int test_wolfSSL_BIO_get_init(void);
int test_wolfSSL_BIO_get_new_index(void);

#define TEST_OSSL_BIO_DECLS \
TEST_DECL_GROUP("ossl_bio", test_wolfSSL_BIO_gets), \
Expand All @@ -70,7 +71,8 @@ int test_wolfSSL_BIO_get_init(void);
TEST_DECL_GROUP("ossl_bio", test_wolfSSL_BIO_set_conn_hostname), \
TEST_DECL_GROUP("ossl_bio", test_wolfSSL_BIO_ctrl_pending_chain), \
TEST_DECL_GROUP("ossl_bio", test_wolfSSL_BIO_meth_type_large), \
TEST_DECL_GROUP("ossl_bio", test_wolfSSL_BIO_get_init)
TEST_DECL_GROUP("ossl_bio", test_wolfSSL_BIO_get_init), \
TEST_DECL_GROUP("ossl_bio", test_wolfSSL_BIO_get_new_index)

#define TEST_OSSL_BIO_TLS_DECLS \
TEST_DECL_GROUP("ossl_bio_tls", test_wolfSSL_BIO_connect), \
Expand Down
53 changes: 53 additions & 0 deletions wolfcrypt/src/evp_pk.c
Original file line number Diff line number Diff line change
Expand Up @@ -2452,6 +2452,59 @@ int wolfSSL_i2d_PUBKEY(const WOLFSSL_EVP_PKEY *key, unsigned char **der)
{
return wolfSSL_i2d_PublicKey(key, der);
}

#ifndef NO_BIO
/* Encode public key as DER data and write to BIO.
*
* @param [in] bio BIO to write data to.
* @param [in] key Public key to encode.
* @return WOLFSSL_SUCCESS on success.
* @return WOLFSSL_FAILURE on failure.
*/
int wolfSSL_i2d_PUBKEY_bio(WOLFSSL_BIO* bio, WOLFSSL_EVP_PKEY* key)
{
int ret = WC_NO_ERR_TRACE(WOLFSSL_FAILURE);
int derSz = 0;
byte* der = NULL;
byte* derPtr = NULL;

WOLFSSL_ENTER("wolfSSL_i2d_PUBKEY_bio");

if (bio == NULL || key == NULL) {
return WOLFSSL_FAILURE;
}

derSz = wolfSSL_i2d_PUBKEY(key, NULL);
if (derSz <= 0) {
WOLFSSL_MSG("wolfSSL_i2d_PUBKEY size query failed");
return WOLFSSL_FAILURE;
}

der = (byte*)XMALLOC((size_t)derSz, NULL, DYNAMIC_TYPE_TMP_BUFFER);
if (der == NULL) {
WOLFSSL_MSG("XMALLOC failed");
return WOLFSSL_FAILURE;
}

derPtr = der;
derSz = wolfSSL_i2d_PUBKEY(key, &derPtr);
if (derSz <= 0) {
WOLFSSL_MSG("wolfSSL_i2d_PUBKEY failed");
goto cleanup;
}

if (wolfSSL_BIO_write(bio, der, derSz) != derSz) {
goto cleanup;
}

ret = WOLFSSL_SUCCESS;

cleanup:
XFREE(der, NULL, DYNAMIC_TYPE_TMP_BUFFER);
Comment thread
Roy-Carter marked this conversation as resolved.
return ret;
}
#endif /* !NO_BIO */

#endif /* !NO_ASN && !NO_PWDBASED */

#endif /* OPENSSL_EXTRA */
Expand Down
2 changes: 2 additions & 0 deletions wolfssl/openssl/bio.h
Original file line number Diff line number Diff line change
Expand Up @@ -138,6 +138,8 @@
#define BIO_TYPE_BIO WOLFSSL_BIO_BIO
#define BIO_TYPE_MEM WOLFSSL_BIO_MEMORY
#define BIO_TYPE_BASE64 WOLFSSL_BIO_BASE64
#define BIO_TYPE_START WOLFSSL_BIO_TYPE_START
#define BIO_get_new_index wolfSSL_BIO_get_new_index

#define BIO_vprintf wolfSSL_BIO_vprintf
#define BIO_printf wolfSSL_BIO_printf
Expand Down
15 changes: 15 additions & 0 deletions wolfssl/openssl/opensslv.h
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,21 @@
#ifndef OPENSSL_VERSION
#define OPENSSL_VERSION 0
#endif
#ifndef OPENSSL_CFLAGS
#define OPENSSL_CFLAGS 1
#endif
#ifndef OPENSSL_BUILT_ON
#define OPENSSL_BUILT_ON 2
#endif
#ifndef OPENSSL_PLATFORM
#define OPENSSL_PLATFORM 3
#endif
#ifndef OPENSSL_DIR
#define OPENSSL_DIR 4
#endif
#ifndef OPENSSL_ENGINES_DIR
#define OPENSSL_ENGINES_DIR 5
#endif

#ifndef OPENSSL_IS_WOLFSSL
#define OPENSSL_IS_WOLFSSL
Expand Down
5 changes: 1 addition & 4 deletions wolfssl/openssl/ssl.h
Original file line number Diff line number Diff line change
Expand Up @@ -273,6 +273,7 @@ typedef STACK_OF(ACCESS_DESCRIPTION) AUTHORITY_INFO_ACCESS;
#define SSL_CTX_set_ecdh_auto wolfSSL_CTX_set_ecdh_auto

#define i2d_PUBKEY wolfSSL_i2d_PUBKEY
#define i2d_PUBKEY_bio wolfSSL_i2d_PUBKEY_bio
#define i2d_X509_PUBKEY wolfSSL_i2d_X509_PUBKEY
#define d2i_PUBKEY wolfSSL_d2i_PUBKEY
#define d2i_PUBKEY_bio wolfSSL_d2i_PUBKEY_bio
Expand Down Expand Up @@ -1877,11 +1878,7 @@ typedef WOLFSSL_SRTP_PROTECTION_PROFILE SRTP_PROTECTION_PROFILE;
#define X509_OBJECT_new wolfSSL_X509_OBJECT_new
#define X509_OBJECT_free wolfSSL_X509_OBJECT_free
#define X509_OBJECT_get_type wolfSSL_X509_OBJECT_get_type
#if defined(OPENSSL_VERSION_NUMBER) && OPENSSL_VERSION_NUMBER >= 0x10100000L
#define OpenSSL_version(x) wolfSSL_OpenSSL_version(x)
#else
#define OpenSSL_version(x) wolfSSL_OpenSSL_version()
#endif

#define X509_OBJECT_retrieve_by_subject wolfSSL_X509_OBJECT_retrieve_by_subject

Expand Down
Loading
Loading