1656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project/* a_mbstr.c */
2e45f106cb6b47af1f21efe76e933bdea2f5dd1caNagendra Modadugu/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
3656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * project 1999.
4656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project */
5656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project/* ====================================================================
6656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * Copyright (c) 1999 The OpenSSL Project.  All rights reserved.
7656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *
8656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * Redistribution and use in source and binary forms, with or without
9656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * modification, are permitted provided that the following conditions
10656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * are met:
11656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *
12656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * 1. Redistributions of source code must retain the above copyright
13656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *    notice, this list of conditions and the following disclaimer.
14656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *
15656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * 2. Redistributions in binary form must reproduce the above copyright
16656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *    notice, this list of conditions and the following disclaimer in
17656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *    the documentation and/or other materials provided with the
18656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *    distribution.
19656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *
20656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * 3. All advertising materials mentioning features or use of this
21656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *    software must display the following acknowledgment:
22656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *    "This product includes software developed by the OpenSSL Project
23656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *    for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
24656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *
25656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
26656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *    endorse or promote products derived from this software without
27656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *    prior written permission. For written permission, please contact
28656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *    licensing@OpenSSL.org.
29656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *
30656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * 5. Products derived from this software may not be called "OpenSSL"
31656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *    nor may "OpenSSL" appear in their names without prior written
32656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *    permission of the OpenSSL Project.
33656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *
34656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * 6. Redistributions of any form whatsoever must retain the following
35656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *    acknowledgment:
36656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *    "This product includes software developed by the OpenSSL Project
37656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *    for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
38656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *
39656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
40656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
41656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
42656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE OpenSSL PROJECT OR
43656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
44656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
45656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
46656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
47656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
48656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
49656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
50656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * OF THE POSSIBILITY OF SUCH DAMAGE.
51656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * ====================================================================
52656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *
53656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * This product includes cryptographic software written by Eric Young
54656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * (eay@cryptsoft.com).  This product includes software written by Tim
55656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * Hudson (tjh@cryptsoft.com).
56656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project *
57656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project */
58656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
59656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#include <stdio.h>
60656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#include <ctype.h>
61656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#include "cryptlib.h"
62656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#include <openssl/asn1.h>
63656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
64656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectstatic int traverse_string(const unsigned char *p, int len, int inform,
65656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		 int (*rfunc)(unsigned long value, void *in), void *arg);
66656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectstatic int in_utf8(unsigned long value, void *arg);
67656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectstatic int out_utf8(unsigned long value, void *arg);
68656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectstatic int type_str(unsigned long value, void *arg);
69656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectstatic int cpy_asc(unsigned long value, void *arg);
70656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectstatic int cpy_bmp(unsigned long value, void *arg);
71656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectstatic int cpy_univ(unsigned long value, void *arg);
72656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectstatic int cpy_utf8(unsigned long value, void *arg);
73656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectstatic int is_printable(unsigned long value);
74656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
75656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project/* These functions take a string in UTF8, ASCII or multibyte form and
76656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * a mask of permissible ASN1 string types. It then works out the minimal
77656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * type (using the order Printable < IA5 < T61 < BMP < Universal < UTF8)
78656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * and creates a string of the correct type with the supplied data.
79656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * Yes this is horrible: it has to be :-(
80656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * The 'ncopy' form checks minimum and maximum size limits too.
81656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project */
82656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
83656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectint ASN1_mbstring_copy(ASN1_STRING **out, const unsigned char *in, int len,
84656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project					int inform, unsigned long mask)
85656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project{
86656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	return ASN1_mbstring_ncopy(out, in, len, inform, mask, 0, 0);
87656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project}
88656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
89656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectint ASN1_mbstring_ncopy(ASN1_STRING **out, const unsigned char *in, int len,
90656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project					int inform, unsigned long mask,
91656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project					long minsize, long maxsize)
92656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project{
93656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	int str_type;
94656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	int ret;
95656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	char free_out;
9698d58bb80c64b02a33662f0ea80351d4a1535267Brian Carlstrom	int outform, outlen = 0;
97656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	ASN1_STRING *dest;
98656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	unsigned char *p;
99656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	int nchar;
100656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	char strbuf[32];
101656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	int (*cpyfunc)(unsigned long,void *) = NULL;
102656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if(len == -1) len = strlen((const char *)in);
103656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if(!mask) mask = DIRSTRING_TYPE;
104656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
105656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	/* First do a string check and work out the number of characters */
106656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	switch(inform) {
107656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
108656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		case MBSTRING_BMP:
109656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		if(len & 1) {
110656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			ASN1err(ASN1_F_ASN1_MBSTRING_NCOPY,
111656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project					 ASN1_R_INVALID_BMPSTRING_LENGTH);
112656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			return -1;
113656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		}
114656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		nchar = len >> 1;
115656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		break;
116656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
117656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		case MBSTRING_UNIV:
118656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		if(len & 3) {
119656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			ASN1err(ASN1_F_ASN1_MBSTRING_NCOPY,
120656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project					 ASN1_R_INVALID_UNIVERSALSTRING_LENGTH);
121656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			return -1;
122656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		}
123656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		nchar = len >> 2;
124656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		break;
125656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
126656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		case MBSTRING_UTF8:
127656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		nchar = 0;
128656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		/* This counts the characters and does utf8 syntax checking */
129656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		ret = traverse_string(in, len, MBSTRING_UTF8, in_utf8, &nchar);
130656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		if(ret < 0) {
131656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			ASN1err(ASN1_F_ASN1_MBSTRING_NCOPY,
132656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project						 ASN1_R_INVALID_UTF8STRING);
133656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			return -1;
134656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		}
135656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		break;
136656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
137656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		case MBSTRING_ASC:
138656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		nchar = len;
139656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		break;
140656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
141656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		default:
142656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		ASN1err(ASN1_F_ASN1_MBSTRING_NCOPY, ASN1_R_UNKNOWN_FORMAT);
143656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		return -1;
144656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	}
145656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
146656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if((minsize > 0) && (nchar < minsize)) {
147656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		ASN1err(ASN1_F_ASN1_MBSTRING_NCOPY, ASN1_R_STRING_TOO_SHORT);
148656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		BIO_snprintf(strbuf, sizeof strbuf, "%ld", minsize);
149656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		ERR_add_error_data(2, "minsize=", strbuf);
150656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		return -1;
151656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	}
152656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
153656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if((maxsize > 0) && (nchar > maxsize)) {
154656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		ASN1err(ASN1_F_ASN1_MBSTRING_NCOPY, ASN1_R_STRING_TOO_LONG);
155656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		BIO_snprintf(strbuf, sizeof strbuf, "%ld", maxsize);
156656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		ERR_add_error_data(2, "maxsize=", strbuf);
157656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		return -1;
158656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	}
159656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
160656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	/* Now work out minimal type (if any) */
161656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if(traverse_string(in, len, inform, type_str, &mask) < 0) {
162656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		ASN1err(ASN1_F_ASN1_MBSTRING_NCOPY, ASN1_R_ILLEGAL_CHARACTERS);
163656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		return -1;
164656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	}
165656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
166656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
167656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	/* Now work out output format and string type */
168656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	outform = MBSTRING_ASC;
169656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if(mask & B_ASN1_PRINTABLESTRING) str_type = V_ASN1_PRINTABLESTRING;
170656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	else if(mask & B_ASN1_IA5STRING) str_type = V_ASN1_IA5STRING;
171656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	else if(mask & B_ASN1_T61STRING) str_type = V_ASN1_T61STRING;
172656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	else if(mask & B_ASN1_BMPSTRING) {
173656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		str_type = V_ASN1_BMPSTRING;
174656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		outform = MBSTRING_BMP;
175656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	} else if(mask & B_ASN1_UNIVERSALSTRING) {
176656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		str_type = V_ASN1_UNIVERSALSTRING;
177656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		outform = MBSTRING_UNIV;
178656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	} else {
179656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		str_type = V_ASN1_UTF8STRING;
180656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		outform = MBSTRING_UTF8;
181656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	}
182656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if(!out) return str_type;
183656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if(*out) {
184656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		free_out = 0;
185656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		dest = *out;
186656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		if(dest->data) {
187656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			dest->length = 0;
188656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			OPENSSL_free(dest->data);
189656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			dest->data = NULL;
190656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		}
191656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		dest->type = str_type;
192656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	} else {
193656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		free_out = 1;
194656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		dest = ASN1_STRING_type_new(str_type);
195656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		if(!dest) {
196656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			ASN1err(ASN1_F_ASN1_MBSTRING_NCOPY,
197656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project							ERR_R_MALLOC_FAILURE);
198656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			return -1;
199656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		}
200656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		*out = dest;
201656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	}
202656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	/* If both the same type just copy across */
203656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if(inform == outform) {
204656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		if(!ASN1_STRING_set(dest, in, len)) {
205656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			ASN1err(ASN1_F_ASN1_MBSTRING_NCOPY,ERR_R_MALLOC_FAILURE);
206656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			return -1;
207656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		}
208656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		return str_type;
209656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	}
210656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
211656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	/* Work out how much space the destination will need */
212656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	switch(outform) {
213656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		case MBSTRING_ASC:
214656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		outlen = nchar;
215656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		cpyfunc = cpy_asc;
216656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		break;
217656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
218656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		case MBSTRING_BMP:
219656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		outlen = nchar << 1;
220656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		cpyfunc = cpy_bmp;
221656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		break;
222656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
223656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		case MBSTRING_UNIV:
224656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		outlen = nchar << 2;
225656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		cpyfunc = cpy_univ;
226656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		break;
227656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
228656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		case MBSTRING_UTF8:
229656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		outlen = 0;
230656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		traverse_string(in, len, inform, out_utf8, &outlen);
231656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		cpyfunc = cpy_utf8;
232656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		break;
233656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	}
234656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if(!(p = OPENSSL_malloc(outlen + 1))) {
235656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		if(free_out) ASN1_STRING_free(dest);
236656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		ASN1err(ASN1_F_ASN1_MBSTRING_NCOPY,ERR_R_MALLOC_FAILURE);
237656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		return -1;
238656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	}
239656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	dest->length = outlen;
240656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	dest->data = p;
241656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	p[outlen] = 0;
242656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	traverse_string(in, len, inform, cpyfunc, &p);
243656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	return str_type;
244656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project}
245656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
246656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project/* This function traverses a string and passes the value of each character
247656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * to an optional function along with a void * argument.
248656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project */
249656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
250656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectstatic int traverse_string(const unsigned char *p, int len, int inform,
251656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		 int (*rfunc)(unsigned long value, void *in), void *arg)
252656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project{
253656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	unsigned long value;
254656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	int ret;
255656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	while(len) {
256656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		if(inform == MBSTRING_ASC) {
257656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			value = *p++;
258656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			len--;
259656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		} else if(inform == MBSTRING_BMP) {
260656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			value = *p++ << 8;
261656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			value |= *p++;
262656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			len -= 2;
263656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		} else if(inform == MBSTRING_UNIV) {
264656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			value = ((unsigned long)*p++) << 24;
265656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			value |= ((unsigned long)*p++) << 16;
266656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			value |= *p++ << 8;
267656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			value |= *p++;
268656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			len -= 4;
269656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		} else {
270656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			ret = UTF8_getc(p, len, &value);
271656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			if(ret < 0) return -1;
272656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			len -= ret;
273656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			p += ret;
274656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		}
275656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		if(rfunc) {
276656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			ret = rfunc(value, arg);
277656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project			if(ret <= 0) return ret;
278656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project		}
279656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	}
280656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	return 1;
281656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project}
282656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
283656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project/* Various utility functions for traverse_string */
284656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
285656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project/* Just count number of characters */
286656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
287656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectstatic int in_utf8(unsigned long value, void *arg)
288656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project{
289656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	int *nchar;
290656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	nchar = arg;
291656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	(*nchar)++;
292656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	return 1;
293656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project}
294656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
295656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project/* Determine size of output as a UTF8 String */
296656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
297656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectstatic int out_utf8(unsigned long value, void *arg)
298656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project{
299656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	int *outlen;
300656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	outlen = arg;
301656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	*outlen += UTF8_putc(NULL, -1, value);
302656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	return 1;
303656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project}
304656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
305656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project/* Determine the "type" of a string: check each character against a
306656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project * supplied "mask".
307656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project */
308656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
309656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectstatic int type_str(unsigned long value, void *arg)
310656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project{
311656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	unsigned long types;
312656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	types = *((unsigned long *)arg);
313656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if((types & B_ASN1_PRINTABLESTRING) && !is_printable(value))
314656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project					types &= ~B_ASN1_PRINTABLESTRING;
315656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if((types & B_ASN1_IA5STRING) && (value > 127))
316656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project					types &= ~B_ASN1_IA5STRING;
317656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if((types & B_ASN1_T61STRING) && (value > 0xff))
318656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project					types &= ~B_ASN1_T61STRING;
319656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if((types & B_ASN1_BMPSTRING) && (value > 0xffff))
320656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project					types &= ~B_ASN1_BMPSTRING;
321656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if(!types) return -1;
322656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	*((unsigned long *)arg) = types;
323656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	return 1;
324656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project}
325656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
326656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project/* Copy one byte per character ASCII like strings */
327656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
328656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectstatic int cpy_asc(unsigned long value, void *arg)
329656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project{
330656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	unsigned char **p, *q;
331656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	p = arg;
332656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	q = *p;
333656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	*q = (unsigned char) value;
334656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	(*p)++;
335656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	return 1;
336656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project}
337656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
338656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project/* Copy two byte per character BMPStrings */
339656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
340656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectstatic int cpy_bmp(unsigned long value, void *arg)
341656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project{
342656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	unsigned char **p, *q;
343656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	p = arg;
344656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	q = *p;
345656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	*q++ = (unsigned char) ((value >> 8) & 0xff);
346656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	*q = (unsigned char) (value & 0xff);
347656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	*p += 2;
348656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	return 1;
349656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project}
350656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
351656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project/* Copy four byte per character UniversalStrings */
352656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
353656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectstatic int cpy_univ(unsigned long value, void *arg)
354656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project{
355656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	unsigned char **p, *q;
356656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	p = arg;
357656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	q = *p;
358656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	*q++ = (unsigned char) ((value >> 24) & 0xff);
359656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	*q++ = (unsigned char) ((value >> 16) & 0xff);
360656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	*q++ = (unsigned char) ((value >> 8) & 0xff);
361656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	*q = (unsigned char) (value & 0xff);
362656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	*p += 4;
363656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	return 1;
364656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project}
365656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
366656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project/* Copy to a UTF8String */
367656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
368656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectstatic int cpy_utf8(unsigned long value, void *arg)
369656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project{
370656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	unsigned char **p;
371656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	int ret;
372656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	p = arg;
373656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	/* We already know there is enough room so pass 0xff as the length */
374656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	ret = UTF8_putc(*p, 0xff, value);
375656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	*p += ret;
376656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	return 1;
377656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project}
378656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project
379656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project/* Return 1 if the character is permitted in a PrintableString */
380656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Projectstatic int is_printable(unsigned long value)
381656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project{
382656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	int ch;
383656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if(value > 0x7f) return 0;
384656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	ch = (int) value;
385656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	/* Note: we can't use 'isalnum' because certain accented
386656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	 * characters may count as alphanumeric in some environments.
387656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	 */
388656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#ifndef CHARSET_EBCDIC
389656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if((ch >= 'a') && (ch <= 'z')) return 1;
390656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if((ch >= 'A') && (ch <= 'Z')) return 1;
391656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if((ch >= '0') && (ch <= '9')) return 1;
392656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if ((ch == ' ') || strchr("'()+,-./:=?", ch)) return 1;
393656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#else /*CHARSET_EBCDIC*/
394656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if((ch >= os_toascii['a']) && (ch <= os_toascii['z'])) return 1;
395656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if((ch >= os_toascii['A']) && (ch <= os_toascii['Z'])) return 1;
396656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if((ch >= os_toascii['0']) && (ch <= os_toascii['9'])) return 1;
397656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	if ((ch == os_toascii[' ']) || strchr("'()+,-./:=?", os_toebcdic[ch])) return 1;
398656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project#endif /*CHARSET_EBCDIC*/
399656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project	return 0;
400656d9c7f52f88b3a3daccafa7655dec086c4756eThe Android Open Source Project}
401