summaryrefslogtreecommitdiff
path: root/src/libstrongswan/asn1/asn1.h
blob: d29190df70087e54d9eaefd77ca49f001d0cef7e (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
/*
 * Copyright (C) 2006 Martin Will
 * Copyright (C) 2000-2008 Andreas Steffen
 *
 * Hochschule fuer Technik Rapperswil
 *
 * This program is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by the
 * Free Software Foundation; either version 2 of the License, or (at your
 * option) any later version.  See <http://www.fsf.org/copyleft/gpl.txt>.
 *
 * This program is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
 * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 * for more details.
 */

/**
 * @defgroup asn1i asn1
 * @{ @ingroup asn1
 */

#ifndef ASN1_H_
#define ASN1_H_

#include <stdarg.h>

#include <utils.h>
#include <chunk.h>

/**
 * Definition of some primitive ASN1 types
 */
typedef enum {
	ASN1_EOC =				0x00,
	ASN1_BOOLEAN =			0x01,
	ASN1_INTEGER =			0x02,
	ASN1_BIT_STRING =		0x03,
	ASN1_OCTET_STRING = 	0x04,
	ASN1_NULL = 			0x05,
	ASN1_OID =				0x06,
	ASN1_ENUMERATED =		0x0A,
	ASN1_UTF8STRING =		0x0C,
	ASN1_NUMERICSTRING =	0x12,
	ASN1_PRINTABLESTRING =	0x13,
	ASN1_T61STRING =		0x14,
	ASN1_VIDEOTEXSTRING =	0x15,
	ASN1_IA5STRING =		0x16,
	ASN1_UTCTIME =			0x17,
	ASN1_GENERALIZEDTIME =	0x18,
	ASN1_GRAPHICSTRING =	0x19,
	ASN1_VISIBLESTRING = 	0x1A,
	ASN1_GENERALSTRING =	0x1B,
	ASN1_UNIVERSALSTRING =	0x1C,
	ASN1_BMPSTRING =		0x1E,

	ASN1_CONSTRUCTED =		0x20,

	ASN1_SEQUENCE =			0x30,
	ASN1_SET =				0x31,

	ASN1_CONTEXT_S_0 =		0x80,
	ASN1_CONTEXT_S_1 =		0x81,
	ASN1_CONTEXT_S_2 =		0x82,
	ASN1_CONTEXT_S_3 =		0x83,
	ASN1_CONTEXT_S_4 =		0x84,
	ASN1_CONTEXT_S_5 =		0x85,
	ASN1_CONTEXT_S_6 =		0x86,
	ASN1_CONTEXT_S_7 =		0x87,
	ASN1_CONTEXT_S_8 =		0x88,

	ASN1_CONTEXT_C_0 =		0xA0,
	ASN1_CONTEXT_C_1 =		0xA1,
	ASN1_CONTEXT_C_2 =		0xA2,
	ASN1_CONTEXT_C_3 =		0xA3,
	ASN1_CONTEXT_C_4 =		0xA4,
	ASN1_CONTEXT_C_5 =		0xA5,

	ASN1_INVALID = 			0x100,
} asn1_t;

#define ASN1_INVALID_LENGTH	0xffffffff

/**
 * Some common prefabricated ASN.1 constants
 */
extern const chunk_t ASN1_INTEGER_0;
extern const chunk_t ASN1_INTEGER_1;
extern const chunk_t ASN1_INTEGER_2;


/** Some ASN.1 analysis functions */

/**
 * Build an algorithmIdentifier from a known OID.
 *
 * @param oid		known OID index
 * @return			body of the corresponding OID, allocated
 */
chunk_t asn1_algorithmIdentifier(int oid);

/**
 * Converts an ASN.1 OID into a known OID index
 *
 * @param object	body of an OID
 * @return			index into the oid_names[] table or OID_UNKNOWN
 */
int asn1_known_oid(chunk_t object);

/**
 * Converts a known OID index to an ASN.1 OID
 *
 * @param n			index into the oid_names[] table
 * @return			allocated OID chunk, chunk_empty if index out of range
 */
chunk_t asn1_build_known_oid(int n);

/**
 * Returns the length of an ASN.1 object
 * The blob pointer is advanced past the tag length fields
 *
 * @param blob		pointer to an ASN.1 coded blob
 * @return			length of ASN.1 object
 */
size_t asn1_length(chunk_t *blob);

/**
 * Unwrap the inner content of an ASN.1 type/length wrapped object.
 *
 * @param blob		blob to parse header from, moved behind parsed content
 * @param content	inner content
 * @return			parsed type, ASN1_INVALID if length parsing failed
 */
int asn1_unwrap(chunk_t *blob, chunk_t *content);

/**
 * Parses an ASN.1 algorithmIdentifier object
 *
 * @param blob		ASN.1 coded blob
 * @param level0	top-most level offset
 * @param params	returns optional [ASN.1 coded] parameters
 * @return			known OID index or OID_UNKNOWN
 */
int asn1_parse_algorithmIdentifier(chunk_t blob, int level0, chunk_t *params);

/**
 * Parse the top-most level of an ASN.1 object
 *
 * @param object	ASN.1 coded object
 * @param type		Expected ASN.1 type
 * @param level0	top-most level offset
 * @param name		descriptive name of object
 * @return			TRUE if parsing successful
 */
bool asn1_parse_simple_object(chunk_t *object, asn1_t type, u_int level0,
							  const char* name);

/**
 * Print the value of an ASN.1 simple object
 *
 * @param object	ASN.1 object to be printed
 * @param type		asn1_t type
 * @param private	ASN.1 data is confidential (use debug level 4)
 */
void asn1_debug_simple_object(chunk_t object, asn1_t type, bool private);

/**
 * Converts an ASN.1 UTCTIME or GENERALIZEDTIME string to time_t
 *
 * @param utctime	body of an ASN.1 coded time object
 * @param type		ASN1_UTCTIME or ASN1_GENERALIZEDTIME
 * @return			time_t in UTC
 */
time_t asn1_to_time(const chunk_t *utctime, asn1_t type);

/**
 * Converts time_t to an ASN.1 UTCTIME or GENERALIZEDTIME string
 *
 * @param time		time_t in UTC
 * @param type		ASN1_UTCTIME or ASN1_GENERALIZEDTIME
 * @return			body of an ASN.1 code time object
 */
chunk_t asn1_from_time(const time_t *time, asn1_t type);

/**
 * Parse an ASN.1 UTCTIME or GENERALIZEDTIME object
 *
 * @param blob		ASN.1 coded time object
 * @param level0	top-most level offset
 * @return			time_t in UTC
 */
time_t asn1_parse_time(chunk_t blob, int level0);

/**
 * Determines if a binary blob is ASN.1 coded
 *
 * @param blob		blob to be tested
 * @return			TRUE if blob is ASN.1 coded (SEQUENCE or SET)
 */
bool is_asn1(chunk_t blob);

/**
 * Determines if a character string can be coded as PRINTABLESTRING
 *
 * @param str		character string to be tested
 * @return			TRUE if no special characters are contained
 */
bool asn1_is_printablestring(chunk_t str);


/** some ASN.1 synthesis functions */

/**
 * Build an empty ASN.1 object with tag and length fields already filled in
 *
 * @param object	returned object - memory is allocated by function
 * @param type		ASN.1 type to be created
 * @param datalen	size of the body to be created
 * @return			points to the first position in the body
 */
u_char* asn1_build_object(chunk_t *object, asn1_t type, size_t datalen);

/**
 * Build a simple ASN.1 object
 *
 * @param tag		ASN.1 type to be created
 * @param content	content of the ASN.1 object
 * @return			chunk containing the ASN.1 coded object
 */
chunk_t asn1_simple_object(asn1_t tag, chunk_t content);

/**
 * Build an ASN.1 BITSTRING object
 *
 * @param mode		'c' for copy or 'm' for move
 * @param content	content of the BITSTRING
 * @return			chunk containing the ASN.1 coded BITSTRING
 */
chunk_t asn1_bitstring(const char *mode, chunk_t content);

/**
 * Build an ASN.1 INTEGER object
 *
 * @param mode		'c' for copy or 'm' for move
 * @param content	content of the INTEGER
 * @return			chunk containing the ASN.1 coded INTEGER
 */
chunk_t asn1_integer(const char *mode, chunk_t content);

/**
 * Build an ASN.1 object from a variable number of individual chunks
 *
 * The mode string specifies the number of chunks, and how to handle each of
 * them with a single character: 'c' for copy (allocate new chunk), 'm' for move
 * (free given chunk) or 's' for sensitive-copy (clear given chunk, then free).
 *
 * @param type		ASN.1 type to be created
 * @param mode		for each list member: 'c', 'm' or 's'
 * @return			chunk containing the ASN.1 coded object
 */
chunk_t asn1_wrap(asn1_t type, const char *mode, ...);

#endif /** ASN1_H_ @}*/