blob: 55cee4a4da1448b0b71ff71271796e71cba1cd1a [file] [log] [blame]
Lev Walkincfc16d32017-08-30 19:15:08 -07001/*
2 * Copyright (c) 2017 Lev Walkin <vlm@lionet.info>.
3 * All rights reserved.
4 * Redistribution and modifications are permitted subject to BSD license.
5 */
6#ifndef ASN_DISABLE_OER_SUPPORT
7
8#include <asn_internal.h>
9#include <BIT_STRING.h>
10#include <errno.h>
11
12asn_dec_rval_t
13BIT_STRING_decode_oer(asn_codec_ctx_t *opt_codec_ctx, asn_TYPE_descriptor_t *td,
14 const asn_oer_constraints_t *constraints, void **sptr,
15 const void *ptr, size_t size) {
16 BIT_STRING_t *st = (BIT_STRING_t *)*sptr;
17 const asn_oer_constraints_t *cts =
18 constraints ? constraints : td->oer_constraints;
19 ssize_t ct_size = cts ? cts->size : -1;
20 asn_dec_rval_t rval = {RC_OK, 0};
21 size_t expected_length = 0;
22
23 (void)opt_codec_ctx;
24
25 if(!st) {
26 st = (BIT_STRING_t *)(*sptr = CALLOC(1, sizeof(*st)));
27 if(!st) ASN__DECODE_FAILED;
28 }
29
30 if(ct_size >= 0) {
31 expected_length = (ct_size + 7) >> 3;
32 st->bits_unused = (8 - (ct_size & 7)) & 7;
33 } else {
34 /*
35 * X.696 (08/2015) #13.3.1
36 * Encode length determinant as _number of octets_, but only
37 * if upper bound is not equal to lower bound.
38 */
39 ssize_t len_len = oer_fetch_length(ptr, size, &expected_length);
40 if(len_len > 0) {
41 ptr = (const char *)ptr + len_len;
42 size -= len_len;
43 } else if(len_len == 0) {
44 ASN__DECODE_STARVED;
45 } else if(len_len < 0) {
46 ASN__DECODE_FAILED;
47 }
48
49 if(expected_length < 1) {
50 ASN__DECODE_STARVED;
51 }
52
53 st->bits_unused = ((const uint8_t *)ptr)[0];
54 if(st->bits_unused & ~7) {
55 ASN_DEBUG("%s: unused bits outside of 0..7 range", td->name);
56 ASN__DECODE_FAILED;
57 }
58 ptr = (const char *)ptr + 1;
59 size--;
60 expected_length--;
61 rval.consumed = len_len + 1;
62 }
63
64 if(size < expected_length) {
65 ASN__DECODE_STARVED;
66 } else {
67 uint8_t *buf = MALLOC(expected_length + 1);
68 if(buf == NULL) {
69 ASN__DECODE_FAILED;
70 } else {
71 memcpy(buf, ptr, expected_length);
72 buf[expected_length] = '\0';
73 }
74 FREEMEM(st->buf);
75 st->buf = buf;
76 st->size = expected_length;
77 if(expected_length > 0) {
78 buf[expected_length - 1] &= (0xff << st->bits_unused);
79 }
80
81 rval.consumed += expected_length;
82 return rval;
83 }
84}
85
86/*
87 * Encode as Canonical OER.
88 */
89asn_enc_rval_t
90BIT_STRING_encode_oer(asn_TYPE_descriptor_t *td,
91 const asn_oer_constraints_t *constraints, void *sptr,
92 asn_app_consume_bytes_f *cb, void *app_key) {
93 asn_enc_rval_t er = {-1,td,sptr};
94 (void)constraints;
95 (void)cb;
96 (void)app_key;
97 return er;
98}
99
100
101#endif /* ASN_DISABLE_OER_SUPPORT */