Esempio n. 1
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. 2
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. 3
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;
}
Esempio n. 4
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. 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;
}