/** * cdk_pk_sign: * @sk: secret key * @sig: signature * @md: the message digest * * Sign the message digest from @md and write the result into @sig. **/ cdk_error_t cdk_pk_sign (cdk_seckey_t sk, cdk_pkt_signature_t sig, const byte *md) { gcry_sexp_t s_skey = NULL, s_sig = NULL, s_hash = NULL; byte *encmd = NULL; size_t enclen = 0; int nbits; cdk_error_t rc; gcry_error_t err; if (!sk || !sk->pk || !sig || !md) return CDK_Inv_Value; if (!is_unprotected (sk)) return CDK_Inv_Mode; if (!KEY_CAN_SIGN (sig->pubkey_algo)) return CDK_Inv_Algo; nbits = cdk_pk_get_nbits (sk->pk); rc = _cdk_digest_encode_pkcs1 (&encmd, &enclen, sk->pk->pubkey_algo, md, sig->digest_algo, nbits); if (rc) return rc; rc = seckey_to_sexp (&s_skey, sk); if (!rc) rc = digest_to_sexp (&s_hash, sig->digest_algo, encmd, enclen); if (rc) { cdk_free (encmd); gcry_sexp_release (s_skey); return rc; } err = gcry_pk_sign (&s_sig, s_hash, s_skey); if (err) rc = map_gcry_error (err); else { rc = sexp_to_sig (sig, s_sig); if (!rc) { sig->digest_start[0] = md[0]; sig->digest_start[1] = md[1]; } } gcry_sexp_release (s_skey); gcry_sexp_release (s_hash); gcry_sexp_release (s_sig); cdk_free (encmd); return rc; }
cdk_error_t cdk_keydb_export( cdk_keydb_hd_t hd, cdk_stream_t out, cdk_strlist_t remusr ) { cdk_kbnode_t knode, node; cdk_strlist_t r; int old_ctb = 0; int rc = 0; for( r = remusr; r; r = r->next ) { rc = cdk_keydb_search_start( hd, CDK_DBSEARCH_AUTO, r->d ); if( !rc ) rc = cdk_keydb_search( hd, &knode ); if( rc ) break; for( node = knode; node; node = node->next ) { /* those packets are not intended for the real wolrd */ if( node->pkt->pkttype == CDK_PKT_RING_TRUST ) continue; /* we never export local signed signatures */ if( node->pkt->pkttype == CDK_PKT_SIGNATURE && !node->pkt->pkt.signature->flags.exportable ) continue; /* filter out invalid signatures */ if( node->pkt->pkttype == CDK_PKT_SIGNATURE && !KEY_CAN_SIGN (node->pkt->pkt.signature->pubkey_algo) ) continue; if( node->pkt->pkttype == CDK_PKT_PUBLIC_KEY && node->pkt->pkt.public_key->version == 3 ) old_ctb = 1; node->pkt->old_ctb = old_ctb; rc = cdk_pkt_write( out, node->pkt ); if( rc ) break; } cdk_kbnode_release( knode ); knode = NULL; } return rc; }
static cdk_error_t write_signature (cdk_stream_t out, cdk_pkt_signature_t sig, int old_ctb) { byte *buf; size_t nbytes, size, nsig; cdk_error_t rc; assert (out); assert (sig); if (!KEY_CAN_SIGN (sig->pubkey_algo)) return CDK_Inv_Algo; if (sig->version < 2 || sig->version > 4) return CDK_Inv_Packet; if (DEBUG_PKT) _cdk_log_debug ("write_signature:\n"); nsig = cdk_pk_get_nsig (sig->pubkey_algo); if (!nsig) return CDK_Inv_Algo; if (sig->version < 4) return write_v3_sig (out, sig, nsig); size = 10 + calc_subpktsize (sig->hashed) + calc_subpktsize (sig->unhashed) + calc_mpisize (sig->mpi, nsig); rc = pkt_write_head (out, 0, size, CDK_PKT_SIGNATURE); if (!rc) rc = stream_putc (out, 4); if (!rc) rc = stream_putc (out, sig->sig_class); if (!rc) rc = stream_putc (out, _cdk_pub_algo_to_pgp (sig->pubkey_algo)); if (!rc) rc = stream_putc (out, _gnutls_hash_algo_to_pgp (sig->digest_algo)); if (!rc) rc = write_16 (out, sig->hashed_size); if (!rc) { buf = _cdk_subpkt_get_array (sig->hashed, 0, &nbytes); if (!buf) return CDK_Out_Of_Core; rc = stream_write (out, buf, nbytes); cdk_free (buf); } if (!rc) rc = write_16 (out, sig->unhashed_size); if (!rc) { buf = _cdk_subpkt_get_array (sig->unhashed, 0, &nbytes); if (!buf) return CDK_Out_Of_Core; rc = stream_write (out, buf, nbytes); cdk_free (buf); } if (!rc) rc = stream_putc (out, sig->digest_start[0]); if (!rc) rc = stream_putc (out, sig->digest_start[1]); if (!rc) rc = write_mpibuf (out, sig->mpi, nsig); return rc; }