Exemple #1
0
static BIGNUM * calculate_x( SRP_HashAlgorithm alg, const BIGNUM * salt, const char * username, const unsigned char * password, int password_len )
{
    unsigned char ucp_hash[SHA512_DIGEST_LENGTH];
    HashCTX       ctx;

    hash_init( alg, &ctx );

    hash_update( alg, &ctx, username, strlen(username) );
    hash_update( alg, &ctx, ":", 1 );
    hash_update( alg, &ctx, password, password_len );
    
    hash_final( alg, &ctx, ucp_hash );
        
    return H_ns( alg, salt, ucp_hash, hash_length(alg) );
}
Exemple #2
0
static PyObject *
hash_digest (const hash_state *self)
{
	U8 padding[16];
	U32 padlen;
	hash_state temp;
	unsigned int i;
  
	memcpy(&temp, self, sizeof(hash_state));
	padlen= 16-self->count;
	for(i=0; i<padlen; i++) padding[i]=padlen;
	hash_update(&temp, padding, padlen);
	hash_update(&temp, temp.C, 16);
	return PyBytes_FromStringAndSize((char *) temp.X, 16);
}
Exemple #3
0
static void hash_bytes(const byte t, const byte * const b, const size_t l,
                       hash hash) {
  hash_ctx ctx;
  hash_init(&ctx, t);
  hash_update(&ctx, b, l);
  hash_final(&ctx, hash);
}
Exemple #4
0
static int calculate_x(mpz_t result, SRP_HashAlgorithm alg, const unsigned char *salt, size_t salt_len, const char *username, const unsigned char *password, size_t password_len)
{
	unsigned char ucp_hash[SHA512_DIGEST_LENGTH];
	HashCTX ctx;
	hash_init(alg, &ctx);

	srp_dbg_data((char*) username, strlen(username), "Username for x: ");
	srp_dbg_data((char*) password, password_len, "Password for x: ");
	hash_update(alg, &ctx, username, strlen(username));
	hash_update(alg, &ctx, ":", 1);
	hash_update(alg, &ctx, password, password_len);

	hash_final(alg, &ctx, ucp_hash);

	return H_ns(result, alg, salt, salt_len, ucp_hash, hash_length(alg));
}
Exemple #5
0
int
ikev2_msg_integr(struct iked *env, struct iked_sa *sa, struct ibuf *src)
{
	int			 ret = -1;
	size_t			 integrlen, tmplen;
	struct ibuf		*integr, *prf, *tmp = NULL;
	u_int8_t		*ptr;

	log_debug("%s: message length %d", __func__, ibuf_size(src));
	print_hex(ibuf_data(src), 0, ibuf_size(src));

	if (sa == NULL ||
	    sa->sa_integr == NULL) {
		log_debug("%s: invalid SA", __func__);
		return (-1);
	}

	if (sa->sa_hdr.sh_initiator) {
		integr = sa->sa_key_iauth;
		prf = sa->sa_key_iprf;
	} else {
		integr = sa->sa_key_rauth;
		prf = sa->sa_key_rprf;
	}

	integrlen = hash_length(sa->sa_integr);

	log_debug("%s: integrity checksum length %d", __func__,
	    integrlen);

	/*
	 * Validate packet checksum
	 */
	if ((tmp = ibuf_new(NULL, hash_keylength(sa->sa_integr))) == NULL)
		goto done;

	hash_setkey(sa->sa_integr, ibuf_data(integr), ibuf_size(integr));
	hash_init(sa->sa_integr);
	hash_update(sa->sa_integr, ibuf_data(src),
	    ibuf_size(src) - integrlen);
	hash_final(sa->sa_integr, ibuf_data(tmp), &tmplen);

	if (tmplen != integrlen) {
		log_debug("%s: hash failure", __func__);
		goto done;
	}

	if ((ptr = ibuf_seek(src,
	    ibuf_size(src) - integrlen, integrlen)) == NULL)
		goto done;
	memcpy(ptr, ibuf_data(tmp), tmplen);

	print_hex(ibuf_data(tmp), 0, ibuf_size(tmp));

	ret = 0;
 done:
	ibuf_release(tmp);

	return (ret);
}
Exemple #6
0
static void hash_init(hash_ctx * const c, const byte t) {
  SHA256_Init(c);

  byte b[1];
  b[0] = t;
  hash_update(c, b, 1);
}
Exemple #7
0
struct ibuf *
ikev2_msg_auth(struct iked *env, struct iked_sa *sa, int response)
{
	struct ibuf		*authmsg = NULL, *nonce, *prfkey, *buf;
	uint8_t			*ptr;
	struct iked_id		*id;
	size_t			 tmplen;

	/*
	 * Create the payload to be signed/MAC'ed for AUTH
	 */

	if (!response) {
		if ((nonce = sa->sa_rnonce) == NULL ||
		    (sa->sa_iid.id_type == 0) ||
		    (prfkey = sa->sa_key_iprf) == NULL ||
		    (buf = sa->sa_1stmsg) == NULL)
			return (NULL);
		id = &sa->sa_iid;
	} else {
		if ((nonce = sa->sa_inonce) == NULL ||
		    (sa->sa_rid.id_type == 0) ||
		    (prfkey = sa->sa_key_rprf) == NULL ||
		    (buf = sa->sa_2ndmsg) == NULL)
			return (NULL);
		id = &sa->sa_rid;
	}

	if ((authmsg = ibuf_dup(buf)) == NULL)
		return (NULL);
	if (ibuf_cat(authmsg, nonce) != 0)
		goto fail;

	if ((hash_setkey(sa->sa_prf, ibuf_data(prfkey),
	    ibuf_size(prfkey))) == NULL)
		goto fail;

	if ((ptr = ibuf_advance(authmsg,
	    hash_length(sa->sa_prf))) == NULL)
		goto fail;

	hash_init(sa->sa_prf);
	hash_update(sa->sa_prf, ibuf_data(id->id_buf), ibuf_size(id->id_buf));
	hash_final(sa->sa_prf, ptr, &tmplen);

	if (tmplen != hash_length(sa->sa_prf))
		goto fail;

	log_debug("%s: %s auth data length %zu",
	    __func__, response ? "responder" : "initiator",
	    ibuf_size(authmsg));
	print_hex(ibuf_data(authmsg), 0, ibuf_size(authmsg));

	return (authmsg);

 fail:
	ibuf_release(authmsg);
	return (NULL);
}
Exemple #8
0
static void update_hash_n( SRP_HashAlgorithm alg, HashCTX *ctx, const BIGNUM * n )
{
    unsigned long len = BN_num_bytes(n);
    unsigned char * n_bytes = (unsigned char *) malloc( len );
    BN_bn2bin(n, n_bytes);
    hash_update(alg, ctx, n_bytes, len);
    free(n_bytes);
}
Exemple #9
0
CK_RV C_DigestUpdate(CK_SESSION_HANDLE hSession,  /* the session's handle */
                     CK_BYTE_PTR       pPart,     /* data to be digested */
                     CK_ULONG          ulPartLen) /* bytes of data to be digested */
{
   int ret;
   P11_SESSION *pSession = NULL;
   P11_DIGEST_DATA *pDigestData = NULL;

	if (p11_get_init() != BEIDP11_INITIALIZED)
	{
		log_trace(WHERE, "I: leave, CKR_CRYPTOKI_NOT_INITIALIZED");
		return (CKR_CRYPTOKI_NOT_INITIALIZED);
	}		

   ret = p11_lock();
   if (ret != CKR_OK)
          return ret;

	 log_trace(WHERE, "I: enter");

   ret = p11_get_session(hSession, &pSession);
   if (ret)
      {
      log_trace(WHERE, "E: Invalid session handle (%d)", hSession);
      goto cleanup;
      }

   //is there an active search operation for this session
   if (pSession->Operation[P11_OPERATION_DIGEST].active == 0)
      {
      log_trace(WHERE, "E: Session %d: no digest operation initialized", hSession);
      ret = CKR_OPERATION_NOT_INITIALIZED;
      goto cleanup;
      }

   /* get digest operation */
   if((pDigestData = pSession->Operation[P11_OPERATION_DIGEST].pData) == NULL)
      {
      log_trace( WHERE, "E: no digest operation initialized");
      ret = CKR_OPERATION_NOT_INITIALIZED;
      goto cleanup;
      }

   ret = hash_update(pDigestData->phash, (char*)pPart, ulPartLen);
   if(ret)
      {
      log_trace(WHERE, "E: hash_update failed()");
      ret = CKR_FUNCTION_FAILED;
      goto cleanup;
      }

cleanup:
   p11_unlock();
	 log_trace(WHERE, "I: leave, ret = 0x%08x",ret);

return ret;
}
Exemple #10
0
/* changes a nick in the hashlist */
void db_chgnick(char *newnick, char *oldnick)
{
#ifdef HASHLISTSUPPORT
	/* people often change from NICK-sthing to NICK-sthing */
	strtolwr(newnick);
	strtolwr(oldnick);
	hash_update(hashnicks, newnick, oldnick, KEYOTHER);
#endif
}
Exemple #11
0
static void update_hash_n(SRP_HashAlgorithm alg, HashCTX *ctx, const mpz_t n)
{
	size_t len = mpz_num_bytes(n);
	unsigned char* n_bytes = (unsigned char *) malloc(len);
	if (!n_bytes)
		return;
	mpz_to_bin(n, n_bytes);
	hash_update(alg, ctx, n_bytes, len);
	free(n_bytes);
}
Exemple #12
0
static SRP_Result update_hash_n(SRP_HashAlgorithm alg, HashCTX *ctx, const mpz_t n)
{
	size_t len = mpz_num_bytes(n);
	unsigned char *n_bytes = (unsigned char *)srp_alloc(len);
	if (!n_bytes) return SRP_ERR;
	mpz_to_bin(n, n_bytes);
	hash_update(alg, ctx, n_bytes, len);
	srp_free(n_bytes);
	return SRP_OK;
}
Exemple #13
0
NTSTATUS WINAPI BCryptHashData( BCRYPT_HASH_HANDLE handle, UCHAR *input, ULONG size, ULONG flags )
{
    struct hash *hash = handle;

    TRACE( "%p, %p, %u, %08x\n", handle, input, size, flags );

    if (!hash || hash->hdr.magic != MAGIC_HASH) return STATUS_INVALID_HANDLE;
    if (!input) return STATUS_SUCCESS;

    return hash_update( &hash->inner, hash->alg_id, input, size );
}
Exemple #14
0
//----------------------------------------------------------------------
void h_final(unsigned char hmac[HASH_DIGEST_SIZE])
{
  // Finish inner hash
	hash_final(hmac);

  // Outer hash
  hash_init();

  // Outer padding (opad) from inner padding
  for (size_t n = 0; n < sizeof(g_k_opad); ++n) {
    g_k_opad[n] ^= (0x36 ^ 0x5C);
  }
  hash_update(g_k_opad, sizeof(g_k_opad));
  // Finish HMAC
  hash_update(hmac, HASH_DIGEST_SIZE);
  hash_final(hmac);

  // Cleanup
  memset(g_k_opad, 0, sizeof(g_k_opad));
}
Exemple #15
0
int MD5_testRun(void)
{
	int i;
	MD5_Context context;
	MD5_init(&context);

	hash_begin(&context.h);
	hash_update(&context.h, "abc", 3);
	ASSERT(memcmp(hash_final(&context.h), "\x90\x01\x50\x98\x3C\xD2\x4F\xB0\xD6\x96\x3F\x7D\x28\xE1\x7F\x72", 16) == 0);

	hash_begin(&context.h);
	hash_update(&context.h, "aaa", 3);
	ASSERT(memcmp(hash_final(&context.h), "\x47\xBC\xE5\xC7\x4F\x58\x9F\x48\x67\xDB\xD5\x7E\x9C\xA9\xF8\x08", 16) == 0);

	hash_begin(&context.h);
	hash_update(&context.h, "abcdefghijklmnopqrstuvwxyz", 26);
	ASSERT(memcmp(hash_final(&context.h), "\xC3\xFC\xD3\xD7\x61\x92\xE4\x00\x7D\xFB\x49\x6C\xCA\x67\xE1\x3B", 16) == 0);

	hash_begin(&context.h);
	hash_update(&context.h, "0123456789", 10);
	ASSERT(memcmp(hash_final(&context.h), "\x78\x1E\x5E\x24\x5D\x69\xB5\x66\x97\x9B\x86\xE2\x8D\x23\xF2\xC7", 16) == 0);

	hash_begin(&context.h);
	for (i = 0; i < 1000; i++)
		hash_update(&context.h, "a", 1);
	ASSERT(memcmp(hash_final(&context.h), "\xCA\xBE\x45\xDC\xC9\xAE\x5B\x66\xBA\x86\x60\x0C\xCA\x6B\x8B\xA8", 16) == 0);

	hash_begin(&context.h);
	for (i = 0; i < 1000000; i++)
		hash_update(&context.h, "a", 1);
	ASSERT(memcmp(hash_final(&context.h), "\x77\x07\xd6\xae\x4e\x02\x7c\x70\xee\xa2\xa9\x35\xc2\x29\x6f\x21", 16) == 0);
	
	return 0;
}
Exemple #16
0
void CW_each_document(unsigned int target, unsigned int *words, unsigned int length)
{
    if (static_cw_model->skip_documents > 0) {
        static_cw_model->skip_documents--;
        static_cw_model->document_index++;
        return;
    }
    
    if(length < 1)
    	return;
    
    // Look up the target index for this +target+
    hash_element *element = hash_get(static_cw_model->wordmap_to_target, target);
    int index = 0; // +index+ is the index in model->targets for this target
    if (element != NULL) {
        // Success! We've seen this word before.
        index = element->value;
    } else {
        // +target+ is a new word, so add it.
        index = static_cw_model->num_targets++;
        int category = static_cw_model->num_categories++;
        hash_add(static_cw_model->wordmap_to_target, target, index);
        unsigned_array_set(static_cw_model->assignments, index, category);
        static_cw_model->targets[index] = hash_new(32);
    }
    
    // Update the frequency counts for this target
    for (int i=0; i<length; i++) {
        //model->targets[i] is f_ij, where i is the target word and j is the context word
        hash_update(static_cw_model->targets[index], words[i], 1);
        static_cw_model->f_xx++;
        
        // Also update the frequency count for this context word
        hash_update(static_cw_model->context_counts, words[i], 1);
    }
    
    progressbar_inc(static_progress);
    static_cw_model->document_index++;
}
Exemple #17
0
static void calculate_y2(uint8_t *ims, uint8_t *y2) {
    /* Y2 = sha256(IMS[0:31] xor copy(0x5a, 32)) */
    uint32_t i;
    uint32_t temp;
    uint32_t *pims = (uint32_t *)ims;

    hash_start();
    /* grab IMS 4bytes at a time and feed that to hash_update */
    for (i = 0; i < 8; i++) {
        temp = pims[i] ^ 0x5a5a5a5a;
        hash_update((unsigned char *)&temp, sizeof(temp));
    }
    hash_final(y2);
}
Exemple #18
0
static int data_load_mmapped_load(void *dest, uint32_t length, bool hash) {
    if(initialized != 1 ||
       current_addr + length >= (uint8_t*)(MMAP_LOAD_BASE + MMAP_LOAD_SIZE))
        return -1;

    uint8_t *load_end = current_addr + length;
    uint8_t *dst;
    for (dst = (uint8_t*) dest; current_addr < load_end;)
        *dst++ = *current_addr++;

    if (hash) {
        hash_update((unsigned char *)dest, length);
    }
    return 0;
}
Exemple #19
0
static void hash_init_with_dom(
    hash_ctx_t hash,
    uint8_t prehashed,
    uint8_t for_prehash,
    const uint8_t *context,
    uint8_t context_len
) {
    hash_init(hash);

#if NO_CONTEXT
    if (context_len == 0 && context == CRYPTONITE_DECAF_ED448_NO_CONTEXT) {
        (void)prehashed;
        (void)for_prehash;
        (void)context;
        (void)context_len;
        return;
    }
#endif
    const char *dom_s = "SigEd448";
    const uint8_t dom[2] = {2+word_is_zero(prehashed)+word_is_zero(for_prehash), context_len};
    hash_update(hash,(const unsigned char *)dom_s, strlen(dom_s));
    hash_update(hash,dom,2);
    hash_update(hash,context,context_len);
}
Exemple #20
0
char *hash_file(const char *file) {
  int fd, cnt;
  struct hash_ctx *ctx;
  char buf[_HASH_BUFSZ], *res;

  fd = open(file, O_RDONLY);
  if (fd == -1) errormsg("open(%s)", file);

  ctx = hash_new();
  while ((cnt = read(fd,buf,sizeof buf)) > 0) {
    if (cnt == -1) errormsg("read(%s)",file);
    hash_update(ctx, buf, cnt);
  }
  close(fd);
  res = mymalloc(hash_len());
  hash_free(ctx,res);
  return res;
}
Exemple #21
0
NTSTATUS WINAPI BCryptFinishHash( BCRYPT_HASH_HANDLE handle, UCHAR *output, ULONG size, ULONG flags )
{
    UCHAR buffer[MAX_HASH_OUTPUT_BYTES];
    struct hash *hash = handle;
    NTSTATUS status;
    int hash_length;

    TRACE( "%p, %p, %u, %08x\n", handle, output, size, flags );

    if (!hash || hash->hdr.magic != MAGIC_HASH) return STATUS_INVALID_HANDLE;
    if (!output) return STATUS_INVALID_PARAMETER;

    if (!hash->hmac)
        return hash_finish( &hash->inner, hash->alg_id, output, size );

    hash_length = alg_props[hash->alg_id].hash_length;
    if ((status = hash_finish( &hash->inner, hash->alg_id, buffer, hash_length ))) return status;
    if ((status = hash_update( &hash->outer, hash->alg_id, buffer, hash_length ))) return status;
    return hash_finish( &hash->outer, hash->alg_id, output, size );
}
static void http_hash_insert(const char* name, http_atom_t* entry,
                             http_atom_t** hash, int hsize)
{
    unsigned long h = 0;
    const unsigned char* ptr = (const unsigned char*) name;
    int ix;
    int len = 0;

    while (*ptr != '\0') {
        hash_update(h, *ptr);
        ptr++;
        len++;
    }
    ix = h % hsize;

    entry->next = hash[ix];
    entry->h    = h;
    entry->name = name;
    entry->len  = len;
    entry->atom = driver_mk_atom((char*)name);

    hash[ix] = entry;
}
Exemple #23
0
CK_RV C_Digest(CK_SESSION_HANDLE hSession,     /* the session's handle */
               CK_BYTE_PTR       pData,        /* data to be digested */
               CK_ULONG          ulDataLen,    /* bytes of data to be digested */
               CK_BYTE_PTR       pDigest,      /* receives the message digest */
               CK_ULONG_PTR      pulDigestLen) /* receives byte length of digest */
{
   CK_RV ret;
   P11_SESSION *pSession = NULL;
   P11_DIGEST_DATA *pDigestData = NULL;

	if (p11_get_init() != BEIDP11_INITIALIZED)
	{
		log_trace(WHERE, "I: leave, CKR_CRYPTOKI_NOT_INITIALIZED");
		return (CKR_CRYPTOKI_NOT_INITIALIZED);
	}		

   p11_lock();

	 log_trace(WHERE, "I: enter, hSession = %i",hSession);

   ret = p11_get_session(hSession, &pSession);
   if (ret)
      {
      log_trace(WHERE, "E: Invalid session handle (%d)", hSession);
      goto cleanup;
      }

   //is there an active search operation for this session
   if ((pSession->Operation[P11_OPERATION_DIGEST].active) == 0)
      {
      log_trace(WHERE, "E: Session %d: no digest operation initialized", hSession);
      ret = CKR_OPERATION_NOT_INITIALIZED;
      goto cleanup;
      }

   /* get digest operation */
   if((pDigestData = pSession->Operation[P11_OPERATION_DIGEST].pData) == NULL)
      {
      log_trace(WHERE, "E: no digest operation initialized");
      ret = CKR_OPERATION_NOT_INITIALIZED;
      goto cleanup;
      }

   if(pDigestData->update)
      {
      log_trace(WHERE, "E: C_Digest() cannot be used to finalize C_DigestUpdate()");
      ret = CKR_FUNCTION_FAILED;
      goto cleanup;
      }

   if (pDigest == NULL)
      {
      *pulDigestLen = pDigestData->l_hash;
      /* return ok without terminating digest params */
      ret = CKR_OK;   
      goto cleanup;
      }

   if (*pulDigestLen < pDigestData->l_hash)
      {
      *pulDigestLen = pDigestData->l_hash;
      ret = CKR_BUFFER_TOO_SMALL;
      goto cleanup;
      }

   ret = hash_update(pDigestData->phash, (char*)pData, ulDataLen);
   if(ret == 0)
      ret = hash_final(pDigestData->phash, pDigest, pulDigestLen);
   if(ret)
      {
      log_trace(WHERE, "E: hash failed()");
      ret = CKR_FUNCTION_FAILED;
      //don't goto cleanup here
      }

   /* terminate digest operation */
   free(pDigestData);
   pSession->Operation[P11_OPERATION_DIGEST].pData = NULL;
   pSession->Operation[P11_OPERATION_DIGEST].active = 0;

cleanup:
   p11_unlock();
	 log_trace(WHERE, "I: leave, ret = 0x%08x",ret);

return ret;
}
Exemple #24
0
int main(int argc, char *argv[]){
	if(argc != 2){
		printf("usage: \n\tnoriega filelist\n");
		exit(1);
	}

	FILE *file = fopen(argv[1], "r");
	if(file == NULL) {
		perror("Couldn't open file list!");
		exit(1);
	}

	word *allwords = NULL; /*prime hash*/
	char line[LINE_SIZE]; 
	unsigned int wordcount = 0;
	while(1){ /*filename getting loop*/
		if(feof(file)) break;
		feed(line, file);

		FILE *article = fopen (line, "r");

		if(article == NULL){
			perror("Problem opening article!");
			continue;
		}
		/*OK, do the article now*/

		feed(line, article);
		char *tw;
		tw = strtok(line, PUNCTUATION);
		do {
			wordcount++;
			temp_hash_update(tw, HIST);
		} while((tw = strtok(NULL, PUNCTUATION)) != NULL);

		while(!feof(article)){
			feed(line, article);
			tw = strtok(line, PUNCTUATION);
			do {
			if(tw == NULL || !strcmp(tw, "\n")) continue;
			wordcount++;
			temp_hash_update(tw, TEST);
			} while((tw = strtok(NULL, PUNCTUATION)) != NULL);
		}
		/*finished the article.*/
		fclose(article);
		hash_update();
	}

	/*cleanup*/
	fclose(file);
	word *cw;
	/*output*/
	while(words){
		cw = words;
		double posapp = (0 != cw->h + cw->ht ) ? (double)cw->ht / (double)(cw->h + cw->ht) : -1;
		double prior = (double)cw->occ / wordcount;
		double ec = (0 != posapp) ? prior / posapp : -1;
		double newec = (-1 != ec) ? ec * prior : -1;
		printf("%.10f\t%.10f\t%.8f\t%.8f\t%u\t%u\t%u\t%u\t%s\n",
				newec,
				ec,
				posapp,
				prior,
				cw->ht,
				cw->h,
				cw->t,
				cw->occ,
				cw->s);
		HASH_DEL(words, cw);
		free(cw->s);
		free(cw);
	}


}
Exemple #25
0
void cryptonite_decaf_ed448_sign (
    uint8_t signature[CRYPTONITE_DECAF_EDDSA_448_SIGNATURE_BYTES],
    const uint8_t privkey[CRYPTONITE_DECAF_EDDSA_448_PRIVATE_BYTES],
    const uint8_t pubkey[CRYPTONITE_DECAF_EDDSA_448_PUBLIC_BYTES],
    const uint8_t *message,
    size_t message_len,
    uint8_t prehashed,
    const uint8_t *context,
    uint8_t context_len
) {
    API_NS(scalar_t) secret_scalar;
    hash_ctx_t hash;
    {
        /* Schedule the secret key */
        struct {
            uint8_t secret_scalar_ser[CRYPTONITE_DECAF_EDDSA_448_PRIVATE_BYTES];
            uint8_t seed[CRYPTONITE_DECAF_EDDSA_448_PRIVATE_BYTES];
        } __attribute__((packed)) expanded;
        hash_hash(
            (uint8_t *)&expanded,
            sizeof(expanded),
            privkey,
            CRYPTONITE_DECAF_EDDSA_448_PRIVATE_BYTES
        );
        clamp(expanded.secret_scalar_ser);   
        API_NS(scalar_decode_long)(secret_scalar, expanded.secret_scalar_ser, sizeof(expanded.secret_scalar_ser));
    
        /* Hash to create the nonce */
        hash_init_with_dom(hash,prehashed,0,context,context_len);
        hash_update(hash,expanded.seed,sizeof(expanded.seed));
        hash_update(hash,message,message_len);
        cryptonite_decaf_bzero(&expanded, sizeof(expanded));
    }
    
    /* Decode the nonce */
    API_NS(scalar_t) nonce_scalar;
    {
        uint8_t nonce[2*CRYPTONITE_DECAF_EDDSA_448_PRIVATE_BYTES];
        hash_final(hash,nonce,sizeof(nonce));
        API_NS(scalar_decode_long)(nonce_scalar, nonce, sizeof(nonce));
        cryptonite_decaf_bzero(nonce, sizeof(nonce));
    }
    
    uint8_t nonce_point[CRYPTONITE_DECAF_EDDSA_448_PUBLIC_BYTES] = {0};
    {
        /* Scalarmul to create the nonce-point */
        API_NS(scalar_t) nonce_scalar_2;
        API_NS(scalar_halve)(nonce_scalar_2,nonce_scalar);
        for (unsigned int c = 2*EDDSA_BASE_POINT_RATIO; c < COFACTOR; c <<= 1) {
            API_NS(scalar_halve)(nonce_scalar_2,nonce_scalar_2);
        }
        
        API_NS(point_t) p;
        API_NS(precomputed_scalarmul)(p,API_NS(precomputed_base),nonce_scalar_2);
        API_NS(point_mul_by_cofactor_and_encode_like_eddsa)(nonce_point, p);
        API_NS(point_destroy)(p);
        API_NS(scalar_destroy)(nonce_scalar_2);
    }
    
    API_NS(scalar_t) challenge_scalar;
    {
        /* Compute the challenge */
        hash_init_with_dom(hash,prehashed,0,context,context_len);
        hash_update(hash,nonce_point,sizeof(nonce_point));
        hash_update(hash,pubkey,CRYPTONITE_DECAF_EDDSA_448_PUBLIC_BYTES);
        hash_update(hash,message,message_len);
        uint8_t challenge[2*CRYPTONITE_DECAF_EDDSA_448_PRIVATE_BYTES];
        hash_final(hash,challenge,sizeof(challenge));
        hash_destroy(hash);
        API_NS(scalar_decode_long)(challenge_scalar,challenge,sizeof(challenge));
        cryptonite_decaf_bzero(challenge,sizeof(challenge));
    }
    
    API_NS(scalar_mul)(challenge_scalar,challenge_scalar,secret_scalar);
    API_NS(scalar_add)(challenge_scalar,challenge_scalar,nonce_scalar);
    
    cryptonite_decaf_bzero(signature,CRYPTONITE_DECAF_EDDSA_448_SIGNATURE_BYTES);
    memcpy(signature,nonce_point,sizeof(nonce_point));
    API_NS(scalar_encode)(&signature[CRYPTONITE_DECAF_EDDSA_448_PUBLIC_BYTES],challenge_scalar);
    
    API_NS(scalar_destroy)(secret_scalar);
    API_NS(scalar_destroy)(nonce_scalar);
    API_NS(scalar_destroy)(challenge_scalar);
}
Exemple #26
0
CK_RV C_Sign(CK_SESSION_HANDLE hSession,        /* the session's handle */
             CK_BYTE_PTR       pData,           /* the data to be signed */
             CK_ULONG          ulDataLen,       /* count of bytes to be signed */
             CK_BYTE_PTR       pSignature,      /* receives the signature */
             CK_ULONG_PTR      pulSignatureLen) /* receives byte count of signature */
{
   CK_RV ret                  = CKR_OK;
   P11_SESSION*   pSession    = NULL;
   P11_SIGN_DATA* pSignData   = NULL;
   unsigned char* pDigest     = NULL;
   unsigned long  ulDigestLen = 0;
// unsigned int ulSignatureLen = *pulSignatureLen;

	if (p11_get_init() != BEIDP11_INITIALIZED)
	{
		log_trace(WHERE, "I: leave, CKR_CRYPTOKI_NOT_INITIALIZED");
		return (CKR_CRYPTOKI_NOT_INITIALIZED);
	}		

   p11_lock();

	 log_trace(WHERE, "I: enter");

   ret = p11_get_session(hSession, &pSession);
   if (ret)
      {
      log_trace(WHERE, "E: Invalid session handle (%d)", hSession);
      goto cleanup;
      }

   //is there an active search operation for this session
   if (pSession->Operation[P11_OPERATION_SIGN].active == 0)
      {
      log_trace(WHERE, "E: Session %d: no sign operation initialized", hSession);
      ret = CKR_OPERATION_NOT_INITIALIZED;
      goto cleanup;
      }

   /* get sign operation */
   if((pSignData = pSession->Operation[P11_OPERATION_SIGN].pData) == NULL)
      {
      log_trace( WHERE, "E: no sign operation initialized");
      ret = CKR_OPERATION_NOT_INITIALIZED;
      goto cleanup;
      }

   if(pSignData->update)
      {
      log_trace(WHERE, "E: C_Sign() cannot be used to finalize a C_SignUpdate() function");
      ret = CKR_FUNCTION_FAILED;
      goto cleanup;
      }

   if (pSignature == NULL)
      {
      /* just return the signature size */
      *pulSignatureLen = pSignData->l_sign;
      ret = CKR_OK;
      goto cleanup;
      }

   if (pSignData->l_sign > *pulSignatureLen)
      {
      *pulSignatureLen = pSignData->l_sign;
      ret = CKR_BUFFER_TOO_SMALL;
      goto cleanup;
      }

   /* do we have to hash first? */
   if (pSignData->phash)
      {
      /* reserve space for data to sign */
      pDigest = (unsigned char*) malloc(pSignData->l_hash);
      if (pDigest == NULL)
         {
         ret = CKR_HOST_MEMORY;
         goto cleanup;
         }
      ret = hash_update(pSignData->phash, (char*)pData, ulDataLen);
      if(ret == 0)
         ret = hash_final(pSignData->phash, pDigest, &ulDigestLen);
      if(ret)
         {
         log_trace(WHERE, "E: hash failed()");
         ret = CKR_FUNCTION_FAILED;
         goto terminate;
         }
      }
   else
      {
      /* reserve space for data to sign */
      pDigest = (unsigned char*) malloc(ulDataLen);
      if (pDigest == NULL)
         {
         ret = CKR_HOST_MEMORY;
         goto cleanup;
         }
      memcpy(pDigest, pData, ulDataLen);
      ulDigestLen = ulDataLen;
      }

   /* do the signing (and add pkcs headers first if needed) */
   ret = cal_sign(pSession->hslot, pSignData, pDigest, ulDigestLen, pSignature, pulSignatureLen);
   if (ret != CKR_OK)
      log_trace(WHERE, "E: cal_sign() returned %s", log_map_error(ret));

terminate:
   //terminate sign operation
   free(pSignData);
   pSession->Operation[P11_OPERATION_SIGN].pData = NULL;
   pSession->Operation[P11_OPERATION_SIGN].active = 0;

cleanup:        
   if (pDigest)
      free(pDigest);
   p11_unlock();
	 log_trace(WHERE, "I: leave, ret = 0x%08x",ret);
return ret;
}
/*
** parse http message:
**  http_eoh                          - end of headers
**  {http_header,   Key, Value}       - Key = atom() | string()
**  {http_request,  Method,Url,Version}
**  {http_response, Version, Status, Message}
**  {http_error,    Error-Line}
*/
int packet_parse_http(const char* buf, int len, int* statep,
                      PacketCallbacks* pcb, void* arg)
{
    const char* ptr = buf;
    const char* p0;
    int n = len;

    /* remove trailing CRNL (accept NL as well) */
    if ((n >= 2) && (buf[n-2] == '\r'))
        n -= 2;
    else if ((n >= 1) && (buf[n-1] == '\n'))
        n -= 1;

    if (*statep == 0) {
        /* start-line = Request-Line | Status-Line */

        if (n >= 5 && (strncmp(buf, "HTTP/", 5) == 0)) {
            int major  = 0;
            int minor  = 0;
            int status = 0;
            /* Status-Line = HTTP-Version SP
             *              Status-Code SP Reason-Phrase
             *              CRNL
             * HTTP-Version   = "HTTP" "/" 1*DIGIT "." 1*DIGIT
             */
            ptr += 5;
            n -= 5;
            p0 = ptr;
            while (n && isdigit((int) *ptr)) {
                major = 10*major + (*ptr - '0');
                ptr++;
                n--;
            }
            if (ptr==p0 || !n || (*ptr != '.'))
                return -1;
            ptr++;
            n--;
            p0 = ptr;
            while (n && isdigit((int) *ptr)) {
                minor = 10*minor + (*ptr - '0');
                ptr++;
                n--;
            }
            if (ptr==p0) return -1;
            p0 = ptr;
            while (n && SP(ptr)) {
                ptr++; n--;
            }
            if (ptr==p0) return -1;
            
            while (n && isdigit((int) *ptr)) {
                status = 10*status + (*ptr - '0');
                ptr++;
                n--;
            }
            p0 = ptr;
            while (n && SP(ptr)) {
                ptr++; n--;
            }
            if (ptr==p0 && n>0) return -1;
            
            /* NOTE: the syntax allows empty reason phrases */
            (*statep) = !0;
            
            return pcb->http_response(arg, major, minor, status,
                                      ptr, n);
        }
        else {
            /* Request-Line = Method SP Request-URI SP HTTP-Version CRLF */
            http_atom_t* meth;
            const char* meth_ptr = buf;
            int         meth_len;
            PacketHttpURI uri;
            const char*   uri_ptr;
            int           uri_len;
            int major  = 0;
            int minor  = 0;
            unsigned long h = 0;

            while (n && !is_tspecial((unsigned char)*ptr)) {
                hash_update(h, (int)*ptr);
                ptr++;
                n--;
            }
            meth_len = ptr - meth_ptr;
            if (n == 0 || meth_len == 0 || !SP(ptr)) return -1;

            meth = http_hash_lookup(meth_ptr, meth_len, h,
                                    http_meth_hash, HTTP_METH_HASH_SIZE);

            while (n && SP(ptr)) {
                ptr++; n--;
            }
            uri_ptr = ptr;
            while (n && !SP(ptr)) {
                ptr++; n--;
            }
            if ((uri_len = (ptr - uri_ptr)) == 0)
                return -1;
            while (n && SP(ptr)) {
                ptr++; n--;
            }
            if (n == 0) {
                (*statep) = !0;
                http_parse_uri(&uri, uri_ptr, uri_len);
                return pcb->http_request(arg, meth, meth_ptr, meth_len,
                                         &uri, 0, 9);
            }
            if (n < 8)
                return -1;
            if (strncmp(ptr, "HTTP/", 5) != 0)
                return -1;
            ptr += 5;
            n   -= 5;

            p0 = ptr;
            while (n && isdigit((int) *ptr)) {
                major = 10*major + (*ptr - '0');
                ptr++;
                n--;
            }            
            if (ptr==p0 || !n || (*ptr != '.'))
                return -1;
            ptr++;
            n--;
            p0 = ptr;
            while (n && isdigit((int) *ptr)) {
                minor = 10*minor + (*ptr - '0');
                ptr++;
                n--;
            }
            if (ptr==p0) return -1;

            (*statep) = !0;
            http_parse_uri(&uri, uri_ptr, uri_len);
            return pcb->http_request(arg, meth, meth_ptr, meth_len,
                                     &uri, major, minor);
        }
    }
    else {
        int up = 1;      /* make next char uppercase */
        http_atom_t* name;
        char name_buf[HTTP_MAX_NAME_LEN];
        const char* name_ptr = name_buf;
        int  name_len;
        unsigned long h;

        if (n == 0) {
            /* end of headers */
            *statep = 0;  /* reset state (for next request) */
            return pcb->http_eoh(arg);
        }
        h = 0;
        name_len = 0;
        while (!is_tspecial((unsigned char)*ptr)) {
            if (name_len < HTTP_MAX_NAME_LEN) {
                int c = *ptr;
                if (up) {
                    if (islower(c)) {
                        c = toupper(c);
                    }
                    up = 0;
                }
                else {
                    if (isupper(c))
                        c = tolower(c);
                    else if (c == '-')
                        up = 1;
                }                            
                name_buf[name_len] = c;
                hash_update(h, c);
            }
            name_len++;
            ptr++;
            if (--n == 0) return -1;
        }
        while (n && SP(ptr)) { /* Skip white space before ':' */
            ptr++; n--;
        } 
        if (*ptr != ':') {
            return -1;
        }
        if (name_len <= HTTP_MAX_NAME_LEN) {
            name = http_hash_lookup(name_buf, name_len, h,
                                    http_hdr_hash, HTTP_HDR_HASH_SIZE);
        } 
        else {
            /* Is it ok to return original name without case adjustments? */
            name_ptr = buf;
            name = NULL;
        }
        ptr++;
        n--;
        /* Skip white space after ':' */
        while (n && SP(ptr)) {
            ptr++; n--;
        }
        return pcb->http_header(arg, name, name_ptr, name_len,
                                ptr, n);
    }
    return -1;
}   
Exemple #28
0
CK_RV C_SignUpdate(CK_SESSION_HANDLE hSession,  /* the session's handle */
                   CK_BYTE_PTR       pPart,     /* the data (digest) to be signed */
                   CK_ULONG          ulPartLen) /* count of bytes to be signed */
{
   CK_RV ret;
   P11_SESSION *pSession = NULL;
   P11_SIGN_DATA *pSignData = NULL;
   char* oldBuf = NULL;

	if (p11_get_init() != BEIDP11_INITIALIZED)
	{
		log_trace(WHERE, "I: leave, CKR_CRYPTOKI_NOT_INITIALIZED");
		return (CKR_CRYPTOKI_NOT_INITIALIZED);
	}		

   p11_lock();
	
   log_trace(WHERE, "I: enter");

   ret = p11_get_session(hSession, &pSession);
   if (ret)
      {
      log_trace(WHERE, "E: Invalid session handle (%d)", hSession);
      goto cleanup;
      }

   //is there an active search operation for this session
   if (pSession->Operation[P11_OPERATION_SIGN].active == 0)
      {
      log_trace(WHERE, "E: Session %d: no sign operation initialized", hSession);
      ret = CKR_OPERATION_NOT_INITIALIZED;
      goto cleanup;
      }

   /* get sign operation */
   if((pSignData = pSession->Operation[P11_OPERATION_SIGN].pData) == NULL)
      {
      log_trace( WHERE, "E: no sign operation initialized");
      ret = CKR_OPERATION_NOT_INITIALIZED;
      goto cleanup;
      }

   if (pSignData->phash == NULL)
      {
      if ( (ulPartLen + pSignData->lbuf) > pSignData->l_sign)
         {
         log_trace(WHERE, "E: size not possible for signing");
         ret = CKR_DATA_LEN_RANGE;
         goto cleanup;
         }
	  oldBuf = pSignData->pbuf;
	  pSignData->pbuf = (char*)realloc(pSignData->pbuf, pSignData->lbuf + ulPartLen);

      if (pSignData->pbuf == NULL)
         {
         log_trace(WHERE, "E: memory allocation problem for host");
         ret = CKR_HOST_MEMORY;
		 //old location has not been freed, so do that now
		 if (oldBuf != NULL)
			free(oldBuf);
         goto cleanup;
         }
      //add data
      memcpy(pSignData->pbuf+pSignData->lbuf, pPart, ulPartLen);
      pSignData->lbuf += ulPartLen;
      }
   else
      {
      ret = hash_update(pSignData->phash, (char*)pPart, ulPartLen);
      if (ret)
         {
         log_trace(WHERE, "E: hash_update failed");
         ret = CKR_FUNCTION_FAILED;
         goto cleanup;
         }
      }

cleanup:

   p11_unlock();
	 log_trace(WHERE, "I: leave, ret = 0x%08x",ret);
return ret;
}
int
rsstool_write_xml (st_rsstool_t *rt)
{
#define XMLPRINTF(s) xmlTextWriterWriteString(writer,BAD_CAST s)
  st_rss_t rss;
  int i = 0;
  xmlTextWriterPtr writer;
  xmlBufferPtr buffer;
  st_hash_t *dl_url_h = NULL;
  st_hash_t *url_h = NULL;
  st_hash_t *title_h = NULL;
  int items = rsstool_get_item_count (rt);
#define ENCODE(s) s
//#define ENCODE(s) base64_enc(s,0)
//#define ENCODE(s) str_escape_xml(s)

  memset (&rss, 0, sizeof (st_rss_t));

  if (!(buffer = xmlBufferCreate ()))
    return -1;

  if (!(writer = xmlNewTextWriterMemory (buffer, 0)))
    return -1;

  xmlTextWriterStartDocument (writer, NULL, "UTF-8", NULL);

  xmlTextWriterWriteComment (writer, BAD_CAST " RSStool - read, parse, merge and write RSS and Atom feeds\n"                            
    "http://rsstool.berlios.de ");

  XMLPRINTF("\n");

  xmlTextWriterWriteComment (writer, BAD_CAST "\n"
         "format:\n"
         "item[]\n"
         "  dl_url           \n"
         "  dl_url_md5\n"
         "  dl_url_crc32\n"
         "  dl_date\n"
         "  user             author\n"
         "  site\n"
         "  url              \n"
         "  url_md5\n"
         "  url_crc32\n"
         "  date             default: current time\n"
         "  title            used by searches for related items\n"
         "  title_md5\n"
         "  title_crc32\n"
         "  desc             description\n"
         "  media_keywords   default: keywords from title and description\n"
         "  media_duration   event length\n"
         "  media_image      thumbnail\n"
         "  event_start      default: date\n"
         "  event_end        default: event_start + media_duration\n"
);

  XMLPRINTF("\n");

  xmlTextWriterStartElement (writer, BAD_CAST "rsstool");  // <rsstool>
  xmlTextWriterWriteAttribute (writer, BAD_CAST "version", BAD_CAST RSSTOOL_VERSION_S);

  for (i = 0; i < items && i < RSSMAXITEM; i++)
//  for (i = 0; i < items; i++)
    {
      dl_url_h = hash_open (HASH_MD5|HASH_CRC32);
      url_h = hash_open (HASH_MD5|HASH_CRC32);
      title_h = hash_open (HASH_MD5|HASH_CRC32);

      dl_url_h = hash_update (dl_url_h, (const unsigned char *) rt->item[i]->feed_url, strlen (rt->item[i]->feed_url));
      url_h = hash_update (url_h, (const unsigned char *) rt->item[i]->url, strlen (rt->item[i]->url));
      title_h = hash_update (title_h, (const unsigned char *) rt->item[i]->title, strlen (rt->item[i]->title));

      XMLPRINTF("\n  ");

      xmlTextWriterStartElement (writer, BAD_CAST "item"); // <item>

      XMLPRINTF("\n    ");

//      xmlTextWriterWriteElement (writer, BAD_CAST "dl_url", BAD_CAST rt->item[i]->feed_url);
      xmlTextWriterWriteFormatElement (writer, BAD_CAST "dl_url", "%s", rt->item[i]->feed_url);

      XMLPRINTF("\n    ");

      xmlTextWriterWriteFormatElement (writer, BAD_CAST "dl_url_md5", "%s", hash_get_s (dl_url_h, HASH_MD5));

      XMLPRINTF("\n    ");

      xmlTextWriterWriteFormatElement (writer, BAD_CAST "dl_url_crc32", "%u", hash_get_crc32 (dl_url_h));

      XMLPRINTF("\n    ");

      xmlTextWriterWriteFormatElement (writer, BAD_CAST "dl_date", "%ld", rsstool.start_time);

      XMLPRINTF("\n    ");

      xmlTextWriterWriteFormatElement (writer, BAD_CAST "user", "%s", ENCODE (rt->item[i]->user));

      XMLPRINTF("\n    ");

      xmlTextWriterWriteFormatElement (writer, BAD_CAST "site", "%s", ENCODE (rt->item[i]->site));

      XMLPRINTF("\n    ");

      xmlTextWriterWriteFormatElement (writer, BAD_CAST "url", "%s", rt->item[i]->url);

      XMLPRINTF("\n    ");

      xmlTextWriterWriteFormatElement (writer, BAD_CAST "url_md5", "%s", hash_get_s (url_h, HASH_MD5));

      XMLPRINTF("\n    ");

      xmlTextWriterWriteFormatElement (writer, BAD_CAST "url_crc32", "%u", hash_get_crc32 (url_h));

      XMLPRINTF("\n    ");

      xmlTextWriterWriteFormatElement (writer, BAD_CAST "date", "%ld", rt->item[i]->date);

      XMLPRINTF("\n    ");

      xmlTextWriterWriteFormatElement (writer, BAD_CAST "title", "%s", ENCODE (rt->item[i]->title));


      XMLPRINTF("\n    ");

      xmlTextWriterWriteFormatElement (writer, BAD_CAST "title_md5", "%s", hash_get_s (title_h, HASH_MD5));

      XMLPRINTF("\n    ");

      xmlTextWriterWriteFormatElement (writer, BAD_CAST "title_crc32", "%u", hash_get_crc32 (title_h));

      XMLPRINTF("\n    ");

      xmlTextWriterWriteFormatElement (writer, BAD_CAST "desc", "%s", ENCODE (rt->item[i]->desc));

      XMLPRINTF("\n    ");

      xmlTextWriterWriteFormatElement (writer, BAD_CAST "media_keywords", "%s", ENCODE (rt->item[i]->media_keywords));

      XMLPRINTF("\n    ");

      xmlTextWriterWriteFormatElement (writer, BAD_CAST "media_duration", "%ld", rt->item[i]->media_duration);

      XMLPRINTF("\n    ");

      xmlTextWriterWriteFormatElement (writer, BAD_CAST "media_image", "%s", rt->item[i]->media_image);

      XMLPRINTF("\n    ");

      xmlTextWriterWriteFormatElement (writer, BAD_CAST "event_start", "%ld", rt->item[i]->event_start);

      XMLPRINTF("\n    ");

      xmlTextWriterWriteFormatElement (writer, BAD_CAST "event_end", "%ld", rt->item[i]->event_end);

      XMLPRINTF("\n  ");

      xmlTextWriterEndElement (writer); // </item>

      hash_close (dl_url_h);
      hash_close (url_h);
      hash_close (title_h);
    }

  XMLPRINTF("\n");

  xmlTextWriterEndDocument (writer);  // </rsstool>

  xmlFreeTextWriter (writer);

  fputs ((const char *) buffer->content, rt->output_file);

  xmlBufferFree (buffer);

  if (items >= RSSMAXITEM)
    {
      char buf[MAXBUFSIZE];

      sprintf (buf, "can write only RSS feeds with up to %d items (was %d items)\n",
        RSSMAXITEM, items);
      rsstool_log (rt, buf);
    }

  return 0;
}
int
rsstool_write_xml (st_rsstool_t *rt)
{
  st_rss_t rss;
  int i = 0;
  st_hash_t *dl_url_h = NULL;
  st_hash_t *url_h = NULL;
  st_hash_t *title_h = NULL;
  int items = rsstool_get_item_count (rt);
//#define ENCODE(s) s
#define ENCODE(s) base64_enc(s,0)
//#define ENCODE(s) str_escape_xml(s)

  memset (&rss, 0, sizeof (st_rss_t));

  fputs ("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n", rsstool.output_file);

  fputs ("<!--\n"
         "RSStool - read, parse, merge and write RSS and Atom feeds\n"
         "http://rsstool.berlios.de\n"
         "-->\n", rsstool.output_file);

  fputs ("<!--\n"
         "format:\n"
         "item[]\n"
         "  dl_url           \n"
         "  dl_url_md5\n"
         "  dl_url_crc32\n"
         "  dl_date\n"
         "  user             (base64 encoded)\n"
         "  site             (base64 encoded)\n"
         "  url              \n"
         "  url_md5\n"
         "  url_crc32\n"
         "  date\n"
         "  title            used by searches for related items (base64 encoded)\n"
         "  title_md5\n"
         "  title_crc32\n"
         "  desc             description (base64 encoded)\n"
         "  media_keywords   default: keywords from title and description\n"
         "  media_duration\n"
         "  media_thumbnail  path (base64 encoded)\n"
//         "  media_image      path (base64 encoded)\n"
//         "  event_start      default: date\n"
//         "  event_end        default: event_start + media_duration\n"
         "-->\n", rsstool.output_file);

  fputs ("<rsstool version=\"" RSSTOOL_VERSION_S "\">\n", rsstool.output_file);

  for (i = 0; i < items && i < RSSMAXITEM; i++)
//  for (i = 0; i < items; i++)
    {
      dl_url_h = hash_open (HASH_MD5|HASH_CRC32);
      url_h = hash_open (HASH_MD5|HASH_CRC32);
      title_h = hash_open (HASH_MD5|HASH_CRC32);

      dl_url_h = hash_update (dl_url_h, (const unsigned char *) rt->item[i]->feed_url, strlen (rt->item[i]->feed_url));
      url_h = hash_update (url_h, (const unsigned char *) rt->item[i]->url, strlen (rt->item[i]->url));
      title_h = hash_update (title_h, (const unsigned char *) rt->item[i]->title, strlen (rt->item[i]->title));

      fprintf (rsstool.output_file,
               "  <item>\n"
               "    <dl_url>%s</dl_url>\n"
               "    <dl_url_md5>%s</dl_url_md5>\n"
               "    <dl_url_crc32>%u</dl_url_crc32>\n"
               "    <dl_date>%ld</dl_date>\n"
               "    <user>%s</user>\n"
               "    <site>%s</site>\n"
               "    <url>%s</url>\n"
               "    <url_md5>%s</url_md5>\n"
               "    <url_crc32>%u</url_crc32>\n"
               "    <date>%ld</date>\n"
               "    <title>%s</title>\n"
               "    <title_md5>%s</title_md5>\n"
               "    <title_crc32>%u</title_crc32>\n"
               "    <desc>%s</desc>\n"
               "    <media_keywords>%s</media_keywords>\n"
               "    <media_duration>%d</media_duration>\n"
               "    <media_thumbnail>%s</media_thumbnail>\n"
//               "    <media_image>%s</media_image>\n"
//               "    <event_start>%u</event_start>\n"
//               "    <event_end>%u</event_end>\n"
               "  </item>\n",
        str_escape_xml (rt->item[i]->feed_url),
        hash_get_s (dl_url_h, HASH_MD5),
        hash_get_crc32 (dl_url_h),
        time (0),
        ENCODE (rt->item[i]->user),
        ENCODE (rt->item[i]->site),
        str_escape_xml (rt->item[i]->url),
        hash_get_s (url_h, HASH_MD5),
        hash_get_crc32 (url_h),
        rt->item[i]->date,
        ENCODE (rt->item[i]->title),
        hash_get_s (title_h, HASH_MD5),
        hash_get_crc32 (title_h),
        ENCODE (rt->item[i]->desc),
        ENCODE (rt->item[i]->media_keywords),
        rt->item[i]->media_duration,
        str_escape_xml (rt->item[i]->media_thumbnail)
//        str_escape_xml (rt->item[i]->media_image),
//        rt->item[i]->event_start,
//        rt->item[i]->event_end
);

      hash_close (dl_url_h);
      hash_close (url_h);
      hash_close (title_h);
    }

  fputs ("</rsstool>\n", rsstool.output_file);

  if (items >= RSSMAXITEM)
    {
      char buf[MAXBUFSIZE];

      sprintf (buf, "can write only RSS feeds with up to %d items (was %d items)\n",
        RSSMAXITEM, items);
      rsstool_log (rt, buf);
    }

  return 0;
}