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));

}
Beispiel #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;
}
Beispiel #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;
}
unsigned int OpenSSLCryptoBase64::decodeFinish(unsigned char * outData,
							 	      unsigned int outLength) {

	int outLen;
	outLen = outLength;

	EVP_DecodeFinal(&m_dctx, outData, &outLen); 

	return outLen;

}
Beispiel #5
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; 
}
Beispiel #6
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;
}
Beispiel #7
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);
}
Beispiel #8
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);
}
Beispiel #9
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);
  }
Beispiel #10
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;
}
Beispiel #11
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;
}
Beispiel #12
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;

}
Beispiel #13
0
/* {{{ php_crypto_base64_decode_finish */
static inline void php_crypto_base64_decode_finish(EVP_ENCODE_CTX *ctx,
		char *out, int *outl)
{
	EVP_DecodeFinal(ctx, (unsigned char *) out, outl);
}
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);

}
//--------------------------------------------------
// 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;
}
Beispiel #16
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);
}
Beispiel #17
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;
}
Beispiel #18
0
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;
}