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