Example #1
0
/**
 * cdk_pk_get_fingerprint:
 * @pk: the public key
 * @fpr: the buffer to hold the fingerprint
 *
 * Return the fingerprint of the given public key.
 * The buffer must be at least 20 octets.
 * This function should be considered deprecated and
 * the new cdk_pk_to_fingerprint() should be used whenever
 * possible to avoid overflows.
 **/
cdk_error_t
cdk_pk_get_fingerprint (cdk_pubkey_t pk, byte * fpr)
{
    digest_hd_st hd;
    int md_algo;
    int dlen = 0;
    int err;

    if (!pk || !fpr)
        return CDK_Inv_Value;

    if (pk->version < 4 && is_RSA (pk->pubkey_algo))
        md_algo = GNUTLS_DIG_MD5;   /* special */
    else
        md_algo = GNUTLS_DIG_SHA1;
    dlen = _gnutls_hash_get_algo_len (md_algo);
    err = _gnutls_hash_init (&hd, md_algo);
    if (err < 0)
    {
        gnutls_assert ();
        return map_gnutls_error (err);
    }
    _cdk_hash_pubkey (pk, &hd, 1);
    _gnutls_hash_deinit (&hd, fpr);
    if (dlen == 16)
        memset (fpr + 16, 0, 4);
    return 0;
}
Example #2
0
/**
 * cdk_pk_get_fingerprint:
 * @pk: the public key
 * @fpr: the buffer to hold the fingerprint
 * 
 * Return the fingerprint of the given public key.
 * The buffer must be at least 20 octets.
 * This function should be considered deprecated and
 * the new cdk_pk_to_fingerprint() should be used whenever
 * possible to avoid overflows.
 **/
cdk_error_t
cdk_pk_get_fingerprint (cdk_pubkey_t pk, byte *fpr)
{
  gcry_md_hd_t hd;
  int md_algo;
  int dlen = 0;
  gcry_error_t err;

  if (!pk || !fpr)
    return CDK_Inv_Value;
  
  if (pk->version < 4 && is_RSA (pk->pubkey_algo))
    md_algo = GCRY_MD_MD5; /* special */
  else
    md_algo = GCRY_MD_SHA1;
  dlen = gcry_md_get_algo_dlen (md_algo);
  err = gcry_md_open (&hd, md_algo, 0);
  if (err)
    return map_gcry_error (err);
  _cdk_hash_pubkey (pk, hd, 1);
  gcry_md_final (hd);
  memcpy (fpr, gcry_md_read (hd, md_algo), dlen);
  gcry_md_close (hd);
  if (dlen == 16)
    memset (fpr + 16, 0, 4);
  return 0;
}
Example #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;
}
Example #4
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 #5
0
File: kbnode.c Project: ares89/vlc
/**
 * cdk_kbnode_hash:
 * @node: the key node
 * @hashctx: opaque pointer to the hash context
 * @is_v4: OpenPGP signature (yes=1, no=0)
 * @pkttype: packet type to hash (if zero use the packet type from the node)
 * @flags: flags which depend on the operation
 *
 * Hashes the key node contents. Two modes are supported. If the packet
 * type is used (!= 0) then the function searches the first node with
 * this type. Otherwise the node is seen as a single node and the type
 * is extracted from it.
 **/
cdk_error_t
cdk_kbnode_hash (cdk_kbnode_t node, digest_hd_st * md, int is_v4,
                 cdk_packet_type_t pkttype, int flags)
{
  cdk_packet_t pkt;

  if (!node || !md)
    {
      gnutls_assert ();
      return CDK_Inv_Value;
    }
  if (!pkttype)
    {
      pkt = cdk_kbnode_get_packet (node);
      pkttype = pkt->pkttype;
    }
  else
    {
      pkt = cdk_kbnode_find_packet (node, pkttype);
      if (!pkt)
        {
          gnutls_assert ();
          return CDK_Inv_Packet;
        }
    }

  switch (pkttype)
    {
    case CDK_PKT_PUBLIC_KEY:
    case CDK_PKT_PUBLIC_SUBKEY:
      _cdk_hash_pubkey (pkt->pkt.public_key, md, flags & 1);
      break;

    case CDK_PKT_USER_ID:
      _cdk_hash_userid (pkt->pkt.user_id, is_v4, md);
      break;

    case CDK_PKT_SIGNATURE:
      _cdk_hash_sig_data (pkt->pkt.signature, md);
      break;

    default:
      gnutls_assert ();
      return CDK_Inv_Mode;
    }
  return 0;
}
Example #6
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;
}