[WPE][GTK] Pass full certificate chain in CertificateInfo coder
authorcsaavedra@igalia.com <csaavedra@igalia.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 23 Oct 2018 15:52:11 +0000 (15:52 +0000)
committercsaavedra@igalia.com <csaavedra@igalia.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 23 Oct 2018 15:52:11 +0000 (15:52 +0000)
https://bugs.webkit.org/show_bug.cgi?id=190789

Reviewed by Michael Catanzaro.

When the network process serializes certificate data to other
processes through the argument coders, the certificate chain, if
present, is lost. In practice this means that applications using
the public API to process certificate info have no details on the
certificate chain, other than the very basics included in the
certificate. Serialize the entire chain if available in the
certificate.

Source/WebKit:

* Shared/soup/WebCoreArgumentCodersSoup.cpp:
(IPC::ArgumentCoder<CertificateInfo>::encode): Encode the
certificate chain if present.
(IPC::ArgumentCoder<CertificateInfo>::decode): Decode the
entire certificate chain and rebuild it.

Tools:

* TestWebKitAPI/Tests/WebKitGLib/TestSSL.cpp:
(testSSL): Test that the self-signed certificate has no bogus
issuer certificate.

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@237351 268f45cc-cd09-0410-ab3c-d52691b4dbfc

Source/WebKit/ChangeLog
Source/WebKit/Shared/soup/WebCoreArgumentCodersSoup.cpp
Tools/ChangeLog
Tools/TestWebKitAPI/Tests/WebKitGLib/TestSSL.cpp

index cedcb2bc9caff6b1648d8b1ac9b3360ae18f3021..7535e17d8ced3d910cdbc25bd7b87e99b6a6cb33 100644 (file)
@@ -1,3 +1,24 @@
+2018-10-23  Claudio Saavedra  <csaavedra@igalia.com>
+
+        [WPE][GTK] Pass full certificate chain in CertificateInfo coder
+        https://bugs.webkit.org/show_bug.cgi?id=190789
+
+        Reviewed by Michael Catanzaro.
+
+        When the network process serializes certificate data to other
+        processes through the argument coders, the certificate chain, if
+        present, is lost. In practice this means that applications using
+        the public API to process certificate info have no details on the
+        certificate chain, other than the very basics included in the
+        certificate. Serialize the entire chain if available in the
+        certificate.
+
+        * Shared/soup/WebCoreArgumentCodersSoup.cpp:
+        (IPC::ArgumentCoder<CertificateInfo>::encode): Encode the
+        certificate chain if present.
+        (IPC::ArgumentCoder<CertificateInfo>::decode): Decode the
+        entire certificate chain and rebuild it.
+
 2018-10-22  Keith Rollin  <krollin@apple.com>
 
         Use Location = "Relative to Build Products" rather than "Relative to Group"
index bd9ba09fcb0ebba45678f0c93803cce052d4efd4..e1109203bdac84ddc5638ec9bc95bd2a12a76461 100644 (file)
@@ -52,48 +52,73 @@ bool ArgumentCoder<ResourceRequest>::decodePlatformData(Decoder& decoder, Resour
 void ArgumentCoder<CertificateInfo>::encode(Encoder& encoder, const CertificateInfo& certificateInfo)
 {
     if (!certificateInfo.certificate()) {
-        encoder << false;
+        encoder << 0;
         return;
     }
 
+    uint32_t chainLength = 0;
+    GTlsCertificate* certificate = certificateInfo.certificate();
     GByteArray* certificateData = 0;
-    g_object_get(G_OBJECT(certificateInfo.certificate()), "certificate", &certificateData, NULL);
-    if (!certificateData) {
-        encoder << false;
+    Vector<GByteArray*> certificatesDataList;
+
+    do {
+        g_object_get(G_OBJECT(certificate), "certificate", &certificateData, NULL);
+
+        if (!certificateData)
+            break;
+
+        certificatesDataList.append(certificateData);
+        chainLength++;
+
+        certificate = g_tls_certificate_get_issuer(certificate);
+    } while (certificate);
+
+    encoder << chainLength;
+
+    if (!chainLength)
         return;
+
+    // Encode starting from the root certificate.
+    for (uint32_t i = chainLength; i > 0; i--) {
+        GRefPtr<GByteArray> certificate = adoptGRef(certificatesDataList[i - 1]);
+        encoder.encodeVariableLengthByteArray(IPC::DataReference(certificate->data, certificate->len));
     }
 
-    encoder << true;
-    GRefPtr<GByteArray> certificate = adoptGRef(certificateData);
-    encoder.encodeVariableLengthByteArray(IPC::DataReference(certificate->data, certificate->len));
     encoder << static_cast<uint32_t>(certificateInfo.tlsErrors());
 }
 
 bool ArgumentCoder<CertificateInfo>::decode(Decoder& decoder, CertificateInfo& certificateInfo)
 {
-    bool hasCertificate;
-    if (!decoder.decode(hasCertificate))
+    uint32_t chainLength;
+    if (!decoder.decode(chainLength))
         return false;
 
-    if (!hasCertificate)
+    if (!chainLength)
         return true;
 
-    IPC::DataReference certificateDataReference;
-    if (!decoder.decodeVariableLengthByteArray(certificateDataReference))
-        return false;
+    GTlsCertificate* issuer = nullptr;
+    GTlsBackend* backend = g_tls_backend_get_default();
+    GRefPtr<GTlsCertificate> certificate;
+    for (uint32_t i = 0; i < chainLength; i++) {
+        IPC::DataReference certificateDataReference;
+        if (!decoder.decodeVariableLengthByteArray(certificateDataReference))
+            return false;
 
-    GByteArray* certificateData = g_byte_array_sized_new(certificateDataReference.size());
-    certificateData = g_byte_array_append(certificateData, certificateDataReference.data(), certificateDataReference.size());
-    GRefPtr<GByteArray> certificateBytes = adoptGRef(certificateData);
+        GByteArray* certificateData = g_byte_array_sized_new(certificateDataReference.size());
+        certificateData = g_byte_array_append(certificateData, certificateDataReference.data(), certificateDataReference.size());
+        GRefPtr<GByteArray> certificateBytes = adoptGRef(certificateData);
 
-    GTlsBackend* backend = g_tls_backend_get_default();
-    GRefPtr<GTlsCertificate> certificate = adoptGRef(G_TLS_CERTIFICATE(g_initable_new(
-        g_tls_backend_get_certificate_type(backend), 0, 0, "certificate", certificateBytes.get(), nullptr)));
-    certificateInfo.setCertificate(certificate.get());
+        certificate = adoptGRef(G_TLS_CERTIFICATE(g_initable_new(
+            g_tls_backend_get_certificate_type(backend), 0, 0, "certificate", certificateBytes.get(), "issuer", issuer, nullptr)));
+
+        issuer = certificate.get();
+    }
 
     uint32_t tlsErrors;
     if (!decoder.decode(tlsErrors))
         return false;
+
+    certificateInfo.setCertificate(certificate.get());
     certificateInfo.setTLSErrors(static_cast<GTlsCertificateFlags>(tlsErrors));
 
     return true;
index 6e217a0771672fcd35417227efda321521ccc5b8..89c111d103ba491f28b9d47479cce3108e99fee8 100644 (file)
@@ -1,3 +1,22 @@
+2018-10-23  Claudio Saavedra  <csaavedra@igalia.com>
+
+        [WPE][GTK] Pass full certificate chain in CertificateInfo coder
+        https://bugs.webkit.org/show_bug.cgi?id=190789
+
+        Reviewed by Michael Catanzaro.
+
+        When the network process serializes certificate data to other
+        processes through the argument coders, the certificate chain, if
+        present, is lost. In practice this means that applications using
+        the public API to process certificate info have no details on the
+        certificate chain, other than the very basics included in the
+        certificate. Serialize the entire chain if available in the
+        certificate.
+
+        * TestWebKitAPI/Tests/WebKitGLib/TestSSL.cpp:
+        (testSSL): Test that the self-signed certificate has no bogus
+        issuer certificate.
+
 2018-10-22  Tim Horton  <timothy_horton@apple.com>
 
         REGRESSION (r237331): InteractionDeadlockAfterCrash API test fails
index 14e19fdace2abd62a5adf1f4a47c98ab30d0d98b..70e606b9872106ba7c03c4a9c7a8052ce66ccb63 100644 (file)
@@ -73,6 +73,8 @@ static void testSSL(SSLTest* test, gconstpointer)
     test->loadURI(kHttpsServer->getURIForPath("/").data());
     test->waitUntilLoadFinished();
     g_assert(test->m_certificate);
+    // Self-signed certificate has a nullptr issuer.
+    g_assert(!g_tls_certificate_get_issuer(test->m_certificate.get()));
     // We always expect errors because we are using a self-signed certificate,
     // but only G_TLS_CERTIFICATE_UNKNOWN_CA flags should be present.
     g_assert(test->m_tlsErrors);