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