cdk_error_t _cdk_copy_seckey (cdk_pkt_seckey_t* dst, cdk_pkt_seckey_t src) { cdk_pkt_seckey_t k; int i; if (!dst || !src) return CDK_Inv_Value; *dst = NULL; k = cdk_calloc (1, sizeof *k); if (!k) return CDK_Out_Of_Core; memcpy (k, src, sizeof *k); _cdk_copy_pubkey (&k->pk, src->pk); if (src->encdata) { k->encdata = cdk_calloc (1, src->enclen + 1); if (!k->encdata) return CDK_Out_Of_Core; memcpy (k->encdata, src->encdata, src->enclen); } _cdk_s2k_copy (&k->protect.s2k, src->protect.s2k); for (i = 0; i < cdk_pk_get_nskey (src->pubkey_algo); i++) { k->mpi[i] = gcry_mpi_copy (src->mpi[i]); gcry_mpi_set_flag (k->mpi[i], GCRYMPI_FLAG_SECURE); } *dst = k; return 0; }
cdk_error_t cdk_sklist_build( cdk_keylist_t * ret_skl, cdk_keydb_hd_t db, cdk_ctx_t hd, cdk_strlist_t locusr, int unlock, unsigned int use ) { cdk_keylist_t r = NULL, sk_list = NULL; cdk_pkt_seckey_t sk = NULL; int rc = 0; if( !db || !hd || !ret_skl ) return CDK_Inv_Value; if( !locusr ) { /* use the default one */ rc = _cdk_keydb_get_sk_byusage( db, NULL, &sk, use ); if( rc ) { _cdk_free_seckey( sk ); return rc; } if( unlock ) { rc = _cdk_sk_unprotect_auto( hd, sk ); if( rc ) return rc; } r = cdk_calloc( 1, sizeof *r ); if( !r ) return CDK_Out_Of_Core; r->key.sk = sk; r->next = sk_list; r->type = CDK_PKT_SECRET_KEY; sk_list = r; } else { cdk_strlist_t locusr_orig = locusr; for( ; locusr; locusr = locusr->next ) { if( is_duplicated_entry( locusr_orig, locusr ) ) continue; rc = _cdk_keydb_get_sk_byusage( db, locusr->d, &sk, use ); if( rc ) { _cdk_free_seckey( sk ); sk = NULL; } else { if( unlock && (rc = _cdk_sk_unprotect_auto( hd, sk )) ) break; r = cdk_calloc( 1, sizeof *r ); if( !r ) return CDK_Out_Of_Core; r->key.sk = sk; r->next = sk_list; r->type = CDK_PKT_SECRET_KEY; sk_list = r; } } } if( rc ) { cdk_sklist_release( sk_list ); sk_list = NULL; } *ret_skl = sk_list; return rc; }
/** * 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; }
/** * cdk_sklist_write: * @skl: secret keylist * @outp: the stream to write in the data * @hash: opaque handle for the message digest operations * @sigclass: the class of the sig * @sigver: version of the sig * * Complete the sig based on @hash and write all signatures to @outp. **/ cdk_error_t cdk_sklist_write( cdk_keylist_t skl, cdk_stream_t outp, cdk_md_hd_t hash, int sigclass, int sigver ) { cdk_keylist_t r = NULL; cdk_pkt_signature_t sig = NULL; cdk_packet_t pkt; cdk_md_hd_t md = NULL; byte * mdbuf; int rc = 0, digest_algo; if( !skl || !outp || !hash ) return CDK_Inv_Value; if( skl->type != CDK_PKT_SECRET_KEY ) return CDK_Inv_Mode; pkt = cdk_calloc( 1, sizeof *pkt ); if( !pkt ) return CDK_Out_Of_Core; digest_algo = cdk_md_get_algo( hash ); for( r = skl; r; r = r->next ) { sig = cdk_calloc( 1, sizeof *sig ); if( !sig ) return CDK_Out_Of_Core; sig->version = sigver; _cdk_sig_create( r->key.sk->pk, sig ); if( sig->digest_algo != digest_algo ) sig->digest_algo = digest_algo; sig->sig_class = sigclass; md = cdk_md_copy( hash ); _cdk_hash_sig_data( sig, md ); cdk_md_final( md ); mdbuf = cdk_md_read( md, sig->digest_algo ); rc = cdk_pk_sign( r->key.sk, sig, mdbuf ); if( rc ) break; cdk_pkt_init( pkt ); pkt->old_ctb = sig->version == 3? 1 : 0; pkt->pkttype = CDK_PKT_SIGNATURE; pkt->pkt.signature = sig; rc = cdk_pkt_write( outp, pkt ); cdk_pkt_free( pkt ); if( rc ) break; cdk_md_close( md ); md = NULL; } cdk_free( pkt ); cdk_md_close( md ); return rc; }
/** * cdk_sklist_write_onepass: * @skl: secret keylist * @outp: the stream to write in the data * @sigclass: the class of the sig to create * @mdalgo: the message digest algorithm * * Write a one-pass signature for each key in the list into @outp. **/ cdk_error_t cdk_sklist_write_onepass( cdk_keylist_t skl, cdk_stream_t outp, int sigclass, int mdalgo ) { cdk_pkt_onepass_sig_t ops; cdk_keylist_t r; cdk_packet_t pkt; int i, skcount = 0; int rc = 0; if( !skl || !outp ) return CDK_Inv_Value; if( skl->type != CDK_PKT_SECRET_KEY ) return CDK_Inv_Mode; pkt = cdk_calloc( 1, sizeof * pkt ); if( !pkt ) return CDK_Out_Of_Core; for( skcount = 0, r = skl; r; r = r->next ) skcount++; for( ; skcount; skcount-- ) { for( i = 0, r = skl; r; r = r->next ) { if( ++i == skcount ) break; } ops = cdk_calloc( 1, sizeof *ops ); if( !ops ) return CDK_Out_Of_Core; ops->version = 3; cdk_sk_get_keyid( r->key.sk, ops->keyid ); ops->sig_class = sigclass; if( !mdalgo ) mdalgo = _cdk_sig_hash_for( r->key.sk->pubkey_algo, r->key.sk->version ); ops->digest_algo = mdalgo; ops->pubkey_algo = r->key.sk->pubkey_algo; ops->last = (skcount == 1); cdk_pkt_init( pkt ); pkt->pkttype = CDK_PKT_ONEPASS_SIG; pkt->pkt.onepass_sig = ops; rc = cdk_pkt_write( outp, pkt ); cdk_pkt_free( pkt ); if( rc ) break; } cdk_free( pkt ); return rc; }
/** * cdk_pklist_encrypt: * @pkl: the keylist * @dek: the data encryption key * @outp: the stream to write in the data * * Encrypt the session key with each key of the list and wrap it * into a PUBKEY_ENC packet and write it to @outp. */ cdk_error_t cdk_pklist_encrypt( cdk_keylist_t pk_list, cdk_dek_t dek, cdk_stream_t outp ) { cdk_pkt_pubkey_t pk = NULL; cdk_pkt_pubkey_enc_t enc = NULL; cdk_packet_t pkt; cdk_sesskey_t frame = NULL; int nbits = 0; int rc = 0; if( !pk_list || !dek || !outp ) return CDK_Inv_Value; if( pk_list->type != CDK_PKT_PUBLIC_KEY ) return CDK_Inv_Mode; pkt = cdk_calloc( 1, sizeof * pkt ); if( !pkt ) return CDK_Out_Of_Core; for( ; pk_list; pk_list = pk_list->next ) { pk = pk_list->key.pk; cdk_free( enc ); enc = cdk_calloc( 1, sizeof *enc ); if( !enc ) return CDK_Out_Of_Core; enc->version = 3; enc->pubkey_algo = pk->pubkey_algo; cdk_pk_get_keyid( pk, enc->keyid ); nbits = cdk_pk_get_nbits( pk ); rc = cdk_dek_encode_pkcs1( dek, nbits, &frame ); if( rc ) break; rc = cdk_pk_encrypt( pk, enc, frame ); cdk_sesskey_free( frame ); if( rc ) break; else { cdk_pkt_init( pkt ); pkt->old_ctb = dek->rfc1991? 1 : 0; pkt->pkttype = CDK_PKT_PUBKEY_ENC; pkt->pkt.pubkey_enc = enc; rc = cdk_pkt_write( outp, pkt ); cdk_pkt_free( pkt ); if( rc ) break; } } cdk_free( pkt ); cdk_free( enc ); return rc; }
/** * cdk_stream_new: Create a new stream into into the given file. * @file: The name of the new file * @ret_s: The new STREAM object **/ cdk_error_t cdk_stream_new( const char * file, cdk_stream_t * ret_s ) { cdk_stream_t s; if( !ret_s ) return CDK_Inv_Value; _cdk_log_debug( "new stream `%s'\n", file? file : "[temp]" ); *ret_s = NULL; s = cdk_calloc( 1, sizeof *s ); if( !s ) return CDK_Out_Of_Core; s->flags.write = 1; if( !file ) s->flags.temp = 1; else { s->fname = cdk_strdup( file ); if( !s->fname ) { cdk_free( s ); return CDK_Out_Of_Core; } } s->fp = tmpfile( ); if( !s->fp ) { cdk_free( s->fname ); cdk_free( s ); return CDK_File_Error; } *ret_s = s; return 0; }
/** * cdk_stream_new_from_cbs: * @cbs: the callback context with all user callback functions * @opa: opaque handle which is passed to all callbacks. * @ret_s: the allocated stream * * This function creates a stream which uses user callback * for the core operations (open, close, read, write, seek). */ cdk_error_t cdk_stream_new_from_cbs (cdk_stream_cbs_t cbs, void *opa, cdk_stream_t * ret_s) { cdk_stream_t s; if (!cbs || !opa || !ret_s) { gnutls_assert (); return CDK_Inv_Value; } *ret_s = NULL; s = cdk_calloc (1, sizeof *s); if (!s) { gnutls_assert (); return CDK_Out_Of_Core; } s->cbs.read = cbs->read; s->cbs.write = cbs->write; s->cbs.seek = cbs->seek; s->cbs.release = cbs->release; s->cbs.open = cbs->open; s->cbs_hd = opa; *ret_s = s; /* If there is a user callback for open, we need to call it here because read/write expects an open stream. */ if (s->cbs.open) return s->cbs.open (s->cbs_hd); return 0; }
/** * cdk_stream_mmap: * @s: the stream * @ret_buf: the buffer to store the content * @ret_count: length of the buffer * * Map the data of the given stream into a memory section. @ret_count * contains the length of the buffer. **/ cdk_error_t cdk_stream_mmap( cdk_stream_t s, byte ** ret_buf, size_t * ret_count ) { const u32 max_filesize = 16777216; u32 len, oldpos; int n, rc; char * p; if( !s || !ret_buf || !ret_count ) return CDK_Inv_Value; *ret_count = 0; *ret_buf = NULL; oldpos = cdk_stream_tell( s ); rc = cdk_stream_flush( s ); if( !rc ) rc = cdk_stream_seek( s, 0 ); if( rc ) return rc; len = cdk_stream_get_length( s ); if( !len || len > max_filesize ) return 0; p = *ret_buf = cdk_calloc( 1, len+1 ); if( !p ) return 0; *ret_count = len; n = cdk_stream_read( s, p, len ); if( n != len ) *ret_count = n; rc = cdk_stream_seek( s, oldpos ); return rc; }
/** * cdk_s2k_new: * @ret_s2k: output for the new S2K object * @mode: the S2K mode (simple, salted, iter+salted) * @digest_algo: the hash algorithm * @salt: random salt * * Create a new S2K object with the given parameter. * The @salt parameter must be always 8 octets. **/ cdk_error_t cdk_s2k_new (cdk_s2k_t * ret_s2k, int mode, int digest_algo, const byte * salt) { cdk_s2k_t s2k; if (!ret_s2k) return CDK_Inv_Value; if (mode != 0x00 && mode != 0x01 && mode != 0x03) return CDK_Inv_Mode; if (_gnutls_hash_get_algo_len (digest_algo) <= 0) return CDK_Inv_Algo; s2k = cdk_calloc (1, sizeof *s2k); if (!s2k) return CDK_Out_Of_Core; s2k->mode = mode; s2k->hash_algo = digest_algo; if (salt) memcpy (s2k->salt, salt, 8); *ret_s2k = s2k; return 0; }
static int keydb_idx_parse( cdk_stream_t inp, key_idx_t * r_idx ) { key_idx_t idx; byte buf[4]; int i; if( !inp || !r_idx ) return CDK_Inv_Value; idx = cdk_calloc( 1, sizeof * idx ); if( !idx ) return CDK_Out_Of_Core; while( !cdk_stream_eof( inp ) ) { i = cdk_stream_read( inp, buf, 4 ); if( i == CDK_EOF ) break; idx->offset = _cdk_buftou32( buf ); cdk_stream_read( inp, buf, 4 ); idx->keyid[0] = _cdk_buftou32( buf ); cdk_stream_read( inp, buf, 4 ); idx->keyid[1] = _cdk_buftou32( buf ); cdk_stream_read( inp, idx->fpr, 20 ); #if 0 _cdk_log_debug( "%08lu: keyid=%08lX fpr=", idx->offset,idx->keyid[1] ); for( i = 0; i < 20; i++ ) _cdk_log_debug( "%02X", idx->fpr[i] ); _cdk_log_debug( "\n" ); #endif break; } *r_idx = idx; return cdk_stream_eof( inp )? CDK_EOF : 0; }
static int keydb_search_copy (cdk_dbsearch_t * r_dst, cdk_dbsearch_t src) { cdk_dbsearch_t dst; if (!r_dst || !src) return CDK_Inv_Value; dst = cdk_calloc( 1, sizeof *dst ); if( !dst ) return CDK_Out_Of_Core; dst->type = src->type; switch( src->type ) { case CDK_DBSEARCH_EXACT: case CDK_DBSEARCH_SUBSTR: dst->u.pattern = cdk_strdup( src->u.pattern ); if( !dst->u.pattern ) return CDK_Out_Of_Core; break; case CDK_DBSEARCH_SHORT_KEYID: case CDK_DBSEARCH_KEYID: dst->u.keyid[0] = src->u.keyid[0]; dst->u.keyid[1] = src->u.keyid[1]; break; case CDK_DBSEARCH_FPR: memcpy( dst->u.fpr, src->u.fpr, 20 ); break; } *r_dst = dst; return 0; }
/** * cdk_stream_open: create a new stream based on an existing file. * @file: The file to open * @ret_s: The new STREAM object **/ cdk_error_t cdk_stream_open( const char * file, cdk_stream_t * ret_s ) { cdk_stream_t s; if( !file || !ret_s ) return CDK_Inv_Value; _cdk_log_debug( "open stream `%s'\n", file ); *ret_s = NULL; s = cdk_calloc( 1, sizeof *s ); if( !s ) return CDK_Out_Of_Core; s->fname = cdk_strdup( file ); if( !s->fname ) { cdk_free( s ); return CDK_Out_Of_Core; } s->fp = fopen( file, "rb" ); if( !s->fp ) { cdk_free( s->fname ); cdk_free( s ); return CDK_File_Error; } s->flags.write = 0; *ret_s = s; return 0; }
/** * cdk_listkey_start: * @r_ctx: pointer to store the new context * @db: the key database handle * @patt: string pattern * @fpatt: recipients from a stringlist to show * * Prepare a key listing with the given parameters. Two modes are supported. * The first mode uses string pattern to determine if the key should be * returned or not. The other mode uses a string list to request the key * which should be listed. **/ cdk_error_t cdk_listkey_start( cdk_listkey_t * r_ctx, cdk_keydb_hd_t db, const char * patt, cdk_strlist_t fpatt ) { cdk_listkey_t ctx; cdk_stream_t inp; int rc; if( !r_ctx || !db ) return CDK_Inv_Value; if( (patt && fpatt) || (!patt && !fpatt) ) return CDK_Inv_Mode; rc = cdk_keydb_open( db, &inp ); if( rc ) return rc; ctx = cdk_calloc( 1, sizeof * ctx ); if( !ctx ) return CDK_Out_Of_Core; ctx->db = db; ctx->inp = inp; if( patt ) { ctx->u.patt = cdk_strdup( patt ); if( !ctx->u.patt ) return CDK_Out_Of_Core; } else if( fpatt ) { cdk_strlist_t l; for( l = fpatt; l; l = l->next ) cdk_strlist_add( &ctx->u.fpatt, l->d ); } ctx->type = patt? 1 : 0; ctx->init = 1; *r_ctx = ctx; return 0; }
byte *_cdk_subpkt_get_array(cdk_subpkt_t s, int count, size_t * r_nbytes) { cdk_subpkt_t list; byte *buf; size_t n, nbytes; if (!s) { if (r_nbytes) *r_nbytes = 0; return NULL; } for (n = 0, list = s; list; list = list->next) { n++; /* type */ n += list->size; if (list->size < 192) n++; else if (list->size < 8384) n += 2; else n += 5; } buf = cdk_calloc(1, n + 1); if (!buf) return NULL; n = 0; for (list = s; list; list = list->next) { nbytes = 1 + list->size; /* type */ if (nbytes < 192) buf[n++] = nbytes; else if (nbytes < 8384) { nbytes -= 192; buf[n++] = nbytes / 256 + 192; buf[n++] = nbytes & 0xff; } else { buf[n++] = 0xFF; buf[n++] = nbytes >> 24; buf[n++] = nbytes >> 16; buf[n++] = nbytes >> 8; buf[n++] = nbytes; } buf[n++] = list->type; memcpy(buf + n, list->d, list->size); n += list->size; } if (count) { cdk_free(buf); buf = NULL; } if (r_nbytes) *r_nbytes = n; return buf; }
/** * cdk_stream_write: * @s: The STREAM object * @buf: The buffer with the values to write. * @count: The size of the buffer. * * Tries to write count bytes into the stream. * In this function we simply write the bytes to the stream. We can't * use the filters here because it would mean they have to support * partial flushing. **/ int cdk_stream_write (cdk_stream_t s, const void *buf, size_t count) { int nwritten; if (!s) { s->error = CDK_Inv_Value; gnutls_assert(); return EOF; } if (s->cbs_hd) { if (s->cbs.write) return s->cbs.write (s->cbs_hd, buf, count); return 0; } if (!s->flags.write) { s->error = CDK_Inv_Mode; /* this is a read stream */ gnutls_assert(); return EOF; } if (!buf && !count) return stream_flush (s); if (s->cache.on) { /* We need to resize the buffer if the additional data wouldn't fit into it. We allocate more memory to avoid to resize it the next time the function is used. */ if (s->cache.size + count > s->cache.alloced) { byte *old = s->cache.buf; s->cache.buf = cdk_calloc (1, s->cache.alloced + count + STREAM_BUFSIZE); s->cache.alloced += (count + STREAM_BUFSIZE); memcpy (s->cache.buf, old, s->cache.size); cdk_free (old); _cdk_log_debug ("stream: enlarge cache to %d octets\n", s->cache.alloced); } memcpy (s->cache.buf + s->cache.size, buf, count); s->cache.size += count; return count; } nwritten = fwrite (buf, 1, count, s->fp); if (!nwritten) nwritten = EOF; return nwritten; }
cdk_verify_result_t _cdk_result_verify_new (void) { cdk_verify_result_t res; res = cdk_calloc (1, sizeof *res); if (!res) return NULL; return res; }
/* This functions builds an index of the keyring into a separate file with the name keyring.ext.idx. It contains the offset of all public- and public subkeys. The format of the file is: -------- 4 octets offset of the packet 8 octets keyid 20 octets fingerprint -------- We store the keyid and the fingerprint due to the fact we can't get the keyid from a v3 fingerprint directly. */ static int keydb_idx_build( const char * file ) { cdk_packet_t pkt; cdk_stream_t inp, out = NULL; byte buf[8], fpr[20]; char * fname; u32 keyid[2]; int rc, pos; if( !file ) return CDK_Inv_Value; pkt = cdk_calloc( 1, sizeof * pkt ); if( !pkt ) return CDK_Out_Of_Core; fname = keydb_idx_mkname( file ); if( !fname ) { rc = CDK_Out_Of_Core; goto leave; } rc = cdk_stream_open( file, &inp ); if( !rc ) rc = cdk_stream_create( fname, &out ); if( rc ) goto leave; while( !cdk_stream_eof( inp ) ) { pos = cdk_stream_tell( inp ); rc = cdk_pkt_read( inp, pkt ); if( rc ) break; if( pkt->pkttype == CDK_PKT_PUBLIC_KEY || pkt->pkttype == CDK_PKT_PUBLIC_SUBKEY ) { _cdk_u32tobuf( pos, buf ); cdk_stream_write( out, buf, 4 ); cdk_pk_get_keyid( pkt->pkt.public_key, keyid ); _cdk_u32tobuf( keyid[0], buf ); _cdk_u32tobuf( keyid[1], buf + 4 ); cdk_stream_write( out, buf, 8 ); cdk_pk_get_fingerprint( pkt->pkt.public_key, fpr ); cdk_stream_write( out, fpr, 20 ); } cdk_pkt_free( pkt ); cdk_pkt_init( pkt ); } cdk_stream_close( out ); leave: cdk_stream_close( inp ); cdk_free( fname ); cdk_free( pkt ); return rc; }
/** * cdk_keygen_set_prefs: Set the preferences for the userID * @hd: the keygen object * @hd: the preference type * @array: one-octet array with algorithm numers * **/ 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; }
static char * keydb_idx_mkname( const char * file ) { char * fname; fname = cdk_calloc( 1, strlen( file ) + 5 ); if( !fname ) return NULL; sprintf( fname, "%s.idx", file ); return fname; }
/** * cdk_kbnode_new: * @pkt: the packet to add * * Allocates a new key node and adds a packet. **/ cdk_kbnode_t cdk_kbnode_new (cdk_packet_t pkt) { cdk_kbnode_t n; n = cdk_calloc (1, sizeof *n); if (!n) return NULL; n->pkt = pkt; return n; }
/** * cdk_subpkt_new: * @size: the size of the new context * * Create a new sub packet node with the size of @size. **/ cdk_subpkt_t cdk_subpkt_new (size_t size) { cdk_subpkt_t s; if (!size) return NULL; s = cdk_calloc (1, sizeof *s + size + 1); if (!s) return NULL; return s; }
/** * cdk_pkt_new: * @r_pkt: the new packet * * Allocate a new packet. **/ cdk_error_t cdk_pkt_new(cdk_packet_t * r_pkt) { cdk_packet_t pkt; if (!r_pkt) return CDK_Inv_Value; pkt = cdk_calloc(1, sizeof *pkt); if (!pkt) return CDK_Out_Of_Core; *r_pkt = pkt; return 0; }
/** * cdk_kbnode_write_to_mem_alloc: * @node: the key node * @r_buf: buffer to hold the raw data * @r_buflen: buffer length of the allocated raw data. * * The function acts similar to cdk_kbnode_write_to_mem but * it allocates the buffer to avoid the lengthy second run. */ cdk_error_t cdk_kbnode_write_to_mem_alloc (cdk_kbnode_t node, byte ** r_buf, size_t * r_buflen) { cdk_kbnode_t n; cdk_stream_t s; cdk_error_t rc; size_t len; if (!node || !r_buf || !r_buflen) { gnutls_assert (); return CDK_Inv_Value; } *r_buf = NULL; *r_buflen = 0; rc = cdk_stream_tmp_new (&s); if (rc) { gnutls_assert (); return rc; } for (n = node; n; n = n->next) { /* Skip all packets which cannot occur in a key composition. */ if (n->pkt->pkttype != CDK_PKT_PUBLIC_KEY && n->pkt->pkttype != CDK_PKT_PUBLIC_SUBKEY && n->pkt->pkttype != CDK_PKT_SECRET_KEY && n->pkt->pkttype != CDK_PKT_SECRET_SUBKEY && n->pkt->pkttype != CDK_PKT_SIGNATURE && n->pkt->pkttype != CDK_PKT_USER_ID && n->pkt->pkttype != CDK_PKT_ATTRIBUTE) continue; rc = cdk_pkt_write (s, n->pkt); if (rc) { cdk_stream_close (s); gnutls_assert (); return rc; } } cdk_stream_seek (s, 0); len = cdk_stream_get_length (s); *r_buf = cdk_calloc (1, len); *r_buflen = cdk_stream_read (s, *r_buf, len); cdk_stream_close (s); return 0; }
/** * 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; }
/** * cdk_subpkt_new: * @size: the size of the new context * * Create a new sub packet node with the size of @size. **/ cdk_subpkt_t cdk_subpkt_new(size_t size) { cdk_subpkt_t s; if (!size) return NULL; s = cdk_calloc(1, sizeof *s + size + 2); if (!s) return NULL; s->d = (byte *) s + sizeof(*s); return s; }
static cdk_error_t literal_encode (void *data, FILE * in, FILE * out) { literal_filter_t *pfx = data; cdk_pkt_literal_t pt; cdk_stream_t si; cdk_packet_t pkt; size_t filelen; cdk_error_t rc; _cdk_log_debug ("literal filter: encode\n"); if (!pfx || !in || !out) return CDK_Inv_Value; if (!pfx->filename) { pfx->filename = cdk_strdup ("_CONSOLE"); if (!pfx->filename) return CDK_Out_Of_Core; } rc = _cdk_stream_fpopen (in, STREAMCTL_READ, &si); if (rc) return rc; filelen = strlen (pfx->filename); cdk_pkt_new (&pkt); pt = pkt->pkt.literal = cdk_calloc (1, sizeof *pt + filelen); pt->name = (char *) pt + sizeof (*pt); if (!pt) { cdk_pkt_release (pkt); cdk_stream_close (si); return CDK_Out_Of_Core; } memcpy (pt->name, pfx->filename, filelen); pt->namelen = filelen; pt->name[pt->namelen] = '\0'; pt->timestamp = (u32) time (NULL); pt->mode = intmode_to_char (pfx->mode); pt->len = cdk_stream_get_length (si); pt->buf = si; pkt->old_ctb = 1; pkt->pkttype = CDK_PKT_LITERAL; pkt->pkt.literal = pt; rc = _cdk_pkt_write_fp (out, pkt); cdk_pkt_release (pkt); cdk_stream_close (si); return rc; }
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 struct stream_filter_s * filter_add2( cdk_stream_t s ) { struct stream_filter_s * f; assert( s ); f = cdk_calloc( 1, sizeof *f ); if( !f ) return NULL; f->next = s->filters; s->filters = f; return f; }
cdk_stream_t _cdk_stream_fpopen( FILE * fp, unsigned write_mode ) { cdk_stream_t s; s = cdk_calloc( 1, sizeof *s ); if( !s ) return NULL; s->fp = fp; s->flags.filtrated = 1; s->flags.write = write_mode; return s; }