| 1 |  |  | /* $OpenBSD: encode.c,v 1.24 2016/05/04 15:05:13 tedu Exp $ */ | 
    
    | 2 |  |  | /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) | 
    
    | 3 |  |  |  * All rights reserved. | 
    
    | 4 |  |  |  * | 
    
    | 5 |  |  |  * This package is an SSL implementation written | 
    
    | 6 |  |  |  * by Eric Young (eay@cryptsoft.com). | 
    
    | 7 |  |  |  * The implementation was written so as to conform with Netscapes SSL. | 
    
    | 8 |  |  |  * | 
    
    | 9 |  |  |  * This library is free for commercial and non-commercial use as long as | 
    
    | 10 |  |  |  * the following conditions are aheared to.  The following conditions | 
    
    | 11 |  |  |  * apply to all code found in this distribution, be it the RC4, RSA, | 
    
    | 12 |  |  |  * lhash, DES, etc., code; not just the SSL code.  The SSL documentation | 
    
    | 13 |  |  |  * included with this distribution is covered by the same copyright terms | 
    
    | 14 |  |  |  * except that the holder is Tim Hudson (tjh@cryptsoft.com). | 
    
    | 15 |  |  |  * | 
    
    | 16 |  |  |  * Copyright remains Eric Young's, and as such any Copyright notices in | 
    
    | 17 |  |  |  * the code are not to be removed. | 
    
    | 18 |  |  |  * If this package is used in a product, Eric Young should be given attribution | 
    
    | 19 |  |  |  * as the author of the parts of the library used. | 
    
    | 20 |  |  |  * This can be in the form of a textual message at program startup or | 
    
    | 21 |  |  |  * in documentation (online or textual) provided with the package. | 
    
    | 22 |  |  |  * | 
    
    | 23 |  |  |  * Redistribution and use in source and binary forms, with or without | 
    
    | 24 |  |  |  * modification, are permitted provided that the following conditions | 
    
    | 25 |  |  |  * are met: | 
    
    | 26 |  |  |  * 1. Redistributions of source code must retain the copyright | 
    
    | 27 |  |  |  *    notice, this list of conditions and the following disclaimer. | 
    
    | 28 |  |  |  * 2. Redistributions in binary form must reproduce the above copyright | 
    
    | 29 |  |  |  *    notice, this list of conditions and the following disclaimer in the | 
    
    | 30 |  |  |  *    documentation and/or other materials provided with the distribution. | 
    
    | 31 |  |  |  * 3. All advertising materials mentioning features or use of this software | 
    
    | 32 |  |  |  *    must display the following acknowledgement: | 
    
    | 33 |  |  |  *    "This product includes cryptographic software written by | 
    
    | 34 |  |  |  *     Eric Young (eay@cryptsoft.com)" | 
    
    | 35 |  |  |  *    The word 'cryptographic' can be left out if the rouines from the library | 
    
    | 36 |  |  |  *    being used are not cryptographic related :-). | 
    
    | 37 |  |  |  * 4. If you include any Windows specific code (or a derivative thereof) from | 
    
    | 38 |  |  |  *    the apps directory (application code) you must include an acknowledgement: | 
    
    | 39 |  |  |  *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" | 
    
    | 40 |  |  |  * | 
    
    | 41 |  |  |  * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND | 
    
    | 42 |  |  |  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | 
    
    | 43 |  |  |  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | 
    
    | 44 |  |  |  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE | 
    
    | 45 |  |  |  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | 
    
    | 46 |  |  |  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | 
    
    | 47 |  |  |  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | 
    
    | 48 |  |  |  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | 
    
    | 49 |  |  |  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | 
    
    | 50 |  |  |  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | 
    
    | 51 |  |  |  * SUCH DAMAGE. | 
    
    | 52 |  |  |  * | 
    
    | 53 |  |  |  * The licence and distribution terms for any publically available version or | 
    
    | 54 |  |  |  * derivative of this code cannot be changed.  i.e. this code cannot simply be | 
    
    | 55 |  |  |  * copied and put under another distribution licence | 
    
    | 56 |  |  |  * [including the GNU Public Licence.] | 
    
    | 57 |  |  |  */ | 
    
    | 58 |  |  |  | 
    
    | 59 |  |  | #include <limits.h> | 
    
    | 60 |  |  | #include <stdio.h> | 
    
    | 61 |  |  | #include <string.h> | 
    
    | 62 |  |  |  | 
    
    | 63 |  |  | #include <openssl/evp.h> | 
    
    | 64 |  |  |  | 
    
    | 65 |  |  | #define conv_bin2ascii(a)	(data_bin2ascii[(a)&0x3f]) | 
    
    | 66 |  |  | #define conv_ascii2bin(a)	(data_ascii2bin[(a)&0x7f]) | 
    
    | 67 |  |  |  | 
    
    | 68 |  |  | /* 64 char lines | 
    
    | 69 |  |  |  * pad input with 0 | 
    
    | 70 |  |  |  * left over chars are set to = | 
    
    | 71 |  |  |  * 1 byte  => xx== | 
    
    | 72 |  |  |  * 2 bytes => xxx= | 
    
    | 73 |  |  |  * 3 bytes => xxxx | 
    
    | 74 |  |  |  */ | 
    
    | 75 |  |  | #define BIN_PER_LINE    (64/4*3) | 
    
    | 76 |  |  | #define CHUNKS_PER_LINE (64/4) | 
    
    | 77 |  |  | #define CHAR_PER_LINE   (64+1) | 
    
    | 78 |  |  |  | 
    
    | 79 |  |  | static const unsigned char data_bin2ascii[65] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ\ | 
    
    | 80 |  |  | abcdefghijklmnopqrstuvwxyz0123456789+/"; | 
    
    | 81 |  |  |  | 
    
    | 82 |  |  | /* 0xF0 is a EOLN | 
    
    | 83 |  |  |  * 0xF1 is ignore but next needs to be 0xF0 (for \r\n processing). | 
    
    | 84 |  |  |  * 0xF2 is EOF | 
    
    | 85 |  |  |  * 0xE0 is ignore at start of line. | 
    
    | 86 |  |  |  * 0xFF is error | 
    
    | 87 |  |  |  */ | 
    
    | 88 |  |  |  | 
    
    | 89 |  |  | #define B64_EOLN		0xF0 | 
    
    | 90 |  |  | #define B64_CR			0xF1 | 
    
    | 91 |  |  | #define B64_EOF			0xF2 | 
    
    | 92 |  |  | #define B64_WS			0xE0 | 
    
    | 93 |  |  | #define B64_ERROR       	0xFF | 
    
    | 94 |  |  | #define B64_NOT_BASE64(a)	(((a)|0x13) == 0xF3) | 
    
    | 95 |  |  |  | 
    
    | 96 |  |  | static const unsigned char data_ascii2bin[128] = { | 
    
    | 97 |  |  | 	0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, | 
    
    | 98 |  |  | 	0xFF, 0xE0, 0xF0, 0xFF, 0xFF, 0xF1, 0xFF, 0xFF, | 
    
    | 99 |  |  | 	0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, | 
    
    | 100 |  |  | 	0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, | 
    
    | 101 |  |  | 	0xE0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, | 
    
    | 102 |  |  | 	0xFF, 0xFF, 0xFF, 0x3E, 0xFF, 0xF2, 0xFF, 0x3F, | 
    
    | 103 |  |  | 	0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A, 0x3B, | 
    
    | 104 |  |  | 	0x3C, 0x3D, 0xFF, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, | 
    
    | 105 |  |  | 	0xFF, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, | 
    
    | 106 |  |  | 	0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, | 
    
    | 107 |  |  | 	0x0F, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, | 
    
    | 108 |  |  | 	0x17, 0x18, 0x19, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, | 
    
    | 109 |  |  | 	0xFF, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, 0x20, | 
    
    | 110 |  |  | 	0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, | 
    
    | 111 |  |  | 	0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F, 0x30, | 
    
    | 112 |  |  | 	0x31, 0x32, 0x33, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, | 
    
    | 113 |  |  | }; | 
    
    | 114 |  |  |  | 
    
    | 115 |  |  | void | 
    
    | 116 |  |  | EVP_EncodeInit(EVP_ENCODE_CTX *ctx) | 
    
    | 117 |  |  | { | 
    
    | 118 |  | 2792 | 	ctx->length = 48; | 
    
    | 119 |  | 1396 | 	ctx->num = 0; | 
    
    | 120 |  | 1396 | 	ctx->line_num = 0; | 
    
    | 121 |  | 1396 | } | 
    
    | 122 |  |  |  | 
    
    | 123 |  |  | void | 
    
    | 124 |  |  | EVP_EncodeUpdate(EVP_ENCODE_CTX *ctx, unsigned char *out, int *outl, | 
    
    | 125 |  |  |     const unsigned char *in, int inl) | 
    
    | 126 |  |  | { | 
    
    | 127 |  |  | 	int i, j; | 
    
    | 128 |  |  | 	size_t total = 0; | 
    
    | 129 |  |  |  | 
    
    | 130 |  | 4928 | 	*outl = 0; | 
    
    | 131 | ✗✓ | 2464 | 	if (inl == 0) | 
    
    | 132 |  |  | 		return; | 
    
    | 133 | ✗✓ | 2464 | 	OPENSSL_assert(ctx->length <= (int)sizeof(ctx->enc_data)); | 
    
    | 134 | ✓✓ | 2464 | 	if (ctx->length - ctx->num > inl) { | 
    
    | 135 |  | 700 | 		memcpy(&(ctx->enc_data[ctx->num]), in, inl); | 
    
    | 136 |  | 700 | 		ctx->num += inl; | 
    
    | 137 |  | 700 | 		return; | 
    
    | 138 |  |  | 	} | 
    
    | 139 | ✓✓ | 1764 | 	if (ctx->num != 0) { | 
    
    | 140 |  |  | 		i = ctx->length - ctx->num; | 
    
    | 141 |  | 804 | 		memcpy(&(ctx->enc_data[ctx->num]), in, i); | 
    
    | 142 |  | 804 | 		in += i; | 
    
    | 143 |  | 804 | 		inl -= i; | 
    
    | 144 |  | 804 | 		j = EVP_EncodeBlock(out, ctx->enc_data, ctx->length); | 
    
    | 145 |  | 804 | 		ctx->num = 0; | 
    
    | 146 |  | 804 | 		out += j; | 
    
    | 147 |  | 804 | 		*(out++) = '\n'; | 
    
    | 148 |  | 804 | 		*out = '\0'; | 
    
    | 149 |  | 804 | 		total = j + 1; | 
    
    | 150 |  | 804 | 	} | 
    
    | 151 | ✓✓ | 21710 | 	while (inl >= ctx->length && total <= INT_MAX) { | 
    
    | 152 |  | 9973 | 		j = EVP_EncodeBlock(out, in, ctx->length); | 
    
    | 153 |  | 9973 | 		in += ctx->length; | 
    
    | 154 |  | 9973 | 		inl -= ctx->length; | 
    
    | 155 |  | 9973 | 		out += j; | 
    
    | 156 |  | 9973 | 		*(out++) = '\n'; | 
    
    | 157 |  | 9973 | 		*out = '\0'; | 
    
    | 158 |  | 9973 | 		total += j + 1; | 
    
    | 159 |  |  | 	} | 
    
    | 160 | ✗✓ | 1764 | 	if (total > INT_MAX) { | 
    
    | 161 |  |  | 		/* Too much output data! */ | 
    
    | 162 |  |  | 		*outl = 0; | 
    
    | 163 |  |  | 		return; | 
    
    | 164 |  |  | 	} | 
    
    | 165 | ✓✓ | 1764 | 	if (inl != 0) | 
    
    | 166 |  | 1538 | 		memcpy(&(ctx->enc_data[0]), in, inl); | 
    
    | 167 |  | 1764 | 	ctx->num = inl; | 
    
    | 168 |  | 1764 | 	*outl = total; | 
    
    | 169 |  | 4228 | } | 
    
    | 170 |  |  |  | 
    
    | 171 |  |  | void | 
    
    | 172 |  |  | EVP_EncodeFinal(EVP_ENCODE_CTX *ctx, unsigned char *out, int *outl) | 
    
    | 173 |  |  | { | 
    
    | 174 |  |  | 	unsigned int ret = 0; | 
    
    | 175 |  |  |  | 
    
    | 176 | ✓✓ | 2504 | 	if (ctx->num != 0) { | 
    
    | 177 |  | 1230 | 		ret = EVP_EncodeBlock(out, ctx->enc_data, ctx->num); | 
    
    | 178 |  | 1230 | 		out[ret++] = '\n'; | 
    
    | 179 |  | 1230 | 		out[ret] = '\0'; | 
    
    | 180 |  | 1230 | 		ctx->num = 0; | 
    
    | 181 |  | 1230 | 	} | 
    
    | 182 |  | 1252 | 	*outl = ret; | 
    
    | 183 |  | 1252 | } | 
    
    | 184 |  |  |  | 
    
    | 185 |  |  | int | 
    
    | 186 |  |  | EVP_EncodeBlock(unsigned char *t, const unsigned char *f, int dlen) | 
    
    | 187 |  |  | { | 
    
    | 188 |  |  | 	int i, ret = 0; | 
    
    | 189 |  |  | 	unsigned long l; | 
    
    | 190 |  |  |  | 
    
    | 191 | ✓✓ | 398721 | 	for (i = dlen; i > 0; i -= 3) { | 
    
    | 192 | ✓✓ | 181023 | 		if (i >= 3) { | 
    
    | 193 |  | 179967 | 			l = (((unsigned long)f[0]) << 16L) | | 
    
    | 194 |  | 359934 | 			    (((unsigned long)f[1]) << 8L) | f[2]; | 
    
    | 195 |  | 179967 | 			*(t++) = conv_bin2ascii(l >> 18L); | 
    
    | 196 |  | 179967 | 			*(t++) = conv_bin2ascii(l >> 12L); | 
    
    | 197 |  | 179967 | 			*(t++) = conv_bin2ascii(l >> 6L); | 
    
    | 198 |  | 179967 | 			*(t++) = conv_bin2ascii(l     ); | 
    
    | 199 |  | 179967 | 		} else { | 
    
    | 200 |  |  | 			l = ((unsigned long)f[0]) << 16L; | 
    
    | 201 | ✓✓ | 1056 | 			if (i == 2) | 
    
    | 202 |  | 446 | 				l |= ((unsigned long)f[1] << 8L); | 
    
    | 203 |  |  |  | 
    
    | 204 |  | 1056 | 			*(t++) = conv_bin2ascii(l >> 18L); | 
    
    | 205 |  | 1056 | 			*(t++) = conv_bin2ascii(l >> 12L); | 
    
    | 206 | ✓✓ | 2558 | 			*(t++) = (i == 1) ? '=' : conv_bin2ascii(l >> 6L); | 
    
    | 207 |  | 1056 | 			*(t++) = '='; | 
    
    | 208 |  |  | 		} | 
    
    | 209 |  | 181023 | 		ret += 4; | 
    
    | 210 |  | 181023 | 		f += 3; | 
    
    | 211 |  |  | 	} | 
    
    | 212 |  |  |  | 
    
    | 213 |  | 12225 | 	*t = '\0'; | 
    
    | 214 |  | 12225 | 	return (ret); | 
    
    | 215 |  |  | } | 
    
    | 216 |  |  |  | 
    
    | 217 |  |  | void | 
    
    | 218 |  |  | EVP_DecodeInit(EVP_ENCODE_CTX *ctx) | 
    
    | 219 |  |  | { | 
    
    | 220 |  | 34058 | 	ctx->length = 30; | 
    
    | 221 |  | 17029 | 	ctx->num = 0; | 
    
    | 222 |  | 17029 | 	ctx->line_num = 0; | 
    
    | 223 |  | 17029 | 	ctx->expect_nl = 0; | 
    
    | 224 |  | 17029 | } | 
    
    | 225 |  |  |  | 
    
    | 226 |  |  | /* -1 for error | 
    
    | 227 |  |  |  *  0 for last line | 
    
    | 228 |  |  |  *  1 for full line | 
    
    | 229 |  |  |  */ | 
    
    | 230 |  |  | int | 
    
    | 231 |  |  | EVP_DecodeUpdate(EVP_ENCODE_CTX *ctx, unsigned char *out, int *outl, | 
    
    | 232 |  |  |     const unsigned char *in, int inl) | 
    
    | 233 |  |  | { | 
    
    | 234 |  |  | 	int seof = -1, eof = 0, rv = -1, ret = 0, i, v, tmp, n, ln, exp_nl; | 
    
    | 235 |  |  | 	unsigned char *d; | 
    
    | 236 |  |  |  | 
    
    | 237 |  | 33522 | 	n = ctx->num; | 
    
    | 238 |  | 16761 | 	d = ctx->enc_data; | 
    
    | 239 |  | 16761 | 	ln = ctx->line_num; | 
    
    | 240 |  | 16761 | 	exp_nl = ctx->expect_nl; | 
    
    | 241 |  |  |  | 
    
    | 242 |  |  | 	/* last line of input. */ | 
    
    | 243 | ✓✗✓✓ ✓✓
 | 50179 | 	if ((inl == 0) || ((n == 0) && (conv_ascii2bin(in[0]) == B64_EOF))) { | 
    
    | 244 |  |  | 		rv = 0; | 
    
    | 245 |  | 2 | 		goto end; | 
    
    | 246 |  |  | 	} | 
    
    | 247 |  |  |  | 
    
    | 248 |  |  | 	/* We parse the input data */ | 
    
    | 249 | ✓✓ | 41541710 | 	for (i = 0; i < inl; i++) { | 
    
    | 250 |  |  | 		/* If the current line is > 80 characters, scream alot */ | 
    
    | 251 | ✗✓ | 20764969 | 		if (ln >= 80) { | 
    
    | 252 |  |  | 			rv = -1; | 
    
    | 253 |  |  | 			goto end; | 
    
    | 254 |  |  | 		} | 
    
    | 255 |  |  |  | 
    
    | 256 |  |  | 		/* Get char and put it into the buffer */ | 
    
    | 257 |  | 20764969 | 		tmp= *(in++); | 
    
    | 258 |  | 20764969 | 		v = conv_ascii2bin(tmp); | 
    
    | 259 |  |  | 		/* only save the good data :-) */ | 
    
    | 260 | ✓✓ | 20764969 | 		if (!B64_NOT_BASE64(v)) { | 
    
    | 261 | ✗✓ | 20438428 | 			OPENSSL_assert(n < (int)sizeof(ctx->enc_data)); | 
    
    | 262 |  | 20438428 | 			d[n++] = tmp; | 
    
    | 263 |  | 20438428 | 			ln++; | 
    
    | 264 | ✗✓ | 20764969 | 		} else if (v == B64_ERROR) { | 
    
    | 265 |  |  | 			rv = -1; | 
    
    | 266 |  |  | 			goto end; | 
    
    | 267 |  |  | 		} | 
    
    | 268 |  |  |  | 
    
    | 269 |  |  | 		/* There should not be base64 data after padding. */ | 
    
    | 270 | ✓✓ | 41529938 | 		if (eof && tmp != '=' && tmp != '\r' && tmp != '\n' && | 
    
    | 271 |  | 20764969 | 		    v != B64_EOF) { | 
    
    | 272 |  |  | 			rv = -1; | 
    
    | 273 |  | 60 | 			goto end; | 
    
    | 274 |  |  | 		} | 
    
    | 275 |  |  |  | 
    
    | 276 |  |  | 		/* have we seen a '=' which is 'definitely' the last | 
    
    | 277 |  |  | 		 * input line.  seof will point to the character that | 
    
    | 278 |  |  | 		 * holds it. and eof will hold how many characters to | 
    
    | 279 |  |  | 		 * chop off. */ | 
    
    | 280 | ✓✓ | 20764909 | 		if (tmp == '=') { | 
    
    | 281 | ✓✓ | 17463 | 			if (seof == -1) | 
    
    | 282 |  | 10895 | 				seof = n; | 
    
    | 283 |  | 17463 | 			eof++; | 
    
    | 284 |  | 17463 | 		} | 
    
    | 285 |  |  |  | 
    
    | 286 |  |  | 		/* There should be no more than two padding markers. */ | 
    
    | 287 | ✓✓ | 20764909 | 		if (eof > 2) { | 
    
    | 288 |  |  | 			rv = -1; | 
    
    | 289 |  | 48 | 			goto end; | 
    
    | 290 |  |  | 		} | 
    
    | 291 |  |  |  | 
    
    | 292 | ✓✓ | 20764861 | 		if (v == B64_CR) { | 
    
    | 293 |  |  | 			ln = 0; | 
    
    | 294 | ✓✓ | 576 | 			if (exp_nl) | 
    
    | 295 |  |  | 				continue; | 
    
    | 296 |  |  | 		} | 
    
    | 297 |  |  |  | 
    
    | 298 |  |  | 		/* eoln */ | 
    
    | 299 | ✓✓ | 20764797 | 		if (v == B64_EOLN) { | 
    
    | 300 |  |  | 			ln = 0; | 
    
    | 301 | ✓✓ | 325961 | 			if (exp_nl) { | 
    
    | 302 |  |  | 				exp_nl = 0; | 
    
    | 303 |  | 310745 | 				continue; | 
    
    | 304 |  |  | 			} | 
    
    | 305 |  |  | 		} | 
    
    | 306 |  |  | 		exp_nl = 0; | 
    
    | 307 |  |  |  | 
    
    | 308 |  |  | 		/* If we are at the end of input and it looks like a | 
    
    | 309 |  |  | 		 * line, process it. */ | 
    
    | 310 | ✓✓✓✓ 
 | 20469310 | 		if (((i + 1) == inl) && (((n&3) == 0) || eof)) { | 
    
    | 311 |  |  | 			v = B64_EOF; | 
    
    | 312 |  |  | 			/* In case things were given us in really small | 
    
    | 313 |  |  | 			   records (so two '=' were given in separate | 
    
    | 314 |  |  | 			   updates), eof may contain the incorrect number | 
    
    | 315 |  |  | 			   of ending bytes to skip, so let's redo the count */ | 
    
    | 316 |  |  | 			eof = 0; | 
    
    | 317 | ✓✓ | 15100 | 			if (d[n-1] == '=') | 
    
    | 318 |  | 9786 | 				eof++; | 
    
    | 319 | ✓✓ | 15100 | 			if (d[n-2] == '=') | 
    
    | 320 |  | 5967 | 				eof++; | 
    
    | 321 |  |  | 			/* There will never be more than two '=' */ | 
    
    | 322 |  |  | 		} | 
    
    | 323 |  |  |  | 
    
    | 324 | ✓✓✓✓ ✓✓
 | 40908104 | 		if ((v == B64_EOF && (n&3) == 0) || (n >= 64)) { | 
    
    | 325 |  |  | 			/* This is needed to work correctly on 64 byte input | 
    
    | 326 |  |  | 			 * lines.  We process the line and then need to | 
    
    | 327 |  |  | 			 * accept the '\n' */ | 
    
    | 328 | ✓✓ | 326790 | 			if ((v != B64_EOF) && (n >= 64)) | 
    
    | 329 |  | 311746 | 				exp_nl = 1; | 
    
    | 330 | ✓✓ | 326790 | 			if (n > 0) { | 
    
    | 331 |  | 326764 | 				v = EVP_DecodeBlock(out, d, n); | 
    
    | 332 |  |  | 				n = 0; | 
    
    | 333 | ✓✓ | 326764 | 				if (v < 0) { | 
    
    | 334 |  |  | 					rv = 0; | 
    
    | 335 |  | 12 | 					goto end; | 
    
    | 336 |  |  | 				} | 
    
    | 337 |  | 326752 | 				ret += (v - eof); | 
    
    | 338 |  | 326752 | 			} else { | 
    
    | 339 |  |  | 				eof = 1; | 
    
    | 340 |  |  | 				v = 0; | 
    
    | 341 |  |  | 			} | 
    
    | 342 |  |  |  | 
    
    | 343 |  |  | 			/* This is the case where we have had a short | 
    
    | 344 |  |  | 			 * but valid input line */ | 
    
    | 345 | ✓✓ | 326778 | 			if ((v < ctx->length) && eof) { | 
    
    | 346 |  |  | 				rv = 0; | 
    
    | 347 |  | 9736 | 				goto end; | 
    
    | 348 |  |  | 			} else | 
    
    | 349 |  | 317042 | 				ctx->length = v; | 
    
    | 350 |  |  |  | 
    
    | 351 | ✓✓ | 317042 | 			if (seof >= 0) { | 
    
    | 352 |  |  | 				rv = 0; | 
    
    | 353 |  | 1017 | 				goto end; | 
    
    | 354 |  |  | 			} | 
    
    | 355 |  | 316025 | 			out += v; | 
    
    | 356 |  | 316025 | 		} | 
    
    | 357 |  |  | 	} | 
    
    | 358 |  | 5886 | 	rv = 1; | 
    
    | 359 |  |  |  | 
    
    | 360 |  |  | end: | 
    
    | 361 |  | 16761 | 	*outl = ret; | 
    
    | 362 |  | 16761 | 	ctx->num = n; | 
    
    | 363 |  | 16761 | 	ctx->line_num = ln; | 
    
    | 364 |  | 16761 | 	ctx->expect_nl = exp_nl; | 
    
    | 365 |  | 16761 | 	return (rv); | 
    
    | 366 |  |  | } | 
    
    | 367 |  |  |  | 
    
    | 368 |  |  | int | 
    
    | 369 |  |  | EVP_DecodeBlock(unsigned char *t, const unsigned char *f, int n) | 
    
    | 370 |  |  | { | 
    
    | 371 |  |  | 	int i, ret = 0, a, b, c, d; | 
    
    | 372 |  |  | 	unsigned long l; | 
    
    | 373 |  |  |  | 
    
    | 374 |  |  | 	/* trim white space from the start of the line. */ | 
    
    | 375 | ✗✓ | 981384 | 	while ((conv_ascii2bin(*f) == B64_WS) && (n > 0)) { | 
    
    | 376 |  |  | 		f++; | 
    
    | 377 |  |  | 		n--; | 
    
    | 378 |  |  | 	} | 
    
    | 379 |  |  |  | 
    
    | 380 |  |  | 	/* strip off stuff at the end of the line | 
    
    | 381 |  |  | 	 * ascii2bin values B64_WS, B64_EOLN, B64_EOLN and B64_EOF */ | 
    
    | 382 | ✓✓✓✓ 
 | 981318 | 	while ((n > 3) && (B64_NOT_BASE64(conv_ascii2bin(f[n - 1])))) | 
    
    | 383 |  | 6 | 		n--; | 
    
    | 384 |  |  |  | 
    
    | 385 | ✓✓ | 327128 | 	if (n % 4 != 0) | 
    
    | 386 |  | 6 | 		return (-1); | 
    
    | 387 |  |  |  | 
    
    | 388 | ✓✓ | 10875528 | 	for (i = 0; i < n; i += 4) { | 
    
    | 389 |  | 5110696 | 		a = conv_ascii2bin(*(f++)); | 
    
    | 390 |  | 5110696 | 		b = conv_ascii2bin(*(f++)); | 
    
    | 391 |  | 5110696 | 		c = conv_ascii2bin(*(f++)); | 
    
    | 392 |  | 5110696 | 		d = conv_ascii2bin(*(f++)); | 
    
    | 393 | ✓✓✓✓ ✓✓
 | 15332034 | 		if ((a & 0x80) || (b & 0x80) || | 
    
    | 394 | ✓✓ | 10221326 | 		    (c & 0x80) || (d & 0x80)) | 
    
    | 395 |  | 54 | 			return (-1); | 
    
    | 396 |  | 10221284 | 		l = ((((unsigned long)a) << 18L) | | 
    
    | 397 |  | 10221284 | 		    (((unsigned long)b) << 12L) | | 
    
    | 398 |  | 10221284 | 		    (((unsigned long)c) << 6L) | | 
    
    | 399 |  | 5110642 | 		    (((unsigned long)d))); | 
    
    | 400 |  | 5110642 | 		*(t++) = (unsigned char)(l >> 16L) & 0xff; | 
    
    | 401 |  | 5110642 | 		*(t++) = (unsigned char)(l >> 8L) & 0xff; | 
    
    | 402 |  | 5110642 | 		*(t++) = (unsigned char)(l) & 0xff; | 
    
    | 403 |  | 5110642 | 		ret += 3; | 
    
    | 404 |  |  | 	} | 
    
    | 405 |  | 327068 | 	return (ret); | 
    
    | 406 |  | 327128 | } | 
    
    | 407 |  |  |  | 
    
    | 408 |  |  | int | 
    
    | 409 |  |  | EVP_DecodeFinal(EVP_ENCODE_CTX *ctx, unsigned char *out, int *outl) | 
    
    | 410 |  |  | { | 
    
    | 411 |  |  | 	int i; | 
    
    | 412 |  |  |  | 
    
    | 413 |  | 31262 | 	*outl = 0; | 
    
    | 414 | ✗✓ | 15631 | 	if (ctx->num != 0) { | 
    
    | 415 |  |  | 		i = EVP_DecodeBlock(out, ctx->enc_data, ctx->num); | 
    
    | 416 |  |  | 		if (i < 0) | 
    
    | 417 |  |  | 			return (-1); | 
    
    | 418 |  |  | 		ctx->num = 0; | 
    
    | 419 |  |  | 		*outl = i; | 
    
    | 420 |  |  | 		return (1); | 
    
    | 421 |  |  | 	} else | 
    
    | 422 |  | 15631 | 		return (1); | 
    
    | 423 |  | 15631 | } |