]>
git.ipfire.org Git - people/ms/strongswan.git/blob - Source/lib/asn1-pluto/ttodata.c
5e8149955f21ab9ce503773beec87d421a01bc9f
2 * convert from text form of arbitrary data (e.g., keys) to binary
3 * Copyright (C) 2000 Henry Spencer.
5 * This library is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU Library General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or (at your
8 * option) any later version. See <http://www.fsf.org/copyleft/lgpl.txt>.
10 * This library is distributed in the hope that it will be useful, but
11 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
12 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public
13 * License for more details.
21 /* converters and misc */
22 static int unhex(const char *, char *, size_t);
23 static int unb64(const char *, char *, size_t);
24 static int untext(const char *, char *, size_t);
25 static const char *badch(const char *, int, char *, size_t);
27 /* internal error codes for converters */
28 #define SHORT (-2) /* internal buffer too short */
29 #define BADPAD (-3) /* bad base64 padding */
30 #define BADCH0 (-4) /* invalid character 0 */
31 #define BADCH1 (-5) /* invalid character 1 */
32 #define BADCH2 (-6) /* invalid character 2 */
33 #define BADCH3 (-7) /* invalid character 3 */
34 #define BADOFF(code) (BADCH0-(code))
37 - ttodatav - convert text to data, with verbose error reports
38 * If some of this looks slightly odd, it's because it has changed
39 * repeatedly (from the original atodata()) without a major rewrite.
41 const char * /* NULL on success, else literal or errp */
42 ttodatav(src
, srclen
, base
, dst
, dstlen
, lenp
, errp
, errlen
, flags
)
44 size_t srclen
; /* 0 means apply strlen() */
45 int base
; /* 0 means figure it out */
46 char *dst
; /* need not be valid if dstlen is 0 */
48 size_t *lenp
; /* where to record length (NULL is nowhere) */
49 char *errp
; /* error buffer */
53 size_t ingroup
; /* number of input bytes converted at once */
54 char buf
[4]; /* output from conversion */
55 int nbytes
; /* size of output */
56 int (*decode
)(const char *, char *, size_t);
66 dst
= buf
; /* point it somewhere valid */
71 return "input too short to be valid";
73 return "input does not begin with format prefix";
88 return "unknown format prefix";
102 if(flags
& TTODATAV_IGNORESPACE
) {
113 return "unknown base";
119 char stage
[4]; /* staging area for group */
122 /* Grab ingroup characters into stage,
123 * squeezing out blanks if we are supposed to ignore them.
125 for (sl
= 0; sl
< ingroup
; src
++, srclen
--) {
127 return "input ends in mid-byte, perhaps truncated";
128 else if (!(skipSpace
&& (*src
== ' ' || *src
== '\t')))
132 nbytes
= (*decode
)(stage
, buf
, sizeof(buf
));
138 return badch(stage
, nbytes
, errp
, errlen
);
140 return "internal buffer too short (\"can't happen\")";
142 return "bad (non-zero) padding at end of base64 input";
145 return "unknown internal error";
146 for (i
= 0; i
< nbytes
; i
++) {
151 while (srclen
>= 1 && skipSpace
&& (*src
== ' ' || *src
== '\t')){
155 if (underscoreok
&& srclen
> 1 && *src
== '_') {
156 /* srclen > 1 means not last character */
163 return "no data bytes specified by input";
170 - ttodata - convert text to data
172 const char * /* NULL on success, else literal */
173 ttodata(src
, srclen
, base
, dst
, dstlen
, lenp
)
175 size_t srclen
; /* 0 means apply strlen() */
176 int base
; /* 0 means figure it out */
177 char *dst
; /* need not be valid if dstlen is 0 */
179 size_t *lenp
; /* where to record length (NULL is nowhere) */
181 return ttodatav(src
, srclen
, base
, dst
, dstlen
, lenp
, (char *)NULL
,
182 (size_t)0, TTODATAV_SPACECOUNTS
);
186 - atodata - convert ASCII to data
187 * backward-compatibility interface
189 size_t /* 0 for failure, true length for success */
190 atodata(src
, srclen
, dst
, dstlen
)
199 err
= ttodata(src
, srclen
, 0, dst
, dstlen
, &len
);
206 - atobytes - convert ASCII to data bytes
207 * another backward-compatibility interface
210 atobytes(src
, srclen
, dst
, dstlen
, lenp
)
217 return ttodata(src
, srclen
, 0, dst
, dstlen
, lenp
);
221 - unhex - convert two ASCII hex digits to byte
223 static int /* number of result bytes, or error code */
224 unhex(src
, dst
, dstlen
)
225 const char *src
; /* known to be full length */
227 size_t dstlen
; /* not large enough is a failure */
231 static char hex
[] = "0123456789abcdef";
236 p
= strchr(hex
, *src
);
238 p
= strchr(hex
, tolower(*src
));
241 byte
= (p
- hex
) << 4;
244 p
= strchr(hex
, *src
);
246 p
= strchr(hex
, tolower(*src
));
256 - unb64 - convert four ASCII base64 digits to three bytes
257 * Note that a base64 digit group is padded out with '=' if it represents
258 * less than three bytes: one byte is dd==, two is ddd=, three is dddd.
260 static int /* number of result bytes, or error code */
261 unb64(src
, dst
, dstlen
)
262 const char *src
; /* known to be full length */
269 static char base64
[] =
270 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
275 p
= strchr(base64
, *src
++);
279 byte1
= (p
- base64
) << 2; /* first six bits */
281 p
= strchr(base64
, *src
++);
286 byte2
= p
- base64
; /* next six: two plus four */
287 *dst
++ = byte1
| (byte2
>> 4);
288 byte1
= (byte2
& 0xf) << 4;
290 p
= strchr(base64
, *src
++);
292 if (*(src
-1) == '=' && *src
== '=') {
293 if (byte1
!= 0) /* bad padding */
300 byte2
= p
- base64
; /* next six: four plus two */
301 *dst
++ = byte1
| (byte2
>> 2);
302 byte1
= (byte2
& 0x3) << 6;
304 p
= strchr(base64
, *src
++);
306 if (*(src
-1) == '=') {
307 if (byte1
!= 0) /* bad padding */
313 byte2
= p
- base64
; /* last six */
314 *dst
++ = byte1
| byte2
;
320 - untext - convert one ASCII character to byte
322 static int /* number of result bytes, or error code */
323 untext(src
, dst
, dstlen
)
324 const char *src
; /* known to be full length */
326 size_t dstlen
; /* not large enough is a failure */
336 - badch - produce a nice complaint about an unknown character
338 * If the compiler complains that the array bigenough[] has a negative
339 * size, that means the TTODATAV_BUF constant has been set too small.
341 static const char * /* literal or errp */
342 badch(src
, errcode
, errp
, errlen
)
345 char *errp
; /* might be NULL */
348 static const char pre
[] = "unknown character (`";
349 static const char suf
[] = "') in input";
351 # define REQD (sizeof(pre) - 1 + sizeof(buf) - 1 + sizeof(suf))
353 char bigenough
[TTODATAV_BUF
- REQD
]; /* see above */
357 if (errp
== NULL
|| errlen
< REQD
)
358 return "unknown character in input";
360 ch
= *(src
+ BADOFF(errcode
));
366 buf
[1] = ((ch
& 0700) >> 6) + '0';
367 buf
[2] = ((ch
& 0070) >> 3) + '0';
368 buf
[3] = ((ch
& 0007) >> 0) + '0';
373 return (const char *)errp
;