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