Esempio n. 1
0
/**
 * cdk_stream_close: Close a stream and flush all buffers.
 * @s: The STREAM object.
 *
 * This function work different for read or write streams. When the
 * stream is for reading, the filtering is already done and we can
 * simply close the file and all buffers.
 * But for the case it's a write stream, we need to apply all registered
 * filters now. The file is closed in the filter function and not here.
 **/
cdk_error_t
cdk_stream_close( cdk_stream_t s )
{
    struct stream_filter_s * f, * f2;
    int rc = 0;

    if( !s )
        return CDK_Inv_Value;
    
    _cdk_log_debug( "close stream `%s'\n", s->fname? s->fname : "[temp]" );
    
    if( !s->flags.filtrated && !s->error )
        rc = cdk_stream_flush( s );
    if( s->fname || s->flags.temp ) {
        rc = fclose( s->fp );
        s->fp = NULL;
        if( rc )
            rc = CDK_File_Error;
    }
    f = s->filters;
    while( f ) {
        f2 = f->next;
        if( f->fnct )
            f->fnct( f->opaque, STREAMCTL_FREE, NULL, NULL );
        cdk_free( f );
        f = f2;
    }
    if( s->fname ) {
        cdk_free( s->fname );
        s->fname = NULL;
    }
    cdk_free( s );
    return rc;
}
Esempio n. 2
0
/**
 * cdk_stream_new: Create a new stream into into the given file.
 * @file: The name of the new file
 * @ret_s: The new STREAM object
 **/
cdk_error_t
cdk_stream_new( const char * file, cdk_stream_t * ret_s )
{
    cdk_stream_t s;

    if( !ret_s )
        return CDK_Inv_Value;

    _cdk_log_debug( "new stream `%s'\n", file? file : "[temp]" );
    *ret_s = NULL;
    s = cdk_calloc( 1, sizeof *s );
    if( !s )
        return CDK_Out_Of_Core;  
    s->flags.write = 1;
    if( !file )
        s->flags.temp = 1;
    else {
        s->fname = cdk_strdup( file );
        if( !s->fname ) {
            cdk_free( s );
            return CDK_Out_Of_Core;
        }
    }
    s->fp = tmpfile( );
    if( !s->fp ) {
        cdk_free( s->fname );
        cdk_free( s );
        return CDK_File_Error;
    }
    *ret_s = s;
    return 0;
}
Esempio n. 3
0
static int
keydb_idx_search( cdk_stream_t inp, u32 * keyid,
                  const byte * fpr, u32 * r_off )
{
    key_idx_t idx;

    if( !inp || !r_off )
        return CDK_Inv_Value;
    if( (keyid && fpr) || (!keyid && !fpr) )
        return CDK_Inv_Mode;

    *r_off = 0xFFFFFFFF;
    cdk_stream_seek( inp, 0 );
    while( keydb_idx_parse( inp, &idx ) != CDK_EOF ) {
        if( keyid && KEYID_CMP( keyid, idx->keyid ) ) {
            *r_off = idx->offset;
            break; 
        }
        else if( fpr && !memcmp( idx->fpr, fpr, 20 ) ) {
            *r_off = idx->offset;
            break; 
        }
        cdk_free( idx );
        idx = NULL; 
    }
    cdk_free( idx );
    return *r_off != 0xFFFFFFFF ? 0 : CDK_EOF;
}
Esempio n. 4
0
void
cdk_pkt_free (cdk_packet_t pkt)
{
  if (!pkt)
    return;
  
  switch (pkt->pkttype) 
    {
    case CDK_PKT_ATTRIBUTE    :
    case CDK_PKT_USER_ID      : _cdk_free_userid (pkt->pkt.user_id); break;
    case CDK_PKT_PUBLIC_KEY   :
    case CDK_PKT_PUBLIC_SUBKEY: cdk_pk_release (pkt->pkt.public_key); break;
    case CDK_PKT_SECRET_KEY   :
    case CDK_PKT_SECRET_SUBKEY: cdk_sk_release (pkt->pkt.secret_key); break;
    case CDK_PKT_SIGNATURE    : _cdk_free_signature (pkt->pkt.signature);break;
    case CDK_PKT_PUBKEY_ENC   : free_pubkey_enc (pkt->pkt.pubkey_enc); break;
    case CDK_PKT_SYMKEY_ENC   : free_symkey_enc (pkt->pkt.symkey_enc); break;
    case CDK_PKT_MDC          : cdk_free (pkt->pkt.mdc); break;
    case CDK_PKT_ENCRYPTED    :
    case CDK_PKT_ENCRYPTED_MDC: free_encrypted (pkt->pkt.encrypted); break;
    case CDK_PKT_ONEPASS_SIG  : cdk_free (pkt->pkt.onepass_sig); break;
    case CDK_PKT_LITERAL      : free_literal (pkt->pkt.literal); break;
    case CDK_PKT_COMPRESSED   : cdk_free (pkt->pkt.compressed); break;
    default                   : break;
    }
  
  /* Reset the packet type to avoid, when cdk_pkt_release() will be
     used, that the second cdk_pkt_free() call will double free the data. */
  pkt->pkttype = 0;
}
Esempio n. 5
0
/**
 * cdk_stream_open: create a new stream based on an existing file.
 * @file: The file to open
 * @ret_s: The new STREAM object
 **/
cdk_error_t
cdk_stream_open( const char * file, cdk_stream_t * ret_s )
{
    cdk_stream_t s;

    if( !file || !ret_s )
        return CDK_Inv_Value;

    _cdk_log_debug( "open stream `%s'\n", file );
    *ret_s = NULL;
    s = cdk_calloc( 1, sizeof *s );
    if( !s )
        return CDK_Out_Of_Core;
    s->fname = cdk_strdup( file );
    if( !s->fname ) {
        cdk_free( s );
        return CDK_Out_Of_Core;
    }
    s->fp = fopen( file, "rb" );
    if( !s->fp ) {
        cdk_free( s->fname );
        cdk_free( s );
        return CDK_File_Error;
    }
    s->flags.write = 0;
    *ret_s = s;
    return 0;
}
Esempio n. 6
0
void
_cdk_result_verify_free (cdk_verify_result_t res)
{
  if (!res)
    return;
  cdk_free (res->policy_url);
  cdk_free (res->sig_data);
  cdk_free (res);
}
Esempio n. 7
0
void
keydb_search_free( cdk_dbsearch_t dbs )
{
    if( !dbs )
        return;
    if( dbs->type == CDK_DBSEARCH_EXACT || dbs->type == CDK_DBSEARCH_SUBSTR )
        cdk_free( dbs->u.pattern );
    dbs->type = 0;
    cdk_free( dbs );    
}
Esempio n. 8
0
/**
 * cdk_pk_from_secret_key:
 * @sk: the secret key
 * @ret_pk: the new public key
 *
 * Create a new public key from a secret key.
 **/
cdk_error_t
cdk_pk_from_secret_key (cdk_pkt_seckey_t sk, cdk_pubkey_t *ret_pk)
{
  if (!sk)
    return CDK_Inv_Value;
  return _cdk_copy_pubkey (ret_pk, sk->pk);
}


#if 0 /* FIXME: Code is not finished yet. */
cdk_error_t
cdk_pk_revoke_cert_create (cdk_pkt_seckey_t sk, int code, const char *inf,
			   char **ret_revcert)
{
  gcry_md_hd_t md;
  cdk_subpkt_t node;
  cdk_pkt_signature_t sig;
  char *p = NULL, *dat;
  gcry_error_t err;
  cdk_error_t rc = 0;
  size_t n;
  
  if (!sk || !ret_revcert)
    return CDK_Inv_Value;
  if(code < 0 || code > 3)
    return CDK_Inv_Value;
  
  sig = cdk_calloc (1, sizeof *sig);
  if (!sig)
    return CDK_Out_Of_Core;
  _cdk_sig_create (sk->pk, sig);
  n = 1;
  if (inf) 
    {
      n += strlen (p);
      p = cdk_utf8_encode (inf);
    }
  dat = cdk_calloc (1, n+1);
  if (!dat)
    {
      _cdk_free_signature (sig);
      return CDK_Out_Of_Core;
    }
  dat[0] = code;
  if (inf)
    memcpy (dat+1, p, strlen (p));
  cdk_free (p);
  
  node = cdk_subpkt_new (n);
  if (node)
    {
      cdk_subpkt_init (node, CDK_SIGSUBPKT_REVOC_REASON, dat, n);
      cdk_subpkt_add (sig->hashed, node);
    }
  cdk_free (dat);
  
  err = gcry_md_open (&md, GCRY_MD_SHA1, 0);
  if (err)
    rc = map_gcry_error (err);
  else
    _cdk_hash_pubkey (sk->pk, md, 0);
  _cdk_free_signature (sig);
  
  return rc;
}
Esempio n. 9
0
/* This functions builds an index of the keyring into a separate file
   with the name keyring.ext.idx. It contains the offset of all public-
   and public subkeys. The format of the file is:
   --------
    4 octets offset of the packet
    8 octets keyid
   20 octets fingerprint
   --------
   We store the keyid and the fingerprint due to the fact we can't get
   the keyid from a v3 fingerprint directly.
*/
static int
keydb_idx_build( const char * file )
{
    cdk_packet_t pkt;
    cdk_stream_t inp, out = NULL;
    byte buf[8], fpr[20];
    char * fname;
    u32 keyid[2];
    int rc, pos;

    if( !file )
        return CDK_Inv_Value;

    pkt = cdk_calloc( 1, sizeof * pkt );
    if( !pkt )
        return CDK_Out_Of_Core;
    
    fname = keydb_idx_mkname( file );
    if( !fname ) {
        rc = CDK_Out_Of_Core;
        goto leave;
    }
  
    rc = cdk_stream_open( file, &inp );
    if( !rc )
        rc = cdk_stream_create( fname, &out );
    if( rc )
        goto leave;

    while( !cdk_stream_eof( inp ) ) {
        pos = cdk_stream_tell( inp );
        rc = cdk_pkt_read( inp, pkt );
        if( rc )
            break;
        if( pkt->pkttype == CDK_PKT_PUBLIC_KEY
            || pkt->pkttype == CDK_PKT_PUBLIC_SUBKEY ) {
            _cdk_u32tobuf( pos, buf );
            cdk_stream_write( out, buf, 4 );
            cdk_pk_get_keyid( pkt->pkt.public_key, keyid );
            _cdk_u32tobuf( keyid[0], buf );
            _cdk_u32tobuf( keyid[1], buf + 4 );
            cdk_stream_write( out, buf, 8 );
            cdk_pk_get_fingerprint( pkt->pkt.public_key, fpr );
            cdk_stream_write( out, fpr, 20 );
        }
        cdk_pkt_free( pkt );
        cdk_pkt_init( pkt );
    }
    cdk_stream_close( out );
 leave:
    cdk_stream_close( inp );
    cdk_free( fname );
    cdk_free( pkt );
    return rc;
}
Esempio n. 10
0
/**
 * cdk_listkey_close:
 * @ctx: the list key context
 *
 * Free the list key context.
 **/
void
cdk_listkey_close( cdk_listkey_t ctx )
{
    if( ctx ) {
        if( ctx->type )
            cdk_free( ctx->u.patt );
        else
            cdk_strlist_free( ctx->u.fpatt );
        cdk_free( ctx );
    }
}
Esempio n. 11
0
/**
 * cdk_pk_sign:
 * @sk: secret key
 * @sig: signature
 * @md: the message digest
 *
 * Sign the message digest from @md and write the result into @sig.
 **/
cdk_error_t
cdk_pk_sign (cdk_seckey_t sk, cdk_pkt_signature_t sig, const byte *md)
{
  gcry_sexp_t s_skey = NULL, s_sig = NULL, s_hash = NULL;
  byte *encmd = NULL;
  size_t enclen = 0;
  int nbits;
  cdk_error_t rc;
  gcry_error_t err;
  
  if (!sk || !sk->pk || !sig || !md)
    return CDK_Inv_Value;
  
  if (!is_unprotected (sk))
    return CDK_Inv_Mode;
  
  if (!KEY_CAN_SIGN (sig->pubkey_algo))
    return CDK_Inv_Algo;
  
  nbits = cdk_pk_get_nbits (sk->pk);
  rc = _cdk_digest_encode_pkcs1 (&encmd, &enclen, sk->pk->pubkey_algo, md,
				 sig->digest_algo, nbits);
  if (rc)
    return rc;

  rc = seckey_to_sexp (&s_skey, sk);
  if (!rc)
    rc = digest_to_sexp (&s_hash, sig->digest_algo, encmd, enclen);
  if (rc)
    {
      cdk_free (encmd);
      gcry_sexp_release (s_skey);
      return rc;
    }  
  
  err = gcry_pk_sign (&s_sig, s_hash, s_skey);
  if (err)
    rc = map_gcry_error (err);
  else
    {      
      rc = sexp_to_sig (sig, s_sig);
      if (!rc)
	{
	  sig->digest_start[0] = md[0];
	  sig->digest_start[1] = md[1];
	}
    }
  
  gcry_sexp_release (s_skey);
  gcry_sexp_release (s_hash);
  gcry_sexp_release (s_sig);
  cdk_free (encmd);
  return rc;
}
Esempio n. 12
0
void _cdk_free_userid(cdk_pkt_userid_t uid)
{
	if (!uid)
		return;

	cdk_free(uid->prefs);
	uid->prefs = NULL;
	cdk_free(uid->attrib_img);
	uid->attrib_img = NULL;
	cdk_free(uid);
}
Esempio n. 13
0
/**
 * cdk_pklist_encrypt:
 * @pkl: the keylist
 * @dek: the data encryption key
 * @outp: the stream to write in the data
 *
 * Encrypt the session key with each key of the list and wrap it
 * into a PUBKEY_ENC packet and write it to @outp.
 */
cdk_error_t
cdk_pklist_encrypt( cdk_keylist_t pk_list, cdk_dek_t dek, cdk_stream_t outp )
{
    cdk_pkt_pubkey_t pk = NULL;
    cdk_pkt_pubkey_enc_t enc = NULL;
    cdk_packet_t pkt;
    cdk_sesskey_t frame = NULL;
    int nbits = 0;
    int rc = 0;

    if( !pk_list || !dek || !outp )
        return CDK_Inv_Value;

    if( pk_list->type != CDK_PKT_PUBLIC_KEY )
        return CDK_Inv_Mode;

    pkt = cdk_calloc( 1, sizeof * pkt );
    if( !pkt )
        return CDK_Out_Of_Core;
    for( ; pk_list; pk_list = pk_list->next ) {
        pk = pk_list->key.pk;
        cdk_free( enc );
        enc = cdk_calloc( 1, sizeof *enc );
        if( !enc )
            return CDK_Out_Of_Core;
        enc->version = 3;
        enc->pubkey_algo = pk->pubkey_algo;
        cdk_pk_get_keyid( pk, enc->keyid );
        nbits = cdk_pk_get_nbits( pk );
        rc = cdk_dek_encode_pkcs1( dek, nbits, &frame );
        if( rc )
            break;
        rc = cdk_pk_encrypt( pk, enc, frame );
        cdk_sesskey_free( frame );
        if( rc )
            break;
        else {
            cdk_pkt_init( pkt );
            pkt->old_ctb = dek->rfc1991? 1 : 0;
            pkt->pkttype = CDK_PKT_PUBKEY_ENC;
            pkt->pkt.pubkey_enc = enc;
            rc = cdk_pkt_write( outp, pkt );
            cdk_pkt_free( pkt );
            if( rc )
                break;
	}
    }
    cdk_free( pkt );
    cdk_free( enc );
    return rc;
}
Esempio n. 14
0
void cdk_pk_release(cdk_pubkey_t pk)
{
	size_t npkey;

	if (!pk)
		return;

	npkey = cdk_pk_get_npkey(pk->pubkey_algo);
	_cdk_free_userid(pk->uid);
	pk->uid = NULL;
	cdk_free(pk->prefs);
	pk->prefs = NULL;
	_cdk_free_mpibuf(npkey, pk->mpi);
	cdk_free(pk);
}
Esempio n. 15
0
/* Detach the openpgp packet from the packet structure
   and release the packet structure itself. */
void
_cdk_pkt_detach_free (cdk_packet_t pkt, int *r_pkttype, void **ctx)
{
  /* For now we just allow this for keys. */
  switch (pkt->pkttype)
    {
    case CDK_PKT_PUBLIC_KEY:
    case CDK_PKT_PUBLIC_SUBKEY:
      *ctx = pkt->pkt.public_key;
      break;
      
    case CDK_PKT_SECRET_KEY:
    case CDK_PKT_SECRET_SUBKEY:
      *ctx = pkt->pkt.secret_key;
      break;
      
    default:
      *r_pkttype = 0;
      return;
    }
  
  /* The caller might expect a specific packet type and
     is not interested to store it for later use. */
  if (r_pkttype)
    *r_pkttype = pkt->pkttype;
  
  cdk_free (pkt);
}
Esempio n. 16
0
cdk_error_t
_cdk_pkt_write2 (cdk_stream_t out, int pkttype, void *pktctx)
{
  cdk_packet_t pkt;
  cdk_error_t rc;

  rc = cdk_pkt_new (&pkt);
  if (rc)
    return rc;

  switch (pkttype)
    {
    case CDK_PKT_PUBLIC_KEY:
    case CDK_PKT_PUBLIC_SUBKEY:
      pkt->pkt.public_key = pktctx;
      break;
    case CDK_PKT_SIGNATURE:
      pkt->pkt.signature = pktctx;
      break;
    case CDK_PKT_SECRET_KEY:
    case CDK_PKT_SECRET_SUBKEY:
      pkt->pkt.secret_key = pktctx;
      break;

    case CDK_PKT_USER_ID:
      pkt->pkt.user_id = pktctx;
      break;
    }
  pkt->pkttype = pkttype;
  rc = cdk_pkt_write (out, pkt);
  cdk_free (pkt);
  return rc;
}
Esempio n. 17
0
/**
 * cdk_pkt_release:
 * @pkt: the packet
 * 
 * Free the contents of the given package and
 * release the memory of the structure.
 **/
void cdk_pkt_release(cdk_packet_t pkt)
{
	if (!pkt)
		return;
	cdk_pkt_free(pkt);
	cdk_free(pkt);
}
Esempio n. 18
0
static void
free_symkey_enc (cdk_pkt_symkey_enc_t enc)
{
  if (!enc)
    return;
  cdk_s2k_free (enc->s2k);
  cdk_free (enc);
}
Esempio n. 19
0
/**
 * cdk_keygen_set_name: set the userid name for the key
 * @hd: the keygen object
 * @name: name
 *
 * The name will be encoded in UTF8 to avoid problems.
 **/
void
cdk_keygen_set_name( cdk_keygen_ctx_t hd, const char * name )
{
    if( hd ) {
        cdk_free( hd->user_id );
        hd->user_id = cdk_utf8_encode( name );
    }
}
Esempio n. 20
0
void cdk_sk_release(cdk_seckey_t sk)
{
	size_t nskey;

	if (!sk)
		return;

	nskey = cdk_pk_get_nskey(sk->pubkey_algo);
	_cdk_free_mpibuf(nskey, sk->mpi);
	cdk_free(sk->encdata);
	sk->encdata = NULL;
	cdk_pk_release(sk->pk);
	sk->pk = NULL;
	cdk_s2k_free(sk->protect.s2k);
	sk->protect.s2k = NULL;
	cdk_free(sk);
}
Esempio n. 21
0
static void free_literal(cdk_pkt_literal_t pt)
{
	if (!pt)
		return;
	/* The buffer which is referenced in this packet is closed
	   elsewhere. To close it here would cause a double close. */
	cdk_free(pt);
}
Esempio n. 22
0
/**
 * cdk_stream_write: 
 * @s: The STREAM object
 * @buf: The buffer with the values to write.
 * @count: The size of the buffer.
 *
 * Tries to write count bytes into the stream.
 * In this function we simply write the bytes to the stream. We can't
 * use the filters here because it would mean they have to support
 * partial flushing.
 **/
int
cdk_stream_write (cdk_stream_t s, const void *buf, size_t count)
{
  int nwritten;

  if (!s)
    {
      s->error = CDK_Inv_Value;
      gnutls_assert();
      return EOF;
    }

  if (s->cbs_hd)
    {
      if (s->cbs.write)
	return s->cbs.write (s->cbs_hd, buf, count);
      return 0;
    }

  if (!s->flags.write)
    {
      s->error = CDK_Inv_Mode;	/* this is a read stream */
      gnutls_assert();
      return EOF;
    }

  if (!buf && !count)
    return stream_flush (s);

  if (s->cache.on)
    {
      /* We need to resize the buffer if the additional data wouldn't
         fit into it. We allocate more memory to avoid to resize it the
         next time the function is used. */
      if (s->cache.size + count > s->cache.alloced)
	{
	  byte *old = s->cache.buf;

	  s->cache.buf =
	    cdk_calloc (1, s->cache.alloced + count + STREAM_BUFSIZE);
	  s->cache.alloced += (count + STREAM_BUFSIZE);
	  memcpy (s->cache.buf, old, s->cache.size);
	  cdk_free (old);
	  _cdk_log_debug ("stream: enlarge cache to %d octets\n",
			  s->cache.alloced);
	}
      memcpy (s->cache.buf + s->cache.size, buf, count);
      s->cache.size += count;
      return count;
    }

  nwritten = fwrite (buf, 1, count, s->fp);
  if (!nwritten)
    nwritten = EOF;
  return nwritten;
}
Esempio n. 23
0
byte *_cdk_subpkt_get_array(cdk_subpkt_t s, int count, size_t * r_nbytes)
{
	cdk_subpkt_t list;
	byte *buf;
	size_t n, nbytes;

	if (!s) {
		if (r_nbytes)
			*r_nbytes = 0;
		return NULL;
	}

	for (n = 0, list = s; list; list = list->next) {
		n++;		/* type */
		n += list->size;
		if (list->size < 192)
			n++;
		else if (list->size < 8384)
			n += 2;
		else
			n += 5;
	}
	buf = cdk_calloc(1, n + 1);
	if (!buf)
		return NULL;

	n = 0;
	for (list = s; list; list = list->next) {
		nbytes = 1 + list->size;	/* type */
		if (nbytes < 192)
			buf[n++] = nbytes;
		else if (nbytes < 8384) {
			nbytes -= 192;
			buf[n++] = nbytes / 256 + 192;
			buf[n++] = nbytes & 0xff;
		} else {
			buf[n++] = 0xFF;
			buf[n++] = nbytes >> 24;
			buf[n++] = nbytes >> 16;
			buf[n++] = nbytes >> 8;
			buf[n++] = nbytes;
		}

		buf[n++] = list->type;
		memcpy(buf + n, list->d, list->size);
		n += list->size;
	}

	if (count) {
		cdk_free(buf);
		buf = NULL;
	}
	if (r_nbytes)
		*r_nbytes = n;
	return buf;
}
Esempio n. 24
0
void
cdk_strlist_free (cdk_strlist_t sl)
{
    cdk_strlist_t sl2;

    for(; sl; sl = sl2 ) {
        sl2 = sl->next;
        cdk_free (sl);
    }
}
Esempio n. 25
0
/**
 * cdk_subpkt_free:
 * @ctx: the sub packet node to free
 *
 * Release the context.
 **/
void cdk_subpkt_free(cdk_subpkt_t ctx)
{
	cdk_subpkt_t s;

	while (ctx) {
		s = ctx->next;
		cdk_free(ctx);
		ctx = s;
	}
}
Esempio n. 26
0
/**
 * cdk_keygen_free: free the keygen object
 * @hd: the keygen object
 *
 **/
void
cdk_keygen_free( cdk_keygen_ctx_t hd )
{
    if( hd ) {
        _cdk_free_pubkey( hd->key[0].pk );
        _cdk_free_pubkey( hd->key[1].pk );
        _cdk_free_seckey( hd->key[0].sk );
        _cdk_free_seckey( hd->key[1].sk );
        _cdk_free_userid( hd->id );
        _cdk_free_signature( hd->sig );
        cdk_free( hd->sym_prefs );
        cdk_free( hd->hash_prefs );
        cdk_free( hd->zip_prefs );
        _cdk_sec_free( hd->pass, hd->pass_len );
        _cdk_free_mpibuf( hd->key[0].n, hd->key[0].resarr );
        _cdk_free_mpibuf( hd->key[1].n, hd->key[1].resarr );
        cdk_free( hd );
    }
}
Esempio n. 27
0
/* We encode the MD in this way:
 *
 * 0  1 PAD(n bytes)   0  ASN(asnlen bytes)  MD(len bytes)
 *
 * PAD consists of FF bytes.
 */
static cdk_error_t
do_encode_md (byte ** r_frame, size_t * r_flen, const byte * md, int algo,
              size_t len, unsigned nbits, const byte * asn, size_t asnlen)
{
  byte *frame = NULL;
  size_t nframe = (nbits + 7) / 8;
  ssize_t i;
  size_t n = 0;

  if (!asn || !md || !r_frame || !r_flen)
    return CDK_Inv_Value;

  if (len + asnlen + 4 > nframe)
    return CDK_General_Error;

  frame = cdk_calloc (1, nframe);
  if (!frame)
    return CDK_Out_Of_Core;
  frame[n++] = 0;
  frame[n++] = 1;
  i = nframe - len - asnlen - 3;
  if (i < 0)
    {
      cdk_free (frame);
      return CDK_Inv_Value;
    }
  memset (frame + n, 0xFF, i);
  n += i;
  frame[n++] = 0;
  memcpy (frame + n, asn, asnlen);
  n += asnlen;
  memcpy (frame + n, md, len);
  n += len;
  if (n != nframe)
    {
      cdk_free (frame);
      return CDK_Inv_Value;
    }
  *r_frame = frame;
  *r_flen = n;
  return 0;
}
Esempio n. 28
0
static void free_pubkey_enc(cdk_pkt_pubkey_enc_t enc)
{
	size_t nenc;

	if (!enc)
		return;

	nenc = cdk_pk_get_nenc(enc->pubkey_algo);
	_cdk_free_mpibuf(nenc, enc->mpi);
	cdk_free(enc);
}
Esempio n. 29
0
/**
 * cdk_sklist_write:
 * @skl: secret keylist
 * @outp: the stream to write in the data
 * @hash: opaque handle for the message digest operations
 * @sigclass: the class of the sig
 * @sigver: version of the sig
 *
 * Complete the sig based on @hash and write all signatures to @outp.
 **/
cdk_error_t
cdk_sklist_write( cdk_keylist_t skl, cdk_stream_t outp, cdk_md_hd_t hash,
		  int sigclass, int sigver )
{
    cdk_keylist_t r = NULL;
    cdk_pkt_signature_t sig = NULL;
    cdk_packet_t pkt;
    cdk_md_hd_t md = NULL;
    byte * mdbuf;
    int rc = 0, digest_algo;

    if( !skl || !outp || !hash )
        return CDK_Inv_Value;

    if( skl->type != CDK_PKT_SECRET_KEY )
        return CDK_Inv_Mode;

    pkt = cdk_calloc( 1, sizeof *pkt );
    if( !pkt )
        return CDK_Out_Of_Core;
    digest_algo = cdk_md_get_algo( hash );
    for( r = skl; r; r = r->next ) {
        sig = cdk_calloc( 1, sizeof *sig );
        if( !sig )
            return CDK_Out_Of_Core;
        sig->version = sigver;
        _cdk_sig_create( r->key.sk->pk, sig );
        if( sig->digest_algo != digest_algo )
            sig->digest_algo = digest_algo;
        sig->sig_class = sigclass;
        md = cdk_md_copy( hash );
        _cdk_hash_sig_data( sig, md );
        cdk_md_final( md );

        mdbuf = cdk_md_read( md, sig->digest_algo );
        rc = cdk_pk_sign( r->key.sk, sig, mdbuf );
        if( rc )
            break;
        cdk_pkt_init( pkt );
        pkt->old_ctb = sig->version == 3? 1 : 0;
        pkt->pkttype = CDK_PKT_SIGNATURE;
        pkt->pkt.signature = sig;
        rc = cdk_pkt_write( outp, pkt );
        cdk_pkt_free( pkt );
        if( rc )
            break;
        cdk_md_close( md );
        md = NULL;
    }
    cdk_free( pkt );
    cdk_md_close( md );
    return rc;
}
Esempio n. 30
0
/**
 * cdk_sklist_release:
 * @skl: secret keylist
 *
 * Free the memory of the secret keylist.
 **/
void
cdk_sklist_release( cdk_keylist_t sk_list )
{
    cdk_keylist_t sk_rover = NULL;

    for( ; sk_list; sk_list = sk_rover ) {
        sk_rover = sk_list->next;
        _cdk_free_seckey( sk_list->key.sk );
        sk_list->key.sk = NULL;
        cdk_free( sk_list );
    }
}