コード例 #1
0
ファイル: BoxEncoding.cpp プロジェクト: 2Quico/netbox
BSTR CBoxEncoding::Base64Encode(VARIANT& var)
{
	CBoxBinPtr varPtr(var);
	CStringA str;
	LPSTR pstr;
	int strSize;
	int nPos, i;

	strSize = ((varPtr.m_nSize + 2) / 3) * 4;
	strSize += (strSize / 64) * 2;
	pstr = str.GetBuffer(strSize);

	for(i = 0, nPos = 0; i < varPtr.m_nSize; i += 48)
		if(varPtr.m_nSize - i > 48)
		{
			EVP_EncodeBlock((unsigned char*)pstr + nPos, (unsigned char*)varPtr + i, 48);
			nPos += 64;
			pstr[nPos ++] = '\r';
			pstr[nPos ++] = '\n';
		}else
			EVP_EncodeBlock((unsigned char*)pstr + nPos, (unsigned char*)varPtr + i, varPtr.m_nSize - i);

	str.ReleaseBuffer(strSize);
	return str.AllocSysString();
}
コード例 #2
0
ファイル: ship_crypto.c プロジェクト: sksushilkumar/p2pship
/* Encode something to base-64 */
char *
ship_encode_base64(unsigned char *input, int length)
{
	char *ret = NULL;
	unsigned char in[48];
	int blen, i=0, ilen, len=0, olen=0;
	
	blen = (((length + 2) / 3) * 4) + 3;
	ASSERT_TRUE(ret = (char *)malloc(blen), err);
	
	while(i<length){
		
		ilen = (i+48<length)?48:length-i;
		memcpy (in, input, ilen);
		input += ilen;
		i += ilen;
		
		/* Each 48-byte text should encode to 64-byte binary */ 
		len = EVP_EncodeBlock((unsigned char*)ret+olen, in, ilen);
		olen += len;
	}

	ret[olen] = '\0';
	
err:
  	return ret;
}
コード例 #3
0
int WXBizMsgCrypt::EncodeBase64(const std::string sSrc, std::string & sTarget)
{
    if(0 == sSrc.size() || kMaxBase64Size < sSrc.size())
    {
        return -1;
    }
    
    uint32_t iBlockNum = sSrc.size() / 3;
    if (iBlockNum * 3 != sSrc.size())
    {
        iBlockNum++;
    }
    uint32_t iOutBufSize = iBlockNum * 4 + 1;
    
    char * pcOutBuf = (char*)malloc( iOutBufSize);
    if(NULL == pcOutBuf)
    {
        return -1;
    }
    int iReturn = 0;
    int ret = EVP_EncodeBlock((unsigned char*)pcOutBuf, (const unsigned char*)sSrc.c_str(), sSrc.size());
    if (ret > 0 && ret < (int)iOutBufSize)
    {
        sTarget.assign(pcOutBuf,ret);
    }
    else
    {
        iReturn = -1;
    }
    
    FREE_PTR(pcOutBuf);
    return iReturn;
}
コード例 #4
0
ファイル: pem_sign.c プロジェクト: ajinkya93/OpenBSD
int
PEM_SignFinal(EVP_MD_CTX *ctx, unsigned char *sigret, unsigned int *siglen,
    EVP_PKEY *pkey)
{
	unsigned char *m;
	int i, ret = 0;
	unsigned int m_len;

	m = malloc(EVP_PKEY_size(pkey) + 2);
	if (m == NULL) {
		PEMerr(PEM_F_PEM_SIGNFINAL, ERR_R_MALLOC_FAILURE);
		goto err;
	}

	if (EVP_SignFinal(ctx, m, &m_len, pkey) <= 0)
		goto err;

	i = EVP_EncodeBlock(sigret, m, m_len);
	*siglen = i;
	ret = 1;

err:
	/* ctx has been zeroed by EVP_SignFinal() */
	free(m);
	return (ret);
}
コード例 #5
0
ファイル: x509spki.c プロジェクト: HungMingWu/libquic
char * NETSCAPE_SPKI_b64_encode(NETSCAPE_SPKI *spki)
{
	unsigned char *der_spki, *p;
	char *b64_str;
	size_t b64_len;
	int der_len;
	der_len = i2d_NETSCAPE_SPKI(spki, NULL);
	if (!EVP_EncodedLength(&b64_len, der_len))
		{
		OPENSSL_PUT_ERROR(X509, NETSCAPE_SPKI_b64_encode, ERR_R_OVERFLOW);
		return NULL;
		}
	der_spki = OPENSSL_malloc(der_len);
	if (der_spki == NULL) {
		OPENSSL_PUT_ERROR(X509, NETSCAPE_SPKI_b64_encode, ERR_R_MALLOC_FAILURE);
		return NULL;
	}
	b64_str = OPENSSL_malloc(b64_len);
	if (b64_str == NULL) {
		OPENSSL_free(der_spki);
		OPENSSL_PUT_ERROR(X509, NETSCAPE_SPKI_b64_encode, ERR_R_MALLOC_FAILURE);
		return NULL;
	}
	p = der_spki;
	i2d_NETSCAPE_SPKI(spki, &p);
	EVP_EncodeBlock((unsigned char *)b64_str, der_spki, der_len);
	OPENSSL_free(der_spki);
	return b64_str;
}
コード例 #6
0
ファイル: msnlib.c プロジェクト: freehaha/libfreemsn
char *base64(const unsigned char *input, int length)
{
	char *buffer = (char*)xmalloc(length*2);
	memset(buffer, 0, length*2);
	EVP_EncodeBlock((unsigned char*)buffer, input, length);
	return buffer;
}
コード例 #7
0
ファイル: ssl.c プロジェクト: UIKit0/picogui
static char *
_SSL_do_cipher_base64(char *buf, int buf_len, char *key, int operation)
{
	char *pt;
	char *pt2;
	int i;


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

	return (pt2);
}
コード例 #8
0
ファイル: encode.c プロジェクト: bbbrumley/openbsd
void
EVP_EncodeUpdate(EVP_ENCODE_CTX *ctx, unsigned char *out, int *outl,
    const unsigned char *in, int inl)
{
	int i, j;
	size_t total = 0;

	*outl = 0;
	if (inl == 0)
		return;
	OPENSSL_assert(ctx->length <= (int)sizeof(ctx->enc_data));
	if (ctx->length - ctx->num > inl) {
		memcpy(&(ctx->enc_data[ctx->num]), in, inl);
		ctx->num += inl;
		return;
	}
	if (ctx->num != 0) {
		i = ctx->length - ctx->num;
		memcpy(&(ctx->enc_data[ctx->num]), in, i);
		in += i;
		inl -= i;
		j = EVP_EncodeBlock(out, ctx->enc_data, ctx->length);
		ctx->num = 0;
		out += j;
		*(out++) = '\n';
		*out = '\0';
		total = j + 1;
	}
	while (inl >= ctx->length && total <= INT_MAX) {
		j = EVP_EncodeBlock(out, in, ctx->length);
		in += ctx->length;
		inl -= ctx->length;
		out += j;
		*(out++) = '\n';
		*out = '\0';
		total += j + 1;
	}
	if (total > INT_MAX) {
		/* Too much output data! */
		*outl = 0;
		return;
	}
	if (inl != 0)
		memcpy(&(ctx->enc_data[0]), in, inl);
	ctx->num = inl;
	*outl = total;
}
コード例 #9
0
ファイル: base64.c プロジェクト: Cyril2004/proto-quic
void EVP_EncodeUpdate(EVP_ENCODE_CTX *ctx, uint8_t *out, int *out_len,
                      const uint8_t *in, size_t in_len) {
  size_t total = 0;

  *out_len = 0;
  if (in_len == 0) {
    return;
  }

  assert(ctx->length <= sizeof(ctx->enc_data));
  assert(ctx->num < ctx->length);

  if (ctx->length - ctx->num > in_len) {
    memcpy(&ctx->enc_data[ctx->num], in, in_len);
    ctx->num += in_len;
    return;
  }

  if (ctx->num != 0) {
    size_t todo = ctx->length - ctx->num;
    memcpy(&ctx->enc_data[ctx->num], in, todo);
    in += todo;
    in_len -= todo;
    size_t encoded = EVP_EncodeBlock(out, ctx->enc_data, ctx->length);
    ctx->num = 0;
    out += encoded;
    *(out++) = '\n';
    *out = '\0';
    total = encoded + 1;
  }

  while (in_len >= ctx->length) {
    size_t encoded = EVP_EncodeBlock(out, in, ctx->length);
    in += ctx->length;
    in_len -= ctx->length;
    out += encoded;
    *(out++) = '\n';
    *out = '\0';
    total += encoded + 1;
  }

  if (in_len != 0) {
    memcpy(&ctx->enc_data[0], in, in_len);
  }
  ctx->num = in_len;
  *out_len = total;
}
コード例 #10
0
ファイル: pem_seal.c プロジェクト: MiKTeX/miktex
int
PEM_SealInit(PEM_ENCODE_SEAL_CTX *ctx, EVP_CIPHER *type, EVP_MD *md_type,
    unsigned char **ek, int *ekl, unsigned char *iv, EVP_PKEY **pubk, int npubk)
{
	unsigned char key[EVP_MAX_KEY_LENGTH];
	int ret = -1;
	int i, j, max = 0;
	char *s = NULL;

	/*
	 * Make sure ctx is properly initialized so that we can always pass
	 * it to PEM_ENCODE_SEAL_CTX_cleanup() in the error path.
	 */
	EVP_EncodeInit(&ctx->encode);
	EVP_MD_CTX_init(&ctx->md);
	EVP_CIPHER_CTX_init(&ctx->cipher);

	for (i = 0; i < npubk; i++) {
		if (pubk[i]->type != EVP_PKEY_RSA) {
			PEMerror(PEM_R_PUBLIC_KEY_NO_RSA);
			goto err;
		}
		j = RSA_size(pubk[i]->pkey.rsa);
		if (j > max)
			max = j;
	}
	s = reallocarray(NULL, max, 2);
	if (s == NULL) {
		PEMerror(ERR_R_MALLOC_FAILURE);
		goto err;
	}

	if (!EVP_SignInit(&ctx->md, md_type))
		goto err;

	ret = EVP_SealInit(&ctx->cipher, type, ek, ekl, iv, pubk, npubk);
	if (ret <= 0)
		goto err;

	/* base64 encode the keys */
	for (i = 0; i < npubk; i++) {
		j = EVP_EncodeBlock((unsigned char *)s, ek[i],
		    RSA_size(pubk[i]->pkey.rsa));
		ekl[i] = j;
		memcpy(ek[i], s, j + 1);
	}

	ret = npubk;

	if (0) {
err:
		PEM_ENCODE_SEAL_CTX_cleanup(ctx);
	}
	free(s);
	explicit_bzero(key, sizeof(key));
	return (ret);
}
コード例 #11
0
ファイル: auth.c プロジェクト: laszlo/imapfilter
/*
 * Authenticate to the server with the Challenge-Response Authentication
 * Mechanism (CRAM).  The authentication type associated with CRAM is
 * "CRAM-MD5".
 */
int
auth_cram_md5(session *ssn, const char *user, const char *pass)
{
	int t;
	size_t n;
	unsigned int i;
	unsigned char *chal, *resp, *out, *buf;
	unsigned char md[EVP_MAX_MD_SIZE], mdhex[EVP_MAX_MD_SIZE * 2 + 1];
	unsigned int mdlen;
	HMAC_CTX hmac;

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

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

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

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

		xfree(chal);
		xfree(resp);

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

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

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

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

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

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

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

	return response_authenticate(ssn, t, NULL);
}
コード例 #12
0
void EVP_EncodeUpdate(EVP_ENCODE_CTX *ctx, unsigned char *out, int *outl,
	     const unsigned char *in, int inl)
	{
	int i,j;
	unsigned int total=0;

	*outl=0;
	if (inl == 0) return;
	OPENSSL_assert(ctx->length <= (int)sizeof(ctx->enc_data));
	if ((ctx->num+inl) < ctx->length)
		{
		TINYCLR_SSL_MEMCPY(&(ctx->enc_data[ctx->num]),in,inl);
		ctx->num+=inl;
		return;
		}
	if (ctx->num != 0)
		{
		i=ctx->length-ctx->num;
		TINYCLR_SSL_MEMCPY(&(ctx->enc_data[ctx->num]),in,i);
		in+=i;
		inl-=i;
		j=EVP_EncodeBlock(out,ctx->enc_data,ctx->length);
		ctx->num=0;
		out+=j;
		*(out++)='\n';
		*out='\0';
		total=j+1;
		}
	while (inl >= ctx->length)
		{
		j=EVP_EncodeBlock(out,in,ctx->length);
		in+=ctx->length;
		inl-=ctx->length;
		out+=j;
		*(out++)='\n';
		*out='\0';
		total+=j+1;
		}
	if (inl != 0)
		TINYCLR_SSL_MEMCPY(&(ctx->enc_data[0]),in,inl);
	ctx->num=inl;
	*outl=total;
	}
コード例 #13
0
ファイル: base64.c プロジェクト: Cyril2004/proto-quic
void EVP_EncodeFinal(EVP_ENCODE_CTX *ctx, uint8_t *out, int *out_len) {
  unsigned ret = 0;

  if (ctx->num != 0) {
    ret = EVP_EncodeBlock(out, ctx->enc_data, ctx->num);
    out[ret++] = '\n';
    out[ret] = '\0';
    ctx->num = 0;
  }
  *out_len = ret;
}
コード例 #14
0
ファイル: encode.c プロジェクト: AndreV84/openssl
void EVP_EncodeFinal(EVP_ENCODE_CTX *ctx, unsigned char *out, int *outl)
{
    unsigned int ret = 0;

    if (ctx->num != 0) {
        ret = EVP_EncodeBlock(out, ctx->enc_data, ctx->num);
        out[ret++] = '\n';
        out[ret] = '\0';
        ctx->num = 0;
    }
    *outl = ret;
}
コード例 #15
0
ファイル: pem_seal.c プロジェクト: benwh4/libressl
int
PEM_SealInit(PEM_ENCODE_SEAL_CTX *ctx, EVP_CIPHER *type, EVP_MD *md_type,
    unsigned char **ek, int *ekl, unsigned char *iv, EVP_PKEY **pubk, int npubk)
{
	unsigned char key[EVP_MAX_KEY_LENGTH];
	int ret = -1;
	int i, j, max = 0;
	char *s = NULL;

	for (i = 0; i < npubk; i++) {
		if (pubk[i]->type != EVP_PKEY_RSA) {
			PEMerr(PEM_F_PEM_SEALINIT, PEM_R_PUBLIC_KEY_NO_RSA);
			goto err;
		}
		j = RSA_size(pubk[i]->pkey.rsa);
		if (j > max)
			max = j;
	}
	s = (char *)reallocarray(NULL, max, 2);
	if (s == NULL) {
		PEMerr(PEM_F_PEM_SEALINIT, ERR_R_MALLOC_FAILURE);
		goto err;
	}

	EVP_EncodeInit(&ctx->encode);

	EVP_MD_CTX_init(&ctx->md);
	if (!EVP_SignInit(&ctx->md, md_type))
		goto err;

	EVP_CIPHER_CTX_init(&ctx->cipher);
	ret = EVP_SealInit(&ctx->cipher, type, ek, ekl, iv, pubk, npubk);
	if (ret <= 0)
		goto err;

	/* base64 encode the keys */
	for (i = 0; i < npubk; i++) {
		j = EVP_EncodeBlock((unsigned char *)s, ek[i],
		    RSA_size(pubk[i]->pkey.rsa));
		ekl[i] = j;
		memcpy(ek[i], s, j + 1);
	}

	ret = npubk;

err:
	if (s != NULL)
		free(s);
	OPENSSL_cleanse(key, EVP_MAX_KEY_LENGTH);
	return (ret);
}
コード例 #16
0
ファイル: ssl.c プロジェクト: UIKit0/picogui
static char *
_SSL_get_obj_base64(void *s, int type)
{
	unsigned char *pt, *ppt;
	unsigned char *t;
	int len = 0;
	int i;


	switch (type) {
	    case 0:
		len = i2d_PublicKey(s, NULL);
		break;
	    case 1:
		len = i2d_PrivateKey(s, NULL);
		break;
	    case 2:
		len = i2d_X509(s, NULL);
		break;
	}
	if (len < 0)
		return (NULL);

	pt = ppt = mmalloc(len);

	switch (type) {
	    case 0:
		i2d_PublicKey(s, &pt);
		break;
	    case 1:
		i2d_PrivateKey(s, &pt);
		break;
	    case 2:
		i2d_X509(s, &pt);
		break;
	}

	t = mmalloc(len * 2 + 1);	/* + NULL */
	if ((i = EVP_EncodeBlock(t, ppt, len)) == -1) {
		fprintf(stderr, "_SSL_get_key_base64 :: EVP_EncodeBlock failed\n");
		exit(1);
	}
	free (ppt);

	return (t);
}
コード例 #17
0
char * NETSCAPE_SPKI_b64_encode(NETSCAPE_SPKI *spki)
{
    unsigned char *der_spki, *p;
    char *b64_str;
    int der_len;
    der_len = i2d_NETSCAPE_SPKI(spki, NULL);
    der_spki = OPENSSL_malloc(der_len);
    b64_str = OPENSSL_malloc(der_len * 2);
    if(!der_spki || !b64_str) {
        X509err(X509_F_NETSCAPE_SPKI_B64_ENCODE, ERR_R_MALLOC_FAILURE);
        return NULL;
    }
    p = der_spki;
    i2d_NETSCAPE_SPKI(spki, &p);
    EVP_EncodeBlock((unsigned char *)b64_str, der_spki, der_len);
    OPENSSL_free(der_spki);
    return b64_str;
}
コード例 #18
0
ファイル: pem_seal.c プロジェクト: benwh4/libressl
int
PEM_SealFinal(PEM_ENCODE_SEAL_CTX *ctx, unsigned char *sig, int *sigl,
    unsigned char *out, int *outl, EVP_PKEY *priv)
{
	unsigned char *s = NULL;
	int ret = 0, j;
	unsigned int i;

	if (priv->type != EVP_PKEY_RSA) {
		PEMerr(PEM_F_PEM_SEALFINAL, PEM_R_PUBLIC_KEY_NO_RSA);
		goto err;
	}
	i = RSA_size(priv->pkey.rsa);
	if (i < 100)
		i = 100;
	s = reallocarray(NULL, i, 2);
	if (s == NULL) {
		PEMerr(PEM_F_PEM_SEALFINAL, ERR_R_MALLOC_FAILURE);
		goto err;
	}

	if (!EVP_EncryptFinal_ex(&ctx->cipher, s, (int *)&i))
		goto err;
	EVP_EncodeUpdate(&ctx->encode, out, &j, s, i);
	*outl = j;
	out += j;
	EVP_EncodeFinal(&ctx->encode, out, &j);
	*outl += j;

	if (!EVP_SignFinal(&ctx->md, s, &i, priv))
		goto err;
	*sigl = EVP_EncodeBlock(sig, s, i);

	ret = 1;

err:
	EVP_MD_CTX_cleanup(&ctx->md);
	EVP_CIPHER_CTX_cleanup(&ctx->cipher);
	if (s != NULL)
		free(s);
	return (ret);
}
コード例 #19
0
ファイル: encoding.c プロジェクト: dparnell/raopd
utility_retcode_t raopd_base64_encode(char *dst,
				      size_t dstlen,
				      const uint8_t *src,
				      size_t srclen,
				      size_t *encoded_length)
{
	utility_retcode_t ret = UTILITY_SUCCESS;

	FUNC_ENTER;

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

	*encoded_length = EVP_EncodeBlock((uint8_t *)dst, src, srclen);

	remove_base64_columnation(dst, encoded_length);

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

	FUNC_RETURN;
	return ret;
}
コード例 #20
0
ファイル: mite_base64.c プロジェクト: LiTianjue/arm-vpn
int mite_string_2_base64_block(char *input,int input_len,char **base64)
{
    int len = 0;
    char *out = NULL;
    out = malloc(((input_len/3+1)*4));
    len = EVP_EncodeBlock(out,input,input_len);

    *base64 = out;
    return len;
    /*
    char *p = out+len-1;
    int pad=0;
    int i = 0;
    for(i=0;i<4;i++)
    {
        if(*p=='=')
            pad++;
        p--;
    }
    */
}
コード例 #21
0
/*++
 * Function:	cmd_authenticate_login
 *
 * Purpose:	implement the AUTHENTICATE LOGIN mechanism
 *
 * Parameters:	ptr to ITD_Struct for client connection.
 *              ptr to client tag
 *
 * Returns:	0 on success prior to authentication
 *              1 on success after authentication (we caught a logout)
 *              -1 on failure	
 *
 * Authors:	Dave McMurtrie <*****@*****.**>
 *
 * Notes:
 *--
 */
static int cmd_authenticate_login( ITD_Struct *Client,
				   char *Tag )
{
    char *fn = "cmd_authenticate_login()";
    char SendBuf[BUFSIZE];
    char Username[MAXUSERNAMELEN];
    char EncodedUsername[BUFSIZE];
    char Password[MAXPASSWDLEN];
    char EncodedPassword[BUFSIZE];
    ICD_Struct *conn;
    int rc;
    ITD_Struct Server;
    int BytesRead;
    struct sockaddr_in cli_addr;
    int addrlen;
    char *hostaddr;
    
    unsigned int BufLen = BUFSIZE - 1;
    memset ( &Server, 0, sizeof Server );
    addrlen = sizeof( struct sockaddr_in );
    
    /*
     * send a base64 encoded username prompt to the client.  Note that we're
     * using our Username and EncodedUsername buffers temporarily here to
     * avoid allocating additional buffers.  Keep this in mind for future
     * code modification...
     */
    snprintf( Username, BufLen, "Username:"******"+ %s\r\n", EncodedUsername );
    
    if ( IMAP_Write( Client->conn, SendBuf, strlen(SendBuf) ) == -1 )
    {
	syslog(LOG_ERR, "%s: Unable to send base64 encoded username prompt to client: %s", fn, strerror(errno) );
	return( -1 );
    }

    /*
     * The response from the client should be a base64 encoded version of the
     * username.
     */
    BytesRead = IMAP_Line_Read( Client );
    
    if ( BytesRead == -1 )
    {
	syslog( LOG_NOTICE, "%s: Failed to read base64 encoded username from client on socket %d", fn, Client->conn->sd );
	return( -1 );
    }
    
    /*
     * Easy, but not perfect sanity check.  If the client sent enough data
     * to fill our entire buffer, we're not even going to bother looking at it.
     */
    if ( Client->MoreData ||
	 BytesRead > BufLen )
    {
	syslog( LOG_NOTICE, "%s: Base64 encoded username sent from client on sd %d is too large.", fn, Client->conn->sd );
	return( -1 );
    }
    
    /*
     * copy BytesRead -2 so we don't include the CRLF.
     */
    memcpy( (void *)EncodedUsername, (const void *)Client->ReadBuf, 
	    BytesRead - 2 );
    
    rc = EVP_DecodeBlock( Username, EncodedUsername, BytesRead - 2 );
    Username[rc] = '\0';
    
    /*
     * Same drill all over again, except this time it's for the password.
     */
    snprintf( Password, BufLen, "Password:"******"+ %s\r\n", EncodedPassword );
    
    if ( IMAP_Write( Client->conn, SendBuf, strlen(SendBuf) ) == -1 )
    {
        syslog(LOG_ERR, "%s: Unable to send base64 encoded password prompt to 
client: %s", fn, strerror(errno) );
        return( -1 );
    }
コード例 #22
0
ファイル: identity.c プロジェクト: Parantido/opensips
/* adds a Identity header field to msg
return value: 1: success
			0: else
*/
static int addIdentity(char * dateHF, struct sip_msg * msg)
{
	#define IDENTITY_HDR_S  "Identity: \""
	#define IDENTITY_HDR_L  (sizeof(IDENTITY_HDR_S)-1)
	EVP_MD_CTX ctx;
	unsigned int siglen = 0;
	int b64len = 0;
	unsigned char * sig = NULL;
	char digestString[MAX_DIGEST];
	str buf;

	if(!makeDigestString(digestString, dateHF, msg))
	{
		LM_ERR("error making digest string\n");
		return 0;
	}

	EVP_SignInit(&ctx, EVP_sha1());

	EVP_SignUpdate(&ctx, digestString, strlen(digestString));

	sig = pkg_malloc(EVP_PKEY_size(privKey_evp));
	if(!sig)
	{
		EVP_MD_CTX_cleanup(&ctx);
		LM_ERR("failed allocating memory\n");
		return 0;
	}

	if(!EVP_SignFinal(&ctx, sig, &siglen, privKey_evp))
	{
		EVP_MD_CTX_cleanup(&ctx);
		pkg_free(sig);
		LM_ERR("error calculating signature\n");
		return 0;
	}
	EVP_MD_CTX_cleanup(&ctx);

	/* ###Base64-encoding### */
	/* annotation: The next few lines are based on example 7-11 of [VIE-02] */
	b64len = (((siglen + 2) / 3) * 4) + 1;
	buf.len = IDENTITY_HDR_L + b64len + 1 + CRLF_LEN;
	buf.s = pkg_malloc(buf.len);
	if(!buf.s)
	{
		pkg_free(sig);
		LM_ERR("error allocating memory\n");
		return 0;
	}
	memcpy( buf.s, IDENTITY_HDR_S, IDENTITY_HDR_L);
	EVP_EncodeBlock((unsigned char*)(buf.s+IDENTITY_HDR_L), sig, siglen);
	memcpy( buf.s+IDENTITY_HDR_L+b64len, "\""CRLF, CRLF_LEN+1);

	pkg_free(sig);

	if ( id_add_header( msg, buf.s, buf.len )!=0) {
		pkg_free(buf.s);
		LM_ERR("failed to add Identity header\n");
		return 0;
	}

	return 1;
}
コード例 #23
0
ファイル: LOF_connection.c プロジェクト: avastms/LOF
int LOF_CONNECTION_FetionConnection_connect_with_proxy(LOF_CONNECTION_FetionConnectionType* connection
        , const char* ipaddress , const int port , LOF_CONNECTION_ProxyType *proxy)
{
    struct sockaddr_in addr;

    char *ip = LOF_TOOL_get_ip_by_name(proxy->proxyHost);
    addr.sin_family = AF_INET;
    addr.sin_addr.s_addr = inet_addr(ip);
    free(ip);
    addr.sin_port = htons(proxy->proxyPort);
    strcpy(connection->remote_ipaddress , ipaddress);
    connection->remote_port = port;

    unsigned int n = LOF_MAX_RECV_BUF_SIZE;
    int ret = setsockopt(connection->socketfd , SOL_SOCKET , SO_RCVBUF , (const char*)&n , sizeof(n));
    if(ret == -1) return -1;
    ret = connect(connection->socketfd , (struct sockaddr*)&addr , sizeof(struct sockaddr));
    if(ret == -1) return -1;
    LOF_debug_info("%s:%d\n", ipaddress, port);

    char http[1024] , code[5] , *pos = NULL;
    unsigned char authentication[1024];
    char authen[1024];
    char authorization[1024];

    memset(authorization, 0, sizeof(authorization));
    if(strlen(proxy->proxyUser) != 0 && strlen(proxy->proxyPass) != 0)
    {
        memset(authen, 0, sizeof(authen));
        sprintf(authen , "%s:%s" , proxy->proxyUser , proxy->proxyPass);
        EVP_EncodeBlock(authentication , (unsigned char*)authen , strlen(authen));
        sprintf(authorization , "Proxy-Authorization: Basic %s\r\n" , (char*)authentication);
    }

    memset(http, 0, sizeof(http));
    snprintf(http , sizeof(http)-1 , "CONNECT %s:%d HTTP/1.1\r\n"
             "Host: %s:%d\r\n%s"
             "User-Agent: OpenFetion\r\n\r\n"
             , ipaddress , port , ipaddress , port , authorization);

    LOF_CONNECTION_FetionConnection_send(connection , http , strlen(http));

    memset(http, 0, sizeof(http));

    LOF_CONNECTION_FetionConnection_recv(connection , http , sizeof(http));

    pos = strstr(http , " ");
    if(pos == NULL) {
        return -1;
    }
    pos++;
    n = strlen(pos) - strlen(strstr(pos , " "));
    memset(code, 0, sizeof(code));
    strncpy(code, pos, (sizeof(code)-1 < n) ? (sizeof(code)-1) : n);
    code[sizeof(code)-1]='\0';

    if(strcmp(code , "200") != 0)
        return -1;

    return 1;
}
コード例 #24
0
ファイル: base64_bio.c プロジェクト: 0x64616E69656C/boringssl
static int b64_write(BIO *b, const char *in, int inl) {
  int ret = 0, n, i;
  BIO_B64_CTX *ctx;

  ctx = (BIO_B64_CTX *)b->ptr;
  BIO_clear_retry_flags(b);

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

  assert(ctx->buf_off < (int)sizeof(ctx->buf));
  assert(ctx->buf_len <= (int)sizeof(ctx->buf));
  assert(ctx->buf_len >= ctx->buf_off);

  n = ctx->buf_len - ctx->buf_off;
  while (n > 0) {
    i = BIO_write(b->next_bio, &(ctx->buf[ctx->buf_off]), n);
    if (i <= 0) {
      BIO_copy_next_retry(b);
      return i;
    }
    assert(i <= n);
    ctx->buf_off += i;
    assert(ctx->buf_off <= (int)sizeof(ctx->buf));
    assert(ctx->buf_len >= ctx->buf_off);
    n -= i;
  }

  // at this point all pending data has been written.
  ctx->buf_off = 0;
  ctx->buf_len = 0;

  if (in == NULL || inl <= 0) {
    return 0;
  }

  while (inl > 0) {
    n = (inl > B64_BLOCK_SIZE) ? B64_BLOCK_SIZE : inl;

    if (BIO_test_flags(b, BIO_FLAGS_BASE64_NO_NL)) {
      if (ctx->tmp_len > 0) {
        assert(ctx->tmp_len <= 3);
        n = 3 - ctx->tmp_len;
        // There's a theoretical possibility of this.
        if (n > inl) {
          n = inl;
        }
        OPENSSL_memcpy(&(ctx->tmp[ctx->tmp_len]), in, n);
        ctx->tmp_len += n;
        ret += n;
        if (ctx->tmp_len < 3) {
          break;
        }
        ctx->buf_len = EVP_EncodeBlock((uint8_t *)ctx->buf, (uint8_t *)ctx->tmp,
                                       ctx->tmp_len);
        assert(ctx->buf_len <= (int)sizeof(ctx->buf));
        assert(ctx->buf_len >= ctx->buf_off);

        // Since we're now done using the temporary buffer, the length should
        // be zeroed.
        ctx->tmp_len = 0;
      } else {
        if (n < 3) {
          OPENSSL_memcpy(ctx->tmp, in, n);
          ctx->tmp_len = n;
          ret += n;
          break;
        }
        n -= n % 3;
        ctx->buf_len =
            EVP_EncodeBlock((uint8_t *)ctx->buf, (const uint8_t *)in, n);
        assert(ctx->buf_len <= (int)sizeof(ctx->buf));
        assert(ctx->buf_len >= ctx->buf_off);
        ret += n;
      }
    } else {
      EVP_EncodeUpdate(&(ctx->base64), (uint8_t *)ctx->buf, &ctx->buf_len,
                       (uint8_t *)in, n);
      assert(ctx->buf_len <= (int)sizeof(ctx->buf));
      assert(ctx->buf_len >= ctx->buf_off);
      ret += n;
    }
    inl -= n;
    in += n;

    ctx->buf_off = 0;
    n = ctx->buf_len;

    while (n > 0) {
      i = BIO_write(b->next_bio, &(ctx->buf[ctx->buf_off]), n);
      if (i <= 0) {
        BIO_copy_next_retry(b);
        return ret == 0 ? i : ret;
      }
      assert(i <= n);
      n -= i;
      ctx->buf_off += i;
      assert(ctx->buf_off <= (int)sizeof(ctx->buf));
      assert(ctx->buf_len >= ctx->buf_off);
    }
    ctx->buf_len = 0;
    ctx->buf_off = 0;
  }
  return ret;
}
コード例 #25
0
ファイル: base64_bio.c プロジェクト: 0x64616E69656C/boringssl
static long b64_ctrl(BIO *b, int cmd, long num, void *ptr) {
  BIO_B64_CTX *ctx;
  long ret = 1;
  int i;

  ctx = (BIO_B64_CTX *)b->ptr;

  switch (cmd) {
    case BIO_CTRL_RESET:
      ctx->cont = 1;
      ctx->start = 1;
      ctx->encode = B64_NONE;
      ret = BIO_ctrl(b->next_bio, cmd, num, ptr);
      break;

    case BIO_CTRL_EOF:  // More to read
      if (ctx->cont <= 0) {
        ret = 1;
      } else {
        ret = BIO_ctrl(b->next_bio, cmd, num, ptr);
      }
      break;

    case BIO_CTRL_WPENDING:  // More to write in buffer
      assert(ctx->buf_len >= ctx->buf_off);
      ret = ctx->buf_len - ctx->buf_off;
      if ((ret == 0) && (ctx->encode != B64_NONE) && (ctx->base64.data_used != 0)) {
        ret = 1;
      } else if (ret <= 0) {
        ret = BIO_ctrl(b->next_bio, cmd, num, ptr);
      }
      break;

    case BIO_CTRL_PENDING:  // More to read in buffer
      assert(ctx->buf_len >= ctx->buf_off);
      ret = ctx->buf_len - ctx->buf_off;
      if (ret <= 0) {
        ret = BIO_ctrl(b->next_bio, cmd, num, ptr);
      }
      break;

    case BIO_CTRL_FLUSH:
    // do a final write
    again:
      while (ctx->buf_len != ctx->buf_off) {
        i = b64_write(b, NULL, 0);
        if (i < 0) {
          return i;
        }
      }
      if (BIO_test_flags(b, BIO_FLAGS_BASE64_NO_NL)) {
        if (ctx->tmp_len != 0) {
          ctx->buf_len = EVP_EncodeBlock((uint8_t *)ctx->buf,
                                         (uint8_t *)ctx->tmp, ctx->tmp_len);
          ctx->buf_off = 0;
          ctx->tmp_len = 0;
          goto again;
        }
      } else if (ctx->encode != B64_NONE && ctx->base64.data_used != 0) {
        ctx->buf_off = 0;
        EVP_EncodeFinal(&(ctx->base64), (uint8_t *)ctx->buf, &(ctx->buf_len));
        // push out the bytes
        goto again;
      }
      // Finally flush the underlying BIO
      ret = BIO_ctrl(b->next_bio, cmd, num, ptr);
      break;

    case BIO_C_DO_STATE_MACHINE:
      BIO_clear_retry_flags(b);
      ret = BIO_ctrl(b->next_bio, cmd, num, ptr);
      BIO_copy_next_retry(b);
      break;

    case BIO_CTRL_INFO:
    case BIO_CTRL_GET:
    case BIO_CTRL_SET:
    default:
      ret = BIO_ctrl(b->next_bio, cmd, num, ptr);
      break;
  }
  return ret;
}
コード例 #26
0
BST_ERR_ENUM_UINT8  BST_CORE_EncryptChk ( BST_CORE_PID_ENUM_UINT16  enPid,
                                          const BST_VOID           *pvData,
                                          BST_UINT16                usLen,
                                          BST_VOID                **ppOutData,
                                          BST_UINT16               *pusOutLen )
{
    BST_ERR_ENUM_UINT8                  enRet;
    BST_UINT32                          ulInLen;
    BST_UINT32                          ulOutLen;
    BST_UINT32                          ulBase64DataLen;
    BST_UINT8                          *pucIn;
    BST_UINT8                          *pucOut;
    BST_UINT8                          *pucBase64Data;
    ulInLen                             = 0;
    ulOutLen                            = 0;
    ulBase64DataLen                     = 0;
    pucIn                               = BST_NULL_PTR;
    pucOut                              = BST_NULL_PTR;
    pucBase64Data                       = BST_NULL_PTR;
    enRet                               = BST_NO_ERROR_MSG;

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

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

    if ( CheckIfEcryOrDecry ( enPid ) )
    {

        pucIn                           = ( BST_UINT8 * )BST_OS_MALLOC ( usLen );

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

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

        pucOut                           = ( BST_UINT8 * )BST_OS_MALLOC ( ulInLen + EVP_MAX_IV_LENGTH );

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

        enRet                           = EncryptInternal ( ( BST_UINT8 * )pucIn,
                                                            ulInLen,
                                                            pucOut,
                                                            &ulOutLen,
                                                            gs_BastetDsppKey );

        if ( BST_NO_ERROR_MSG == enRet )
        {
            pucBase64Data = ( BST_UINT8 * )BST_OS_MALLOC ( ulOutLen * 2 );

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

            ulBase64DataLen = EVP_EncodeBlock ( pucBase64Data, pucOut, ulOutLen );
            *ppOutData = pucBase64Data;
            *pusOutLen = ulBase64DataLen;
        }

        BST_OS_FREE ( pucIn );
        pucIn = BST_NULL_PTR;
        BST_OS_FREE ( pucOut );
        pucOut = BST_NULL_PTR;

        return enRet;
    }

    return BST_NO_ERROR_MSG;
}
コード例 #27
0
ファイル: bio_b64.c プロジェクト: AndreV84/openssl
static int b64_write(BIO *b, const char *in, int inl)
{
    int ret = 0;
    int n;
    int i;
    BIO_B64_CTX *ctx;

    ctx = (BIO_B64_CTX *)b->ptr;
    BIO_clear_retry_flags(b);

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

    OPENSSL_assert(ctx->buf_off < (int)sizeof(ctx->buf));
    OPENSSL_assert(ctx->buf_len <= (int)sizeof(ctx->buf));
    OPENSSL_assert(ctx->buf_len >= ctx->buf_off);
    n = ctx->buf_len - ctx->buf_off;
    while (n > 0) {
        i = BIO_write(b->next_bio, &(ctx->buf[ctx->buf_off]), n);
        if (i <= 0) {
            BIO_copy_next_retry(b);
            return (i);
        }
        OPENSSL_assert(i <= n);
        ctx->buf_off += i;
        OPENSSL_assert(ctx->buf_off <= (int)sizeof(ctx->buf));
        OPENSSL_assert(ctx->buf_len >= ctx->buf_off);
        n -= i;
    }
    /* at this point all pending data has been written */
    ctx->buf_off = 0;
    ctx->buf_len = 0;

    if ((in == NULL) || (inl <= 0))
        return (0);

    while (inl > 0) {
        n = (inl > B64_BLOCK_SIZE) ? B64_BLOCK_SIZE : inl;

        if (BIO_get_flags(b) & BIO_FLAGS_BASE64_NO_NL) {
            if (ctx->tmp_len > 0) {
                OPENSSL_assert(ctx->tmp_len <= 3);
                n = 3 - ctx->tmp_len;
                /*
                 * There's a theoretical possibility for this
                 */
                if (n > inl)
                    n = inl;
                memcpy(&(ctx->tmp[ctx->tmp_len]), in, n);
                ctx->tmp_len += n;
                ret += n;
                if (ctx->tmp_len < 3)
                    break;
                ctx->buf_len =
                    EVP_EncodeBlock((unsigned char *)ctx->buf,
                                    (unsigned char *)ctx->tmp, ctx->tmp_len);
                OPENSSL_assert(ctx->buf_len <= (int)sizeof(ctx->buf));
                OPENSSL_assert(ctx->buf_len >= ctx->buf_off);
                /*
                 * Since we're now done using the temporary buffer, the
                 * length should be 0'd
                 */
                ctx->tmp_len = 0;
            } else {
                if (n < 3) {
                    memcpy(ctx->tmp, in, n);
                    ctx->tmp_len = n;
                    ret += n;
                    break;
                }
                n -= n % 3;
                ctx->buf_len =
                    EVP_EncodeBlock((unsigned char *)ctx->buf,
                                    (const unsigned char *)in, n);
                OPENSSL_assert(ctx->buf_len <= (int)sizeof(ctx->buf));
                OPENSSL_assert(ctx->buf_len >= ctx->buf_off);
                ret += n;
            }
        } else {
            EVP_EncodeUpdate(ctx->base64,
                             (unsigned char *)ctx->buf, &ctx->buf_len,
                             (unsigned char *)in, n);
            OPENSSL_assert(ctx->buf_len <= (int)sizeof(ctx->buf));
            OPENSSL_assert(ctx->buf_len >= ctx->buf_off);
            ret += n;
        }
        inl -= n;
        in += n;

        ctx->buf_off = 0;
        n = ctx->buf_len;
        while (n > 0) {
            i = BIO_write(b->next_bio, &(ctx->buf[ctx->buf_off]), n);
            if (i <= 0) {
                BIO_copy_next_retry(b);
                return ((ret == 0) ? i : ret);
            }
            OPENSSL_assert(i <= n);
            n -= i;
            ctx->buf_off += i;
            OPENSSL_assert(ctx->buf_off <= (int)sizeof(ctx->buf));
            OPENSSL_assert(ctx->buf_len >= ctx->buf_off);
        }
        ctx->buf_len = 0;
        ctx->buf_off = 0;
    }
    return (ret);
}
コード例 #28
0
ファイル: bio_b64.c プロジェクト: AndreV84/openssl
static long b64_ctrl(BIO *b, int cmd, long num, void *ptr)
{
    BIO_B64_CTX *ctx;
    long ret = 1;
    int i;

    ctx = (BIO_B64_CTX *)b->ptr;

    switch (cmd) {
    case BIO_CTRL_RESET:
        ctx->cont = 1;
        ctx->start = 1;
        ctx->encode = B64_NONE;
        ret = BIO_ctrl(b->next_bio, cmd, num, ptr);
        break;
    case BIO_CTRL_EOF:         /* More to read */
        if (ctx->cont <= 0)
            ret = 1;
        else
            ret = BIO_ctrl(b->next_bio, cmd, num, ptr);
        break;
    case BIO_CTRL_WPENDING:    /* More to write in buffer */
        OPENSSL_assert(ctx->buf_len >= ctx->buf_off);
        ret = ctx->buf_len - ctx->buf_off;
        if ((ret == 0) && (ctx->encode != B64_NONE)
            && (EVP_ENCODE_CTX_num(ctx->base64) != 0))
            ret = 1;
        else if (ret <= 0)
            ret = BIO_ctrl(b->next_bio, cmd, num, ptr);
        break;
    case BIO_CTRL_PENDING:     /* More to read in buffer */
        OPENSSL_assert(ctx->buf_len >= ctx->buf_off);
        ret = ctx->buf_len - ctx->buf_off;
        if (ret <= 0)
            ret = BIO_ctrl(b->next_bio, cmd, num, ptr);
        break;
    case BIO_CTRL_FLUSH:
        /* do a final write */
 again:
        while (ctx->buf_len != ctx->buf_off) {
            i = b64_write(b, NULL, 0);
            if (i < 0)
                return i;
        }
        if (BIO_get_flags(b) & BIO_FLAGS_BASE64_NO_NL) {
            if (ctx->tmp_len != 0) {
                ctx->buf_len = EVP_EncodeBlock((unsigned char *)ctx->buf,
                                               (unsigned char *)ctx->tmp,
                                               ctx->tmp_len);
                ctx->buf_off = 0;
                ctx->tmp_len = 0;
                goto again;
            }
        } else if (ctx->encode != B64_NONE
                   && EVP_ENCODE_CTX_num(ctx->base64) != 0) {
            ctx->buf_off = 0;
            EVP_EncodeFinal(ctx->base64,
                            (unsigned char *)ctx->buf, &(ctx->buf_len));
            /* push out the bytes */
            goto again;
        }
        /* Finally flush the underlying BIO */
        ret = BIO_ctrl(b->next_bio, cmd, num, ptr);
        break;

    case BIO_C_DO_STATE_MACHINE:
        BIO_clear_retry_flags(b);
        ret = BIO_ctrl(b->next_bio, cmd, num, ptr);
        BIO_copy_next_retry(b);
        break;

    case BIO_CTRL_DUP:
        break;
    case BIO_CTRL_INFO:
    case BIO_CTRL_GET:
    case BIO_CTRL_SET:
    default:
        ret = BIO_ctrl(b->next_bio, cmd, num, ptr);
        break;
    }
    return (ret);
}
コード例 #29
0
ファイル: open-enc.cpp プロジェクト: BackupTheBerlios/smx-svn
int B64_encode(const char *strin, char *strout, int cbstr)
{
	return EVP_EncodeBlock((unsigned char*)strout, (unsigned char*)strin, cbstr);
}
コード例 #30
0
ファイル: hip_dht.c プロジェクト: carriercomm/openhip
/*
 * \fn hip_xmlrpc_getput()
 *
 * \param mode		determines get or put, app, retry on/off
 *		         If retry is off only one attempt should be made,
 *                       on means the connect() should keep retrying
 * \param app		string to use in the XML RPC application field
 * \param server	server address and port to connect to
 * \param key           DHT key used for get or put
 * \param key_len	length of DHT key in bytes
 * \param value		DHT value used for put, ptr for storing value for get
 * \param value_len	ptr to length of value buffer, length of get is returned
 * \param secret	secret value used to make put removable
 * \param secret_len	length of secret value
 * \param ttl		time to live in seconds
 *
 * \brief Perform the XML RPC GET, PUT, and RM operations.
 */
int hip_xmlrpc_getput(int mode, char *app, struct sockaddr *server,
                      char *key, int key_len, char *value, int *value_len,
                      char *secret, int secret_len, int ttl)
{
  xmlDocPtr doc = NULL;
  xmlNodePtr root_node = NULL, node;
  int len = 0, s, retval = 0;
  char buff[2048], oper[14];
  unsigned char key64[2 * DHT_KEY_SIZE], val64[2 * DHT_VAL_SIZE];
  unsigned char tmp[2 * DHT_VAL_SIZE], *xmlbuff = NULL;
  fd_set read_fdset;
  struct timeval timeout, now;
  char *p;
  unsigned int retry_attempts = 0;
  struct sockaddr_in src_addr;
  struct dht_val *dv, rm;
  SHA_CTX c;
  __u8 secret_hash[SHA_DIGEST_LENGTH], value_hash[SHA_DIGEST_LENGTH];
  int rm_ttl = 0, value_hash_len;

  int retry = ((mode & 0x00F0) == XMLRPC_MODE_RETRY_ON);

  if ((key_len > (2 * DHT_KEY_SIZE)) ||
      (*value_len > (2 * DHT_VAL_SIZE)))
    {
      return(-1);
    }

  /*
   * support for removable puts
   */
  memset(&rm, 0, sizeof(struct dht_val));
  if ((mode & 0x000F) == XMLRPC_MODE_PUT)
    {
      /*
       * produce hashes of the secret and the value, for later removal
       */
      SHA1_Init(&c);
      SHA1_Update(&c, value, *value_len);
      SHA1_Final(value_hash, &c);
      SHA1_Init(&c);
      SHA1_Update(&c, secret, secret_len);
      SHA1_Final(secret_hash, &c);

      /*
       * check if we already published a record with this key; record
       * this new secret value and value_hash
       */
      pthread_mutex_lock(&dht_vals_lock);
      gettimeofday(&now, NULL);
      dv = lookup_dht_val(key);
      if (dv)
        {
          /* save old secret so we can remove it later below */
          memcpy(&rm, &dv, sizeof(struct dht_val));
          /* any time left for removing the old record? */
          rm_ttl = TDIFF(rm.expire_time, now);
        }
      else
        {
          dv = insert_dht_val(key);
        }
      strncpy(dv->app, app, sizeof(dv->app));
      dv->value_hash_len = SHA_DIGEST_LENGTH;
      memcpy(dv->value_hash, value_hash, SHA_DIGEST_LENGTH);
      dv->secret_len = secret_len;
      memcpy(dv->secret, secret, secret_len);
      dv->expire_time.tv_usec = now.tv_usec;
      dv->expire_time.tv_sec = now.tv_sec + ttl;
      pthread_mutex_unlock(&dht_vals_lock);
    }

  switch (mode & 0x000F)
    {
    case XMLRPC_MODE_PUT:
      sprintf(oper, "put_removable");
      break;
    case XMLRPC_MODE_GET:
      sprintf(oper, "get");
      break;
    case XMLRPC_MODE_RM:
      sprintf(oper, "rm");
      break;
    default:
      log_(WARN, "Invalid XMLRPC mode given to DHT.\n");
      return(-1);
    }

  /*
   * create a new XML document
   */
  doc = xmlNewDoc(BAD_CAST "1.0");
  root_node = xmlNewNode(NULL, BAD_CAST "methodCall");
  xmlDocSetRootElement(doc, root_node);
  node = xmlNewChild(root_node, NULL, BAD_CAST "methodName",
                     BAD_CAST oper);
  node = xmlNewChild(root_node, NULL, BAD_CAST "params", NULL);
  memset(tmp, 0, sizeof(tmp));
  memcpy(tmp, key, key_len);
  EVP_EncodeBlock(key64, tmp, key_len);
  xml_new_param(node, "base64", (char *)key64);                 /* key */
  /* log_(NORM, "Doing %s using key(%d)=",
   *    ((mode & 0x000F)==XMLRPC_MODE_PUT) ? "PUT":"GET", key_len);
   *  print_hex(key, key_len);
   *  log_(NORM, " [%s]\n", key64); // */
  switch (mode & 0x000F)
    {
    case XMLRPC_MODE_PUT:
      memset(tmp, 0, sizeof(tmp));
      memcpy(tmp, value, *value_len);
      EVP_EncodeBlock(val64, tmp, *value_len);
      xml_new_param(node, "base64", (char *)val64);             /* value */
      xml_new_param(node, "string", "SHA");                     /* hash type */
      memset(tmp, 0, sizeof(tmp));
      memcpy(tmp, secret_hash, SHA_DIGEST_LENGTH);
      EVP_EncodeBlock(val64, tmp, SHA_DIGEST_LENGTH);
      xml_new_param(node, "base64", (char *)val64);            /* secret_hash */
      sprintf((char *)tmp, "%d", ttl);
      xml_new_param(node, "int", (char *)tmp);                  /* lifetime */
      break;
    case XMLRPC_MODE_GET:
      xml_new_param(node, "int", "10");                 /* maxvals */
      xml_new_param(node, "base64", "");                /* placemark */
      memset(value, 0, *value_len);
      break;
    case XMLRPC_MODE_RM:
      memset(tmp, 0, sizeof(tmp));
      memcpy(tmp, value_hash, SHA_DIGEST_LENGTH);
      EVP_EncodeBlock(val64, tmp, SHA_DIGEST_LENGTH);
      xml_new_param(node, "base64", (char *)val64);             /* value_hash */
      xml_new_param(node, "string", "SHA");                     /* hash type */
      memset(tmp, 0, sizeof(tmp));
      memcpy(tmp, secret, secret_len);
      EVP_EncodeBlock(val64, tmp, secret_len);
      xml_new_param(node, "base64", (char *)val64);             /* secret */
      sprintf((char *)tmp, "%d", ttl);
      xml_new_param(node, "int", (char *)tmp);                  /* lifetime */
    }
  xml_new_param(node, "string", app);                   /* app */
  xmlDocDumpFormatMemory(doc, &xmlbuff, &len, 0);

  /*
   * Build an HTTP POST and transmit to server
   */
  memset(buff, 0, sizeof(buff));
  build_http_post_header(buff, len, server);       /* len is XML length above */
  memcpy(&buff[strlen(buff)], xmlbuff, len);
  xmlFree(xmlbuff);
  len = strlen(buff) + 1;
connect_retry:
  /* Connect and send the XML RPC */
  if ((s = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0)
    {
      log_(WARN, "DHT connect - socket error: %s\n", strerror(errno));
      retval = -1;
      goto putget_exit;
    }
  /* Use the preferred address as source */
  memset(&src_addr, 0, sizeof(src_addr));
  src_addr.sin_family = AF_INET;
  src_addr.sin_addr.s_addr = get_preferred_addr();
  if (!src_addr.sin_addr.s_addr)
    {
      log_(NORM, "No preferred address, deferring DHT!\n");
      return(-1);
    }
  log_(NORM, "Using source address of %s for DHT %s.\n",
       logaddr(SA(&src_addr)), oper);
  fflush(stdout);
  if (bind(s, SA(&src_addr), SALEN(&src_addr)) < 0)
    {
      log_(WARN, "DHT connect - bind error: %s\n", strerror(errno));
    }

  if (g_state != 0)
    {
      return(-1);
    }
  if (retry && (retry_attempts > 0))
    {
      /* quit after a certain number of retries */
      if (retry_attempts >= HCNF.max_retries)
        {
          retval = -2;
          goto putget_exit;
        }
      /* wait packet_timeout seconds before retrying */
      hip_sleep(HCNF.packet_timeout);
    }
  retry_attempts++;

  if (connect(s, server, SALEN(server)) < 0)
    {
      log_(WARN, "DHT server connect error: %s\n", strerror(errno));
      closesocket(s);
#ifdef __WIN32__
      errno = WSAGetLastError();
      if (retry && ((errno == WSAETIMEDOUT) ||
                    (errno == WSAENETUNREACH)))
        {
          goto connect_retry;
        }
#else
      if (retry &&
          ((errno == ETIMEDOUT) || (errno == EHOSTUNREACH)))
        {
          goto connect_retry;
        }
#endif
      retval = -3;
      goto putget_exit;
    }

  if (send(s, buff, len, 0) != len)
    {
      log_(WARN, "DHT sent incorrect number of bytes\n");
      retval = -4;
      goto putget_exit;
    }
  xmlFreeDoc(doc);
  doc = NULL;

  /*
   * Receive XML RPC response from server
   */
  FD_ZERO(&read_fdset);
  FD_SET((unsigned int)s, &read_fdset);
  /* use longer timeout when retry==TRUE, because we have own thread */
  if (retry)
    {
      timeout.tv_sec = 3;
      timeout.tv_usec = 0;
    }
  else
    {
      timeout.tv_sec = 0;
      timeout.tv_usec = 300000;           /* 300ms */
    }
  if (select(s + 1, &read_fdset, NULL, NULL, &timeout) < 0)
    {
      log_(WARN, "DHT select error: %s\n", strerror(errno));
      retval = -5;
      goto putget_exit;
    }
  else if (FD_ISSET(s, &read_fdset))
    {
      if ((len = recv(s, buff, sizeof(buff) - 1, 0)) <= 0)
        {
          log_(WARN, "DHT error receiving from server: %s\n",
               strerror(errno));
          retval = -6;
          goto putget_exit;
        }
      if (strncmp(buff, "HTTP", 4) != 0)
        {
          return(-7);
        }
      if ((p = strstr(buff, "Content-Length: ")) == NULL)
        {
          return(-8);
        }
      else               /* advance ptr to Content-Length */
        {
          p += 16;
        }
      sscanf(p, "%d", &len);
      p = strchr(p, '\n') + 3;           /* advance to end of line */
      retval = hip_xmlrpc_parse_response(mode, p, len,
                                         value, value_len);
      log_(NORM, "DHT server responded with return code %d (%s).\n",
           retval, hip_xmlrpc_resp_to_str(retval));
    }
  else
    {
      /* select timeout */
      if (retry)             /* XXX testme: retry select instead? */
        {
          goto connect_retry;
        }
      retval = -9;
    }

putget_exit:
#ifdef __WIN32__
  closesocket(s);
#else
  close(s);
#endif
  if (doc != NULL)
    {
      xmlFreeDoc(doc);
    }
  if (rm_ttl > 0)
    {
      value_hash_len = sizeof(rm.value_hash);
      hip_xmlrpc_getput(((mode & 0x00F0) | XMLRPC_MODE_RM),
                        app, server, key, key_len,
                        (char *)rm.value_hash, &value_hash_len,
                        (char *)rm.secret, secret_len, rm_ttl);
    }
  return(retval);
}