static int write_pubkey_enc (cdk_stream_t out, cdk_pkt_pubkey_enc_t pke, int old_ctb) { size_t size; int rc, nenc; assert (out); assert (pke); if (pke->version < 2 || pke->version > 3) return CDK_Inv_Packet; if (!KEY_CAN_ENCRYPT (pke->pubkey_algo)) return CDK_Inv_Algo; if (DEBUG_PKT) _cdk_log_debug ("write_pubkey_enc:\n"); nenc = cdk_pk_get_nenc (pke->pubkey_algo); size = 10 + calc_mpisize (pke->mpi, nenc); rc = pkt_write_head (out, old_ctb, size, CDK_PKT_PUBKEY_ENC); if (rc) return rc; rc = stream_putc (out, pke->version); if (!rc) rc = write_32 (out, pke->keyid[0]); if (!rc) rc = write_32 (out, pke->keyid[1]); if (!rc) rc = stream_putc (out, _cdk_pub_algo_to_pgp (pke->pubkey_algo)); if (!rc) rc = write_mpibuf (out, pke->mpi, nenc); return rc; }
/** * cdk_pk_encrypt: * @pk: the public key * @pke: the public key encrypted packet * @esk: the actual session key * * Encrypt the session key in @esk and write its encrypted content * into the @pke struct. **/ cdk_error_t cdk_pk_encrypt (cdk_pubkey_t pk, cdk_pkt_pubkey_enc_t pke, gcry_mpi_t esk) { gcry_sexp_t s_data = NULL, s_pkey = NULL, s_ciph = NULL; gcry_error_t err; cdk_error_t rc; if (!pk || !esk || !pke) return CDK_Inv_Value; if (!KEY_CAN_ENCRYPT (pk->pubkey_algo)) return CDK_Inv_Algo; rc = enckey_to_sexp (&s_data, esk); if (!rc) rc = pubkey_to_sexp (&s_pkey, pk); if (!rc) { err = gcry_pk_encrypt (&s_ciph, s_data, s_pkey); if (err) return map_gcry_error (err); } if (!rc) rc = sexp_to_pubenc (pke, s_ciph); gcry_sexp_release (s_data); gcry_sexp_release (s_pkey); gcry_sexp_release (s_ciph); return rc; }