Coverage Report

Created: 2018-09-25 14:53

/src/mozilla-central/dom/crypto/CryptoBuffer.cpp
Line
Count
Source (jump to first uncovered line)
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 "CryptoBuffer.h"
8
#include "secitem.h"
9
#include "mozilla/Base64.h"
10
#include "mozilla/dom/UnionTypes.h"
11
12
namespace mozilla {
13
namespace dom {
14
15
uint8_t*
16
CryptoBuffer::Assign(const CryptoBuffer& aData)
17
0
{
18
0
  // Same as in nsTArray_Impl::operator=, but return the value
19
0
  // returned from ReplaceElementsAt to enable OOM detection
20
0
  return ReplaceElementsAt(0, Length(), aData.Elements(), aData.Length(),
21
0
                           fallible);
22
0
}
23
24
uint8_t*
25
CryptoBuffer::Assign(const uint8_t* aData, uint32_t aLength)
26
0
{
27
0
  return ReplaceElementsAt(0, Length(), aData, aLength, fallible);
28
0
}
29
30
uint8_t*
31
CryptoBuffer::Assign(const nsACString& aString)
32
0
{
33
0
  return Assign(reinterpret_cast<uint8_t const*>(aString.BeginReading()),
34
0
                aString.Length());
35
0
}
36
37
uint8_t*
38
CryptoBuffer::Assign(const SECItem* aItem)
39
0
{
40
0
  MOZ_ASSERT(aItem);
41
0
  return Assign(aItem->data, aItem->len);
42
0
}
43
44
uint8_t*
45
CryptoBuffer::Assign(const InfallibleTArray<uint8_t>& aData)
46
0
{
47
0
  return ReplaceElementsAt(0, Length(), aData.Elements(), aData.Length(),
48
0
                           fallible);
49
0
}
50
51
uint8_t*
52
CryptoBuffer::Assign(const ArrayBuffer& aData)
53
0
{
54
0
  aData.ComputeLengthAndData();
55
0
  return Assign(aData.Data(), aData.Length());
56
0
}
57
58
uint8_t*
59
CryptoBuffer::Assign(const ArrayBufferView& aData)
60
0
{
61
0
  aData.ComputeLengthAndData();
62
0
  return Assign(aData.Data(), aData.Length());
63
0
}
64
65
uint8_t*
66
CryptoBuffer::Assign(const ArrayBufferViewOrArrayBuffer& aData)
67
0
{
68
0
  if (aData.IsArrayBufferView()) {
69
0
    return Assign(aData.GetAsArrayBufferView());
70
0
  } else if (aData.IsArrayBuffer()) {
71
0
    return Assign(aData.GetAsArrayBuffer());
72
0
  }
73
0
74
0
  // If your union is uninitialized, something's wrong
75
0
  MOZ_ASSERT(false);
76
0
  Clear();
77
0
  return nullptr;
78
0
}
79
80
uint8_t*
81
CryptoBuffer::Assign(const OwningArrayBufferViewOrArrayBuffer& aData)
82
0
{
83
0
  if (aData.IsArrayBufferView()) {
84
0
    return Assign(aData.GetAsArrayBufferView());
85
0
  } else if (aData.IsArrayBuffer()) {
86
0
    return Assign(aData.GetAsArrayBuffer());
87
0
  }
88
0
89
0
  // If your union is uninitialized, something's wrong
90
0
  MOZ_ASSERT(false);
91
0
  Clear();
92
0
  return nullptr;
93
0
}
94
95
uint8_t*
96
CryptoBuffer::AppendSECItem(const SECItem* aItem)
97
0
{
98
0
  MOZ_ASSERT(aItem);
99
0
  return AppendElements(aItem->data, aItem->len, fallible);
100
0
}
101
102
uint8_t*
103
CryptoBuffer::AppendSECItem(const SECItem& aItem)
104
0
{
105
0
  return AppendElements(aItem.data, aItem.len, fallible);
106
0
}
107
108
// Helpers to encode/decode JWK's special flavor of Base64
109
// * No whitespace
110
// * No padding
111
// * URL-safe character set
112
nsresult
113
CryptoBuffer::FromJwkBase64(const nsString& aBase64)
114
0
{
115
0
  NS_ConvertUTF16toUTF8 temp(aBase64);
116
0
  temp.StripWhitespace();
117
0
118
0
  // JWK prohibits padding per RFC 7515, section 2.
119
0
  nsresult rv = Base64URLDecode(temp, Base64URLDecodePaddingPolicy::Reject,
120
0
                                *this);
121
0
  NS_ENSURE_SUCCESS(rv, rv);
122
0
123
0
  return NS_OK;
124
0
}
125
126
nsresult
127
CryptoBuffer::ToJwkBase64(nsString& aBase64) const
128
0
{
129
0
  // Shortcut for the empty octet string
130
0
  if (Length() == 0) {
131
0
    aBase64.Truncate();
132
0
    return NS_OK;
133
0
  }
134
0
135
0
  nsAutoCString base64;
136
0
  nsresult rv = Base64URLEncode(Length(), Elements(),
137
0
                                Base64URLEncodePaddingPolicy::Omit, base64);
138
0
  NS_ENSURE_SUCCESS(rv, rv);
139
0
140
0
  CopyASCIItoUTF16(base64, aBase64);
141
0
  return NS_OK;
142
0
}
143
144
bool
145
CryptoBuffer::ToSECItem(PLArenaPool *aArena, SECItem* aItem) const
146
0
{
147
0
  aItem->type = siBuffer;
148
0
  aItem->data = nullptr;
149
0
150
0
  if (!::SECITEM_AllocItem(aArena, aItem, Length())) {
151
0
    return false;
152
0
  }
153
0
154
0
  memcpy(aItem->data, Elements(), Length());
155
0
  return true;
156
0
}
157
158
JSObject*
159
CryptoBuffer::ToUint8Array(JSContext* aCx) const
160
0
{
161
0
  return Uint8Array::Create(aCx, Length(), Elements());
162
0
}
163
164
JSObject*
165
CryptoBuffer::ToArrayBuffer(JSContext* aCx) const
166
0
{
167
0
  return ArrayBuffer::Create(aCx, Length(), Elements());
168
0
}
169
170
bool
171
CryptoBuffer::ToNewUnsignedBuffer(uint8_t** aBuf, uint32_t* aBufLen) const
172
0
{
173
0
  MOZ_ASSERT(aBuf);
174
0
  MOZ_ASSERT(aBufLen);
175
0
176
0
  uint32_t dataLen = Length();
177
0
  uint8_t* tmp = reinterpret_cast<uint8_t*>(moz_xmalloc(dataLen));
178
0
179
0
  memcpy(tmp, Elements(), dataLen);
180
0
  *aBuf = tmp;
181
0
  *aBufLen = dataLen;
182
0
  return true;
183
0
}
184
185
// "BigInt" comes from the WebCrypto spec
186
// ("unsigned long" isn't very "big", of course)
187
// Likewise, the spec calls for big-endian ints
188
bool
189
CryptoBuffer::GetBigIntValue(unsigned long& aRetVal)
190
0
{
191
0
  if (Length() > sizeof(aRetVal)) {
192
0
    return false;
193
0
  }
194
0
195
0
  aRetVal = 0;
196
0
  for (size_t i=0; i < Length(); ++i) {
197
0
    aRetVal = (aRetVal << 8) + ElementAt(i);
198
0
  }
199
0
  return true;
200
0
}
201
202
} // namespace dom
203
} // namespace mozilla