1/*
2 * Copyright (C) 2010 Apple Inc. All rights reserved.
3 * Portions Copyright (c) 2010 Motorola Mobility, Inc.  All rights reserved.
4 * Portions Copyright (c) 2013 Company 100 Inc. All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
9 * 1. Redistributions of source code must retain the above copyright
10 *    notice, this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright
12 *    notice, this list of conditions and the following disclaimer in the
13 *    documentation and/or other materials provided with the distribution.
14 *
15 * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
16 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
17 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
18 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
19 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
20 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
21 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
22 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
23 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
24 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
25 * THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28#include "config.h"
29#include "DataReference.h"
30#include "WebCoreArgumentCoders.h"
31
32#include <WebCore/CertificateInfo.h>
33#include <WebCore/ResourceError.h>
34#include <WebCore/ResourceRequest.h>
35#include <WebCore/ResourceResponse.h>
36#include <wtf/text/CString.h>
37
38using namespace WebCore;
39
40namespace IPC {
41
42void ArgumentCoder<ResourceRequest>::encodePlatformData(ArgumentEncoder& encoder, const ResourceRequest& resourceRequest)
43{
44    encoder << static_cast<uint32_t>(resourceRequest.soupMessageFlags());
45    encoder << resourceRequest.initiatingPageID();
46}
47
48bool ArgumentCoder<ResourceRequest>::decodePlatformData(ArgumentDecoder& decoder, ResourceRequest& resourceRequest)
49{
50    uint32_t soupMessageFlags;
51    if (!decoder.decode(soupMessageFlags))
52        return false;
53    resourceRequest.setSoupMessageFlags(static_cast<SoupMessageFlags>(soupMessageFlags));
54
55    uint64_t initiatingPageID;
56    if (!decoder.decode(initiatingPageID))
57        return false;
58    resourceRequest.setInitiatingPageID(initiatingPageID);
59
60    return true;
61}
62
63
64void ArgumentCoder<ResourceResponse>::encodePlatformData(ArgumentEncoder& encoder, const ResourceResponse& resourceResponse)
65{
66    encoder << static_cast<uint32_t>(resourceResponse.soupMessageFlags());
67}
68
69bool ArgumentCoder<ResourceResponse>::decodePlatformData(ArgumentDecoder& decoder, ResourceResponse& resourceResponse)
70{
71    uint32_t soupMessageFlags;
72    if (!decoder.decode(soupMessageFlags))
73        return false;
74    resourceResponse.setSoupMessageFlags(static_cast<SoupMessageFlags>(soupMessageFlags));
75    return true;
76}
77
78void ArgumentCoder<CertificateInfo>::encode(ArgumentEncoder& encoder, const CertificateInfo& certificateInfo)
79{
80    if (!certificateInfo.certificate()) {
81        encoder << false;
82        return;
83    }
84
85    GByteArray* certificateData = 0;
86    g_object_get(G_OBJECT(certificateInfo.certificate()), "certificate", &certificateData, NULL);
87    if (!certificateData) {
88        encoder << false;
89        return;
90    }
91
92    encoder << true;
93    GRefPtr<GByteArray> certificate = adoptGRef(certificateData);
94    encoder.encodeVariableLengthByteArray(IPC::DataReference(certificate->data, certificate->len));
95    encoder << static_cast<uint32_t>(certificateInfo.tlsErrors());
96}
97
98bool ArgumentCoder<CertificateInfo>::decode(ArgumentDecoder& decoder, CertificateInfo& certificateInfo)
99{
100    bool hasCertificate;
101    if (!decoder.decode(hasCertificate))
102        return false;
103
104    if (!hasCertificate)
105        return true;
106
107    IPC::DataReference certificateDataReference;
108    if (!decoder.decodeVariableLengthByteArray(certificateDataReference))
109        return false;
110
111    GByteArray* certificateData = g_byte_array_sized_new(certificateDataReference.size());
112    certificateData = g_byte_array_append(certificateData, certificateDataReference.data(), certificateDataReference.size());
113    GRefPtr<GByteArray> certificateBytes = adoptGRef(certificateData);
114
115    GTlsBackend* backend = g_tls_backend_get_default();
116    GRefPtr<GTlsCertificate> certificate = adoptGRef(G_TLS_CERTIFICATE(g_initable_new(
117        g_tls_backend_get_certificate_type(backend), 0, 0, "certificate", certificateBytes.get(), nullptr)));
118    certificateInfo.setCertificate(certificate.get());
119
120    uint32_t tlsErrors;
121    if (!decoder.decode(tlsErrors))
122        return false;
123    certificateInfo.setTLSErrors(static_cast<GTlsCertificateFlags>(tlsErrors));
124
125    return true;
126}
127
128void ArgumentCoder<ResourceError>::encodePlatformData(ArgumentEncoder& encoder, const ResourceError& resourceError)
129{
130    encoder << CertificateInfo(resourceError);
131}
132
133bool ArgumentCoder<ResourceError>::decodePlatformData(ArgumentDecoder& decoder, ResourceError& resourceError)
134{
135    CertificateInfo certificateInfo;
136    if (!decoder.decode(certificateInfo))
137        return false;
138
139    resourceError.setCertificate(certificateInfo.certificate());
140    resourceError.setTLSErrors(certificateInfo.tlsErrors());
141    return true;
142}
143
144void ArgumentCoder<ProtectionSpace>::encodePlatformData(ArgumentEncoder&, const ProtectionSpace&)
145{
146    ASSERT_NOT_REACHED();
147}
148
149bool ArgumentCoder<ProtectionSpace>::decodePlatformData(ArgumentDecoder&, ProtectionSpace&)
150{
151    ASSERT_NOT_REACHED();
152    return false;
153}
154
155}
156
157