Backed out changeset 2450366cf7ca (bug 1891629) for causing win msix mochitest failures
[gecko.git] / dom / crypto / CryptoBuffer.cpp
blob67e1a8e56a0d80667abd0868ed9e392861d5c418
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/. */
7 #include "CryptoBuffer.h"
8 #include "secitem.h"
9 #include "mozilla/Base64.h"
10 #include "mozilla/dom/UnionTypes.h"
12 namespace mozilla::dom {
14 uint8_t* CryptoBuffer::Assign(const CryptoBuffer& aData) {
15 // Same as in nsTArray_Impl::operator=, but return the value
16 // returned from ReplaceElementsAt to enable OOM detection
17 return ReplaceElementsAt(0, Length(), aData.Elements(), aData.Length(),
18 fallible);
21 uint8_t* CryptoBuffer::Assign(const uint8_t* aData, uint32_t aLength) {
22 return ReplaceElementsAt(0, Length(), aData, aLength, fallible);
25 uint8_t* CryptoBuffer::Assign(const nsACString& aString) {
26 return Assign(reinterpret_cast<uint8_t const*>(aString.BeginReading()),
27 aString.Length());
30 uint8_t* CryptoBuffer::Assign(const SECItem* aItem) {
31 MOZ_ASSERT(aItem);
32 return Assign(aItem->data, aItem->len);
35 uint8_t* CryptoBuffer::Assign(const nsTArray<uint8_t>& aData) {
36 return ReplaceElementsAt(0, Length(), aData.Elements(), aData.Length(),
37 fallible);
40 uint8_t* CryptoBuffer::Assign(const ArrayBuffer& aData) {
41 Clear();
42 return aData.AppendDataTo(*this) ? Elements() : nullptr;
45 uint8_t* CryptoBuffer::Assign(const ArrayBufferView& aData) {
46 Clear();
47 return aData.AppendDataTo(*this) ? Elements() : nullptr;
50 uint8_t* CryptoBuffer::Assign(const ArrayBufferViewOrArrayBuffer& aData) {
51 Clear();
53 return AppendTypedArrayDataTo(aData, *this) ? Elements() : nullptr;
56 uint8_t* CryptoBuffer::Assign(const OwningArrayBufferViewOrArrayBuffer& aData) {
57 Clear();
59 return AppendTypedArrayDataTo(aData, *this) ? Elements() : nullptr;
62 uint8_t* CryptoBuffer::Assign(const Uint8Array& aArray) {
63 Clear();
64 return aArray.AppendDataTo(*this) ? Elements() : nullptr;
67 uint8_t* CryptoBuffer::AppendSECItem(const SECItem* aItem) {
68 MOZ_ASSERT(aItem);
69 return AppendElements(aItem->data, aItem->len, fallible);
72 uint8_t* CryptoBuffer::AppendSECItem(const SECItem& aItem) {
73 return AppendElements(aItem.data, aItem.len, fallible);
76 // Helpers to encode/decode JWK's special flavor of Base64
77 // * No whitespace
78 // * No padding
79 // * URL-safe character set
80 nsresult CryptoBuffer::FromJwkBase64(const nsString& aBase64) {
81 NS_ConvertUTF16toUTF8 temp(aBase64);
82 temp.StripWhitespace();
84 // JWK prohibits padding per RFC 7515, section 2.
85 nsresult rv =
86 Base64URLDecode(temp, Base64URLDecodePaddingPolicy::Reject, *this);
87 NS_ENSURE_SUCCESS(rv, rv);
89 return NS_OK;
92 nsresult CryptoBuffer::ToJwkBase64(nsString& aBase64) const {
93 // Shortcut for the empty octet string
94 if (Length() == 0) {
95 aBase64.Truncate();
96 return NS_OK;
99 nsAutoCString base64;
100 nsresult rv = Base64URLEncode(Length(), Elements(),
101 Base64URLEncodePaddingPolicy::Omit, base64);
102 NS_ENSURE_SUCCESS(rv, rv);
104 CopyASCIItoUTF16(base64, aBase64);
105 return NS_OK;
108 bool CryptoBuffer::ToSECItem(PLArenaPool* aArena, SECItem* aItem) const {
109 aItem->type = siBuffer;
110 aItem->data = nullptr;
112 if (!::SECITEM_AllocItem(aArena, aItem, Length())) {
113 return false;
115 // If this CryptoBuffer is of 0 length, aItem->data will be null. Passing
116 // null to memcpy is not valid, even if the length is 0, so return early.
117 if (!aItem->data) {
118 MOZ_ASSERT(Length() == 0);
119 return true;
121 memcpy(aItem->data, Elements(), Length());
122 return true;
125 JSObject* CryptoBuffer::ToUint8Array(JSContext* aCx,
126 ErrorResult& aError) const {
127 return Uint8Array::Create(aCx, *this, aError);
130 JSObject* CryptoBuffer::ToArrayBuffer(JSContext* aCx,
131 ErrorResult& aError) const {
132 return ArrayBuffer::Create(aCx, *this, aError);
135 // "BigInt" comes from the WebCrypto spec
136 // ("unsigned long" isn't very "big", of course)
137 // Likewise, the spec calls for big-endian ints
138 bool CryptoBuffer::GetBigIntValue(unsigned long& aRetVal) {
139 if (Length() > sizeof(aRetVal)) {
140 return false;
143 aRetVal = 0;
144 for (size_t i = 0; i < Length(); ++i) {
145 aRetVal = (aRetVal << 8) + ElementAt(i);
147 return true;
150 } // namespace mozilla::dom