blob: 25f4af43f24fda17f71c43105500019bcac11c61 [file] [log] [blame]
Harald Welte77847ad2015-10-06 22:07:04 +02001/* helper functions to dela with asn1c data types */
2
3/* (C) 2014-2015 by Harald Welte <laforge@gnumonks.org>
4 * All Rights Reserved
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU Affero General Public License as published by
8 * the Free Software Foundation; either version 3 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU Affero General Public License for more details.
15 *
16 * You should have received a copy of the GNU Affero General Public License
17 * along with this program. If not, see <http://www.gnu.org/licenses/>.
18 *
19 */
Harald Welte30afef32015-08-30 12:28:29 +020020
21#include <string.h>
Harald Weltefcabec32015-12-18 17:50:57 +010022#include <errno.h>
Daniel Willmannb2548fb2015-11-30 16:24:57 +010023#include <arpa/inet.h>
Harald Welte30afef32015-08-30 12:28:29 +020024
Harald Welte27f9c4a2015-08-30 22:47:18 +020025#include <osmocom/core/utils.h>
Harald Welte30afef32015-08-30 12:28:29 +020026
27#include "asn1helpers.h"
Harald Weltefcabec32015-12-18 17:50:57 +010028#include "asn_internal.h"
Harald Welte30afef32015-08-30 12:28:29 +020029
Daniel Willmannb2548fb2015-11-30 16:24:57 +010030void asn1_u32_to_bitstring(BIT_STRING_t *bitstr, uint32_t *buf, uint32_t in)
Harald Welte27f9c4a2015-08-30 22:47:18 +020031{
Daniel Willmannb2548fb2015-11-30 16:24:57 +010032 *buf = htonl(in);
33 bitstr->buf = (uint8_t *) buf;
Harald Welte27f9c4a2015-08-30 22:47:18 +020034 bitstr->size = sizeof(uint32_t);
35 bitstr->bits_unused = 0;
36}
37
Daniel Willmannd6a45b42015-12-08 13:55:17 +010038void asn1_u28_to_bitstring(BIT_STRING_t *bitstr, uint32_t *buf, uint32_t in)
39{
40 *buf = htonl(in<<4);
41 bitstr->buf = (uint8_t *) buf;
42 bitstr->size = sizeof(uint32_t);
43 bitstr->bits_unused = 4;
44}
45
Daniel Willmannb2548fb2015-11-30 16:24:57 +010046void asn1_u24_to_bitstring(BIT_STRING_t *bitstr, uint32_t *buf, uint32_t in)
Harald Welte0bb12612015-10-06 22:08:54 +020047{
Daniel Willmann92247312015-12-09 19:04:33 +010048 *buf = htonl(in<<8);
Daniel Willmannb2548fb2015-11-30 16:24:57 +010049 bitstr->buf = (uint8_t *) buf;
Harald Welte0bb12612015-10-06 22:08:54 +020050 bitstr->size = 24/8;
51 bitstr->bits_unused = 0;
52}
53
Harald Weltefcabec32015-12-18 17:50:57 +010054int BIT_STRING_fromBuf(BIT_STRING_t *st, const uint8_t *str, unsigned int bit_len)
55{
56 void *buf;
57 unsigned int len = bit_len / 8;
58
59 if (bit_len % 8)
60 len++;
61
62 if (!st || (!str && len)) {
63 errno = EINVAL;
64 return -1;
65 }
66
67 if (!str) {
68 FREEMEM(st->buf);
69 st->buf = 0;
70 st->size = 0;
71 st->bits_unused = 0;
72 return 0;
73 }
74
75 if (len < 0)
76 len = strlen(str);
77
78 buf = MALLOC(len);
79 if (!buf) {
80 errno = ENOMEM;
81 return -1;
82 }
83
84 memcpy(buf, str, len);
85 FREEMEM(st->buf);
86 st->buf = buf;
87 st->size = len;
88 st->bits_unused = (len * 8) - bit_len;
89
90 return 0;
91}
92
Daniel Willmannf3685c22015-12-07 17:18:56 +010093void asn1_u16_to_str(OCTET_STRING_t *str, uint16_t *buf, uint16_t in)
94{
95 *buf = htons(in);
96 str->buf = (uint8_t *) buf;
97 str->size = sizeof(uint16_t);
98}
99
100void asn1_u8_to_str(OCTET_STRING_t *str, uint8_t *buf, uint8_t in)
101{
102 *buf = in;
103 str->buf = buf;
104 str->size = sizeof(uint8_t);
105}
Harald Welte27f9c4a2015-08-30 22:47:18 +0200106
107int asn1_strncpy(char *out, const OCTET_STRING_t *in, size_t n)
Harald Welte30afef32015-08-30 12:28:29 +0200108{
Daniel Willmann53018e92015-11-23 15:49:29 +0100109 size_t cpylen = n-1;
Harald Welte30afef32015-08-30 12:28:29 +0200110
Harald Welte27f9c4a2015-08-30 22:47:18 +0200111 if (in->size < cpylen)
112 cpylen = in->size;
Harald Welte30afef32015-08-30 12:28:29 +0200113
114 strncpy(out, (char *)in->buf, cpylen);
Daniel Willmann53018e92015-11-23 15:49:29 +0100115 out[cpylen] = '\0';
Harald Welte30afef32015-08-30 12:28:29 +0200116
117 return cpylen;
118}
Harald Welte27f9c4a2015-08-30 22:47:18 +0200119
120uint16_t asn1str_to_u16(const OCTET_STRING_t *in)
121{
Daniel Willmannb2548fb2015-11-30 16:24:57 +0100122 OSMO_ASSERT(in && in->size == sizeof(uint16_t));
Daniel Willmanne3adf0e2015-11-27 17:53:19 +0100123 return ntohs(*(uint16_t *)in->buf);
Harald Welte27f9c4a2015-08-30 22:47:18 +0200124}
125
126uint8_t asn1str_to_u8(const OCTET_STRING_t *in)
127{
Daniel Willmannb2548fb2015-11-30 16:24:57 +0100128 OSMO_ASSERT(in && in->size == sizeof(uint8_t));
Harald Welte27f9c4a2015-08-30 22:47:18 +0200129 return *(uint8_t *)in->buf;
130}
131
132uint32_t asn1bitstr_to_u32(const BIT_STRING_t *in)
133{
Daniel Willmannb2548fb2015-11-30 16:24:57 +0100134 OSMO_ASSERT(in && in->size == sizeof(uint32_t));
Harald Welte4dd16b92015-10-06 22:08:10 +0200135
Daniel Willmanne3adf0e2015-11-27 17:53:19 +0100136 return ntohl(*(uint32_t *)in->buf);
137}
Daniel Willmann6e59d412015-11-23 14:03:04 +0100138
Daniel Willmannd6a45b42015-12-08 13:55:17 +0100139uint32_t asn1bitstr_to_u28(const BIT_STRING_t *in)
140{
141 OSMO_ASSERT(in && in->size == sizeof(uint32_t) && in->bits_unused == 4);
142
143 return ntohl(*(uint32_t *)in->buf) >> 4;
144}
145
Daniel Willmanne3adf0e2015-11-27 17:53:19 +0100146uint32_t asn1bitstr_to_u24(const BIT_STRING_t *in)
147{
Daniel Willmannb2548fb2015-11-30 16:24:57 +0100148 OSMO_ASSERT(in && in->size == 3);
Daniel Willmann6e59d412015-11-23 14:03:04 +0100149
Daniel Willmann92247312015-12-09 19:04:33 +0100150 return ntohl(*(uint32_t *)in->buf) >> 8;
Harald Welte27f9c4a2015-08-30 22:47:18 +0200151}