1 /*
2  * Copyright (c) 2010 SURFnet bv
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  * 1. Redistributions of source code must retain the above copyright
9  *    notice, this list of conditions and the following disclaimer.
10  * 2. Redistributions in binary form must reproduce the above copyright
11  *    notice, this list of conditions and the following disclaimer in the
12  *    documentation and/or other materials provided with the distribution.
13  *
14  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
15  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
16  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17  * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
18  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
20  * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
21  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
22  * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
23  * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
24  * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25  */
26 
27 /*****************************************************************************
28  ByteString.cpp
29 
30  A string class for byte strings stored in securely allocated memory
31  *****************************************************************************/
32 
33 #include <algorithm>
34 #include <string>
35 #include <stdio.h>
36 #include "config.h"
37 #include "log.h"
38 #include "ByteString.h"
39 
40 /**
41  * Backward compatible fix: byte_str()/const_byte_str() to
42  * return a non-NULL pointer, even if size() == 0, and yet
43  * be compatible with -Wp,-D_GLIBCXX_ASSERTIONS stricter
44  * bounds checking
45  */
46 static unsigned char sentinel[1];
47 
48 // Constructors
ByteString()49 ByteString::ByteString()
50 {
51 }
52 
ByteString(const unsigned char * bytes,const size_t bytesLen)53 ByteString::ByteString(const unsigned char* bytes, const size_t bytesLen)
54 {
55 	byteString.resize(bytesLen);
56 
57 	if (bytesLen > 0)
58 		memcpy(&byteString[0], bytes, bytesLen);
59 }
60 
ByteString(const char * hexString)61 ByteString::ByteString(const char* hexString)
62 {
63 	std::string hex = std::string(hexString);
64 
65 	if (hex.size() % 2 != 0)
66 	{
67 		hex = "0" + hex;
68 	}
69 
70 	for (size_t i = 0; i < hex.size(); i += 2)
71 	{
72 		std::string byteStr;
73 		byteStr += hex[i];
74 		byteStr += hex[i+1];
75 
76 		unsigned char byteVal = (unsigned char) strtoul(byteStr.c_str(), NULL, 16);
77 
78 		this->operator+=(byteVal);
79 	}
80 }
81 
ByteString(const unsigned long longValue)82 ByteString::ByteString(const unsigned long longValue)
83 {
84 	unsigned long setValue = longValue;
85 
86 	// Convert the value to a big-endian byte string; N.B.: this code assumes that unsigned long
87 	// values are stored as a 64-bit value, which is a safe assumption on modern systems. It will
88 	// also properly handle a 32-bit value and will simply store 4 zeroes at the front of the
89 	// string. If at some point in time we get 128-bit architectures, the top 8 bytes of the value
90 	// will be discarded... (but hey, 640K is enough for everybody, right?)
91 	//
92 	// The reason for coding it this way is that implementations of SoftHSM will maintain
93 	// binary compatibility between eachothers background storage (i.e. a 32-bit SoftHSM version can
94 	// read the storage of a 64-bit version and vice versa under the assumption that the stored
95 	// values never exceed 32-bits, which is likely since these values are only used to encode
96 	// byte string lengths)
97 	unsigned char byteStrIn[8];
98 
99 	for (size_t i = 0; i < 8; i++)
100 	{
101 		byteStrIn[7-i] = (unsigned char) (setValue & 0xFF);
102 		setValue >>= 8;
103 	}
104 
105 	byteString.resize(8);
106 	memcpy(&byteString[0], byteStrIn, 8);
107 }
108 
ByteString(const ByteString & in)109 ByteString::ByteString(const ByteString& in)
110 {
111 	this->byteString = in.byteString;
112 }
113 
114 // Assignment
operator =(const ByteString & in)115 ByteString& ByteString::operator=(const ByteString& in)
116 {
117 	this->byteString = in.byteString;
118 	return *this;
119 }
120 
121 // Append data
operator +=(const ByteString & append)122 ByteString& ByteString::operator+=(const ByteString& append)
123 {
124 	size_t curLen = byteString.size();
125 	size_t toAdd = append.byteString.size();
126 	size_t newLen = curLen + toAdd;
127 
128 	byteString.resize(newLen);
129 
130 	if (toAdd > 0)
131 		memcpy(&byteString[curLen], &append.byteString[0], toAdd);
132 
133 	return *this;
134 }
135 
operator +=(const unsigned char byte)136 ByteString& ByteString::operator+=(const unsigned char byte)
137 {
138 	byteString.push_back(byte);
139 
140 	return *this;
141 }
142 
143 // XORing
operator ^=(const ByteString & rhs)144 ByteString& ByteString::operator^=(const ByteString& rhs)
145 {
146 	size_t xorLen = std::min(this->size(), rhs.size());
147 
148 	for (size_t i = 0; i < xorLen; i++)
149 	{
150 		byteString[i] ^= rhs.const_byte_str()[i];
151 	}
152 
153 	return *this;
154 }
155 
156 // Return a substring
substr(const size_t start,const size_t len) const157 ByteString ByteString::substr(const size_t start, const size_t len /* = SIZE_T_MAX */) const
158 {
159 	size_t retLen = std::min(len, byteString.size() - start);
160 
161 	if (start >= byteString.size())
162 	{
163 		return ByteString();
164 	}
165 	else
166 	{
167 		return ByteString(&byteString[start], retLen);
168 	}
169 }
170 
171 // Add data
operator +(const ByteString & lhs,const ByteString & rhs)172 ByteString operator+(const ByteString& lhs, const ByteString& rhs)
173 {
174 	ByteString rv = lhs;
175 	rv += rhs;
176 
177 	return rv;
178 }
179 
operator +(const unsigned char lhs,const ByteString & rhs)180 ByteString operator+(const unsigned char lhs, const ByteString& rhs)
181 {
182 	ByteString rv(&lhs, 1);
183 	rv += rhs;
184 
185 	return rv;
186 }
187 
operator +(const ByteString & lhs,const unsigned char rhs)188 ByteString operator+(const ByteString& lhs, const unsigned char rhs)
189 {
190 	ByteString rv = lhs;
191 	rv += rhs;
192 
193 	return rv;
194 }
195 
196 // Array operator
operator [](size_t pos)197 unsigned char& ByteString::operator[](size_t pos)
198 {
199 	return byteString[pos];
200 }
201 
202 // Return the byte string data
byte_str()203 unsigned char* ByteString::byte_str()
204 {
205 	if (byteString.size() != 0) {
206 		return &byteString[0];
207 	} else {
208 		return (unsigned char*) sentinel;
209 	}
210 }
211 
212 // Return the const byte string
const_byte_str() const213 const unsigned char* ByteString::const_byte_str() const
214 {
215 	if (byteString.size() != 0) {
216 		return (const unsigned char*) &byteString[0];
217 	} else {
218 		return (const unsigned char*) sentinel;
219 	}
220 }
221 
222 // Return a hexadecimal character representation of the string
hex_str() const223 std::string ByteString::hex_str() const
224 {
225 	std::string rv;
226 	char hex[3];
227 
228 	for (size_t i = 0; i < byteString.size(); i++)
229 	{
230 		sprintf(hex, "%02X", byteString[i]);
231 
232 		rv += hex;
233 	}
234 
235 	return rv;
236 }
237 
238 // Return the long value
long_val() const239 unsigned long ByteString::long_val() const
240 {
241 	// Convert the first 8 bytes of the string to an unsigned long value
242 	unsigned long rv = 0;
243 
244 	for (size_t i = 0; i < std::min(size_t(8), byteString.size()); i++)
245 	{
246 		rv <<= 8;
247 		rv += byteString[i];
248 	}
249 
250 	return rv;
251 }
252 
253 // Cut of the first part of the string and convert it to a long value
firstLong()254 unsigned long ByteString::firstLong()
255 {
256 	unsigned long rv = long_val();
257 
258 	split(8);
259 
260 	return rv;
261 }
262 
263 // Split of the specified part of the string as a separate byte string
split(size_t len)264 ByteString ByteString::split(size_t len)
265 {
266 	ByteString rv = substr(0, len);
267 
268 	size_t newSize = (byteString.size() > len) ? (byteString.size() - len) : 0;
269 
270 	if (newSize > 0)
271 	{
272 		for (size_t i = 0; i < newSize; i++)
273 		{
274 			byteString[i] = byteString[i + len];
275 		}
276 	}
277 
278 	byteString.resize(newSize);
279 
280 	return rv;
281 }
282 
283 // The size of the byte string in bits
bits() const284 size_t ByteString::bits() const
285 {
286 	size_t bits = byteString.size() * 8;
287 
288 	if (bits == 0) return 0;
289 
290 	for (size_t i = 0; i < byteString.size(); i++)
291 	{
292 		unsigned char byte = byteString[i];
293 
294 		for (unsigned char mask = 0x80; mask > 0; mask >>= 1)
295 		{
296 			if ((byte & mask) == 0)
297 			{
298 				bits--;
299 			}
300 			else
301 			{
302 				return bits;
303 			}
304 		}
305 	}
306 
307 	return bits;
308 }
309 
310 // The size of the byte string in bytes
size() const311 size_t ByteString::size() const
312 {
313 	return byteString.size();
314 }
315 
resize(const size_t newSize)316 void ByteString::resize(const size_t newSize)
317 {
318 	byteString.resize(newSize);
319 }
320 
wipe(const size_t newSize)321 void ByteString::wipe(const size_t newSize /* = 0 */)
322 {
323 	this->resize(newSize);
324 
325 	if (!byteString.empty())
326 		memset(&byteString[0], 0x00, byteString.size());
327 }
328 
329 // Comparison
operator ==(const ByteString & compareTo) const330 bool ByteString::operator==(const ByteString& compareTo) const
331 {
332 	if (compareTo.size() != this->size())
333 	{
334 		return false;
335 	}
336 	else if (this->size() == 0)
337 	{
338 		return true;
339 	}
340 
341 	return (memcmp(&byteString[0], &compareTo.byteString[0], this->size()) == 0);
342 }
343 
operator !=(const ByteString & compareTo) const344 bool ByteString::operator!=(const ByteString& compareTo) const
345 {
346 	if (compareTo.size() != this->size())
347 	{
348 		return true;
349 	}
350 	else if (this->size() == 0)
351 	{
352 		return false;
353 	}
354 
355 	return (memcmp(&byteString[0], &compareTo.byteString[0], this->size()) != 0);
356 }
357 
358 // XOR data
operator ^(const ByteString & lhs,const ByteString & rhs)359 ByteString operator^(const ByteString& lhs, const ByteString& rhs)
360 {
361 	size_t xorLen = std::min(lhs.size(), rhs.size());
362 	ByteString rv;
363 
364 	for (size_t i = 0; i < xorLen; i++)
365 	{
366 		rv += lhs.const_byte_str()[i] ^ rhs.const_byte_str()[i];
367 	}
368 
369 	return rv;
370 }
371 
372 // Serialisation/deserialisation
serialise() const373 ByteString ByteString::serialise() const
374 {
375 	ByteString len((unsigned long) size());
376 
377 	return len + *this;
378 }
379 
chainDeserialise(ByteString & serialised)380 /* static */ ByteString ByteString::chainDeserialise(ByteString& serialised)
381 {
382 	size_t len = (size_t) serialised.firstLong();
383 
384 	ByteString rv = serialised.split(len);
385 
386 	return rv;
387 }
388 
389