X-Git-Url: https://git.openssl.org/gitweb/?p=openssl.git;a=blobdiff_plain;f=crypto%2Fevp%2Fencode.c;h=e278a1b5d400fd95ce6fd09f51f7af1666acc0a0;hp=7cd65244e652fc7a5aefea12950f8a3be6d384c7;hb=5f487e031735a8504022d4fbabb57f249b7a6bd4;hpb=d02b48c63a58ea4367a0e905979f140b7d090f86 diff --git a/crypto/evp/encode.c b/crypto/evp/encode.c index 7cd65244e6..e278a1b5d4 100644 --- a/crypto/evp/encode.c +++ b/crypto/evp/encode.c @@ -1,5 +1,5 @@ /* crypto/evp/encode.c */ -/* Copyright (C) 1995-1997 Eric Young (eay@cryptsoft.com) +/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) * All rights reserved. * * This package is an SSL implementation written @@ -58,10 +58,21 @@ #include #include "cryptlib.h" -#include "evp.h" +#include +#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 @@ -74,7 +85,7 @@ #define CHUNKS_PER_LINE (64/4) #define CHAR_PER_LINE (64+1) -static unsigned char data_bin2ascii[65]="ABCDEFGHIJKLMNOPQRSTUVWXYZ\ +static const unsigned char data_bin2ascii[65]="ABCDEFGHIJKLMNOPQRSTUVWXYZ\ abcdefghijklmnopqrstuvwxyz0123456789+/"; /* 0xF0 is a EOLN @@ -91,7 +102,7 @@ abcdefghijklmnopqrstuvwxyz0123456789+/"; #define B64_ERROR 0xFF #define B64_NOT_BASE64(a) (((a)|0x13) == 0xF3) -static unsigned char data_ascii2bin[128]={ +static const 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, @@ -110,26 +121,22 @@ static unsigned char data_ascii2bin[128]={ 0x31,0x32,0x33,0xFF,0xFF,0xFF,0xFF,0xFF, }; -void EVP_EncodeInit(ctx) -EVP_ENCODE_CTX *ctx; +void EVP_EncodeInit(EVP_ENCODE_CTX *ctx) { ctx->length=48; ctx->num=0; ctx->line_num=0; } -void EVP_EncodeUpdate(ctx,out,outl,in,inl) -EVP_ENCODE_CTX *ctx; -unsigned char *out; -int *outl; -unsigned char *in; -int inl; +void EVP_EncodeUpdate(EVP_ENCODE_CTX *ctx, unsigned char *out, int *outl, + const unsigned char *in, int inl) { int i,j; unsigned int total=0; *outl=0; if (inl == 0) return; + OPENSSL_assert(ctx->length <= (int)sizeof(ctx->enc_data)); if ((ctx->num+inl) < ctx->length) { memcpy(&(ctx->enc_data[ctx->num]),in,inl); @@ -165,10 +172,7 @@ int inl; *outl=total; } -void EVP_EncodeFinal(ctx,out,outl) -EVP_ENCODE_CTX *ctx; -unsigned char *out; -int *outl; +void EVP_EncodeFinal(EVP_ENCODE_CTX *ctx, unsigned char *out, int *outl) { unsigned int ret=0; @@ -182,9 +186,7 @@ int *outl; *outl=ret; } -int EVP_EncodeBlock(t,f,dlen) -unsigned char *t,*f; -int dlen; +int EVP_EncodeBlock(unsigned char *t, const unsigned char *f, int dlen) { int i,ret=0; unsigned long l; @@ -218,31 +220,28 @@ int dlen; return(ret); } -void EVP_DecodeInit(ctx) -EVP_ENCODE_CTX *ctx; +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(ctx,out,outl,in,inl) -EVP_ENCODE_CTX *ctx; -unsigned char *out; -int *outl; -unsigned char *in; -int inl; +int EVP_DecodeUpdate(EVP_ENCODE_CTX *ctx, unsigned char *out, int *outl, + const unsigned char *in, int inl) { - int seof= -1,eof=0,rv= -1,ret=0,i,v,tmp,n,ln,tmp2; + int seof= -1,eof=0,rv= -1,ret=0,i,v,tmp,n,ln,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))) @@ -251,7 +250,7 @@ int inl; /* We parse the input data */ for (i=0; i 80 characters, scream alot */ + /* If the current line is > 80 characters, scream a lot */ if (ln >= 80) { rv= -1; goto end; } /* Get char and put it into the buffer */ @@ -260,6 +259,7 @@ int inl; /* only save the good data :-) */ if (!B64_NOT_BASE64(v)) { + OPENSSL_assert(n < (int)sizeof(ctx->enc_data)); d[n++]=tmp; ln++; } @@ -279,22 +279,51 @@ int inl; eof++; } + if (v == B64_CR) + { + ln = 0; + if (exp_nl) + continue; + } + /* eoln */ - if (v == B64_EOLN) ln=0; + 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)) + if ((v == B64_EOF && (n&3) == 0) || (n >= 64)) { - tmp2=v; + /* 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; if (n > 0) { v=EVP_DecodeBlock(out,d,n); - if (v < 0) { rv=0; goto end; } n=0; + if (v < 0) { rv=0; goto end; } ret+=(v-eof); } else @@ -322,12 +351,11 @@ end: *outl=ret; ctx->num=n; ctx->line_num=ln; + ctx->expect_nl=exp_nl; return(rv); } -int EVP_DecodeBlock(t,f,n) -unsigned char *t,*f; -int n; +int EVP_DecodeBlock(unsigned char *t, const unsigned char *f, int n) { int i,ret=0,a,b,c,d; unsigned long l; @@ -367,10 +395,7 @@ int n; return(ret); } -int EVP_DecodeFinal(ctx,out,outl) -EVP_ENCODE_CTX *ctx; -unsigned char *out; -int *outl; +int EVP_DecodeFinal(EVP_ENCODE_CTX *ctx, unsigned char *out, int *outl) { int i; @@ -388,9 +413,7 @@ int *outl; } #ifdef undef -int EVP_DecodeValid(buf,len) -unsigned char *buf; -int len; +int EVP_DecodeValid(unsigned char *buf, int len) { int i,num=0,bad=0;