1 /*
2  * libpri: An implementation of Primary Rate ISDN
3  *
4  * Copyright (C) 2009 Digium, Inc.
5  *
6  * Richard Mudgett <rmudgett@digium.com>
7  *
8  * See http://www.asterisk.org for more information about
9  * the Asterisk project. Please do not directly contact
10  * any of the maintainers of this project for assistance;
11  * the project provides a web site, mailing lists and IRC
12  * channels for your use.
13  *
14  * This program is free software, distributed under the terms of
15  * the GNU General Public License Version 2 as published by the
16  * Free Software Foundation. See the LICENSE file included with
17  * this program for more details.
18  *
19  * In addition, when this program is distributed with Asterisk in
20  * any form that would qualify as a 'combined work' or as a
21  * 'derivative work' (but not mere aggregation), you can redistribute
22  * and/or modify the combination under the terms of the license
23  * provided with that copy of Asterisk, instead of the license
24  * terms granted here.
25  */
26 
27 /*!
28  * \file
29  * \brief Q.SIG ROSE Name operations and elements
30  *
31  * Name-Operations ECMA-164 Annex C
32  *
33  * \author Richard Mudgett <rmudgett@digium.com>
34  */
35 
36 
37 #include "compat.h"
38 #include "libpri.h"
39 #include "pri_internal.h"
40 #include "rose.h"
41 #include "rose_internal.h"
42 #include "asn1.h"
43 
44 
45 /* ------------------------------------------------------------------- */
46 
47 /*!
48  * \internal
49  * \brief Encode the Q.SIG NameSet type.
50  *
51  * \param ctrl D channel controller for diagnostic messages or global options.
52  * \param pos Starting position to encode ASN.1 component.
53  * \param end End of ASN.1 encoding data buffer.
54  * \param tag Component tag to identify the encoded component.
55  *   The tag should be ASN1_TAG_SEQUENCE unless the caller
56  *   implicitly tags it otherwise.
57  * \param name
58  *
59  * \retval Start of the next ASN.1 component to encode on success.
60  * \retval NULL on error.
61  */
rose_enc_qsig_NameSet(struct pri * ctrl,unsigned char * pos,unsigned char * end,unsigned tag,const struct roseQsigName * name)62 static unsigned char *rose_enc_qsig_NameSet(struct pri *ctrl, unsigned char *pos,
63 	unsigned char *end, unsigned tag, const struct roseQsigName *name)
64 {
65 	unsigned char *seq_len;
66 
67 	ASN1_CONSTRUCTED_BEGIN(seq_len, pos, end, tag);
68 
69 	ASN1_CALL(pos, asn1_enc_string_bin(pos, end, ASN1_TYPE_OCTET_STRING, name->data,
70 		name->length));
71 	ASN1_CALL(pos, asn1_enc_int(pos, end, ASN1_TYPE_INTEGER, name->char_set));
72 
73 	ASN1_CONSTRUCTED_END(seq_len, pos, end);
74 
75 	return pos;
76 }
77 
78 /*!
79  * \brief Encode the Q.SIG Name type.
80  *
81  * \param ctrl D channel controller for diagnostic messages or global options.
82  * \param pos Starting position to encode ASN.1 component.
83  * \param end End of ASN.1 encoding data buffer.
84  * \param name
85  *
86  * \retval Start of the next ASN.1 component to encode on success.
87  * \retval NULL on error.
88  */
rose_enc_qsig_Name(struct pri * ctrl,unsigned char * pos,unsigned char * end,const struct roseQsigName * name)89 unsigned char *rose_enc_qsig_Name(struct pri *ctrl, unsigned char *pos,
90 	unsigned char *end, const struct roseQsigName *name)
91 {
92 	switch (name->presentation) {
93 	case 0:	/* optional_name_not_present */
94 		/* Do not encode anything */
95 		break;
96 	case 1:	/* presentation_allowed */
97 		if (name->char_set == 1) {
98 			ASN1_CALL(pos, asn1_enc_string_bin(pos, end, ASN1_CLASS_CONTEXT_SPECIFIC | 0,
99 				name->data, name->length));
100 		} else {
101 			ASN1_CALL(pos, rose_enc_qsig_NameSet(ctrl, pos, end,
102 				ASN1_CLASS_CONTEXT_SPECIFIC | 1, name));
103 		}
104 		break;
105 	case 2:	/* presentation_restricted */
106 		if (name->char_set == 1) {
107 			ASN1_CALL(pos, asn1_enc_string_bin(pos, end, ASN1_CLASS_CONTEXT_SPECIFIC | 2,
108 				name->data, name->length));
109 		} else {
110 			ASN1_CALL(pos, rose_enc_qsig_NameSet(ctrl, pos, end,
111 				ASN1_CLASS_CONTEXT_SPECIFIC | 3, name));
112 		}
113 		break;
114 	case 3:	/* presentation_restricted_null */
115 		ASN1_CALL(pos, asn1_enc_null(pos, end, ASN1_CLASS_CONTEXT_SPECIFIC | 7));
116 		break;
117 	case 4:	/* name_not_available */
118 		ASN1_CALL(pos, asn1_enc_null(pos, end, ASN1_CLASS_CONTEXT_SPECIFIC | 4));
119 		break;
120 	default:
121 		ASN1_ENC_ERROR(ctrl, "Unknown name presentation");
122 		return NULL;
123 	}
124 
125 	return pos;
126 }
127 
128 /*!
129  * \internal
130  * \brief Encode the Q.SIG party-Name invoke facility ie arguments.
131  *
132  * \param ctrl D channel controller for diagnostic messages or global options.
133  * \param pos Starting position to encode ASN.1 component.
134  * \param end End of ASN.1 encoding data buffer.
135  * \param party Information to encode.
136  *
137  * \retval Start of the next ASN.1 component to encode on success.
138  * \retval NULL on error.
139  */
rose_enc_qsig_PartyName_ARG_Backend(struct pri * ctrl,unsigned char * pos,unsigned char * end,const struct roseQsigPartyName_ARG * party)140 static unsigned char *rose_enc_qsig_PartyName_ARG_Backend(struct pri *ctrl,
141 	unsigned char *pos, unsigned char *end, const struct roseQsigPartyName_ARG *party)
142 {
143 	return rose_enc_qsig_Name(ctrl, pos, end, &party->name);
144 }
145 
146 /*!
147  * \brief Encode the Q.SIG CallingName invoke facility ie arguments.
148  *
149  * \param ctrl D channel controller for diagnostic messages or global options.
150  * \param pos Starting position to encode ASN.1 component.
151  * \param end End of ASN.1 encoding data buffer.
152  * \param args Arguments to encode in the buffer.
153  *
154  * \retval Start of the next ASN.1 component to encode on success.
155  * \retval NULL on error.
156  */
rose_enc_qsig_CallingName_ARG(struct pri * ctrl,unsigned char * pos,unsigned char * end,const union rose_msg_invoke_args * args)157 unsigned char *rose_enc_qsig_CallingName_ARG(struct pri *ctrl, unsigned char *pos,
158 	unsigned char *end, const union rose_msg_invoke_args *args)
159 {
160 	return rose_enc_qsig_PartyName_ARG_Backend(ctrl, pos, end, &args->qsig.CallingName);
161 }
162 
163 /*!
164  * \brief Encode the Q.SIG CalledName invoke facility ie arguments.
165  *
166  * \param ctrl D channel controller for diagnostic messages or global options.
167  * \param pos Starting position to encode ASN.1 component.
168  * \param end End of ASN.1 encoding data buffer.
169  * \param args Arguments to encode in the buffer.
170  *
171  * \retval Start of the next ASN.1 component to encode on success.
172  * \retval NULL on error.
173  */
rose_enc_qsig_CalledName_ARG(struct pri * ctrl,unsigned char * pos,unsigned char * end,const union rose_msg_invoke_args * args)174 unsigned char *rose_enc_qsig_CalledName_ARG(struct pri *ctrl, unsigned char *pos,
175 	unsigned char *end, const union rose_msg_invoke_args *args)
176 {
177 	return rose_enc_qsig_PartyName_ARG_Backend(ctrl, pos, end, &args->qsig.CalledName);
178 }
179 
180 /*!
181  * \brief Encode the Q.SIG ConnectedName invoke facility ie arguments.
182  *
183  * \param ctrl D channel controller for diagnostic messages or global options.
184  * \param pos Starting position to encode ASN.1 component.
185  * \param end End of ASN.1 encoding data buffer.
186  * \param args Arguments to encode in the buffer.
187  *
188  * \retval Start of the next ASN.1 component to encode on success.
189  * \retval NULL on error.
190  */
rose_enc_qsig_ConnectedName_ARG(struct pri * ctrl,unsigned char * pos,unsigned char * end,const union rose_msg_invoke_args * args)191 unsigned char *rose_enc_qsig_ConnectedName_ARG(struct pri *ctrl, unsigned char *pos,
192 	unsigned char *end, const union rose_msg_invoke_args *args)
193 {
194 	return rose_enc_qsig_PartyName_ARG_Backend(ctrl, pos, end,
195 		&args->qsig.ConnectedName);
196 }
197 
198 /*!
199  * \brief Encode the Q.SIG BusyName invoke facility ie arguments.
200  *
201  * \param ctrl D channel controller for diagnostic messages or global options.
202  * \param pos Starting position to encode ASN.1 component.
203  * \param end End of ASN.1 encoding data buffer.
204  * \param args Arguments to encode in the buffer.
205  *
206  * \retval Start of the next ASN.1 component to encode on success.
207  * \retval NULL on error.
208  */
rose_enc_qsig_BusyName_ARG(struct pri * ctrl,unsigned char * pos,unsigned char * end,const union rose_msg_invoke_args * args)209 unsigned char *rose_enc_qsig_BusyName_ARG(struct pri *ctrl, unsigned char *pos,
210 	unsigned char *end, const union rose_msg_invoke_args *args)
211 {
212 	return rose_enc_qsig_PartyName_ARG_Backend(ctrl, pos, end, &args->qsig.BusyName);
213 }
214 
215 /*!
216  * \internal
217  * \brief Decode the Q.SIG NameData Name argument parameters.
218  *
219  * \param ctrl D channel controller for any diagnostic messages.
220  * \param fname Field name
221  * \param tag Component tag that identified this production.
222  * \param pos Starting position of the ASN.1 component length.
223  * \param end End of ASN.1 decoding data buffer.
224  * \param name Parameter storage to fill.
225  *
226  * \retval Start of the next ASN.1 component on success.
227  * \retval NULL on error.
228  */
rose_dec_qsig_NameData(struct pri * ctrl,const char * fname,unsigned tag,const unsigned char * pos,const unsigned char * end,struct roseQsigName * name)229 static const unsigned char *rose_dec_qsig_NameData(struct pri *ctrl, const char *fname,
230 	unsigned tag, const unsigned char *pos, const unsigned char *end,
231 	struct roseQsigName *name)
232 {
233 	size_t str_len;
234 
235 	ASN1_CALL(pos, asn1_dec_string_bin(ctrl, fname, tag, pos, end, sizeof(name->data),
236 		name->data, &str_len));
237 	name->length = str_len;
238 
239 	return pos;
240 }
241 
242 /*!
243  * \internal
244  * \brief Decode the Q.SIG NameSet Name argument parameters.
245  *
246  * \param ctrl D channel controller for any diagnostic messages.
247  * \param fname Field name
248  * \param tag Component tag that identified this production.
249  * \param pos Starting position of the ASN.1 component length.
250  * \param end End of ASN.1 decoding data buffer.
251  * \param name Parameter storage to fill.
252  *
253  * \retval Start of the next ASN.1 component on success.
254  * \retval NULL on error.
255  */
rose_dec_qsig_NameSet(struct pri * ctrl,const char * fname,unsigned tag,const unsigned char * pos,const unsigned char * end,struct roseQsigName * name)256 static const unsigned char *rose_dec_qsig_NameSet(struct pri *ctrl, const char *fname,
257 	unsigned tag, const unsigned char *pos, const unsigned char *end,
258 	struct roseQsigName *name)
259 {
260 	int32_t value;
261 	int length;
262 	int seq_offset;
263 	const unsigned char *seq_end;
264 
265 	if (ctrl->debug & PRI_DEBUG_APDU) {
266 		pri_message(ctrl, "  %s NameSet %s\n", fname, asn1_tag2str(tag));
267 	}
268 	ASN1_CALL(pos, asn1_dec_length(pos, end, &length));
269 	ASN1_END_SETUP(seq_end, seq_offset, length, pos, end);
270 
271 	ASN1_CALL(pos, asn1_dec_tag(pos, seq_end, &tag));
272 	ASN1_CHECK_TAG(ctrl, tag, tag & ~ASN1_PC_MASK, ASN1_TYPE_OCTET_STRING);
273 	ASN1_CALL(pos, rose_dec_qsig_NameData(ctrl, "nameData", tag, pos, seq_end, name));
274 
275 	if (pos < end && *pos != ASN1_INDEF_TERM) {
276 		ASN1_CALL(pos, asn1_dec_tag(pos, seq_end, &tag));
277 		ASN1_CHECK_TAG(ctrl, tag, tag, ASN1_TYPE_INTEGER);
278 		ASN1_CALL(pos, asn1_dec_int(ctrl, "characterSet", tag, pos, seq_end, &value));
279 		name->char_set = value;
280 	} else {
281 		name->char_set = 1;	/* default to iso8859-1 */
282 	}
283 
284 	ASN1_END_FIXUP(ctrl, pos, seq_offset, seq_end, end);
285 
286 	return pos;
287 }
288 
289 /*!
290  * \brief Decode the Q.SIG Name argument parameters.
291  *
292  * \param ctrl D channel controller for any diagnostic messages.
293  * \param fname Field name
294  * \param tag Component tag that identified this production.
295  * \param pos Starting position of the ASN.1 component length.
296  * \param end End of ASN.1 decoding data buffer.
297  * \param name Parameter storage to fill.
298  *
299  * \retval Start of the next ASN.1 component on success.
300  * \retval NULL on error.
301  */
rose_dec_qsig_Name(struct pri * ctrl,const char * fname,unsigned tag,const unsigned char * pos,const unsigned char * end,struct roseQsigName * name)302 const unsigned char *rose_dec_qsig_Name(struct pri *ctrl, const char *fname,
303 	unsigned tag, const unsigned char *pos, const unsigned char *end,
304 	struct roseQsigName *name)
305 {
306 	if (ctrl->debug & PRI_DEBUG_APDU) {
307 		pri_message(ctrl, "  %s Name\n", fname);
308 	}
309 	name->char_set = 1;	/* default to iso8859-1 */
310 	switch (tag & ~ASN1_PC_MASK) {
311 	case ASN1_CLASS_CONTEXT_SPECIFIC | 0:
312 		name->presentation = 1;	/* presentation_allowed */
313 		ASN1_CALL(pos, rose_dec_qsig_NameData(ctrl, "namePresentationAllowedSimple", tag,
314 			pos, end, name));
315 		break;
316 	case ASN1_CLASS_CONTEXT_SPECIFIC | 1:
317 		/* Must be constructed but we will not check for it for simplicity. */
318 		name->presentation = 1;	/* presentation_allowed */
319 		ASN1_CALL(pos, rose_dec_qsig_NameSet(ctrl, "namePresentationAllowedExtended",
320 			tag, pos, end, name));
321 		break;
322 	case ASN1_CLASS_CONTEXT_SPECIFIC | 2:
323 		name->presentation = 2;	/* presentation_restricted */
324 		ASN1_CALL(pos, rose_dec_qsig_NameData(ctrl, "namePresentationRestrictedSimple",
325 			tag, pos, end, name));
326 		break;
327 	case ASN1_CLASS_CONTEXT_SPECIFIC | 3:
328 		/* Must be constructed but we will not check for it for simplicity. */
329 		name->presentation = 2;	/* presentation_restricted */
330 		ASN1_CALL(pos, rose_dec_qsig_NameSet(ctrl, "namePresentationRestrictedExtended",
331 			tag, pos, end, name));
332 		break;
333 	case ASN1_CLASS_CONTEXT_SPECIFIC | 4:
334 		/* Must not be constructed but we will not check for it for simplicity. */
335 		name->presentation = 4;	/* name_not_available */
336 		name->length = 0;
337 		name->data[0] = 0;
338 		ASN1_CALL(pos, asn1_dec_null(ctrl, "nameNotAvailable", tag, pos, end));
339 		break;
340 	case ASN1_CLASS_CONTEXT_SPECIFIC | 7:
341 		/* Must not be constructed but we will not check for it for simplicity. */
342 		name->presentation = 3;	/* presentation_restricted_null */
343 		name->length = 0;
344 		name->data[0] = 0;
345 		ASN1_CALL(pos, asn1_dec_null(ctrl, "namePresentationRestrictedNull", tag, pos,
346 			end));
347 		break;
348 	default:
349 		ASN1_DID_NOT_EXPECT_TAG(ctrl, tag);
350 		return NULL;
351 	}
352 
353 	return pos;
354 }
355 
356 /*!
357  * \internal
358  * \brief Decode the Q.SIG party-Name invoke argument parameters.
359  *
360  * \param ctrl D channel controller for diagnostic messages or global options.
361  * \param name Field name
362  * \param tag Component tag that identified this structure.
363  * \param pos Starting position of the ASN.1 component length.
364  * \param end End of ASN.1 decoding data buffer.
365  * \param party Parameter storage to fill.
366  *
367  * \retval Start of the next ASN.1 component on success.
368  * \retval NULL on error.
369  */
rose_dec_qsig_PartyName_ARG_Backend(struct pri * ctrl,const char * name,unsigned tag,const unsigned char * pos,const unsigned char * end,struct roseQsigPartyName_ARG * party)370 static const unsigned char *rose_dec_qsig_PartyName_ARG_Backend(struct pri *ctrl,
371 	const char *name, unsigned tag, const unsigned char *pos, const unsigned char *end,
372 	struct roseQsigPartyName_ARG *party)
373 {
374 	int length;
375 	int seq_offset;
376 	const unsigned char *seq_end;
377 
378 	if (tag == ASN1_TAG_SEQUENCE) {
379 		if (ctrl->debug & PRI_DEBUG_APDU) {
380 			pri_message(ctrl, "  %s %s\n", name, asn1_tag2str(tag));
381 		}
382 		ASN1_CALL(pos, asn1_dec_length(pos, end, &length));
383 		ASN1_END_SETUP(seq_end, seq_offset, length, pos, end);
384 
385 		ASN1_CALL(pos, asn1_dec_tag(pos, seq_end, &tag));
386 		ASN1_CALL(pos, rose_dec_qsig_Name(ctrl, "name", tag, pos, seq_end,
387 			&party->name));
388 
389 		/* Fixup will skip over any OPTIONAL manufacturer extension information */
390 		ASN1_END_FIXUP(ctrl, pos, seq_offset, seq_end, end);
391 	} else {
392 		ASN1_CALL(pos, rose_dec_qsig_Name(ctrl, name, tag, pos, end, &party->name));
393 	}
394 
395 	return pos;
396 }
397 
398 /*!
399  * \brief Decode the Q.SIG CallingName invoke argument parameters.
400  *
401  * \param ctrl D channel controller for diagnostic messages or global options.
402  * \param tag Component tag that identified this structure.
403  * \param pos Starting position of the ASN.1 component length.
404  * \param end End of ASN.1 decoding data buffer.
405  * \param args Arguments to fill in from the decoded buffer.
406  *
407  * \retval Start of the next ASN.1 component on success.
408  * \retval NULL on error.
409  */
rose_dec_qsig_CallingName_ARG(struct pri * ctrl,unsigned tag,const unsigned char * pos,const unsigned char * end,union rose_msg_invoke_args * args)410 const unsigned char *rose_dec_qsig_CallingName_ARG(struct pri *ctrl, unsigned tag,
411 	const unsigned char *pos, const unsigned char *end, union rose_msg_invoke_args *args)
412 {
413 	return rose_dec_qsig_PartyName_ARG_Backend(ctrl, "callingName", tag, pos, end,
414 		&args->qsig.CallingName);
415 }
416 
417 /*!
418  * \brief Decode the Q.SIG CalledName invoke argument parameters.
419  *
420  * \param ctrl D channel controller for diagnostic messages or global options.
421  * \param tag Component tag that identified this structure.
422  * \param pos Starting position of the ASN.1 component length.
423  * \param end End of ASN.1 decoding data buffer.
424  * \param args Arguments to fill in from the decoded buffer.
425  *
426  * \retval Start of the next ASN.1 component on success.
427  * \retval NULL on error.
428  */
rose_dec_qsig_CalledName_ARG(struct pri * ctrl,unsigned tag,const unsigned char * pos,const unsigned char * end,union rose_msg_invoke_args * args)429 const unsigned char *rose_dec_qsig_CalledName_ARG(struct pri *ctrl, unsigned tag,
430 	const unsigned char *pos, const unsigned char *end, union rose_msg_invoke_args *args)
431 {
432 	return rose_dec_qsig_PartyName_ARG_Backend(ctrl, "calledName", tag, pos, end,
433 		&args->qsig.CalledName);
434 }
435 
436 /*!
437  * \brief Decode the Q.SIG ConnectedName invoke argument parameters.
438  *
439  * \param ctrl D channel controller for diagnostic messages or global options.
440  * \param tag Component tag that identified this structure.
441  * \param pos Starting position of the ASN.1 component length.
442  * \param end End of ASN.1 decoding data buffer.
443  * \param args Arguments to fill in from the decoded buffer.
444  *
445  * \retval Start of the next ASN.1 component on success.
446  * \retval NULL on error.
447  */
rose_dec_qsig_ConnectedName_ARG(struct pri * ctrl,unsigned tag,const unsigned char * pos,const unsigned char * end,union rose_msg_invoke_args * args)448 const unsigned char *rose_dec_qsig_ConnectedName_ARG(struct pri *ctrl, unsigned tag,
449 	const unsigned char *pos, const unsigned char *end, union rose_msg_invoke_args *args)
450 {
451 	return rose_dec_qsig_PartyName_ARG_Backend(ctrl, "connectedName", tag, pos, end,
452 		&args->qsig.ConnectedName);
453 }
454 
455 /*!
456  * \brief Decode the Q.SIG BusyName invoke argument parameters.
457  *
458  * \param ctrl D channel controller for diagnostic messages or global options.
459  * \param tag Component tag that identified this structure.
460  * \param pos Starting position of the ASN.1 component length.
461  * \param end End of ASN.1 decoding data buffer.
462  * \param args Arguments to fill in from the decoded buffer.
463  *
464  * \retval Start of the next ASN.1 component on success.
465  * \retval NULL on error.
466  */
rose_dec_qsig_BusyName_ARG(struct pri * ctrl,unsigned tag,const unsigned char * pos,const unsigned char * end,union rose_msg_invoke_args * args)467 const unsigned char *rose_dec_qsig_BusyName_ARG(struct pri *ctrl, unsigned tag,
468 	const unsigned char *pos, const unsigned char *end, union rose_msg_invoke_args *args)
469 {
470 	return rose_dec_qsig_PartyName_ARG_Backend(ctrl, "busyName", tag, pos, end,
471 		&args->qsig.BusyName);
472 }
473 
474 /* ------------------------------------------------------------------- */
475 /* end rose_qsig_name.c */
476