BHttpRequest: add SSL certificate exception management.
When an HTTPS request uses an SSL certificate that OpenSSL considers untrusted, and the user decides to continue anyway, add the certificate to an exception list. Match certificates against this list and don't ask the user again if they are already there. Fixes #12004. Thanks to markh for the initial patch and peeking into the WebKit code!
This commit is contained in:
parent
f26dbfe79b
commit
4849ab6c8b
@ -29,7 +29,7 @@ public:
|
|||||||
|
|
||||||
BString String() const;
|
BString String() const;
|
||||||
|
|
||||||
bool operator==(const BCertificate& other);
|
bool operator==(const BCertificate& other) const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
friend class BSecureSocket::Private;
|
friend class BSecureSocket::Private;
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2010-2014 Haiku Inc. All rights reserved.
|
* Copyright 2010-2015 Haiku Inc. All rights reserved.
|
||||||
* Distributed under the terms of the MIT License.
|
* Distributed under the terms of the MIT License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@ -8,6 +8,7 @@
|
|||||||
#define _B_URL_CONTEXT_H_
|
#define _B_URL_CONTEXT_H_
|
||||||
|
|
||||||
|
|
||||||
|
#include <Certificate.h>
|
||||||
#include <HttpAuthentication.h>
|
#include <HttpAuthentication.h>
|
||||||
#include <NetworkCookieJar.h>
|
#include <NetworkCookieJar.h>
|
||||||
#include <Referenceable.h>
|
#include <Referenceable.h>
|
||||||
@ -30,6 +31,7 @@ public:
|
|||||||
void AddAuthentication(const BUrl& url,
|
void AddAuthentication(const BUrl& url,
|
||||||
const BHttpAuthentication& authentication);
|
const BHttpAuthentication& authentication);
|
||||||
void SetProxy(BString host, uint16 port);
|
void SetProxy(BString host, uint16 port);
|
||||||
|
void AddCertificateException(const BCertificate& certificate);
|
||||||
|
|
||||||
// Context accessors
|
// Context accessors
|
||||||
BNetworkCookieJar& GetCookieJar();
|
BNetworkCookieJar& GetCookieJar();
|
||||||
@ -37,12 +39,15 @@ public:
|
|||||||
bool UseProxy();
|
bool UseProxy();
|
||||||
BString GetProxyHost();
|
BString GetProxyHost();
|
||||||
uint16 GetProxyPort();
|
uint16 GetProxyPort();
|
||||||
|
bool HasCertificateException(const BCertificate& certificate);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
BNetworkCookieJar fCookieJar;
|
BNetworkCookieJar fCookieJar;
|
||||||
typedef BPrivate::SynchronizedHashMap<BPrivate::HashString,
|
typedef BPrivate::SynchronizedHashMap<BPrivate::HashString,
|
||||||
BHttpAuthentication*> BHttpAuthenticationMap;
|
BHttpAuthentication*> BHttpAuthenticationMap;
|
||||||
BHttpAuthenticationMap* fAuthenticationMap;
|
BHttpAuthenticationMap* fAuthenticationMap;
|
||||||
|
typedef BObjectList<const BCertificate> BCertificateSet;
|
||||||
|
BCertificateSet fCertificates;
|
||||||
|
|
||||||
BString fProxyHost;
|
BString fProxyHost;
|
||||||
uint16 fProxyPort;
|
uint16 fProxyPort;
|
||||||
|
@ -60,7 +60,7 @@ BCertificate::BCertificate(Private* data)
|
|||||||
|
|
||||||
BCertificate::BCertificate(const BCertificate& other)
|
BCertificate::BCertificate(const BCertificate& other)
|
||||||
{
|
{
|
||||||
fPrivate = new(std::nothrow) BCertificate::Private(other.fPrivate);
|
fPrivate = new(std::nothrow) BCertificate::Private(other.fPrivate->fX509);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -151,7 +151,7 @@ BCertificate::String() const
|
|||||||
|
|
||||||
|
|
||||||
bool
|
bool
|
||||||
BCertificate::operator==(const BCertificate& other)
|
BCertificate::operator==(const BCertificate& other) const
|
||||||
{
|
{
|
||||||
return X509_cmp(fPrivate->fX509, other.fPrivate->fX509) == 0;
|
return X509_cmp(fPrivate->fX509, other.fPrivate->fX509) == 0;
|
||||||
}
|
}
|
||||||
@ -168,7 +168,7 @@ BCertificate::Private::Private(X509* data)
|
|||||||
|
|
||||||
BCertificate::Private::~Private()
|
BCertificate::Private::~Private()
|
||||||
{
|
{
|
||||||
sk_X509_pop_free(fX509, X509_free);
|
X509_free(fX509);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -247,7 +247,7 @@ BCertificate::String() const
|
|||||||
|
|
||||||
|
|
||||||
bool
|
bool
|
||||||
BCertificate::operator==(const BCertificate& other)
|
BCertificate::operator==(const BCertificate& other) const
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2010-2014 Haiku Inc. All rights reserved.
|
* Copyright 2010-2015 Haiku Inc. All rights reserved.
|
||||||
* Distributed under the terms of the MIT License.
|
* Distributed under the terms of the MIT License.
|
||||||
*
|
*
|
||||||
* Authors:
|
* Authors:
|
||||||
@ -1083,9 +1083,14 @@ bool
|
|||||||
BHttpRequest::_CertificateVerificationFailed(BCertificate& certificate,
|
BHttpRequest::_CertificateVerificationFailed(BCertificate& certificate,
|
||||||
const char* message)
|
const char* message)
|
||||||
{
|
{
|
||||||
if (fListener != NULL) {
|
if (fContext->HasCertificateException(certificate))
|
||||||
return fListener->CertificateVerificationFailed(this, certificate,
|
return true;
|
||||||
message);
|
|
||||||
|
if (fListener != NULL
|
||||||
|
&& fListener->CertificateVerificationFailed(this, certificate, message)) {
|
||||||
|
// User asked us to continue anyway, let's add a temporary exception for this certificate
|
||||||
|
fContext->AddCertificateException(certificate);
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
|
@ -1,9 +1,10 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2010 Haiku Inc. All rights reserved.
|
* Copyright 2010-2015 Haiku Inc. All rights reserved.
|
||||||
* Distributed under the terms of the MIT License.
|
* Distributed under the terms of the MIT License.
|
||||||
*
|
*
|
||||||
* Authors:
|
* Authors:
|
||||||
* Christophe Huriaux, c.huriaux@gmail.com
|
* Christophe Huriaux, c.huriaux@gmail.com
|
||||||
|
* Adrien Destugues, pulkomandy@pulkomandy.tk
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
@ -19,6 +20,7 @@ BUrlContext::BUrlContext()
|
|||||||
:
|
:
|
||||||
fCookieJar(),
|
fCookieJar(),
|
||||||
fAuthenticationMap(NULL),
|
fAuthenticationMap(NULL),
|
||||||
|
fCertificates(20, true),
|
||||||
fProxyHost(),
|
fProxyHost(),
|
||||||
fProxyPort(0)
|
fProxyPort(0)
|
||||||
{
|
{
|
||||||
@ -84,6 +86,16 @@ BUrlContext::SetProxy(BString host, uint16 port)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
BUrlContext::AddCertificateException(const BCertificate& certificate)
|
||||||
|
{
|
||||||
|
BCertificate* copy = new(std::nothrow) BCertificate(certificate);
|
||||||
|
if (copy != NULL) {
|
||||||
|
fCertificates.AddItem(copy);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// #pragma mark Context accessors
|
// #pragma mark Context accessors
|
||||||
|
|
||||||
|
|
||||||
@ -133,3 +145,25 @@ BUrlContext::GetProxyPort()
|
|||||||
{
|
{
|
||||||
return fProxyPort;
|
return fProxyPort;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool
|
||||||
|
BUrlContext::HasCertificateException(const BCertificate& certificate)
|
||||||
|
{
|
||||||
|
struct Equals: public UnaryPredicate<const BCertificate> {
|
||||||
|
Equals(const BCertificate& itemToMatch)
|
||||||
|
:
|
||||||
|
fItemToMatch(itemToMatch)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
int operator()(const BCertificate* item) const
|
||||||
|
{
|
||||||
|
return *item == fItemToMatch;
|
||||||
|
}
|
||||||
|
|
||||||
|
const BCertificate& fItemToMatch;
|
||||||
|
} comparator(certificate);
|
||||||
|
|
||||||
|
return fCertificates.FindIf(comparator) != NULL;
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user