Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 9 additions & 4 deletions src/x509.c
Original file line number Diff line number Diff line change
Expand Up @@ -4582,6 +4582,9 @@ char* wolfSSL_X509_get_name_oneline(WOLFSSL_X509_NAME* name, char* in, int sz)
#endif


static WOLFSSL_X509* d2i_X509orX509REQ(WOLFSSL_X509** x509,
const byte* in, int len, int req, byte allowTrailing, void* heap);

/* Wraps wolfSSL_X509_d2i
*
* returns a WOLFSSL_X509 structure pointer on success and NULL on fail
Expand All @@ -4597,15 +4600,16 @@ WOLFSSL_X509* wolfSSL_d2i_X509(WOLFSSL_X509** x509, const unsigned char** in,
return NULL;
}

newX509 = wolfSSL_X509_d2i(x509, *in, len);
/* len only bounds the input; *in is advanced past this certificate. */
newX509 = d2i_X509orX509REQ(x509, *in, len, 0, 1, NULL);
if (newX509 != NULL) {
*in += newX509->derCert->length;
}
return newX509;
}

static WOLFSSL_X509* d2i_X509orX509REQ(WOLFSSL_X509** x509,
const byte* in, int len, int req, void* heap)
const byte* in, int len, int req, byte allowTrailing, void* heap)
{
WOLFSSL_X509 *newX509 = NULL;
int type = req ? CERTREQ_TYPE : CERT_TYPE;
Expand All @@ -4628,6 +4632,7 @@ static WOLFSSL_X509* d2i_X509orX509REQ(WOLFSSL_X509** x509,
#ifdef WOLFSSL_CERT_REQ
cert->isCSR = (byte)req;
#endif
cert->allowTrailing = allowTrailing;
#if defined(OPENSSL_EXTRA) || defined(OPENSSL_EXTRA_X509_SMALL)
/* CopyDecodedToX509() adds the name entries to the X509 directly. */
cert->noX509Name = 1;
Expand Down Expand Up @@ -4668,7 +4673,7 @@ int wolfSSL_X509_get_isCA(WOLFSSL_X509* x509)
WOLFSSL_X509* wolfSSL_X509_d2i_ex(WOLFSSL_X509** x509, const byte* in, int len,
void* heap)
{
return d2i_X509orX509REQ(x509, in, len, 0, heap);
return d2i_X509orX509REQ(x509, in, len, 0, 0, heap);
}

WOLFSSL_X509* wolfSSL_X509_d2i(WOLFSSL_X509** x509, const byte* in, int len)
Expand All @@ -4680,7 +4685,7 @@ WOLFSSL_X509* wolfSSL_X509_d2i(WOLFSSL_X509** x509, const byte* in, int len)
WOLFSSL_X509* wolfSSL_X509_REQ_d2i(WOLFSSL_X509** x509,
const unsigned char* in, int len)
{
return d2i_X509orX509REQ(x509, in, len, 1, NULL);
return d2i_X509orX509REQ(x509, in, len, 1, 0, NULL);
}

WOLFSSL_X509* wolfSSL_d2i_X509_REQ_INFO(WOLFSSL_X509** req,
Expand Down
64 changes: 64 additions & 0 deletions tests/api/test_ossl_x509_io.c
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,70 @@ int test_wolfSSL_i2d_X509(void)
return EXPECT_RESULT();
}

int test_wolfSSL_d2i_X509_concatenated(void)
{
EXPECT_DECLS;
#if defined(OPENSSL_EXTRA) && defined(USE_CERT_BUFFERS_2048) && !defined(NO_RSA)
const word32 srvSz = (word32)sizeof_server_cert_der_2048;
const word32 caSz = (word32)sizeof_ca_cert_der_2048;
const word32 junkSz = 8;
byte* buf = NULL;
const unsigned char* p = NULL;
const byte* der = NULL;
int derSz = 0;
X509* cert = NULL;

ExpectNotNull(buf = (byte*)XMALLOC(srvSz + caSz, NULL,
DYNAMIC_TYPE_TMP_BUFFER));
if (buf != NULL) {
XMEMCPY(buf, server_cert_der_2048, srvSz);
XMEMCPY(buf + srvSz, ca_cert_der_2048, caSz);
}

/* Each call decodes one certificate and advances past it only. */
p = buf;
ExpectNotNull(cert = d2i_X509(NULL, &p, (long)(srvSz + caSz)));
ExpectPtrEq(p, buf + srvSz);
ExpectNotNull(der = wolfSSL_X509_get_der(cert, &derSz));
ExpectIntEQ(derSz, (int)srvSz);
ExpectBufEQ(der, server_cert_der_2048, srvSz);
X509_free(cert);
cert = NULL;
ExpectNotNull(cert = d2i_X509(NULL, &p, (long)caSz));
ExpectPtrEq(p, buf + srvSz + caSz);
ExpectNotNull(der = wolfSSL_X509_get_der(cert, &derSz));
ExpectIntEQ(derSz, (int)caSz);
ExpectBufEQ(der, ca_cert_der_2048, caSz);
X509_free(cert);
cert = NULL;

/* A truncated certificate is rejected and the pointer is untouched. */
p = buf;
ExpectNull(d2i_X509(NULL, &p, (long)(srvSz - 1)));
ExpectPtrEq(p, buf);

/* Trailing junk is left for the caller and fails to decode on its own. */
if (buf != NULL) {
XMEMSET(buf + srvSz, 0xA5, junkSz);
}
p = buf;
ExpectNotNull(cert = d2i_X509(NULL, &p, (long)(srvSz + junkSz)));
ExpectPtrEq(p, buf + srvSz);
X509_free(cert);
cert = NULL;
ExpectNull(d2i_X509(NULL, &p, (long)junkSz));
ExpectPtrEq(p, buf + srvSz);

/* wolfSSL_X509_d2i() takes an exact length and still rejects junk. */
#ifndef WOLFSSL_NO_ASN_STRICT
ExpectNull(wolfSSL_X509_d2i(NULL, buf, (int)(srvSz + junkSz)));
#endif

XFREE(buf, NULL, DYNAMIC_TYPE_TMP_BUFFER);
#endif
return EXPECT_RESULT();
}

int test_wolfSSL_X509_get_der_length_guards(void)
{
EXPECT_DECLS;
Expand Down
3 changes: 3 additions & 0 deletions tests/api/test_ossl_x509_io.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,13 +25,16 @@
#include <tests/api/api_decl.h>

int test_wolfSSL_i2d_X509(void);
int test_wolfSSL_d2i_X509_concatenated(void);
int test_wolfSSL_X509_get_der_length_guards(void);
int test_wolfSSL_i2d_X509_der_length_guards(void);
int test_wolfSSL_PEM_read_X509(void);
int test_wolfSSL_PEM_write_bio_X509(void);

#define TEST_OSSL_X509_IO_DECLS \
TEST_DECL_GROUP("ossl_x509_io", test_wolfSSL_i2d_X509), \
TEST_DECL_GROUP("ossl_x509_io", \
test_wolfSSL_d2i_X509_concatenated), \
TEST_DECL_GROUP("ossl_x509_io", \
test_wolfSSL_X509_get_der_length_guards), \
TEST_DECL_GROUP("ossl_x509_io", \
Expand Down
Loading