OCTET_STRING.c
Go to the documentation of this file.
1 /*-
2  * Copyright (c) 2003-2017 Lev Walkin <vlm@lionet.info>.
3  * All rights reserved.
4  * Redistribution and modifications are permitted subject to BSD license.
5  */
8 #include <errno.h>
9 
10 /*
11  * OCTET STRING basic type description.
12  */
14  (ASN_TAG_CLASS_UNIVERSAL | (4 << 2))
15 };
17  sizeof(OCTET_STRING_t),
18  offsetof(OCTET_STRING_t, _asn_ctx),
19  ASN_OSUBV_STR
20 };
23 #if !defined(ASN_DISABLE_PRINT_SUPPORT)
24  OCTET_STRING_print, /* OCTET STRING generally means a non-ascii sequence */
25 #else
26  0,
27 #endif /* !defined(ASN_DISABLE_PRINT_SUPPORT) */
30 #if !defined(ASN_DISABLE_BER_SUPPORT)
33 #else
34  0,
35  0,
36 #endif /* !defined(ASN_DISABLE_BER_SUPPORT) */
37 #if !defined(ASN_DISABLE_XER_SUPPORT)
40 #else
41  0,
42  0,
43 #endif /* !defined(ASN_DISABLE_XER_SUPPORT) */
44 #if !defined(ASN_DISABLE_JER_SUPPORT)
47 #else
48  0,
49  0,
50 #endif /* !defined(ASN_DISABLE_JER_SUPPORT) */
51 #if !defined(ASN_DISABLE_OER_SUPPORT)
54 #else
55  0,
56  0,
57 #endif /* !defined(ASN_DISABLE_OER_SUPPORT) */
58 #if !defined(ASN_DISABLE_UPER_SUPPORT)
59  OCTET_STRING_decode_uper, /* Unaligned PER decoder */
60  OCTET_STRING_encode_uper, /* Unaligned PER encoder */
61 #else
62  0,
63  0,
64 #endif /* !defined(ASN_DISABLE_UPER_SUPPORT) */
65 #if !defined(ASN_DISABLE_APER_SUPPORT)
66  OCTET_STRING_decode_aper, /* Aligned PER decoder */
67  OCTET_STRING_encode_aper, /* Aligned PER encoder */
68 #else
69  0,
70  0,
71 #endif /* !defined(ASN_DISABLE_APER_SUPPORT) */
72 #if !defined(ASN_DISABLE_RFILL_SUPPORT)
74 #else
75  0,
76 #endif /* !defined(ASN_DISABLE_RFILL_SUPPORT) */
77  0 /* Use generic outmost tag fetcher */
78 };
80  "OCTET STRING", /* Canonical name */
81  "OCTET_STRING", /* XML tag name */
85  / sizeof(asn_DEF_OCTET_STRING_tags[0]),
86  asn_DEF_OCTET_STRING_tags, /* Same as above */
88  / sizeof(asn_DEF_OCTET_STRING_tags[0]),
89  {
90 #if !defined(ASN_DISABLE_OER_SUPPORT)
91  0,
92 #endif /* !defined(ASN_DISABLE_OER_SUPPORT) */
93 #if !defined(ASN_DISABLE_UPER_SUPPORT) || !defined(ASN_DISABLE_APER_SUPPORT)
94  0,
95 #endif /* !defined(ASN_DISABLE_UPER_SUPPORT) || !defined(ASN_DISABLE_APER_SUPPORT) */
96 #if !defined(ASN_DISABLE_JER_SUPPORT)
97  0,
98 #endif /* !defined(ASN_DISABLE_JER_SUPPORT) */
100  },
101  0, 0, /* No members */
103 };
104 
105 void
107  enum asn_struct_free_method method) {
108  OCTET_STRING_t *st = (OCTET_STRING_t *)sptr;
109 
110  if(!td || !st)
111  return;
112 
113  ASN_DEBUG("Freeing %s as OCTET STRING", td->name);
114 
115  if(st->buf) {
116  FREEMEM(st->buf);
117  st->buf = 0;
118  }
119 
120 #if !defined(ASN_DISABLE_BER_SUPPORT)
121  const asn_OCTET_STRING_specifics_t *specs;
122  asn_struct_ctx_t *ctx;
123 
124  specs = td->specifics
127  ctx = (asn_struct_ctx_t *)((char *)st + specs->ctx_offset);
128 
129  /*
130  * Remove decode-time stack.
131  */
132  struct _stack *stck;
133  stck = (struct _stack *)ctx->ptr;
134  if(stck) {
135  while(stck->tail) {
136  struct _stack_el *sel = stck->tail;
137  stck->tail = sel->prev;
138  FREEMEM(sel);
139  }
140  FREEMEM(stck);
141  }
142 #endif /* !defined(ASN_DISABLE_BER_SUPPORT) */
143 
144  switch(method) {
146  FREEMEM(sptr);
147  break;
149  break;
151  memset(sptr, 0,
152  td->specifics
153  ? ((const asn_OCTET_STRING_specifics_t *)(td->specifics))
154  ->struct_size
155  : sizeof(OCTET_STRING_t));
156  break;
157  }
158 }
159 
160 /*
161  * Conversion routines.
162  */
163 int
164 OCTET_STRING_fromBuf(OCTET_STRING_t *st, const char *str, int len) {
165  void *buf;
166 
167  if(st == 0 || (str == 0 && len)) {
168  errno = EINVAL;
169  return -1;
170  }
171 
172  /*
173  * Clear the OCTET STRING.
174  */
175  if(str == NULL) {
176  FREEMEM(st->buf);
177  st->buf = 0;
178  st->size = 0;
179  return 0;
180  }
181 
182  /* Determine the original string size, if not explicitly given */
183  if(len < 0)
184  len = strlen(str);
185 
186  /* Allocate and fill the memory */
187  buf = MALLOC(len + 1);
188  if(buf == NULL)
189  return -1;
190 
191  memcpy(buf, str, len);
192  ((uint8_t *)buf)[len] = '\0'; /* Couldn't use memcpy(len+1)! */
193  FREEMEM(st->buf);
194  st->buf = (uint8_t *)buf;
195  st->size = len;
196 
197  return 0;
198 }
199 
202  int len) {
203  const asn_OCTET_STRING_specifics_t *specs =
206  OCTET_STRING_t *st;
207 
208  st = (OCTET_STRING_t *)CALLOC(1, specs->struct_size);
209  if(st && str && OCTET_STRING_fromBuf(st, str, len)) {
210  FREEMEM(st);
211  st = NULL;
212  }
213 
214  return st;
215 }
216 
217 /*
218  * Lexicographically compare the common prefix of both strings,
219  * and if it is the same return -1 for the smallest string.
220  */
221 int
222 OCTET_STRING_compare(const asn_TYPE_descriptor_t *td, const void *aptr,
223  const void *bptr) {
224  const asn_OCTET_STRING_specifics_t *specs = td->specifics;
225  const OCTET_STRING_t *a = aptr;
226  const OCTET_STRING_t *b = bptr;
227 
228  (void)specs;
229  assert(!specs || specs->subvariant != ASN_OSUBV_BIT);
230 
231  if(a && b) {
232  size_t common_prefix_size = a->size <= b->size ? a->size : b->size;
233  int ret = memcmp(a->buf, b->buf, common_prefix_size);
234  if(ret == 0) {
235  /* Figure out which string with equal prefixes is longer. */
236  if(a->size < b->size) {
237  return -1;
238  } else if(a->size > b->size) {
239  return 1;
240  } else {
241  return 0;
242  }
243  } else {
244  return ret < 0 ? -1 : 1;
245  }
246  } else if(!a && !b) {
247  return 0;
248  } else if(!a) {
249  return -1;
250  } else {
251  return 1;
252  }
253 
254 }
255 
256 int
258  const void *bptr) {
259  const asn_OCTET_STRING_specifics_t *specs =
262  OCTET_STRING_t *a = *aptr;
263  const OCTET_STRING_t *b = bptr;
264 
265  if(!b) {
266  if(a) {
267  FREEMEM(a->buf);
268  a->buf = 0;
269  a->size = 0;
270  FREEMEM(a);
271  }
272  *aptr = 0;
273  return 0;
274  }
275 
276  if(!a) {
277  a = *aptr = (OCTET_STRING_t *)CALLOC(1, specs->struct_size);
278  if(!a) return -1;
279  }
280 
281  void *buf = MALLOC(b->size + 1);
282  if(!buf) return -1;
283  memcpy(buf, b->buf, b->size);
284  ((uint8_t *)buf)[b->size] = '\0';
285 
286  FREEMEM(a->buf);
287  a->buf = (uint8_t *)buf;
288  a->size = b->size;
289 
290  return 0;
291 }
292 
293 #if !defined(ASN_DISABLE_UPER_SUPPORT) || !defined(ASN_DISABLE_APER_SUPPORT)
294 int
296  size_t units, unsigned int bpc, unsigned int unit_bits,
297  long lb, long ub, const asn_per_constraints_t *pc) {
298  uint8_t *end = buf + units * bpc;
299 
300  ASN_DEBUG("Expanding %d characters into (%ld..%ld):%d",
301  (int)units, lb, ub, unit_bits);
302 
303  /* X.691: 27.5.4 */
304  if((unsigned long)ub <= ((unsigned long)2 << (unit_bits - 1))) {
305  /* Decode without translation */
306  lb = 0;
307  } else if(pc && pc->code2value) {
308  if(unit_bits > 16)
309  return 1; /* FATAL: can't have constrained
310  * UniversalString with more than
311  * 16 million code points */
312  for(; buf < end; buf += bpc) {
313  int value;
314  int code = per_get_few_bits(po, unit_bits);
315  if(code < 0) return -1; /* WMORE */
316  value = pc->code2value(code);
317  if(value < 0) {
318  ASN_DEBUG("Code %d (0x%02x) is"
319  " not in map (%ld..%ld)",
320  code, code, lb, ub);
321  return 1; /* FATAL */
322  }
323  switch(bpc) {
324  case 1: *buf = value; break;
325  case 2: buf[0] = value >> 8; buf[1] = value; break;
326  case 4: buf[0] = value >> 24; buf[1] = value >> 16;
327  buf[2] = value >> 8; buf[3] = value; break;
328  }
329  }
330  return 0;
331  }
332 
333  /* Shortcut the no-op copying to the aligned structure */
334  if(lb == 0 && (unit_bits == 8 * bpc)) {
335  return per_get_many_bits(po, buf, 0, unit_bits * units);
336  }
337 
338  for(; buf < end; buf += bpc) {
339  int32_t code = per_get_few_bits(po, unit_bits);
340  int32_t ch = code + lb;
341  if(code < 0) return -1; /* WMORE */
342  if(ch > ub) {
343  ASN_DEBUG("Code %d is out of range (%ld..%ld)",
344  ch, lb, ub);
345  return 1; /* FATAL */
346  }
347  switch(bpc) {
348  case 1: *buf = ch; break;
349  case 2: buf[0] = ch >> 8; buf[1] = ch; break;
350  case 4: buf[0] = ch >> 24; buf[1] = ch >> 16;
351  buf[2] = ch >> 8; buf[3] = ch; break;
352  }
353  }
354 
355  return 0;
356 }
357 
358 int
360  size_t units, unsigned int bpc, unsigned int unit_bits,
361  long lb, long ub, const asn_per_constraints_t *pc) {
362  const uint8_t *end = buf + units * bpc;
363 
364  ASN_DEBUG("Squeezing %d characters into (%ld..%ld):%d (%d bpc)",
365  (int)units, lb, ub, unit_bits, bpc);
366 
367  /* X.691: 27.5.4 */
368  if((unsigned long)ub <= ((unsigned long)2 << (unit_bits - 1))) {
369  /* Encode as is */
370  lb = 0;
371  } else if(pc && pc->value2code) {
372  for(; buf < end; buf += bpc) {
373  int code;
374  uint32_t value;
375  switch(bpc) {
376  case 1: value = *(const uint8_t *)buf; break;
377  case 2: value = (buf[0] << 8) | buf[1]; break;
378  case 4: value = (buf[0] << 24) | (buf[1] << 16)
379  | (buf[2] << 8) | buf[3]; break;
380  default: return -1;
381  }
382  code = pc->value2code(value);
383  if(code < 0) {
384  ASN_DEBUG("Character %d (0x%02x) is"
385  " not in map (%ld..%ld)",
386  *buf, *buf, lb, ub);
387  return -1;
388  }
389  if(per_put_few_bits(po, code, unit_bits))
390  return -1;
391  }
392  }
393 
394  /* Shortcut the no-op copying to the aligned structure */
395  if(lb == 0 && (unit_bits == 8 * bpc)) {
396  return per_put_many_bits(po, buf, unit_bits * units);
397  }
398 
399  for(ub -= lb; buf < end; buf += bpc) {
400  int ch;
401  uint32_t value;
402  switch(bpc) {
403  case 1:
404  value = *(const uint8_t *)buf;
405  break;
406  case 2:
407  value = (buf[0] << 8) | buf[1];
408  break;
409  case 4:
410  value = (buf[0] << 24) | (buf[1] << 16) | (buf[2] << 8) | buf[3];
411  break;
412  default:
413  return -1;
414  }
415  ch = value - lb;
416  if(ch < 0 || ch > ub) {
417  ASN_DEBUG("Character %d (0x%02x) is out of range (%ld..%ld)", *buf,
418  value, lb, ub + lb);
419  return -1;
420  }
421  if(per_put_few_bits(po, ch, unit_bits)) return -1;
422  }
423 
424  return 0;
425 }
426 #endif /* !defined(ASN_DISABLE_UPER_SUPPORT) || !defined(ASN_DISABLE_APER_SUPPORT) */
asn_bit_outp_s
Definition: asn_bit_data.h:56
asn_struct_ctx_s
Definition: constr_TYPE.h:29
asn_TYPE_operation_s
Definition: constr_TYPE.h:184
OCTET_STRING_compare
int OCTET_STRING_compare(const asn_TYPE_descriptor_t *td, const void *aptr, const void *bptr)
Definition: OCTET_STRING.c:222
ASFM_FREE_UNDERLYING
@ ASFM_FREE_UNDERLYING
Definition: constr_TYPE.h:92
OCTET_STRING_copy
int OCTET_STRING_copy(const asn_TYPE_descriptor_t *td, void **aptr, const void *bptr)
Definition: OCTET_STRING.c:257
ber_tlv_tag_t
unsigned ber_tlv_tag_t
Definition: ber_tlv_tag.h:18
OCTET_STRING_encode_der
der_type_encoder_f OCTET_STRING_encode_der
Definition: OCTET_STRING.h:38
ASN_TAG_CLASS_UNIVERSAL
@ ASN_TAG_CLASS_UNIVERSAL
Definition: ber_tlv_tag.h:13
asn_TYPE_descriptor_s::name
const char * name
Definition: constr_TYPE.h:225
OCTET_STRING_encode_jer
jer_type_encoder_f OCTET_STRING_encode_jer
Definition: OCTET_STRING.h:52
_stack_el
Definition: OCTET_STRING.h:148
CALLOC
#define CALLOC(nmemb, size)
Definition: asn_internal.h:37
per_get_few_bits
#define per_get_few_bits(data, bits)
Definition: per_support.h:39
asn_OCTET_STRING_specifics_s::struct_size
unsigned struct_size
Definition: OCTET_STRING.h:131
ASFM_FREE_UNDERLYING_AND_RESET
@ ASFM_FREE_UNDERLYING_AND_RESET
Definition: constr_TYPE.h:93
ASFM_FREE_EVERYTHING
@ ASFM_FREE_EVERYTHING
Definition: constr_TYPE.h:91
OCTET_STRING_decode_oer
oer_type_decoder_f OCTET_STRING_decode_oer
Definition: OCTET_STRING.h:57
OCTET_STRING::buf
uint8_t * buf
Definition: OCTET_STRING.h:15
asn_SPC_OCTET_STRING_specs
asn_OCTET_STRING_specifics_t asn_SPC_OCTET_STRING_specs
Definition: OCTET_STRING.c:16
OCTET_STRING_decode_jer_hex
jer_type_decoder_f OCTET_STRING_decode_jer_hex
Definition: OCTET_STRING.h:50
asn_OCTET_STRING_specifics_s::ctx_offset
unsigned ctx_offset
Definition: OCTET_STRING.h:132
asn_OCTET_STRING_specifics_s
Definition: OCTET_STRING.h:125
OCTET_STRING_encode_aper
per_type_encoder_f OCTET_STRING_encode_aper
Definition: OCTET_STRING.h:67
FREEMEM
#define FREEMEM(ptr)
Definition: asn_internal.h:40
asn_bit_data_s
Definition: asn_bit_data.h:17
asn_TYPE_descriptor_s
Definition: constr_TYPE.h:224
OCTET_STRING_decode_aper
per_type_decoder_f OCTET_STRING_decode_aper
Definition: OCTET_STRING.h:66
OCTET_STRING_new_fromBuf
OCTET_STRING_t * OCTET_STRING_new_fromBuf(const asn_TYPE_descriptor_t *td, const char *str, int len)
Definition: OCTET_STRING.c:201
asn_DEF_OCTET_STRING_tags
static const ber_tlv_tag_t asn_DEF_OCTET_STRING_tags[]
Definition: OCTET_STRING.c:13
offsetof
#define offsetof(s, m)
Definition: asn_system.h:132
asn_TYPE_descriptor_s::specifics
const void * specifics
Definition: constr_TYPE.h:259
asn_OCTET_STRING_specifics_s::subvariant
enum asn_OCTET_STRING_specifics_s::asn_OS_Subvariant subvariant
asn_generic_no_constraint
asn_constr_check_f asn_generic_no_constraint
Definition: constraints.h:51
asn_struct_free_method
asn_struct_free_method
Definition: constr_TYPE.h:90
_stack::tail
struct _stack_el * tail
Definition: OCTET_STRING.h:159
per_put_many_bits
#define per_put_many_bits(out, src, nbits)
Definition: per_support.h:47
MALLOC
#define MALLOC(size)
Definition: asn_internal.h:38
OCTET_STRING_random_fill
asn_random_fill_f OCTET_STRING_random_fill
Definition: OCTET_STRING.h:71
OCTET_STRING_per_put_characters
int OCTET_STRING_per_put_characters(asn_per_outp_t *po, const uint8_t *buf, size_t units, unsigned int bpc, unsigned int unit_bits, long lb, long ub, const asn_per_constraints_t *pc)
Definition: OCTET_STRING.c:359
per_get_many_bits
#define per_get_many_bits(data, dst, align, bits)
Definition: per_support.h:41
OCTET_STRING
Definition: OCTET_STRING.h:14
OCTET_STRING_encode_oer
oer_type_encoder_f OCTET_STRING_encode_oer
Definition: OCTET_STRING.h:58
asn_internal.h
OCTET_STRING_print
asn_struct_print_f OCTET_STRING_print
Definition: OCTET_STRING.h:27
_stack
Definition: OCTET_STRING.h:158
OCTET_STRING_decode_ber
ber_type_decoder_f OCTET_STRING_decode_ber
Definition: OCTET_STRING.h:37
OCTET_STRING_free
void OCTET_STRING_free(const asn_TYPE_descriptor_t *td, void *sptr, enum asn_struct_free_method method)
Definition: OCTET_STRING.c:106
OCTET_STRING_decode_uper
per_type_decoder_f OCTET_STRING_decode_uper
Definition: OCTET_STRING.h:62
OCTET_STRING_encode_xer
xer_type_encoder_f OCTET_STRING_encode_xer
Definition: OCTET_STRING.h:45
_stack_el::prev
struct _stack_el * prev
Definition: OCTET_STRING.h:155
asn_DEF_OCTET_STRING
asn_TYPE_descriptor_t asn_DEF_OCTET_STRING
Definition: OCTET_STRING.c:79
OCTET_STRING_decode_xer_hex
xer_type_decoder_f OCTET_STRING_decode_xer_hex
Definition: OCTET_STRING.h:42
asn_per_constraints_s
Definition: per_support.h:30
asn_OP_OCTET_STRING
asn_TYPE_operation_t asn_OP_OCTET_STRING
Definition: OCTET_STRING.c:21
asn_struct_ctx_s::ptr
void * ptr
Definition: constr_TYPE.h:33
asn_per_constraints_s::code2value
int(* code2value)(unsigned int code)
Definition: per_support.h:34
OCTET_STRING_per_get_characters
int OCTET_STRING_per_get_characters(asn_per_data_t *po, uint8_t *buf, size_t units, unsigned int bpc, unsigned int unit_bits, long lb, long ub, const asn_per_constraints_t *pc)
Definition: OCTET_STRING.c:295
OCTET_STRING_encode_uper
per_type_encoder_f OCTET_STRING_encode_uper
Definition: OCTET_STRING.h:63
OCTET_STRING_t
struct OCTET_STRING OCTET_STRING_t
asn_per_constraints_s::value2code
int(* value2code)(unsigned int value)
Definition: per_support.h:33
OCTET_STRING.h
per_put_few_bits
#define per_put_few_bits(out, bits, obits)
Definition: per_support.h:46
OCTET_STRING::size
size_t size
Definition: OCTET_STRING.h:16
OCTET_STRING_fromBuf
int OCTET_STRING_fromBuf(OCTET_STRING_t *st, const char *str, int len)
Definition: OCTET_STRING.c:164


etsi_its_denm_coding
Author(s): Jean-Pierre Busch , Guido Küppers , Lennart Reiher
autogenerated on Sun May 18 2025 02:23:48