Home | History | Annotate | Line # | Download | only in liblutil
base64.c revision 1.1.1.1.6.2
      1  1.1.1.1.6.2  wrstuden /* base64.c -- routines to encode/decode base64 data */
      2  1.1.1.1.6.2  wrstuden /* $OpenLDAP: pkg/ldap/libraries/liblutil/base64.c,v 1.15.2.3 2008/02/11 23:26:42 kurt Exp $ */
      3  1.1.1.1.6.2  wrstuden /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
      4  1.1.1.1.6.2  wrstuden  *
      5  1.1.1.1.6.2  wrstuden  * Copyright 1998-2008 The OpenLDAP Foundation.
      6  1.1.1.1.6.2  wrstuden  * Portions Copyright 1998-2003 Kurt D. Zeilenga.
      7  1.1.1.1.6.2  wrstuden  * Portions Copyright 1995 IBM Corporation.
      8  1.1.1.1.6.2  wrstuden  * All rights reserved.
      9  1.1.1.1.6.2  wrstuden  *
     10  1.1.1.1.6.2  wrstuden  * Redistribution and use in source and binary forms, with or without
     11  1.1.1.1.6.2  wrstuden  * modification, are permitted only as authorized by the OpenLDAP
     12  1.1.1.1.6.2  wrstuden  * Public License.
     13  1.1.1.1.6.2  wrstuden  *
     14  1.1.1.1.6.2  wrstuden  * A copy of this license is available in the file LICENSE in the
     15  1.1.1.1.6.2  wrstuden  * top-level directory of the distribution or, alternatively, at
     16  1.1.1.1.6.2  wrstuden  * <http://www.OpenLDAP.org/license.html>.
     17  1.1.1.1.6.2  wrstuden  */
     18  1.1.1.1.6.2  wrstuden /* Portions Copyright (c) 1996, 1998 by Internet Software Consortium.
     19  1.1.1.1.6.2  wrstuden  *
     20  1.1.1.1.6.2  wrstuden  * Permission to use, copy, modify, and distribute this software for any
     21  1.1.1.1.6.2  wrstuden  * purpose with or without fee is hereby granted, provided that the above
     22  1.1.1.1.6.2  wrstuden  * copyright notice and this permission notice appear in all copies.
     23  1.1.1.1.6.2  wrstuden  *
     24  1.1.1.1.6.2  wrstuden  * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS
     25  1.1.1.1.6.2  wrstuden  * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES
     26  1.1.1.1.6.2  wrstuden  * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE
     27  1.1.1.1.6.2  wrstuden  * CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
     28  1.1.1.1.6.2  wrstuden  * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
     29  1.1.1.1.6.2  wrstuden  * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
     30  1.1.1.1.6.2  wrstuden  * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
     31  1.1.1.1.6.2  wrstuden  * SOFTWARE.
     32  1.1.1.1.6.2  wrstuden  */
     33  1.1.1.1.6.2  wrstuden /* This work is based upon Base64 routines (developed by IBM) found
     34  1.1.1.1.6.2  wrstuden  * Berkeley Internet Name Daemon (BIND) as distributed by ISC.  They
     35  1.1.1.1.6.2  wrstuden  * were adapted for inclusion in OpenLDAP Software by Kurt D. Zeilenga.
     36  1.1.1.1.6.2  wrstuden  */
     37  1.1.1.1.6.2  wrstuden 
     38  1.1.1.1.6.2  wrstuden #include "portable.h"
     39  1.1.1.1.6.2  wrstuden 
     40  1.1.1.1.6.2  wrstuden #include <ac/assert.h>
     41  1.1.1.1.6.2  wrstuden #include <ac/stdlib.h>
     42  1.1.1.1.6.2  wrstuden #include <ac/ctype.h>
     43  1.1.1.1.6.2  wrstuden #include <ac/string.h>
     44  1.1.1.1.6.2  wrstuden 
     45  1.1.1.1.6.2  wrstuden /* include socket.h to get sys/types.h and/or winsock2.h */
     46  1.1.1.1.6.2  wrstuden #include <ac/socket.h>
     47  1.1.1.1.6.2  wrstuden 
     48  1.1.1.1.6.2  wrstuden #include "lutil.h"
     49  1.1.1.1.6.2  wrstuden 
     50  1.1.1.1.6.2  wrstuden static const char Base64[] =
     51  1.1.1.1.6.2  wrstuden 	"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
     52  1.1.1.1.6.2  wrstuden static const char Pad64 = '=';
     53  1.1.1.1.6.2  wrstuden 
     54  1.1.1.1.6.2  wrstuden /* (From RFC1521 and draft-ietf-dnssec-secext-03.txt)
     55  1.1.1.1.6.2  wrstuden    The following encoding technique is taken from RFC 1521 by Borenstein
     56  1.1.1.1.6.2  wrstuden    and Freed.  It is reproduced here in a slightly edited form for
     57  1.1.1.1.6.2  wrstuden    convenience.
     58  1.1.1.1.6.2  wrstuden 
     59  1.1.1.1.6.2  wrstuden    A 65-character subset of US-ASCII is used, enabling 6 bits to be
     60  1.1.1.1.6.2  wrstuden    represented per printable character. (The extra 65th character, "=",
     61  1.1.1.1.6.2  wrstuden    is used to signify a special processing function.)
     62  1.1.1.1.6.2  wrstuden 
     63  1.1.1.1.6.2  wrstuden    The encoding process represents 24-bit groups of input bits as output
     64  1.1.1.1.6.2  wrstuden    strings of 4 encoded characters. Proceeding from left to right, a
     65  1.1.1.1.6.2  wrstuden    24-bit input group is formed by concatenating 3 8-bit input groups.
     66  1.1.1.1.6.2  wrstuden    These 24 bits are then treated as 4 concatenated 6-bit groups, each
     67  1.1.1.1.6.2  wrstuden    of which is translated into a single digit in the base64 alphabet.
     68  1.1.1.1.6.2  wrstuden 
     69  1.1.1.1.6.2  wrstuden    Each 6-bit group is used as an index into an array of 64 printable
     70  1.1.1.1.6.2  wrstuden    characters. The character referenced by the index is placed in the
     71  1.1.1.1.6.2  wrstuden    output string.
     72  1.1.1.1.6.2  wrstuden 
     73  1.1.1.1.6.2  wrstuden                          Table 1: The Base64 Alphabet
     74  1.1.1.1.6.2  wrstuden 
     75  1.1.1.1.6.2  wrstuden       Value Encoding  Value Encoding  Value Encoding  Value Encoding
     76  1.1.1.1.6.2  wrstuden           0 A            17 R            34 i            51 z
     77  1.1.1.1.6.2  wrstuden           1 B            18 S            35 j            52 0
     78  1.1.1.1.6.2  wrstuden           2 C            19 T            36 k            53 1
     79  1.1.1.1.6.2  wrstuden           3 D            20 U            37 l            54 2
     80  1.1.1.1.6.2  wrstuden           4 E            21 V            38 m            55 3
     81  1.1.1.1.6.2  wrstuden           5 F            22 W            39 n            56 4
     82  1.1.1.1.6.2  wrstuden           6 G            23 X            40 o            57 5
     83  1.1.1.1.6.2  wrstuden           7 H            24 Y            41 p            58 6
     84  1.1.1.1.6.2  wrstuden           8 I            25 Z            42 q            59 7
     85  1.1.1.1.6.2  wrstuden           9 J            26 a            43 r            60 8
     86  1.1.1.1.6.2  wrstuden          10 K            27 b            44 s            61 9
     87  1.1.1.1.6.2  wrstuden          11 L            28 c            45 t            62 +
     88  1.1.1.1.6.2  wrstuden          12 M            29 d            46 u            63 /
     89  1.1.1.1.6.2  wrstuden          13 N            30 e            47 v
     90  1.1.1.1.6.2  wrstuden          14 O            31 f            48 w         (pad) =
     91  1.1.1.1.6.2  wrstuden          15 P            32 g            49 x
     92  1.1.1.1.6.2  wrstuden          16 Q            33 h            50 y
     93  1.1.1.1.6.2  wrstuden 
     94  1.1.1.1.6.2  wrstuden    Special processing is performed if fewer than 24 bits are available
     95  1.1.1.1.6.2  wrstuden    at the end of the data being encoded.  A full encoding quantum is
     96  1.1.1.1.6.2  wrstuden    always completed at the end of a quantity.  When fewer than 24 input
     97  1.1.1.1.6.2  wrstuden    bits are available in an input group, zero bits are added (on the
     98  1.1.1.1.6.2  wrstuden    right) to form an integral number of 6-bit groups.  Padding at the
     99  1.1.1.1.6.2  wrstuden    end of the data is performed using the '=' character.
    100  1.1.1.1.6.2  wrstuden 
    101  1.1.1.1.6.2  wrstuden    Since all base64 input is an integral number of octets, only the
    102  1.1.1.1.6.2  wrstuden          -------------------------------------------------
    103  1.1.1.1.6.2  wrstuden    following cases can arise:
    104  1.1.1.1.6.2  wrstuden 
    105  1.1.1.1.6.2  wrstuden        (1) the final quantum of encoding input is an integral
    106  1.1.1.1.6.2  wrstuden            multiple of 24 bits; here, the final unit of encoded
    107  1.1.1.1.6.2  wrstuden 	   output will be an integral multiple of 4 characters
    108  1.1.1.1.6.2  wrstuden 	   with no "=" padding,
    109  1.1.1.1.6.2  wrstuden        (2) the final quantum of encoding input is exactly 8 bits;
    110  1.1.1.1.6.2  wrstuden            here, the final unit of encoded output will be two
    111  1.1.1.1.6.2  wrstuden 	   characters followed by two "=" padding characters, or
    112  1.1.1.1.6.2  wrstuden        (3) the final quantum of encoding input is exactly 16 bits;
    113  1.1.1.1.6.2  wrstuden            here, the final unit of encoded output will be three
    114  1.1.1.1.6.2  wrstuden 	   characters followed by one "=" padding character.
    115  1.1.1.1.6.2  wrstuden    */
    116  1.1.1.1.6.2  wrstuden 
    117  1.1.1.1.6.2  wrstuden int
    118  1.1.1.1.6.2  wrstuden lutil_b64_ntop(
    119  1.1.1.1.6.2  wrstuden 	u_char const *src,
    120  1.1.1.1.6.2  wrstuden 	size_t srclength,
    121  1.1.1.1.6.2  wrstuden 	char *target,
    122  1.1.1.1.6.2  wrstuden 	size_t targsize)
    123  1.1.1.1.6.2  wrstuden {
    124  1.1.1.1.6.2  wrstuden 	size_t datalength = 0;
    125  1.1.1.1.6.2  wrstuden 	u_char input[3];
    126  1.1.1.1.6.2  wrstuden 	u_char output[4];
    127  1.1.1.1.6.2  wrstuden 	size_t i;
    128  1.1.1.1.6.2  wrstuden 
    129  1.1.1.1.6.2  wrstuden 	while (2 < srclength) {
    130  1.1.1.1.6.2  wrstuden 		input[0] = *src++;
    131  1.1.1.1.6.2  wrstuden 		input[1] = *src++;
    132  1.1.1.1.6.2  wrstuden 		input[2] = *src++;
    133  1.1.1.1.6.2  wrstuden 		srclength -= 3;
    134  1.1.1.1.6.2  wrstuden 
    135  1.1.1.1.6.2  wrstuden 		output[0] = input[0] >> 2;
    136  1.1.1.1.6.2  wrstuden 		output[1] = ((input[0] & 0x03) << 4) + (input[1] >> 4);
    137  1.1.1.1.6.2  wrstuden 		output[2] = ((input[1] & 0x0f) << 2) + (input[2] >> 6);
    138  1.1.1.1.6.2  wrstuden 		output[3] = input[2] & 0x3f;
    139  1.1.1.1.6.2  wrstuden 		assert(output[0] < 64);
    140  1.1.1.1.6.2  wrstuden 		assert(output[1] < 64);
    141  1.1.1.1.6.2  wrstuden 		assert(output[2] < 64);
    142  1.1.1.1.6.2  wrstuden 		assert(output[3] < 64);
    143  1.1.1.1.6.2  wrstuden 
    144  1.1.1.1.6.2  wrstuden 		if (datalength + 4 > targsize)
    145  1.1.1.1.6.2  wrstuden 			return (-1);
    146  1.1.1.1.6.2  wrstuden 		target[datalength++] = Base64[output[0]];
    147  1.1.1.1.6.2  wrstuden 		target[datalength++] = Base64[output[1]];
    148  1.1.1.1.6.2  wrstuden 		target[datalength++] = Base64[output[2]];
    149  1.1.1.1.6.2  wrstuden 		target[datalength++] = Base64[output[3]];
    150  1.1.1.1.6.2  wrstuden 	}
    151  1.1.1.1.6.2  wrstuden 
    152  1.1.1.1.6.2  wrstuden 	/* Now we worry about padding. */
    153  1.1.1.1.6.2  wrstuden 	if (0 != srclength) {
    154  1.1.1.1.6.2  wrstuden 		/* Get what's left. */
    155  1.1.1.1.6.2  wrstuden 		input[0] = input[1] = input[2] = '\0';
    156  1.1.1.1.6.2  wrstuden 		for (i = 0; i < srclength; i++)
    157  1.1.1.1.6.2  wrstuden 			input[i] = *src++;
    158  1.1.1.1.6.2  wrstuden 
    159  1.1.1.1.6.2  wrstuden 		output[0] = input[0] >> 2;
    160  1.1.1.1.6.2  wrstuden 		output[1] = ((input[0] & 0x03) << 4) + (input[1] >> 4);
    161  1.1.1.1.6.2  wrstuden 		output[2] = ((input[1] & 0x0f) << 2) + (input[2] >> 6);
    162  1.1.1.1.6.2  wrstuden 		assert(output[0] < 64);
    163  1.1.1.1.6.2  wrstuden 		assert(output[1] < 64);
    164  1.1.1.1.6.2  wrstuden 		assert(output[2] < 64);
    165  1.1.1.1.6.2  wrstuden 
    166  1.1.1.1.6.2  wrstuden 		if (datalength + 4 > targsize)
    167  1.1.1.1.6.2  wrstuden 			return (-1);
    168  1.1.1.1.6.2  wrstuden 		target[datalength++] = Base64[output[0]];
    169  1.1.1.1.6.2  wrstuden 		target[datalength++] = Base64[output[1]];
    170  1.1.1.1.6.2  wrstuden 		if (srclength == 1)
    171  1.1.1.1.6.2  wrstuden 			target[datalength++] = Pad64;
    172  1.1.1.1.6.2  wrstuden 		else
    173  1.1.1.1.6.2  wrstuden 			target[datalength++] = Base64[output[2]];
    174  1.1.1.1.6.2  wrstuden 		target[datalength++] = Pad64;
    175  1.1.1.1.6.2  wrstuden 	}
    176  1.1.1.1.6.2  wrstuden 	if (datalength >= targsize)
    177  1.1.1.1.6.2  wrstuden 		return (-1);
    178  1.1.1.1.6.2  wrstuden 	target[datalength] = '\0';	/* Returned value doesn't count \0. */
    179  1.1.1.1.6.2  wrstuden 	return (datalength);
    180  1.1.1.1.6.2  wrstuden }
    181  1.1.1.1.6.2  wrstuden 
    182  1.1.1.1.6.2  wrstuden /* skips all whitespace anywhere.
    183  1.1.1.1.6.2  wrstuden    converts characters, four at a time, starting at (or after)
    184  1.1.1.1.6.2  wrstuden    src from base - 64 numbers into three 8 bit bytes in the target area.
    185  1.1.1.1.6.2  wrstuden    it returns the number of data bytes stored at the target, or -1 on error.
    186  1.1.1.1.6.2  wrstuden  */
    187  1.1.1.1.6.2  wrstuden 
    188  1.1.1.1.6.2  wrstuden int
    189  1.1.1.1.6.2  wrstuden lutil_b64_pton(
    190  1.1.1.1.6.2  wrstuden 	char const *src,
    191  1.1.1.1.6.2  wrstuden 	u_char *target,
    192  1.1.1.1.6.2  wrstuden 	size_t targsize)
    193  1.1.1.1.6.2  wrstuden {
    194  1.1.1.1.6.2  wrstuden 	int tarindex, state, ch;
    195  1.1.1.1.6.2  wrstuden 	char *pos;
    196  1.1.1.1.6.2  wrstuden 
    197  1.1.1.1.6.2  wrstuden 	state = 0;
    198  1.1.1.1.6.2  wrstuden 	tarindex = 0;
    199  1.1.1.1.6.2  wrstuden 
    200  1.1.1.1.6.2  wrstuden 	while ((ch = *src++) != '\0') {
    201  1.1.1.1.6.2  wrstuden 		if (isascii(ch) && isspace(ch))	/* Skip whitespace anywhere. */
    202  1.1.1.1.6.2  wrstuden 			continue;
    203  1.1.1.1.6.2  wrstuden 
    204  1.1.1.1.6.2  wrstuden 		if (ch == Pad64)
    205  1.1.1.1.6.2  wrstuden 			break;
    206  1.1.1.1.6.2  wrstuden 
    207  1.1.1.1.6.2  wrstuden 		pos = strchr(Base64, ch);
    208  1.1.1.1.6.2  wrstuden 		if (pos == 0) 		/* A non-base64 character. */
    209  1.1.1.1.6.2  wrstuden 			return (-1);
    210  1.1.1.1.6.2  wrstuden 
    211  1.1.1.1.6.2  wrstuden 		switch (state) {
    212  1.1.1.1.6.2  wrstuden 		case 0:
    213  1.1.1.1.6.2  wrstuden 			if (target) {
    214  1.1.1.1.6.2  wrstuden 				if ((size_t)tarindex >= targsize)
    215  1.1.1.1.6.2  wrstuden 					return (-1);
    216  1.1.1.1.6.2  wrstuden 				target[tarindex] = (pos - Base64) << 2;
    217  1.1.1.1.6.2  wrstuden 			}
    218  1.1.1.1.6.2  wrstuden 			state = 1;
    219  1.1.1.1.6.2  wrstuden 			break;
    220  1.1.1.1.6.2  wrstuden 		case 1:
    221  1.1.1.1.6.2  wrstuden 			if (target) {
    222  1.1.1.1.6.2  wrstuden 				if ((size_t)tarindex + 1 >= targsize)
    223  1.1.1.1.6.2  wrstuden 					return (-1);
    224  1.1.1.1.6.2  wrstuden 				target[tarindex]   |=  (pos - Base64) >> 4;
    225  1.1.1.1.6.2  wrstuden 				target[tarindex+1]  = ((pos - Base64) & 0x0f)
    226  1.1.1.1.6.2  wrstuden 							<< 4 ;
    227  1.1.1.1.6.2  wrstuden 			}
    228  1.1.1.1.6.2  wrstuden 			tarindex++;
    229  1.1.1.1.6.2  wrstuden 			state = 2;
    230  1.1.1.1.6.2  wrstuden 			break;
    231  1.1.1.1.6.2  wrstuden 		case 2:
    232  1.1.1.1.6.2  wrstuden 			if (target) {
    233  1.1.1.1.6.2  wrstuden 				if ((size_t)tarindex + 1 >= targsize)
    234  1.1.1.1.6.2  wrstuden 					return (-1);
    235  1.1.1.1.6.2  wrstuden 				target[tarindex]   |=  (pos - Base64) >> 2;
    236  1.1.1.1.6.2  wrstuden 				target[tarindex+1]  = ((pos - Base64) & 0x03)
    237  1.1.1.1.6.2  wrstuden 							<< 6;
    238  1.1.1.1.6.2  wrstuden 			}
    239  1.1.1.1.6.2  wrstuden 			tarindex++;
    240  1.1.1.1.6.2  wrstuden 			state = 3;
    241  1.1.1.1.6.2  wrstuden 			break;
    242  1.1.1.1.6.2  wrstuden 		case 3:
    243  1.1.1.1.6.2  wrstuden 			if (target) {
    244  1.1.1.1.6.2  wrstuden 				if ((size_t)tarindex >= targsize)
    245  1.1.1.1.6.2  wrstuden 					return (-1);
    246  1.1.1.1.6.2  wrstuden 				target[tarindex] |= (pos - Base64);
    247  1.1.1.1.6.2  wrstuden 			}
    248  1.1.1.1.6.2  wrstuden 			tarindex++;
    249  1.1.1.1.6.2  wrstuden 			state = 0;
    250  1.1.1.1.6.2  wrstuden 			break;
    251  1.1.1.1.6.2  wrstuden 		default:
    252  1.1.1.1.6.2  wrstuden 			abort();
    253  1.1.1.1.6.2  wrstuden 		}
    254  1.1.1.1.6.2  wrstuden 	}
    255  1.1.1.1.6.2  wrstuden 
    256  1.1.1.1.6.2  wrstuden 	/*
    257  1.1.1.1.6.2  wrstuden 	 * We are done decoding Base-64 chars.  Let's see if we ended
    258  1.1.1.1.6.2  wrstuden 	 * on a byte boundary, and/or with erroneous trailing characters.
    259  1.1.1.1.6.2  wrstuden 	 */
    260  1.1.1.1.6.2  wrstuden 
    261  1.1.1.1.6.2  wrstuden 	if (ch == Pad64) {		/* We got a pad char. */
    262  1.1.1.1.6.2  wrstuden 		ch = *src++;		/* Skip it, get next. */
    263  1.1.1.1.6.2  wrstuden 		switch (state) {
    264  1.1.1.1.6.2  wrstuden 		case 0:		/* Invalid = in first position */
    265  1.1.1.1.6.2  wrstuden 		case 1:		/* Invalid = in second position */
    266  1.1.1.1.6.2  wrstuden 			return (-1);
    267  1.1.1.1.6.2  wrstuden 
    268  1.1.1.1.6.2  wrstuden 		case 2:		/* Valid, means one byte of info */
    269  1.1.1.1.6.2  wrstuden 			/* Skip any number of spaces. */
    270  1.1.1.1.6.2  wrstuden 			for ((void)NULL; ch != '\0'; ch = *src++)
    271  1.1.1.1.6.2  wrstuden 				if (! (isascii(ch) && isspace(ch)))
    272  1.1.1.1.6.2  wrstuden 					break;
    273  1.1.1.1.6.2  wrstuden 			/* Make sure there is another trailing = sign. */
    274  1.1.1.1.6.2  wrstuden 			if (ch != Pad64)
    275  1.1.1.1.6.2  wrstuden 				return (-1);
    276  1.1.1.1.6.2  wrstuden 			ch = *src++;		/* Skip the = */
    277  1.1.1.1.6.2  wrstuden 			/* Fall through to "single trailing =" case. */
    278  1.1.1.1.6.2  wrstuden 			/* FALLTHROUGH */
    279  1.1.1.1.6.2  wrstuden 
    280  1.1.1.1.6.2  wrstuden 		case 3:		/* Valid, means two bytes of info */
    281  1.1.1.1.6.2  wrstuden 			/*
    282  1.1.1.1.6.2  wrstuden 			 * We know this char is an =.  Is there anything but
    283  1.1.1.1.6.2  wrstuden 			 * whitespace after it?
    284  1.1.1.1.6.2  wrstuden 			 */
    285  1.1.1.1.6.2  wrstuden 			for ((void)NULL; ch != '\0'; ch = *src++)
    286  1.1.1.1.6.2  wrstuden 				if (! (isascii(ch) && isspace(ch)))
    287  1.1.1.1.6.2  wrstuden 					return (-1);
    288  1.1.1.1.6.2  wrstuden 
    289  1.1.1.1.6.2  wrstuden 			/*
    290  1.1.1.1.6.2  wrstuden 			 * Now make sure for cases 2 and 3 that the "extra"
    291  1.1.1.1.6.2  wrstuden 			 * bits that slopped past the last full byte were
    292  1.1.1.1.6.2  wrstuden 			 * zeros.  If we don't check them, they become a
    293  1.1.1.1.6.2  wrstuden 			 * subliminal channel.
    294  1.1.1.1.6.2  wrstuden 			 */
    295  1.1.1.1.6.2  wrstuden 			if (target && target[tarindex] != 0)
    296  1.1.1.1.6.2  wrstuden 				return (-1);
    297  1.1.1.1.6.2  wrstuden 		}
    298  1.1.1.1.6.2  wrstuden 	} else {
    299  1.1.1.1.6.2  wrstuden 		/*
    300  1.1.1.1.6.2  wrstuden 		 * We ended by seeing the end of the string.  Make sure we
    301  1.1.1.1.6.2  wrstuden 		 * have no partial bytes lying around.
    302  1.1.1.1.6.2  wrstuden 		 */
    303  1.1.1.1.6.2  wrstuden 		if (state != 0)
    304  1.1.1.1.6.2  wrstuden 			return (-1);
    305  1.1.1.1.6.2  wrstuden 	}
    306  1.1.1.1.6.2  wrstuden 
    307  1.1.1.1.6.2  wrstuden 	return (tarindex);
    308  1.1.1.1.6.2  wrstuden }
    309