aboutsummaryrefslogtreecommitdiff
path: root/extension/background/emscriptif.js
diff options
context:
space:
mode:
authorFlorian Dold <florian.dold@gmail.com>2015-12-13 23:47:30 +0100
committerFlorian Dold <florian.dold@gmail.com>2015-12-13 23:47:30 +0100
commit441f41deccac779889ee19f3803e33936da43eb3 (patch)
tree03e9c24940a9ad551a367ef7e53a4c3c6471727e /extension/background/emscriptif.js
parente370cd9ef673600199ad2581697c814e8e5ae414 (diff)
Type-safe emscripten interface.
Diffstat (limited to 'extension/background/emscriptif.js')
-rw-r--r--extension/background/emscriptif.js649
1 files changed, 148 insertions, 501 deletions
diff --git a/extension/background/emscriptif.js b/extension/background/emscriptif.js
index da574b877..7188012f3 100644
--- a/extension/background/emscriptif.js
+++ b/extension/background/emscriptif.js
@@ -14,510 +14,157 @@
You should have received a copy of the GNU General Public License along with
TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/>
*/
-
"use strict";
-
-
-/* According to emscripten's design, we need our emscripted library to be executed
- with a 'window' object as its global scope.
- Note: that holds on emscripten's functions too, that is they need to be *explicitly*
- run with some 'window' object as their global scope. In practice, given a function
- 'foo' pointing to some emscripted function, that is accomplished by the mean of 'call()'
- or 'apply()' methods; so, being 'someWin' a 'window' object, the statements
-
- foo.call('someWin', arg1, .., argN) or foo.apply('someWin', ['arg1', .., 'argN']) will
- execute foo(arg1, .., argN) with 'someWin' as its global scope.
- See http://www.bennadel.com/blog/2265-changing-the-execution-context-of-javascript
- -functions-using-call-and-apply.htm. */
-
-/* The naming convention is such that:
- - 'GCfunctionName' takes its code from GNUNET_CRYPTO_function_name
- - 'GCALLfunctionName' takes its code from GNUNET_CRYPTO_function_name and returns
- a pointer that must be deallocated using 'WRgnunetFree' (that takes its code from
- 'GNUNET_free' in the wrapper)
- - 'GSfunctionName' and 'GSALLfunctionName' comply to the same convention respect to
- GNUNET_STRINGS_* realm.
- - 'TWRfunctionName' takes its code from 'TALER_function_name' in the wrapper.
- - 'TWRALLfunctionName' takes its code from 'TALER_ALL_function_name' in the wrapper
- and returns a pointer that must be deallocated using 'TWRgnunetFree' (or a function
- provided by some emscripted routine) (the 'wrapper' is an additional layer written in
- C that does some struct(s) manipulations where that is uncovenient to do from JavaScript.
- Currently located at '../../emscripten/testcases/wrap.c')
- - The same applies to 'TfunctionName' and 'TALLfunctionName', to indicate that the
- respective functions come from (the emscripted version of) TALER_* realm. */
-
-
+// Size of a native pointer.
const PTR_SIZE = 4;
-
-// shortcut to emscr's 'malloc'
-function emscMalloc(size) {
- var ptr = Module._malloc(size);
- return ptr;
+let getEmsc = Module.cwrap;
+var emsc = {
+ free: (ptr) => Module._free(ptr),
+ get_value: getEmsc('TALER_WR_get_value', 'number', ['number']),
+ get_fraction: getEmsc('TALER_WR_get_fraction', 'number', ['number']),
+ get_currency: getEmsc('TALER_WR_get_currency', 'string', ['number']),
+ amount_add: getEmsc('TALER_amount_add', 'void', ['number', 'number', 'number']),
+ amount_subtract: getEmsc('TALER_amount_subtract', 'void', ['number', 'number', 'number']),
+ amount_normalize: getEmsc('TALER_amount_normalize', 'void', ['number']),
+ amount_cmp: getEmsc('TALER_amount_cmp', 'number', ['number', 'number'])
+};
+var emscAlloc = {
+ get_amount: getEmsc('TALER_WRALL_get_amount', 'number', ['number', 'number', 'number', 'string']),
+ eddsa_key_create: getEmsc('GNUNET_CRYPTO_eddsa_key_create', 'number'),
+ eddsa_public_key_from_private: getEmsc('TALER_WRALL_eddsa_public_key_from_private', 'number', ['number']),
+ malloc: (size) => Module._malloc(size),
+};
+class ArenaObject {
+ constructor(arena) {
+ this.nativePtr = 0;
+ if (!arena)
+ arena = defaultArena;
+ arena.put(this);
+ this.arena = arena;
+ }
}
-
-/* shortcut to emscr's 'free'. This function is problematic:
- it randomly stops working giving 'emscFree is not a function'
- error */
-function emscFree(ptr) {
- Module._free(ptr);
+class Arena {
+ constructor() {
+ this.heap = [];
+ }
+ put(obj) {
+ this.heap.push(obj);
+ }
+ destroy(obj) {
+ // XXX: todo
+ }
}
-
-var getEmsc = Module.cwrap;
-
-var TWRhelloWorld = getEmsc('TALER_WR_hello_world', 'void', []);
-
-var TWRverifyConfirmation = getEmsc('TALER_WR_verify_confirmation',
- 'number',
- ['number',
- 'number',
- 'number',
- 'number',
- 'number',
- 'number',
- 'number',
- 'number',
- 'number',
- 'number',
- 'number']);
-var TWRgetValue = getEmsc('TALER_WR_get_value',
- 'number',
- ['number']);
-
-var TWRgetFraction = getEmsc('TALER_WR_get_fraction',
- 'number',
- ['number']);
-
-var TWRgetCurrency = getEmsc('TALER_WR_get_currency',
- 'string',
- ['number']);
-
-
-var TWRmultiplyAmounts = getEmsc('TALER_WR_multiply_amounts',
- 'number',
- ['number',
- 'number'] );
-
-var TWRmultiplyAmount = getEmsc('TALER_WR_multiply_amount',
- 'number',
- ['number',
- 'number'] );
-
-var TWRALLrsaPublicKeyHash = getEmsc('TALER_WRALL_rsa_public_key_hash',
- 'number',
- ['number']);
-
-var TWRverifyDenom = getEmsc('TALER_WR_verify_denom',
- 'number',
- ['number',
- 'number',
- 'number',
- 'number',
- 'number',
- 'number',
- 'number',
- 'number',
- 'number',
- 'number',
- 'number']);
-
-var TWRverifyDenoms = getEmsc('TALER_WR_verify_denoms',
- 'number',
- ['number',
- 'number',
- 'number',
- 'number',
- 'number']);
-
-var TWRverifySignKey = getEmsc('TALER_WR_verify_sign_key',
- 'number',
- ['number',
- 'number',
- 'number',
- 'number',
- 'number',
- 'number']);
-
-
-var TWRALLgetEncodingFromRsaSignature = getEmsc('TALER_WRALL_get_encoding_from_rsa_signature',
- 'number',
- ['number']);
-
-var TamountCmp = getEmsc('TALER_amount_cmp',
- 'number',
- ['number',
- 'number']);
-
-var DWRdumpAmount = getEmsc('DEBUG_WR_dump_amount',
- 'void'
- ['number']);
-
-var DWRtestStringCmp = getEmsc('DEBUG_WR_test_string_cmp',
- 'number',
- ['number',
- 'string']);
-
-var TWRALLgetAmount = getEmsc('TALER_WRALL_get_amount',
- 'number',
- ['number',
- 'number',
- 'number',
- 'string']);
-
-var DWRgetPurpose = getEmsc('DEBUG_WR_get_purpose',
- 'number',
- ['number']);
-
-var TWReddsaVerify = getEmsc('TALER_WR_eddsa_verify',
- 'number',
- ['string',
- 'number',
- 'number',
- 'number']);
-
-var TWRALLmakeEddsaSignature = getEmsc('TALER_WRALL_make_eddsa_signature',
- 'number',
- ['number',
- 'number']);
-
-var TWRALLamountAdd = getEmsc('TALER_WRALL_amount_add',
- 'number',
- ['number',
- 'number',
- 'number',
- 'number',
- 'number',
- 'number',
- 'string']);
-
-var TamountSubtract = getEmsc('TALER_amount_subtract',
- 'number',
- ['number',
- 'number',
- 'number']);
-
-var TamountAdd = getEmsc('TALER_amount_add',
- 'number',
- ['number',
- 'number',
- 'number']);
-var TWRALLeddsaPublicKeyFromPrivate = getEmsc('TALER_WRALL_eddsa_public_key_from_private',
- 'number',
- ['number']);
-
-var TWRALLeddsaPublicKeyFromPrivString = getEmsc('TALER_WRALL_eddsa_public_key_from_priv_string',
- 'number',
- ['string']);
-
-var TWRALLsignDepositPermission = getEmsc('TALER_WRALL_sign_deposit_permission',
- 'number',
- ['number',
- 'number',
- 'number',
- 'number',
- 'number',
- 'number',
- 'number',
- 'number',
- 'number',
- 'number']);
-
-var TWRALLeddsaPrivateKeyFromString = getEmsc('TALER_WRALL_eddsa_private_key_from_string',
- 'number',
- ['string']);
-
-var TWRALLrsaPublicKeyDecodeFromString = getEmsc('TALER_WRALL_rsa_public_key_decode_from_string',
- 'number',
- ['string']);
-
-var TWRALLecdhePublicKeyFromPrivateKey = getEmsc('TALER_WRALL_ecdhe_public_key_from_private_key',
- 'number',
- ['number']);
-
-var TWRALLeccEcdh = getEmsc('TALER_WRALL_ecc_ecdh',
- 'number',
- ['number',
- 'number',
- 'number']);
-
-var TWRALLmakeWithdrawBundle = getEmsc('TALER_WRALL_make_withdraw_bundle',
- 'number',
- ['number',
- 'number',
- 'number',
- 'number',
- 'number',
- 'number']);
-
-var WRALLmakePurpose = getEmsc('WRALL_make_purpose',
- 'number',
- ['string',
- 'number',
- 'number',
- 'number']);
-
-var GCALLrsaSignatureDecode = getEmsc('GNUNET_CRYPTO_rsa_signature_decode',
- 'number',
- ['number',
- 'number']);
-
-var GCALLrsaSignatureEncode = getEmsc('GNUNET_CRYPTO_rsa_signature_encode',
- 'number',
- ['number',
- 'number']);
-
-var GCALLrsaPublicKeyEncode = getEmsc('GNUNET_CRYPTO_rsa_public_key_encode',
- 'number',
- ['number',
- 'number']);
-
-var GCALLrsaPublicKeyDecode = getEmsc('GNUNET_CRYPTO_rsa_public_key_decode',
- 'number',
- ['number',
- 'number']);
-
-var GCALLrsaPrivateKeyGetPublic = getEmsc('GNUNET_CRYPTO_rsa_private_key_get_public',
- 'number',
- ['number']);
-
-var GCALLrsaPrivateKeyCreate = getEmsc('GNUNET_CRYPTO_rsa_private_key_create',
- 'number',
- ['number']);
-
-var GCALLrsaBlindingKeyCreate = getEmsc('GNUNET_CRYPTO_rsa_blinding_key_create',
- 'number',
- ['number']);
-
-
-var GCALLrsaBlindingKeyEncode = getEmsc('GNUNET_CRYPTO_rsa_blinding_key_encode',
- 'number',
- ['number', 'number']);
-
-var GCrsaBlindingKeyFree = getEmsc('GNUNET_CRYPTO_rsa_blinding_key_free',
- 'void',
- ['number']);
-
-var GCrsaPublicKeyFree = getEmsc('GNUNET_CRYPTO_rsa_public_key_free',
- 'void',
- ['number']);
-
-var GCrsaPrivateKeyFree = getEmsc('GNUNET_CRYPTO_rsa_private_key_free',
- 'void',
- ['number']);
-
-var GCALLrsaBlind = getEmsc('GNUNET_CRYPTO_rsa_blind',
- 'number',
- ['number',
- 'number',
- 'number',
- 'number']);
-
-var GCALLrsaUnblind = getEmsc('GNUNET_CRYPTO_rsa_unblind',
- 'number',
- ['number',
- 'number',
- 'number']);
-
-var GCALLrsaSign = getEmsc('GNUNET_CRYPTO_rsa_sign',
- 'number',
- ['number',
- 'number',
- 'number']);
-
-var GCrsaVerify = getEmsc('GNUNET_CRYPTO_rsa_verify',
- 'number',
- ['number',
- 'number',
- 'number']);
-
-var GCrsaSignatureFree = getEmsc('GNUNET_CRYPTO_rsa_signature_free',
- 'void',
- ['number']);
-
-var GChkdf = getEmsc('GNUNET_CRYPTO_hkdf',
- 'number',
- ['number',
- 'number',
- 'number',
- 'number',
- 'number',
- 'number',
- 'number',
- 'number']);
-
-var TWRALLgenKeyFromBlob = getEmsc('TALER_WRALL_gen_key_from_blob',
- 'number',
- ['string',
- 'number',
- 'number']);
-
-var DWRtestString = getEmsc('DEBUG_WR_test_string',
- 'void',
- ['number',
- 'number',
- 'string']);
-
-var GCsymmetricDecrypt = getEmsc('GNUNET_CRYPTO_symmetric_decrypt',
- 'number',
- ['number',
- 'number',
- 'number',
- 'number',
- 'number']);
-
-var GCsymmetricEncrypt = getEmsc('GNUNET_CRYPTO_symmetric_encrypt',
- 'number',
- ['number',
- 'number',
- 'number',
- 'number',
- 'number']);
-
-/* returns a pointer to a symmetric session key strucure and takes a salt, a
- (pointer to) binary data used to generate the key, and the length of that
- data */
-var TWRALLgenSymmetricKey = getEmsc('TALER_WRALL_gen_symmetric_key',
- 'number',
- ['string',
- 'number',
- 'number']);
-
-/* returns a pointer to a init. vector strucure and takes a salt, a
- (pointer to) binary data used to generate the key, and the length of that
- data */
-var TWRALLgenInitVector = getEmsc('TALER_WRALL_gen_init_vector',
- 'number',
- ['string',
- 'number',
- 'number']);
-
-// return key material from ECC keys
-var GCeccEcdh = getEmsc('GNUNET_CRYPTO_ecc_ecdh',
- 'number',
- ['number',
- 'number',
- 'number']);
-
-// return a pointer to a freshly allocated EddsaPublicKey structure
-/* var WRALLeddsaPublicKey = getEmsc('WRALL_eddsa_public_key',
- 'number'); */
-
-// return a pointer to a freshly allocated EcdhePublicKey structure
-/* var WRALLecdhePublicKey = getEmsc('WRALL_ecdhe_public_key',
- 'number'); */
-
-/* generates a new eddsa private key, returning a pointer to EddsaPrivateKey
- structure */
-var GCALLeddsaKeyCreate = getEmsc('GNUNET_CRYPTO_eddsa_key_create',
- 'number');
-
-/* extract eddsa public key from a pointer to a EddsaPrivateKey structure
- and put it in second argument */
-var GCeddsaKeyGetPublic = getEmsc('GNUNET_CRYPTO_eddsa_key_get_public',
- 'void',
- ['number',
- 'number']);
-
-/* generates a new ecdhe private key, returning a pointer to EcdhePrivateKey
- structure */
-var GCALLecdheKeyCreate = getEmsc('GNUNET_CRYPTO_ecdhe_key_create',
- 'number');
-
-/* extract eddsa public key from a pointer to a EddsaPrivateKey structure and
- put it in second argument */
-var GCecdheKeyGetPublic = getEmsc('GNUNET_CRYPTO_ecdhe_key_get_public',
- 'void',
- ['number',
- 'number']);
-
-// what to sign, the reason to sign, the location to store the signature
-var GCeddsaSign = getEmsc('GNUNET_CRYPTO_eddsa_sign',
- 'int',
- ['number',
- 'number',
- 'number']);
-
-/* get reference to the emscripted primitive: the first parameter is a
- pointer (note that it points to the emscripten's heap) to the data being
- encoded, the second is its length */
-var GSALLdataToStringAlloc = getEmsc('GNUNET_STRINGS_data_to_string_alloc',
- 'number',
- ['number',
- 'number']);
-
-// import GNUnet's memory deallocator
-var TWRgnunetFree = getEmsc('TALER_WR_GNUNET_free',
- 'void',
- ['number']);
-
-// GNUnet's base32 decoder
-var GSstringToData = getEmsc('GNUNET_STRINGS_string_to_data',
- 'number',
- ['number',
- 'number',
- 'number',
- 'number']);
-
-// get absolute time. Returned value has to be freed by gnunetFree
-var TWRALLgetCurrentTime = getEmsc('TALER_WRALL_get_current_time',
- 'number');
-
-// prettyfy time
-var TWRgetFancyTime = getEmsc('TALER_WR_get_fancy_time',
- 'string',
- ['number']);
-
-var TWRALLhash = getEmsc('TALER_WRALL_hash',
- 'number',
- ['number',
- 'number']);
-
-/* computes the hashcode of the value pointed to by 'val' and sets the
- pointer to the location holding the hashcode (which has to be previously
- allocated and is a reflection of GNUNET_HashCode type). The returned
- pointer has to be freed by gnunetFree.
- Its interface is hash('val', 'valSize', 'hashedBuf') */
-var GChash = getEmsc('GNUNET_CRYPTO_hash',
- 'void',
- ['number',
- 'number',
- 'number']);
-
-/* this test just takes the private key to sign a dummy hardcoded
- message. Return a pointer to the signed message (to be freed) */
-var TWRALLsignTest = getEmsc('TALER_WRALL_sign_test',
- 'number',
- ['number']);
-
-/* this test just takes the public key and the signed dummy
- message. Return GNUNET_OK (=1) if it succeeds, otherwise
- GNUNET_SYSERR (=-1) */
-var WRverifyTest = getEmsc('WR_verify_test',
- 'number',
- ['number']);
-
-
-let d2s = getEmsc('GNUNET_STRINGS_data_to_string_alloc',
- 'string',
- ['number', 'number']);
-
-
-let sizeof_EddsaPrivateKey = 32;
-let sizeof_EddsaPublicKey = 32;
-
-function createEddsaKeyPair() {
- let privPtr = GCALLeddsaKeyCreate();
- let pubPtr = emscMalloc(sizeof_EddsaPublicKey);
- GCeddsaKeyGetPublic(privPtr, pubPtr);
- let privStr = d2s(privPtr, sizeof_EddsaPrivateKey);
- let pubStr = d2s(pubPtr, sizeof_EddsaPublicKey);
- return {priv: privStr, pub: pubStr};
+// Arena to track allocations that do not use an explicit arena.
+var defaultArena = new Arena();
+class Amount extends ArenaObject {
+ constructor(args, arena) {
+ super(arena);
+ if (args) {
+ this.nativePtr = emscAlloc.get_amount(args.value, 0, args.fraction, args.currency);
+ }
+ else {
+ this.nativePtr = emscAlloc.get_amount(0, 0, 0, "");
+ }
+ }
+ destroy() {
+ if (this.nativePtr != 0) {
+ emsc.free(this.nativePtr);
+ }
+ }
+ get value() {
+ return emsc.get_value(this.nativePtr);
+ }
+ get fraction() {
+ return emsc.get_fraction(this.nativePtr);
+ }
+ get currency() {
+ return emsc.get_currency(this.nativePtr);
+ }
+ toJson() {
+ return {
+ value: emsc.get_value(this.nativePtr),
+ fraction: emsc.get_fraction(this.nativePtr),
+ currency: emsc.get_currency(this.nativePtr)
+ };
+ }
+ /**
+ * Add an amount to this amount.
+ */
+ add(a) {
+ let res = emsc.amount_add(this.nativePtr, a.nativePtr, this.nativePtr);
+ if (res < 1) {
+ // Overflow
+ return false;
+ }
+ return true;
+ }
+ /**
+ * Perform saturating subtraction on amounts.
+ */
+ sub(a) {
+ let res = emsc.amount_subtract(this.nativePtr, a.nativePtr, this.nativePtr);
+ if (res == 0) {
+ // Underflow
+ return false;
+ }
+ if (res > 0) {
+ return true;
+ }
+ throw "Incompatible currencies";
+ }
+ cmp(a) {
+ return emsc.amount_cmp(this.nativePtr, a.nativePtr);
+ }
+ normalize() {
+ emsc.amount_normalize(this.nativePtr);
+ }
}
-
-function createRsaBlindingKey() {
- let blindFac = GCALLrsaBlindingKeyCreate(1024);
- let bufPtr = emscMalloc(PTR_SIZE);
- let size = GCALLrsaBlindingKeyEncode (blindFac, bufPtr);
- let key = d2s(Module.getValue(bufPtr, '*'), size);
- emscFree(bufPtr);
- return key;
+class EddsaPrivateKey extends ArenaObject {
+ static create(a) {
+ let k = new EddsaPrivateKey(a);
+ k.nativePtr = emscAlloc.eddsa_key_create();
+ return k;
+ }
+ destroy() {
+ // TODO
+ }
+ getPublicKey() {
+ let pk = new EddsaPublicKey(this.arena);
+ pk.nativePtr = emscAlloc.eddsa_public_key_from_private(this.nativePtr);
+ return pk;
+ }
+ encode() {
+ throw "not implemented";
+ }
+}
+class EddsaPublicKey extends ArenaObject {
+ destroy() {
+ // TODO
+ }
+ encode() {
+ throw "not implemented";
+ }
+}
+class RsaBlindingKey extends ArenaObject {
+ destroy() {
+ // TODO
+ }
+}
+class HashCode extends ArenaObject {
+ destroy() {
+ // TODO
+ }
+}
+class ByteArray extends ArenaObject {
+ destroy() {
+ // TODO
+ }
+}
+class RsaPublicKey extends ArenaObject {
+ destroy() {
+ // TODO
+ }
+}
+function rsaBlind(hashCode, blindingKey, pkey, arena) {
+ return null;
}