Skip to content

Commit

Permalink
[Curl] Represent IPv6 addresses according to RFC 5952 addressing arch…
Browse files Browse the repository at this point in the history
…itecture

https://bugs.webkit.org/show_bug.cgi?id=244520

Reviewed by Alex Christensen.

Conform to RFC 5952, https://www.rfc-editor.org/rfc/rfc4291, when displaying certificate
information.

* Source/WebCore/platform/network/curl/OpenSSLHelper.cpp:
(OpenSSL::getSubjectAltName):
(OpenSSL::getIPv6):
* Source/WebCore/platform/network/curl/OpenSSLHelper.h:
* Tools/TestWebKitAPI/PlatformPlayStation.cmake:
* Tools/TestWebKitAPI/PlatformWin.cmake:
* Tools/TestWebKitAPI/Tests/WebCore/curl/OpenSSLHelperTests.cpp: Added.
(TestWebKitAPI::Curl::OpenSSLHelperTests::OpenSSLHelperTests):
(TestWebKitAPI::Curl::TEST):

Canonical link: https://commits.webkit.org/255147@main
  • Loading branch information
mokjasmine authored and donny-dont committed Oct 4, 2022
1 parent cbc5008 commit 8bec657
Show file tree
Hide file tree
Showing 5 changed files with 147 additions and 8 deletions.
61 changes: 53 additions & 8 deletions Source/WebCore/platform/network/curl/OpenSSLHelper.cpp
Expand Up @@ -301,19 +301,64 @@ static void getSubjectAltName(const X509* x509, Vector<String>& dnsNames, Vector
if (value->d.iPAddress->length == 4)
ipAddresses.append(makeString(data[0], ".", data[1], ".", data[2], ".", data[3]));
else if (value->d.iPAddress->length == 16) {
StringBuilder ipAddress;
for (int i = 0; i < 8; i++) {
ipAddress.append(makeString(hex(data[0] << 8 | data[1], 4)));
if (i != 7)
ipAddress.append(":");
data += 2;
}
ipAddresses.append(ipAddress.toString());
Span<uint8_t, 16> dataSpan { data, 16 };
ipAddresses.append(canonicalizeIPv6Address(dataSpan));
}
}
}
}

String canonicalizeIPv6Address(Span<uint8_t, 16> data)
{
bool compressCurrentSection = false;
size_t maxZeros = 0;
std::optional<size_t> startRunner;
std::optional<size_t> endRunner;
std::optional<size_t> start;
std::optional<size_t> end;

for (int i = 0; i < 8; i++) {
compressCurrentSection = !data[2 * i] && !data[2 * i + 1];
if (compressCurrentSection) {
startRunner = !startRunner.has_value() ? i : startRunner;
endRunner = i;
size_t len = endRunner.value() - startRunner.value() + 1;
if (len > maxZeros) {
start = startRunner;
end = endRunner;
maxZeros = len;
}
} else
startRunner.reset();
}

size_t minimum = 1;
StringBuilder ipAddress;
String oldSection = ""_s;
StringBuilder newSection;
for (int j = 0; j < 8; j++) {
if (j == start && maxZeros > minimum) {
if (ipAddress.isEmpty())
ipAddress.append(":");
ipAddress.append(":");

j = end.value();
continue;
}
oldSection = makeString(hex(data[2 * j] << 8 | data[2 * j + 1], 4, Lowercase));
newSection = StringBuilder();
for (int k = 0; k < 4; k++) {
if (oldSection[k] != '0' || !newSection.isEmpty() || k == 3)
newSection.append(oldSection[k]);
}
ipAddress.append(newSection.toString());

if (j != 7)
ipAddress.append(":");
}
return ipAddress.toString();
}

std::optional<WebCore::CertificateSummary> createSummaryInfo(const Vector<uint8_t>& pem)
{
BIO bio { pem };
Expand Down
1 change: 1 addition & 0 deletions Source/WebCore/platform/network/curl/OpenSSLHelper.h
Expand Up @@ -37,5 +37,6 @@ std::optional<WebCore::CertificateSummary> createSummaryInfo(const Vector<uint8_

String tlsVersion(const SSL*);
String tlsCipherName(const SSL*);
String canonicalizeIPv6Address(Span<uint8_t, 16> data);

} // namespace OpenSSL
2 changes: 2 additions & 0 deletions Tools/TestWebKitAPI/PlatformPlayStation.cmake
Expand Up @@ -20,6 +20,8 @@ list(APPEND TestJavaScriptCore_PRIVATE_INCLUDE_DIRECTORIES

list(APPEND TestWebCore_SOURCES
${test_main_SOURCES}

Tests/WebCore/curl/OpenSSLHelperTests.cpp
)
list(APPEND TestWebCore_PRIVATE_INCLUDE_DIRECTORIES
${WEBKIT_LIBRARIES_DIR}/include
Expand Down
1 change: 1 addition & 0 deletions Tools/TestWebKitAPI/PlatformWin.cmake
Expand Up @@ -26,6 +26,7 @@ set(TestWTF_OUTPUT_NAME TestWTF${DEBUG_SUFFIX})
list(APPEND TestWebCore_SOURCES
${test_main_SOURCES}

Tests/WebCore/curl/OpenSSLHelperTests.cpp
Tests/WebCore/win/DIBPixelData.cpp
Tests/WebCore/win/LinkedFonts.cpp
Tests/WebCore/win/WebCoreBundle.cpp
Expand Down
90 changes: 90 additions & 0 deletions Tools/TestWebKitAPI/Tests/WebCore/curl/OpenSSLHelperTests.cpp
@@ -0,0 +1,90 @@
/*
* Copyright (C) 2019 Sony Interactive Entertainment Inc.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*/

#include "config.h"

#if USE(CURL)

#include <WebCore/OpenSSLHelper.h>

using namespace WebCore;

namespace TestWebKitAPI {

namespace Curl {

class OpenSSLHelperTests : public testing::Test {
public:
OpenSSLHelperTests() { }
};

TEST(OpenSSLHelper, IPv6AddressCompression)
{
String ipv6;
unsigned char ipAddress[] = { 0x2a, 0x00, 0x8a, 0x00, 0xa0, 0x00, 0x11, 0x90, 0x00, 0x00, 0x00, 0x01, 0x00, 0x0, 0x02, 0x52 };
ipv6 = OpenSSL::canonicalizeIPv6Address(ipAddress);
EXPECT_EQ("2a00:8a00:a000:1190:0:1:0:252"_s, ipv6);

// Ensure the zero compression could handle multiple octects.
unsigned char ipAddress2[] = { 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x01 };
ipv6 = OpenSSL::canonicalizeIPv6Address(ipAddress2);
EXPECT_EQ("::1"_s, ipv6);

// Make sure multiple 0 octects compressed.
unsigned char ipAddress3[] = { 0xfe, 0x80, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x02, 0xaa, 0x0, 0xff, 0xfe, 0x9a, 0x4c, 0xa2 };
ipv6 = OpenSSL::canonicalizeIPv6Address(ipAddress3);
EXPECT_EQ("fe80::2aa:ff:fe9a:4ca2"_s, ipv6);

// Test zero compression at the end of string.
unsigned char ipAddress4[] = { 0x2a, 0x0, 0x0, 0x0, 0x0, 0x0, 0x11, 0x90, 0x0, 0x01, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 };
ipv6 = OpenSSL::canonicalizeIPv6Address(ipAddress4);
EXPECT_EQ("2a00:0:0:1190:1::"_s, ipv6);

// Test zero compression at the beginning of string.
unsigned char ipAddress5[] = { 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x11, 0x90, 0x0, 0x0, 0x0, 0x01, 0x0, 0x0, 0x0, 0x0 };
ipv6 = OpenSSL::canonicalizeIPv6Address(ipAddress5);
EXPECT_EQ("::1190:0:1:0:0"_s, ipv6);

// Test zero compression only done once.
unsigned char ipAddress6[] = { 0x0, 0x01, 0x0, 0x01, 0x0, 0x0, 0x11, 0x90, 0x0, 0x0, 0x0, 0x0, 0x0, 0x01, 0x0, 0x0 };
ipv6 = OpenSSL::canonicalizeIPv6Address(ipAddress6);
EXPECT_EQ("1:1:0:1190::1:0"_s, ipv6);

// Make sure noncompressable IPv6 is the same.
unsigned char ipAddress7[] = { 0x12, 0x34, 0x56, 0x78, 0xab, 0xcd, 0x12, 0x34, 0x56, 0x78, 0xab, 0xcd, 0x12, 0x34, 0x56, 0x78 };
ipv6 = OpenSSL::canonicalizeIPv6Address(ipAddress7);
EXPECT_EQ("1234:5678:abcd:1234:5678:abcd:1234:5678"_s, ipv6);

// When there are multiple consecutive octet sections that can be compressed, make sure the first occurring one is compressed.
unsigned char ipAddress8[] = { 0x0, 0x01, 0x0, 0x0, 0x0, 0x0, 0x0, 0x01, 0x0, 0x0, 0x0, 0x0, 0x0, 0x01, 0x0, 0x0 };
ipv6 = OpenSSL::canonicalizeIPv6Address(ipAddress8);
EXPECT_EQ("1::1:0:0:1:0"_s, ipv6);
}

}

}

#endif

0 comments on commit 8bec657

Please sign in to comment.