Branch data Line data Source code
1 : : /* crypto/asn1/a_bitstr.c */
2 : : /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
3 : : * All rights reserved.
4 : : *
5 : : * This package is an SSL implementation written
6 : : * by Eric Young (eay@cryptsoft.com).
7 : : * The implementation was written so as to conform with Netscapes SSL.
8 : : *
9 : : * This library is free for commercial and non-commercial use as long as
10 : : * the following conditions are aheared to. The following conditions
11 : : * apply to all code found in this distribution, be it the RC4, RSA,
12 : : * lhash, DES, etc., code; not just the SSL code. The SSL documentation
13 : : * included with this distribution is covered by the same copyright terms
14 : : * except that the holder is Tim Hudson (tjh@cryptsoft.com).
15 : : *
16 : : * Copyright remains Eric Young's, and as such any Copyright notices in
17 : : * the code are not to be removed.
18 : : * If this package is used in a product, Eric Young should be given attribution
19 : : * as the author of the parts of the library used.
20 : : * This can be in the form of a textual message at program startup or
21 : : * in documentation (online or textual) provided with the package.
22 : : *
23 : : * Redistribution and use in source and binary forms, with or without
24 : : * modification, are permitted provided that the following conditions
25 : : * are met:
26 : : * 1. Redistributions of source code must retain the copyright
27 : : * notice, this list of conditions and the following disclaimer.
28 : : * 2. Redistributions in binary form must reproduce the above copyright
29 : : * notice, this list of conditions and the following disclaimer in the
30 : : * documentation and/or other materials provided with the distribution.
31 : : * 3. All advertising materials mentioning features or use of this software
32 : : * must display the following acknowledgement:
33 : : * "This product includes cryptographic software written by
34 : : * Eric Young (eay@cryptsoft.com)"
35 : : * The word 'cryptographic' can be left out if the rouines from the library
36 : : * being used are not cryptographic related :-).
37 : : * 4. If you include any Windows specific code (or a derivative thereof) from
38 : : * the apps directory (application code) you must include an acknowledgement:
39 : : * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
40 : : *
41 : : * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
42 : : * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
43 : : * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
44 : : * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
45 : : * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
46 : : * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
47 : : * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
48 : : * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
49 : : * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
50 : : * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
51 : : * SUCH DAMAGE.
52 : : *
53 : : * The licence and distribution terms for any publically available version or
54 : : * derivative of this code cannot be changed. i.e. this code cannot simply be
55 : : * copied and put under another distribution licence
56 : : * [including the GNU Public Licence.]
57 : : */
58 : :
59 : : #include <stdio.h>
60 : : #include "cryptlib.h"
61 : : #include <openssl/asn1.h>
62 : :
63 : 0 : int ASN1_BIT_STRING_set(ASN1_BIT_STRING *x, unsigned char *d, int len)
64 : 0 : { return M_ASN1_BIT_STRING_set(x, d, len); }
65 : :
66 : 24813 : int i2c_ASN1_BIT_STRING(ASN1_BIT_STRING *a, unsigned char **pp)
67 : : {
68 : : int ret,j,bits,len;
69 : : unsigned char *p,*d;
70 : :
71 [ + - ]: 24813 : if (a == NULL) return(0);
72 : :
73 : 24813 : len=a->length;
74 : :
75 [ + - ]: 24813 : if (len > 0)
76 : : {
77 [ + + ]: 24813 : if (a->flags & ASN1_STRING_FLAG_BITS_LEFT)
78 : : {
79 : 24771 : bits=(int)a->flags&0x07;
80 : : }
81 : : else
82 : : {
83 [ + - ]: 42 : for ( ; len > 0; len--)
84 : : {
85 [ - + ]: 42 : if (a->data[len-1]) break;
86 : : }
87 : 42 : j=a->data[len-1];
88 [ + - ]: 42 : if (j & 0x01) bits=0;
89 [ + + ]: 42 : else if (j & 0x02) bits=1;
90 [ + - ]: 18 : else if (j & 0x04) bits=2;
91 [ + - ]: 18 : else if (j & 0x08) bits=3;
92 [ + - ]: 18 : else if (j & 0x10) bits=4;
93 [ + + ]: 18 : else if (j & 0x20) bits=5;
94 [ - + ]: 12 : else if (j & 0x40) bits=6;
95 [ # # ]: 0 : else if (j & 0x80) bits=7;
96 : 0 : else bits=0; /* should not happen */
97 : : }
98 : : }
99 : : else
100 : : bits=0;
101 : :
102 : 24813 : ret=1+len;
103 [ + + ]: 24813 : if (pp == NULL) return(ret);
104 : :
105 : 5997 : p= *pp;
106 : :
107 : 5997 : *(p++)=(unsigned char)bits;
108 : 5997 : d=a->data;
109 : 5997 : memcpy(p,d,len);
110 : 5997 : p+=len;
111 [ + - ]: 5997 : if (len > 0) p[-1]&=(0xff<<bits);
112 : 5997 : *pp=p;
113 : 5997 : return(ret);
114 : : }
115 : :
116 : 11004 : ASN1_BIT_STRING *c2i_ASN1_BIT_STRING(ASN1_BIT_STRING **a,
117 : : const unsigned char **pp, long len)
118 : : {
119 : 11004 : ASN1_BIT_STRING *ret=NULL;
120 : : const unsigned char *p;
121 : : unsigned char *s;
122 : : int i;
123 : :
124 [ + - ]: 11004 : if (len < 1)
125 : : {
126 : : i=ASN1_R_STRING_TOO_SHORT;
127 : : goto err;
128 : : }
129 : :
130 [ + - ][ + + ]: 11004 : if ((a == NULL) || ((*a) == NULL))
131 : : {
132 [ + - ]: 1854 : if ((ret=M_ASN1_BIT_STRING_new()) == NULL) return(NULL);
133 : : }
134 : : else
135 : : ret=(*a);
136 : :
137 : 11004 : p= *pp;
138 : 11004 : i= *(p++);
139 : : /* We do this to preserve the settings. If we modify
140 : : * the settings, via the _set_bit function, we will recalculate
141 : : * on output */
142 : 11004 : ret->flags&= ~(ASN1_STRING_FLAG_BITS_LEFT|0x07); /* clear */
143 : 11004 : ret->flags|=(ASN1_STRING_FLAG_BITS_LEFT|(i&0x07)); /* set */
144 : :
145 [ + - ]: 11004 : if (len-- > 1) /* using one because of the bits left byte */
146 : : {
147 : 11004 : s=(unsigned char *)OPENSSL_malloc((int)len);
148 [ + - ]: 11004 : if (s == NULL)
149 : : {
150 : : i=ERR_R_MALLOC_FAILURE;
151 : : goto err;
152 : : }
153 : 11004 : memcpy(s,p,(int)len);
154 : 11004 : s[len-1]&=(0xff<<i);
155 : 11004 : p+=len;
156 : : }
157 : : else
158 : : s=NULL;
159 : :
160 : 11004 : ret->length=(int)len;
161 [ - + ]: 11004 : if (ret->data != NULL) OPENSSL_free(ret->data);
162 : 11004 : ret->data=s;
163 : 11004 : ret->type=V_ASN1_BIT_STRING;
164 [ + - ]: 11004 : if (a != NULL) (*a)=ret;
165 : 11004 : *pp=p;
166 : 11004 : return(ret);
167 : : err:
168 : 0 : ASN1err(ASN1_F_C2I_ASN1_BIT_STRING,i);
169 [ # # ][ # # ]: 0 : if ((ret != NULL) && ((a == NULL) || (*a != ret)))
[ # # ]
170 : 0 : M_ASN1_BIT_STRING_free(ret);
171 : : return(NULL);
172 : : }
173 : :
174 : : /* These next 2 functions from Goetz Babin-Ebell <babinebell@trustcenter.de>
175 : : */
176 : 30 : int ASN1_BIT_STRING_set_bit(ASN1_BIT_STRING *a, int n, int value)
177 : : {
178 : : int w,v,iv;
179 : : unsigned char *c;
180 : :
181 : 30 : w=n/8;
182 : 30 : v=1<<(7-(n&0x07));
183 : 30 : iv= ~v;
184 [ - + ]: 30 : if (!value) v=0;
185 : :
186 [ + - ]: 30 : if (a == NULL)
187 : : return 0;
188 : :
189 : 30 : a->flags&= ~(ASN1_STRING_FLAG_BITS_LEFT|0x07); /* clear, set on write */
190 : :
191 [ + + ][ - + ]: 30 : if ((a->length < (w+1)) || (a->data == NULL))
192 : : {
193 [ + - ]: 14 : if (!value) return(1); /* Don't need to set */
194 [ + - ]: 14 : if (a->data == NULL)
195 : 14 : c=(unsigned char *)OPENSSL_malloc(w+1);
196 : : else
197 : 0 : c=(unsigned char *)OPENSSL_realloc_clean(a->data,
198 : : a->length,
199 : : w+1);
200 [ - + ]: 14 : if (c == NULL)
201 : : {
202 : 0 : ASN1err(ASN1_F_ASN1_BIT_STRING_SET_BIT,ERR_R_MALLOC_FAILURE);
203 : 0 : return 0;
204 : : }
205 [ + - ]: 14 : if (w+1-a->length > 0) memset(c+a->length, 0, w+1-a->length);
206 : 14 : a->data=c;
207 : 14 : a->length=w+1;
208 : : }
209 : 30 : a->data[w]=((a->data[w])&iv)|v;
210 [ + - ][ - + ]: 30 : while ((a->length > 0) && (a->data[a->length-1] == 0))
211 : 0 : a->length--;
212 : : return(1);
213 : : }
214 : :
215 : 36 : int ASN1_BIT_STRING_get_bit(ASN1_BIT_STRING *a, int n)
216 : : {
217 : : int w,v;
218 : :
219 : 36 : w=n/8;
220 : 36 : v=1<<(7-(n&0x07));
221 [ + - ][ + + ]: 36 : if ((a == NULL) || (a->length < (w+1)) || (a->data == NULL))
[ + - ]
222 : : return(0);
223 : 32 : return((a->data[w]&v) != 0);
224 : : }
225 : :
226 : : /*
227 : : * Checks if the given bit string contains only bits specified by
228 : : * the flags vector. Returns 0 if there is at least one bit set in 'a'
229 : : * which is not specified in 'flags', 1 otherwise.
230 : : * 'len' is the length of 'flags'.
231 : : */
232 : 0 : int ASN1_BIT_STRING_check(ASN1_BIT_STRING *a,
233 : : unsigned char *flags, int flags_len)
234 : : {
235 : : int i, ok;
236 : : /* Check if there is one bit set at all. */
237 [ # # ][ # # ]: 0 : if (!a || !a->data) return 1;
238 : :
239 : : /* Check each byte of the internal representation of the bit string. */
240 : : ok = 1;
241 [ # # ][ # # ]: 0 : for (i = 0; i < a->length && ok; ++i)
242 : : {
243 [ # # ]: 0 : unsigned char mask = i < flags_len ? ~flags[i] : 0xff;
244 : : /* We are done if there is an unneeded bit set. */
245 : 0 : ok = (a->data[i] & mask) == 0;
246 : : }
247 : : return ok;
248 : : }
|