1 /*
2  * The key bag header functions
3  *
4  * Copyright (C) 2018-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 <byte_stream.h>
24 #include <memory.h>
25 #include <types.h>
26 
27 #include "libfsapfs_debug.h"
28 #include "libfsapfs_key_bag_header.h"
29 #include "libfsapfs_libcerror.h"
30 #include "libfsapfs_libcnotify.h"
31 #include "libfsapfs_libfguid.h"
32 
33 #include "fsapfs_key_bag.h"
34 
35 /* Creates container physical_map_header
36  * Make sure the value key_bag_header is referencing, is set to NULL
37  * Returns 1 if successful or -1 on error
38  */
libfsapfs_key_bag_header_initialize(libfsapfs_key_bag_header_t ** key_bag_header,libcerror_error_t ** error)39 int libfsapfs_key_bag_header_initialize(
40      libfsapfs_key_bag_header_t **key_bag_header,
41      libcerror_error_t **error )
42 {
43 	static char *function = "libfsapfs_key_bag_header_initialize";
44 
45 	if( key_bag_header == NULL )
46 	{
47 		libcerror_error_set(
48 		 error,
49 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
50 		 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
51 		 "%s: invalid key bag header.",
52 		 function );
53 
54 		return( -1 );
55 	}
56 	if( *key_bag_header != NULL )
57 	{
58 		libcerror_error_set(
59 		 error,
60 		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
61 		 LIBCERROR_RUNTIME_ERROR_VALUE_ALREADY_SET,
62 		 "%s: invalid key bag header value already set.",
63 		 function );
64 
65 		return( -1 );
66 	}
67 	*key_bag_header = memory_allocate_structure(
68 	                   libfsapfs_key_bag_header_t );
69 
70 	if( *key_bag_header == NULL )
71 	{
72 		libcerror_error_set(
73 		 error,
74 		 LIBCERROR_ERROR_DOMAIN_MEMORY,
75 		 LIBCERROR_MEMORY_ERROR_INSUFFICIENT,
76 		 "%s: unable to create key bag header.",
77 		 function );
78 
79 		goto on_error;
80 	}
81 	if( memory_set(
82 	     *key_bag_header,
83 	     0,
84 	     sizeof( libfsapfs_key_bag_header_t ) ) == NULL )
85 	{
86 		libcerror_error_set(
87 		 error,
88 		 LIBCERROR_ERROR_DOMAIN_MEMORY,
89 		 LIBCERROR_MEMORY_ERROR_SET_FAILED,
90 		 "%s: unable to clear key bag header.",
91 		 function );
92 
93 		goto on_error;
94 	}
95 	return( 1 );
96 
97 on_error:
98 	if( *key_bag_header != NULL )
99 	{
100 		memory_free(
101 		 *key_bag_header );
102 
103 		*key_bag_header = NULL;
104 	}
105 	return( -1 );
106 }
107 
108 /* Frees key bag header
109  * Returns 1 if successful or -1 on error
110  */
libfsapfs_key_bag_header_free(libfsapfs_key_bag_header_t ** key_bag_header,libcerror_error_t ** error)111 int libfsapfs_key_bag_header_free(
112      libfsapfs_key_bag_header_t **key_bag_header,
113      libcerror_error_t **error )
114 {
115 	static char *function = "libfsapfs_key_bag_header_free";
116 
117 	if( key_bag_header == NULL )
118 	{
119 		libcerror_error_set(
120 		 error,
121 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
122 		 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
123 		 "%s: invalid key bag header.",
124 		 function );
125 
126 		return( -1 );
127 	}
128 	if( *key_bag_header != NULL )
129 	{
130 		memory_free(
131 		 *key_bag_header );
132 
133 		*key_bag_header = NULL;
134 	}
135 	return( 1 );
136 }
137 
138 /* Reads the key bag header
139  * Returns 1 if successful or -1 on error
140  */
libfsapfs_key_bag_header_read_data(libfsapfs_key_bag_header_t * key_bag_header,const uint8_t * data,size_t data_size,libcerror_error_t ** error)141 int libfsapfs_key_bag_header_read_data(
142      libfsapfs_key_bag_header_t *key_bag_header,
143      const uint8_t *data,
144      size_t data_size,
145      libcerror_error_t **error )
146 {
147 	static char *function   = "libfsapfs_key_bag_header_read_data";
148 	uint16_t format_version = 0;
149 
150 #if defined( HAVE_DEBUG_OUTPUT )
151 	uint64_t value_64bit    = 0;
152 #endif
153 
154 	if( key_bag_header == NULL )
155 	{
156 		libcerror_error_set(
157 		 error,
158 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
159 		 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
160 		 "%s: invalid key bag header.",
161 		 function );
162 
163 		return( -1 );
164 	}
165 	if( data == NULL )
166 	{
167 		libcerror_error_set(
168 		 error,
169 		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
170 		 LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
171 		 "%s: invalid data.",
172 		 function );
173 
174 		return( -1 );
175 	}
176 	if( ( data_size < sizeof( fsapfs_key_bag_header_t ) )
177 	 || ( data_size > (size_t) SSIZE_MAX ) )
178 	{
179 		libcerror_error_set(
180 		 error,
181 		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
182 		 LIBCERROR_RUNTIME_ERROR_VALUE_OUT_OF_BOUNDS,
183 		 "%s: invalid data size value out of bounds.",
184 		 function );
185 
186 		return( -1 );
187 	}
188 #if defined( HAVE_DEBUG_OUTPUT )
189 	if( libcnotify_verbose != 0 )
190 	{
191 		libcnotify_printf(
192 		 "%s: key bag header data:\n",
193 		 function );
194 		libcnotify_print_data(
195 		 data,
196 		 sizeof( fsapfs_key_bag_header_t ),
197 		 LIBCNOTIFY_PRINT_DATA_FLAG_GROUP_DATA );
198 	}
199 #endif
200 	byte_stream_copy_to_uint16_little_endian(
201 	 ( (fsapfs_key_bag_header_t *) data )->format_version,
202 	 format_version );
203 
204 	byte_stream_copy_to_uint16_little_endian(
205 	 ( (fsapfs_key_bag_header_t *) data )->number_of_entries,
206 	 key_bag_header->number_of_entries );
207 
208 	byte_stream_copy_to_uint32_little_endian(
209 	 ( (fsapfs_key_bag_header_t *) data )->data_size,
210 	 key_bag_header->data_size );
211 
212 #if defined( HAVE_DEBUG_OUTPUT )
213 	if( libcnotify_verbose != 0 )
214 	{
215 		libcnotify_printf(
216 		 "%s: format version\t\t\t: %" PRIu16 "\n",
217 		 function,
218 		 format_version );
219 
220 		libcnotify_printf(
221 		 "%s: number of entries\t\t\t: %" PRIu16 "\n",
222 		 function,
223 		 key_bag_header->number_of_entries );
224 
225 		libcnotify_printf(
226 		 "%s: data size\t\t\t\t: %" PRIu32 "\n",
227 		 function,
228 		 key_bag_header->data_size );
229 
230 		byte_stream_copy_to_uint64_little_endian(
231 		 ( (fsapfs_key_bag_header_t *) data )->unknown1,
232 		 value_64bit );
233 		libcnotify_printf(
234 		 "%s: unknown1\t\t\t\t: 0x%08" PRIx64 "\n",
235 		 function,
236 		 value_64bit );
237 
238 		libcnotify_printf(
239 		 "\n" );
240 	}
241 #endif /* defined( HAVE_DEBUG_OUTPUT ) */
242 
243 	if( format_version != 2 )
244 	{
245 		libcerror_error_set(
246 		 error,
247 		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
248 		 LIBCERROR_RUNTIME_ERROR_UNSUPPORTED_VALUE,
249 		 "%s: unsupported format version: %" PRIu16 ".",
250 		 function,
251 		 format_version );
252 
253 		return( -1 );
254 	}
255 	return( 1 );
256 }
257 
258