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 | Optional<SummaryInfo> summaryInfo() const { notImplemented(); return WTF::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 | g_byte_array_set_size(byteArray.get(), size); |
87 | return decoder.decodeFixedLengthData(byteArray->data, size); |
88 | } |
89 | }; |
90 | |
91 | static Vector<GRefPtr<GByteArray>> certificatesDataListFromCertificateInfo(const WebCore::CertificateInfo &certificateInfo) |
92 | { |
93 | auto* certificate = certificateInfo.certificate(); |
94 | if (!certificate) |
95 | return { }; |
96 | |
97 | Vector<GRefPtr<GByteArray>> certificatesDataList; |
98 | for (; certificate; certificate = g_tls_certificate_get_issuer(certificate)) { |
99 | GByteArray* certificateData = nullptr; |
100 | g_object_get(G_OBJECT(certificate), "certificate" , &certificateData, nullptr); |
101 | |
102 | if (!certificateData) { |
103 | certificatesDataList.clear(); |
104 | break; |
105 | } |
106 | certificatesDataList.append(adoptGRef(certificateData)); |
107 | } |
108 | |
109 | // Reverse so that the list starts from the rootmost certificate. |
110 | certificatesDataList.reverse(); |
111 | |
112 | return certificatesDataList; |
113 | } |
114 | |
115 | static GRefPtr<GTlsCertificate> certificateFromCertificatesDataList(const Vector<GRefPtr<GByteArray>> &certificatesDataList) |
116 | { |
117 | GType certificateType = g_tls_backend_get_certificate_type(g_tls_backend_get_default()); |
118 | GRefPtr<GTlsCertificate> certificate; |
119 | for (auto& certificateData : certificatesDataList) { |
120 | certificate = adoptGRef(G_TLS_CERTIFICATE(g_initable_new( |
121 | certificateType, nullptr, nullptr, "certificate" , certificateData.get(), "issuer" , certificate.get(), nullptr))); |
122 | if (!certificate) |
123 | break; |
124 | } |
125 | |
126 | return certificate; |
127 | } |
128 | |
129 | template<> struct Coder<WebCore::CertificateInfo> { |
130 | static void encode(Encoder& encoder, const WebCore::CertificateInfo& certificateInfo) |
131 | { |
132 | auto certificatesDataList = certificatesDataListFromCertificateInfo(certificateInfo); |
133 | |
134 | encoder << certificatesDataList; |
135 | |
136 | if (certificatesDataList.isEmpty()) |
137 | return; |
138 | |
139 | encoder << static_cast<uint32_t>(certificateInfo.tlsErrors()); |
140 | } |
141 | |
142 | static bool decode(Decoder& decoder, WebCore::CertificateInfo& certificateInfo) |
143 | { |
144 | Vector<GRefPtr<GByteArray>> certificatesDataList; |
145 | if (!decoder.decode(certificatesDataList)) |
146 | return false; |
147 | |
148 | if (certificatesDataList.isEmpty()) |
149 | return true; |
150 | auto certificate = certificateFromCertificatesDataList(certificatesDataList); |
151 | if (!certificate) |
152 | return false; |
153 | certificateInfo.setCertificate(certificate.get()); |
154 | |
155 | uint32_t tlsErrors; |
156 | if (!decoder.decode(tlsErrors)) |
157 | return false; |
158 | certificateInfo.setTLSErrors(static_cast<GTlsCertificateFlags>(tlsErrors)); |
159 | |
160 | return true; |
161 | } |
162 | }; |
163 | |
164 | } // namespace WTF::Persistence |
165 | } // namespace WTF |
166 | |