1 /*
2  * Python object definition of the libbde key protection types
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_key_protection_types.h"
30 #include "pybde_libbde.h"
31 #include "pybde_python.h"
32 #include "pybde_unused.h"
33 
34 PyTypeObject pybde_key_protection_types_type_object = {
35 	PyVarObject_HEAD_INIT( NULL, 0 )
36 
37 	/* tp_name */
38 	"pybde.key_protection_types",
39 	/* tp_basicsize */
40 	sizeof( pybde_key_protection_types_t ),
41 	/* tp_itemsize */
42 	0,
43 	/* tp_dealloc */
44 	(destructor) pybde_key_protection_types_free,
45 	/* tp_print */
46 	0,
47 	/* tp_getattr */
48 	0,
49 	/* tp_setattr */
50 	0,
51 	/* tp_compare */
52 	0,
53 	/* tp_repr */
54 	0,
55 	/* tp_as_number */
56 	0,
57 	/* tp_as_sequence */
58 	0,
59 	/* tp_as_mapping */
60 	0,
61 	/* tp_hash */
62 	0,
63 	/* tp_call */
64 	0,
65 	/* tp_str */
66 	0,
67 	/* tp_getattro */
68 	0,
69 	/* tp_setattro */
70 	0,
71 	/* tp_as_buffer */
72 	0,
73 	/* tp_flags */
74 	Py_TPFLAGS_DEFAULT,
75 	/* tp_doc */
76 	"pybde key protection types object (wraps LIBBDE_KEY_PROTECTION_TYPES)",
77 	/* tp_traverse */
78 	0,
79 	/* tp_clear */
80 	0,
81 	/* tp_richcompare */
82 	0,
83 	/* tp_weaklistoffset */
84 	0,
85 	/* tp_iter */
86 	0,
87 	/* tp_iternext */
88 	0,
89 	/* tp_methods */
90 	0,
91 	/* tp_members */
92 	0,
93 	/* tp_getset */
94 	0,
95 	/* tp_base */
96 	0,
97 	/* tp_dict */
98 	0,
99 	/* tp_descr_get */
100 	0,
101 	/* tp_descr_set */
102 	0,
103 	/* tp_dictoffset */
104 	0,
105 	/* tp_init */
106 	(initproc) pybde_key_protection_types_init,
107 	/* tp_alloc */
108 	0,
109 	/* tp_new */
110 	0,
111 	/* tp_free */
112 	0,
113 	/* tp_is_gc */
114 	0,
115 	/* tp_bases */
116 	NULL,
117 	/* tp_mro */
118 	NULL,
119 	/* tp_cache */
120 	NULL,
121 	/* tp_subclasses */
122 	NULL,
123 	/* tp_weaklist */
124 	NULL,
125 	/* tp_del */
126 	0
127 };
128 
129 /* Initializes the type object
130  * Returns 1 if successful or -1 on error
131  */
pybde_key_protection_types_init_type(PyTypeObject * type_object)132 int pybde_key_protection_types_init_type(
133      PyTypeObject *type_object )
134 {
135 	PyObject *value_object = NULL;
136 
137 	if( type_object == NULL )
138 	{
139 		return( -1 );
140 	}
141 	type_object->tp_dict = PyDict_New();
142 
143 	if( type_object->tp_dict == NULL )
144 	{
145 		return( -1 );
146 	}
147 #if PY_MAJOR_VERSION >= 3
148 	value_object = PyLong_FromLong(
149 	                LIBBDE_KEY_PROTECTION_TYPE_CLEAR_KEY );
150 #else
151 	value_object = PyInt_FromLong(
152 	                LIBBDE_KEY_PROTECTION_TYPE_CLEAR_KEY );
153 #endif
154 	if( PyDict_SetItemString(
155 	     type_object->tp_dict,
156 	     "CLEAR_KEY",
157 	     value_object ) != 0 )
158 	{
159 		goto on_error;
160 	}
161 #if PY_MAJOR_VERSION >= 3
162 	value_object = PyLong_FromLong(
163 	                LIBBDE_KEY_PROTECTION_TYPE_TPM );
164 #else
165 	value_object = PyInt_FromLong(
166 	                LIBBDE_KEY_PROTECTION_TYPE_TPM );
167 #endif
168 	if( PyDict_SetItemString(
169 	     type_object->tp_dict,
170 	     "TPM",
171 	     value_object ) != 0 )
172 	{
173 		goto on_error;
174 	}
175 #if PY_MAJOR_VERSION >= 3
176 	value_object = PyLong_FromLong(
177 	                LIBBDE_KEY_PROTECTION_TYPE_STARTUP_KEY );
178 #else
179 	value_object = PyInt_FromLong(
180 	                LIBBDE_KEY_PROTECTION_TYPE_STARTUP_KEY );
181 #endif
182 	if( PyDict_SetItemString(
183 	     type_object->tp_dict,
184 	     "STARTUP_KEY",
185 	     value_object ) != 0 )
186 	{
187 		goto on_error;
188 	}
189 #if PY_MAJOR_VERSION >= 3
190 	value_object = PyLong_FromLong(
191 	                LIBBDE_KEY_PROTECTION_TYPE_TPM_AND_PIN );
192 #else
193 	value_object = PyInt_FromLong(
194 	                LIBBDE_KEY_PROTECTION_TYPE_TPM_AND_PIN );
195 #endif
196 	if( PyDict_SetItemString(
197 	     type_object->tp_dict,
198 	     "TPM_AND_PIN",
199 	     value_object ) != 0 )
200 	{
201 		goto on_error;
202 	}
203 #if PY_MAJOR_VERSION >= 3
204 	value_object = PyLong_FromLong(
205 	                LIBBDE_KEY_PROTECTION_TYPE_RECOVERY_PASSWORD );
206 #else
207 	value_object = PyInt_FromLong(
208 	                LIBBDE_KEY_PROTECTION_TYPE_RECOVERY_PASSWORD );
209 #endif
210 	if( PyDict_SetItemString(
211 	     type_object->tp_dict,
212 	     "RECOVERY_PASSWORD",
213 	     value_object ) != 0 )
214 	{
215 		goto on_error;
216 	}
217 #if PY_MAJOR_VERSION >= 3
218 	value_object = PyLong_FromLong(
219 	                LIBBDE_KEY_PROTECTION_TYPE_PASSWORD );
220 #else
221 	value_object = PyInt_FromLong(
222 	                LIBBDE_KEY_PROTECTION_TYPE_PASSWORD );
223 #endif
224 	if( PyDict_SetItemString(
225 	     type_object->tp_dict,
226 	     "PASSWORD",
227 	     value_object ) != 0 )
228 	{
229 		goto on_error;
230 	}
231 	return( 1 );
232 
233 on_error:
234 	if( type_object->tp_dict != NULL )
235 	{
236 		Py_DecRef(
237 		 type_object->tp_dict );
238 
239 		type_object->tp_dict = NULL;
240 	}
241 	return( -1 );
242 }
243 
244 /* Creates a new key protection types object
245  * Returns a Python object if successful or NULL on error
246  */
pybde_key_protection_types_new(void)247 PyObject *pybde_key_protection_types_new(
248            void )
249 {
250 	pybde_key_protection_types_t *definitions_object = NULL;
251 	static char *function                            = "pybde_key_protection_types_new";
252 
253 	definitions_object = PyObject_New(
254 	                      struct pybde_key_protection_types,
255 	                      &pybde_key_protection_types_type_object );
256 
257 	if( definitions_object == NULL )
258 	{
259 		PyErr_Format(
260 		 PyExc_MemoryError,
261 		 "%s: unable to create definitions object.",
262 		 function );
263 
264 		goto on_error;
265 	}
266 	if( pybde_key_protection_types_init(
267 	     definitions_object ) != 0 )
268 	{
269 		PyErr_Format(
270 		 PyExc_MemoryError,
271 		 "%s: unable to initialize definitions object.",
272 		 function );
273 
274 		goto on_error;
275 	}
276 	return( (PyObject *) definitions_object );
277 
278 on_error:
279 	if( definitions_object != NULL )
280 	{
281 		Py_DecRef(
282 		 (PyObject *) definitions_object );
283 	}
284 	return( NULL );
285 }
286 
287 /* Initializes a key protection types object
288  * Returns 0 if successful or -1 on error
289  */
pybde_key_protection_types_init(pybde_key_protection_types_t * definitions_object)290 int pybde_key_protection_types_init(
291      pybde_key_protection_types_t *definitions_object )
292 {
293 	static char *function = "pybde_key_protection_types_init";
294 
295 	if( definitions_object == NULL )
296 	{
297 		PyErr_Format(
298 		 PyExc_TypeError,
299 		 "%s: invalid definitions object.",
300 		 function );
301 
302 		return( -1 );
303 	}
304 	return( 0 );
305 }
306 
307 /* Frees a key protection types object
308  */
pybde_key_protection_types_free(pybde_key_protection_types_t * definitions_object)309 void pybde_key_protection_types_free(
310       pybde_key_protection_types_t *definitions_object )
311 {
312 	struct _typeobject *ob_type = NULL;
313 	static char *function       = "pybde_key_protection_types_free";
314 
315 	if( definitions_object == NULL )
316 	{
317 		PyErr_Format(
318 		 PyExc_TypeError,
319 		 "%s: invalid definitions object.",
320 		 function );
321 
322 		return;
323 	}
324 	ob_type = Py_TYPE(
325 	           definitions_object );
326 
327 	if( ob_type == NULL )
328 	{
329 		PyErr_Format(
330 		 PyExc_ValueError,
331 		 "%s: missing ob_type.",
332 		 function );
333 
334 		return;
335 	}
336 	if( ob_type->tp_free == NULL )
337 	{
338 		PyErr_Format(
339 		 PyExc_ValueError,
340 		 "%s: invalid ob_type - missing tp_free.",
341 		 function );
342 
343 		return;
344 	}
345 	ob_type->tp_free(
346 	 (PyObject*) definitions_object );
347 }
348 
349