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
70 changes: 39 additions & 31 deletions src/x509.c
Original file line number Diff line number Diff line change
Expand Up @@ -11608,11 +11608,15 @@ int wolfSSL_X509_VERIFY_PARAM_set1_ip(WOLFSSL_X509_VERIFY_PARAM* param,
int ret = WC_NO_ERR_TRACE(WOLFSSL_FAILURE);
#ifndef NO_FILESYSTEM
char* buf = NULL;
char* p = NULL;
word32 val = 0;
int i;
int n;
int runStart = 0;
int runLen = 0;
int zeroStart = -1;
int zeroLen = 0;
size_t idx = 0;
const size_t max_ipv6_len = 40;
byte write_zero = 0;
#endif

/* sanity check */
Expand Down Expand Up @@ -11667,43 +11671,47 @@ int wolfSSL_X509_VERIFY_PARAM_set1_ip(WOLFSSL_X509_VERIFY_PARAM* param,
WOLFSSL_MSG("failed malloc");
return ret;
}
p = buf;
for (i = 0; i < 16; i += 2) {
val = (((word32)(ip[i]<<8)) | (ip[i+1])) & 0xFFFF;
if (val == 0) {
if (!write_zero) {
*p = ':';
/* RFC 5952 4.2: compress only the first longest run of two or more
* zero groups, every other zero group is written as 0. */
for (i = 0; i < 8; i++) {
if (ip[2 * i] == 0 && ip[2 * i + 1] == 0) {
if (runLen == 0)
runStart = i;
runLen++;
if (runLen > zeroLen) {
zeroStart = runStart;
zeroLen = runLen;
}
p++;
*p = '\0';
write_zero = 1;
}
else {
if (i != 0) {
*p++ = ':';
}
(void)XSNPRINTF(p, max_ipv6_len - (size_t)(p - buf), "%x", val);
runLen = 0;
}
}
if (zeroLen < 2) {
zeroStart = -1;
zeroLen = 0;
}

for (i = 0; i < 8 && buf != NULL; i++) {
if (i == zeroStart) {
n = XSNPRINTF(buf + idx, max_ipv6_len - idx, "::");
}
/* sanity check */
if (XSTRLEN(buf) > max_ipv6_len) {
else if (i > zeroStart && i < zeroStart + zeroLen) {
n = 0;
}
else {
val = ((word32)ip[2 * i] << 8) | ip[2 * i + 1];
n = XSNPRINTF(buf + idx, max_ipv6_len - idx, "%s%x",
(i == 0 || i == zeroStart + zeroLen) ? "" : ":",
(unsigned int)val);
}
if (n < 0 || (size_t)n >= max_ipv6_len - idx) {
WOLFSSL_MSG("The target ip address exceeds buffer length(40)");
XFREE(buf, NULL, DYNAMIC_TYPE_TMP_BUFFER);
buf = NULL;
break;
}
/* move the pointer to the last */
/* XSTRLEN includes NULL because of XSPRINTF use */
p = buf + (XSTRLEN(buf));
}
/* termination */
if (i == 16 && buf) {
p--;
if ((*p) == ':') {
/* when the last character is :, the following segments are zero
* Therefore, adding : and null termination */
p++;
*p++ = ':';
*p = '\0';
else {
idx += (size_t)n;
}
}
}
Expand Down
31 changes: 31 additions & 0 deletions tests/api/test_ossl_x509_vp.c
Original file line number Diff line number Diff line change
Expand Up @@ -250,6 +250,30 @@ int test_wolfSSL_X509_VERIFY_PARAM_set1_ip(void)
#if defined(OPENSSL_EXTRA) && !defined(NO_FILESYSTEM)
unsigned char buf[16] = {0};
WOLFSSL_X509_VERIFY_PARAM* param = NULL;
int i;
static const struct {
unsigned char ip[16];
const char* asc;
} ip6Tests[] = {
{ { 0x20,0x01, 0x0d,0xb8, 0,0, 0,1, 0,0, 0,0, 0,0, 0,5 },
"2001:db8:0:1::5" },
{ { 0x20,0x01, 0x0d,0xb8, 0,0, 0,1, 0,0, 0,0, 0,0, 0,0 },
"2001:db8:0:1::" },
{ { 0,1, 0,0, 0,0, 0,2, 0,0, 0,0, 0,0, 0,3 },
"1:0:0:2::3" },
{ { 0,0, 0,0, 0,0, 0,0, 0,1, 0,0, 0,0, 0,2 },
"::1:0:0:2" },
/* equal length runs compress the first one */
{ { 0,1, 0,0, 0,0, 0,2, 0,0, 0,0, 0,3, 0,4 },
"1::2:0:0:3:4" },
/* a single zero group is not compressed */
{ { 0x20,0x01, 0x0d,0xb8, 0,0, 0,1, 0,2, 0,3, 0,4, 0,5 },
"2001:db8:0:1:2:3:4:5" },
{ { 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 },
"::" },
{ { 0,0, 0,1, 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 },
"0:1::" }
};

ExpectNotNull(param = X509_VERIFY_PARAM_new());

Expand Down Expand Up @@ -318,6 +342,13 @@ int test_wolfSSL_X509_VERIFY_PARAM_set1_ip(void)
ExpectIntEQ(XSTRNCMP(param->ipasc, "2001:db8:1::ab9:c0a8:102",
sizeof(param->ipasc)), 0);

/* Addresses with more than one zero run must not drop the later runs */
for (i = 0; i < (int)(sizeof(ip6Tests) / sizeof(ip6Tests[0])); i++) {
ExpectIntEQ(X509_VERIFY_PARAM_set1_ip(param, ip6Tests[i].ip, 16),
SSL_SUCCESS);
ExpectStrEQ(param->ipasc, ip6Tests[i].asc);
}

XFREE(param, HEAP_HINT, DYNAMIC_TYPE_OPENSSL);
#endif /* OPENSSL_EXTRA */
return EXPECT_RESULT();
Expand Down
Loading