Example #1
0
cdk_error_t
_cdk_subpkt_copy (cdk_subpkt_t *r_dst, cdk_subpkt_t src)
{
  cdk_subpkt_t root, p, node;
  
  if (!src || !r_dst)
    return CDK_Inv_Value;
  
  root = NULL;
  for (p = src; p; p = p->next) 
    {
      node = cdk_subpkt_new (p->size);
      if (node) 
	{
	  memcpy (node->d, p->d, p->size);
	  node->type = p->type;
	  node->size = p->size;
        }
      if (!root)
	root = node;
      else
	cdk_subpkt_add (root, node);
    }
  *r_dst = root;
  return 0;
}
Example #2
0
static cdk_error_t
read_subpkt (cdk_stream_t inp, cdk_subpkt_t * r_ctx, size_t * r_nbytes)
{
  byte c, c1;
  size_t size, nread, n;
  cdk_subpkt_t node;
  cdk_error_t rc;

  if (!inp || !r_nbytes)
    return CDK_Inv_Value;

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

  n = 0;
  *r_nbytes = 0;
  c = cdk_stream_getc (inp);
  n++;
  if (c == 255)
    {
      size = read_32 (inp);
      n += 4;
    }
  else if (c >= 192 && c < 255)
    {
      c1 = cdk_stream_getc (inp);
      n++;
      if (c1 == 0)
	return 0;
      size = ((c - 192) << 8) + c1 + 192;
    }
  else if (c < 192)
    size = c;
  else
    return CDK_Inv_Packet;

  node = cdk_subpkt_new (size);
  if (!node)
    return CDK_Out_Of_Core;
  node->size = size;
  node->type = cdk_stream_getc (inp);
  if (DEBUG_PKT)
    _cdk_log_debug (" %d octets %d type\n", node->size, node->type);
  n++;
  node->size--;
  rc = stream_read (inp, node->d, node->size, &nread);
  n += nread;
  if (rc)
    return rc;
  *r_nbytes = n;
  if (!*r_ctx)
    *r_ctx = node;
  else
    cdk_subpkt_add (*r_ctx, node);
  return rc;
}
Example #3
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;
}
Example #4
0
static cdk_pkt_signature_t
sig_subkey_create( cdk_keygen_ctx_t hd )
{
    cdk_md_hd_t md;
    cdk_subpkt_t node;
    cdk_pkt_signature_t sig;
    cdk_pkt_pubkey_t pk = hd->key[0].pk;
    cdk_pkt_pubkey_t sub_pk = hd->key[1].pk;
    cdk_pkt_seckey_t sk = hd->key[0].sk;
    byte buf[4];
    int rc;
  
    sig = cdk_calloc( 1, sizeof * sig );
    if( !sig )
        return NULL;
    _cdk_sig_create( pk, sig );
    sig->sig_class = 0x18;
    sig->digest_algo = CDK_MD_SHA1;

    if( sub_pk->expiredate ) {
        _cdk_u32tobuf( sub_pk->expiredate - sub_pk->timestamp, buf );
        node = cdk_subpkt_new( 4 );
        if( node ) {
            cdk_subpkt_init( node, CDK_SIGSUBPKT_KEY_EXPIRE, buf, 4 );
            cdk_subpkt_add( sig->hashed, node );
        }
    }
  
    md = cdk_md_open( sig->digest_algo, 0 );
    if( !md ) {
        _cdk_free_signature( sig );
        return NULL;
    }
    
    _cdk_hash_pubkey( pk, md, 0 );
    _cdk_hash_pubkey( sub_pk, md, 0 );
    rc = _cdk_sig_complete( sig, sk, md );
    cdk_md_close( md );
    if( rc ) {
        _cdk_free_signature( sig );
        return NULL;
    }
    return sig;
}
Example #5
0
static cdk_pkt_signature_t
sig_self_create( cdk_keygen_ctx_t hd )
{
    cdk_md_hd_t md;
    cdk_subpkt_t node;
    cdk_pkt_signature_t sig;
    cdk_pkt_pubkey_t pk = hd->key[0].pk;
    cdk_pkt_userid_t id = hd->id;
    cdk_pkt_seckey_t sk = hd->key[0].sk;
    u32 keyid[2];
    byte buf[8], * p;
    int rc;

    sig = cdk_calloc( 1, sizeof * sig );
    if( !sig )
        return NULL;
    sig->version = 4;
    sig->timestamp = _cdk_timestamp( );
    sig->sig_class = 0x13;
    sig->pubkey_algo = hd->key[0].algo;
    sig->digest_algo = CDK_MD_SHA1;

    _cdk_u32tobuf( sig->timestamp, buf );
    sig->hashed = node = cdk_subpkt_new( 4 );
    if( node )
        cdk_subpkt_init( node, CDK_SIGSUBPKT_SIG_CREATED, buf, 4 );

    p = hd->sym_prefs;
    node = cdk_subpkt_new( hd->sym_len + 1 );
    if( node ) {
        cdk_subpkt_init( node, CDK_SIGSUBPKT_PREFS_SYM, p, hd->sym_len );
        cdk_subpkt_add( sig->hashed, node );
    }

    p = hd->hash_prefs;
    node = cdk_subpkt_new( hd->hash_len + 1 );
    if( node ) {
        cdk_subpkt_init( node, CDK_SIGSUBPKT_PREFS_HASH, p, hd->hash_len );
        cdk_subpkt_add( sig->hashed, node );
    }

    p = hd->zip_prefs;
    node = cdk_subpkt_new( hd->zip_len + 1 );
    if( node ) {
        cdk_subpkt_init( node, CDK_SIGSUBPKT_PREFS_ZIP, p, hd->zip_len );
        cdk_subpkt_add( sig->hashed, node );
    }

    if( hd->mdc_feature ) {
        buf[0] = 0x01;
        node = cdk_subpkt_new( 1 );
        if( node ) {
            cdk_subpkt_init( node, CDK_SIGSUBPKT_FEATURES, buf, 1 );
            cdk_subpkt_add( sig->hashed, node );
        }
    }

    if( hd->ks_no_modify ) {
        buf[0] = 0x80;
        node = cdk_subpkt_new( 1 );
        if( node ) {
            cdk_subpkt_init( node, CDK_SIGSUBPKT_KS_FLAGS, buf, 1 );
            cdk_subpkt_add( sig->hashed, node );
        }
    }

    if( hd->ks_pref_url ) {
        node = cdk_subpkt_new( strlen( hd->ks_pref_url ) + 1 );
        if( node ) {
            cdk_subpkt_init( node, CDK_SIGSUBPKT_PREF_KS,
                             hd->ks_pref_url, strlen( hd->ks_pref_url ) );
            cdk_subpkt_add( sig->hashed, node );
        }
    }
  
    if( pk->expiredate ) {
        node = cdk_subpkt_new( 4 );
        if( node ) {
            _cdk_u32tobuf( pk->expiredate - pk->timestamp, buf );
            cdk_subpkt_init( node, CDK_SIGSUBPKT_KEY_EXPIRE, buf, 4 );
            cdk_subpkt_add( sig->hashed, node );
        }
    }

    sig->unhashed = node = cdk_subpkt_new( 8 );
    if( node ) {
        cdk_pk_get_keyid( pk, keyid );
        _cdk_u32tobuf( keyid[0], buf );
        _cdk_u32tobuf( keyid[1], buf + 4 );
        cdk_subpkt_init( node, CDK_SIGSUBPKT_ISSUER,  buf, 8 );
    }

    md = cdk_md_open( sig->digest_algo, 0 );
    if( !md ) {
        _cdk_free_signature( sig );
        return NULL;
    }

    _cdk_hash_pubkey( pk, md, 0 );
    _cdk_hash_userid( id, sig->version == 4, md );
    rc = _cdk_sig_complete( sig, sk, md );
    cdk_md_close( md );
    if( rc ) {
        _cdk_free_signature( sig );
        return NULL;
    }  
    return sig;
}