#include "pgsodium.h" PG_FUNCTION_INFO_V1 (pgsodium_crypto_kx_seed_keypair); Datum pgsodium_crypto_kx_seed_keypair (PG_FUNCTION_ARGS) { TupleDesc tupdesc; Datum values[2]; bool nulls[2] = { false, false }; HeapTuple tuple; Datum result; bytea *publickey; bytea *secretkey; bytea *seed = PG_GETARG_BYTEA_P (0); size_t public_size = crypto_kx_PUBLICKEYBYTES + VARHDRSZ; size_t secret_size = crypto_kx_SECRETKEYBYTES + VARHDRSZ; if (get_call_result_type (fcinfo, NULL, &tupdesc) != TYPEFUNC_COMPOSITE) ereport (ERROR, (errcode (ERRCODE_FEATURE_NOT_SUPPORTED), errmsg ("function returning record called in context " "that cannot accept type record"))); ERRORIF (VARSIZE_ANY_EXHDR (seed) != crypto_kx_SEEDBYTES, "%s: invalid seed"); publickey = _pgsodium_zalloc_bytea (public_size); secretkey = _pgsodium_zalloc_bytea (secret_size); crypto_kx_seed_keypair (PGSODIUM_UCHARDATA (publickey), PGSODIUM_UCHARDATA (secretkey), PGSODIUM_UCHARDATA (seed)); values[0] = PointerGetDatum (publickey); values[1] = PointerGetDatum (secretkey); tuple = heap_form_tuple (tupdesc, values, nulls); result = HeapTupleGetDatum (tuple); return result; } PG_FUNCTION_INFO_V1 (pgsodium_crypto_kx_new_seed); Datum pgsodium_crypto_kx_new_seed (PG_FUNCTION_ARGS) { size_t result_size = VARHDRSZ + crypto_kx_SEEDBYTES; bytea *result = _pgsodium_zalloc_bytea (result_size); randombytes_buf (VARDATA (result), crypto_kx_SEEDBYTES); PG_RETURN_BYTEA_P (result); } PG_FUNCTION_INFO_V1 (pgsodium_crypto_kx_client_session_keys); Datum pgsodium_crypto_kx_client_session_keys (PG_FUNCTION_ARGS) { int success; TupleDesc tupdesc; Datum values[2]; bool nulls[2] = { false, false }; HeapTuple tuple; Datum result; bytea *rx; bytea *tx; bytea *client_pk = PG_GETARG_BYTEA_P (0); bytea *client_sk = PG_GETARG_BYTEA_P (1); bytea *server_pk = PG_GETARG_BYTEA_P (2); size_t rx_size = crypto_kx_SESSIONKEYBYTES + VARHDRSZ; size_t tx_size = crypto_kx_SESSIONKEYBYTES + VARHDRSZ; if (get_call_result_type (fcinfo, NULL, &tupdesc) != TYPEFUNC_COMPOSITE) ereport (ERROR, (errcode (ERRCODE_FEATURE_NOT_SUPPORTED), errmsg ("function returning record called in context " "that cannot accept type record"))); ERRORIF (VARSIZE_ANY_EXHDR (client_pk) != crypto_kx_PUBLICKEYBYTES, "%s: bad client public key"); ERRORIF (VARSIZE_ANY_EXHDR (client_sk) != crypto_kx_SECRETKEYBYTES, "%s: bad client secret key"); ERRORIF (VARSIZE_ANY_EXHDR (server_pk) != crypto_kx_PUBLICKEYBYTES, "%s: bad server public key"); rx = _pgsodium_zalloc_bytea (rx_size); tx = _pgsodium_zalloc_bytea (tx_size); success = crypto_kx_client_session_keys (PGSODIUM_UCHARDATA (rx), PGSODIUM_UCHARDATA (tx), PGSODIUM_UCHARDATA (client_pk), PGSODIUM_UCHARDATA (client_sk), PGSODIUM_UCHARDATA (server_pk)); ERRORIF (success != 0, "%s: invalid message"); values[0] = PointerGetDatum (rx); values[1] = PointerGetDatum (tx); tuple = heap_form_tuple (tupdesc, values, nulls); result = HeapTupleGetDatum (tuple); return result; } PG_FUNCTION_INFO_V1 (pgsodium_crypto_kx_server_session_keys); Datum pgsodium_crypto_kx_server_session_keys (PG_FUNCTION_ARGS) { int success; TupleDesc tupdesc; Datum values[2]; bool nulls[2] = { false, false }; HeapTuple tuple; Datum result; bytea *rx; bytea *tx; bytea *server_pk = PG_GETARG_BYTEA_P (0); bytea *server_sk = PG_GETARG_BYTEA_P (1); bytea *client_pk = PG_GETARG_BYTEA_P (2); size_t rx_size = crypto_kx_SESSIONKEYBYTES + VARHDRSZ; size_t tx_size = crypto_kx_SESSIONKEYBYTES + VARHDRSZ; if (get_call_result_type (fcinfo, NULL, &tupdesc) != TYPEFUNC_COMPOSITE) ereport (ERROR, (errcode (ERRCODE_FEATURE_NOT_SUPPORTED), errmsg ("function returning record called in context " "that cannot accept type record"))); ERRORIF (VARSIZE_ANY_EXHDR (server_pk) != crypto_kx_PUBLICKEYBYTES, "%s: bad server public key"); ERRORIF (VARSIZE_ANY_EXHDR (server_sk) != crypto_kx_SECRETKEYBYTES, "%s: bad server secret key"); ERRORIF (VARSIZE_ANY_EXHDR (client_pk) != crypto_kx_PUBLICKEYBYTES, "%s: bad client public key"); rx = _pgsodium_zalloc_bytea (rx_size); tx = _pgsodium_zalloc_bytea (tx_size); success = crypto_kx_server_session_keys (PGSODIUM_UCHARDATA (rx), PGSODIUM_UCHARDATA (tx), PGSODIUM_UCHARDATA (server_pk), PGSODIUM_UCHARDATA (server_sk), PGSODIUM_UCHARDATA (client_pk)); ERRORIF (success != 0, "%s: invalid message"); values[0] = PointerGetDatum (rx); values[1] = PointerGetDatum (tx); tuple = heap_form_tuple (tupdesc, values, nulls); result = HeapTupleGetDatum (tuple); return result; } PG_FUNCTION_INFO_V1 (pgsodium_crypto_kx_keypair); Datum pgsodium_crypto_kx_keypair (PG_FUNCTION_ARGS) { TupleDesc tupdesc; Datum values[2]; bool nulls[2] = { false, false }; HeapTuple tuple; Datum result; bytea *publickey; bytea *secretkey; size_t public_size = crypto_kx_PUBLICKEYBYTES + VARHDRSZ; size_t secret_size = crypto_kx_SECRETKEYBYTES + VARHDRSZ; if (get_call_result_type (fcinfo, NULL, &tupdesc) != TYPEFUNC_COMPOSITE) ereport (ERROR, (errcode (ERRCODE_FEATURE_NOT_SUPPORTED), errmsg ("function returning record called in context " "that cannot accept type record"))); publickey = _pgsodium_zalloc_bytea (public_size); secretkey = _pgsodium_zalloc_bytea (secret_size); crypto_kx_keypair (PGSODIUM_UCHARDATA (publickey), PGSODIUM_UCHARDATA (secretkey)); values[0] = PointerGetDatum (publickey); values[1] = PointerGetDatum (secretkey); tuple = heap_form_tuple (tupdesc, values, nulls); result = HeapTupleGetDatum (tuple); return result; }