Exemplo n.º 1
0
Arquivo: ssl.c Projeto: UIKit0/picogui
static char *
_SSL_do_cipher_base64(char *buf, int buf_len, char *key, int operation)
{
	char *pt;
	char *pt2;
	int i;


	if (operation) {
		i = _SSL_do_cipher(buf, buf_len, key, operation, &pt);
		pt2 = mmalloc(i * 2 + 1);		/* + NULL */
		memset(pt2, 0, i * 2 + 1);	/* FIXME: need it? */
		if ((i = EVP_EncodeBlock(pt2, pt, i)) == -1) {
			fprintf(stderr, "_SSL_do_cipher_base64 :: EVP_EncodeBlock failed\n");
			exit(1);
		}
fprintf(stderr, "_SSL_do_cipher_base64 :: EVP_EncodeBlock %d [%24s]\n", i, key);
	} else {
		pt = mmalloc(buf_len / 2 * 2 + 1);		/* + NULL */
		memset(pt, 0, buf_len / 2 * 2 + 1);	/* FIXME: need it? */
		if ((i = EVP_DecodeBlock(pt, buf, buf_len)) == -1) {
			fprintf(stderr, "_SSL_do_cipher_base64 :: EVP_DecodeBlock failed\n");
			exit(1);
		}
fprintf(stderr, "_SSL_do_cipher_base64 :: EVP_DecodeBlock %d [%24s]\n", i, key);
		i -= i % 8;	/* cut padding */
		i = _SSL_do_cipher(pt, i, key, operation, &pt2);
	}
	free (pt);

	return (pt2);
}
Exemplo n.º 2
0
/*
 * Decodes the base64 string |in| into |out|.
 * A new string will be malloc'd and assigned to |out|. This will be owned by
 * the caller. Do not provide a pre-allocated string in |out|.
 */
static int ct_base64_decode(const char *in, unsigned char **out)
{
    size_t inlen = strlen(in);
    int outlen;
    unsigned char *outbuf = NULL;

    if (inlen == 0) {
        *out = NULL;
        return 0;
    }

    outlen = (inlen / 4) * 3;
    outbuf = OPENSSL_malloc(outlen);
    if (outbuf == NULL) {
        CTerr(CT_F_CT_BASE64_DECODE, ERR_R_MALLOC_FAILURE);
        goto err;
    }

    outlen = EVP_DecodeBlock(outbuf, (unsigned char *)in, inlen);
    if (outlen < 0) {
        CTerr(CT_F_CT_BASE64_DECODE, CT_R_BASE64_DECODE_ERROR);
        goto err;
    }

    *out = outbuf;
    return outlen;
err:
    OPENSSL_free(outbuf);
    return -1;
}
Exemplo n.º 3
0
utility_retcode_t raopd_base64_decode(uint8_t *dst,
				      size_t dstlen,
				      const char *src,
				      const size_t srclen,
				      size_t *decoded_length)
{
	utility_retcode_t ret = UTILITY_SUCCESS;
	char *begin_padding, *end_padding;

	FUNC_ENTER;

	DEBG("srclen: %d dstlen: %d\n", srclen, dstlen);

	*decoded_length = EVP_DecodeBlock(dst, (const uint8_t *)src, srclen);

	/* Adjust length to account for the somewhat broken OpenSSL API.  See:
	   http://osdir.com/ml/encryption.openssl.devel/2002-08/msg00267.html */
	begin_padding = syscalls_strchr(src, '=');
	end_padding = syscalls_strrchr(src, '=');
	if (NULL != end_padding) {
		*decoded_length -= (end_padding - begin_padding + 1);
	}

	INFO("decoded_length: %d\n", *decoded_length);

	FUNC_RETURN;
	return ret;
}
Exemplo n.º 4
0
NETSCAPE_SPKI *
NETSCAPE_SPKI_b64_decode(const char *str, int len)
{
	unsigned char *spki_der;
	const unsigned char *p;
	int spki_len;
	NETSCAPE_SPKI *spki;

	if (len <= 0)
		len = strlen(str);
	if (!(spki_der = malloc(len + 1))) {
		X509err(X509_F_NETSCAPE_SPKI_B64_DECODE, ERR_R_MALLOC_FAILURE);
		return NULL;
	}
	spki_len = EVP_DecodeBlock(spki_der, (const unsigned char *)str, len);
	if (spki_len < 0) {
		X509err(X509_F_NETSCAPE_SPKI_B64_DECODE,
		    X509_R_BASE64_DECODE_ERROR);
		free(spki_der);
		return NULL;
	}
	p = spki_der;
	spki = d2i_NETSCAPE_SPKI(NULL, &p, spki_len);
	free(spki_der);
	return spki;
}
int decode_base64( __in const char* in, __out char** buffer, __out int* len)
{
	unsigned int t = 0 , c = 0;
	int n = 0;
	unsigned char out[3];
	unsigned char inp[4];
	
	n = strlen(in);
	if(n % 4 != 0)
	{
		return 0;
	}
	n = n / 4 * 3;
	if(len != NULL)
		*len = n;
	*buffer = (char*)malloc(n);
	memset(*buffer , 0 , n);
	while(1)
	{
		memset(inp , 0 , 4);
		memset(out , 0 , 3);
		memcpy(inp , in + c , 4);
		c += 4;
		n = EVP_DecodeBlock(out , inp , 4 );
		memcpy( *buffer + t , out, n);
		t += n;
		if(c >= strlen(in))
			break;
	}
	return 1;
}
Exemplo n.º 6
0
/* Decode base-64 */
unsigned char *
ship_decode_base64(char *input, int length, int* outlen)
{
	unsigned char *ret = NULL;
	unsigned char in[64];
	int blen, len=0, i=0, ilen, olen=0;
	
	blen = (((length + 3) / 4) * 3);
	ASSERT_TRUE(ret = (unsigned char *)mallocz(blen), err); 
	
	while(i<length){
		
		ilen = (i+64<length)?64:length-i;
		memcpy (in, input, ilen);
		input += ilen;
		i += ilen;

		/* Each 64-byte text should decode to 48-byte binary */ 
		len = EVP_DecodeBlock((unsigned char*)ret+olen, in, ilen);
		olen += len;
	}
	
	*outlen = olen;
	
	/* remove padded = */
	while(*(--input) == '='){
		--(*outlen);
	}
	
err:
	return ret;
}
Exemplo n.º 7
0
/* base64 conversions {{{ */
char *unbase64(unsigned char *input, int length)
{
	char *buffer = (char*)xmalloc(length);
	memset(buffer, 0, length);
	EVP_DecodeBlock((unsigned char*)buffer, input, length);
	return buffer;
}
Exemplo n.º 8
0
/*
 * Authenticate to the server with the Challenge-Response Authentication
 * Mechanism (CRAM).  The authentication type associated with CRAM is
 * "CRAM-MD5".
 */
int
auth_cram_md5(session *ssn, const char *user, const char *pass)
{
	int t;
	size_t n;
	unsigned int i;
	unsigned char *chal, *resp, *out, *buf;
	unsigned char md[EVP_MAX_MD_SIZE], mdhex[EVP_MAX_MD_SIZE * 2 + 1];
	unsigned int mdlen;
	HMAC_CTX hmac;

	if ((t = imap_authenticate(ssn, "CRAM-MD5")) == -1)
		return -1;

	if (response_authenticate(ssn, t, &chal) ==
	    STATUS_RESPONSE_CONTINUE) {
		n = strlen((char *)(chal)) * 3 / 4 + 1;
		resp = (unsigned char *)xmalloc(n * sizeof(char));
		memset(resp, 0, n);

		EVP_DecodeBlock(resp, chal, strlen((char *)(chal)));

		HMAC_Init(&hmac, (const unsigned char *)pass, strlen(pass),
		    EVP_md5());
		HMAC_Update(&hmac, resp, strlen((char *)(resp)));
		HMAC_Final(&hmac, md, &mdlen);

		xfree(chal);
		xfree(resp);

		for (i = 0; i < mdlen; i++)
			snprintf((char *)(mdhex) + i * 2, mdlen * 2 - i * 2 + 1,
			    "%02x", md[i]);
		mdhex[mdlen * 2] = '\0';

		n = strlen(user) + 1 + strlen((char *)(mdhex)) + 1;
		buf = (unsigned char *)xmalloc(n * sizeof(unsigned char));
		memset(buf, 0, n);

		snprintf((char *)(buf), n, "%s %s", user, mdhex);

		n = (strlen((char *)(buf)) + 3) * 4 / 3 + 1;
		out = (unsigned char *)xmalloc(n * sizeof(unsigned char));
		memset(out, 0, n);

		EVP_EncodeBlock(out, buf, strlen((char *)(buf)));

		imap_continuation(ssn, (char *)(out), strlen((char *)(out)));

		xfree(buf);
		xfree(out);
	} else
		return -1;

	return response_authenticate(ssn, t, NULL);
}
Exemplo n.º 9
0
int mite_base64_2_string_block(char *base64,int inlen,char **ppout)
{
    char *p=base64+inlen -1;
    int pad = 0;
    int i = 0;
    for(i=0;i<4;i++)
    {
        if(*p=='=')
            pad++;
        p--;
    }
    char *out;
    out = malloc(inlen);
    int len = EVP_DecodeBlock(out,base64,inlen);
    len -= pad;

    *ppout = out;
    return len;
}
Exemplo n.º 10
0
int WXBizMsgCrypt::DecodeBase64(const std::string sSrc, std::string & sTarget)
{
    if(0 == sSrc.size() || kMaxBase64Size < sSrc.size())
    {
        return -1;
    }
    
    //����ĩβ=�Ÿ���
    int iEqualNum = 0;
    for(int n= sSrc.size() - 1; n>=0; --n)
    {
        if(sSrc.c_str()[n] == '=')
        {
            iEqualNum++;
        }
        else
        {
            break;
        }
    }
    
    int iOutBufSize = sSrc.size();
    char * pcOutBuf = (char*)malloc( iOutBufSize);
    if(NULL == pcOutBuf)
    {
        return -1;
    }
    
    int iRet = 0;
    int iTargetSize = 0;
    iTargetSize =  EVP_DecodeBlock((unsigned char*)pcOutBuf, (const unsigned char*)sSrc.c_str(), sSrc.size());
    if(iTargetSize > iEqualNum && iTargetSize < iOutBufSize)
    {
        sTarget.assign(pcOutBuf, iTargetSize - iEqualNum);
    }
    else
    {
        iRet = -1;
    }
    
    FREE_PTR(pcOutBuf);
    return iRet;
}
Exemplo n.º 11
0
VARIANT CBoxEncoding::Base64Decode(LPCTSTR pstrText)
{
#ifdef _UNICODE
	CStringA str(pstrText);
	int len = str.GetLength();
	LPCSTR pstr = str;
#else
	int len = (int)_tcslen(pstrText);
	LPCSTR pstr = pstrText;
#endif

	CBoxBinPtr varPtr((len / 4) * 3);
	int nPos = 0, nPos1, nPos2, n = 0, nSize = 0;

	while(nPos < len)
	{
		nPos1 = nPos;
		while(nPos1 < len && pstr[nPos1] != '\n')
			nPos1 ++;

		nPos2 = nPos1;
		while(nPos2 > nPos && (unsigned char)pstr[nPos2 - 1] <= ' ')
			nPos2 --;

		n = EVP_DecodeBlock((unsigned char*)varPtr + nSize, (unsigned char*)pstr + nPos, nPos2 - nPos);
		if(n != -1)
		{
			if(nPos2 > nPos && pstr[nPos2 - 1] == '=')
				n --;
			nPos2 --;
			if(nPos2 > nPos && pstr[nPos2 - 1] == '=')
				n --;
			nSize += n;
		}

		nPos = nPos1 + 1;
	}

	return varPtr.GetVariant(nSize);
}
Exemplo n.º 12
0
/*
 * Decodes the base64 string |in| into |out|.
 * A new string will be malloc'd and assigned to |out|. This will be owned by
 * the caller. Do not provide a pre-allocated string in |out|.
 */
static int ct_base64_decode(const char *in, unsigned char **out)
{
    size_t inlen = strlen(in);
    int outlen, i;
    unsigned char *outbuf = NULL;

    if (inlen == 0) {
        *out = NULL;
        return 0;
    }

    outlen = (inlen / 4) * 3;
    outbuf = OPENSSL_malloc(outlen);
    if (outbuf == NULL) {
        CTerr(CT_F_CT_BASE64_DECODE, ERR_R_MALLOC_FAILURE);
        goto err;
    }

    outlen = EVP_DecodeBlock(outbuf, (unsigned char *)in, inlen);
    if (outlen < 0) {
        CTerr(CT_F_CT_BASE64_DECODE, CT_R_BASE64_DECODE_ERROR);
        goto err;
    }

    /* Subtract padding bytes from |outlen|.  Any more than 2 is malformed. */
    i = 0;
    while (in[--inlen] == '=') {
        --outlen;
        if (++i > 2)
            goto err;
    }

    *out = outbuf;
    return outlen;
err:
    OPENSSL_free(outbuf);
    return -1;
}
Exemplo n.º 13
0
int B64_decode(const char *strin, char *strout, int cbstr)
{
	CStr altin;
	if ((cbstr % 4 == 3) || (cbstr % 4 == 2)) {
		altin.Copy(strin, cbstr);
		if (cbstr % 4 <= 3) altin << '=';
		if (cbstr % 4 == 2) altin << '=';
		strin = altin.Data();
		cbstr = altin.Length();
	}

	int len = EVP_DecodeBlock((unsigned char*)strout, (unsigned char*)strin, cbstr);
	if ( cbstr && (len > 0) )
		{
		if (strin[cbstr-1] == '=') 
			{
			if (strin[cbstr-2] == '=')
				return(len-2);
			else 
				return(len-1);
			}
		}
	return len;
}
Exemplo n.º 14
0
static int b64_read(BIO *b, char *out, int outl)
	{
	int ret=0,i,ii,j,k,x,n,num,ret_code=0;
	BIO_B64_CTX *ctx;
	unsigned char *p,*q;

	if (out == NULL) return(0);
	ctx=(BIO_B64_CTX *)b->ptr;

	if ((ctx == NULL) || (b->next_bio == NULL)) return(0);

	if (ctx->encode != B64_DECODE)
		{
		ctx->encode=B64_DECODE;
		ctx->buf_len=0;
		ctx->buf_off=0;
		ctx->tmp_len=0;
		EVP_DecodeInit(&(ctx->base64));
		}

	/* First check if there are bytes decoded/encoded */
	if (ctx->buf_len > 0)
		{
		i=ctx->buf_len-ctx->buf_off;
		if (i > outl) i=outl;
		OPENSSL_assert(ctx->buf_off+i < (int)sizeof(ctx->buf));
		memcpy(out,&(ctx->buf[ctx->buf_off]),i);
		ret=i;
		out+=i;
		outl-=i;
		ctx->buf_off+=i;
		if (ctx->buf_len == ctx->buf_off)
			{
			ctx->buf_len=0;
			ctx->buf_off=0;
			}
		}

	/* At this point, we have room of outl bytes and an empty
	 * buffer, so we should read in some more. */

	ret_code=0;
	while (outl > 0)
		{

		if (ctx->cont <= 0)
			break;

		i=BIO_read(b->next_bio,&(ctx->tmp[ctx->tmp_len]),
			B64_BLOCK_SIZE-ctx->tmp_len);

		if (i <= 0)
			{
			ret_code=i;

			/* Should be continue next time we are called? */
			if (!BIO_should_retry(b->next_bio))
				{
				ctx->cont=i;
				/* If buffer empty break */
				if(ctx->tmp_len == 0)
					break;
				/* Fall through and process what we have */
				else
					i = 0;
				}
			/* else we retry and add more data to buffer */
			else
				break;
			}
		i+=ctx->tmp_len;
		ctx->tmp_len = i;

		/* We need to scan, a line at a time until we
		 * have a valid line if we are starting. */
		if (ctx->start && (BIO_get_flags(b) & BIO_FLAGS_BASE64_NO_NL))
			{
			/* ctx->start=1; */
			ctx->tmp_len=0;
			}
		else if (ctx->start)
			{
			q=p=(unsigned char *)ctx->tmp;
			for (j=0; j<i; j++)
				{
				if (*(q++) != '\n') continue;

				/* due to a previous very long line,
				 * we need to keep on scanning for a '\n'
				 * before we even start looking for
				 * base64 encoded stuff. */
				if (ctx->tmp_nl)
					{
					p=q;
					ctx->tmp_nl=0;
					continue;
					}

				k=EVP_DecodeUpdate(&(ctx->base64),
					(unsigned char *)ctx->buf,
					&num,p,q-p);
				if ((k <= 0) && (num == 0) && (ctx->start))
					EVP_DecodeInit(&ctx->base64);
				else 
					{
					if (p != (unsigned char *)
						&(ctx->tmp[0]))
						{
						i-=(p- (unsigned char *)
							&(ctx->tmp[0]));
						for (x=0; x < i; x++)
							ctx->tmp[x]=p[x];
						}
					EVP_DecodeInit(&ctx->base64);
					ctx->start=0;
					break;
					}
				p=q;
				}

			/* we fell off the end without starting */
			if (j == i)
				{
				/* Is this is one long chunk?, if so, keep on
				 * reading until a new line. */
				if (p == (unsigned char *)&(ctx->tmp[0]))
					{
					/* Check buffer full */
					if (i == B64_BLOCK_SIZE)
						{
						ctx->tmp_nl=1;
						ctx->tmp_len=0;
						}
					}
				else if (p != q) /* finished on a '\n' */
					{
					n=q-p;
					for (ii=0; ii<n; ii++)
						ctx->tmp[ii]=p[ii];
					ctx->tmp_len=n;
					}
				/* else finished on a '\n' */
				continue;
				}
			else
				ctx->tmp_len=0;
			}
		/* If buffer isn't full and we can retry then
		 * restart to read in more data.
		 */
		else if ((i < B64_BLOCK_SIZE) && (ctx->cont > 0))
			continue;

		if (BIO_get_flags(b) & BIO_FLAGS_BASE64_NO_NL)
			{
			int z,jj;

			jj=(i>>2)<<2;
			z=EVP_DecodeBlock((unsigned char *)ctx->buf,
				(unsigned char *)ctx->tmp,jj);
			if (jj > 2)
				{
				if (ctx->tmp[jj-1] == '=')
					{
					z--;
					if (ctx->tmp[jj-2] == '=')
						z--;
					}
				}
			/* z is now number of output bytes and jj is the
			 * number consumed */
			if (jj != i)
				{
				memcpy((unsigned char *)ctx->tmp,
					(unsigned char *)&(ctx->tmp[jj]),i-jj);
				ctx->tmp_len=i-jj;
				}
			ctx->buf_len=0;
			if (z > 0)
				{
				ctx->buf_len=z;
				i=1;
				}
			else
				i=z;
			}
		else
			{
Exemplo n.º 15
0
/*++
 * Function:	cmd_authenticate_login
 *
 * Purpose:	implement the AUTHENTICATE LOGIN mechanism
 *
 * Parameters:	ptr to ITD_Struct for client connection.
 *              ptr to client tag
 *
 * Returns:	0 on success prior to authentication
 *              1 on success after authentication (we caught a logout)
 *              -1 on failure	
 *
 * Authors:	Dave McMurtrie <*****@*****.**>
 *
 * Notes:
 *--
 */
static int cmd_authenticate_login( ITD_Struct *Client,
				   char *Tag )
{
    char *fn = "cmd_authenticate_login()";
    char SendBuf[BUFSIZE];
    char Username[MAXUSERNAMELEN];
    char EncodedUsername[BUFSIZE];
    char Password[MAXPASSWDLEN];
    char EncodedPassword[BUFSIZE];
    ICD_Struct *conn;
    int rc;
    ITD_Struct Server;
    int BytesRead;
    struct sockaddr_in cli_addr;
    int addrlen;
    char *hostaddr;
    
    unsigned int BufLen = BUFSIZE - 1;
    memset ( &Server, 0, sizeof Server );
    addrlen = sizeof( struct sockaddr_in );
    
    /*
     * send a base64 encoded username prompt to the client.  Note that we're
     * using our Username and EncodedUsername buffers temporarily here to
     * avoid allocating additional buffers.  Keep this in mind for future
     * code modification...
     */
    snprintf( Username, BufLen, "Username:"******"+ %s\r\n", EncodedUsername );
    
    if ( IMAP_Write( Client->conn, SendBuf, strlen(SendBuf) ) == -1 )
    {
	syslog(LOG_ERR, "%s: Unable to send base64 encoded username prompt to client: %s", fn, strerror(errno) );
	return( -1 );
    }

    /*
     * The response from the client should be a base64 encoded version of the
     * username.
     */
    BytesRead = IMAP_Line_Read( Client );
    
    if ( BytesRead == -1 )
    {
	syslog( LOG_NOTICE, "%s: Failed to read base64 encoded username from client on socket %d", fn, Client->conn->sd );
	return( -1 );
    }
    
    /*
     * Easy, but not perfect sanity check.  If the client sent enough data
     * to fill our entire buffer, we're not even going to bother looking at it.
     */
    if ( Client->MoreData ||
	 BytesRead > BufLen )
    {
	syslog( LOG_NOTICE, "%s: Base64 encoded username sent from client on sd %d is too large.", fn, Client->conn->sd );
	return( -1 );
    }
    
    /*
     * copy BytesRead -2 so we don't include the CRLF.
     */
    memcpy( (void *)EncodedUsername, (const void *)Client->ReadBuf, 
	    BytesRead - 2 );
    
    rc = EVP_DecodeBlock( Username, EncodedUsername, BytesRead - 2 );
    Username[rc] = '\0';
    
    /*
     * Same drill all over again, except this time it's for the password.
     */
    snprintf( Password, BufLen, "Password:"******"+ %s\r\n", EncodedPassword );
    
    if ( IMAP_Write( Client->conn, SendBuf, strlen(SendBuf) ) == -1 )
    {
        syslog(LOG_ERR, "%s: Unable to send base64 encoded password prompt to 
client: %s", fn, strerror(errno) );
        return( -1 );
    }
BST_ERR_ENUM_UINT8  BST_CORE_DencryptChk ( BST_CORE_PID_ENUM_UINT16     enPid,
                                           const BST_VOID              *pvData,
                                           BST_UINT16                   usLen,
                                           BST_VOID                   **ppOutData,
                                           BST_UINT16                  *pusOutLen )
{
    BST_ERR_ENUM_UINT8                  enRet;
    BST_UINT32                          ulInLen;
    BST_UINT32                          ulOutLen;
    BST_UINT32                          ulBase64DataLen;
    BST_UINT8                          *pucIn;
    BST_UINT8                          *pucOut;
    BST_UINT8                          *pucBase64Data;
    ulInLen                             = 0;
    ulOutLen                            = 0;
    ulBase64DataLen                     = 0;
    pucIn                               = BST_NULL_PTR;
    pucOut                              = BST_NULL_PTR;
    pucBase64Data                       = BST_NULL_PTR;
    enRet                               = BST_NO_ERROR_MSG;

    if ( ( BST_NULL_PTR == pvData )
      || ( BST_NULL_PTR == pusOutLen )
      || ( BST_NULL_PTR == ppOutData) )
    {
        return BST_ERR_INVALID_PTR;
    }

    if ( 0 == usLen )
    {
        return BST_ERR_PAR_LEN;
    }

    if ( CheckIfEcryOrDecry ( enPid ) )
    {
        pucIn = ( BST_UINT8 * )BST_OS_MALLOC ( usLen );

        if ( BST_NULL_PTR == pucIn )
        {
            return BST_ERR_NO_MEMORY;
        }

        BST_OS_MEMCPY ( pucIn, pvData, usLen );
        ulInLen = usLen;

        pucBase64Data = ( BST_UINT8 * )BST_OS_MALLOC ( ulInLen );

        if ( BST_NULL_PTR == pucBase64Data )
        {
            BST_OS_FREE ( pucIn );
            pucIn = BST_NULL_PTR;
            return BST_ERR_NO_MEMORY;
        }

        ulBase64DataLen = EVP_DecodeBlock ( pucBase64Data, pucIn, ulInLen );

        while ( pucIn[--ulInLen] == '=' ) // Ecrypter string end is '='
        {
            ulBase64DataLen--;
        }

        pucOut = ( BST_UINT8 * )BST_OS_MALLOC ( ulInLen );

        if ( BST_NULL_PTR == pucOut )
        {
            BST_OS_FREE ( pucIn );
            pucIn = BST_NULL_PTR;
            BST_OS_FREE ( pucBase64Data );
            pucBase64Data = BST_NULL_PTR;
            return BST_ERR_NO_MEMORY;
        }

        BST_OS_MEMSET ( pucOut, 0, ulInLen );

        enRet = DecryptInternal ( pucBase64Data,
                                  ulBase64DataLen,
                                  pucOut,
                                 &ulOutLen,
                                  gs_BastetDsppKey );

        if ( BST_NO_ERROR_MSG == enRet )
        {
            *ppOutData = ( BST_VOID * )pucOut;
            *pusOutLen = ( BST_UINT16 )ulOutLen;
        }

        BST_OS_FREE ( pucIn );
        pucIn = BST_NULL_PTR;
        BST_OS_FREE ( pucBase64Data );
        pucBase64Data = BST_NULL_PTR;

        return enRet;
    }

    return BST_NO_ERROR_MSG;
}
Exemplo n.º 17
0
static int b64_read(BIO *b, char *out, int outl) {
  int ret = 0, i, ii, j, k, x, n, num, ret_code = 0;
  BIO_B64_CTX *ctx;
  uint8_t *p, *q;

  if (out == NULL) {
    return 0;
  }
  ctx = (BIO_B64_CTX *) b->ptr;

  if (ctx == NULL || b->next_bio == NULL) {
    return 0;
  }

  BIO_clear_retry_flags(b);

  if (ctx->encode != B64_DECODE) {
    ctx->encode = B64_DECODE;
    ctx->buf_len = 0;
    ctx->buf_off = 0;
    ctx->tmp_len = 0;
    EVP_DecodeInit(&ctx->base64);
  }

  // First check if there are bytes decoded/encoded
  if (ctx->buf_len > 0) {
    assert(ctx->buf_len >= ctx->buf_off);
    i = ctx->buf_len - ctx->buf_off;
    if (i > outl) {
      i = outl;
    }
    assert(ctx->buf_off + i < (int)sizeof(ctx->buf));
    OPENSSL_memcpy(out, &ctx->buf[ctx->buf_off], i);
    ret = i;
    out += i;
    outl -= i;
    ctx->buf_off += i;
    if (ctx->buf_len == ctx->buf_off) {
      ctx->buf_len = 0;
      ctx->buf_off = 0;
    }
  }

  // At this point, we have room of outl bytes and an empty buffer, so we
  // should read in some more.

  ret_code = 0;
  while (outl > 0) {
    if (ctx->cont <= 0) {
      break;
    }

    i = BIO_read(b->next_bio, &(ctx->tmp[ctx->tmp_len]),
                 B64_BLOCK_SIZE - ctx->tmp_len);

    if (i <= 0) {
      ret_code = i;

      // Should we continue next time we are called?
      if (!BIO_should_retry(b->next_bio)) {
        ctx->cont = i;
        // If buffer empty break
        if (ctx->tmp_len == 0) {
          break;
        } else {
          // Fall through and process what we have
          i = 0;
        }
      } else {
        // else we retry and add more data to buffer
        break;
      }
    }
    i += ctx->tmp_len;
    ctx->tmp_len = i;

    // We need to scan, a line at a time until we have a valid line if we are
    // starting.
    if (ctx->start && (BIO_test_flags(b, BIO_FLAGS_BASE64_NO_NL))) {
      // ctx->start = 1;
      ctx->tmp_len = 0;
    } else if (ctx->start) {
      q = p = (uint8_t *)ctx->tmp;
      num = 0;
      for (j = 0; j < i; j++) {
        if (*(q++) != '\n') {
          continue;
        }

        // due to a previous very long line, we need to keep on scanning for a
        // '\n' before we even start looking for base64 encoded stuff.
        if (ctx->tmp_nl) {
          p = q;
          ctx->tmp_nl = 0;
          continue;
        }

        k = EVP_DecodeUpdate(&(ctx->base64), (uint8_t *)ctx->buf, &num, p,
                             q - p);

        if (k <= 0 && num == 0 && ctx->start) {
          EVP_DecodeInit(&ctx->base64);
        } else {
          if (p != (uint8_t *)&(ctx->tmp[0])) {
            i -= (p - (uint8_t *)&(ctx->tmp[0]));
            for (x = 0; x < i; x++) {
              ctx->tmp[x] = p[x];
            }
          }
          EVP_DecodeInit(&ctx->base64);
          ctx->start = 0;
          break;
        }
        p = q;
      }

      // we fell off the end without starting
      if (j == i && num == 0) {
        // Is this is one long chunk?, if so, keep on reading until a new
        // line.
        if (p == (uint8_t *)&(ctx->tmp[0])) {
          // Check buffer full
          if (i == B64_BLOCK_SIZE) {
            ctx->tmp_nl = 1;
            ctx->tmp_len = 0;
          }
        } else if (p != q) {  // finished on a '\n'
          n = q - p;
          for (ii = 0; ii < n; ii++) {
            ctx->tmp[ii] = p[ii];
          }
          ctx->tmp_len = n;
        }
        // else finished on a '\n'
        continue;
      } else {
        ctx->tmp_len = 0;
      }
    } else if (i < B64_BLOCK_SIZE && ctx->cont > 0) {
      // If buffer isn't full and we can retry then restart to read in more
      // data.
      continue;
    }

    if (BIO_test_flags(b, BIO_FLAGS_BASE64_NO_NL)) {
      int z, jj;

      jj = i & ~3;  // process per 4
      z = EVP_DecodeBlock((uint8_t *)ctx->buf, (uint8_t *)ctx->tmp, jj);
      if (jj > 2) {
        if (ctx->tmp[jj - 1] == '=') {
          z--;
          if (ctx->tmp[jj - 2] == '=') {
            z--;
          }
        }
      }
      // z is now number of output bytes and jj is the number consumed.
      if (jj != i) {
        OPENSSL_memmove(ctx->tmp, &ctx->tmp[jj], i - jj);
        ctx->tmp_len = i - jj;
      }
      ctx->buf_len = 0;
      if (z > 0) {
        ctx->buf_len = z;
      }
      i = z;
    } else {
      i = EVP_DecodeUpdate(&(ctx->base64), (uint8_t *)ctx->buf,
                           &ctx->buf_len, (uint8_t *)ctx->tmp, i);
      ctx->tmp_len = 0;
    }
    ctx->buf_off = 0;
    if (i < 0) {
      ret_code = 0;
      ctx->buf_len = 0;
      break;
    }

    if (ctx->buf_len <= outl) {
      i = ctx->buf_len;
    } else {
      i = outl;
    }

    OPENSSL_memcpy(out, ctx->buf, i);
    ret += i;
    ctx->buf_off = i;
    if (ctx->buf_off == ctx->buf_len) {
      ctx->buf_len = 0;
      ctx->buf_off = 0;
    }
    outl -= i;
    out += i;
  }

  BIO_copy_next_retry(b);
  return ret == 0 ? ret_code : ret;
}
Exemplo n.º 18
0
static int b64_read(BIO *b, char *out, int outl)
{
    int ret = 0, i, ii, j, k, x, n, num, ret_code = 0;
    BIO_B64_CTX *ctx;
    unsigned char *p, *q;
    BIO *next;

    if (out == NULL)
        return 0;
    ctx = (BIO_B64_CTX *)BIO_get_data(b);

    next = BIO_next(b);
    if ((ctx == NULL) || (next == NULL))
        return 0;

    BIO_clear_retry_flags(b);

    if (ctx->encode != B64_DECODE) {
        ctx->encode = B64_DECODE;
        ctx->buf_len = 0;
        ctx->buf_off = 0;
        ctx->tmp_len = 0;
        EVP_DecodeInit(ctx->base64);
    }

    /* First check if there are bytes decoded/encoded */
    if (ctx->buf_len > 0) {
        OPENSSL_assert(ctx->buf_len >= ctx->buf_off);
        i = ctx->buf_len - ctx->buf_off;
        if (i > outl)
            i = outl;
        OPENSSL_assert(ctx->buf_off + i < (int)sizeof(ctx->buf));
        memcpy(out, &(ctx->buf[ctx->buf_off]), i);
        ret = i;
        out += i;
        outl -= i;
        ctx->buf_off += i;
        if (ctx->buf_len == ctx->buf_off) {
            ctx->buf_len = 0;
            ctx->buf_off = 0;
        }
    }

    /*
     * At this point, we have room of outl bytes and an empty buffer, so we
     * should read in some more.
     */

    ret_code = 0;
    while (outl > 0) {
        if (ctx->cont <= 0)
            break;

        i = BIO_read(next, &(ctx->tmp[ctx->tmp_len]),
                     B64_BLOCK_SIZE - ctx->tmp_len);

        if (i <= 0) {
            ret_code = i;

            /* Should we continue next time we are called? */
            if (!BIO_should_retry(next)) {
                ctx->cont = i;
                /* If buffer empty break */
                if (ctx->tmp_len == 0)
                    break;
                /* Fall through and process what we have */
                else
                    i = 0;
            }
            /* else we retry and add more data to buffer */
            else
                break;
        }
        i += ctx->tmp_len;
        ctx->tmp_len = i;

        /*
         * We need to scan, a line at a time until we have a valid line if we
         * are starting.
         */
        if (ctx->start && (BIO_get_flags(b) & BIO_FLAGS_BASE64_NO_NL)) {
            /* ctx->start=1; */
            ctx->tmp_len = 0;
        } else if (ctx->start) {
            q = p = (unsigned char *)ctx->tmp;
            num = 0;
            for (j = 0; j < i; j++) {
                if (*(q++) != '\n')
                    continue;

                /*
                 * due to a previous very long line, we need to keep on
                 * scanning for a '\n' before we even start looking for
                 * base64 encoded stuff.
                 */
                if (ctx->tmp_nl) {
                    p = q;
                    ctx->tmp_nl = 0;
                    continue;
                }

                k = EVP_DecodeUpdate(ctx->base64,
                                     (unsigned char *)ctx->buf,
                                     &num, p, q - p);
                if ((k <= 0) && (num == 0) && (ctx->start))
                    EVP_DecodeInit(ctx->base64);
                else {
                    if (p != (unsigned char *)
                        &(ctx->tmp[0])) {
                        i -= (p - (unsigned char *)
                              &(ctx->tmp[0]));
                        for (x = 0; x < i; x++)
                            ctx->tmp[x] = p[x];
                    }
                    EVP_DecodeInit(ctx->base64);
                    ctx->start = 0;
                    break;
                }
                p = q;
            }

            /* we fell off the end without starting */
            if ((j == i) && (num == 0)) {
                /*
                 * Is this is one long chunk?, if so, keep on reading until a
                 * new line.
                 */
                if (p == (unsigned char *)&(ctx->tmp[0])) {
                    /* Check buffer full */
                    if (i == B64_BLOCK_SIZE) {
                        ctx->tmp_nl = 1;
                        ctx->tmp_len = 0;
                    }
                } else if (p != q) { /* finished on a '\n' */
                    n = q - p;
                    for (ii = 0; ii < n; ii++)
                        ctx->tmp[ii] = p[ii];
                    ctx->tmp_len = n;
                }
                /* else finished on a '\n' */
                continue;
            } else {
                ctx->tmp_len = 0;
            }
        } else if ((i < B64_BLOCK_SIZE) && (ctx->cont > 0)) {
            /*
             * If buffer isn't full and we can retry then restart to read in
             * more data.
             */
            continue;
        }

        if (BIO_get_flags(b) & BIO_FLAGS_BASE64_NO_NL) {
            int z, jj;

            jj = i & ~3;        /* process per 4 */
            z = EVP_DecodeBlock((unsigned char *)ctx->buf,
                                (unsigned char *)ctx->tmp, jj);
            if (jj > 2) {
                if (ctx->tmp[jj - 1] == '=') {
                    z--;
                    if (ctx->tmp[jj - 2] == '=')
                        z--;
                }
            }
            /*
             * z is now number of output bytes and jj is the number consumed
             */
            if (jj != i) {
                memmove(ctx->tmp, &ctx->tmp[jj], i - jj);
                ctx->tmp_len = i - jj;
            }
            ctx->buf_len = 0;
            if (z > 0) {
                ctx->buf_len = z;
            }
            i = z;
        } else {
            i = EVP_DecodeUpdate(ctx->base64,
                                 (unsigned char *)ctx->buf, &ctx->buf_len,
                                 (unsigned char *)ctx->tmp, i);
            ctx->tmp_len = 0;
        }
        /*
         * If eof or an error was signalled, then the condition
         * 'ctx->cont <= 0' will prevent b64_read() from reading
         * more data on subsequent calls. This assignment was
         * deleted accidentally in commit 5562cfaca4f3.
         */
        ctx->cont = i;

        ctx->buf_off = 0;
        if (i < 0) {
            ret_code = 0;
            ctx->buf_len = 0;
            break;
        }

        if (ctx->buf_len <= outl)
            i = ctx->buf_len;
        else
            i = outl;

        memcpy(out, ctx->buf, i);
        ret += i;
        ctx->buf_off = i;
        if (ctx->buf_off == ctx->buf_len) {
            ctx->buf_len = 0;
            ctx->buf_off = 0;
        }
        outl -= i;
        out += i;
    }
    /* BIO_clear_retry_flags(b); */
    BIO_copy_next_retry(b);
    return ((ret == 0) ? ret_code : ret);
}