1 | /*
|
---|
2 | * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved.
|
---|
3 | *
|
---|
4 | * Licensed under the OpenSSL license (the "License"). You may not use
|
---|
5 | * this file except in compliance with the License. You can obtain a copy
|
---|
6 | * in the file LICENSE in the source distribution or at
|
---|
7 | * https://www.openssl.org/source/license.html
|
---|
8 | */
|
---|
9 |
|
---|
10 | #include <limits.h>
|
---|
11 | #include <stdio.h>
|
---|
12 | #include "internal/cryptlib.h"
|
---|
13 | #include <openssl/asn1.h>
|
---|
14 | #include "asn1_local.h"
|
---|
15 |
|
---|
16 | int ASN1_BIT_STRING_set(ASN1_BIT_STRING *x, unsigned char *d, int len)
|
---|
17 | {
|
---|
18 | return ASN1_STRING_set(x, d, len);
|
---|
19 | }
|
---|
20 |
|
---|
21 | int i2c_ASN1_BIT_STRING(ASN1_BIT_STRING *a, unsigned char **pp)
|
---|
22 | {
|
---|
23 | int ret, j, bits, len;
|
---|
24 | unsigned char *p, *d;
|
---|
25 |
|
---|
26 | if (a == NULL)
|
---|
27 | return 0;
|
---|
28 |
|
---|
29 | len = a->length;
|
---|
30 |
|
---|
31 | if (len > 0) {
|
---|
32 | if (a->flags & ASN1_STRING_FLAG_BITS_LEFT) {
|
---|
33 | bits = (int)a->flags & 0x07;
|
---|
34 | } else {
|
---|
35 | for (; len > 0; len--) {
|
---|
36 | if (a->data[len - 1])
|
---|
37 | break;
|
---|
38 | }
|
---|
39 | j = a->data[len - 1];
|
---|
40 | if (j & 0x01)
|
---|
41 | bits = 0;
|
---|
42 | else if (j & 0x02)
|
---|
43 | bits = 1;
|
---|
44 | else if (j & 0x04)
|
---|
45 | bits = 2;
|
---|
46 | else if (j & 0x08)
|
---|
47 | bits = 3;
|
---|
48 | else if (j & 0x10)
|
---|
49 | bits = 4;
|
---|
50 | else if (j & 0x20)
|
---|
51 | bits = 5;
|
---|
52 | else if (j & 0x40)
|
---|
53 | bits = 6;
|
---|
54 | else if (j & 0x80)
|
---|
55 | bits = 7;
|
---|
56 | else
|
---|
57 | bits = 0; /* should not happen */
|
---|
58 | }
|
---|
59 | } else
|
---|
60 | bits = 0;
|
---|
61 |
|
---|
62 | ret = 1 + len;
|
---|
63 | if (pp == NULL)
|
---|
64 | return ret;
|
---|
65 |
|
---|
66 | p = *pp;
|
---|
67 |
|
---|
68 | *(p++) = (unsigned char)bits;
|
---|
69 | d = a->data;
|
---|
70 | if (len > 0) {
|
---|
71 | memcpy(p, d, len);
|
---|
72 | p += len;
|
---|
73 | p[-1] &= (0xff << bits);
|
---|
74 | }
|
---|
75 | *pp = p;
|
---|
76 | return ret;
|
---|
77 | }
|
---|
78 |
|
---|
79 | ASN1_BIT_STRING *c2i_ASN1_BIT_STRING(ASN1_BIT_STRING **a,
|
---|
80 | const unsigned char **pp, long len)
|
---|
81 | {
|
---|
82 | ASN1_BIT_STRING *ret = NULL;
|
---|
83 | const unsigned char *p;
|
---|
84 | unsigned char *s;
|
---|
85 | int i;
|
---|
86 |
|
---|
87 | if (len < 1) {
|
---|
88 | i = ASN1_R_STRING_TOO_SHORT;
|
---|
89 | goto err;
|
---|
90 | }
|
---|
91 |
|
---|
92 | if (len > INT_MAX) {
|
---|
93 | i = ASN1_R_STRING_TOO_LONG;
|
---|
94 | goto err;
|
---|
95 | }
|
---|
96 |
|
---|
97 | if ((a == NULL) || ((*a) == NULL)) {
|
---|
98 | if ((ret = ASN1_BIT_STRING_new()) == NULL)
|
---|
99 | return NULL;
|
---|
100 | } else
|
---|
101 | ret = (*a);
|
---|
102 |
|
---|
103 | p = *pp;
|
---|
104 | i = *(p++);
|
---|
105 | if (i > 7) {
|
---|
106 | i = ASN1_R_INVALID_BIT_STRING_BITS_LEFT;
|
---|
107 | goto err;
|
---|
108 | }
|
---|
109 | /*
|
---|
110 | * We do this to preserve the settings. If we modify the settings, via
|
---|
111 | * the _set_bit function, we will recalculate on output
|
---|
112 | */
|
---|
113 | ret->flags &= ~(ASN1_STRING_FLAG_BITS_LEFT | 0x07); /* clear */
|
---|
114 | ret->flags |= (ASN1_STRING_FLAG_BITS_LEFT | i); /* set */
|
---|
115 |
|
---|
116 | if (len-- > 1) { /* using one because of the bits left byte */
|
---|
117 | s = OPENSSL_malloc((int)len);
|
---|
118 | if (s == NULL) {
|
---|
119 | i = ERR_R_MALLOC_FAILURE;
|
---|
120 | goto err;
|
---|
121 | }
|
---|
122 | memcpy(s, p, (int)len);
|
---|
123 | s[len - 1] &= (0xff << i);
|
---|
124 | p += len;
|
---|
125 | } else
|
---|
126 | s = NULL;
|
---|
127 |
|
---|
128 | ret->length = (int)len;
|
---|
129 | OPENSSL_free(ret->data);
|
---|
130 | ret->data = s;
|
---|
131 | ret->type = V_ASN1_BIT_STRING;
|
---|
132 | if (a != NULL)
|
---|
133 | (*a) = ret;
|
---|
134 | *pp = p;
|
---|
135 | return ret;
|
---|
136 | err:
|
---|
137 | ASN1err(ASN1_F_C2I_ASN1_BIT_STRING, i);
|
---|
138 | if ((a == NULL) || (*a != ret))
|
---|
139 | ASN1_BIT_STRING_free(ret);
|
---|
140 | return NULL;
|
---|
141 | }
|
---|
142 |
|
---|
143 | /*
|
---|
144 | * These next 2 functions from Goetz Babin-Ebell.
|
---|
145 | */
|
---|
146 | int ASN1_BIT_STRING_set_bit(ASN1_BIT_STRING *a, int n, int value)
|
---|
147 | {
|
---|
148 | int w, v, iv;
|
---|
149 | unsigned char *c;
|
---|
150 |
|
---|
151 | w = n / 8;
|
---|
152 | v = 1 << (7 - (n & 0x07));
|
---|
153 | iv = ~v;
|
---|
154 | if (!value)
|
---|
155 | v = 0;
|
---|
156 |
|
---|
157 | if (a == NULL)
|
---|
158 | return 0;
|
---|
159 |
|
---|
160 | a->flags &= ~(ASN1_STRING_FLAG_BITS_LEFT | 0x07); /* clear, set on write */
|
---|
161 |
|
---|
162 | if ((a->length < (w + 1)) || (a->data == NULL)) {
|
---|
163 | if (!value)
|
---|
164 | return 1; /* Don't need to set */
|
---|
165 | c = OPENSSL_clear_realloc(a->data, a->length, w + 1);
|
---|
166 | if (c == NULL) {
|
---|
167 | ASN1err(ASN1_F_ASN1_BIT_STRING_SET_BIT, ERR_R_MALLOC_FAILURE);
|
---|
168 | return 0;
|
---|
169 | }
|
---|
170 | if (w + 1 - a->length > 0)
|
---|
171 | memset(c + a->length, 0, w + 1 - a->length);
|
---|
172 | a->data = c;
|
---|
173 | a->length = w + 1;
|
---|
174 | }
|
---|
175 | a->data[w] = ((a->data[w]) & iv) | v;
|
---|
176 | while ((a->length > 0) && (a->data[a->length - 1] == 0))
|
---|
177 | a->length--;
|
---|
178 | return 1;
|
---|
179 | }
|
---|
180 |
|
---|
181 | int ASN1_BIT_STRING_get_bit(const ASN1_BIT_STRING *a, int n)
|
---|
182 | {
|
---|
183 | int w, v;
|
---|
184 |
|
---|
185 | w = n / 8;
|
---|
186 | v = 1 << (7 - (n & 0x07));
|
---|
187 | if ((a == NULL) || (a->length < (w + 1)) || (a->data == NULL))
|
---|
188 | return 0;
|
---|
189 | return ((a->data[w] & v) != 0);
|
---|
190 | }
|
---|
191 |
|
---|
192 | /*
|
---|
193 | * Checks if the given bit string contains only bits specified by
|
---|
194 | * the flags vector. Returns 0 if there is at least one bit set in 'a'
|
---|
195 | * which is not specified in 'flags', 1 otherwise.
|
---|
196 | * 'len' is the length of 'flags'.
|
---|
197 | */
|
---|
198 | int ASN1_BIT_STRING_check(const ASN1_BIT_STRING *a,
|
---|
199 | const unsigned char *flags, int flags_len)
|
---|
200 | {
|
---|
201 | int i, ok;
|
---|
202 | /* Check if there is one bit set at all. */
|
---|
203 | if (!a || !a->data)
|
---|
204 | return 1;
|
---|
205 |
|
---|
206 | /*
|
---|
207 | * Check each byte of the internal representation of the bit string.
|
---|
208 | */
|
---|
209 | ok = 1;
|
---|
210 | for (i = 0; i < a->length && ok; ++i) {
|
---|
211 | unsigned char mask = i < flags_len ? ~flags[i] : 0xff;
|
---|
212 | /* We are done if there is an unneeded bit set. */
|
---|
213 | ok = (a->data[i] & mask) == 0;
|
---|
214 | }
|
---|
215 | return ok;
|
---|
216 | }
|
---|