⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 encode.c

📁 With OpenSSL 0.9.6, a new component has been added to support external crypto devices, for example a
💻 C
字号:
/* crypto/evp/encode.c *//* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) * All rights reserved. * * This package is an SSL implementation written * by Eric Young (eay@cryptsoft.com). * The implementation was written so as to conform with Netscapes SSL. *  * This library is free for commercial and non-commercial use as long as * the following conditions are aheared to.  The following conditions * apply to all code found in this distribution, be it the RC4, RSA, * lhash, DES, etc., code; not just the SSL code.  The SSL documentation * included with this distribution is covered by the same copyright terms * except that the holder is Tim Hudson (tjh@cryptsoft.com). *  * Copyright remains Eric Young's, and as such any Copyright notices in * the code are not to be removed. * If this package is used in a product, Eric Young should be given attribution * as the author of the parts of the library used. * This can be in the form of a textual message at program startup or * in documentation (online or textual) provided with the package. *  * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the copyright *    notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright *    notice, this list of conditions and the following disclaimer in the *    documentation and/or other materials provided with the distribution. * 3. All advertising materials mentioning features or use of this software *    must display the following acknowledgement: *    "This product includes cryptographic software written by *     Eric Young (eay@cryptsoft.com)" *    The word 'cryptographic' can be left out if the rouines from the library *    being used are not cryptographic related :-). * 4. If you include any Windows specific code (or a derivative thereof) from  *    the apps directory (application code) you must include an acknowledgement: *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)" *  * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. *  * The licence and distribution terms for any publically available version or * derivative of this code cannot be changed.  i.e. this code cannot simply be * copied and put under another distribution licence * [including the GNU Public Licence.] */#include <stdio.h>#include "cryptlib.h"#include <openssl/evp.h>#ifndef CHARSET_EBCDIC#define conv_bin2ascii(a)	(data_bin2ascii[(a)&0x3f])#define conv_ascii2bin(a)	(data_ascii2bin[(a)&0x7f])#else/* We assume that PEM encoded files are EBCDIC files * (i.e., printable text files). Convert them here while decoding. * When encoding, output is EBCDIC (text) format again. * (No need for conversion in the conv_bin2ascii macro, as the * underlying textstring data_bin2ascii[] is already EBCDIC) */#define conv_bin2ascii(a)	(data_bin2ascii[(a)&0x3f])#define conv_ascii2bin(a)	(data_ascii2bin[os_toascii[a]&0x7f])#endif/* 64 char lines * pad input with 0 * left over chars are set to = * 1 byte  => xx== * 2 bytes => xxx= * 3 bytes => xxxx */#define BIN_PER_LINE    (64/4*3)#define CHUNKS_PER_LINE (64/4)#define CHAR_PER_LINE   (64+1)static unsigned char data_bin2ascii[65]="ABCDEFGHIJKLMNOPQRSTUVWXYZ\abcdefghijklmnopqrstuvwxyz0123456789+/";/* 0xF0 is a EOLN * 0xF1 is ignore but next needs to be 0xF0 (for \r\n processing). * 0xF2 is EOF * 0xE0 is ignore at start of line. * 0xFF is error */#define B64_EOLN		0xF0#define B64_CR			0xF1#define B64_EOF			0xF2#define B64_WS			0xE0#define B64_ERROR       	0xFF#define B64_NOT_BASE64(a)	(((a)|0x13) == 0xF3)static unsigned char data_ascii2bin[128]={	0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,	0xFF,0xE0,0xF0,0xFF,0xFF,0xF1,0xFF,0xFF,	0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,	0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,	0xE0,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,	0xFF,0xFF,0xFF,0x3E,0xFF,0xF2,0xFF,0x3F,	0x34,0x35,0x36,0x37,0x38,0x39,0x3A,0x3B,	0x3C,0x3D,0xFF,0xFF,0xFF,0x00,0xFF,0xFF,	0xFF,0x00,0x01,0x02,0x03,0x04,0x05,0x06,	0x07,0x08,0x09,0x0A,0x0B,0x0C,0x0D,0x0E,	0x0F,0x10,0x11,0x12,0x13,0x14,0x15,0x16,	0x17,0x18,0x19,0xFF,0xFF,0xFF,0xFF,0xFF,	0xFF,0x1A,0x1B,0x1C,0x1D,0x1E,0x1F,0x20,	0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,	0x29,0x2A,0x2B,0x2C,0x2D,0x2E,0x2F,0x30,	0x31,0x32,0x33,0xFF,0xFF,0xFF,0xFF,0xFF,	};void EVP_EncodeInit(EVP_ENCODE_CTX *ctx)	{	ctx->length=48;	ctx->num=0;	ctx->line_num=0;	}void EVP_EncodeUpdate(EVP_ENCODE_CTX *ctx, unsigned char *out, int *outl,	     unsigned char *in, int inl)	{	int i,j;	unsigned int total=0;	*outl=0;	if (inl == 0) return;	if ((ctx->num+inl) < ctx->length)		{		memcpy(&(ctx->enc_data[ctx->num]),in,inl);		ctx->num+=inl;		return;		}	if (ctx->num != 0)		{		i=ctx->length-ctx->num;		memcpy(&(ctx->enc_data[ctx->num]),in,i);		in+=i;		inl-=i;		j=EVP_EncodeBlock(out,ctx->enc_data,ctx->length);		ctx->num=0;		out+=j;		*(out++)='\n';		*out='\0';		total=j+1;		}	while (inl >= ctx->length)		{		j=EVP_EncodeBlock(out,in,ctx->length);		in+=ctx->length;		inl-=ctx->length;		out+=j;		*(out++)='\n';		*out='\0';		total+=j+1;		}	if (inl != 0)		memcpy(&(ctx->enc_data[0]),in,inl);	ctx->num=inl;	*outl=total;	}void EVP_EncodeFinal(EVP_ENCODE_CTX *ctx, unsigned char *out, int *outl)	{	unsigned int ret=0;	if (ctx->num != 0)		{		ret=EVP_EncodeBlock(out,ctx->enc_data,ctx->num);		out[ret++]='\n';		out[ret]='\0';		ctx->num=0;		}	*outl=ret;	}int EVP_EncodeBlock(unsigned char *t, const unsigned char *f, int dlen)	{	int i,ret=0;	unsigned long l;	for (i=dlen; i > 0; i-=3)		{		if (i >= 3)			{			l=	(((unsigned long)f[0])<<16L)|				(((unsigned long)f[1])<< 8L)|f[2];			*(t++)=conv_bin2ascii(l>>18L);			*(t++)=conv_bin2ascii(l>>12L);			*(t++)=conv_bin2ascii(l>> 6L);			*(t++)=conv_bin2ascii(l     );			}		else			{			l=((unsigned long)f[0])<<16L;			if (i == 2) l|=((unsigned long)f[1]<<8L);			*(t++)=conv_bin2ascii(l>>18L);			*(t++)=conv_bin2ascii(l>>12L);			*(t++)=(i == 1)?'=':conv_bin2ascii(l>> 6L);			*(t++)='=';			}		ret+=4;		f+=3;		}	*t='\0';	return(ret);	}void EVP_DecodeInit(EVP_ENCODE_CTX *ctx)	{	ctx->length=30;	ctx->num=0;	ctx->line_num=0;	ctx->expect_nl=0;	}/* -1 for error *  0 for last line *  1 for full line */int EVP_DecodeUpdate(EVP_ENCODE_CTX *ctx, unsigned char *out, int *outl,	     unsigned char *in, int inl)	{	int seof= -1,eof=0,rv= -1,ret=0,i,v,tmp,n,ln,tmp2,exp_nl;	unsigned char *d;	n=ctx->num;	d=ctx->enc_data;	ln=ctx->line_num;	exp_nl=ctx->expect_nl;	/* last line of input. */	if ((inl == 0) || ((n == 0) && (conv_ascii2bin(in[0]) == B64_EOF)))		{ rv=0; goto end; }			/* We parse the input data */	for (i=0; i<inl; i++)		{		/* If the current line is > 80 characters, scream alot */		if (ln >= 80) { rv= -1; goto end; }		/* Get char and put it into the buffer */		tmp= *(in++);		v=conv_ascii2bin(tmp);		/* only save the good data :-) */		if (!B64_NOT_BASE64(v))			{			d[n++]=tmp;			ln++;			}		else if (v == B64_ERROR)			{			rv= -1;			goto end;			}		/* have we seen a '=' which is 'definitly' the last		 * input line.  seof will point to the character that		 * holds it. and eof will hold how many characters to		 * chop off. */		if (tmp == '=')			{			if (seof == -1) seof=n;			eof++;			}		if (v == B64_CR)			{			ln = 0;			if (exp_nl)				continue;			}		/* eoln */		if (v == B64_EOLN)			{			ln=0;			if (exp_nl)				{				exp_nl=0;				continue;				}			}		exp_nl=0;		/* If we are at the end of input and it looks like a		 * line, process it. */		if (((i+1) == inl) && (((n&3) == 0) || eof))			{			v=B64_EOF;			/* In case things were given us in really small			   records (so two '=' were given in separate			   updates), eof may contain the incorrect number			   of ending bytes to skip, so let's redo the count */			eof = 0;			if (d[n-1] == '=') eof++;			if (d[n-2] == '=') eof++;			/* There will never be more than two '=' */			}		if ((v == B64_EOF) || (n >= 64))			{			/* This is needed to work correctly on 64 byte input			 * lines.  We process the line and then need to			 * accept the '\n' */			if ((v != B64_EOF) && (n >= 64)) exp_nl=1;			tmp2=v;			if (n > 0)				{				v=EVP_DecodeBlock(out,d,n);				if (v < 0) { rv=0; goto end; }				n=0;				ret+=(v-eof);				}			else				{				eof=1;				v=0;				}			/* This is the case where we have had a short			 * but valid input line */			if ((v < ctx->length) && eof)				{				rv=0;				goto end;				}			else				ctx->length=v;			if (seof >= 0) { rv=0; goto end; }			out+=v;			}		}	rv=1;end:	*outl=ret;	ctx->num=n;	ctx->line_num=ln;	ctx->expect_nl=exp_nl;	return(rv);	}int EVP_DecodeBlock(unsigned char *t, const unsigned char *f, int n)	{	int i,ret=0,a,b,c,d;	unsigned long l;	/* trim white space from the start of the line. */	while ((conv_ascii2bin(*f) == B64_WS) && (n > 0))		{		f++;		n--;		}	/* strip off stuff at the end of the line	 * ascii2bin values B64_WS, B64_EOLN, B64_EOLN and B64_EOF */	while ((n > 3) && (B64_NOT_BASE64(conv_ascii2bin(f[n-1]))))		n--;	if (n%4 != 0) return(-1);	for (i=0; i<n; i+=4)		{		a=conv_ascii2bin(*(f++));		b=conv_ascii2bin(*(f++));		c=conv_ascii2bin(*(f++));		d=conv_ascii2bin(*(f++));		if (	(a & 0x80) || (b & 0x80) ||			(c & 0x80) || (d & 0x80))			return(-1);		l=(	(((unsigned long)a)<<18L)|			(((unsigned long)b)<<12L)|			(((unsigned long)c)<< 6L)|			(((unsigned long)d)     ));		*(t++)=(unsigned char)(l>>16L)&0xff;		*(t++)=(unsigned char)(l>> 8L)&0xff;		*(t++)=(unsigned char)(l     )&0xff;		ret+=3;		}	return(ret);	}int EVP_DecodeFinal(EVP_ENCODE_CTX *ctx, unsigned char *out, int *outl)	{	int i;	*outl=0;	if (ctx->num != 0)		{		i=EVP_DecodeBlock(out,ctx->enc_data,ctx->num);		if (i < 0) return(-1);		ctx->num=0;		*outl=i;		return(1);		}	else		return(1);	}#ifdef undefint EVP_DecodeValid(unsigned char *buf, int len)	{	int i,num=0,bad=0;	if (len == 0) return(-1);	while (conv_ascii2bin(*buf) == B64_WS)		{		buf++;		len--;		if (len == 0) return(-1);		}	for (i=len; i >= 4; i-=4)		{		if (	(conv_ascii2bin(buf[0]) >= 0x40) ||			(conv_ascii2bin(buf[1]) >= 0x40) ||			(conv_ascii2bin(buf[2]) >= 0x40) ||			(conv_ascii2bin(buf[3]) >= 0x40))			return(-1);		buf+=4;		num+=1+(buf[2] != '=')+(buf[3] != '=');		}	if ((i == 1) && (conv_ascii2bin(buf[0]) == B64_EOLN))		return(num);	if ((i == 2) && (conv_ascii2bin(buf[0]) == B64_EOLN) &&		(conv_ascii2bin(buf[0]) == B64_EOLN))		return(num);	return(1);	}#endif

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -