/** * 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; }
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; }
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; }
/** * 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 ); } }
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; }