diff --git a/headers/os/net/Certificate.h b/headers/os/net/Certificate.h index fe064520d8..cb3bee4ee0 100644 --- a/headers/os/net/Certificate.h +++ b/headers/os/net/Certificate.h @@ -29,7 +29,7 @@ public: BString String() const; - bool operator==(const BCertificate& other); + bool operator==(const BCertificate& other) const; private: friend class BSecureSocket::Private; diff --git a/headers/os/net/UrlContext.h b/headers/os/net/UrlContext.h index d561ef5115..514c523ea4 100644 --- a/headers/os/net/UrlContext.h +++ b/headers/os/net/UrlContext.h @@ -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. */ @@ -8,6 +8,7 @@ #define _B_URL_CONTEXT_H_ +#include #include #include #include @@ -30,6 +31,7 @@ public: void AddAuthentication(const BUrl& url, const BHttpAuthentication& authentication); void SetProxy(BString host, uint16 port); + void AddCertificateException(const BCertificate& certificate); // Context accessors BNetworkCookieJar& GetCookieJar(); @@ -37,12 +39,15 @@ public: bool UseProxy(); BString GetProxyHost(); uint16 GetProxyPort(); + bool HasCertificateException(const BCertificate& certificate); private: BNetworkCookieJar fCookieJar; typedef BPrivate::SynchronizedHashMap BHttpAuthenticationMap; BHttpAuthenticationMap* fAuthenticationMap; + typedef BObjectList BCertificateSet; + BCertificateSet fCertificates; BString fProxyHost; uint16 fProxyPort; diff --git a/src/kits/network/libnetapi/Certificate.cpp b/src/kits/network/libnetapi/Certificate.cpp index ac2296b049..957790ddb9 100644 --- a/src/kits/network/libnetapi/Certificate.cpp +++ b/src/kits/network/libnetapi/Certificate.cpp @@ -60,7 +60,7 @@ BCertificate::BCertificate(Private* data) 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 -BCertificate::operator==(const BCertificate& other) +BCertificate::operator==(const BCertificate& other) const { return X509_cmp(fPrivate->fX509, other.fPrivate->fX509) == 0; } @@ -168,7 +168,7 @@ BCertificate::Private::Private(X509* data) BCertificate::Private::~Private() { - sk_X509_pop_free(fX509, X509_free); + X509_free(fX509); } @@ -247,7 +247,7 @@ BCertificate::String() const bool -BCertificate::operator==(const BCertificate& other) +BCertificate::operator==(const BCertificate& other) const { return false; } diff --git a/src/kits/network/libnetapi/HttpRequest.cpp b/src/kits/network/libnetapi/HttpRequest.cpp index 972c5ccbea..3c3625007f 100644 --- a/src/kits/network/libnetapi/HttpRequest.cpp +++ b/src/kits/network/libnetapi/HttpRequest.cpp @@ -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. * * Authors: @@ -1083,9 +1083,14 @@ bool BHttpRequest::_CertificateVerificationFailed(BCertificate& certificate, const char* message) { - if (fListener != NULL) { - return fListener->CertificateVerificationFailed(this, certificate, - message); + if (fContext->HasCertificateException(certificate)) + return true; + + 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; diff --git a/src/kits/network/libnetapi/UrlContext.cpp b/src/kits/network/libnetapi/UrlContext.cpp index 6a9f6e1028..4a7970a664 100644 --- a/src/kits/network/libnetapi/UrlContext.cpp +++ b/src/kits/network/libnetapi/UrlContext.cpp @@ -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. * * Authors: * Christophe Huriaux, c.huriaux@gmail.com + * Adrien Destugues, pulkomandy@pulkomandy.tk */ @@ -19,6 +20,7 @@ BUrlContext::BUrlContext() : fCookieJar(), fAuthenticationMap(NULL), + fCertificates(20, true), fProxyHost(), 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 @@ -133,3 +145,25 @@ BUrlContext::GetProxyPort() { return fProxyPort; } + + +bool +BUrlContext::HasCertificateException(const BCertificate& certificate) +{ + struct Equals: public UnaryPredicate { + 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; +}