BIGNUM * OpenSSLCryptoBase64::b642BN(char * b64in, unsigned int len) {

	if (len > 1024)
		return NULL;

	int bufLen;
	unsigned char buf[1024];

	EVP_ENCODE_CTX m_dctx;
	EVP_DecodeInit(&m_dctx);
	int rc = EVP_DecodeUpdate(&m_dctx, 
						  buf, 
						  &bufLen, 
						  (unsigned char *) b64in, 
						  len);

	if (rc < 0) {

		throw XSECCryptoException(XSECCryptoException::Base64Error,
			"OpenSSL:Base64 - Error during Base64 Decode of BIGNUMS");
	}

	int finalLen;
	EVP_DecodeFinal(&m_dctx, &buf[bufLen], &finalLen); 

	bufLen += finalLen;

	// Now translate to a bignum
	return BN_dup(BN_bin2bn(buf, bufLen, NULL));

}
Example #2
0
int _ldapfull_base64_decode( const char *src, char **ret, int *rlen ) {
    unsigned int rc, i, tlen = 0;
    char *text;
    EVP_ENCODE_CTX EVP_ctx;

    text = (char *)malloc(((strlen(src)+3)/4 * 3) + 1);
    if (text == NULL) {
        return 0;
    }

    EVP_DecodeInit(&EVP_ctx);
    rc = EVP_DecodeUpdate(&EVP_ctx, text, &i, (char *)src, strlen(src));
    if (rc < 0) {
        free(text);
        return 0;
    }
    tlen+=i;
    EVP_DecodeFinal(&EVP_ctx, text, &i); 

    *ret = text;
    if (rlen != NULL) {
        *rlen = tlen;
    }

    return 1;
}
Example #3
0
int main(void)
{
	int i, len, total = 0, total2 = 0, ret;
	EVP_ENCODE_CTX ctx1, ctx2;
	unsigned char f[60];
	unsigned char t[80 + 1];
	for(i = 0; i < 60; i++)
	{
	  memset(&f[i], i, 1);	
	}
	EVP_EncodeInit(&ctx1);
	EVP_EncodeUpdate(&ctx1, t, &len, f, 60);
	total += len;
	printf("total = %d\n", total);
//	printf("%s\n", t);
	EVP_EncodeFinal(&ctx1, t + total, &len);
	total += len;
	printf("%total = %d\n", total);
	printf("%s\n", t);
	EVP_DecodeInit(&ctx2);
	ret = EVP_DecodeUpdate(&ctx2, f, &len, t, total);
	total2 += len;
	ret = EVP_DecodeFinal(&ctx2, f, &len);
	total2 += len;
	for(i = 0; i < total2; i++)
	{
		printf("%02x\t", f[i]);
	}
printf("\n");
	return 0;
}
Example #4
0
int32_t cm_base_64_decode(unsigned char *pIn, int32_t iInlen,unsigned char *pOut, int32_t *pOutlen)
{
  EVP_ENCODE_CTX ctx;

  EVP_DecodeInit(&ctx);

  if(EVP_DecodeUpdate(&ctx,pOut,pOutlen,pIn,iInlen)<0)
    return OF_FAILURE;
  if(EVP_DecodeFinal(&ctx,pOut,pOutlen)<0)
   return OF_FAILURE;

  return OF_SUCCESS; 
}
Example #5
0
/***********************
    Decode
************************/
int mite_base64_2_string(char *base64,int inlen,char **ppout)
{
    EVP_ENCODE_CTX dctx;
    EVP_DecodeInit(&dctx);
    int outlen = 0;
    int total = 0;
    int ret = 0;
    char *out = malloc(inlen);
    ret = EVP_DecodeUpdate(&dctx,out,&outlen,base64,inlen);
    if(ret < 0)
    {
        printf("EVP_DecodeUpdate err!\n");
        return -1;
    }
    total+=outlen;
    ret = EVP_DecodeFinal(&dctx,out,&outlen);
    total += outlen;
    *ppout=out;
    return total;
}
Example #6
0
void openssl_evp_encode()
{
	FILE *fin, *fout;
	int inLen, outLen;
	EVP_ENCODE_CTX ctx;
	unsigned char ins[MAX1_LEN], outs[MAX2_LEN];

	fin = fopen("/tmp/test.dat", "rb");
	fout = fopen("/tmp/test.txt", "w");
	memset(ins, 0, sizeof(ins));
	memset(outs, 0, sizeof(outs));
	printf("\nEVP_Encode(/tmp/test.dat) = ");
	EVP_EncodeInit(&ctx);
	while ((inLen = fread(ins, 1, MAX1_LEN, fin)) > 0) {
		EVP_EncodeUpdate(&ctx, outs, &outLen, ins, inLen);
		fwrite(outs, 1, outLen, fout);
		printf("%s", outs);
	}
	EVP_EncodeFinal(&ctx, outs, &outLen);
	fwrite(outs, 1, outLen, fout);
	printf("%s", outs);
	fclose(fin);
	fclose(fout);

	fin = fopen("/tmp/test.txt", "r");
	fout = fopen("/tmp/test-1.dat", "wb");
	memset(ins, 0, sizeof(ins));
	memset(outs, 0, sizeof(outs));
	printf("\nEVP_Decode(/tmp/test.txt) = ");
	EVP_DecodeInit(&ctx);
	while ((inLen = fread(ins, 1, MAX1_LEN, fin)) > 0) {
		EVP_DecodeUpdate(&ctx, outs, &outLen, ins, inLen);
		fwrite(outs, 1, outLen, fout);
		printf("%s", outs);
	}
	EVP_DecodeFinal(&ctx, outs, &outLen);
	fwrite(outs, 1, outLen, fout);
	printf("%s\n", outs);
	fclose(fin);
	fclose(fout);
}
Example #7
0
/* {{{ php_crypto_base64_decode_update */
static inline int php_crypto_base64_decode_update(
		EVP_ENCODE_CTX *ctx, char *out, int *outl,
		const char *in, phpc_str_size_t in_len TSRMLS_DC)
{
	int inl, rc;

	/* check string length overflow */
	if (php_crypto_str_size_to_int(in_len, &inl) == FAILURE) {
		php_crypto_error(PHP_CRYPTO_ERROR_ARGS(Base64, INPUT_DATA_LENGTH_HIGH));
		return FAILURE;
	}

	rc = EVP_DecodeUpdate(ctx,
			(unsigned char *) out, outl,
			(const unsigned char *) in, inl);
	if (rc < 0) {
		php_crypto_error(PHP_CRYPTO_ERROR_ARGS(Base64, DECODE_UPDATE_FAILED));
		return FAILURE;
	}

	return SUCCESS;
}
unsigned int OpenSSLCryptoBase64::decode(unsigned char * inData, 
						 	    unsigned int inLength,
								unsigned char * outData,
								unsigned int outLength) {

	int rc;
	int outLen;

	if (outLength < inLength) {

		throw XSECCryptoException(XSECCryptoException::MemoryError,
			"OpenSSL:Base64 - Output buffer not big enough for Base64 decode");

	}

	rc = EVP_DecodeUpdate(&m_dctx, 
						  outData, 
						  &outLen, 
						  inData, 
						  inLength);

	if (rc < 0) {

		throw XSECCryptoException(XSECCryptoException::Base64Error,
			"OpenSSL:Base64 - Error during Base64 Decode");
	}

	if (outLen > (int) outLength) {

		throw XSECCryptoException(XSECCryptoException::MemoryError,
			"OpenSSL:Base64 - Output buffer not big enough for Base64 decode and overflowed");

	}
		
	return outLen;

}
Example #9
0
static void mime_get(byte_string_t bs, FILE *infp)
{
    char line[crypt_buf_size];
    int l, l2;
    EVP_ENCODE_CTX mime;

    byte_string_init(bs, 1024);
    EVP_DecodeInit(&mime);
    l = 0;

    for (;;) {
	fgets(line, crypt_buf_size, infp);
	if (feof(infp)) break;
	//break on blank line = "\n" or "\r\n"
	if (strlen(line) <= 2) break;
	EVP_DecodeUpdate(&mime, &bs->data[l], &l2, (unsigned char *) line, strlen(line));
	l += l2;
	if (bs->len - l < crypt_buf_size) {
	    byte_string_reinit(bs, bs->len * 2);
	}
    }
    EVP_DecodeFinal(&mime, &bs->data[l], &l2);
    byte_string_reinit(bs, l + l2);
}
Example #10
0
/**
 * Read in PEM-formatted data from the given BIO.
 *
 * By nature of the PEM format, all content must be printable ASCII (except
 * for line endings).  Other characters are malformed input and will be rejected.
 */
int PEM_read_bio_ex(BIO *bp, char **name_out, char **header,
                    unsigned char **data, long *len_out, unsigned int flags)
{
    EVP_ENCODE_CTX *ctx = EVP_ENCODE_CTX_new();
    const BIO_METHOD *bmeth;
    BIO *headerB = NULL, *dataB = NULL;
    char *name = NULL;
    int len, taillen, headerlen, ret = 0;
    BUF_MEM * buf_mem;

    if (ctx == NULL) {
        PEMerr(PEM_F_PEM_READ_BIO_EX, ERR_R_MALLOC_FAILURE);
        return 0;
    }

    *len_out = 0;
    *name_out = *header = NULL;
    *data = NULL;
    if ((flags & PEM_FLAG_EAY_COMPATIBLE) && (flags & PEM_FLAG_ONLY_B64)) {
        /* These two are mutually incompatible; bail out. */
        PEMerr(PEM_F_PEM_READ_BIO_EX, ERR_R_PASSED_INVALID_ARGUMENT);
        goto end;
    }
    bmeth = (flags & PEM_FLAG_SECURE) ? BIO_s_secmem() : BIO_s_mem();

    headerB = BIO_new(bmeth);
    dataB = BIO_new(bmeth);
    if (headerB == NULL || dataB == NULL) {
        PEMerr(PEM_F_PEM_READ_BIO_EX, ERR_R_MALLOC_FAILURE);
        goto end;
    }

    if (!get_name(bp, &name, flags))
        goto end;
    if (!get_header_and_data(bp, &headerB, &dataB, name, flags))
        goto end;

    EVP_DecodeInit(ctx);
    BIO_get_mem_ptr(dataB, &buf_mem);
    len = buf_mem->length;
    if (EVP_DecodeUpdate(ctx, (unsigned char*)buf_mem->data, &len,
                         (unsigned char*)buf_mem->data, len) < 0
            || EVP_DecodeFinal(ctx, (unsigned char*)&(buf_mem->data[len]),
                               &taillen) < 0) {
        PEMerr(PEM_F_PEM_READ_BIO_EX, PEM_R_BAD_BASE64_DECODE);
        goto end;
    }
    len += taillen;
    buf_mem->length = len;

    /* There was no data in the PEM file; avoid malloc(0). */
    if (len == 0)
        goto end;
    headerlen = BIO_get_mem_data(headerB, NULL);
    *header = pem_malloc(headerlen + 1, flags);
    *data = pem_malloc(len, flags);
    if (*header == NULL || *data == NULL) {
        pem_free(*header, flags, 0);
        pem_free(*data, flags, 0);
        goto end;
    }
    BIO_read(headerB, *header, headerlen);
    (*header)[headerlen] = '\0';
    BIO_read(dataB, *data, len);
    *len_out = len;
    *name_out = name;
    name = NULL;
    ret = 1;

end:
    EVP_ENCODE_CTX_free(ctx);
    pem_free(name, flags, 0);
    BIO_free(headerB);
    BIO_free(dataB);
    return ret;
}
Example #11
0
int PEM_read_bio(BIO *bp, char **name, char **header, unsigned char **data,
       long *len)
  {
  EVP_ENCODE_CTX ctx;
  int end=0,i,k,bl=0,hl=0,nohead=0;
  char buf[256];
  BUF_MEM *nameB;
  BUF_MEM *headerB;
  BUF_MEM *dataB,*tmpB;
  
  nameB=BUF_MEM_new();
  headerB=BUF_MEM_new();
  dataB=BUF_MEM_new();
  if ((nameB == NULL) || (headerB == NULL) || (dataB == NULL))
    {
    BUF_MEM_free(nameB);
    BUF_MEM_free(headerB);
    BUF_MEM_free(dataB);
    PEMerr(PEM_F_PEM_READ_BIO,ERR_R_MALLOC_FAILURE);
    return(0);
    }

  buf[254]='\0';
  for (;;)
    {
    i=BIO_gets(bp,buf,254);

    if (i <= 0)
      {
      PEMerr(PEM_F_PEM_READ_BIO,PEM_R_NO_START_LINE);
      goto err;
      }

    while ((i >= 0) && (buf[i] <= ' ')) i--;
    buf[++i]='\n'; buf[++i]='\0';

    if (strncmp(buf,"-----BEGIN ",11) == 0)
      {
      i=strlen(&(buf[11]));

      if (strncmp(&(buf[11+i-6]),"-----\n",6) != 0)
        continue;
      if (!BUF_MEM_grow(nameB,i+9))
        {
        PEMerr(PEM_F_PEM_READ_BIO,ERR_R_MALLOC_FAILURE);
        goto err;
        }
      memcpy(nameB->data,&(buf[11]),i-6);
      nameB->data[i-6]='\0';
      break;
      }
    }
  hl=0;
  if (!BUF_MEM_grow(headerB,256))
    { PEMerr(PEM_F_PEM_READ_BIO,ERR_R_MALLOC_FAILURE); goto err; }
  headerB->data[0]='\0';
  for (;;)
    {
    i=BIO_gets(bp,buf,254);
    if (i <= 0) break;

    while ((i >= 0) && (buf[i] <= ' ')) i--;
    buf[++i]='\n'; buf[++i]='\0';

    if (buf[0] == '\n') break;
    if (!BUF_MEM_grow(headerB,hl+i+9))
      { PEMerr(PEM_F_PEM_READ_BIO,ERR_R_MALLOC_FAILURE); goto err; }
    if (strncmp(buf,"-----END ",9) == 0)
      {
      nohead=1;
      break;
      }
    memcpy(&(headerB->data[hl]),buf,i);
    headerB->data[hl+i]='\0';
    hl+=i;
    }

  bl=0;
  if (!BUF_MEM_grow(dataB,1024))
    { PEMerr(PEM_F_PEM_READ_BIO,ERR_R_MALLOC_FAILURE); goto err; }
  dataB->data[0]='\0';
  if (!nohead)
    {
    for (;;)
      {
      i=BIO_gets(bp,buf,254);
      if (i <= 0) break;

      while ((i >= 0) && (buf[i] <= ' ')) i--;
      buf[++i]='\n'; buf[++i]='\0';

      if (i != 65) end=1;
      if (strncmp(buf,"-----END ",9) == 0)
        break;
      if (i > 65) break;
      if (!BUF_MEM_grow_clean(dataB,i+bl+9))
        {
        PEMerr(PEM_F_PEM_READ_BIO,ERR_R_MALLOC_FAILURE);
        goto err;
        }
      memcpy(&(dataB->data[bl]),buf,i);
      dataB->data[bl+i]='\0';
      bl+=i;
      if (end)
        {
        buf[0]='\0';
        i=BIO_gets(bp,buf,254);
        if (i <= 0) break;

        while ((i >= 0) && (buf[i] <= ' ')) i--;
        buf[++i]='\n'; buf[++i]='\0';

        break;
        }
      }
    }
  else
    {
    tmpB=headerB;
    headerB=dataB;
    dataB=tmpB;
    bl=hl;
    }
  i=strlen(nameB->data);
  if (  (strncmp(buf,"-----END ",9) != 0) ||
    (strncmp(nameB->data,&(buf[9]),i) != 0) ||
    (strncmp(&(buf[9+i]),"-----\n",6) != 0))
    {
    PEMerr(PEM_F_PEM_READ_BIO,PEM_R_BAD_END_LINE);
    goto err;
    }

  EVP_DecodeInit(&ctx);
  i=EVP_DecodeUpdate(&ctx,
    (unsigned char *)dataB->data,&bl,
    (unsigned char *)dataB->data,bl);
  if (i < 0)
    {
    PEMerr(PEM_F_PEM_READ_BIO,PEM_R_BAD_BASE64_DECODE);
    goto err;
    }
  i=EVP_DecodeFinal(&ctx,(unsigned char *)&(dataB->data[bl]),&k);
  if (i < 0)
    {
    PEMerr(PEM_F_PEM_READ_BIO,PEM_R_BAD_BASE64_DECODE);
    goto err;
    }
  bl+=k;

  if (bl == 0) goto err;
  *name=nameB->data;
  *header=headerB->data;
  *data=(unsigned char *)dataB->data;
  *len=bl;
  OPENSSL_free(nameB);
  OPENSSL_free(headerB);
  OPENSSL_free(dataB);
  return(1);
err:
  BUF_MEM_free(nameB);
  BUF_MEM_free(headerB);
  BUF_MEM_free(dataB);
  return(0);
  }
Example #12
0
					(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
			{
			i=EVP_DecodeUpdate(&(ctx->base64),
				(unsigned char *)ctx->buf,&ctx->buf_len,
				(unsigned char *)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;
Example #13
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
			{
bool OpenSSLCryptoKeyDSA::verifyBase64Signature(unsigned char * hashBuf, 
								 unsigned int hashLen,
								 char * base64Signature,
								 unsigned int sigLen) {

	// Use the currently loaded key to validate the Base64 encoded signature

	if (mp_dsaKey == NULL) {

		throw XSECCryptoException(XSECCryptoException::DSAError,
			"OpenSSL:DSA - Attempt to validate signature with empty key");
	}

	unsigned char sigVal[512];
	int sigValLen;
	int err;


	/*
	BIO * b64 = BIO_new(BIO_f_base64());
	BIO * bmem = BIO_new(BIO_s_mem());

	BIO_set_mem_eof_return(bmem, 0);
	b64 = BIO_push(b64, bmem);

	// Translate signature from Base64

	BIO_write(bmem, base64Signature, sigLen);
	sigValLen = BIO_read(b64, sigVal, 512);

  */

	EVP_ENCODE_CTX m_dctx;
	int rc;

	EVP_DecodeInit(&m_dctx);
	rc = EVP_DecodeUpdate(&m_dctx, 
						  sigVal, 
						  &sigValLen, 
						  (unsigned char *) base64Signature, 
						  sigLen);

	if (rc < 0) {

		throw XSECCryptoException(XSECCryptoException::DSAError,
			"OpenSSL:DSA - Error during Base64 Decode");
	}
	int t = 0;

	EVP_DecodeFinal(&m_dctx, &sigVal[sigValLen], &t); 

	sigValLen += t;

	if (sigValLen != 40) {

		throw XSECCryptoException(XSECCryptoException::DSAError,
			"OpenSSL:DSA - Signature Length incorrect");
	}

	// Translate to BNs and thence to DSA_SIG
	BIGNUM * R = BN_bin2bn(sigVal, 20, NULL);
	BIGNUM * S = BN_bin2bn(&sigVal[20], 20, NULL);

	DSA_SIG * dsa_sig = DSA_SIG_new();

	dsa_sig->r = BN_dup(R);
	dsa_sig->s = BN_dup(S);

	unsigned char sigValTranslatedBuf[256];
	unsigned char * sigValTranslated = sigValTranslatedBuf;
	int sigValTranslatedLen;

	sigValTranslatedLen = i2d_DSA_SIG(dsa_sig, &sigValTranslated);

	// Now we have a signature and a key - lets check
	
	err = DSA_do_verify(hashBuf, hashLen, dsa_sig, mp_dsaKey);

	DSA_SIG_free(dsa_sig);

	if (err < 0) {

		throw XSECCryptoException(XSECCryptoException::DSAError,
			"OpenSSL:DSA - Error validating signature");
	}

	return (err == 1);

}
Example #15
0
/*
 * Convert a base64 string into raw byte array representation.
 * Returns the length of the decoded data, or -1 on error.
 */
static int t_fromb64(unsigned char *a, size_t alen, const char *src)
{
    EVP_ENCODE_CTX *ctx;
    int outl = 0, outl2 = 0;
    size_t size, padsize;
    const unsigned char *pad = (const unsigned char *)"00";

    while (*src == ' ' || *src == '\t' || *src == '\n')
        ++src;
    size = strlen(src);
    padsize = 4 - (size & 3);
    padsize &= 3;

    /* Four bytes in src become three bytes output. */
    if (size > INT_MAX || ((size + padsize) / 4) * 3 > alen)
        return -1;

    ctx = EVP_ENCODE_CTX_new();
    if (ctx == NULL)
        return -1;

    /*
     * This should never occur because 1 byte of data always requires 2 bytes of
     * encoding, i.e.
     *  0 bytes unencoded = 0 bytes encoded
     *  1 byte unencoded  = 2 bytes encoded
     *  2 bytes unencoded = 3 bytes encoded
     *  3 bytes unencoded = 4 bytes encoded
     *  4 bytes unencoded = 6 bytes encoded
     *  etc
     */
    if (padsize == 3) {
        outl = -1;
        goto err;
    }

    /* Valid padsize values are now 0, 1 or 2 */

    EVP_DecodeInit(ctx);
    evp_encode_ctx_set_flags(ctx, EVP_ENCODE_CTX_USE_SRP_ALPHABET);

    /* Add any encoded padding that is required */
    if (padsize != 0
            && EVP_DecodeUpdate(ctx, a, &outl, pad, padsize) < 0) {
        outl = -1;
        goto err;
    }
    if (EVP_DecodeUpdate(ctx, a, &outl2, (const unsigned char *)src, size) < 0) {
        outl = -1;
        goto err;
    }
    outl += outl2;
    EVP_DecodeFinal(ctx, a + outl, &outl2);
    outl += outl2;

    /* Strip off the leading padding */
    if (padsize != 0) {
        if ((int)padsize >= outl) {
            outl = -1;
            goto err;
        }

        /*
         * If we added 1 byte of padding prior to encoding then we have 2 bytes
         * of "real" data which gets spread across 4 encoded bytes like this:
         *   (6 bits pad)(2 bits pad | 4 bits data)(6 bits data)(6 bits data)
         * So 1 byte of pre-encoding padding results in 1 full byte of encoded
         * padding.
         * If we added 2 bytes of padding prior to encoding this gets encoded
         * as:
         *   (6 bits pad)(6 bits pad)(4 bits pad | 2 bits data)(6 bits data)
         * So 2 bytes of pre-encoding padding results in 2 full bytes of encoded
         * padding, i.e. we have to strip the same number of bytes of padding
         * from the encoded data as we added to the pre-encoded data.
         */
        memmove(a, a + padsize, outl - padsize);
        outl -= padsize;
    }

 err:
    EVP_ENCODE_CTX_free(ctx);

    return outl;
}
Example #16
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);
}
Example #17
0
bool OpenSSLCryptoKeyRSA::verifySHA1PKCS1Base64Signature(const unsigned char * hashBuf,
								 unsigned int hashLen,
								 const char * base64Signature,
								 unsigned int sigLen,
								 hashMethod hm = HASH_SHA1) {

	// Use the currently loaded key to validate the Base64 encoded signature

	if (mp_rsaKey == NULL) {

		throw XSECCryptoException(XSECCryptoException::RSAError,
			"OpenSSL:RSA - Attempt to validate signature with empty key");
	}

	char* cleanedBase64Signature;
	unsigned int cleanedBase64SignatureLen = 0;

	cleanedBase64Signature =
		XSECCryptoBase64::cleanBuffer(base64Signature, sigLen, cleanedBase64SignatureLen);
	ArrayJanitor<char> j_cleanedBase64Signature(cleanedBase64Signature);

	int sigValLen;
	unsigned char* sigVal = new unsigned char[sigLen + 1];
    ArrayJanitor<unsigned char> j_sigVal(sigVal);

    EVP_ENCODE_CTX m_dctx;
	EVP_DecodeInit(&m_dctx);
	int rc = EVP_DecodeUpdate(&m_dctx,
						  sigVal,
						  &sigValLen,
						  (unsigned char *) cleanedBase64Signature,
						  cleanedBase64SignatureLen);

	if (rc < 0) {

		throw XSECCryptoException(XSECCryptoException::RSAError,
			"OpenSSL:RSA - Error during Base64 Decode");
	}
	int t = 0;

	EVP_DecodeFinal(&m_dctx, &sigVal[sigValLen], &t);

	sigValLen += t;

	// Now decrypt

	unsigned char * decryptBuf;

	// Decrypt will always be longer than (RSA_len(key) - 11)
	decryptBuf = new unsigned char [RSA_size(mp_rsaKey)];
	ArrayJanitor<unsigned char> j_decryptBuf(decryptBuf);

	// Note at this time only supports PKCS1 padding
	// As that is what is defined in the standard.
	// If this ever changes we will need to pass some paramaters
	// into this function to allow it to determine what the
	// padding should be and what the message digest OID should
	// be.

	int decryptSize = RSA_public_decrypt(sigValLen,
											 sigVal,
											 decryptBuf,
											 mp_rsaKey,
											 RSA_PKCS1_PADDING);

	if (decryptSize < 0) {

/*		throw XSECCryptoException(XSECCryptoException::RSAError,
			"OpenSSL:RSA::verify() - Error decrypting signature"); */
		// Really - this is a failed signature check, not an exception!
		return false;
	}

	/* Check the OID */
	int oidLen = 0;
	unsigned char * oid = getRSASigOID(hm, oidLen);

	if (oid == NULL) {
		throw XSECCryptoException(XSECCryptoException::RSAError,
			"OpenSSL:RSA::verify() - Unsupported HASH algorithm for RSA");
	}

	if (decryptSize != (int) (oidLen + hashLen) || hashLen != oid[oidLen-1]) {

		return false;

	}

	for (t = 0; t < oidLen; ++t) {

		if (oid[t] != decryptBuf[t]) {

			return false;

		}

	}

	for (;t < decryptSize; ++t) {

		if (hashBuf[t-oidLen] != decryptBuf[t]) {

			return false;

		}

	}

	// All OK
	return true;

}
//--------------------------------------------------
// Reads in signed XML document and extracts the desired data file
// pSigDoc - signed document object if exists. Can be NULL
// szFileName - digidoc filename
// szDataFileName - name of the file where to store embedded data.
// szDocId - DataFile Id atribute value
// szCharset - convert DataFile content to charset
//--------------------------------------------------
EXP_OPTION int ddocExtractDataFile(SignedDoc* pSigDoc, const char* szFileName,
                                   const char* szDataFileName, const char* szDocId,
                                   const char* szCharset)
{
    FILE *fIn = 0, *fOut = 0;
    int err = ERR_OK, i, nRead, lt, la, lc, j, ld, lb, l, eState = 0, fs = 0;
    long len, lExtr = 0, lSize = 0;
    char chars[1050], tag[100], attr[100], con[1030], dec[70], b64line[70];
    unsigned char b64 = 0, nNc = 0, bFound = 0;
    void *pBuf;
    EVP_ENCODE_CTX ectx;
#ifdef WIN32
    wchar_t *convFileName = 0, *convDataFileName = 0;
    i= 0;
    err = utf82unicode((const char*)szFileName, (char**)&convFileName, &i);
    ddocDebug(3, "ddocExtractDataFile", "file: %s, conv-file: %s len: %d", szFileName, convFileName, i);
    i= 0;
    err = utf82unicode((const char*)szDataFileName, (char**)&convDataFileName, &i);
    ddocDebug(3, "ddocExtractDataFile", "dfile: %s, conv-dfile: %s len: %d", szDataFileName, convDataFileName, i);
#endif

    RETURN_IF_NULL_PARAM(szFileName);
    RETURN_IF_NULL_PARAM(szDataFileName);
    RETURN_IF_NULL_PARAM(szDocId);
    RETURN_IF_NULL_PARAM(szCharset);
    clearErrors();
    ddocDebug(3, "ddocExtractDataFile", "SigDoc: %s, docid: %s, digidoc: %s, file: %s, charset: %s", (pSigDoc ? "OK" : "NULL"), szDocId, szFileName, szDataFileName, szCharset);
    if(szCharset && !strcmp(szCharset, "NO-CHANGE"))
        nNc = 1;
    // try reading from memory if already cached?
    nRead = ddocGetDataFileCachedData(pSigDoc, szDocId, &pBuf, &len);
    if(pBuf) { // gotcha
        ddocDebug(3, "ddocSaxExtractDataFile", "Using cached data: %d bytes", len);
#ifdef WIN32
        if((fOut = _wfopen(convDataFileName, L"wb")) != NULL) {
#else
        if((fOut = fopen(szDataFileName, "wb")) != NULL) {
#endif
            fwrite(pBuf, 1, len, fOut);
            fclose(fOut);
        } else {
            free(pBuf);
            ddocDebug(1, "ddocSaxExtractDataFile", "Error writing file: %s", szDataFileName);
            SET_LAST_ERROR_RETURN_CODE(ERR_FILE_WRITE);
        }
        free(pBuf);
        return nRead;
    }
    // open ddoc file
#ifdef WIN32
    if((fIn = _wfopen(convFileName, L"rb")) != NULL) {
#else
    if((fIn = fopen(szFileName, "rb")) != NULL) {
#endif
        ddocDebug(3, "ddocExtractDataFile", "Opened ddoc-file: %s", szFileName);
        do {
            nRead = fread(chars, 1, 1024, fIn);
            chars[nRead] = 0;
            ddocDebug(6, "ddocExtractDataFile", "Parsing %d bytes: \n%s\n", nRead, chars);
            // handle read data
            for(i = 0; i < nRead; i++) {
                switch(eState) {
                case ST_START: // search '<?xml'
                    if(chars[i] == '<' &&
                            !strncmp(chars+i, "<?xml", 5)) {
                        eState = ST_XML;
                        i += 4;
                    }
                    break;
                case ST_XML: // search '<'
                    if(chars[i] == '<') {
                        eState = ST_TAG_NM;
                        lt = 0;
                        tag[lt] = 0;
                    }
                    break;
                case ST_TAG_NM: // read tag name
                    if(isalnum(chars[i]) || chars[i] == ':' || chars[i] == '/') {
                        if(lt < sizeof(tag)-1) {
                            tag[lt] = chars[i];
                            tag[++lt] = 0;
                        } else {
                            ddocDebug(1, "ddocSaxExtractDataFile", "Invalid xml tag-len > %d", sizeof(tag));
                            SET_LAST_ERROR_RETURN_CODE(ERR_FILE_READ);
                        }
                    } else if(chars[i] == '>') { // tag ended - content
                        eState = ST_CON;
                    } else { // expecting atributes
                        eState = ST_TAG_WS;
                    }
                    break;
                case ST_TAG_WS:
                    if(chars[i] == '>') {
                        if(bFound) {
                            eState = ST_DF_CON;
                            if(b64)
                                EVP_DecodeInit(&ectx);
                        } else
                            eState = ST_CON; // tag endded - content
                        lc = 0;
                        con[lc] = 0;
                    } else if(isalnum(chars[i])) {
                        eState = ST_ATTR_NM; // attr name started
                        la = 0;
                        attr[la] = chars[i];
                        attr[++la] = 0;
                    }
                    break;
                case ST_ATTR_NM:
                    if(isalnum(chars[i])) {
                        if(la < (int)sizeof(attr)-1) {
                            attr[la] = chars[i];
                            attr[++la] = 0;
                        }
                        else
                            ddocDebug(1, "ddocExtractDataFile", "Truncating attr name: %s", attr);
                        break;
                        //19.11.08 added support for '
                    } else if(chars[i] == '\"'/*|| chars[i] == '\''*/) {
                        eState = ST_ATTR_CON;
                        lc = 0;
                        con[lc] = 0;
                        fs = 2;
                    } else if(chars[i] == '\'' && fs==0) {
                        eState = ST_ATTR_CON;
                        lc = 0;
                        con[lc] = 0;
                        fs = 1;
                    } else {
                        eState = ST_ATTR_WS;
                    }
                    break;
                case ST_ATTR_WS:
                    //19.11.08 added support for '
                    if(chars[i] == '\"'/*|| chars[i] == '\''*/) {
                        eState = ST_ATTR_CON;
                        lc = 0;
                        con[lc] = 0;
                    } else if(chars[i] == '\'' && fs==1)  {
                        eState = ST_ATTR_CON;
                        lc = 0;
                        con[lc] = 0;
                    } else {
                        eState = ST_TAG_WS;
                    }
                    break;
                case ST_ATTR_CON:
                    //19.11.08 added support for '
                    if(chars[i] != '\"' /*&& chars[i] != '\''*/) {
                        if(lc < (int)sizeof(con)-1) {
                            con[lc] = chars[i];
                            con[++lc] = 0;
                        } else
                            ddocDebug(1, "ddocExtractDataFile", "Truncating attr content: %s", attr);
                    } else if(chars[i] == '\'' && fs==1)  {
                        if(lc < (int)sizeof(con)-1) {
                            con[lc] = chars[i];
                            con[++lc] = 0;
                        } else
                            ddocDebug(1, "ddocExtractDataFile", "Truncating attr content: %s", attr);
                    } else {
                        eState = ST_TAG_WS;
                        // attribute value complete
                        if(!strcmp(tag, "DataFile")) {
                            //	ddocDebug(3, "ddocSaxExtractDataFile", "DataFile start, attr: %s", attr);
                            if(!strcmp(attr, "ContentType")) {
                                b64 = (!strcmp(con, "EMBEDDED_BASE64")) ? 1 : 0;
                                lb = 0;
                                b64line[0] = 0;
                            }
                            if(!strcmp(attr, "Size") && bFound) {
                                lSize = atol(con);
                            }
                            if(!strcmp(attr, "Id")) {
                                ddocDebug(3, "ddocSaxExtractDataFile", "Found Id: %s searching id: %s", con, szDocId);
                                if(!strcmp(con, szDocId)) {
                                    bFound = 1;
#ifdef WIN32
                                    fOut = _wfopen(convDataFileName, L"wb");
                                    ddocDebug(3, "ddocSaxExtractDataFile", "Opening file: %s handle: %s", convDataFileName, (fOut ? "OK" : "NULL"));
#else
                                    fOut = fopen(szDataFileName, "wb");
                                    ddocDebug(3, "ddocSaxExtractDataFile", "Opening file: %s handle: %s", szDataFileName, (fOut ? "OK" : "NULL"));
#endif
                                    if(!fOut) {
                                        SET_LAST_ERROR(ERR_FILE_WRITE);
                                        err = ERR_FILE_WRITE;
                                        return err;
                                    }
                                }
                            }
                        }
                    }
                    break;
                case ST_CON:
                    if(chars[i] == '<') {
                        eState = ST_TAG_NM;
                        lt = 0;
                        tag[lt] = 0;
                    } else {
                        //con[lc] = chars[i];
                        //con[++lc] = 0;
                    }
                    break;
                case ST_DF_START: // find tag end
                    if(chars[i] == '>') {
                        eState = ST_DF_CON;
                        lc = 0;
                        con[lc] = 0;
                        if(b64)
                            EVP_DecodeInit(&ectx);
                    }
                    break;
                case ST_DF_CON:
                    if(chars[i] == '<') {
                        eState = ST_DF_TAG;
                        lt = 0;
                        tag[lt] = 0;
                    } else {
                        if(lc < (int)sizeof(con) - 1) {
                            if(b64 && !nNc) {
                                for(l = 0; l < lc; ) {
                                    while(lb < 64 && l < lc && l < sizeof(con)) {
                                        if(con[l] != '\n' && con[l] != '\r')
                                            b64line[lb++] = con[l];
                                        l++;
                                    }
                                    if(lb == 64) {
                                        b64line[lb++] = '\n';
                                        b64line[lb] = 0;
                                        ld = sizeof(dec);
                                        dec[0] = 0;
                                        EVP_DecodeUpdate(&ectx, (unsigned char*)dec, &ld, (unsigned char*)b64line, lb);
                                        lExtr += ld;
                                        if(ld > 0)
                                            fwrite(dec, 1, ld, fOut);
                                        lb = 0;
                                    }
                                }
                            } else if(nNc || !b64) {
                                lExtr += lc;
                                fwrite(con, 1, lc, fOut);
                            }
                            lc = 0;
                        }
                        if(lc < sizeof(con)-1) {
                            con[lc] = chars[i];
                            con[++lc] = 0;
                        }
                    }
                    break;
                case ST_DF_TAG:
                    if(/*isalnum(chars[i]) || chars[i] == ':' || chars[i] == '/' ||*/ chars[i] != '>') {
                        if(lt < sizeof(tag)-1) {
                            tag[lt] = chars[i];
                            tag[++lt] = 0;
                        } else {
                            ddocDebug(1, "ddocSaxExtractDataFile", "Invalid xml tag-len > %d", sizeof(tag));
                            SET_LAST_ERROR_RETURN_CODE(ERR_FILE_READ);
                        }
                    } else { // DF intenal tag name ready
                        if(!strcmp(tag, "/DataFile")) { // end of DF
                            eState = ST_DF_END;
                        } else { // wrong tag - this is content
                            if(lc < sizeof(con)-1) {
                                con[lc] = '<';
                                for(j = 0; j < lt; j++)
                                    con[++lc] = tag[j];
                                con[++lc] = '>';
                                con[++lc] = 0;
                            }
                            eState = ST_DF_CON;
                        }
                    }
                    if(eState != ST_DF_END)
                        break;
                case ST_DF_END:
                    if(b64 && !nNc) {
                        if(lc > 0) {
                            for(l = 0; l < lc; ) {
                                while(lb < 64 && l < lc) {
                                    if(con[l] != '\n' && con[l] != '\r')
                                        b64line[lb++] = con[l];
                                    l++;
                                }
                                b64line[lb++] = '\n';
                                b64line[lb] = 0;
                                ld = sizeof(dec);
                                dec[0] = 0;
                                EVP_DecodeUpdate(&ectx, (unsigned char*)dec, &ld, (unsigned char*)b64line, lb);
                                lExtr += ld;
                                if(ld > 0)
                                    fwrite(dec, 1, ld, fOut);
                                lb = 0;
                            }
                        }
                        ld = 0;
                        dec[ld] = 0;
                        EVP_DecodeFinal(&ectx, (unsigned char*)dec, &ld);
                        lExtr += ld;
                        if(ld)
                            fwrite(dec, 1, ld, fOut);
                    } else if(nNc || !b64) {
                        if(lc) {
                            lExtr += lc;
                            fwrite(con, 1, lc, fOut);
                            lc = 0;

                        }
                    }
                    i = sizeof(chars);
                    //AM 24.09.08 RIK
                    eState = ST_DF_END_END;
                    break;
                }
            }
            //AM 24.09.08 RIK ST_DF_END to ST_DF_END_END_END
        } while(nRead > 0 && !err && eState < ST_DF_END_END);
    } else {
        ddocDebug(1, "ddocExtractDataFile", "Error reading file: %s", szFileName);
        SET_LAST_ERROR(ERR_FILE_READ);
    }
    if(fIn)
        fclose(fIn);
    if(fOut)
        fclose(fOut);
    if(!nNc && lSize != lExtr) {
        ddocDebug(1, "ddocExtractDataFile", "Warning! Extracted: %ld bytes but expected: %ld bytes", lExtr, lSize);
        //SET_LAST_ERROR(ERR_FILE_READ);
        //err = ERR_FILE_READ;
    }
    if(!bFound) {
        ddocDebug(1, "ddocExtractDataFile", "DF: %s not found", szDocId);
        SET_LAST_ERROR(ERR_FILE_WRITE);
        err = ERR_FILE_WRITE;
    }
    ddocDebug(3, "ddocExtractDataFile", "Extracted DF: %s to %s size: %ld expected: %ld", szDocId, szDataFileName, lExtr, lSize);
#ifdef WIN32
    free(convFileName);
    free(convDataFileName);
#endif
    return err;
}
Example #19
0
/*
 * \fn hip_xmlrpc_parse_response()
 *
 * \param mode		is this an XML RPC GET/PUT? store response in hit/addr?
 * \param xmldata       pointer to XML character data
 * \param len		length of XML data
 * \param value		ptr for storing response value
 * \param value_len	ptr to the length of the value buffer and for
 *                      storing response value length
 *
 * \return		For GETs, the address or HIT is returned in addr or hit,
 *	                and 0 is returned for success.
 *	                For PUTs, the XML RPC return code is returned,
 *                      which is 0 for success, or 1 or 2.
 *                      -1 is returned on error.
 */
int hip_xmlrpc_parse_response(int mode, char *xmldata, int len,
                              char *value, int *value_len)
{
  xmlDocPtr doc = NULL;
  xmlNodePtr node, node_val;
  int retval = -10, i;
  xmlChar *data;
  EVP_ENCODE_CTX ctx;

  /* log_(NORM, "Got the DHT response (content-length=%d):\n%s\n",
   *    len, xmldata); // */
  if ((doc = xmlParseMemory(xmldata, len)) == NULL)
    {
      goto parse_response_exit;
    }
  node = xmlDocGetRootElement(doc);                     /* <methodResponse> */
  if (node->children)
    {
      node = node->children;                              /* <params> */
    }
  node = node->children;
  if (!node)                                            /* <param> */
    {
      goto parse_response_exit;
    }
  node_val = NULL;
  if (!strcmp((char *)node->name, "param") && node->children &&
      !strcmp((char *)node->children->name, "value"))
    {
      node_val = node->children->children;
    }
  if (!node_val)
    {
      goto parse_response_exit;
    }

  switch (mode & 0x000F)
    {
    case XMLRPC_MODE_PUT:       /* retrieve status code only */
    case XMLRPC_MODE_RM:
      data = xmlNodeGetContent(node_val);
      /* status code is first int that we encounter */
      if (strcmp((char *)node_val->name, "int") == 0)
        {
          sscanf((const char *)data, "%d", &retval);
          xmlFree(data);
          goto parse_response_exit;
        }
      break;
    case XMLRPC_MODE_GET:        /* retrieve address or HIT */
      /* <?xml version="1.0" encoding="ISO-8859-1"?>
       *   <methodResponse>
       *     <params><param><value><array><data>
       *        <value><array><data>
       *           <value><base64>AgAAAMCoAQAAAAAAA==</base64></value>
       *           <value><base64>AgAAAMCoAgcAAAAAA==</base64></value>
       *        </data></array></value>
       *        <value><base64></base64></value>
       *     </data></array></value></param></params>
       *   </methodResponse>
       */
      if (!strcmp((char *)node_val->name, "array") &&
          node_val->children &&
          !strcmp((char *)node_val->children->name, "data"))
        {
          node = node_val->children->children;
        }

      if (!strcmp((char *)node->name, "value") && node->children &&
          !strcmp((char *)node->children->name, "array"))
        {
          node = node->children->children;               /* <data> */

        }
      /* step through array of responses */
      for (node = node->children; node; node = node->next)
        {
          node_val = node->children;               /* <value><base64> */
          if ((!node_val) ||
              (strcmp((char *)node_val->name, "base64")))
            {
              continue;
            }
          data = xmlNodeGetContent(node_val);
          /* protect against unusually large values */
          if (strlen((char *)data) >
              ((unsigned)(((*value_len + 2) / 3) * 4) + 1))
            {
              xmlFree(data);
              continue;
            }
          /* log_(NORM, "XMLRPC GET: got the value:\n%s\n",
           *               data); */
          /* decode base64 into value pointer */
          /* *value_len = EVP_DecodeBlock((unsigned char *)value, */
          /*			data, strlen((char *)data)); */
          EVP_DecodeInit(&ctx);
          retval = EVP_DecodeUpdate(&ctx, (__u8 *)value, &i,
                                    (__u8 *)data,
                                    strlen((char *)data));
          if (retval < 0)
            {
              xmlFree(data);
              continue;
            }
          *value_len = i;
          EVP_DecodeFinal(&ctx, data, &i);
          retval = 0;
          xmlFree(data);
          /* the last value encountered will be returned */
        }         /* end for */
                  /* placemark and other tags are ignored */
      break;
    }

parse_response_exit:
  if (doc != NULL)
    {
      xmlFreeDoc(doc);
    }
  return(retval);
}
Example #20
0
int FMT_decrypt_stream(char *id, byte_string_t key,
	FILE *infp, FILE *outfp, params_t params)
{
    byte_string_t U;
    byte_string_t K, V;
    crypto_ctx_t ctx;
    unsigned char in[crypt_buf_size];
    unsigned char out[200]; //TODO: what should this be?
    int inl, outl;
    unsigned char data[1024];
    int count;
    EVP_ENCODE_CTX mime;
    int result = 0;
    char *s, slen;
    int status;

    advance_to("-----BEGIN IBE-----", infp);

    advance_to("U:", infp);
    mime_get(U, infp);

    slen = strlen(id) + 2;
    s = (char *) alloca(sizeof(char) * slen);
    for(;;) {
	advance_to("ID:", infp);
	if (feof(infp)) {
	    //ID not found
	    return 0;
	}
	fgets(s, slen, infp);
	if (s[strlen(id)] == '\n') { //correct length?
	    if (!strncmp(s, id, strlen(id))) { //compares?
		break; //email has ID for us
	    }
	}
    }

    advance_to("V:", infp);
    mime_get(V, infp);

    status = IBE_reveal_key(K, U, V, key, params);

    if (status != 1) {
	fprintf(outfp, "WARNING: KMAC MISMATCH. INVALID CIPHERTEXT!\n");
	byte_string_clear(V);
	byte_string_clear(K);
	return result;
    }

    advance_to("W:", infp);

    crypto_ctx_init(ctx);
    crypto_decrypt_init(ctx, K);
    EVP_DecodeInit(&mime);
    for (;;) {
	fgets(in, crypt_buf_size, infp);
	inl = strlen(in);
	if (inl < 0) {
	    fprintf(stderr, "read error\n");
	    exit(1);
	}
	if (inl < 2) break;
	EVP_DecodeUpdate(&mime, data, &count, in, inl);
	crypto_decrypt_update(ctx, out, &outl, data, count);
	fwrite(out, 1, outl, outfp);
    }
    EVP_DecodeFinal(&mime, data, &count);
    crypto_decrypt_update(ctx, out, &outl, data, count);
    fwrite(out, 1, outl, outfp);
    if (1 != crypto_decrypt_final(ctx, out, &outl)) {
	fprintf(outfp, "crypto_decrypt_final() failed!\n");
    } else {
	result = 1;
    }
    fwrite(out, 1, outl, outfp);
    crypto_ctx_clear(ctx);

    byte_string_clear(K);
    byte_string_clear(U);
    byte_string_clear(V);

    return result;
}
Example #21
0
File: ca.c Project: danharkins/est
static void
sign_req (int fd, void *unused)
{
    char thefile[80], cmd_buf[300], p7[3000];
    int i, num;
    unsigned char *data, *asn1;
    int32_t msglen;
    BIO *bio = NULL;
    FILE *fp;
    struct stat blah;
    X509_REQ *req = NULL;
    EVP_ENCODE_CTX ctx;
    
    if (recv(fd, (char *)&msglen, sizeof(int32_t), MSG_WAITALL) < sizeof(int32_t)) {
        return;
    }
    msglen = ntohl(msglen);
    if (msglen > 3000) {
        return;
    }
    if ((data = (unsigned char *)malloc(msglen)) == NULL) {
        return;
    }
    if ((asn1 = (unsigned char *)malloc(msglen)) == NULL) {
        free(data);
        return;
    }
    if (recv(fd, (char *)data, msglen, MSG_WAITALL) < msglen) {
        free(data);
        return;
    }

    EVP_DecodeInit(&ctx);
    EVP_DecodeUpdate(&ctx, asn1, &i, data, msglen);
    num = i;
    EVP_DecodeFinal(&ctx, &(asn1[i]), &i);
    num += i;
    free(data);

    if ((bio = BIO_new_mem_buf(asn1, num)) == NULL) {
        free(asn1);
        goto no_cert;
    }
    if ((req = d2i_X509_REQ_bio(bio, NULL)) == NULL) {
        free(asn1);
        goto no_cert;
    }
    free(asn1);
    BIO_free(bio); bio = NULL;
    
    unique++;
    memset(thefile, 0, sizeof(thefile));
    snprintf(thefile, sizeof(thefile), "%dreq.pem", unique);
    if ((fp = fopen(thefile, "w+")) == NULL) {
        goto no_cert;
    }
    if ((bio = BIO_new(BIO_s_file())) == NULL) {
        fprintf(stderr, "unable to create bio for CSR\n");
        goto no_cert;
    }
    BIO_set_fp(bio, fp, BIO_NOCLOSE);
    PEM_write_bio_X509_REQ(bio, req);
    (void)BIO_flush(bio);
    BIO_free(bio); bio = NULL;
    fclose(fp);

    snprintf(cmd_buf, sizeof(cmd_buf),
             "openssl ca "
             "-policy policy_anything -batch -notext "
             "-config ./conf/openssl.cnf "
             "-out %dcert.pem -in %dreq.pem", unique, unique);
    system(cmd_buf);
    unlink(thefile);

    snprintf(thefile, sizeof(thefile), "%dcert.pem", unique);
    if ((stat(thefile, &blah) < 0) || (blah.st_size < 1)) {
        goto no_cert;
    }

    snprintf(cmd_buf, sizeof(cmd_buf),
             "openssl crl2pkcs7 "
             "-certfile %dcert.pem -outform DER -out %dder.p7 -nocrl", unique, unique);
    system(cmd_buf);
    unlink(thefile); 

    snprintf(thefile, sizeof(thefile), "%dder.p7", unique);
    if (stat(thefile, &blah) < 0) {
        goto no_cert;
    }
    i = blah.st_size;
    printf("DER-encoded P7 is %d bytes\n", i);
    if ((data = (unsigned char *)malloc(blah.st_size*2)) == NULL) {
        goto no_cert;
    }
    
    if ((fp = fopen(thefile, "r")) == NULL) {
        free(data);
        goto no_cert;
    }
    if (fread(p7, 1, sizeof(p7), fp) < blah.st_size) {
        free(data);
        goto no_cert;
    }
    fclose(fp);
    unlink(thefile);
    
    i = 0;
    EVP_EncodeInit(&ctx);
    EVP_EncodeUpdate(&ctx, data, &i, (unsigned char *)p7, blah.st_size);
    num = i;
    EVP_EncodeFinal(&ctx, (unsigned char *)&(data[i]), &i);
    num += i;
    printf("PEM-encoded P7 is %d bytes\n", num);
    msglen = num;
    msglen = htonl(msglen);
    send(fd, (char *)&msglen, sizeof(int32_t), 0);
    send(fd, (char *)data, num, 0);
    free(data);

no_cert:
    BIO_free(bio);
    srv_rem_input(srvctx, fd);
    close(fd);
    
    return;
}
Example #22
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;
}