Web Inspector: Network: add button to show system certificate dialog
[WebKit-https.git] / Source / WebCore / platform / network / soup / CertificateInfo.h
1 /*
2  * Copyright (C) 2010 Apple Inc. All rights reserved.
3  * Portions Copyright (c) 2010 Motorola Mobility, Inc.  All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  * 1. Redistributions of source code must retain the above copyright
9  *    notice, this list of conditions and the following disclaimer.
10  * 2. Redistributions in binary form must reproduce the above copyright
11  *    notice, this list of conditions and the following disclaimer in the
12  *    documentation and/or other materials provided with the distribution.
13  *
14  * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
15  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
16  * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
17  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
18  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
19  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
20  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
21  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
22  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
23  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
24  * THE POSSIBILITY OF SUCH DAMAGE.
25  */
26
27 #pragma once
28
29 #include "CertificateInfoBase.h"
30 #include "NotImplemented.h"
31 #include <libsoup/soup.h>
32 #include <wtf/Vector.h>
33 #include <wtf/glib/GRefPtr.h>
34 #include <wtf/persistence/PersistentCoders.h>
35 #include <wtf/persistence/PersistentDecoder.h>
36 #include <wtf/persistence/PersistentEncoder.h>
37
38 namespace WebCore {
39
40 class ResourceError;
41 class ResourceResponse;
42
43 class CertificateInfo  : public CertificateInfoBase {
44 public:
45     CertificateInfo();
46     explicit CertificateInfo(const WebCore::ResourceResponse&);
47     explicit CertificateInfo(const WebCore::ResourceError&);
48     explicit CertificateInfo(GTlsCertificate*, GTlsCertificateFlags);
49     ~CertificateInfo();
50
51     GTlsCertificate* certificate() const { return m_certificate.get(); }
52     void setCertificate(GTlsCertificate* certificate) { m_certificate = certificate; }
53     GTlsCertificateFlags tlsErrors() const { return m_tlsErrors; }
54     void setTLSErrors(GTlsCertificateFlags tlsErrors) { m_tlsErrors = tlsErrors; }
55
56     bool containsNonRootSHA1SignedCertificate() const { notImplemented(); return false; }
57
58     std::optional<SummaryInfo> summaryInfo() const { notImplemented(); return std::nullopt; }
59
60     bool isEmpty() const { return !m_certificate; }
61
62 private:
63     GRefPtr<GTlsCertificate> m_certificate;
64     GTlsCertificateFlags m_tlsErrors;
65 };
66
67 } // namespace WebCore
68
69 namespace WTF {
70 namespace Persistence {
71
72 template<> struct Coder<GRefPtr<GByteArray>> {
73     static void encode(Encoder &encoder, const GRefPtr<GByteArray>& byteArray)
74     {
75         encoder << static_cast<uint32_t>(byteArray->len);
76         encoder.encodeFixedLengthData(byteArray->data, byteArray->len);
77     }
78
79     static bool decode(Decoder &decoder, GRefPtr<GByteArray>& byteArray)
80     {
81         uint32_t size;
82         if (!decoder.decode(size))
83             return false;
84
85         byteArray = adoptGRef(g_byte_array_sized_new(size));
86         return decoder.decodeFixedLengthData(byteArray->data, byteArray->len);
87     }
88 };
89
90 static Vector<GRefPtr<GByteArray>> certificatesDataListFromCertificateInfo(const WebCore::CertificateInfo &certificateInfo)
91 {
92     auto* certificate = certificateInfo.certificate();
93     if (!certificate)
94         return { };
95
96     Vector<GRefPtr<GByteArray>> certificatesDataList;
97     for (; certificate; certificate = g_tls_certificate_get_issuer(certificate)) {
98         GByteArray* certificateData = nullptr;
99         g_object_get(G_OBJECT(certificate), "certificate", &certificateData, nullptr);
100
101         if (!certificateData) {
102             certificatesDataList.clear();
103             break;
104         }
105         certificatesDataList.append(adoptGRef(certificateData));
106     }
107
108     // Reverse so that the list starts from the rootmost certificate.
109     certificatesDataList.reverse();
110
111     return certificatesDataList;
112 }
113
114 static GRefPtr<GTlsCertificate> certificateFromCertificatesDataList(const Vector<GRefPtr<GByteArray>> &certificatesDataList)
115 {
116     GType certificateType = g_tls_backend_get_certificate_type(g_tls_backend_get_default());
117     GRefPtr<GTlsCertificate> certificate;
118     for (auto& certificateData : certificatesDataList) {
119         certificate = adoptGRef(G_TLS_CERTIFICATE(g_initable_new(
120             certificateType, nullptr, nullptr, "certificate", certificateData.get(), "issuer", certificate.get(), nullptr)));
121     }
122
123     return certificate;
124 }
125
126 template<> struct Coder<WebCore::CertificateInfo> {
127     static void encode(Encoder& encoder, const WebCore::CertificateInfo& certificateInfo)
128     {
129         auto certificatesDataList = certificatesDataListFromCertificateInfo(certificateInfo);
130
131         encoder << certificatesDataList;
132
133         if (certificatesDataList.isEmpty())
134             return;
135
136         encoder << static_cast<uint32_t>(certificateInfo.tlsErrors());
137     }
138
139     static bool decode(Decoder& decoder, WebCore::CertificateInfo& certificateInfo)
140     {
141         Vector<GRefPtr<GByteArray>> certificatesDataList;
142         if (!decoder.decode(certificatesDataList))
143             return false;
144
145         if (certificatesDataList.isEmpty())
146             return true;
147         certificateInfo.setCertificate(certificateFromCertificatesDataList(certificatesDataList).get());
148
149         uint32_t tlsErrors;
150         if (!decoder.decode(tlsErrors))
151             return false;
152         certificateInfo.setTLSErrors(static_cast<GTlsCertificateFlags>(tlsErrors));
153
154         return true;
155     }
156 };
157
158 } // namespace WTF::Persistence
159 } // namespace WTF