Example #1
0
/**
 * cdk_stream_kick_off:
 * @inp: the input stream
 * @out: the output stream.
 *
 * Passes the entire data from @inp into the output stream @out
 * with all the activated filters.
 */
cdk_error_t
cdk_stream_kick_off (cdk_stream_t inp, cdk_stream_t out)
{
    byte buf[BUFSIZE];
    int nread, nwritten;
    cdk_error_t rc;

    if (!inp || !out)
    {
        gnutls_assert ();
        return CDK_Inv_Value;
    }
    rc = CDK_Success;
    while (!cdk_stream_eof (inp))
    {
        nread = cdk_stream_read (inp, buf, DIM (buf));
        if (!nread || nread == EOF)
            break;
        nwritten = cdk_stream_write (out, buf, nread);
        if (!nwritten || nwritten == EOF)
        {   /* In case of errors, we leave the loop. */
            rc = inp->error;
            break;
        }
    }

    wipemem (buf, sizeof (buf));
    return rc;
}
Example #2
0
static cdk_error_t
write_literal (cdk_stream_t out, cdk_pkt_literal_t pt, int old_ctb)
{
  byte buf[BUFSIZE];
  size_t size;
  cdk_error_t rc;

  assert (out);
  assert (pt);

  /* We consider a packet without a body as an invalid packet.
     At least one octet must be present. */
  if (!pt->len)
    return CDK_Inv_Packet;

  if (DEBUG_PKT)
    _cdk_log_debug ("write_literal:\n");

  size = 6 + pt->namelen + pt->len;
  rc = pkt_write_head (out, old_ctb, size, CDK_PKT_LITERAL);
  if (rc)
    return rc;

  rc = stream_putc (out, pt->mode);
  if (rc)
    return rc;
  rc = stream_putc (out, pt->namelen);
  if (rc)
    return rc;

  if (pt->namelen > 0)
    rc = stream_write (out, pt->name, pt->namelen);
  if (!rc)
    rc = write_32 (out, pt->timestamp);
  if (rc)
    return rc;

  while (!cdk_stream_eof (pt->buf) && !rc)
    {
      rc = stream_read (pt->buf, buf, DIM (buf), &size);
      if (!rc)
	rc = stream_write (out, buf, size);
    }

  wipemem (buf, sizeof (buf));
  return rc;
}
Example #3
0
cdk_error_t
cdk_stream_kick_off( cdk_stream_t inp, cdk_stream_t out )
{
    byte buf[8192];
    int nread, nwritten;
    int rc = 0;

    if( !inp || !out )
        return CDK_Inv_Value;
    while( !cdk_stream_eof( inp ) ) {
        nread = cdk_stream_read( inp, buf, sizeof buf-1 );
        if( nread == EOF )
            break;
        nwritten = cdk_stream_write( out, buf, nread );
        if( nwritten == EOF )
            rc = CDK_File_Error;
    }
    wipemem( buf, sizeof buf );
    return rc;
}
Example #4
0
static int
stream_cache_flush (cdk_stream_t s, FILE * fp)
{
    int nwritten;

    assert (s);

    /* FIXME: We should find a way to use cdk_stream_write here. */
    if (s->cache.size > 0)
    {
        nwritten = fwrite (s->cache.buf, 1, s->cache.size, fp);
        if (!nwritten)
        {
            gnutls_assert ();
            return CDK_File_Error;
        }
        s->cache.size = 0;
        s->cache.on = 0;
        wipemem (s->cache.buf, s->cache.alloced);
    }
    return 0;
}
Example #5
0
File: hash.c Project: ares89/vlc
static cdk_error_t
hash_encode (void *data, FILE * in, FILE * out)
{
  md_filter_t *mfx = data;
  byte buf[BUFSIZE];
  int err;
  int nread;

  if (!mfx)
    {
      gnutls_assert ();
      return CDK_Inv_Value;
    }

  _cdk_log_debug ("hash filter: encode algo=%d\n", mfx->digest_algo);

  if (!mfx->md_initialized)
    {
      err = _gnutls_hash_init (&mfx->md, mfx->digest_algo);
      if (err < 0)
        {
          gnutls_assert ();
          return map_gnutls_error (err);
        }

      mfx->md_initialized = 1;
    }

  while (!feof (in))
    {
      nread = fread (buf, 1, BUFSIZE, in);
      if (!nread)
        break;
      _gnutls_hash (&mfx->md, buf, nread);
    }

  wipemem (buf, sizeof (buf));
  return 0;
}
Example #6
0
/**
 * cdk_sk_unprotect:
 * @sk: the secret key
 * @pw: the passphrase
 * 
 * Unprotect the given secret key with the passphrase.
 **/
cdk_error_t
cdk_sk_unprotect (cdk_pkt_seckey_t sk, const char *pw)
{
  gcry_cipher_hd_t hd;
  cdk_dek_t dek = NULL;
  byte *data = NULL;
  u16 chksum = 0;
  size_t ndata, nbits, nbytes;
  int i, dlen, pos = 0, nskey;
  cdk_error_t rc;
  gcry_error_t err;
  
  if (!sk)
    return CDK_Inv_Value;
  
  nskey = cdk_pk_get_nskey (sk->pubkey_algo);
  if (!sk->is_protected)
    {
      chksum = 0;
      for (i = 0; i < nskey; i++)
	chksum += checksum_mpi (sk->mpi[i]);
      if (chksum != sk->csum)
	return CDK_Chksum_Error;
    } 
      
  rc = cdk_dek_from_passphrase (&dek, sk->protect.algo,
				sk->protect.s2k, 0, pw);
  if (rc)
    return rc;
  err = gcry_cipher_open (&hd, sk->protect.algo, GCRY_CIPHER_MODE_CFB, 
			  GCRY_CIPHER_ENABLE_SYNC);
  if (!err)
    err = gcry_cipher_setiv (hd, sk->protect.iv, sk->protect.ivlen);
  if (!err)
    err = gcry_cipher_setkey (hd, dek->key, dek->keylen);
  if (err)
    {
      cdk_free (dek);
      return map_gcry_error (err);
    }
  cdk_dek_free (dek);
  chksum = 0;
  if (sk->version == 4) 
    {
      ndata = sk->enclen;
      data = cdk_salloc (ndata, 1);
      if (!data)
	return CDK_Out_Of_Core;
      gcry_cipher_decrypt (hd, data, ndata, sk->encdata, ndata);
      if (sk->protect.sha1chk) 
	{
	  /* This is the new SHA1 checksum method to detect tampering
	     with the key as used by the Klima/Rosa attack */
	  sk->csum = 0;
	  chksum = 1;
	  dlen = gcry_md_get_algo_dlen (GCRY_MD_SHA1);
	  if (ndata < dlen) 
	    {
	      cdk_free (data);
	      return CDK_Inv_Packet;
	    }
	  else 
	    {
	      byte mdcheck[20];
	      
	      gcry_md_hash_buffer (GCRY_MD_SHA1, 
				   mdcheck, data, ndata-dlen);
	      if (!memcmp (mdcheck, data + ndata - dlen, dlen))
		chksum = 0;	/* Digest does match */
	    }
	}
      else 
	{
	  for (i = 0; i < ndata - 2; i++)
	    chksum += data[i];
	  sk->csum = data[ndata - 2] << 8 | data[ndata - 1];
	}
      if (sk->csum == chksum) 
	{
	  for (i = 0; i < nskey; i++) 
	    {
	      nbits = data[pos] << 8 | data[pos + 1];
	      
	      if (gcry_mpi_scan (&sk->mpi[i], GCRYMPI_FMT_PGP, data,
			     (nbits+7)/8+2, &nbytes))
		{
		  wipemem (data, sk->enclen);
		  cdk_free (data);
		  return CDK_Wrong_Format;
		}	     
	      gcry_mpi_set_flag (sk->mpi[i], GCRYMPI_FLAG_SECURE);
	      pos += (nbits+7)/8+2;
	    }
	}
      wipemem (data, sk->enclen);
      cdk_free (data);
    }
  else 
    {
      byte buf[MAX_MPI_BYTES+2];
      
      chksum = 0;
      for (i = 0; i < nskey; i++)
	{
	  gcry_cipher_sync (hd);
	  gcry_mpi_print (GCRYMPI_FMT_PGP, buf, DIM (buf), 
			  &nbytes, sk->mpi[i]);
	  gcry_cipher_decrypt (hd, buf+2, nbytes-2, NULL, 0);
	  gcry_mpi_release (sk->mpi[i]);
	  if (gcry_mpi_scan (&sk->mpi[i], GCRYMPI_FMT_PGP,
			     buf, nbytes, &nbytes))
	    return CDK_Wrong_Format;
	  chksum += checksum_mpi (sk->mpi[i]);
	}
    }
  gcry_cipher_close (hd);
  if (chksum != sk->csum)
    return CDK_Chksum_Error;
  sk->is_protected = 0;
  return 0;
}