summaryrefslogtreecommitdiff
path: root/src/lib/libcrypto/asn1/a_mbstr.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib/libcrypto/asn1/a_mbstr.c')
-rw-r--r--src/lib/libcrypto/asn1/a_mbstr.c196
1 files changed, 114 insertions, 82 deletions
diff --git a/src/lib/libcrypto/asn1/a_mbstr.c b/src/lib/libcrypto/asn1/a_mbstr.c
index f6d8da8b3c..5a909d6ae2 100644
--- a/src/lib/libcrypto/asn1/a_mbstr.c
+++ b/src/lib/libcrypto/asn1/a_mbstr.c
@@ -10,7 +10,7 @@
10 * are met: 10 * are met:
11 * 11 *
12 * 1. Redistributions of source code must retain the above copyright 12 * 1. Redistributions of source code must retain the above copyright
13 * notice, this list of conditions and the following disclaimer. 13 * notice, this list of conditions and the following disclaimer.
14 * 14 *
15 * 2. Redistributions in binary form must reproduce the above copyright 15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in 16 * notice, this list of conditions and the following disclaimer in
@@ -62,7 +62,7 @@
62#include <openssl/asn1.h> 62#include <openssl/asn1.h>
63 63
64static int traverse_string(const unsigned char *p, int len, int inform, 64static int traverse_string(const unsigned char *p, int len, int inform,
65 int (*rfunc)(unsigned long value, void *in), void *arg); 65 int (*rfunc)(unsigned long value, void *in), void *arg);
66static int in_utf8(unsigned long value, void *arg); 66static int in_utf8(unsigned long value, void *arg);
67static int out_utf8(unsigned long value, void *arg); 67static int out_utf8(unsigned long value, void *arg);
68static int type_str(unsigned long value, void *arg); 68static int type_str(unsigned long value, void *arg);
@@ -80,15 +80,17 @@ static int is_printable(unsigned long value);
80 * The 'ncopy' form checks minimum and maximum size limits too. 80 * The 'ncopy' form checks minimum and maximum size limits too.
81 */ 81 */
82 82
83int ASN1_mbstring_copy(ASN1_STRING **out, const unsigned char *in, int len, 83int
84 int inform, unsigned long mask) 84ASN1_mbstring_copy(ASN1_STRING **out, const unsigned char *in, int len,
85 int inform, unsigned long mask)
85{ 86{
86 return ASN1_mbstring_ncopy(out, in, len, inform, mask, 0, 0); 87 return ASN1_mbstring_ncopy(out, in, len, inform, mask, 0, 0);
87} 88}
88 89
89int ASN1_mbstring_ncopy(ASN1_STRING **out, const unsigned char *in, int len, 90int
90 int inform, unsigned long mask, 91ASN1_mbstring_ncopy(ASN1_STRING **out, const unsigned char *in, int len,
91 long minsize, long maxsize) 92 int inform, unsigned long mask,
93 long minsize, long maxsize)
92{ 94{
93 int str_type; 95 int str_type;
94 int ret; 96 int ret;
@@ -98,59 +100,62 @@ int ASN1_mbstring_ncopy(ASN1_STRING **out, const unsigned char *in, int len,
98 unsigned char *p; 100 unsigned char *p;
99 int nchar; 101 int nchar;
100 char strbuf[32]; 102 char strbuf[32];
101 int (*cpyfunc)(unsigned long,void *) = NULL; 103 int (*cpyfunc)(unsigned long, void *) = NULL;
102 if(len == -1) len = strlen((const char *)in); 104
103 if(!mask) mask = DIRSTRING_TYPE; 105 if (len == -1)
106 len = strlen((const char *)in);
107 if (!mask)
108 mask = DIRSTRING_TYPE;
104 109
105 /* First do a string check and work out the number of characters */ 110 /* First do a string check and work out the number of characters */
106 switch(inform) { 111 switch (inform) {
107 112
108 case MBSTRING_BMP: 113 case MBSTRING_BMP:
109 if(len & 1) { 114 if (len & 1) {
110 ASN1err(ASN1_F_ASN1_MBSTRING_NCOPY, 115 ASN1err(ASN1_F_ASN1_MBSTRING_NCOPY,
111 ASN1_R_INVALID_BMPSTRING_LENGTH); 116 ASN1_R_INVALID_BMPSTRING_LENGTH);
112 return -1; 117 return -1;
113 } 118 }
114 nchar = len >> 1; 119 nchar = len >> 1;
115 break; 120 break;
116 121
117 case MBSTRING_UNIV: 122 case MBSTRING_UNIV:
118 if(len & 3) { 123 if (len & 3) {
119 ASN1err(ASN1_F_ASN1_MBSTRING_NCOPY, 124 ASN1err(ASN1_F_ASN1_MBSTRING_NCOPY,
120 ASN1_R_INVALID_UNIVERSALSTRING_LENGTH); 125 ASN1_R_INVALID_UNIVERSALSTRING_LENGTH);
121 return -1; 126 return -1;
122 } 127 }
123 nchar = len >> 2; 128 nchar = len >> 2;
124 break; 129 break;
125 130
126 case MBSTRING_UTF8: 131 case MBSTRING_UTF8:
127 nchar = 0; 132 nchar = 0;
128 /* This counts the characters and does utf8 syntax checking */ 133 /* This counts the characters and does utf8 syntax checking */
129 ret = traverse_string(in, len, MBSTRING_UTF8, in_utf8, &nchar); 134 ret = traverse_string(in, len, MBSTRING_UTF8, in_utf8, &nchar);
130 if(ret < 0) { 135 if (ret < 0) {
131 ASN1err(ASN1_F_ASN1_MBSTRING_NCOPY, 136 ASN1err(ASN1_F_ASN1_MBSTRING_NCOPY,
132 ASN1_R_INVALID_UTF8STRING); 137 ASN1_R_INVALID_UTF8STRING);
133 return -1; 138 return -1;
134 } 139 }
135 break; 140 break;
136 141
137 case MBSTRING_ASC: 142 case MBSTRING_ASC:
138 nchar = len; 143 nchar = len;
139 break; 144 break;
140 145
141 default: 146 default:
142 ASN1err(ASN1_F_ASN1_MBSTRING_NCOPY, ASN1_R_UNKNOWN_FORMAT); 147 ASN1err(ASN1_F_ASN1_MBSTRING_NCOPY, ASN1_R_UNKNOWN_FORMAT);
143 return -1; 148 return -1;
144 } 149 }
145 150
146 if((minsize > 0) && (nchar < minsize)) { 151 if ((minsize > 0) && (nchar < minsize)) {
147 ASN1err(ASN1_F_ASN1_MBSTRING_NCOPY, ASN1_R_STRING_TOO_SHORT); 152 ASN1err(ASN1_F_ASN1_MBSTRING_NCOPY, ASN1_R_STRING_TOO_SHORT);
148 (void) snprintf(strbuf, sizeof strbuf, "%ld", minsize); 153 (void) snprintf(strbuf, sizeof strbuf, "%ld", minsize);
149 ERR_add_error_data(2, "minsize=", strbuf); 154 ERR_add_error_data(2, "minsize=", strbuf);
150 return -1; 155 return -1;
151 } 156 }
152 157
153 if((maxsize > 0) && (nchar > maxsize)) { 158 if ((maxsize > 0) && (nchar > maxsize)) {
154 ASN1err(ASN1_F_ASN1_MBSTRING_NCOPY, ASN1_R_STRING_TOO_LONG); 159 ASN1err(ASN1_F_ASN1_MBSTRING_NCOPY, ASN1_R_STRING_TOO_LONG);
155 (void) snprintf(strbuf, sizeof strbuf, "%ld", maxsize); 160 (void) snprintf(strbuf, sizeof strbuf, "%ld", maxsize);
156 ERR_add_error_data(2, "maxsize=", strbuf); 161 ERR_add_error_data(2, "maxsize=", strbuf);
@@ -158,7 +163,7 @@ int ASN1_mbstring_ncopy(ASN1_STRING **out, const unsigned char *in, int len,
158 } 163 }
159 164
160 /* Now work out minimal type (if any) */ 165 /* Now work out minimal type (if any) */
161 if(traverse_string(in, len, inform, type_str, &mask) < 0) { 166 if (traverse_string(in, len, inform, type_str, &mask) < 0) {
162 ASN1err(ASN1_F_ASN1_MBSTRING_NCOPY, ASN1_R_ILLEGAL_CHARACTERS); 167 ASN1err(ASN1_F_ASN1_MBSTRING_NCOPY, ASN1_R_ILLEGAL_CHARACTERS);
163 return -1; 168 return -1;
164 } 169 }
@@ -166,24 +171,28 @@ int ASN1_mbstring_ncopy(ASN1_STRING **out, const unsigned char *in, int len,
166 171
167 /* Now work out output format and string type */ 172 /* Now work out output format and string type */
168 outform = MBSTRING_ASC; 173 outform = MBSTRING_ASC;
169 if(mask & B_ASN1_PRINTABLESTRING) str_type = V_ASN1_PRINTABLESTRING; 174 if (mask & B_ASN1_PRINTABLESTRING)
170 else if(mask & B_ASN1_IA5STRING) str_type = V_ASN1_IA5STRING; 175 str_type = V_ASN1_PRINTABLESTRING;
171 else if(mask & B_ASN1_T61STRING) str_type = V_ASN1_T61STRING; 176 else if (mask & B_ASN1_IA5STRING)
172 else if(mask & B_ASN1_BMPSTRING) { 177 str_type = V_ASN1_IA5STRING;
178 else if (mask & B_ASN1_T61STRING)
179 str_type = V_ASN1_T61STRING;
180 else if (mask & B_ASN1_BMPSTRING) {
173 str_type = V_ASN1_BMPSTRING; 181 str_type = V_ASN1_BMPSTRING;
174 outform = MBSTRING_BMP; 182 outform = MBSTRING_BMP;
175 } else if(mask & B_ASN1_UNIVERSALSTRING) { 183 } else if (mask & B_ASN1_UNIVERSALSTRING) {
176 str_type = V_ASN1_UNIVERSALSTRING; 184 str_type = V_ASN1_UNIVERSALSTRING;
177 outform = MBSTRING_UNIV; 185 outform = MBSTRING_UNIV;
178 } else { 186 } else {
179 str_type = V_ASN1_UTF8STRING; 187 str_type = V_ASN1_UTF8STRING;
180 outform = MBSTRING_UTF8; 188 outform = MBSTRING_UTF8;
181 } 189 }
182 if(!out) return str_type; 190 if (!out)
183 if(*out) { 191 return str_type;
192 if (*out) {
184 free_out = 0; 193 free_out = 0;
185 dest = *out; 194 dest = *out;
186 if(dest->data) { 195 if (dest->data) {
187 dest->length = 0; 196 dest->length = 0;
188 free(dest->data); 197 free(dest->data);
189 dest->data = NULL; 198 dest->data = NULL;
@@ -192,75 +201,78 @@ int ASN1_mbstring_ncopy(ASN1_STRING **out, const unsigned char *in, int len,
192 } else { 201 } else {
193 free_out = 1; 202 free_out = 1;
194 dest = ASN1_STRING_type_new(str_type); 203 dest = ASN1_STRING_type_new(str_type);
195 if(!dest) { 204 if (!dest) {
196 ASN1err(ASN1_F_ASN1_MBSTRING_NCOPY, 205 ASN1err(ASN1_F_ASN1_MBSTRING_NCOPY,
197 ERR_R_MALLOC_FAILURE); 206 ERR_R_MALLOC_FAILURE);
198 return -1; 207 return -1;
199 } 208 }
200 *out = dest; 209 *out = dest;
201 } 210 }
202 /* If both the same type just copy across */ 211 /* If both the same type just copy across */
203 if(inform == outform) { 212 if (inform == outform) {
204 if(!ASN1_STRING_set(dest, in, len)) { 213 if (!ASN1_STRING_set(dest, in, len)) {
205 ASN1err(ASN1_F_ASN1_MBSTRING_NCOPY,ERR_R_MALLOC_FAILURE); 214 ASN1err(ASN1_F_ASN1_MBSTRING_NCOPY,
215 ERR_R_MALLOC_FAILURE);
206 return -1; 216 return -1;
207 } 217 }
208 return str_type; 218 return str_type;
209 } 219 }
210 220
211 /* Work out how much space the destination will need */ 221 /* Work out how much space the destination will need */
212 switch(outform) { 222 switch (outform) {
213 case MBSTRING_ASC: 223 case MBSTRING_ASC:
214 outlen = nchar; 224 outlen = nchar;
215 cpyfunc = cpy_asc; 225 cpyfunc = cpy_asc;
216 break; 226 break;
217 227
218 case MBSTRING_BMP: 228 case MBSTRING_BMP:
219 outlen = nchar << 1; 229 outlen = nchar << 1;
220 cpyfunc = cpy_bmp; 230 cpyfunc = cpy_bmp;
221 break; 231 break;
222 232
223 case MBSTRING_UNIV: 233 case MBSTRING_UNIV:
224 outlen = nchar << 2; 234 outlen = nchar << 2;
225 cpyfunc = cpy_univ; 235 cpyfunc = cpy_univ;
226 break; 236 break;
227 237
228 case MBSTRING_UTF8: 238 case MBSTRING_UTF8:
229 outlen = 0; 239 outlen = 0;
230 traverse_string(in, len, inform, out_utf8, &outlen); 240 traverse_string(in, len, inform, out_utf8, &outlen);
231 cpyfunc = cpy_utf8; 241 cpyfunc = cpy_utf8;
232 break; 242 break;
233 } 243 }
234 if(!(p = malloc(outlen + 1))) { 244 if (!(p = malloc(outlen + 1))) {
235 if(free_out) ASN1_STRING_free(dest); 245 if (free_out)
236 ASN1err(ASN1_F_ASN1_MBSTRING_NCOPY,ERR_R_MALLOC_FAILURE); 246 ASN1_STRING_free(dest);
247 ASN1err(ASN1_F_ASN1_MBSTRING_NCOPY, ERR_R_MALLOC_FAILURE);
237 return -1; 248 return -1;
238 } 249 }
239 dest->length = outlen; 250 dest->length = outlen;
240 dest->data = p; 251 dest->data = p;
241 p[outlen] = 0; 252 p[outlen] = 0;
242 traverse_string(in, len, inform, cpyfunc, &p); 253 traverse_string(in, len, inform, cpyfunc, &p);
243 return str_type; 254 return str_type;
244} 255}
245 256
246/* This function traverses a string and passes the value of each character 257/* This function traverses a string and passes the value of each character
247 * to an optional function along with a void * argument. 258 * to an optional function along with a void * argument.
248 */ 259 */
249 260
250static int traverse_string(const unsigned char *p, int len, int inform, 261static int
251 int (*rfunc)(unsigned long value, void *in), void *arg) 262traverse_string(const unsigned char *p, int len, int inform,
263 int (*rfunc)(unsigned long value, void *in), void *arg)
252{ 264{
253 unsigned long value; 265 unsigned long value;
254 int ret; 266 int ret;
255 while(len) { 267 while (len) {
256 if(inform == MBSTRING_ASC) { 268 if (inform == MBSTRING_ASC) {
257 value = *p++; 269 value = *p++;
258 len--; 270 len--;
259 } else if(inform == MBSTRING_BMP) { 271 } else if (inform == MBSTRING_BMP) {
260 value = *p++ << 8; 272 value = *p++ << 8;
261 value |= *p++; 273 value |= *p++;
262 len -= 2; 274 len -= 2;
263 } else if(inform == MBSTRING_UNIV) { 275 } else if (inform == MBSTRING_UNIV) {
264 value = ((unsigned long)*p++) << 24; 276 value = ((unsigned long)*p++) << 24;
265 value |= ((unsigned long)*p++) << 16; 277 value |= ((unsigned long)*p++) << 16;
266 value |= *p++ << 8; 278 value |= *p++ << 8;
@@ -268,13 +280,14 @@ static int traverse_string(const unsigned char *p, int len, int inform,
268 len -= 4; 280 len -= 4;
269 } else { 281 } else {
270 ret = UTF8_getc(p, len, &value); 282 ret = UTF8_getc(p, len, &value);
271 if(ret < 0) return -1; 283 if (ret < 0) return -1;
272 len -= ret; 284 len -= ret;
273 p += ret; 285 p += ret;
274 } 286 }
275 if(rfunc) { 287 if (rfunc) {
276 ret = rfunc(value, arg); 288 ret = rfunc(value, arg);
277 if(ret <= 0) return ret; 289 if (ret <= 0)
290 return ret;
278 } 291 }
279 } 292 }
280 return 1; 293 return 1;
@@ -284,7 +297,8 @@ static int traverse_string(const unsigned char *p, int len, int inform,
284 297
285/* Just count number of characters */ 298/* Just count number of characters */
286 299
287static int in_utf8(unsigned long value, void *arg) 300static int
301in_utf8(unsigned long value, void *arg)
288{ 302{
289 int *nchar; 303 int *nchar;
290 nchar = arg; 304 nchar = arg;
@@ -294,7 +308,8 @@ static int in_utf8(unsigned long value, void *arg)
294 308
295/* Determine size of output as a UTF8 String */ 309/* Determine size of output as a UTF8 String */
296 310
297static int out_utf8(unsigned long value, void *arg) 311static int
312out_utf8(unsigned long value, void *arg)
298{ 313{
299 int *outlen; 314 int *outlen;
300 outlen = arg; 315 outlen = arg;
@@ -306,28 +321,33 @@ static int out_utf8(unsigned long value, void *arg)
306 * supplied "mask". 321 * supplied "mask".
307 */ 322 */
308 323
309static int type_str(unsigned long value, void *arg) 324static int
325type_str(unsigned long value, void *arg)
310{ 326{
311 unsigned long types; 327 unsigned long types;
328
312 types = *((unsigned long *)arg); 329 types = *((unsigned long *)arg);
313 if((types & B_ASN1_PRINTABLESTRING) && !is_printable(value)) 330 if ((types & B_ASN1_PRINTABLESTRING) && !is_printable(value))
314 types &= ~B_ASN1_PRINTABLESTRING; 331 types &= ~B_ASN1_PRINTABLESTRING;
315 if((types & B_ASN1_IA5STRING) && (value > 127)) 332 if ((types & B_ASN1_IA5STRING) && (value > 127))
316 types &= ~B_ASN1_IA5STRING; 333 types &= ~B_ASN1_IA5STRING;
317 if((types & B_ASN1_T61STRING) && (value > 0xff)) 334 if ((types & B_ASN1_T61STRING) && (value > 0xff))
318 types &= ~B_ASN1_T61STRING; 335 types &= ~B_ASN1_T61STRING;
319 if((types & B_ASN1_BMPSTRING) && (value > 0xffff)) 336 if ((types & B_ASN1_BMPSTRING) && (value > 0xffff))
320 types &= ~B_ASN1_BMPSTRING; 337 types &= ~B_ASN1_BMPSTRING;
321 if(!types) return -1; 338 if (!types)
339 return -1;
322 *((unsigned long *)arg) = types; 340 *((unsigned long *)arg) = types;
323 return 1; 341 return 1;
324} 342}
325 343
326/* Copy one byte per character ASCII like strings */ 344/* Copy one byte per character ASCII like strings */
327 345
328static int cpy_asc(unsigned long value, void *arg) 346static int
347cpy_asc(unsigned long value, void *arg)
329{ 348{
330 unsigned char **p, *q; 349 unsigned char **p, *q;
350
331 p = arg; 351 p = arg;
332 q = *p; 352 q = *p;
333 *q = (unsigned char) value; 353 *q = (unsigned char) value;
@@ -337,9 +357,11 @@ static int cpy_asc(unsigned long value, void *arg)
337 357
338/* Copy two byte per character BMPStrings */ 358/* Copy two byte per character BMPStrings */
339 359
340static int cpy_bmp(unsigned long value, void *arg) 360static int
361cpy_bmp(unsigned long value, void *arg)
341{ 362{
342 unsigned char **p, *q; 363 unsigned char **p, *q;
364
343 p = arg; 365 p = arg;
344 q = *p; 366 q = *p;
345 *q++ = (unsigned char) ((value >> 8) & 0xff); 367 *q++ = (unsigned char) ((value >> 8) & 0xff);
@@ -350,9 +372,11 @@ static int cpy_bmp(unsigned long value, void *arg)
350 372
351/* Copy four byte per character UniversalStrings */ 373/* Copy four byte per character UniversalStrings */
352 374
353static int cpy_univ(unsigned long value, void *arg) 375static int
376cpy_univ(unsigned long value, void *arg)
354{ 377{
355 unsigned char **p, *q; 378 unsigned char **p, *q;
379
356 p = arg; 380 p = arg;
357 q = *p; 381 q = *p;
358 *q++ = (unsigned char) ((value >> 24) & 0xff); 382 *q++ = (unsigned char) ((value >> 24) & 0xff);
@@ -365,9 +389,11 @@ static int cpy_univ(unsigned long value, void *arg)
365 389
366/* Copy to a UTF8String */ 390/* Copy to a UTF8String */
367 391
368static int cpy_utf8(unsigned long value, void *arg) 392static int
393cpy_utf8(unsigned long value, void *arg)
369{ 394{
370 unsigned char **p; 395 unsigned char **p;
396
371 int ret; 397 int ret;
372 p = arg; 398 p = arg;
373 /* We already know there is enough room so pass 0xff as the length */ 399 /* We already know there is enough room so pass 0xff as the length */
@@ -377,17 +403,23 @@ static int cpy_utf8(unsigned long value, void *arg)
377} 403}
378 404
379/* Return 1 if the character is permitted in a PrintableString */ 405/* Return 1 if the character is permitted in a PrintableString */
380static int is_printable(unsigned long value) 406static int
407is_printable(unsigned long value)
381{ 408{
382 int ch; 409 int ch;
383 if(value > 0x7f) return 0; 410
384 ch = (int) value; 411 if (value > 0x7f) return 0;
385 /* Note: we can't use 'isalnum' because certain accented 412 ch = (int)value;
413 /* Note: we can't use 'isalnum' because certain accented
386 * characters may count as alphanumeric in some environments. 414 * characters may count as alphanumeric in some environments.
387 */ 415 */
388 if((ch >= 'a') && (ch <= 'z')) return 1; 416 if ((ch >= 'a') && (ch <= 'z'))
389 if((ch >= 'A') && (ch <= 'Z')) return 1; 417 return 1;
390 if((ch >= '0') && (ch <= '9')) return 1; 418 if ((ch >= 'A') && (ch <= 'Z'))
391 if ((ch == ' ') || strchr("'()+,-./:=?", ch)) return 1; 419 return 1;
420 if ((ch >= '0') && (ch <= '9'))
421 return 1;
422 if ((ch == ' ') || strchr("'()+,-./:=?", ch))
423 return 1;
392 return 0; 424 return 0;
393} 425}