summaryrefslogtreecommitdiff
path: root/libextra/opencdk/keygen.c
diff options
context:
space:
mode:
Diffstat (limited to 'libextra/opencdk/keygen.c')
-rw-r--r--libextra/opencdk/keygen.c872
1 files changed, 0 insertions, 872 deletions
diff --git a/libextra/opencdk/keygen.c b/libextra/opencdk/keygen.c
deleted file mode 100644
index 18dd6730d3..0000000000
--- a/libextra/opencdk/keygen.c
+++ /dev/null
@@ -1,872 +0,0 @@
-/* -*- Mode: C; c-file-style: "bsd" -*-
- * keygen.c - OpenPGP key generation
- * Copyright (C) 2006 Free Software Foundation, Inc.
- * Copyright (C) 2002, 2003 Timo Schulz
- *
- * This file is part of OpenCDK.
- *
- * OpenCDK is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * OpenCDK is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with OpenCDK; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
- */
-
-#ifdef HAVE_CONFIG_H
-# include <config.h>
-#endif
-#include <stdio.h>
-
-#include "opencdk.h"
-#include "main.h"
-#include "packet.h"
-#include "cipher.h"
-#include "types.h"
-
-struct key_ctx_s {
- u32 expire_date;
- int algo;
- int len;
- gcry_mpi_t resarr[6];
- size_t n;
- cdk_pkt_pubkey_t pk;
- cdk_pkt_seckey_t sk;
-};
-
-
-struct cdk_keygen_ctx_s {
- char * user_id;
- cdk_pkt_userid_t id;
- byte * sym_prefs;
- size_t sym_len;
- byte * hash_prefs;
- size_t hash_len;
- byte * zip_prefs;
- size_t zip_len;
- unsigned mdc_feature:1;
- unsigned ks_no_modify:1;
- char * ks_pref_url;
- cdk_pkt_signature_t sig;
- unsigned protect:1;
- struct key_ctx_s key[2];
- char * pass;
- size_t pass_len;
-};
-
-
-/* default preferences */
-static byte def_sym_prefs[] = {CDK_CIPHER_AES, CDK_CIPHER_CAST5,
- CDK_CIPHER_TWOFISH, CDK_CIPHER_AES192,
- CDK_CIPHER_AES256, CDK_CIPHER_3DES,
- CDK_CIPHER_BLOWFISH};
-static byte def_hash_prefs[] = {CDK_MD_SHA1, CDK_MD_RMD160, CDK_MD_MD5};
-static byte def_zip_prefs[] = {CDK_COMPRESS_ZIP, CDK_COMPRESS_ZLIB};
-
-
-static int
-check_pref_array( const byte * p, size_t n, int type )
-{
- int i;
-
- if( !p )
- return 0;
-
- if( type == CDK_PREFTYPE_SYM ) {
- for( i = 0; i < n; i++ ) {
- if( cdk_cipher_test_algo( p[i] ) )
- return -1;
- }
- }
- else if( type == CDK_PREFTYPE_HASH ) {
- for( i = 0; i < n; i++ ) {
- if( cdk_md_test_algo( p[i] ) )
- return -1;
- }
- }
- else if( type == CDK_PREFTYPE_ZIP ) {
- if( n > 2 )
- return -1;
- if( p[0] > 2 || p[1] > 2 )
- return -1;
- }
- else
- return -1;
- return 0;
-}
-
-
-/**
- * cdk_keygen_set_prefs: Set the preferences for the userID
- * @hd: the keygen object
- * @type: the preference type
- * @array: one-octet array with algorithm numers
- * @n: length of @array.
- *
- **/
-cdk_error_t
-cdk_keygen_set_prefs( cdk_keygen_ctx_t hd, enum cdk_pref_type_t type,
- const byte * array, size_t n )
-{
- int rc;
-
- if( !hd )
- return CDK_Inv_Value;
-
- rc = check_pref_array( array, n, type );
- if( rc )
- return CDK_Inv_Value;
-
- switch( type) {
- case CDK_PREFTYPE_SYM:
- hd->sym_len = array? n : DIM( def_sym_prefs );
- hd->sym_prefs = cdk_calloc( 1, hd->sym_len );
- if( hd->sym_prefs )
- memcpy( hd->sym_prefs, array? array : def_sym_prefs, hd->sym_len );
- break;
-
- case CDK_PREFTYPE_HASH:
- hd->hash_len = array? n : DIM( def_hash_prefs );
- hd->hash_prefs = cdk_calloc( 1, hd->hash_len );
- if( hd->hash_prefs )
- memcpy( hd->hash_prefs, array? array : def_hash_prefs,
- hd->hash_len );
- break;
-
- case CDK_PREFTYPE_ZIP:
- hd->zip_len = array? n : DIM( def_zip_prefs );
- hd->zip_prefs = cdk_calloc( 1, hd->zip_len );
- if( hd->zip_prefs )
- memcpy( hd->zip_prefs, array? array : def_zip_prefs, hd->zip_len );
- break;
-
- default:
- return CDK_Inv_Mode;
- }
-
- return 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 );
- }
-}
-
-
-static int
-check_bits( int bits, int algo )
-{
- if( bits < 768 )
- return 768;
- if( algo == CDK_PK_DSA && bits > 1024 )
- return 1024;
- if( bits > 4096 )
- return 4096;
- return bits;
-}
-
-
-/**
- * cdk_keygen_set_algo_info: set the length and type of the key
- * @hd: the keygen object.
- * @type: key type (primary=0, subkey=1)
- * @algo: algorithm compliant with rfc2440
- * @bits: lengt of the key in bits
- *
- **/
-cdk_error_t
-cdk_keygen_set_algo_info( cdk_keygen_ctx_t hd, int type,
- enum cdk_pk_algo_t algo, int bits )
-{
- int rc;
- int usage = type? PK_USAGE_ENCR : PK_USAGE_SIGN;
-
- if( !hd )
- return CDK_Inv_Value;
- if( type < 0 || type > 1 )
- return CDK_Inv_Value;
-
- if( bits % 128 != 0 )
- bits = bits + ( bits % 128 );
-
- rc = _cdk_pk_test_algo( algo, usage );
- if( rc )
- return rc;
-
- /* type=0 primary type=1 sub */
- hd->key[type].algo = algo;
- hd->key[type].len = check_bits( bits, algo );
-
- return 0;
-}
-
-
-/**
- * cdk_keygen_set_mdc_feature: set the mdc feature for the key
- * @hd: keygen object
- * @val: boolean( yes=1, no=0)
- *
- * if you want a RFC2440 compliant key, you've to disable this feature
- * until the rfc2440-bis8 becomes the next standard.
- **/
-void
-cdk_keygen_set_mdc_feature( cdk_keygen_ctx_t hd, int val )
-{
- if( hd )
- hd->mdc_feature = val;
-}
-
-
-
-void
-cdk_keygen_set_keyserver_flags( cdk_keygen_ctx_t hd, int no_modify,
- const char *pref_url )
-{
- if( no_modify )
- hd->ks_no_modify = 1;
- if( pref_url )
- hd->ks_pref_url = cdk_strdup( pref_url );
-} /* cdk_keygen_set_keyserver_flags */
-
-
-/**
- * cdk_keygen_set_expire_date: set the expire date of the primary key
- * @hd: keygen object
- * @type: key type( 0=primary, 1=seconardy)
- * @timestamp: the date the key should expire
- *
- **/
-void
-cdk_keygen_set_expire_date( cdk_keygen_ctx_t hd, int type, long int timestamp )
-{
- if( !hd )
- return;
- if( type < 0 || type > 1 )
- return;
- if( timestamp < 0 || timestamp < _cdk_timestamp( ) )
- timestamp = 0;
- hd->key[type].expire_date = timestamp;
-}
-
-
-void
-cdk_keygen_set_passphrase( cdk_keygen_ctx_t hd, const char * pass )
-{
- if( !hd )
- return;
- if( pass ) {
- size_t n = strlen( pass );
- _cdk_sec_free( hd->pass, hd->pass_len );
- hd->pass = cdk_salloc( n + 1, 1 );
- if( hd->pass ) {
- memcpy( hd->pass, pass, n );
- hd->pass[n] = '\0';
- hd->pass_len = n;
- hd->protect = 1;
- }
- }
-}
-
-
-static int
-read_single_mpi( gcry_sexp_t s_key, const char * val, gcry_mpi_t * r_resarr )
-{
- gcry_sexp_t list;
-
- if( !r_resarr )
- return CDK_Inv_Value;
- list = gcry_sexp_find_token( s_key, val, 0 );
- if( list )
- *r_resarr = gcry_sexp_nth_mpi( list, 1, 0 );
- gcry_sexp_release( list );
- return list? 0 : CDK_Gcry_Error;
-}
-
-
-static int
-read_dsa_key( gcry_sexp_t s_key, gcry_mpi_t * resarr )
-{
- int rc = read_single_mpi( s_key, "p", &resarr[0] );
- if( !rc )
- rc = read_single_mpi( s_key, "q", &resarr[1] );
- if( !rc )
- rc = read_single_mpi( s_key, "g", &resarr[2] );
- if( !rc )
- rc = read_single_mpi( s_key, "y", &resarr[3] );
- if( !rc )
- rc = read_single_mpi( s_key, "x", &resarr[4] );
- return rc;
-}
-
-
-static int
-read_elg_key( gcry_sexp_t s_key, gcry_mpi_t * resarr )
-{
- int rc = read_single_mpi( s_key, "p", &resarr[0] );
- if( !rc )
- rc = read_single_mpi( s_key, "g", &resarr[1] );
- if( !rc )
- rc = read_single_mpi( s_key, "y", &resarr[2] );
- if( !rc )
- rc = read_single_mpi( s_key, "x", &resarr[3] );
- return rc;
-}
-
-
-static int
-read_rsa_key( gcry_sexp_t s_key, gcry_mpi_t * resarr )
-{
- int rc = read_single_mpi( s_key, "n", &resarr[0] );
- if( !rc )
- rc =read_single_mpi( s_key, "e", &resarr[1] );
- if( !rc )
- rc = read_single_mpi( s_key, "d", &resarr[2] );
- if( !rc )
- rc = read_single_mpi( s_key, "p", &resarr[3] );
- if( !rc )
- rc = read_single_mpi( s_key, "q", &resarr[4] );
- if( !rc )
- rc = read_single_mpi( s_key, "u", &resarr[5] );
- return rc;
-}
-
-
-static int
-generate_subkey( cdk_keygen_ctx_t hd )
-{
- gcry_sexp_t s_params = NULL, s_key;
- size_t n = hd->key[1].len;
- int rc;
-
- if( !hd )
- return CDK_Inv_Value;
-
- if( is_DSA( hd->key[1].algo) )
- rc = gcry_sexp_build( &s_params, NULL, "(genkey(dsa(nbits %d)))", n );
- else if( is_ELG( hd->key[1].algo) )
- rc = gcry_sexp_build( &s_params, NULL, "(genkey(elg(nbits %d)))", n );
- else if( is_RSA( hd->key[1].algo) )
- rc = gcry_sexp_build( &s_params, NULL, "(genkey(rsa(nbits %d)))", n );
- else
- rc = CDK_Inv_Algo;
- if( !rc )
- rc = gcry_pk_genkey( &s_key, s_params );
- gcry_sexp_release( s_params );
- if( !rc ) {
- if( is_DSA( hd->key[1].algo) )
- rc = read_dsa_key( s_key, hd->key[1].resarr );
- else if( is_ELG( hd->key[1].algo) )
- rc = read_elg_key( s_key, hd->key[1].resarr );
- else if( is_RSA( hd->key[1].algo) )
- rc = read_rsa_key( s_key, hd->key[1].resarr );
- }
- hd->key[1].n = cdk_pk_get_npkey( hd->key[1].algo );
- gcry_sexp_release( s_key );
- return rc;
-}
-
-
-/**
- * cdk_keygen_start: kick off the key generation
- * @hd: the keygen object
- *
- **/
-cdk_error_t
-cdk_keygen_start( cdk_keygen_ctx_t hd )
-{
- gcry_sexp_t s_params = NULL, s_key = NULL;
- size_t n;
- int rc = 0;
-
- if( !hd || !hd->user_id )
- return CDK_Inv_Value;
- if( is_ELG( hd->key[0].algo ) )
- return CDK_Inv_Mode;
- if( !hd->key[0].len )
- hd->key[0].len = 1024;
- n = hd->key[0].len;
-
- if( !hd->sym_prefs )
- cdk_keygen_set_prefs( hd, CDK_PREFTYPE_SYM, NULL, 0 );
- if( !hd->hash_prefs )
- cdk_keygen_set_prefs( hd, CDK_PREFTYPE_HASH, NULL, 0 );
- if( !hd->zip_prefs )
- cdk_keygen_set_prefs( hd, CDK_PREFTYPE_ZIP, NULL, 0 );
-
- if( is_DSA( hd->key[0].algo ) )
- rc = gcry_sexp_build( &s_params, NULL, "(genkey(dsa(nbits %d)))", n );
- else if( is_RSA( hd->key[0].algo ) )
- rc = gcry_sexp_build( &s_params, NULL, "(genkey(rsa(nbits %d)))", n );
- else
- rc = CDK_Inv_Algo;
- if( !rc )
- rc = gcry_pk_genkey( &s_key, s_params );
- gcry_sexp_release( s_params );
- if( !rc ) {
- if( is_DSA( hd->key[0].algo ) )
- rc = read_dsa_key( s_key, hd->key[0].resarr );
- else if( is_RSA( hd->key[0].algo ) )
- rc = read_rsa_key( s_key, hd->key[0].resarr );
- hd->key[0].n = cdk_pk_get_npkey( hd->key[0].algo );
- }
- gcry_sexp_release( s_key );
- if( !rc ) {
- if( hd->key[1].algo && hd->key[1].len )
- rc = generate_subkey( hd );
- }
- return rc;
-}
-
-
-static int
-gcry_mpi_to_native( cdk_keygen_ctx_t hd, size_t nkey, int type,
- cdk_pkt_pubkey_t pk, cdk_pkt_seckey_t sk )
-{
- gcry_mpi_t * resarr;
- cdk_mpi_t a = NULL;
- size_t nbytes;
- int i = 0, j = 0, nbits;
- int rc = 0;
-
- if( !hd )
- return CDK_Inv_Value;
- if( !pk && !sk )
- return CDK_Inv_Value;
- if( type < 0 || type > 1 )
- return CDK_Inv_Value;
-
- resarr = hd->key[type].resarr;
- if( sk )
- i += cdk_pk_get_npkey( sk->pubkey_algo );
- while( j != nkey ) {
- nbits = gcry_mpi_get_nbits( resarr[i] );
- if( pk )
- a = cdk_calloc( 1, sizeof * a + (nbits + 7) / 8 + 2 + 1 );
- else if( sk )
- a = cdk_salloc( sizeof * a + (nbits + 7) / 8 + 2 + 1, 1 );
- a->bits = nbits;
- a->bytes = ( nbits + 7 ) / 8;
- nbytes = a->bytes;
- a->data[0] = nbits >> 8;
- a->data[1] = nbits;
- rc = gcry_mpi_print( GCRYMPI_FMT_USG, a->data+2, nbytes, &nbytes, resarr[i] );
- if( rc )
- break;
- if( pk )
- pk->mpi[j++] = a;
- else if( sk )
- sk->mpi[j++] = a;
- i++;
- }
- return rc;
-}
-
-
-static cdk_pkt_pubkey_t
-pk_create( cdk_keygen_ctx_t hd, int type )
-{
- cdk_pkt_pubkey_t pk;
- int rc = 0, npkey = 0;
-
- if( type < 0 || type > 1 )
- return NULL;
- pk = cdk_calloc( 1, sizeof * pk );
- if( !pk )
- return NULL;
- pk->version = 4;
- pk->pubkey_algo = hd->key[type].algo;
- pk->timestamp = _cdk_timestamp( );
- if( hd->key[type].expire_date )
- pk->expiredate = pk->timestamp + hd->key[type].expire_date;
- npkey = cdk_pk_get_npkey( pk->pubkey_algo );
- rc = gcry_mpi_to_native( hd, npkey, type, pk, NULL );
- if( rc ) {
- cdk_free( pk );
- pk = NULL;
- }
- return pk;
-}
-
-
-static cdk_pkt_seckey_t
-sk_create( cdk_keygen_ctx_t hd, int type )
-{
- cdk_pkt_seckey_t sk;
- int nskey, rc = 0;
-
- if( type < 0 || type > 1 )
- return NULL;
- sk = cdk_calloc( 1, sizeof * sk );
- if( !sk )
- return NULL;
- _cdk_copy_pubkey( &sk->pk, hd->key[type].pk );
- sk->version = 4;
- sk->pubkey_algo = hd->key[type].algo;
- sk->csum = 0;
- sk->is_protected = 0;
- nskey = cdk_pk_get_nskey( sk->pubkey_algo );
- rc = gcry_mpi_to_native( hd, nskey, type, NULL, sk );
- if( rc ) {
- cdk_free( sk );
- sk = NULL;
- }
- return sk;
-}
-
-
-static cdk_pkt_userid_t
-uid_create( cdk_keygen_ctx_t hd )
-{
- cdk_pkt_userid_t id;
-
- if( !hd->user_id )
- return NULL;
- id = cdk_calloc( 1, sizeof * id + strlen( hd->user_id ) + 1 );
- if( !id )
- return NULL;
- strcpy( id->name, hd->user_id );
- id->len = strlen( hd->user_id );
- return id;
-}
-
-
-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;
-}
-
-
-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;
-}
-
-
-/**
- * cdk_keygen_save: save the generated keys to disk
- * @hd: the keygen object
- * @pubf: name of the file to store the public key
- * @secf: name of the file to store the secret key
- *
- **/
-cdk_error_t
-cdk_keygen_save( cdk_keygen_ctx_t hd, const char * pubf, const char * secf )
-{
- cdk_stream_t out = NULL;
- CDK_PACKET pkt;
- int rc;
-
- hd->key[0].pk = pk_create( hd, 0 );
- if( !hd->key[0].pk )
- return CDK_Inv_Packet;
- hd->key[0].sk = sk_create( hd, 0 );
- if( !hd->key[0].sk )
- return CDK_Inv_Packet;
- hd->id = uid_create( hd );
- if( !hd->id )
- return CDK_Inv_Packet;
- hd->sig = sig_self_create( hd );
- if( !hd->sig )
- return CDK_Inv_Packet;
-
- rc = cdk_stream_create( pubf, &out );
- if( rc )
- return rc;
-
- cdk_pkt_init( &pkt );
- pkt.pkttype = CDK_PKT_PUBLIC_KEY;
- pkt.pkt.public_key = hd->key[0].pk;
- rc = cdk_pkt_write( out, &pkt );
- if( rc )
- goto fail;
-
- cdk_pkt_init( &pkt );
- pkt.pkttype = CDK_PKT_USER_ID;
- pkt.pkt.user_id = hd->id;
- rc = cdk_pkt_write( out, &pkt );
- if( rc )
- goto fail;
-
- cdk_pkt_init( &pkt );
- pkt.pkttype = CDK_PKT_SIGNATURE;
- pkt.pkt.signature = hd->sig;
- rc = cdk_pkt_write( out, &pkt );
- if( rc )
- goto fail;
-
- if( hd->key[1].algo ) {
- cdk_pkt_init( &pkt );
- pkt.pkttype = CDK_PKT_PUBLIC_SUBKEY;
- pkt.pkt.public_key = hd->key[1].pk = pk_create( hd, 1 );
- rc = cdk_pkt_write( out, &pkt );
- if( rc )
- goto fail;
-
- cdk_pkt_init( &pkt );
- pkt.pkttype = CDK_PKT_SIGNATURE;
- pkt.pkt.signature = sig_subkey_create( hd );
- rc = cdk_pkt_write( out, &pkt );
- cdk_pkt_free( &pkt );
- if( rc )
- goto fail;
- }
-
- cdk_stream_close( out );
- out = NULL;
-
- rc = cdk_stream_create( secf, &out );
- if( rc )
- goto fail;
-
- if( hd->protect ) {
- rc = cdk_sk_protect( hd->key[0].sk, hd->pass );
- if( rc )
- goto fail;
- }
-
- cdk_pkt_init( &pkt );
- pkt.pkttype = CDK_PKT_SECRET_KEY;
- pkt.pkt.secret_key = hd->key[0].sk;
- rc = cdk_pkt_write( out, &pkt );
- if( rc )
- goto fail;
-
- cdk_pkt_init( &pkt );
- pkt.pkttype = CDK_PKT_USER_ID;
- pkt.pkt.user_id = hd->id;
- rc = cdk_pkt_write( out, &pkt );
- if( rc )
- goto fail;
-
- cdk_pkt_init( &pkt );
- pkt.pkttype = CDK_PKT_SIGNATURE;
- pkt.pkt.signature = hd->sig;
- rc = cdk_pkt_write( out, &pkt );
- if( rc )
- goto fail;
-
- if( hd->key[1].algo ) {
- hd->key[1].sk = sk_create( hd, 1 );
- if( hd->protect && (rc = cdk_sk_protect( hd->key[1].sk, hd->pass )) )
- goto fail;
- cdk_pkt_init( &pkt );
- pkt.pkttype = CDK_PKT_SECRET_SUBKEY;
- pkt.pkt.secret_key = hd->key[1].sk;
- rc = cdk_pkt_write( out, &pkt );
- if( rc )
- goto fail;
- }
-
- fail:
- cdk_stream_close( out );
- return rc;
-}
-
-
-/**
- * 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 );
- }
-}
-
-
-/**
- * cdk_keygen_new:
- * @r_hd: the new object
- *
- **/
-cdk_error_t
-cdk_keygen_new( cdk_keygen_ctx_t * r_hd )
-{
- cdk_keygen_ctx_t hd;
-
- if( !r_hd )
- return CDK_Inv_Value;
- hd = cdk_calloc( 1, sizeof * hd );
- if( !hd )
- return CDK_Out_Of_Core;
- *r_hd = hd;
- return 0;
-}