--- a/netwerk/protocol/http/nsHttpChannel.cpp
+++ b/netwerk/protocol/http/nsHttpChannel.cpp
@@ -1576,17 +1576,17 @@ nsHttpChannel::ProcessSingleSecurityHead
nsAutoCString securityHeader;
nsresult rv = mResponseHead->GetHeader(atom, securityHeader);
if (NS_SUCCEEDED(rv)) {
nsISiteSecurityService* sss = gHttpHandler->GetSSService();
NS_ENSURE_TRUE(sss, NS_ERROR_OUT_OF_MEMORY);
// Process header will now discard the headers itself if the channel
// wasn't secure (whereas before it had to be checked manually)
uint32_t failureResult;
- rv = sss->ProcessHeader(aType, mURI, securityHeader.get(), aSSLStatus,
+ rv = sss->ProcessHeader(aType, mURI, securityHeader, aSSLStatus,
aFlags, nullptr, nullptr, &failureResult);
if (NS_FAILED(rv)) {
nsAutoString consoleErrorCategory;
nsAutoString consoleErrorTag;
switch (aType) {
case nsISiteSecurityService::HEADER_HSTS:
GetSTSConsoleErrorTag(failureResult, consoleErrorTag);
consoleErrorCategory = NS_LITERAL_STRING("Invalid HSTS Headers");
--- a/security/manager/ssl/ContentSignatureVerifier.cpp
+++ b/security/manager/ssl/ContentSignatureVerifier.cpp
@@ -13,16 +13,17 @@
#include "mozilla/Assertions.h"
#include "mozilla/Casting.h"
#include "mozilla/Unused.h"
#include "nsCOMPtr.h"
#include "nsContentUtils.h"
#include "nsISupportsPriority.h"
#include "nsIURI.h"
#include "nsNSSComponent.h"
+#include "nsPromiseFlatString.h"
#include "nsSecurityHeaderParser.h"
#include "nsStreamUtils.h"
#include "nsWhitespaceTokenizer.h"
#include "nsXPCOMStrings.h"
#include "nssb64.h"
#include "pkix/pkix.h"
#include "pkix/pkixtypes.h"
#include "secerr.h"
@@ -428,17 +429,18 @@ nsresult
ContentSignatureVerifier::ParseContentSignatureHeader(
const nsACString& aContentSignatureHeader)
{
MOZ_ASSERT(NS_IsMainThread());
// We only support p384 ecdsa according to spec
NS_NAMED_LITERAL_CSTRING(signature_var, "p384ecdsa");
NS_NAMED_LITERAL_CSTRING(certChainURL_var, "x5u");
- nsSecurityHeaderParser parser(aContentSignatureHeader.BeginReading());
+ const nsCString& flatHeader = PromiseFlatCString(aContentSignatureHeader);
+ nsSecurityHeaderParser parser(flatHeader);
nsresult rv = parser.Parse();
if (NS_FAILED(rv)) {
CSVerifier_LOG(("CSVerifier: could not parse ContentSignature header\n"));
return NS_ERROR_FAILURE;
}
LinkedList<nsSecurityHeaderDirective>* directives = parser.GetDirectives();
for (nsSecurityHeaderDirective* directive = directives->getFirst();
--- a/security/manager/ssl/ContentSignatureVerifier.h
+++ b/security/manager/ssl/ContentSignatureVerifier.h
@@ -8,16 +8,17 @@
#ifndef ContentSignatureVerifier_h
#define ContentSignatureVerifier_h
#include "cert.h"
#include "CSTrustDomain.h"
#include "nsIContentSignatureVerifier.h"
#include "nsIStreamListener.h"
#include "nsNSSShutDown.h"
+#include "nsString.h"
#include "ScopedNSSTypes.h"
// 45a5fe2f-c350-4b86-962d-02d5aaaa955a
#define NS_CONTENTSIGNATUREVERIFIER_CID \
{ 0x45a5fe2f, 0xc350, 0x4b86, \
{ 0x96, 0x2d, 0x02, 0xd5, 0xaa, 0xaa, 0x95, 0x5a } }
#define NS_CONTENTSIGNATUREVERIFIER_CONTRACTID \
"@mozilla.org/security/contentsignatureverifier;1"
--- a/security/manager/ssl/PublicKeyPinningService.cpp
+++ b/security/manager/ssl/PublicKeyPinningService.cpp
@@ -4,16 +4,17 @@
#include "PublicKeyPinningService.h"
#include "RootCertificateTelemetryUtils.h"
#include "mozilla/Base64.h"
#include "mozilla/Casting.h"
#include "mozilla/Logging.h"
#include "mozilla/Telemetry.h"
+#include "nsDependentString.h"
#include "nsISiteSecurityService.h"
#include "nsServiceManagerUtils.h"
#include "nsSiteSecurityService.h"
#include "nssb64.h"
#include "pkix/pkixtypes.h"
#include "seccomon.h"
#include "sechash.h"
@@ -176,18 +177,18 @@ FindPinningInformation(const char* hostn
while (!foundEntry && (evalPart = strchr(evalHost, '.'))) {
MOZ_LOG(gPublicKeyPinningLog, LogLevel::Debug,
("pkpin: Querying pinsets for host: '%s'\n", evalHost));
// Attempt dynamic pins first
nsresult rv;
bool found;
bool includeSubdomains;
nsTArray<nsCString> pinArray;
- rv = sssService->GetKeyPinsForHostname(evalHost, time, pinArray,
- &includeSubdomains, &found);
+ rv = sssService->GetKeyPinsForHostname(nsDependentCString(evalHost), time,
+ pinArray, &includeSubdomains, &found);
if (NS_FAILED(rv)) {
return rv;
}
if (found && (evalHost == hostname || includeSubdomains)) {
MOZ_LOG(gPublicKeyPinningLog, LogLevel::Debug,
("pkpin: Found dyn match for host: '%s'\n", evalHost));
dynamicFingerprints = pinArray;
return NS_OK;
--- a/security/manager/ssl/SSLServerCertVerification.cpp
+++ b/security/manager/ssl/SSLServerCertVerification.cpp
@@ -507,28 +507,28 @@ CertErrorRunnable::CheckCertOverrides()
if (!sss) {
MOZ_LOG(gPIPNSSLog, LogLevel::Debug,
("[%p][%p] couldn't get nsISiteSecurityService to check for HSTS/HPKP\n",
mFdForLogging, this));
return new SSLServerCertVerificationResult(mInfoObject,
mDefaultErrorCodeToReport);
}
nsresult nsrv = sss->IsSecureHost(nsISiteSecurityService::HEADER_HSTS,
- mInfoObject->GetHostNameRaw(),
+ mInfoObject->GetHostName(),
mProviderFlags,
nullptr,
&strictTransportSecurityEnabled);
if (NS_FAILED(nsrv)) {
MOZ_LOG(gPIPNSSLog, LogLevel::Debug,
("[%p][%p] checking for HSTS failed\n", mFdForLogging, this));
return new SSLServerCertVerificationResult(mInfoObject,
mDefaultErrorCodeToReport);
}
nsrv = sss->IsSecureHost(nsISiteSecurityService::HEADER_HPKP,
- mInfoObject->GetHostNameRaw(),
+ mInfoObject->GetHostName(),
mProviderFlags,
nullptr,
&hasPinningInformation);
if (NS_FAILED(nsrv)) {
MOZ_LOG(gPIPNSSLog, LogLevel::Debug,
("[%p][%p] checking for HPKP failed\n", mFdForLogging, this));
return new SSLServerCertVerificationResult(mInfoObject,
mDefaultErrorCodeToReport);
--- a/security/manager/ssl/nsISiteSecurityService.idl
+++ b/security/manager/ssl/nsISiteSecurityService.idl
@@ -55,45 +55,45 @@ interface nsISiteSecurityService : nsISu
* upgraded to HTTPS.
* The format of the HPKP header is defined by the HPKP specification:
* https://tools.ietf.org/html/rfc7469
* and allows a host to specify a subset of trusted anchors to be used
* in future HTTPS connections.
*
* @param aType the type of security header in question.
* @param aSourceURI the URI of the resource with the HTTP header.
- * @param aSSLStatus the SSLStatus of the current channel
* @param aHeader the HTTP response header specifying security data.
+ * @param aSSLStatus the SSLStatus of the current channel.
* @param aFlags options for this request as defined in nsISocketProvider:
* NO_PERMANENT_STORAGE
* @param aMaxAge the parsed max-age directive of the header.
* @param aIncludeSubdomains the parsed includeSubdomains directive.
* @param aFailureResult a more specific failure result if NS_ERROR_FAILURE
was returned.
* @return NS_OK if it succeeds
* NS_ERROR_FAILURE if it can't be parsed
* NS_SUCCESS_LOSS_OF_INSIGNIFICANT_DATA
* if there are unrecognized tokens in the header.
*/
void processHeader(in uint32_t aType,
in nsIURI aSourceURI,
- in string aHeader,
+ in ACString aHeader,
in nsISSLStatus aSSLStatus,
in uint32_t aFlags,
[optional] out unsigned long long aMaxAge,
[optional] out boolean aIncludeSubdomains,
[optional] out uint32_t aFailureResult);
/**
* Same as processHeader but without checking for the security properties
* of the connection. Use ONLY for testing.
*/
void unsafeProcessHeader(in uint32_t aType,
in nsIURI aSourceURI,
- in string aHeader,
+ in ACString aHeader,
in uint32_t aFlags,
[optional] out unsigned long long aMaxAge,
[optional] out boolean aIncludeSubdomains,
[optional] out uint32_t aFailureResult);
/**
* Given a header type, removes state relating to that header of a host,
* including the includeSubdomains state that would affect subdomains.
@@ -114,17 +114,17 @@ interface nsISiteSecurityService : nsISu
* @param aType the type of security state in question.
* @param aHost the hostname (punycode) to query for state.
* @param aFlags options for this request as defined in nsISocketProvider:
* NO_PERMANENT_STORAGE
* @param aCached true if we have cached information regarding whether or not
* the host is HSTS, false otherwise.
*/
boolean isSecureHost(in uint32_t aType,
- in string aHost,
+ in ACString aHost,
in uint32_t aFlags,
[optional] out boolean aCached);
/**
* Checks whether or not the URI's hostname has a given security state set.
* For example, for HSTS:
* The URI is an HSTS URI if either the host has the HSTS state set, or one
* of its super-domains has the HSTS "includeSubdomains" flag set.
@@ -154,24 +154,24 @@ interface nsISiteSecurityService : nsISu
void clearPreloads();
/**
* Returns an array of sha256-hashed key pins for the given domain, if any.
* If these pins also apply to subdomains of the given domain,
* aIncludeSubdomains will be true. Pins returned are only for non-built-in
* pin entries.
*
- * @param aHostname the hosname (punycode) to be queried about
- * @param the time at which the pins should be valid. This is in
+ * @param aHostname the hostname (punycode) to be queried about
+ * @param evalTime the time at which the pins should be valid. This is in
mozilla::pkix::Time which uses internally seconds since 0 AD.
* @param aPinArray the set of sha256-hashed key pins for the given domain
* @param aIncludeSubdomains true if the pins apply to subdomains of the
* given domain
*/
- [noscript] boolean getKeyPinsForHostname(in string aHostname,
+ [noscript] boolean getKeyPinsForHostname(in ACString aHostname,
in mozillaPkixTime evalTime,
out nsCStringTArrayRef aPinArray,
out boolean aIncludeSubdomains);
/**
* Set public-key pins for a host. The resulting pins will be permanent
* and visible from private and non-private contexts. These pins replace
* any already set by this mechanism or those built-in to Gecko.
@@ -179,32 +179,32 @@ interface nsISiteSecurityService : nsISu
* @param aHost the hostname (punycode) that pins will apply to
* @param aIncludeSubdomains whether these pins also apply to subdomains
* @param aExpires the time this pin should expire (millis since epoch)
* @param aPinCount number of keys being pinnned
* @param aSha256Pins array of hashed key fingerprints (SHA-256, base64)
* @param aIsPreload are these key pins for a preload entry? (false by
* default)
*/
- boolean setKeyPins(in string aHost, in boolean aIncludeSubdomains,
+ boolean setKeyPins(in ACString aHost, in boolean aIncludeSubdomains,
in int64_t aExpires, in unsigned long aPinCount,
[array, size_is(aPinCount)] in string aSha256Pins,
[optional] in boolean aIsPreload);
/**
* Set an HSTS preload entry for a host. The resulting entries will be
* permanent and visible from private and non-private contexts. These
* entries replace any already set by this mechanism or those built-in to
* Gecko.
*
* @param aHost the hostname (punycode) that the entry applies to
* @param aIncludeSubdomains whether this entry also applies to subdomains
* @param aExpires the time this entry should expire (millis since epoch)
*/
- boolean setHSTSPreload(in string aHost, in boolean aIncludesSubdomains,
+ boolean setHSTSPreload(in ACString aHost, in boolean aIncludesSubdomains,
in int64_t aExpires);
/**
* Mark a host as declining to provide a given security state so that features
* such as HSTS priming will not flood a server with requests.
*
* @param aURI the nsIURI that this applies to
* @param aMaxAge lifetime (in seconds) of this negative cache
--- a/security/manager/ssl/nsSecurityHeaderParser.cpp
+++ b/security/manager/ssl/nsSecurityHeaderParser.cpp
@@ -45,18 +45,18 @@ bool
IsQuotedPairSymbol(signed char chr) {
return (chr >= 0);
}
static mozilla::LazyLogModule sSHParserLog("nsSecurityHeaderParser");
#define SHPARSERLOG(args) MOZ_LOG(sSHParserLog, mozilla::LogLevel::Debug, args)
-nsSecurityHeaderParser::nsSecurityHeaderParser(const char *aHeader)
- : mCursor(aHeader)
+nsSecurityHeaderParser::nsSecurityHeaderParser(const nsCString& aHeader)
+ : mCursor(aHeader.get())
, mError(false)
{
}
nsSecurityHeaderParser::~nsSecurityHeaderParser() {
nsSecurityHeaderDirective *directive;
while ((directive = mDirectives.popFirst())) {
delete directive;
--- a/security/manager/ssl/nsSecurityHeaderParser.h
+++ b/security/manager/ssl/nsSecurityHeaderParser.h
@@ -1,18 +1,18 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-#ifndef nsSecurityHeaderParser_h__
-#define nsSecurityHeaderParser_h__
+#ifndef nsSecurityHeaderParser_h
+#define nsSecurityHeaderParser_h
-#include "nsString.h"
#include "mozilla/LinkedList.h"
#include "nsCOMPtr.h"
+#include "nsString.h"
// Utility class for handing back parsed directives and (optional) values
class nsSecurityHeaderDirective : public mozilla::LinkedListElement<nsSecurityHeaderDirective> {
public:
nsCString mName;
nsCString mValue;
};
@@ -31,17 +31,19 @@ public:
//
// token = <token, defined in [RFC2616], Section 2.2>
// quoted-string = <quoted-string, defined in [RFC2616], Section 2.2>/
//
// For further reference, see [RFC6797], Section 6.1
class nsSecurityHeaderParser {
public:
- explicit nsSecurityHeaderParser(const char *aHeader);
+ // The input to this class must be null-terminated, and must have a lifetime
+ // greater than or equal to the lifetime of the created nsSecurityHeaderParser.
+ explicit nsSecurityHeaderParser(const nsCString& aHeader);
~nsSecurityHeaderParser();
// Only call Parse once.
nsresult Parse();
// The caller does not take ownership of the memory returned here.
mozilla::LinkedList<nsSecurityHeaderDirective> *GetDirectives();
private:
@@ -66,9 +68,9 @@ private:
mozilla::LinkedList<nsSecurityHeaderDirective> mDirectives;
const char *mCursor;
nsSecurityHeaderDirective *mDirective;
nsCString mOutput;
bool mError;
};
-#endif /* nsSecurityHeaderParser_h__ */
+#endif // nsSecurityHeaderParser_h
--- a/security/manager/ssl/nsSiteSecurityService.cpp
+++ b/security/manager/ssl/nsSiteSecurityService.cpp
@@ -16,21 +16,20 @@
#include "mozilla/Preferences.h"
#include "nsCRTGlue.h"
#include "nsISSLStatus.h"
#include "nsISocketProvider.h"
#include "nsIURI.h"
#include "nsIX509Cert.h"
#include "nsNSSComponent.h"
#include "nsNetUtil.h"
+#include "nsPromiseFlatString.h"
#include "nsSecurityHeaderParser.h"
-#include "nsString.h"
#include "nsThreadUtils.h"
#include "nsXULAppAPI.h"
-#include "pkix/pkixtypes.h"
#include "plstr.h"
#include "prnetdb.h"
#include "prprf.h"
// A note about the preload list:
// When a site specifically disables HSTS by sending a header with
// 'max-age: 0', we keep a "knockout" value that means "we have no information
// regarding the HSTS state of this host" (any ancestor of "this host" can still
@@ -431,71 +430,76 @@ nsSiteSecurityService::RemoveState(uint3
uint32_t aFlags)
{
nsAutoCString hostname;
GetHost(aURI, hostname);
return RemoveStateInternal(aType, hostname, aFlags, false);
}
static bool
-HostIsIPAddress(const char *hostname)
+HostIsIPAddress(const nsCString& hostname)
{
PRNetAddr hostAddr;
- return (PR_StringToNetAddr(hostname, &hostAddr) == PR_SUCCESS);
+ PRErrorCode prv = PR_StringToNetAddr(hostname.get(), &hostAddr);
+ return (prv == PR_SUCCESS);
}
NS_IMETHODIMP
nsSiteSecurityService::ProcessHeader(uint32_t aType,
nsIURI* aSourceURI,
- const char* aHeader,
+ const nsACString& aHeader,
nsISSLStatus* aSSLStatus,
uint32_t aFlags,
uint64_t* aMaxAge,
bool* aIncludeSubdomains,
uint32_t* aFailureResult)
{
- // Child processes are not allowed direct access to this.
- if (!XRE_IsParentProcess()) {
- MOZ_CRASH("Child process: no direct access to nsISiteSecurityService::ProcessHeader");
- }
+ // Child processes are not allowed direct access to this.
+ if (!XRE_IsParentProcess()) {
+ MOZ_CRASH("Child process: no direct access to "
+ "nsISiteSecurityService::ProcessHeader");
+ }
if (aFailureResult) {
*aFailureResult = nsISiteSecurityService::ERROR_UNKNOWN;
}
NS_ENSURE_TRUE(aType == nsISiteSecurityService::HEADER_HSTS ||
aType == nsISiteSecurityService::HEADER_HPKP,
NS_ERROR_NOT_IMPLEMENTED);
NS_ENSURE_ARG(aSSLStatus);
- return ProcessHeaderInternal(aType, aSourceURI, aHeader, aSSLStatus, aFlags,
- aMaxAge, aIncludeSubdomains, aFailureResult);
+ return ProcessHeaderInternal(aType, aSourceURI, PromiseFlatCString(aHeader),
+ aSSLStatus, aFlags, aMaxAge, aIncludeSubdomains,
+ aFailureResult);
}
NS_IMETHODIMP
nsSiteSecurityService::UnsafeProcessHeader(uint32_t aType,
nsIURI* aSourceURI,
- const char* aHeader,
+ const nsACString& aHeader,
uint32_t aFlags,
uint64_t* aMaxAge,
bool* aIncludeSubdomains,
uint32_t* aFailureResult)
{
- // Child processes are not allowed direct access to this.
- if (!XRE_IsParentProcess()) {
- MOZ_CRASH("Child process: no direct access to nsISiteSecurityService::UnsafeProcessHeader");
- }
+ // Child processes are not allowed direct access to this.
+ if (!XRE_IsParentProcess()) {
+ MOZ_CRASH("Child process: no direct access to "
+ "nsISiteSecurityService::UnsafeProcessHeader");
+ }
- return ProcessHeaderInternal(aType, aSourceURI, aHeader, nullptr, aFlags,
- aMaxAge, aIncludeSubdomains, aFailureResult);
+ return ProcessHeaderInternal(aType, aSourceURI, PromiseFlatCString(aHeader),
+ nullptr, aFlags, aMaxAge, aIncludeSubdomains,
+ aFailureResult);
}
nsresult
nsSiteSecurityService::ProcessHeaderInternal(uint32_t aType,
nsIURI* aSourceURI,
- const char* aHeader,
+ const nsCString& aHeader,
nsISSLStatus* aSSLStatus,
uint32_t aFlags,
uint64_t* aMaxAge,
bool* aIncludeSubdomains,
uint32_t* aFailureResult)
{
if (aFailureResult) {
*aFailureResult = nsISiteSecurityService::ERROR_UNKNOWN;
@@ -535,17 +539,17 @@ nsSiteSecurityService::ProcessHeaderInte
}
return NS_ERROR_FAILURE;
}
}
nsAutoCString host;
nsresult rv = GetHost(aSourceURI, host);
NS_ENSURE_SUCCESS(rv, rv);
- if (HostIsIPAddress(host.get())) {
+ if (HostIsIPAddress(host)) {
/* Don't process headers if a site is accessed by IP address. */
return NS_OK;
}
switch (aType) {
case nsISiteSecurityService::HEADER_HSTS:
rv = ProcessSTSHeader(aSourceURI, aHeader, aFlags, aMaxAge,
aIncludeSubdomains, aFailureResult);
@@ -557,17 +561,17 @@ nsSiteSecurityService::ProcessHeaderInte
default:
MOZ_CRASH("unexpected header type");
}
return rv;
}
static uint32_t
ParseSSSHeaders(uint32_t aType,
- const char* aHeader,
+ const nsCString& aHeader,
bool& foundIncludeSubdomains,
bool& foundMaxAge,
bool& foundUnrecognizedDirective,
uint64_t& maxAge,
nsTArray<nsCString>& sha256keys)
{
// Strict transport security and Public Key Pinning have very similar
// Header formats.
@@ -698,27 +702,27 @@ ParseSSSHeaders(uint32_t aType,
foundUnrecognizedDirective = true;
}
}
return nsISiteSecurityService::Success;
}
nsresult
nsSiteSecurityService::ProcessPKPHeader(nsIURI* aSourceURI,
- const char* aHeader,
+ const nsCString& aHeader,
nsISSLStatus* aSSLStatus,
uint32_t aFlags,
uint64_t* aMaxAge,
bool* aIncludeSubdomains,
uint32_t* aFailureResult)
{
if (aFailureResult) {
*aFailureResult = nsISiteSecurityService::ERROR_UNKNOWN;
}
- SSSLOG(("SSS: processing HPKP header '%s'", aHeader));
+ SSSLOG(("SSS: processing HPKP header '%s'", aHeader.get()));
NS_ENSURE_ARG(aSSLStatus);
const uint32_t aType = nsISiteSecurityService::HEADER_HPKP;
bool foundMaxAge = false;
bool foundIncludeSubdomains = false;
bool foundUnrecognizedDirective = false;
uint64_t maxAge = 0;
nsTArray<nsCString> sha256keys;
@@ -872,26 +876,26 @@ nsSiteSecurityService::ProcessPKPHeader(
return foundUnrecognizedDirective
? NS_SUCCESS_LOSS_OF_INSIGNIFICANT_DATA
: NS_OK;
}
nsresult
nsSiteSecurityService::ProcessSTSHeader(nsIURI* aSourceURI,
- const char* aHeader,
+ const nsCString& aHeader,
uint32_t aFlags,
uint64_t* aMaxAge,
bool* aIncludeSubdomains,
uint32_t* aFailureResult)
{
if (aFailureResult) {
*aFailureResult = nsISiteSecurityService::ERROR_UNKNOWN;
}
- SSSLOG(("SSS: processing HSTS header '%s'", aHeader));
+ SSSLOG(("SSS: processing HSTS header '%s'", aHeader.get()));
const uint32_t aType = nsISiteSecurityService::HEADER_HSTS;
bool foundMaxAge = false;
bool foundIncludeSubdomains = false;
bool foundUnrecognizedDirective = false;
uint64_t maxAge = 0;
nsTArray<nsCString> unusedSHA256keys; // Required for sane internal interface
@@ -960,22 +964,22 @@ nsSiteSecurityService::IsSecureURI(uint3
NS_ENSURE_TRUE(aType == nsISiteSecurityService::HEADER_HSTS ||
aType == nsISiteSecurityService::HEADER_HPKP,
NS_ERROR_NOT_IMPLEMENTED);
nsAutoCString hostname;
nsresult rv = GetHost(aURI, hostname);
NS_ENSURE_SUCCESS(rv, rv);
/* An IP address never qualifies as a secure URI. */
- if (HostIsIPAddress(hostname.get())) {
+ if (HostIsIPAddress(hostname)) {
*aResult = false;
return NS_OK;
}
- return IsSecureHost(aType, hostname.get(), aFlags, aCached, aResult);
+ return IsSecureHost(aType, hostname, aFlags, aCached, aResult);
}
int STSPreloadCompare(const void *key, const void *entry)
{
const char *keyStr = (const char *)key;
const nsSTSPreload *preloadEntry = (const nsSTSPreload *)entry;
return strcmp(keyStr, &kSTSHostTable[preloadEntry->mHostIndex]);
}
@@ -1104,61 +1108,64 @@ nsSiteSecurityService::HostHasHSTSEntry(
}
return true;
}
return false;
}
NS_IMETHODIMP
-nsSiteSecurityService::IsSecureHost(uint32_t aType, const char* aHost,
+nsSiteSecurityService::IsSecureHost(uint32_t aType, const nsACString& aHost,
uint32_t aFlags, bool* aCached,
bool* aResult)
{
- // Child processes are not allowed direct access to this.
- if (!XRE_IsParentProcess() && aType != nsISiteSecurityService::HEADER_HSTS) {
- MOZ_CRASH("Child process: no direct access to nsISiteSecurityService::IsSecureHost for non-HSTS entries");
- }
+ // Child processes are not allowed direct access to this.
+ if (!XRE_IsParentProcess() && aType != nsISiteSecurityService::HEADER_HSTS) {
+ MOZ_CRASH("Child process: no direct access to "
+ "nsISiteSecurityService::IsSecureHost for non-HSTS entries");
+ }
- NS_ENSURE_ARG(aHost);
NS_ENSURE_ARG(aResult);
// Only HSTS and HPKP are supported at the moment.
NS_ENSURE_TRUE(aType == nsISiteSecurityService::HEADER_HSTS ||
aType == nsISiteSecurityService::HEADER_HPKP,
NS_ERROR_NOT_IMPLEMENTED);
// set default in case if we can't find any STS information
*aResult = false;
if (aCached) {
*aCached = false;
}
/* An IP address never qualifies as a secure URI. */
- if (HostIsIPAddress(aHost)) {
+ const nsCString& flatHost = PromiseFlatCString(aHost);
+ if (HostIsIPAddress(flatHost)) {
return NS_OK;
}
if (aType == nsISiteSecurityService::HEADER_HPKP) {
RefPtr<SharedCertVerifier> certVerifier(GetDefaultCertVerifier());
if (!certVerifier) {
return NS_ERROR_FAILURE;
}
if (certVerifier->mPinningMode ==
CertVerifier::PinningMode::pinningDisabled) {
return NS_OK;
}
bool enforceTestMode = certVerifier->mPinningMode ==
CertVerifier::PinningMode::pinningEnforceTestMode;
- return PublicKeyPinningService::HostHasPins(aHost, mozilla::pkix::Now(),
+ return PublicKeyPinningService::HostHasPins(flatHost.get(),
+ mozilla::pkix::Now(),
enforceTestMode, *aResult);
}
// Holepunch chart.apis.google.com and subdomains.
- nsAutoCString host(PublicKeyPinningService::CanonicalizeHostname(aHost));
+ nsAutoCString host(
+ PublicKeyPinningService::CanonicalizeHostname(flatHost.get()));
if (host.EqualsLiteral("chart.apis.google.com") ||
StringEndsWith(host, NS_LITERAL_CSTRING(".chart.apis.google.com"))) {
if (aCached) {
*aCached = true;
}
return NS_OK;
}
@@ -1222,35 +1229,38 @@ nsSiteSecurityService::ClearPreloads()
}
bool entryStateNotOK(SiteHPKPState& state, mozilla::pkix::Time& aEvalTime) {
return state.mState != SecurityPropertySet || state.IsExpired(aEvalTime) ||
state.mSHA256keys.Length() < 1;
}
NS_IMETHODIMP
-nsSiteSecurityService::GetKeyPinsForHostname(const char* aHostname,
+nsSiteSecurityService::GetKeyPinsForHostname(const nsACString& aHostname,
mozilla::pkix::Time& aEvalTime,
/*out*/ nsTArray<nsCString>& pinArray,
/*out*/ bool* aIncludeSubdomains,
- /*out*/ bool* afound) {
- // Child processes are not allowed direct access to this.
- if (!XRE_IsParentProcess()) {
- MOZ_CRASH("Child process: no direct access to nsISiteSecurityService::GetKeyPinsForHostname");
- }
+ /*out*/ bool* afound)
+{
+ // Child processes are not allowed direct access to this.
+ if (!XRE_IsParentProcess()) {
+ MOZ_CRASH("Child process: no direct access to "
+ "nsISiteSecurityService::GetKeyPinsForHostname");
+ }
NS_ENSURE_ARG(afound);
- NS_ENSURE_ARG(aHostname);
- SSSLOG(("Top of GetKeyPinsForHostname for %s", aHostname));
+ const nsCString& flatHostname = PromiseFlatCString(aHostname);
+ SSSLOG(("Top of GetKeyPinsForHostname for %s", flatHostname.get()));
*afound = false;
*aIncludeSubdomains = false;
pinArray.Clear();
- nsAutoCString host(PublicKeyPinningService::CanonicalizeHostname(aHostname));
+ nsAutoCString host(
+ PublicKeyPinningService::CanonicalizeHostname(flatHostname.get()));
nsAutoCString storageKey;
SetStorageKey(storageKey, host, nsISiteSecurityService::HEADER_HPKP);
SSSLOG(("storagekey '%s'\n", storageKey.get()));
mozilla::DataStorageType storageType = mozilla::DataStorage_Persistent;
nsCString value = mSiteStateStorage->Get(storageKey, storageType);
// decode now
@@ -1274,28 +1284,29 @@ nsSiteSecurityService::GetKeyPinsForHost
}
pinArray = foundEntry.mSHA256keys;
*aIncludeSubdomains = foundEntry.mIncludeSubdomains;
*afound = true;
return NS_OK;
}
NS_IMETHODIMP
-nsSiteSecurityService::SetKeyPins(const char* aHost, bool aIncludeSubdomains,
+nsSiteSecurityService::SetKeyPins(const nsACString& aHost,
+ bool aIncludeSubdomains,
int64_t aExpires, uint32_t aPinCount,
const char** aSha256Pins,
bool aIsPreload,
/*out*/ bool* aResult)
{
- // Child processes are not allowed direct access to this.
- if (!XRE_IsParentProcess()) {
- MOZ_CRASH("Child process: no direct access to nsISiteSecurityService::SetKeyPins");
- }
+ // Child processes are not allowed direct access to this.
+ if (!XRE_IsParentProcess()) {
+ MOZ_CRASH("Child process: no direct access to "
+ "nsISiteSecurityService::SetKeyPins");
+ }
- NS_ENSURE_ARG_POINTER(aHost);
NS_ENSURE_ARG_POINTER(aResult);
NS_ENSURE_ARG_POINTER(aSha256Pins);
SSSLOG(("Top of SetKeyPins"));
nsTArray<nsCString> sha256keys;
for (unsigned int i = 0; i < aPinCount; i++) {
nsAutoCString pin(aSha256Pins[i]);
@@ -1303,37 +1314,41 @@ nsSiteSecurityService::SetKeyPins(const
if (!stringIsBase64EncodingOf256bitValue(pin)) {
return NS_ERROR_INVALID_ARG;
}
sha256keys.AppendElement(pin);
}
SiteHPKPState dynamicEntry(aExpires, SecurityPropertySet,
aIncludeSubdomains, sha256keys);
// we always store data in permanent storage (ie no flags)
- nsAutoCString host(PublicKeyPinningService::CanonicalizeHostname(aHost));
+ const nsCString& flatHost = PromiseFlatCString(aHost);
+ nsAutoCString host(
+ PublicKeyPinningService::CanonicalizeHostname(flatHost.get()));
return SetHPKPState(host.get(), dynamicEntry, 0, aIsPreload);
}
NS_IMETHODIMP
-nsSiteSecurityService::SetHSTSPreload(const char* aHost,
+nsSiteSecurityService::SetHSTSPreload(const nsACString& aHost,
bool aIncludeSubdomains,
int64_t aExpires,
/*out*/ bool* aResult)
{
- // Child processes are not allowed direct access to this.
- if (!XRE_IsParentProcess()) {
- MOZ_CRASH("Child process: no direct access to nsISiteSecurityService::SetHSTSPreload");
- }
+ // Child processes are not allowed direct access to this.
+ if (!XRE_IsParentProcess()) {
+ MOZ_CRASH("Child process: no direct access to "
+ "nsISiteSecurityService::SetHSTSPreload");
+ }
- NS_ENSURE_ARG_POINTER(aHost);
NS_ENSURE_ARG_POINTER(aResult);
SSSLOG(("Top of SetHSTSPreload"));
- nsAutoCString host(PublicKeyPinningService::CanonicalizeHostname(aHost));
+ const nsCString& flatHost = PromiseFlatCString(aHost);
+ nsAutoCString host(
+ PublicKeyPinningService::CanonicalizeHostname(flatHost.get()));
return SetHSTSState(nsISiteSecurityService::HEADER_HSTS, host.get(), aExpires,
aIncludeSubdomains, 0, SecurityPropertySet, true);
}
nsresult
nsSiteSecurityService::SetHPKPState(const char* aHost, SiteHPKPState& entry,
uint32_t aFlags, bool aIsPreload)
{
--- a/security/manager/ssl/nsSiteSecurityService.h
+++ b/security/manager/ssl/nsSiteSecurityService.h
@@ -127,24 +127,25 @@ protected:
virtual ~nsSiteSecurityService();
private:
nsresult GetHost(nsIURI *aURI, nsACString &aResult);
nsresult SetHSTSState(uint32_t aType, const char* aHost, int64_t maxage,
bool includeSubdomains, uint32_t flags,
SecurityPropertyState aHSTSState, bool aIsPreload);
nsresult ProcessHeaderInternal(uint32_t aType, nsIURI* aSourceURI,
- const char* aHeader, nsISSLStatus* aSSLStatus,
+ const nsCString& aHeader,
+ nsISSLStatus* aSSLStatus,
uint32_t aFlags, uint64_t* aMaxAge,
bool* aIncludeSubdomains,
uint32_t* aFailureResult);
- nsresult ProcessSTSHeader(nsIURI* aSourceURI, const char* aHeader,
+ nsresult ProcessSTSHeader(nsIURI* aSourceURI, const nsCString& aHeader,
uint32_t flags, uint64_t* aMaxAge,
bool* aIncludeSubdomains, uint32_t* aFailureResult);
- nsresult ProcessPKPHeader(nsIURI* aSourceURI, const char* aHeader,
+ nsresult ProcessPKPHeader(nsIURI* aSourceURI, const nsCString& aHeader,
nsISSLStatus* aSSLStatus, uint32_t flags,
uint64_t* aMaxAge, bool* aIncludeSubdomains,
uint32_t* aFailureResult);
nsresult SetHPKPState(const char* aHost, SiteHPKPState& entry, uint32_t flags,
bool aIsPreload);
nsresult RemoveStateInternal(uint32_t aType, const nsAutoCString& aHost,
uint32_t aFlags, bool aIsPreload);
bool HostHasHSTSEntry(const nsAutoCString& aHost,
--- a/security/manager/ssl/tests/gtest/STSParserTest.cpp
+++ b/security/manager/ssl/tests/gtest/STSParserTest.cpp
@@ -1,32 +1,34 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include <stdio.h>
#include "gtest/gtest.h"
+#include "nsDependentString.h"
#include "nsNetUtil.h"
#include "nsISiteSecurityService.h"
#include "nsIURI.h"
void
TestSuccess(const char* hdr, bool extraTokens,
uint64_t expectedMaxAge, bool expectedIncludeSubdomains,
nsISiteSecurityService* sss)
{
nsCOMPtr<nsIURI> dummyUri;
nsresult rv = NS_NewURI(getter_AddRefs(dummyUri), "https://foo.com/bar.html");
ASSERT_TRUE(NS_SUCCEEDED(rv)) << "Failed to create URI";
uint64_t maxAge = 0;
bool includeSubdomains = false;
rv = sss->UnsafeProcessHeader(nsISiteSecurityService::HEADER_HSTS, dummyUri,
- hdr, 0, &maxAge, &includeSubdomains, nullptr);
+ nsDependentCString(hdr), 0, &maxAge,
+ &includeSubdomains, nullptr);
ASSERT_TRUE(NS_SUCCEEDED(rv)) << "Failed to process valid header: " << hdr;
ASSERT_EQ(maxAge, expectedMaxAge) << "Did not correctly parse maxAge";
EXPECT_EQ(includeSubdomains, expectedIncludeSubdomains) <<
"Did not correctly parse presence/absence of includeSubdomains";
if (extraTokens) {
EXPECT_EQ(rv, NS_SUCCESS_LOSS_OF_INSIGNIFICANT_DATA) <<
@@ -41,17 +43,18 @@ TestSuccess(const char* hdr, bool extraT
void TestFailure(const char* hdr,
nsISiteSecurityService* sss)
{
nsCOMPtr<nsIURI> dummyUri;
nsresult rv = NS_NewURI(getter_AddRefs(dummyUri), "https://foo.com/bar.html");
ASSERT_TRUE(NS_SUCCEEDED(rv)) << "Failed to create URI";
rv = sss->UnsafeProcessHeader(nsISiteSecurityService::HEADER_HSTS, dummyUri,
- hdr, 0, nullptr, nullptr, nullptr);
+ nsDependentCString(hdr), 0, nullptr, nullptr,
+ nullptr);
ASSERT_TRUE(NS_FAILED(rv)) << "Parsed invalid header: " << hdr;
printf("%s\n", hdr);
}
TEST(psm_STSParser, Test)
{
nsresult rv;