1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
3 /* This Source Code Form is subject to the terms of the Mozilla Public
4  * License, v. 2.0. If a copy of the MPL was not distributed with this
5  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
6 
7 #include "OriginTrials.h"
8 #include "mozilla/Base64.h"
9 #include "nsString.h"
10 #include "nsIPrincipal.h"
11 #include "nsIURI.h"
12 #include "nsNetUtil.h"
13 
14 namespace mozilla {
15 
VerifySignature(const uint8_t * aSignature,uintptr_t aSignatureLen,const uint8_t * aData,uintptr_t aDataLen,void * aUserData)16 bool VerifySignature(const uint8_t* aSignature, uintptr_t aSignatureLen,
17                      const uint8_t* aData, uintptr_t aDataLen,
18                      void* aUserData) {
19   MOZ_RELEASE_ASSERT(aSignatureLen == 64);
20   // TODO(emilio): Implement.
21   return false;
22 }
23 
MatchesOrigin(const uint8_t * aOrigin,size_t aOriginLen,bool aIsSubdomain,bool aIsThirdParty,bool aIsUsageSubset,void * aUserData)24 bool MatchesOrigin(const uint8_t* aOrigin, size_t aOriginLen, bool aIsSubdomain,
25                    bool aIsThirdParty, bool aIsUsageSubset, void* aUserData) {
26   if (aIsThirdParty || aIsSubdomain || aIsUsageSubset) {
27     // TODO(emilio): Support third-party tokens and so on.
28     return false;
29   }
30 
31   auto* principal = static_cast<nsIPrincipal*>(aUserData);
32   nsDependentCSubstring origin(reinterpret_cast<const char*>(aOrigin),
33                                aOriginLen);
34   nsCOMPtr<nsIURI> originURI;
35   if (NS_WARN_IF(NS_FAILED(NS_NewURI(getter_AddRefs(originURI), origin)))) {
36     return false;
37   }
38 
39   return principal->IsSameOrigin(originURI);
40 }
41 
UpdateFromToken(const nsAString & aBase64EncodedToken,nsIPrincipal * aPrincipal)42 void OriginTrials::UpdateFromToken(const nsAString& aBase64EncodedToken,
43                                    nsIPrincipal* aPrincipal) {
44   nsAutoCString decodedToken;
45   nsresult rv = mozilla::Base64Decode(aBase64EncodedToken, decodedToken);
46   if (NS_WARN_IF(NS_FAILED(rv))) {
47     return;
48   }
49 
50   const Span<const uint8_t> decodedTokenSpan(decodedToken);
51   const origin_trials_ffi::OriginTrialValidationParams params{
52       VerifySignature,
53       MatchesOrigin,
54       /* user_data = */ aPrincipal,
55   };
56   auto result = origin_trials_ffi::origin_trials_parse_and_validate_token(
57       decodedTokenSpan.data(), decodedTokenSpan.size(), &params);
58   if (!result.IsOk()) {
59     return;  // TODO(emilio): Maybe report to console or what not?
60   }
61   OriginTrial trial = result.AsOk().trial;
62   mEnabledTrials += trial;
63 }
64 
65 }  // namespace mozilla
66