1 /*
2  * Python object wrapper of libbde_key_protector_t
3  *
4  * Copyright (C) 2011-2021, Joachim Metz <joachim.metz@gmail.com>
5  *
6  * Refer to AUTHORS for acknowledgements.
7  *
8  * This program is free software: you can redistribute it and/or modify
9  * it under the terms of the GNU Lesser General Public License as published by
10  * the Free Software Foundation, either version 3 of the License, or
11  * (at your option) any later version.
12  *
13  * This program is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16  * GNU General Public License for more details.
17  *
18  * You should have received a copy of the GNU Lesser General Public License
19  * along with this program.  If not, see <https://www.gnu.org/licenses/>.
20  */
21 
22 #include <common.h>
23 #include <types.h>
24 
25 #if defined( HAVE_STDLIB_H ) || defined( HAVE_WINAPI )
26 #include <stdlib.h>
27 #endif
28 
29 #include "pybde_error.h"
30 #include "pybde_guid.h"
31 #include "pybde_key_protector.h"
32 #include "pybde_libbde.h"
33 #include "pybde_libcerror.h"
34 #include "pybde_python.h"
35 #include "pybde_unused.h"
36 
37 PyMethodDef pybde_key_protector_object_methods[] = {
38 
39 	{ "get_identifier",
40 	  (PyCFunction) pybde_key_protector_get_identifier,
41 	  METH_NOARGS,
42 	  "get_identifier() -> Unicode string\n"
43 	  "\n"
44 	  "Retrieves the identifier." },
45 
46 	{ "get_type",
47 	  (PyCFunction) pybde_key_protector_get_type,
48 	  METH_NOARGS,
49 	  "get_type() -> Integer\n"
50 	  "\n"
51 	  "Retrieves the type." },
52 
53 	/* Sentinel */
54 	{ NULL, NULL, 0, NULL }
55 };
56 
57 PyGetSetDef pybde_key_protector_object_get_set_definitions[] = {
58 
59 	{ "identifier",
60 	  (getter) pybde_key_protector_get_identifier,
61 	  (setter) 0,
62 	  "The identifier.",
63 	  NULL },
64 
65 	{ "type",
66 	  (getter) pybde_key_protector_get_type,
67 	  (setter) 0,
68 	  "The type.",
69 	  NULL },
70 
71 	/* Sentinel */
72 	{ NULL, NULL, NULL, NULL, NULL }
73 };
74 
75 PyTypeObject pybde_key_protector_type_object = {
76 	PyVarObject_HEAD_INIT( NULL, 0 )
77 
78 	/* tp_name */
79 	"pybde.key_protector",
80 	/* tp_basicsize */
81 	sizeof( pybde_key_protector_t ),
82 	/* tp_itemsize */
83 	0,
84 	/* tp_dealloc */
85 	(destructor) pybde_key_protector_free,
86 	/* tp_print */
87 	0,
88 	/* tp_getattr */
89 	0,
90 	/* tp_setattr */
91 	0,
92 	/* tp_compare */
93 	0,
94 	/* tp_repr */
95 	0,
96 	/* tp_as_number */
97 	0,
98 	/* tp_as_sequence */
99 	0,
100 	/* tp_as_mapping */
101 	0,
102 	/* tp_hash */
103 	0,
104 	/* tp_call */
105 	0,
106 	/* tp_str */
107 	0,
108 	/* tp_getattro */
109 	0,
110 	/* tp_setattro */
111 	0,
112 	/* tp_as_buffer */
113 	0,
114 	/* tp_flags */
115 	Py_TPFLAGS_DEFAULT,
116 	/* tp_doc */
117 	"pybde key protector object (wraps libbde_key_protector_t)",
118 	/* tp_traverse */
119 	0,
120 	/* tp_clear */
121 	0,
122 	/* tp_richcompare */
123 	0,
124 	/* tp_weaklistoffset */
125 	0,
126 	/* tp_iter */
127 	0,
128 	/* tp_iternext */
129 	0,
130 	/* tp_methods */
131 	pybde_key_protector_object_methods,
132 	/* tp_members */
133 	0,
134 	/* tp_getset */
135 	pybde_key_protector_object_get_set_definitions,
136 	/* tp_base */
137 	0,
138 	/* tp_dict */
139 	0,
140 	/* tp_descr_get */
141 	0,
142 	/* tp_descr_set */
143 	0,
144 	/* tp_dictoffset */
145 	0,
146 	/* tp_init */
147 	(initproc) pybde_key_protector_init,
148 	/* tp_alloc */
149 	0,
150 	/* tp_new */
151 	0,
152 	/* tp_free */
153 	0,
154 	/* tp_is_gc */
155 	0,
156 	/* tp_bases */
157 	NULL,
158 	/* tp_mro */
159 	NULL,
160 	/* tp_cache */
161 	NULL,
162 	/* tp_subclasses */
163 	NULL,
164 	/* tp_weaklist */
165 	NULL,
166 	/* tp_del */
167 	0
168 };
169 
170 /* Creates a new key protector object
171  * Returns a Python object if successful or NULL on error
172  */
pybde_key_protector_new(libbde_key_protector_t * key_protector,PyObject * parent_object)173 PyObject *pybde_key_protector_new(
174            libbde_key_protector_t *key_protector,
175            PyObject *parent_object )
176 {
177 	pybde_key_protector_t *pybde_key_protector = NULL;
178 	static char *function                      = "pybde_key_protector_new";
179 
180 	if( key_protector == NULL )
181 	{
182 		PyErr_Format(
183 		 PyExc_ValueError,
184 		 "%s: invalid key protector.",
185 		 function );
186 
187 		return( NULL );
188 	}
189 	/* PyObject_New does not invoke tp_init
190 	 */
191 	pybde_key_protector = PyObject_New(
192 	                       struct pybde_key_protector,
193 	                       &pybde_key_protector_type_object );
194 
195 	if( pybde_key_protector == NULL )
196 	{
197 		PyErr_Format(
198 		 PyExc_MemoryError,
199 		 "%s: unable to initialize key protector.",
200 		 function );
201 
202 		goto on_error;
203 	}
204 	pybde_key_protector->key_protector = key_protector;
205 	pybde_key_protector->parent_object = parent_object;
206 
207 	if( pybde_key_protector->parent_object != NULL )
208 	{
209 		Py_IncRef(
210 		 pybde_key_protector->parent_object );
211 	}
212 	return( (PyObject *) pybde_key_protector );
213 
214 on_error:
215 	if( pybde_key_protector != NULL )
216 	{
217 		Py_DecRef(
218 		 (PyObject *) pybde_key_protector );
219 	}
220 	return( NULL );
221 }
222 
223 /* Initializes a key protector object
224  * Returns 0 if successful or -1 on error
225  */
pybde_key_protector_init(pybde_key_protector_t * pybde_key_protector)226 int pybde_key_protector_init(
227      pybde_key_protector_t *pybde_key_protector )
228 {
229 	static char *function = "pybde_key_protector_init";
230 
231 	if( pybde_key_protector == NULL )
232 	{
233 		PyErr_Format(
234 		 PyExc_ValueError,
235 		 "%s: invalid key protector.",
236 		 function );
237 
238 		return( -1 );
239 	}
240 	/* Make sure libbde key protector is set to NULL
241 	 */
242 	pybde_key_protector->key_protector = NULL;
243 
244 	PyErr_Format(
245 	 PyExc_NotImplementedError,
246 	 "%s: initialize of key protector not supported.",
247 	 function );
248 
249 	return( -1 );
250 }
251 
252 /* Frees a key protector object
253  */
pybde_key_protector_free(pybde_key_protector_t * pybde_key_protector)254 void pybde_key_protector_free(
255       pybde_key_protector_t *pybde_key_protector )
256 {
257 	struct _typeobject *ob_type = NULL;
258 	libcerror_error_t *error    = NULL;
259 	static char *function       = "pybde_key_protector_free";
260 	int result                  = 0;
261 
262 	if( pybde_key_protector == NULL )
263 	{
264 		PyErr_Format(
265 		 PyExc_ValueError,
266 		 "%s: invalid key protector.",
267 		 function );
268 
269 		return;
270 	}
271 	ob_type = Py_TYPE(
272 	           pybde_key_protector );
273 
274 	if( ob_type == NULL )
275 	{
276 		PyErr_Format(
277 		 PyExc_ValueError,
278 		 "%s: missing ob_type.",
279 		 function );
280 
281 		return;
282 	}
283 	if( ob_type->tp_free == NULL )
284 	{
285 		PyErr_Format(
286 		 PyExc_ValueError,
287 		 "%s: invalid ob_type - missing tp_free.",
288 		 function );
289 
290 		return;
291 	}
292 	if( pybde_key_protector->key_protector != NULL )
293 	{
294 		Py_BEGIN_ALLOW_THREADS
295 
296 		result = libbde_key_protector_free(
297 		          &( pybde_key_protector->key_protector ),
298 		          &error );
299 
300 		Py_END_ALLOW_THREADS
301 
302 		if( result != 1 )
303 		{
304 			pybde_error_raise(
305 			 error,
306 			 PyExc_MemoryError,
307 			 "%s: unable to free libbde key protector.",
308 			 function );
309 
310 			libcerror_error_free(
311 			 &error );
312 		}
313 	}
314 	if( pybde_key_protector->parent_object != NULL )
315 	{
316 		Py_DecRef(
317 		 pybde_key_protector->parent_object );
318 	}
319 	ob_type->tp_free(
320 	 (PyObject*) pybde_key_protector );
321 }
322 
323 /* Retrieves the identifier
324  * Returns a Python object if successful or NULL on error
325  */
pybde_key_protector_get_identifier(pybde_key_protector_t * pybde_key_protector,PyObject * arguments PYBDE_ATTRIBUTE_UNUSED)326 PyObject *pybde_key_protector_get_identifier(
327            pybde_key_protector_t *pybde_key_protector,
328            PyObject *arguments PYBDE_ATTRIBUTE_UNUSED )
329 {
330 	uint8_t guid_data[ 16 ];
331 
332 	PyObject *string_object  = NULL;
333 	libcerror_error_t *error = NULL;
334 	static char *function    = "pybde_key_protector_get_identifier";
335 	int result               = 0;
336 
337 	PYBDE_UNREFERENCED_PARAMETER( arguments )
338 
339 	if( pybde_key_protector == NULL )
340 	{
341 		PyErr_Format(
342 		 PyExc_ValueError,
343 		 "%s: invalid key protector.",
344 		 function );
345 
346 		return( NULL );
347 	}
348 	Py_BEGIN_ALLOW_THREADS
349 
350 	result = libbde_key_protector_get_identifier(
351 	          pybde_key_protector->key_protector,
352 	          guid_data,
353 	          16,
354 	          &error );
355 
356 	Py_END_ALLOW_THREADS
357 
358 	if( result != 1 )
359 	{
360 		pybde_error_raise(
361 		 error,
362 		 PyExc_IOError,
363 		 "%s: unable to retrieve identifier.",
364 		 function );
365 
366 		libcerror_error_free(
367 		 &error );
368 
369 		return( NULL );
370 	}
371 	string_object = pybde_string_new_from_guid(
372 	                 guid_data,
373 	                 16 );
374 
375 	if( string_object == NULL )
376 	{
377 		PyErr_Format(
378 		 PyExc_IOError,
379 		 "%s: unable to convert GUID into Unicode object.",
380 		 function );
381 
382 		return( NULL );
383 	}
384 	return( string_object );
385 }
386 
387 /* Retrieves the type
388  * Returns a Python object if successful or NULL on error
389  */
pybde_key_protector_get_type(pybde_key_protector_t * pybde_key_protector,PyObject * arguments PYBDE_ATTRIBUTE_UNUSED)390 PyObject *pybde_key_protector_get_type(
391            pybde_key_protector_t *pybde_key_protector,
392            PyObject *arguments PYBDE_ATTRIBUTE_UNUSED )
393 {
394 	PyObject *integer_object = NULL;
395 	libcerror_error_t *error = NULL;
396 	static char *function    = "pybde_key_protector_get_type";
397 	uint16_t type            = 0;
398 	int result               = 0;
399 
400 	PYBDE_UNREFERENCED_PARAMETER( arguments )
401 
402 	if( pybde_key_protector == NULL )
403 	{
404 		PyErr_Format(
405 		 PyExc_ValueError,
406 		 "%s: invalid key protector.",
407 		 function );
408 
409 		return( NULL );
410 	}
411 	Py_BEGIN_ALLOW_THREADS
412 
413 	result = libbde_key_protector_get_type(
414 	          pybde_key_protector->key_protector,
415 	          &type,
416 	          &error );
417 
418 	Py_END_ALLOW_THREADS
419 
420 	if( result != 1 )
421 	{
422 		pybde_error_raise(
423 		 error,
424 		 PyExc_IOError,
425 		 "%s: unable to retrieve type.",
426 		 function );
427 
428 		libcerror_error_free(
429 		 &error );
430 
431 		return( NULL );
432 	}
433 #if PY_MAJOR_VERSION >= 3
434 	integer_object = PyLong_FromLong(
435 	                  (long) type );
436 #else
437 	integer_object = PyInt_FromLong(
438 	                  (long) type );
439 #endif
440 	return( integer_object );
441 }
442 
443