Reviewed by Sam Weinig.
authoradachan@apple.com <adachan@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 14 Oct 2010 21:03:49 +0000 (21:03 +0000)
committeradachan@apple.com <adachan@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 14 Oct 2010 21:03:49 +0000 (21:03 +0000)
        WebKit2: Store the certificate chain in PlatformCertificateInfo.
        https://bugs.webkit.org/show_bug.cgi?id=47603

        * Shared/API/c/win/WKCertificateInfoWin.cpp:
        (WKCertificateInfoGetCertificateChainLength):
        (WKCertificateInfoGetCertificateContextAtIndex):
        * Shared/API/c/win/WKCertificateInfoWin.h:
        * Shared/win/PlatformCertificateInfo.cpp:
        (WebKit::PlatformCertificateInfo::PlatformCertificateInfo): Get the chain context from the response and duplicate the certificate contexts
        in the chain to store in m_certificateChain.
        (WebKit::PlatformCertificateInfo::~PlatformCertificateInfo): Free all the certificate contexts in the chain.
        (WebKit::PlatformCertificateInfo::operator=): Duplicate the certificate contexts from the other PlatformCertificateInfo's certificate chain
        to store in m_certificateChain.
        (WebKit::PlatformCertificateInfo::encode):
        (WebKit::PlatformCertificateInfo::decode):
        (WebKit::PlatformCertificateInfo::clearCertificateChain): Free all the certificate contexts in the chain and clear the vector.
        * Shared/win/PlatformCertificateInfo.h:
        (WebKit::PlatformCertificateInfo::certificateChain):

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

WebKit2/ChangeLog
WebKit2/Shared/API/c/win/WKCertificateInfoWin.cpp
WebKit2/Shared/API/c/win/WKCertificateInfoWin.h
WebKit2/Shared/win/PlatformCertificateInfo.cpp
WebKit2/Shared/win/PlatformCertificateInfo.h

index 5b861c5..d488afe 100644 (file)
@@ -1,3 +1,26 @@
+2010-10-14  Ada Chan  <adachan@apple.com>
+
+        Reviewed by Sam Weinig.
+
+        WebKit2: Store the certificate chain in PlatformCertificateInfo.
+        https://bugs.webkit.org/show_bug.cgi?id=47603
+
+        * Shared/API/c/win/WKCertificateInfoWin.cpp:
+        (WKCertificateInfoGetCertificateChainLength):
+        (WKCertificateInfoGetCertificateContextAtIndex):
+        * Shared/API/c/win/WKCertificateInfoWin.h:
+        * Shared/win/PlatformCertificateInfo.cpp:
+        (WebKit::PlatformCertificateInfo::PlatformCertificateInfo): Get the chain context from the response and duplicate the certificate contexts
+        in the chain to store in m_certificateChain.
+        (WebKit::PlatformCertificateInfo::~PlatformCertificateInfo): Free all the certificate contexts in the chain.
+        (WebKit::PlatformCertificateInfo::operator=): Duplicate the certificate contexts from the other PlatformCertificateInfo's certificate chain
+        to store in m_certificateChain.
+        (WebKit::PlatformCertificateInfo::encode):
+        (WebKit::PlatformCertificateInfo::decode):
+        (WebKit::PlatformCertificateInfo::clearCertificateChain): Free all the certificate contexts in the chain and clear the vector.
+        * Shared/win/PlatformCertificateInfo.h:
+        (WebKit::PlatformCertificateInfo::certificateChain):
+
 2010-10-14  Adam Roben  <aroben@apple.com>
 
         Make sure WebKit2 only loads each plugin once
index 04c5a0c..f4c7bb2 100644 (file)
 
 using namespace WebKit;
 
-PCCERT_CONTEXT WKCertificateInfoGetCertificateContext(WKCertificateInfoRef certificateInfoRef)
+size_t WKCertificateInfoGetCertificateChainLength(WKCertificateInfoRef certificateInfoRef)
 {
-    return toImpl(certificateInfoRef)->platformCertificateInfo().certificateContext();
+    return toImpl(certificateInfoRef)->platformCertificateInfo().certificateChain().size();
+}
+
+PCCERT_CONTEXT WKCertificateInfoGetCertificateContextAtIndex(WKCertificateInfoRef certificateInfoRef, size_t index)
+{
+    const Vector<PCCERT_CONTEXT>& certificateChain = toImpl(certificateInfoRef)->platformCertificateInfo().certificateChain();
+    if (index >= certificateChain.size())
+        return 0;
+    return certificateChain[index];
 }
index 1db425e..0fcd818 100644 (file)
@@ -33,7 +33,8 @@
 extern "C" {
 #endif
 
-WK_EXPORT PCCERT_CONTEXT WKCertificateInfoGetCertificateContext(WKCertificateInfoRef certificateInfo);
+WK_EXPORT size_t WKCertificateInfoGetCertificateChainLength(WKCertificateInfoRef certificateInfo);
+WK_EXPORT PCCERT_CONTEXT WKCertificateInfoGetCertificateContextAtIndex(WKCertificateInfoRef certificateInfo, size_t index);
 
 #ifdef __cplusplus
 }
index 69bda7d..b88a7ef 100644 (file)
@@ -38,12 +38,10 @@ using namespace WebCore;
 namespace WebKit {
 
 PlatformCertificateInfo::PlatformCertificateInfo()
-    : m_certificateContext(0)
 {
 }
 
 PlatformCertificateInfo::PlatformCertificateInfo(const ResourceResponse& response)
-    : m_certificateContext(0)
 {
     CFURLResponseRef cfResponse = response.cfURLResponse();
     if (!cfResponse)
@@ -54,11 +52,21 @@ PlatformCertificateInfo::PlatformCertificateInfo(const ResourceResponse& respons
     if (!certificateInfo)
         return;
 
-    void* data = wkGetSSLPeerCertificateData(certificateInfo);
+    void* data = wkGetSSLCertificateChainContext(certificateInfo);
     if (!data)
         return;
 
-    m_certificateContext = ::CertDuplicateCertificateContext(static_cast<PCCERT_CONTEXT>(data));
+    PCCERT_CHAIN_CONTEXT chainContext = static_cast<PCCERT_CHAIN_CONTEXT>(data);
+    if (chainContext->cChain < 1)
+        return;
+
+    // The first simple chain starts with the leaf certificate and ends with a trusted root or self-signed certificate.
+    PCERT_SIMPLE_CHAIN firstSimpleChain = chainContext->rgpChain[0];
+    for (unsigned i = 0; i < firstSimpleChain->cElement; ++i) {
+        PCCERT_CONTEXT certificateContext = firstSimpleChain->rgpElement[i]->pCertContext;
+        ::CertDuplicateCertificateContext(certificateContext);
+        m_certificateChain.append(certificateContext);
+    }
 #else
     // FIXME: WinCairo implementation
 #endif
@@ -66,56 +74,77 @@ PlatformCertificateInfo::PlatformCertificateInfo(const ResourceResponse& respons
 
 PlatformCertificateInfo::~PlatformCertificateInfo()
 {
-    if (m_certificateContext)
-        ::CertFreeCertificateContext(m_certificateContext);
+    clearCertificateChain();
 }
 
 PlatformCertificateInfo::PlatformCertificateInfo(const PlatformCertificateInfo& other)
-    : m_certificateContext(::CertDuplicateCertificateContext(other.m_certificateContext))
 {
+    for (size_t i = 0; i < other.m_certificateChain.size(); ++i) {
+        ::CertDuplicateCertificateContext(other.m_certificateChain[i]);
+        m_certificateChain.append(other.m_certificateChain[i]);
+    }
 }
 
 PlatformCertificateInfo& PlatformCertificateInfo::operator=(const PlatformCertificateInfo& other)
 {
-    ::CertDuplicateCertificateContext(other.m_certificateContext);
-    if (m_certificateContext)
-        ::CertFreeCertificateContext(m_certificateContext);
-    m_certificateContext = other.m_certificateContext;
+    clearCertificateChain();
+    for (size_t i = 0; i < other.m_certificateChain.size(); ++i) {
+        ::CertDuplicateCertificateContext(other.m_certificateChain[i]);
+        m_certificateChain.append(other.m_certificateChain[i]);
+    }
     return *this;
 }
 
 void PlatformCertificateInfo::encode(CoreIPC::ArgumentEncoder* encoder) const
 {
-    // FIXME: We should encode the no certificate context case in the
-    // number of the bytes.
-    if (!m_certificateContext) {
-        encoder->encodeBool(true);
+    // Special case no certificates
+    if (m_certificateChain.isEmpty()) {
+        encoder->encodeUInt64(std::numeric_limits<uint64_t>::max());
         return;
     }
 
-    encoder->encodeBool(false);
-    encoder->encodeBytes(static_cast<uint8_t*>(m_certificateContext->pbCertEncoded), m_certificateContext->cbCertEncoded);
+    uint64_t length = m_certificateChain.size();
+    encoder->encodeUInt64(length);
+
+    for (size_t i = 0; i < length; ++i)
+        encoder->encodeBytes(static_cast<uint8_t*>(m_certificateChain[i]->pbCertEncoded), m_certificateChain[i]->cbCertEncoded);
 }
 
 bool PlatformCertificateInfo::decode(CoreIPC::ArgumentDecoder* decoder, PlatformCertificateInfo& c)
 {
-    bool noCertificate;
-    if (!decoder->decode(noCertificate))
+    uint64_t length;
+    if (!decoder->decode(length))
         return false;
 
-    if (noCertificate)
+    if (length == std::numeric_limits<uint64_t>::max()) {
+        // This is the no certificates case.
         return true;
+    }
 
-    Vector<uint8_t> bytes;
-    if (!decoder->decodeBytes(bytes))
-        return false;
-
-    PCCERT_CONTEXT certificateContext = ::CertCreateCertificateContext(PKCS_7_ASN_ENCODING | X509_ASN_ENCODING, bytes.data(), bytes.size());
-    if (!certificateContext)
-        return false;
+    for (size_t i = 0; i < length; ++i) {
+        Vector<uint8_t> bytes;
+        if (!decoder->decodeBytes(bytes)) {
+            c.clearCertificateChain();
+            return false;
+        }
+
+        PCCERT_CONTEXT certificateContext = ::CertCreateCertificateContext(PKCS_7_ASN_ENCODING | X509_ASN_ENCODING, bytes.data(), bytes.size());
+        if (!certificateContext) {
+            c.clearCertificateChain();
+            return false;
+        }
+        
+        c.m_certificateChain.append(certificateContext);
+    }
 
-    c.m_certificateContext = certificateContext;
     return true;
 }
 
+void PlatformCertificateInfo::clearCertificateChain()
+{
+    for (size_t i = 0; i < m_certificateChain.size(); ++i)
+        ::CertFreeCertificateContext(m_certificateChain[i]);
+    m_certificateChain.clear();
+}
+
 } // namespace WebKit
index b8d6d6d..e483d37 100644 (file)
@@ -26,6 +26,8 @@
 #ifndef PlatformCertificateInfo_h
 #define PlatformCertificateInfo_h
 
+#include <wtf/Vector.h>
+
 namespace CoreIPC {
     class ArgumentDecoder;
     class ArgumentEncoder;
@@ -46,13 +48,15 @@ public:
     PlatformCertificateInfo(const PlatformCertificateInfo&);
     PlatformCertificateInfo& operator=(const PlatformCertificateInfo&);
 
-    PCCERT_CONTEXT certificateContext() const { return m_certificateContext; }
+    const Vector<PCCERT_CONTEXT>& certificateChain() const { return m_certificateChain; }
 
     void encode(CoreIPC::ArgumentEncoder* encoder) const;
     static bool decode(CoreIPC::ArgumentDecoder* decoder, PlatformCertificateInfo& t);
 
 private:
-    PCCERT_CONTEXT m_certificateContext;
+    void clearCertificateChain();
+
+    Vector<PCCERT_CONTEXT> m_certificateChain;
 };
 
 } // namespace WebKit