Changeset 203671 in webkit


Ignore:
Timestamp:
Jul 24, 2016 5:48:51 PM (8 years ago)
Author:
weinig@apple.com
Message:

Add specialization for encoding/decoding WebCore::CertificateInfos in the Network Cache
<rdar://problem/27409315>
https://bugs.webkit.org/show_bug.cgi?id=160144

Reviewed by Chris Dumez.

  • NetworkProcess/cache/NetworkCacheCoders.cpp:

(WebKit::NetworkCache::encodeCFData):
(WebKit::NetworkCache::decodeCFData):
(WebKit::NetworkCache::encodeSecTrustRef):
(WebKit::NetworkCache::decodeSecTrustRef):
(WebKit::NetworkCache::encodeCertificateChain):
(WebKit::NetworkCache::decodeCertificateChain):
(WebKit::NetworkCache::Coder<WebCore::CertificateInfo>::encode):
(WebKit::NetworkCache::Coder<WebCore::CertificateInfo>::decode):

  • NetworkProcess/cache/NetworkCacheStorage.h:

(WebKit::NetworkCache::Storage::version):
Bump the version and lastStableVersion to account for the format change.

Location:
trunk/Source/WebKit2
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebKit2/ChangeLog

    r203635 r203671  
     12016-07-24  Sam Weinig  <sam@webkit.org>
     2
     3        Add specialization for encoding/decoding WebCore::CertificateInfos in the Network Cache
     4        <rdar://problem/27409315>
     5        https://bugs.webkit.org/show_bug.cgi?id=160144
     6
     7        Reviewed by Chris Dumez.
     8
     9        * NetworkProcess/cache/NetworkCacheCoders.cpp:
     10        (WebKit::NetworkCache::encodeCFData):
     11        (WebKit::NetworkCache::decodeCFData):
     12        (WebKit::NetworkCache::encodeSecTrustRef):
     13        (WebKit::NetworkCache::decodeSecTrustRef):
     14        (WebKit::NetworkCache::encodeCertificateChain):
     15        (WebKit::NetworkCache::decodeCertificateChain):
     16        (WebKit::NetworkCache::Coder<WebCore::CertificateInfo>::encode):
     17        (WebKit::NetworkCache::Coder<WebCore::CertificateInfo>::decode):
     18
     19        * NetworkProcess/cache/NetworkCacheStorage.h:
     20        (WebKit::NetworkCache::Storage::version):
     21        Bump the version and lastStableVersion to account for the format change.
     22
    1232016-07-22  Joseph Pecoraro  <pecoraro@apple.com>
    224
  • trunk/Source/WebKit2/NetworkProcess/cache/NetworkCacheCoders.cpp

    r200909 r203671  
    2929#if ENABLE(NETWORK_CACHE)
    3030
    31 #include "WebCoreArgumentCoders.h"
    3231#include <wtf/text/CString.h>
    3332#include <wtf/text/WTFString.h>
     33
     34#if PLATFORM(COCOA)
     35#include <Security/SecCertificate.h>
     36#include <Security/SecTrust.h>
     37#include <wtf/spi/cocoa/SecuritySPI.h>
     38#endif
    3439
    3540namespace WebKit {
     
    146151}
    147152
     153#if PLATFORM(COCOA)
     154static void encodeCFData(Encoder& encoder, CFDataRef data)
     155{
     156    uint64_t length = CFDataGetLength(data);
     157    const uint8_t* bytePtr = CFDataGetBytePtr(data);
     158
     159    encoder << length;
     160    encoder.encodeFixedLengthData(bytePtr, length);
     161}
     162
     163static bool decodeCFData(Decoder& decoder, RetainPtr<CFDataRef>& data)
     164{
     165    uint64_t size = 0;
     166    if (!decoder.decode(size))
     167        return false;
     168
     169    Vector<uint8_t> vector(size);
     170    if (!decoder.decodeFixedLengthData(vector.data(), vector.size()))
     171        return false;
     172
     173    data = adoptCF(CFDataCreate(nullptr, vector.data(), vector.size()));
     174    return true;
     175}
     176
     177
     178#if HAVE(SEC_TRUST_SERIALIZATION)
     179static void encodeSecTrustRef(Encoder& encoder, SecTrustRef trust)
     180{
     181    auto data = adoptCF(SecTrustSerialize(trust, nullptr));
     182    if (!data) {
     183        encoder << false;
     184        return;
     185    }
     186
     187    encoder << true;
     188    encodeCFData(encoder, data.get());
     189}
     190
     191static bool decodeSecTrustRef(Decoder& decoder, RetainPtr<SecTrustRef>& result)
     192{
     193    bool hasTrust;
     194    if (!decoder.decode(hasTrust))
     195        return false;
     196
     197    if (!hasTrust)
     198        return true;
     199
     200    RetainPtr<CFDataRef> trustData;
     201    if (!decodeCFData(decoder, trustData))
     202        return false;
     203
     204    auto trust = adoptCF(SecTrustDeserialize(trustData.get(), nullptr));
     205    if (!trust)
     206        return false;
     207
     208    result = WTFMove(trust);
     209    return true;
     210}
     211#endif
     212
     213static void encodeCertificateChain(Encoder& encoder, CFArrayRef certificateChain)
     214{
     215    CFIndex size = CFArrayGetCount(certificateChain);
     216    Vector<CFTypeRef, 32> values(size);
     217
     218    CFArrayGetValues(certificateChain, CFRangeMake(0, size), values.data());
     219
     220    encoder << static_cast<uint64_t>(size);
     221
     222    for (CFIndex i = 0; i < size; ++i) {
     223        ASSERT(values[i]);
     224        ASSERT(CFGetTypeID(values[i]) != SecCertificateGetTypeID());
     225
     226        auto data = adoptCF(SecCertificateCopyData((SecCertificateRef)values[i]));
     227        encodeCFData(encoder, data.get());
     228    }
     229}
     230
     231static bool decodeCertificateChain(Decoder& decoder, RetainPtr<CFArrayRef>& certificateChain)
     232{
     233    uint64_t size;
     234    if (!decoder.decode(size))
     235        return false;
     236
     237    auto array = adoptCF(CFArrayCreateMutable(0, 0, &kCFTypeArrayCallBacks));
     238
     239    for (size_t i = 0; i < size; ++i) {
     240        RetainPtr<CFDataRef> data;
     241        if (!decodeCFData(decoder, data))
     242            return false;
     243
     244        auto certificate = adoptCF(SecCertificateCreateWithData(0, data.get()));
     245        CFArrayAppendValue(array.get(), certificate.get());
     246    }
     247
     248    certificateChain = WTFMove(array);
     249    return true;
     250}
     251
    148252void Coder<WebCore::CertificateInfo>::encode(Encoder& encoder, const WebCore::CertificateInfo& certificateInfo)
    149253{
    150     // FIXME: Cocoa CertificateInfo is a CF object tree. Generalize CF type coding so we don't need to use ArgumentCoder here.
    151     IPC::ArgumentEncoder argumentEncoder;
    152     argumentEncoder << certificateInfo;
    153     encoder << static_cast<uint64_t>(argumentEncoder.bufferSize());
    154     encoder.encodeFixedLengthData(argumentEncoder.buffer(), argumentEncoder.bufferSize());
     254    encoder.encodeEnum(certificateInfo.type());
     255
     256    switch (certificateInfo.type()) {
     257#if HAVE(SEC_TRUST_SERIALIZATION)
     258    case WebCore::CertificateInfo::Type::Trust:
     259        encodeSecTrustRef(encoder, certificateInfo.trust());
     260        break;
     261#endif
     262    case WebCore::CertificateInfo::Type::CertificateChain: {
     263        encodeCertificateChain(encoder, certificateInfo.certificateChain());
     264        break;
     265    }
     266    case WebCore::CertificateInfo::Type::None:
     267        // Do nothing.
     268        break;
     269    }
    155270}
    156271
    157272bool Coder<WebCore::CertificateInfo>::decode(Decoder& decoder, WebCore::CertificateInfo& certificateInfo)
    158273{
    159     uint64_t certificateSize;
    160     if (!decoder.decode(certificateSize))
    161         return false;
    162     Vector<uint8_t> data(certificateSize);
    163     if (!decoder.decodeFixedLengthData(data.data(), data.size()))
    164         return false;
    165     IPC::ArgumentDecoder argumentDecoder(data.data(), data.size());
    166     return argumentDecoder.decode(certificateInfo);
    167 }
     274    WebCore::CertificateInfo::Type certificateInfoType;
     275    if (!decoder.decodeEnum(certificateInfoType))
     276        return false;
     277
     278    switch (certificateInfoType) {
     279#if HAVE(SEC_TRUST_SERIALIZATION)
     280    case WebCore::CertificateInfo::Type::Trust: {
     281        RetainPtr<SecTrustRef> trust;
     282        if (!decodeSecTrustRef(decoder, trust))
     283            return false;
     284
     285        certificateInfo = WebCore::CertificateInfo(WTFMove(trust));
     286        return true;
     287    }
     288#endif
     289    case WebCore::CertificateInfo::Type::CertificateChain: {
     290        RetainPtr<CFArrayRef> certificateChain;
     291        if (!decodeCertificateChain(decoder, certificateChain))
     292            return false;
     293
     294        certificateInfo = WebCore::CertificateInfo(WTFMove(certificateChain));
     295        return true;
     296    }   
     297    case WebCore::CertificateInfo::Type::None:
     298        // Do nothing.
     299        break;
     300    }
     301
     302    return true;
     303}
     304#else
     305void Coder<WebCore::CertificateInfo>::encode(Encoder& encoder, const WebCore::CertificateInfo& certificateInfo)
     306{
     307    if (!certificateInfo.certificate()) {
     308        encoder << false;
     309        return;
     310    }
     311
     312    GByteArray* certificateData = 0;
     313    g_object_get(G_OBJECT(certificateInfo.certificate()), "certificate", &certificateData, NULL);
     314    if (!certificateData) {
     315        encoder << false;
     316        return;
     317    }
     318
     319    encoder << true;
     320
     321    GRefPtr<GByteArray> certificate = adoptGRef(certificateData);
     322    encoder << static_cast<uint64_t>(certificate->len);
     323    encoder.encodeFixedLengthData(certificate->data, certificate->len);
     324
     325    encoder << static_cast<uint32_t>(certificateInfo.tlsErrors());
     326}
     327
     328bool Coder<WebCore::CertificateInfo>::decode(Decoder& decoder, WebCore::CertificateInfo& certificateInfo)
     329{
     330    bool hasCertificate;
     331    if (!decoder.decode(hasCertificate))
     332        return false;
     333
     334    if (!hasCertificate)
     335        return true;
     336
     337    uint64_t size = 0;
     338    if (!decoder.decode(size))
     339        return false;
     340
     341    Vector<uint8_t> vector(size);
     342    if (!decoder.decodeFixedLengthData(vector.data(), vector.size()))
     343        return false;
     344
     345    GByteArray* certificateData = g_byte_array_sized_new(vector.size());
     346    certificateData = g_byte_array_append(certificateData, vector.data(), vector.size());
     347    GRefPtr<GByteArray> certificateBytes = adoptGRef(certificateData);
     348
     349    GTlsBackend* backend = g_tls_backend_get_default();
     350    GRefPtr<GTlsCertificate> certificate = adoptGRef(G_TLS_CERTIFICATE(g_initable_new(
     351        g_tls_backend_get_certificate_type(backend), 0, 0, "certificate", certificateBytes.get(), nullptr)));
     352    certificateInfo.setCertificate(certificate.get());
     353
     354    uint32_t tlsErrors;
     355    if (!decoder.decode(tlsErrors))
     356        return false;
     357    certificateInfo.setTLSErrors(static_cast<GTlsCertificateFlags>(tlsErrors));
     358
     359    return true;
     360}
     361#endif
    168362
    169363void Coder<SHA1::Digest>::encode(Encoder& encoder, const SHA1::Digest& digest)
  • trunk/Source/WebKit2/NetworkProcess/cache/NetworkCacheStorage.h

    r203061 r203671  
    8888    size_t approximateSize() const;
    8989
    90     static const unsigned version = 8;
     90    static const unsigned version = 9;
    9191#if PLATFORM(MAC)
    9292    /// Allow the last stable version of the cache to co-exist with the latest development one.
    93     static const unsigned lastStableVersion = 8;
     93    static const unsigned lastStableVersion = 9;
    9494#endif
    9595
Note: See TracChangeset for help on using the changeset viewer.