1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/os/ossrv/ssl/libcrypto/src/crypto/evp/encode.c Fri Jun 15 03:10:57 2012 +0200
1.3 @@ -0,0 +1,481 @@
1.4 +/* crypto/evp/encode.c */
1.5 +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
1.6 + * All rights reserved.
1.7 + *
1.8 + * This package is an SSL implementation written
1.9 + * by Eric Young (eay@cryptsoft.com).
1.10 + * The implementation was written so as to conform with Netscapes SSL.
1.11 + *
1.12 + * This library is free for commercial and non-commercial use as long as
1.13 + * the following conditions are aheared to. The following conditions
1.14 + * apply to all code found in this distribution, be it the RC4, RSA,
1.15 + * lhash, DES, etc., code; not just the SSL code. The SSL documentation
1.16 + * included with this distribution is covered by the same copyright terms
1.17 + * except that the holder is Tim Hudson (tjh@cryptsoft.com).
1.18 + *
1.19 + * Copyright remains Eric Young's, and as such any Copyright notices in
1.20 + * the code are not to be removed.
1.21 + * If this package is used in a product, Eric Young should be given attribution
1.22 + * as the author of the parts of the library used.
1.23 + * This can be in the form of a textual message at program startup or
1.24 + * in documentation (online or textual) provided with the package.
1.25 + *
1.26 + * Redistribution and use in source and binary forms, with or without
1.27 + * modification, are permitted provided that the following conditions
1.28 + * are met:
1.29 + * 1. Redistributions of source code must retain the copyright
1.30 + * notice, this list of conditions and the following disclaimer.
1.31 + * 2. Redistributions in binary form must reproduce the above copyright
1.32 + * notice, this list of conditions and the following disclaimer in the
1.33 + * documentation and/or other materials provided with the distribution.
1.34 + * 3. All advertising materials mentioning features or use of this software
1.35 + * must display the following acknowledgement:
1.36 + * "This product includes cryptographic software written by
1.37 + * Eric Young (eay@cryptsoft.com)"
1.38 + * The word 'cryptographic' can be left out if the rouines from the library
1.39 + * being used are not cryptographic related :-).
1.40 + * 4. If you include any Windows specific code (or a derivative thereof) from
1.41 + * the apps directory (application code) you must include an acknowledgement:
1.42 + * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
1.43 + *
1.44 + * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
1.45 + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
1.46 + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
1.47 + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
1.48 + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
1.49 + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
1.50 + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
1.51 + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
1.52 + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
1.53 + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
1.54 + * SUCH DAMAGE.
1.55 + *
1.56 + * The licence and distribution terms for any publically available version or
1.57 + * derivative of this code cannot be changed. i.e. this code cannot simply be
1.58 + * copied and put under another distribution licence
1.59 + * [including the GNU Public Licence.]
1.60 + */
1.61 + /*
1.62 + © Portions copyright (c) 2006 Nokia Corporation. All rights reserved.
1.63 + */
1.64 +
1.65 +
1.66 +#include <stdio.h>
1.67 +#include "cryptlib.h"
1.68 +#include <openssl/evp.h>
1.69 +#if (defined(SYMBIAN) && (defined(__WINSCW__) || defined(__WINS__)))
1.70 +#include "libcrypto_wsd_macros.h"
1.71 +#include "libcrypto_wsd.h"
1.72 +#endif
1.73 +
1.74 +#ifndef CHARSET_EBCDIC
1.75 +#define conv_bin2ascii(a) (data_bin2ascii[(a)&0x3f])
1.76 +#define conv_ascii2bin(a) (data_ascii2bin[(a)&0x7f])
1.77 +#else
1.78 +/* We assume that PEM encoded files are EBCDIC files
1.79 + * (i.e., printable text files). Convert them here while decoding.
1.80 + * When encoding, output is EBCDIC (text) format again.
1.81 + * (No need for conversion in the conv_bin2ascii macro, as the
1.82 + * underlying textstring data_bin2ascii[] is already EBCDIC)
1.83 + */
1.84 +#define conv_bin2ascii(a) (data_bin2ascii[(a)&0x3f])
1.85 +#define conv_ascii2bin(a) (data_ascii2bin[os_toascii[a]&0x7f])
1.86 +#endif
1.87 +
1.88 +/* 64 char lines
1.89 + * pad input with 0
1.90 + * left over chars are set to =
1.91 + * 1 byte => xx==
1.92 + * 2 bytes => xxx=
1.93 + * 3 bytes => xxxx
1.94 + */
1.95 +#define BIN_PER_LINE (64/4*3)
1.96 +#define CHUNKS_PER_LINE (64/4)
1.97 +#define CHAR_PER_LINE (64+1)
1.98 +
1.99 +#ifndef EMULATOR
1.100 +static unsigned char data_bin2ascii[65]="ABCDEFGHIJKLMNOPQRSTUVWXYZ\
1.101 +abcdefghijklmnopqrstuvwxyz0123456789+/";
1.102 +#else
1.103 +static const unsigned char data_bin2ascii[65]="ABCDEFGHIJKLMNOPQRSTUVWXYZ\
1.104 +abcdefghijklmnopqrstuvwxyz0123456789+/";
1.105 +#endif
1.106 +
1.107 +/* 0xF0 is a EOLN
1.108 + * 0xF1 is ignore but next needs to be 0xF0 (for \r\n processing).
1.109 + * 0xF2 is EOF
1.110 + * 0xE0 is ignore at start of line.
1.111 + * 0xFF is error
1.112 + */
1.113 +
1.114 +#define B64_EOLN 0xF0
1.115 +#define B64_CR 0xF1
1.116 +#define B64_EOF 0xF2
1.117 +#define B64_WS 0xE0
1.118 +#define B64_ERROR 0xFF
1.119 +#define B64_NOT_BASE64(a) (((a)|0x13) == 0xF3)
1.120 +
1.121 +#ifndef EMULATOR
1.122 +static unsigned char data_ascii2bin[128]={
1.123 + 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
1.124 + 0xFF,0xE0,0xF0,0xFF,0xFF,0xF1,0xFF,0xFF,
1.125 + 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
1.126 + 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
1.127 + 0xE0,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
1.128 + 0xFF,0xFF,0xFF,0x3E,0xFF,0xF2,0xFF,0x3F,
1.129 + 0x34,0x35,0x36,0x37,0x38,0x39,0x3A,0x3B,
1.130 + 0x3C,0x3D,0xFF,0xFF,0xFF,0x00,0xFF,0xFF,
1.131 + 0xFF,0x00,0x01,0x02,0x03,0x04,0x05,0x06,
1.132 + 0x07,0x08,0x09,0x0A,0x0B,0x0C,0x0D,0x0E,
1.133 + 0x0F,0x10,0x11,0x12,0x13,0x14,0x15,0x16,
1.134 + 0x17,0x18,0x19,0xFF,0xFF,0xFF,0xFF,0xFF,
1.135 + 0xFF,0x1A,0x1B,0x1C,0x1D,0x1E,0x1F,0x20,
1.136 + 0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,
1.137 + 0x29,0x2A,0x2B,0x2C,0x2D,0x2E,0x2F,0x30,
1.138 + 0x31,0x32,0x33,0xFF,0xFF,0xFF,0xFF,0xFF,
1.139 + };
1.140 +
1.141 +#else
1.142 +static const unsigned char data_ascii2bin[128]={
1.143 + 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
1.144 + 0xFF,0xE0,0xF0,0xFF,0xFF,0xF1,0xFF,0xFF,
1.145 + 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
1.146 + 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
1.147 + 0xE0,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,
1.148 + 0xFF,0xFF,0xFF,0x3E,0xFF,0xF2,0xFF,0x3F,
1.149 + 0x34,0x35,0x36,0x37,0x38,0x39,0x3A,0x3B,
1.150 + 0x3C,0x3D,0xFF,0xFF,0xFF,0x00,0xFF,0xFF,
1.151 + 0xFF,0x00,0x01,0x02,0x03,0x04,0x05,0x06,
1.152 + 0x07,0x08,0x09,0x0A,0x0B,0x0C,0x0D,0x0E,
1.153 + 0x0F,0x10,0x11,0x12,0x13,0x14,0x15,0x16,
1.154 + 0x17,0x18,0x19,0xFF,0xFF,0xFF,0xFF,0xFF,
1.155 + 0xFF,0x1A,0x1B,0x1C,0x1D,0x1E,0x1F,0x20,
1.156 + 0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,
1.157 + 0x29,0x2A,0x2B,0x2C,0x2D,0x2E,0x2F,0x30,
1.158 + 0x31,0x32,0x33,0xFF,0xFF,0xFF,0xFF,0xFF,
1.159 + };
1.160 +#endif
1.161 +
1.162 +EXPORT_C void EVP_EncodeInit(EVP_ENCODE_CTX *ctx)
1.163 + {
1.164 + ctx->length=48;
1.165 + ctx->num=0;
1.166 + ctx->line_num=0;
1.167 + }
1.168 +
1.169 +EXPORT_C void EVP_EncodeUpdate(EVP_ENCODE_CTX *ctx, unsigned char *out, int *outl,
1.170 + const unsigned char *in, int inl)
1.171 + {
1.172 + int i,j;
1.173 + unsigned int total=0;
1.174 +
1.175 + *outl=0;
1.176 + if (inl == 0) return;
1.177 + OPENSSL_assert(ctx->length <= (int)sizeof(ctx->enc_data));
1.178 + if ((ctx->num+inl) < ctx->length)
1.179 + {
1.180 + memcpy(&(ctx->enc_data[ctx->num]),in,inl);
1.181 + ctx->num+=inl;
1.182 + return;
1.183 + }
1.184 + if (ctx->num != 0)
1.185 + {
1.186 + i=ctx->length-ctx->num;
1.187 + memcpy(&(ctx->enc_data[ctx->num]),in,i);
1.188 + in+=i;
1.189 + inl-=i;
1.190 + j=EVP_EncodeBlock(out,ctx->enc_data,ctx->length);
1.191 + ctx->num=0;
1.192 + out+=j;
1.193 + *(out++)='\n';
1.194 + *out='\0';
1.195 + total=j+1;
1.196 + }
1.197 + while (inl >= ctx->length)
1.198 + {
1.199 + j=EVP_EncodeBlock(out,in,ctx->length);
1.200 + in+=ctx->length;
1.201 + inl-=ctx->length;
1.202 + out+=j;
1.203 + *(out++)='\n';
1.204 + *out='\0';
1.205 + total+=j+1;
1.206 + }
1.207 + if (inl != 0)
1.208 + memcpy(&(ctx->enc_data[0]),in,inl);
1.209 + ctx->num=inl;
1.210 + *outl=total;
1.211 + }
1.212 +
1.213 +EXPORT_C void EVP_EncodeFinal(EVP_ENCODE_CTX *ctx, unsigned char *out, int *outl)
1.214 + {
1.215 + unsigned int ret=0;
1.216 +
1.217 + if (ctx->num != 0)
1.218 + {
1.219 + ret=EVP_EncodeBlock(out,ctx->enc_data,ctx->num);
1.220 + out[ret++]='\n';
1.221 + out[ret]='\0';
1.222 + ctx->num=0;
1.223 + }
1.224 + *outl=ret;
1.225 + }
1.226 +
1.227 +EXPORT_C int EVP_EncodeBlock(unsigned char *t, const unsigned char *f, int dlen)
1.228 + {
1.229 + int i,ret=0;
1.230 + unsigned long l;
1.231 +
1.232 + for (i=dlen; i > 0; i-=3)
1.233 + {
1.234 + if (i >= 3)
1.235 + {
1.236 + l= (((unsigned long)f[0])<<16L)|
1.237 + (((unsigned long)f[1])<< 8L)|f[2];
1.238 + *(t++)=conv_bin2ascii(l>>18L);
1.239 + *(t++)=conv_bin2ascii(l>>12L);
1.240 + *(t++)=conv_bin2ascii(l>> 6L);
1.241 + *(t++)=conv_bin2ascii(l );
1.242 + }
1.243 + else
1.244 + {
1.245 + l=((unsigned long)f[0])<<16L;
1.246 + if (i == 2) l|=((unsigned long)f[1]<<8L);
1.247 +
1.248 + *(t++)=conv_bin2ascii(l>>18L);
1.249 + *(t++)=conv_bin2ascii(l>>12L);
1.250 + *(t++)=(i == 1)?'=':conv_bin2ascii(l>> 6L);
1.251 + *(t++)='=';
1.252 + }
1.253 + ret+=4;
1.254 + f+=3;
1.255 + }
1.256 +
1.257 + *t='\0';
1.258 + return(ret);
1.259 + }
1.260 +
1.261 +EXPORT_C void EVP_DecodeInit(EVP_ENCODE_CTX *ctx)
1.262 + {
1.263 + ctx->length=30;
1.264 + ctx->num=0;
1.265 + ctx->line_num=0;
1.266 + ctx->expect_nl=0;
1.267 + }
1.268 +
1.269 +/* -1 for error
1.270 + * 0 for last line
1.271 + * 1 for full line
1.272 + */
1.273 +EXPORT_C int EVP_DecodeUpdate(EVP_ENCODE_CTX *ctx, unsigned char *out, int *outl,
1.274 + const unsigned char *in, int inl)
1.275 + {
1.276 + int seof= -1,eof=0,rv= -1,ret=0,i,v,tmp,n,ln,tmp2,exp_nl;
1.277 + unsigned char *d;
1.278 +
1.279 + n=ctx->num;
1.280 + d=ctx->enc_data;
1.281 + ln=ctx->line_num;
1.282 + exp_nl=ctx->expect_nl;
1.283 +
1.284 + /* last line of input. */
1.285 + if ((inl == 0) || ((n == 0) && (conv_ascii2bin(in[0]) == B64_EOF)))
1.286 + { rv=0; goto end; }
1.287 +
1.288 + /* We parse the input data */
1.289 + for (i=0; i<inl; i++)
1.290 + {
1.291 + /* If the current line is > 80 characters, scream alot */
1.292 + if (ln >= 80) { rv= -1; goto end; }
1.293 +
1.294 + /* Get char and put it into the buffer */
1.295 + tmp= *(in++);
1.296 + v=conv_ascii2bin(tmp);
1.297 + /* only save the good data :-) */
1.298 + if (!B64_NOT_BASE64(v))
1.299 + {
1.300 + OPENSSL_assert(n < (int)sizeof(ctx->enc_data));
1.301 + d[n++]=tmp;
1.302 + ln++;
1.303 + }
1.304 + else if (v == B64_ERROR)
1.305 + {
1.306 + rv= -1;
1.307 + goto end;
1.308 + }
1.309 +
1.310 + /* have we seen a '=' which is 'definitly' the last
1.311 + * input line. seof will point to the character that
1.312 + * holds it. and eof will hold how many characters to
1.313 + * chop off. */
1.314 + if (tmp == '=')
1.315 + {
1.316 + if (seof == -1) seof=n;
1.317 + eof++;
1.318 + }
1.319 +
1.320 + if (v == B64_CR)
1.321 + {
1.322 + ln = 0;
1.323 + if (exp_nl)
1.324 + continue;
1.325 + }
1.326 +
1.327 + /* eoln */
1.328 + if (v == B64_EOLN)
1.329 + {
1.330 + ln=0;
1.331 + if (exp_nl)
1.332 + {
1.333 + exp_nl=0;
1.334 + continue;
1.335 + }
1.336 + }
1.337 + exp_nl=0;
1.338 +
1.339 + /* If we are at the end of input and it looks like a
1.340 + * line, process it. */
1.341 + if (((i+1) == inl) && (((n&3) == 0) || eof))
1.342 + {
1.343 + v=B64_EOF;
1.344 + /* In case things were given us in really small
1.345 + records (so two '=' were given in separate
1.346 + updates), eof may contain the incorrect number
1.347 + of ending bytes to skip, so let's redo the count */
1.348 + eof = 0;
1.349 + if (d[n-1] == '=') eof++;
1.350 + if (d[n-2] == '=') eof++;
1.351 + /* There will never be more than two '=' */
1.352 + }
1.353 +
1.354 + if ((v == B64_EOF && (n&3) == 0) || (n >= 64))
1.355 + {
1.356 + /* This is needed to work correctly on 64 byte input
1.357 + * lines. We process the line and then need to
1.358 + * accept the '\n' */
1.359 + if ((v != B64_EOF) && (n >= 64)) exp_nl=1;
1.360 + tmp2=v;
1.361 + if (n > 0)
1.362 + {
1.363 + v=EVP_DecodeBlock(out,d,n);
1.364 + n=0;
1.365 + if (v < 0) { rv=0; goto end; }
1.366 + ret+=(v-eof);
1.367 + }
1.368 + else
1.369 + {
1.370 + eof=1;
1.371 + v=0;
1.372 + }
1.373 +
1.374 + /* This is the case where we have had a short
1.375 + * but valid input line */
1.376 + if ((v < ctx->length) && eof)
1.377 + {
1.378 + rv=0;
1.379 + goto end;
1.380 + }
1.381 + else
1.382 + ctx->length=v;
1.383 +
1.384 + if (seof >= 0) { rv=0; goto end; }
1.385 + out+=v;
1.386 + }
1.387 + }
1.388 + rv=1;
1.389 +end:
1.390 + *outl=ret;
1.391 + ctx->num=n;
1.392 + ctx->line_num=ln;
1.393 + ctx->expect_nl=exp_nl;
1.394 + return(rv);
1.395 + }
1.396 +
1.397 +EXPORT_C int EVP_DecodeBlock(unsigned char *t, const unsigned char *f, int n)
1.398 + {
1.399 + int i,ret=0,a,b,c,d;
1.400 + unsigned long l;
1.401 +
1.402 + /* trim white space from the start of the line. */
1.403 + while ((conv_ascii2bin(*f) == B64_WS) && (n > 0))
1.404 + {
1.405 + f++;
1.406 + n--;
1.407 + }
1.408 +
1.409 + /* strip off stuff at the end of the line
1.410 + * ascii2bin values B64_WS, B64_EOLN, B64_EOLN and B64_EOF */
1.411 + while ((n > 3) && (B64_NOT_BASE64(conv_ascii2bin(f[n-1]))))
1.412 + n--;
1.413 +
1.414 + if (n%4 != 0) return(-1);
1.415 +
1.416 + for (i=0; i<n; i+=4)
1.417 + {
1.418 + a=conv_ascii2bin(*(f++));
1.419 + b=conv_ascii2bin(*(f++));
1.420 + c=conv_ascii2bin(*(f++));
1.421 + d=conv_ascii2bin(*(f++));
1.422 + if ( (a & 0x80) || (b & 0x80) ||
1.423 + (c & 0x80) || (d & 0x80))
1.424 + return(-1);
1.425 + l=( (((unsigned long)a)<<18L)|
1.426 + (((unsigned long)b)<<12L)|
1.427 + (((unsigned long)c)<< 6L)|
1.428 + (((unsigned long)d) ));
1.429 + *(t++)=(unsigned char)(l>>16L)&0xff;
1.430 + *(t++)=(unsigned char)(l>> 8L)&0xff;
1.431 + *(t++)=(unsigned char)(l )&0xff;
1.432 + ret+=3;
1.433 + }
1.434 + return(ret);
1.435 + }
1.436 +
1.437 +EXPORT_C int EVP_DecodeFinal(EVP_ENCODE_CTX *ctx, unsigned char *out, int *outl)
1.438 + {
1.439 + int i;
1.440 +
1.441 + *outl=0;
1.442 + if (ctx->num != 0)
1.443 + {
1.444 + i=EVP_DecodeBlock(out,ctx->enc_data,ctx->num);
1.445 + if (i < 0) return(-1);
1.446 + ctx->num=0;
1.447 + *outl=i;
1.448 + return(1);
1.449 + }
1.450 + else
1.451 + return(1);
1.452 + }
1.453 +
1.454 +#ifdef undef
1.455 +EXPORT_C int EVP_DecodeValid(unsigned char *buf, int len)
1.456 + {
1.457 + int i,num=0,bad=0;
1.458 +
1.459 + if (len == 0) return(-1);
1.460 + while (conv_ascii2bin(*buf) == B64_WS)
1.461 + {
1.462 + buf++;
1.463 + len--;
1.464 + if (len == 0) return(-1);
1.465 + }
1.466 +
1.467 + for (i=len; i >= 4; i-=4)
1.468 + {
1.469 + if ( (conv_ascii2bin(buf[0]) >= 0x40) ||
1.470 + (conv_ascii2bin(buf[1]) >= 0x40) ||
1.471 + (conv_ascii2bin(buf[2]) >= 0x40) ||
1.472 + (conv_ascii2bin(buf[3]) >= 0x40))
1.473 + return(-1);
1.474 + buf+=4;
1.475 + num+=1+(buf[2] != '=')+(buf[3] != '=');
1.476 + }
1.477 + if ((i == 1) && (conv_ascii2bin(buf[0]) == B64_EOLN))
1.478 + return(num);
1.479 + if ((i == 2) && (conv_ascii2bin(buf[0]) == B64_EOLN) &&
1.480 + (conv_ascii2bin(buf[0]) == B64_EOLN))
1.481 + return(num);
1.482 + return(1);
1.483 + }
1.484 +#endif