Coverage Report

Created: 2025-07-23 06:40

/src/sleuthkit/tsk/auto/guid.cpp
Line
Count
Source (jump to first uncovered line)
1
/*
2
The MIT License (MIT)
3
4
Copyright (c) 2014 Graeme Hill (http://graemehill.ca)
5
6
Permission is hereby granted, free of charge, to any person obtaining a copy
7
of this software and associated documentation files (the "Software"), to deal
8
in the Software without restriction, including without limitation the rights
9
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10
copies of the Software, and to permit persons to whom the Software is
11
furnished to do so, subject to the following conditions:
12
13
The above copyright notice and this permission notice shall be included in
14
all copies or substantial portions of the Software.
15
16
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22
THE SOFTWARE.
23
*/
24
25
#include "guid.h"
26
27
#ifdef GUID_LIBUUID
28
#include <uuid/uuid.h>
29
#endif
30
31
#ifdef GUID_CFUUID
32
#include <CoreFoundation/CFUUID.h>
33
#endif
34
35
#ifdef GUID_WINDOWS
36
#include <objbase.h>
37
#endif
38
39
#ifdef GUID_ANDROID
40
#include <jni.h>
41
#endif
42
43
using namespace std;
44
45
// overload << so that it's easy to convert to a string
46
ostream &operator<<(ostream &s, const TSKGuid &guid)
47
0
{
48
0
  return s << hex << setfill('0')
49
0
    << setw(2) << (int)guid._bytes[0]
50
0
    << setw(2) << (int)guid._bytes[1]
51
0
    << setw(2) << (int)guid._bytes[2]
52
0
    << setw(2) << (int)guid._bytes[3]
53
0
    << "-"
54
0
    << setw(2) << (int)guid._bytes[4]
55
0
    << setw(2) << (int)guid._bytes[5]
56
0
    << "-"
57
0
    << setw(2) << (int)guid._bytes[6]
58
0
    << setw(2) << (int)guid._bytes[7]
59
0
    << "-"
60
0
    << setw(2) << (int)guid._bytes[8]
61
0
    << setw(2) << (int)guid._bytes[9]
62
0
    << "-"
63
0
    << setw(2) << (int)guid._bytes[10]
64
0
    << setw(2) << (int)guid._bytes[11]
65
0
    << setw(2) << (int)guid._bytes[12]
66
0
    << setw(2) << (int)guid._bytes[13]
67
0
    << setw(2) << (int)guid._bytes[14]
68
0
    << setw(2) << (int)guid._bytes[15];
69
0
}
70
71
// create a guid from vector of bytes
72
TSKGuid::TSKGuid(const vector<unsigned char> &bytes)
73
0
{
74
0
  _bytes = bytes;
75
0
}
76
77
// create a guid from array of bytes
78
TSKGuid::TSKGuid(const unsigned char *bytes)
79
37
{
80
37
  _bytes.assign(bytes, bytes + 16);
81
37
}
82
83
// converts a single hex char to a number (0 - 15)
84
unsigned char hexDigitToChar(char ch)
85
256
{
86
256
  if (ch > 47 && ch < 58)
87
148
    return ch - 48;
88
89
108
  if (ch > 96 && ch < 103)
90
108
    return ch - 87;
91
92
0
  if (ch > 64 && ch < 71)
93
0
    return ch - 55;
94
95
0
  return 0;
96
0
}
97
98
// converts the two hexadecimal characters to an unsigned char (a byte)
99
unsigned char hexPairToChar(char a, char b)
100
128
{
101
128
  return hexDigitToChar(a) * 16 + hexDigitToChar(b);
102
128
}
103
104
// create a guid from string
105
TSKGuid::TSKGuid(const string &fromString)
106
8
{
107
8
  _bytes.clear();
108
109
8
  char charOne, charTwo;
110
8
  bool lookingForFirstChar = true;
111
112
  // for (const char &ch : fromString) C++ 11 CODE CHANGED FOR TSK
113
296
  for (std::string::const_iterator it = fromString.begin(); it != fromString.end(); ++it)
114
288
  {
115
288
    char ch = *it;
116
288
    if (ch == '-')
117
32
      continue;
118
119
256
    if (lookingForFirstChar)
120
128
    {
121
128
      charOne = ch;
122
128
      lookingForFirstChar = false;
123
128
    }
124
128
    else
125
128
    {
126
128
      charTwo = ch;
127
128
      unsigned char byte = hexPairToChar(charOne, charTwo);
128
128
      _bytes.push_back(byte);
129
128
      lookingForFirstChar = true;
130
128
    }
131
256
  }
132
133
8
}
134
135
// create empty guid
136
TSKGuid::TSKGuid()
137
47
{
138
47
  _bytes = vector<unsigned char>(16, 0);
139
47
}
140
141
// copy constructor
142
TSKGuid::TSKGuid(const TSKGuid &other)
143
0
{
144
0
  _bytes = other._bytes;
145
0
}
146
147
0
std::string TSKGuid::str() const {
148
0
  std::stringstream ss;
149
0
  ss << (*this);
150
151
0
  return ss.str();
152
0
}
153
154
// overload assignment operator
155
TSKGuid &TSKGuid::operator=(const TSKGuid &other)
156
0
{
157
0
  _bytes = other._bytes;
158
0
  return *this;
159
0
}
160
161
// overload equality operator
162
bool TSKGuid::operator==(const TSKGuid &other) const
163
0
{
164
0
  return _bytes == other._bytes;
165
0
}
166
167
// overload inequality operator
168
bool TSKGuid::operator!=(const TSKGuid &other) const
169
0
{
170
0
  return !((*this) == other);
171
0
}
172
173
// This is the linux friendly implementation, but it could work on other
174
// systems that have libuuid available
175
#ifdef GUID_LIBUUID
176
TSKGuid GuidGenerator::newGuid()
177
{
178
  uuid_t id;
179
  uuid_generate(id);
180
  return id;
181
}
182
#endif
183
184
// this is the mac and ios version
185
#ifdef GUID_CFUUID
186
TSKGuid GuidGenerator::newGuid()
187
{
188
  CFUUIDRef newId = CFUUIDCreate(NULL);
189
  CFUUIDBytes bytes = CFUUIDGetUUIDBytes(newId);
190
  CFRelease(newId);
191
192
  const unsigned char byteArray[16] =
193
  {
194
    bytes.byte0,
195
    bytes.byte1,
196
    bytes.byte2,
197
    bytes.byte3,
198
    bytes.byte4,
199
    bytes.byte5,
200
    bytes.byte6,
201
    bytes.byte7,
202
    bytes.byte8,
203
    bytes.byte9,
204
    bytes.byte10,
205
    bytes.byte11,
206
    bytes.byte12,
207
    bytes.byte13,
208
    bytes.byte14,
209
    bytes.byte15
210
  };
211
  return byteArray;
212
}
213
#endif
214
215
// obviously this is the windows version
216
#ifdef GUID_WINDOWS
217
TSKGuid GuidGenerator::newGuid()
218
{
219
  GUID newId;
220
  CoCreateGuid(&newId);
221
222
  const unsigned char bytes[16] =
223
  {
224
    (unsigned char)((newId.Data1 >> 24) & 0xFF),
225
    (unsigned char)((newId.Data1 >> 16) & 0xFF),
226
    (unsigned char)((newId.Data1 >> 8) & 0xFF),
227
    (unsigned char)((newId.Data1) & 0xff),
228
229
    (unsigned char)((newId.Data2 >> 8) & 0xFF),
230
    (unsigned char)((newId.Data2) & 0xff),
231
232
    (unsigned char)((newId.Data3 >> 8) & 0xFF),
233
    (unsigned char)((newId.Data3) & 0xFF),
234
235
    newId.Data4[0],
236
    newId.Data4[1],
237
    newId.Data4[2],
238
    newId.Data4[3],
239
    newId.Data4[4],
240
    newId.Data4[5],
241
    newId.Data4[6],
242
    newId.Data4[7]
243
  };
244
245
  return bytes;
246
}
247
#endif
248
249
// android version that uses a call to a java api
250
#ifdef GUID_ANDROID
251
GuidGenerator::GuidGenerator(JNIEnv *env)
252
{
253
  _env = env;
254
  _uuidClass = env->FindClass("java/util/UUID");
255
  _newGuidMethod = env->GetStaticMethodID(_uuidClass, "randomUUID", "()Ljava/util/UUID;");
256
  _mostSignificantBitsMethod = env->GetMethodID(_uuidClass, "getMostSignificantBits", "()J");
257
  _leastSignificantBitsMethod = env->GetMethodID(_uuidClass, "getLeastSignificantBits", "()J");
258
}
259
260
TSKGuid GuidGenerator::newGuid()
261
{
262
  jobject javaUuid = _env->CallStaticObjectMethod(_uuidClass, _newGuidMethod);
263
  jlong mostSignificant = _env->CallLongMethod(javaUuid, _mostSignificantBitsMethod);
264
  jlong leastSignificant = _env->CallLongMethod(javaUuid, _leastSignificantBitsMethod);
265
266
  unsigned char bytes[16] =
267
  {
268
    (mostSignificant >> 56) & 0xFF,
269
    (mostSignificant >> 48) & 0xFF,
270
    (mostSignificant >> 40) & 0xFF,
271
    (mostSignificant >> 32) & 0xFF,
272
    (mostSignificant >> 24) & 0xFF,
273
    (mostSignificant >> 16) & 0xFF,
274
    (mostSignificant >> 8) & 0xFF,
275
    (mostSignificant) & 0xFF,
276
    (leastSignificant >> 56) & 0xFF,
277
    (leastSignificant >> 48) & 0xFF,
278
    (leastSignificant >> 40) & 0xFF,
279
    (leastSignificant >> 32) & 0xFF,
280
    (leastSignificant >> 24) & 0xFF,
281
    (leastSignificant >> 16) & 0xFF,
282
    (leastSignificant >> 8) & 0xFF,
283
    (leastSignificant) & 0xFF,
284
  };
285
  return bytes;
286
}
287
#endif