tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

AuthenticatorAssertionResponse.cpp (5954B)


      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 "mozilla/dom/AuthenticatorAssertionResponse.h"
      8 
      9 #include "mozilla/Base64.h"
     10 #include "mozilla/HoldDropJSObjects.h"
     11 #include "mozilla/dom/WebAuthenticationBinding.h"
     12 
     13 namespace mozilla::dom {
     14 
     15 NS_IMPL_CYCLE_COLLECTION_CLASS(AuthenticatorAssertionResponse)
     16 NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(AuthenticatorAssertionResponse,
     17                                                AuthenticatorResponse)
     18  tmp->mAuthenticatorDataCachedObj = nullptr;
     19  tmp->mSignatureCachedObj = nullptr;
     20  tmp->mUserHandleCachedObj = nullptr;
     21 NS_IMPL_CYCLE_COLLECTION_UNLINK_END
     22 
     23 NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN_INHERITED(AuthenticatorAssertionResponse,
     24                                               AuthenticatorResponse)
     25  NS_IMPL_CYCLE_COLLECTION_TRACE_PRESERVED_WRAPPER
     26  NS_IMPL_CYCLE_COLLECTION_TRACE_JS_MEMBER_CALLBACK(mAuthenticatorDataCachedObj)
     27  NS_IMPL_CYCLE_COLLECTION_TRACE_JS_MEMBER_CALLBACK(mSignatureCachedObj)
     28  NS_IMPL_CYCLE_COLLECTION_TRACE_JS_MEMBER_CALLBACK(mUserHandleCachedObj)
     29 NS_IMPL_CYCLE_COLLECTION_TRACE_END
     30 
     31 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(
     32    AuthenticatorAssertionResponse, AuthenticatorResponse)
     33 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
     34 
     35 NS_IMPL_ADDREF_INHERITED(AuthenticatorAssertionResponse, AuthenticatorResponse)
     36 NS_IMPL_RELEASE_INHERITED(AuthenticatorAssertionResponse, AuthenticatorResponse)
     37 
     38 NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(AuthenticatorAssertionResponse)
     39 NS_INTERFACE_MAP_END_INHERITING(AuthenticatorResponse)
     40 
     41 AuthenticatorAssertionResponse::AuthenticatorAssertionResponse(
     42    nsPIDOMWindowInner* aParent)
     43    : AuthenticatorResponse(aParent),
     44      mAuthenticatorDataCachedObj(nullptr),
     45      mSignatureCachedObj(nullptr),
     46      mUserHandleCachedObj(nullptr) {
     47  mozilla::HoldJSObjects(this);
     48 }
     49 
     50 AuthenticatorAssertionResponse::~AuthenticatorAssertionResponse() {
     51  mozilla::DropJSObjects(this);
     52 }
     53 
     54 JSObject* AuthenticatorAssertionResponse::WrapObject(
     55    JSContext* aCx, JS::Handle<JSObject*> aGivenProto) {
     56  return AuthenticatorAssertionResponse_Binding::Wrap(aCx, this, aGivenProto);
     57 }
     58 
     59 void AuthenticatorAssertionResponse::GetAuthenticatorData(
     60    JSContext* aCx, JS::MutableHandle<JSObject*> aValue, ErrorResult& aRv) {
     61  if (!mAuthenticatorDataCachedObj) {
     62    mAuthenticatorDataCachedObj =
     63        ArrayBuffer::Create(aCx, mAuthenticatorData, aRv);
     64    if (aRv.Failed()) {
     65      return;
     66    }
     67  }
     68  aValue.set(mAuthenticatorDataCachedObj);
     69 }
     70 
     71 void AuthenticatorAssertionResponse::SetAuthenticatorData(
     72    const nsTArray<uint8_t>& aBuffer) {
     73  mAuthenticatorData.Assign(aBuffer);
     74 }
     75 
     76 void AuthenticatorAssertionResponse::GetSignature(
     77    JSContext* aCx, JS::MutableHandle<JSObject*> aValue, ErrorResult& aRv) {
     78  if (!mSignatureCachedObj) {
     79    mSignatureCachedObj = ArrayBuffer::Create(aCx, mSignature, aRv);
     80    if (aRv.Failed()) {
     81      return;
     82    }
     83  }
     84  aValue.set(mSignatureCachedObj);
     85 }
     86 
     87 void AuthenticatorAssertionResponse::SetSignature(
     88    const nsTArray<uint8_t>& aBuffer) {
     89  mSignature.Assign(aBuffer);
     90 }
     91 
     92 void AuthenticatorAssertionResponse::GetUserHandle(
     93    JSContext* aCx, JS::MutableHandle<JSObject*> aValue, ErrorResult& aRv) {
     94  // Per
     95  // https://w3c.github.io/webauthn/#ref-for-dom-authenticatorassertionresponse-userhandle%E2%91%A0
     96  // this should return null if the handle is unset.
     97  if (mUserHandle.IsEmpty()) {
     98    aValue.set(nullptr);
     99  } else {
    100    if (!mUserHandleCachedObj) {
    101      mUserHandleCachedObj = ArrayBuffer::Create(aCx, mUserHandle, aRv);
    102      if (aRv.Failed()) {
    103        return;
    104      }
    105    }
    106    aValue.set(mUserHandleCachedObj);
    107  }
    108 }
    109 
    110 void AuthenticatorAssertionResponse::SetUserHandle(
    111    const nsTArray<uint8_t>& aBuffer) {
    112  mUserHandle.Assign(aBuffer);
    113 }
    114 
    115 void AuthenticatorAssertionResponse::ToJSON(
    116    AuthenticatorAssertionResponseJSON& aJSON, ErrorResult& aError) {
    117  nsAutoCString clientDataJSONBase64;
    118  nsresult rv = Base64URLEncode(
    119      mClientDataJSON.Length(),
    120      reinterpret_cast<const uint8_t*>(mClientDataJSON.get()),
    121      mozilla::Base64URLEncodePaddingPolicy::Omit, clientDataJSONBase64);
    122  // This will only fail if the length is so long that it overflows 32-bits
    123  // when calculating the encoded size.
    124  if (NS_FAILED(rv)) {
    125    aError.ThrowDataError("clientDataJSON too long");
    126    return;
    127  }
    128  aJSON.mClientDataJSON.Assign(NS_ConvertUTF8toUTF16(clientDataJSONBase64));
    129 
    130  nsAutoCString authenticatorDataBase64;
    131  rv = Base64URLEncode(
    132      mAuthenticatorData.Length(), mAuthenticatorData.Elements(),
    133      mozilla::Base64URLEncodePaddingPolicy::Omit, authenticatorDataBase64);
    134  if (NS_FAILED(rv)) {
    135    aError.ThrowDataError("authenticatorData too long");
    136    return;
    137  }
    138  aJSON.mAuthenticatorData.Assign(
    139      NS_ConvertUTF8toUTF16(authenticatorDataBase64));
    140 
    141  nsAutoCString signatureBase64;
    142  rv = Base64URLEncode(mSignature.Length(), mSignature.Elements(),
    143                       mozilla::Base64URLEncodePaddingPolicy::Omit,
    144                       signatureBase64);
    145  if (NS_FAILED(rv)) {
    146    aError.ThrowDataError("signature too long");
    147    return;
    148  }
    149  aJSON.mSignature.Assign(NS_ConvertUTF8toUTF16(signatureBase64));
    150 
    151  if (!mUserHandle.IsEmpty()) {
    152    nsAutoCString userHandleBase64;
    153    rv = Base64URLEncode(mUserHandle.Length(), mUserHandle.Elements(),
    154                         mozilla::Base64URLEncodePaddingPolicy::Omit,
    155                         userHandleBase64);
    156    if (NS_FAILED(rv)) {
    157      aError.ThrowDataError("userHandle too long");
    158      return;
    159    }
    160    aJSON.mUserHandle.Construct(NS_ConvertUTF8toUTF16(userHandleBase64));
    161  }
    162 
    163  // attestationObject is not currently supported on assertion responses
    164 }
    165 
    166 }  // namespace mozilla::dom