progress on modem and data card
This commit is contained in:
105
src/main.c
105
src/main.c
@@ -48,6 +48,100 @@ static nn_Exit sandbox_handler(nn_ComponentRequest *req) {
|
|||||||
return NN_OK;
|
return NN_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static nn_Exit ne_dataBullshit(nn_DataCardRequest *req) {
|
||||||
|
nn_Computer *C = req->computer;
|
||||||
|
nn_DataCardAction action = req->action;
|
||||||
|
nn_Exit e;
|
||||||
|
|
||||||
|
if(action == NN_DATA_DROP) {
|
||||||
|
return NN_OK;
|
||||||
|
}
|
||||||
|
if(action == NN_DATA_ENCODE64) {
|
||||||
|
int outSize = 0;
|
||||||
|
char *out = EncodeDataBase64((const unsigned char *)req->data, req->datalen, &outSize);
|
||||||
|
if(out == NULL) return NN_ENOMEM;
|
||||||
|
// -1 because raylib includes the NUL terminator??
|
||||||
|
e = nn_pushlstring(C, out, outSize-1);
|
||||||
|
MemFree(out);
|
||||||
|
return e;
|
||||||
|
}
|
||||||
|
if(action == NN_DATA_DECODE64) {
|
||||||
|
int outSize = 0;
|
||||||
|
char *out = (char *)DecodeDataBase64(req->data, &outSize);
|
||||||
|
if(out == NULL) return NN_ENOMEM;
|
||||||
|
e = nn_pushlstring(C, out, outSize);
|
||||||
|
MemFree(out);
|
||||||
|
return e;
|
||||||
|
}
|
||||||
|
if(action == NN_DATA_DEFLATE) {
|
||||||
|
int outSize = 0;
|
||||||
|
char *out = (char *)CompressData((const unsigned char *)req->data, req->datalen, &outSize);
|
||||||
|
if(out == NULL) return NN_ENOMEM;
|
||||||
|
e = nn_pushlstring(C, out, outSize);
|
||||||
|
MemFree(out);
|
||||||
|
return e;
|
||||||
|
}
|
||||||
|
if(action == NN_DATA_INFLATE) {
|
||||||
|
int outSize = 0;
|
||||||
|
char *out = (char *)DecompressData((unsigned char *)req->data, req->datalen, &outSize);
|
||||||
|
if(out == NULL) return NN_ENOMEM;
|
||||||
|
e = nn_pushlstring(C, out, outSize);
|
||||||
|
MemFree(out);
|
||||||
|
return e;
|
||||||
|
}
|
||||||
|
if(action == NN_DATA_CRC32) {
|
||||||
|
unsigned int check = nn_computeCRC32(req->crc32.data, req->crc32.datalen);
|
||||||
|
req->crc32.checksum[0] = (check >> 0) & 0xFF;
|
||||||
|
req->crc32.checksum[1] = (check >> 8) & 0xFF;
|
||||||
|
req->crc32.checksum[2] = (check >> 16) & 0xFF;
|
||||||
|
req->crc32.checksum[3] = (check >> 24) & 0xFF;
|
||||||
|
return NN_OK;
|
||||||
|
}
|
||||||
|
if(action == NN_DATA_MD5) {
|
||||||
|
unsigned int *out = ComputeMD5((unsigned char *)req->md5.data, req->md5.datalen);
|
||||||
|
if(out == NULL) return NN_ENOMEM;
|
||||||
|
memcpy(req->md5.checksum, out, 16);
|
||||||
|
return NN_OK;
|
||||||
|
}
|
||||||
|
if(action == NN_DATA_SHA256) {
|
||||||
|
// does not match OC, dunno why
|
||||||
|
unsigned int *out = ComputeSHA256((unsigned char *)req->sha256.data, req->sha256.datalen);
|
||||||
|
if(out == NULL) return NN_ENOMEM;
|
||||||
|
memcpy(req->sha256.checksum, out, 32);
|
||||||
|
return NN_OK;
|
||||||
|
}
|
||||||
|
if(action == NN_DATA_RANDOM) {
|
||||||
|
for(size_t i = 0; i < req->randbuf.buflen; i++) {
|
||||||
|
req->randbuf.buf[i] = rand();
|
||||||
|
}
|
||||||
|
return NN_OK;
|
||||||
|
}
|
||||||
|
if(action == NN_DATA_ENCRYPT) {
|
||||||
|
return nn_pushlstring(C, req->data, req->datalen);
|
||||||
|
}
|
||||||
|
if(action == NN_DATA_DECRYPT) {
|
||||||
|
return nn_pushlstring(C, req->data, req->datalen);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(C) nn_setError(C, "ne: data method not implemented");
|
||||||
|
return NN_EBADCALL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static nn_Exit ne_modemBullshit(nn_ModemRequest *req) {
|
||||||
|
nn_Computer *C = req->computer;
|
||||||
|
|
||||||
|
if(req->action == NN_MODEM_DROP) {
|
||||||
|
return NN_OK;
|
||||||
|
}
|
||||||
|
if(req->action == NN_MODEM_SEND) {
|
||||||
|
printf("Transmission from %s to %s (port %zu) of %zu bytes (%zu values)\n", req->localAddress, req->send.address == NULL ? "*" : req->send.address, req->send.port, req->send.contents->buflen, req->send.contents->valueCount);
|
||||||
|
return nn_pushModemMessage(C, req->localAddress, nn_getComputerAddress(C), req->send.port, 0, req->send.contents);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(C) nn_setError(C, "ne: modem method not implemented");
|
||||||
|
return NN_EBADCALL;
|
||||||
|
}
|
||||||
|
|
||||||
static unsigned char ne_processColorPart(unsigned char channel, double brightness) {
|
static unsigned char ne_processColorPart(unsigned char channel, double brightness) {
|
||||||
double n = (double)channel / 255;
|
double n = (double)channel / 255;
|
||||||
n *= brightness;
|
n *= brightness;
|
||||||
@@ -392,6 +486,9 @@ int main(int argc, char **argv) {
|
|||||||
nn_setComponentMethods(ocelotCard, sandboxMethods);
|
nn_setComponentMethods(ocelotCard, sandboxMethods);
|
||||||
nn_setComponentHandler(ocelotCard, sandbox_handler);
|
nn_setComponentHandler(ocelotCard, sandbox_handler);
|
||||||
|
|
||||||
|
nn_Component *dataCard = nn_createDataCard(u, NULL, &nn_defaultDataCards[2], NULL, ne_dataBullshit);
|
||||||
|
nn_Component *modem = nn_createModem(u, NULL, &nn_defaultWiredModem, NULL, ne_modemBullshit);
|
||||||
|
|
||||||
char *eepromCode = (char *)minBIOS;
|
char *eepromCode = (char *)minBIOS;
|
||||||
size_t eepromSize = strlen(minBIOS);
|
size_t eepromSize = strlen(minBIOS);
|
||||||
const char *eepromPath = getenv("NN_EEPROM");
|
const char *eepromPath = getenv("NN_EEPROM");
|
||||||
@@ -492,8 +589,8 @@ int main(int argc, char **argv) {
|
|||||||
double nextSecond = 0;
|
double nextSecond = 0;
|
||||||
double wattage = 0;
|
double wattage = 0;
|
||||||
|
|
||||||
nn_Component *screen = ncl_createScreen(u, NULL, &nn_defaultScreens[3]);
|
nn_Component *screen = ncl_createScreen(u, NULL, &nn_defaultScreens[2]);
|
||||||
nn_Component *gpuCard = ncl_createGPU(u, NULL, &nn_defaultGPUs[3]);
|
nn_Component *gpuCard = ncl_createGPU(u, NULL, &nn_defaultGPUs[2]);
|
||||||
nn_Component *keyboard = nn_createComponent(
|
nn_Component *keyboard = nn_createComponent(
|
||||||
u, "mainKB", "keyboard");
|
u, "mainKB", "keyboard");
|
||||||
|
|
||||||
@@ -536,6 +633,8 @@ int main(int argc, char **argv) {
|
|||||||
nn_mountComponent(c, testingfs, 3, false);
|
nn_mountComponent(c, testingfs, 3, false);
|
||||||
nn_mountComponent(c, testDrive, 4, false);
|
nn_mountComponent(c, testDrive, 4, false);
|
||||||
nn_mountComponent(c, testFlash, 5, false);
|
nn_mountComponent(c, testFlash, 5, false);
|
||||||
|
nn_mountComponent(c, dataCard, 6, false);
|
||||||
|
nn_mountComponent(c, modem, 7, false);
|
||||||
int ltx = 0, lty = 0;
|
int ltx = 0, lty = 0;
|
||||||
double scrollBuf = 0;
|
double scrollBuf = 0;
|
||||||
SetTargetFPS(60);
|
SetTargetFPS(60);
|
||||||
@@ -759,6 +858,8 @@ cleanup:;
|
|||||||
nn_dropComponent(screen);
|
nn_dropComponent(screen);
|
||||||
nn_dropComponent(gpuCard);
|
nn_dropComponent(gpuCard);
|
||||||
nn_dropComponent(keyboard);
|
nn_dropComponent(keyboard);
|
||||||
|
nn_dropComponent(dataCard);
|
||||||
|
nn_dropComponent(modem);
|
||||||
// rip the universe
|
// rip the universe
|
||||||
nn_destroyUniverse(u);
|
nn_destroyUniverse(u);
|
||||||
ncl_destroyGlyphCache(gc);
|
ncl_destroyGlyphCache(gc);
|
||||||
|
|||||||
265
src/neonucleus.c
265
src/neonucleus.c
@@ -1752,7 +1752,11 @@ nn_Exit nn_tick(nn_Computer *computer) {
|
|||||||
err = nn_startComputer(computer);
|
err = nn_startComputer(computer);
|
||||||
if(err) return err;
|
if(err) return err;
|
||||||
} else if(computer->state != NN_RUNNING) {
|
} else if(computer->state != NN_RUNNING) {
|
||||||
if(computer->state != NN_CRASHED) nn_setErrorFromExit(computer, NN_EBADSTATE);
|
if(computer->state == NN_BLACKOUT) {
|
||||||
|
nn_setError(computer, "out of energy");
|
||||||
|
} else if(computer->state != NN_CRASHED) {
|
||||||
|
nn_setErrorFromExit(computer, NN_EBADSTATE);
|
||||||
|
}
|
||||||
return NN_EBADSTATE;
|
return NN_EBADSTATE;
|
||||||
}
|
}
|
||||||
computer->state = NN_RUNNING;
|
computer->state = NN_RUNNING;
|
||||||
@@ -2187,6 +2191,11 @@ nn_Exit nn_invokeComponent(nn_Computer *computer, const char *compAddress, const
|
|||||||
}
|
}
|
||||||
computer->stackSize = req.returnCount;
|
computer->stackSize = req.returnCount;
|
||||||
|
|
||||||
|
if(nn_getEnergy(computer) <= 0) {
|
||||||
|
nn_setError(computer, "out of energy");
|
||||||
|
return NN_EBADCALL;
|
||||||
|
}
|
||||||
|
|
||||||
return NN_OK;
|
return NN_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -6055,6 +6064,17 @@ nn_DataCard nn_defaultDataCards[3] = {
|
|||||||
NN_INIT(nn_DataCard) {
|
NN_INIT(nn_DataCard) {
|
||||||
.limit = NN_MiB,
|
.limit = NN_MiB,
|
||||||
.maxRandom = NN_KiB,
|
.maxRandom = NN_KiB,
|
||||||
|
.base64PerTick = 32,
|
||||||
|
.deflatingPerTick = 4,
|
||||||
|
.crc32PerTick = 32,
|
||||||
|
.md5PerTick = 8,
|
||||||
|
.sha256PerTick = 4,
|
||||||
|
.encryptPerTick = 4,
|
||||||
|
.genPerTick = 1,
|
||||||
|
.deserializePerTick = 8,
|
||||||
|
.ecdhPerTick = 1,
|
||||||
|
.ecdsaPerTick = 1,
|
||||||
|
.randomPerTick = 4,
|
||||||
.canHash = true,
|
.canHash = true,
|
||||||
.canEncrypt = false,
|
.canEncrypt = false,
|
||||||
.canECDH = false,
|
.canECDH = false,
|
||||||
@@ -6070,6 +6090,17 @@ nn_DataCard nn_defaultDataCards[3] = {
|
|||||||
NN_INIT(nn_DataCard) {
|
NN_INIT(nn_DataCard) {
|
||||||
.limit = NN_MiB,
|
.limit = NN_MiB,
|
||||||
.maxRandom = NN_KiB,
|
.maxRandom = NN_KiB,
|
||||||
|
.base64PerTick = 32,
|
||||||
|
.deflatingPerTick = 4,
|
||||||
|
.crc32PerTick = 32,
|
||||||
|
.md5PerTick = 8,
|
||||||
|
.sha256PerTick = 4,
|
||||||
|
.encryptPerTick = 4,
|
||||||
|
.genPerTick = 1,
|
||||||
|
.deserializePerTick = 8,
|
||||||
|
.ecdhPerTick = 1,
|
||||||
|
.ecdsaPerTick = 1,
|
||||||
|
.randomPerTick = 4,
|
||||||
.canHash = true,
|
.canHash = true,
|
||||||
.canEncrypt = true,
|
.canEncrypt = true,
|
||||||
.canECDH = false,
|
.canECDH = false,
|
||||||
@@ -6085,6 +6116,17 @@ nn_DataCard nn_defaultDataCards[3] = {
|
|||||||
NN_INIT(nn_DataCard) {
|
NN_INIT(nn_DataCard) {
|
||||||
.limit = NN_MiB,
|
.limit = NN_MiB,
|
||||||
.maxRandom = NN_KiB,
|
.maxRandom = NN_KiB,
|
||||||
|
.base64PerTick = 32,
|
||||||
|
.deflatingPerTick = 4,
|
||||||
|
.crc32PerTick = 32,
|
||||||
|
.md5PerTick = 8,
|
||||||
|
.sha256PerTick = 4,
|
||||||
|
.encryptPerTick = 4,
|
||||||
|
.genPerTick = 1,
|
||||||
|
.deserializePerTick = 8,
|
||||||
|
.ecdhPerTick = 1,
|
||||||
|
.ecdsaPerTick = 1,
|
||||||
|
.randomPerTick = 4,
|
||||||
.canHash = true,
|
.canHash = true,
|
||||||
.canEncrypt = true,
|
.canEncrypt = true,
|
||||||
.canECDH = true,
|
.canECDH = true,
|
||||||
@@ -6111,10 +6153,10 @@ static nn_Exit nn_dataHandler(nn_ComponentRequest *req) {
|
|||||||
if(method == NN_DATANUM_SHA256 || method == NN_DATANUM_MD5) {
|
if(method == NN_DATANUM_SHA256 || method == NN_DATANUM_MD5) {
|
||||||
req->methodEnabled = dataCard.canHash;
|
req->methodEnabled = dataCard.canHash;
|
||||||
}
|
}
|
||||||
if(method == NN_DATANUM_DEFLATE || method == NN_DATANUM_INFLATE || method == NN_DATANUM_RANDOM || method == NN_DATANUM_MAXRANDOM) {
|
if(method == NN_DATANUM_DEFLATE || method == NN_DATANUM_INFLATE) {
|
||||||
req->methodEnabled = dataCard.canCompress;
|
req->methodEnabled = dataCard.canCompress;
|
||||||
}
|
}
|
||||||
if(method == NN_DATANUM_ENCRYPT || method == NN_DATANUM_DECRYPT) {
|
if(method == NN_DATANUM_ENCRYPT || method == NN_DATANUM_DECRYPT || method == NN_DATANUM_RANDOM || method == NN_DATANUM_MAXRANDOM) {
|
||||||
req->methodEnabled = dataCard.canEncrypt;
|
req->methodEnabled = dataCard.canEncrypt;
|
||||||
}
|
}
|
||||||
if(method == NN_DATANUM_GENKEYPAIR || method == NN_DATANUM_ECDH || method == NN_DATANUM_ECDSA || method == NN_DATANUM_DESERIALIZEKEY) {
|
if(method == NN_DATANUM_GENKEYPAIR || method == NN_DATANUM_ECDH || method == NN_DATANUM_ECDSA || method == NN_DATANUM_DESERIALIZEKEY) {
|
||||||
@@ -6147,6 +6189,153 @@ static nn_Exit nn_dataHandler(nn_ComponentRequest *req) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// TODO: the cool methods
|
// TODO: the cool methods
|
||||||
|
if(method == NN_DATANUM_ENCODE64) {
|
||||||
|
nn_costComponent(C, req->compAddress, dataCard.base64PerTick);
|
||||||
|
if(nn_checkstring(C, 0, "bad argument #1 (string expected)")) return NN_EBADCALL;
|
||||||
|
dreq.action = NN_DATA_ENCODE64;
|
||||||
|
dreq.data = nn_tolstring(C, 0, &dreq.datalen);
|
||||||
|
if(dreq.datalen > dataCard.limit) return NN_ELIMIT;
|
||||||
|
e = state->handler(&dreq);
|
||||||
|
if(e) return e;
|
||||||
|
req->returnCount = 1;
|
||||||
|
return NN_OK;
|
||||||
|
}
|
||||||
|
if(method == NN_DATANUM_DECODE64) {
|
||||||
|
nn_costComponent(C, req->compAddress, dataCard.base64PerTick);
|
||||||
|
if(nn_checkstring(C, 0, "bad argument #1 (string expected)")) return NN_EBADCALL;
|
||||||
|
dreq.action = NN_DATA_DECODE64;
|
||||||
|
dreq.data = nn_tolstring(C, 0, &dreq.datalen);
|
||||||
|
if(dreq.datalen > dataCard.limit) return NN_ELIMIT;
|
||||||
|
e = state->handler(&dreq);
|
||||||
|
if(e) return e;
|
||||||
|
req->returnCount = 1;
|
||||||
|
return NN_OK;
|
||||||
|
}
|
||||||
|
if(method == NN_DATANUM_DEFLATE) {
|
||||||
|
nn_costComponent(C, req->compAddress, dataCard.deflatingPerTick);
|
||||||
|
if(nn_checkstring(C, 0, "bad argument #1 (string expected)")) return NN_EBADCALL;
|
||||||
|
dreq.action = NN_DATA_DEFLATE;
|
||||||
|
dreq.data = nn_tolstring(C, 0, &dreq.datalen);
|
||||||
|
if(dreq.datalen > dataCard.limit) return NN_ELIMIT;
|
||||||
|
e = state->handler(&dreq);
|
||||||
|
if(e) return e;
|
||||||
|
req->returnCount = 1;
|
||||||
|
return NN_OK;
|
||||||
|
}
|
||||||
|
if(method == NN_DATANUM_INFLATE) {
|
||||||
|
nn_costComponent(C, req->compAddress, dataCard.deflatingPerTick);
|
||||||
|
if(nn_checkstring(C, 0, "bad argument #1 (string expected)")) return NN_EBADCALL;
|
||||||
|
dreq.action = NN_DATA_INFLATE;
|
||||||
|
dreq.data = nn_tolstring(C, 0, &dreq.datalen);
|
||||||
|
if(dreq.datalen > dataCard.limit) return NN_ELIMIT;
|
||||||
|
e = state->handler(&dreq);
|
||||||
|
if(e) return e;
|
||||||
|
req->returnCount = 1;
|
||||||
|
return NN_OK;
|
||||||
|
}
|
||||||
|
if(method == NN_DATANUM_CRC32) {
|
||||||
|
nn_costComponent(C, req->compAddress, dataCard.crc32PerTick);
|
||||||
|
if(nn_checkstring(C, 0, "bad argument #1 (string expected)")) return NN_EBADCALL;
|
||||||
|
dreq.action = NN_DATA_CRC32;
|
||||||
|
dreq.crc32.data = nn_tolstring(C, 0, &dreq.crc32.datalen);
|
||||||
|
if(dreq.crc32.datalen > dataCard.limit) return NN_ELIMIT;
|
||||||
|
e = state->handler(&dreq);
|
||||||
|
if(e) return e;
|
||||||
|
req->returnCount = 1;
|
||||||
|
return nn_pushlstring(C, dreq.crc32.checksum, 4);
|
||||||
|
}
|
||||||
|
if(method == NN_DATANUM_MD5) {
|
||||||
|
nn_costComponent(C, req->compAddress, dataCard.md5PerTick);
|
||||||
|
if(nn_checkstring(C, 0, "bad argument #1 (string expected)")) return NN_EBADCALL;
|
||||||
|
dreq.action = NN_DATA_MD5;
|
||||||
|
dreq.md5.data = nn_tolstring(C, 0, &dreq.md5.datalen);
|
||||||
|
if(dreq.md5.datalen > dataCard.limit) return NN_ELIMIT;
|
||||||
|
e = state->handler(&dreq);
|
||||||
|
if(e) return e;
|
||||||
|
req->returnCount = 1;
|
||||||
|
return nn_pushlstring(C, dreq.md5.checksum, 16);
|
||||||
|
}
|
||||||
|
if(method == NN_DATANUM_SHA256) {
|
||||||
|
nn_costComponent(C, req->compAddress, dataCard.sha256PerTick);
|
||||||
|
if(nn_checkstring(C, 0, "bad argument #1 (string expected)")) return NN_EBADCALL;
|
||||||
|
dreq.action = NN_DATA_SHA256;
|
||||||
|
dreq.sha256.data = nn_tolstring(C, 0, &dreq.sha256.datalen);
|
||||||
|
if(dreq.sha256.datalen > dataCard.limit) return NN_ELIMIT;
|
||||||
|
e = state->handler(&dreq);
|
||||||
|
if(e) return e;
|
||||||
|
req->returnCount = 1;
|
||||||
|
return nn_pushlstring(C, dreq.sha256.checksum, 32);
|
||||||
|
}
|
||||||
|
if(method == NN_DATANUM_RANDOM) {
|
||||||
|
nn_costComponent(C, req->compAddress, dataCard.randomPerTick);
|
||||||
|
if(nn_checkinteger(C, 0, "bad argument #1 (integer expected)")) return NN_EBADCALL;
|
||||||
|
intptr_t n = nn_tointeger(C, 0);
|
||||||
|
if(n <= 0) {
|
||||||
|
n = 1;
|
||||||
|
}
|
||||||
|
if(n > dataCard.maxRandom) return NN_ELIMIT;
|
||||||
|
char *buf = nn_alloc(ctx, n);
|
||||||
|
dreq.action = NN_DATA_RANDOM;
|
||||||
|
dreq.randbuf.buf = buf;
|
||||||
|
dreq.randbuf.buflen = n;
|
||||||
|
e = state->handler(&dreq);
|
||||||
|
if(e) {
|
||||||
|
nn_free(ctx, buf, n);
|
||||||
|
return e;
|
||||||
|
}
|
||||||
|
req->returnCount = 1;
|
||||||
|
e = nn_pushlstring(C, buf, n);
|
||||||
|
nn_free(ctx, buf, n);
|
||||||
|
return e;
|
||||||
|
}
|
||||||
|
if(method == NN_DATANUM_ENCRYPT) {
|
||||||
|
nn_costComponent(C, req->compAddress, dataCard.encryptPerTick);
|
||||||
|
if(nn_checkstring(C, 0, "bad argument #1 (string expected)")) return NN_EBADCALL;
|
||||||
|
if(nn_checkstring(C, 1, "bad argument #2 (string expected)")) return NN_EBADCALL;
|
||||||
|
if(nn_checkstring(C, 2, "bad argument #3 (string expected)")) return NN_EBADCALL;
|
||||||
|
dreq.action = NN_DATA_ENCRYPT;
|
||||||
|
dreq.encrypt.data = nn_tolstring(C, 0, &dreq.encrypt.datalen);
|
||||||
|
if(dreq.encrypt.datalen > dataCard.limit) return NN_ELIMIT;
|
||||||
|
size_t len;
|
||||||
|
dreq.encrypt.key = nn_tolstring(C, 1, &len);
|
||||||
|
if(len != 16) {
|
||||||
|
nn_setError(C, "invalid key");
|
||||||
|
return NN_EBADCALL;
|
||||||
|
}
|
||||||
|
dreq.encrypt.iv = nn_tolstring(C, 2, &len);
|
||||||
|
if(len != 16) {
|
||||||
|
nn_setError(C, "invalid IV");
|
||||||
|
return NN_EBADCALL;
|
||||||
|
}
|
||||||
|
e = state->handler(&dreq);
|
||||||
|
if(e) return e;
|
||||||
|
req->returnCount = 1;
|
||||||
|
return NN_OK;
|
||||||
|
}
|
||||||
|
if(method == NN_DATANUM_DECRYPT) {
|
||||||
|
nn_costComponent(C, req->compAddress, dataCard.encryptPerTick);
|
||||||
|
if(nn_checkstring(C, 0, "bad argument #1 (string expected)")) return NN_EBADCALL;
|
||||||
|
if(nn_checkstring(C, 1, "bad argument #2 (string expected)")) return NN_EBADCALL;
|
||||||
|
if(nn_checkstring(C, 2, "bad argument #3 (string expected)")) return NN_EBADCALL;
|
||||||
|
dreq.action = NN_DATA_ENCRYPT;
|
||||||
|
dreq.encrypt.data = nn_tolstring(C, 0, &dreq.encrypt.datalen);
|
||||||
|
if(dreq.encrypt.datalen > dataCard.limit) return NN_ELIMIT;
|
||||||
|
size_t len;
|
||||||
|
dreq.encrypt.key = nn_tolstring(C, 1, &len);
|
||||||
|
if(len != 16) {
|
||||||
|
nn_setError(C, "invalid key");
|
||||||
|
return NN_EBADCALL;
|
||||||
|
}
|
||||||
|
dreq.encrypt.iv = nn_tolstring(C, 2, &len);
|
||||||
|
if(len != 16) {
|
||||||
|
nn_setError(C, "invalid IV");
|
||||||
|
return NN_EBADCALL;
|
||||||
|
}
|
||||||
|
e = state->handler(&dreq);
|
||||||
|
if(e) return e;
|
||||||
|
req->returnCount = 1;
|
||||||
|
return NN_OK;
|
||||||
|
}
|
||||||
|
|
||||||
if(C) nn_setError(C, "data: not implemented yet");
|
if(C) nn_setError(C, "data: not implemented yet");
|
||||||
return NN_EBADCALL;
|
return NN_EBADCALL;
|
||||||
@@ -6165,7 +6354,7 @@ nn_Component *nn_createDataCard(nn_Universe *universe, const char *address, cons
|
|||||||
[NN_DATANUM_MD5] = {"md5", "function(data: string): string - Computes the MD5 hash of the data", NN_DIRECT},
|
[NN_DATANUM_MD5] = {"md5", "function(data: string): string - Computes the MD5 hash of the data", NN_DIRECT},
|
||||||
[NN_DATANUM_SHA256] = {"sha256", "function(data: string): string - Computes the SHA256 hash of the data", NN_DIRECT},
|
[NN_DATANUM_SHA256] = {"sha256", "function(data: string): string - Computes the SHA256 hash of the data", NN_DIRECT},
|
||||||
[NN_DATANUM_DEFLATE] = {"deflate", "function(data: string): string - Compresses the data", NN_DIRECT},
|
[NN_DATANUM_DEFLATE] = {"deflate", "function(data: string): string - Compresses the data", NN_DIRECT},
|
||||||
[NN_DATANUM_INFLATE] = {"deflate", "function(data: string): string - Decompresses the compressed data", NN_DIRECT},
|
[NN_DATANUM_INFLATE] = {"inflate", "function(data: string): string - Decompresses the compressed data", NN_DIRECT},
|
||||||
[NN_DATANUM_ENCRYPT] = {"encrypt", "function(data: string, key: string, iv: string): string - Encrypts the data", NN_DIRECT},
|
[NN_DATANUM_ENCRYPT] = {"encrypt", "function(data: string, key: string, iv: string): string - Encrypts the data", NN_DIRECT},
|
||||||
[NN_DATANUM_DECRYPT] = {"decrypt", "function(data: string, key: string, iv: string): string - Decrypts the data", NN_DIRECT},
|
[NN_DATANUM_DECRYPT] = {"decrypt", "function(data: string, key: string, iv: string): string - Decrypts the data", NN_DIRECT},
|
||||||
[NN_DATANUM_RANDOM] = {"random", "function(size: integer): string - Generates an amount of secure random bytes", NN_DIRECT},
|
[NN_DATANUM_RANDOM] = {"random", "function(size: integer): string - Generates an amount of secure random bytes", NN_DIRECT},
|
||||||
@@ -6264,15 +6453,19 @@ static nn_Exit nn_modemHandler(nn_ComponentRequest *req) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if(method == NN_MODEMNUM_ISWIRED) {
|
if(method == NN_MODEMNUM_ISWIRED) {
|
||||||
|
req->returnCount = 1;
|
||||||
return nn_pushbool(C, isWired);
|
return nn_pushbool(C, isWired);
|
||||||
}
|
}
|
||||||
if(method == NN_MODEMNUM_ISWIRELESS) {
|
if(method == NN_MODEMNUM_ISWIRELESS) {
|
||||||
|
req->returnCount = 1;
|
||||||
return nn_pushbool(C, isWireless);
|
return nn_pushbool(C, isWireless);
|
||||||
}
|
}
|
||||||
if(method == NN_MODEMNUM_MAXPACKETSIZE) {
|
if(method == NN_MODEMNUM_MAXPACKETSIZE) {
|
||||||
|
req->returnCount = 1;
|
||||||
return nn_pushinteger(C, state->modem.maxPacketSize);
|
return nn_pushinteger(C, state->modem.maxPacketSize);
|
||||||
}
|
}
|
||||||
if(method == NN_MODEMNUM_MAXVALUES) {
|
if(method == NN_MODEMNUM_MAXVALUES) {
|
||||||
|
req->returnCount = 1;
|
||||||
return nn_pushinteger(C, state->modem.maxValues);
|
return nn_pushinteger(C, state->modem.maxValues);
|
||||||
}
|
}
|
||||||
if(method == NN_MODEMNUM_GETSTRENGTH) {
|
if(method == NN_MODEMNUM_GETSTRENGTH) {
|
||||||
@@ -6283,9 +6476,73 @@ static nn_Exit nn_modemHandler(nn_ComponentRequest *req) {
|
|||||||
return nn_pushinteger(C, mreq.strength);
|
return nn_pushinteger(C, mreq.strength);
|
||||||
}
|
}
|
||||||
if(method == NN_MODEMNUM_MAXSTRENGTH) {
|
if(method == NN_MODEMNUM_MAXSTRENGTH) {
|
||||||
|
req->returnCount = 1;
|
||||||
return nn_pushinteger(C, state->modem.maxRange);
|
return nn_pushinteger(C, state->modem.maxRange);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(method == NN_MODEMNUM_BROADCAST) {
|
||||||
|
if(nn_checkinteger(C, 0, "bad argument #1 (integer expected)")) return NN_EBADCALL;
|
||||||
|
intptr_t port = nn_tointeger(C, 0);
|
||||||
|
if(port < 1 || port > NN_MAX_PORT) {
|
||||||
|
nn_setError(C, "invalid port");
|
||||||
|
return NN_EBADCALL;
|
||||||
|
}
|
||||||
|
size_t valcount = nn_getstacksize(C) - 1;
|
||||||
|
if(valcount > state->modem.maxValues) return NN_EBADCALL;
|
||||||
|
int cost = nn_countValueCost(C, valcount);
|
||||||
|
if(cost < 0) {
|
||||||
|
nn_setError(C, "invalid contents");
|
||||||
|
return NN_EBADCALL;
|
||||||
|
}
|
||||||
|
if(cost > state->modem.maxPacketSize) return NN_ELIMIT;
|
||||||
|
nn_EncodedNetworkContents data;
|
||||||
|
e = nn_encodeNetworkContents(C, &data, valcount);
|
||||||
|
if(e) return e;
|
||||||
|
mreq.action = NN_MODEM_SEND;
|
||||||
|
mreq.send.address = NULL;
|
||||||
|
mreq.send.port = port;
|
||||||
|
mreq.send.contents = &data;
|
||||||
|
e = state->handler(&mreq);
|
||||||
|
nn_dropNetworkContents(&data);
|
||||||
|
if(!e) {
|
||||||
|
req->returnCount = 1;
|
||||||
|
e = nn_pushbool(C, true);
|
||||||
|
}
|
||||||
|
return e;
|
||||||
|
}
|
||||||
|
if(method == NN_MODEMNUM_SEND) {
|
||||||
|
if(nn_checkstring(C, 0, "bad argument #1 (string expected)")) return NN_EBADCALL;
|
||||||
|
if(nn_checkinteger(C, 1, "bad argument #2 (integer expected)")) return NN_EBADCALL;
|
||||||
|
const char *addr = nn_tostring(C, 0);
|
||||||
|
intptr_t port = nn_tointeger(C, 1);
|
||||||
|
if(port < 1 || port > NN_MAX_PORT) {
|
||||||
|
nn_setError(C, "invalid port");
|
||||||
|
return NN_EBADCALL;
|
||||||
|
}
|
||||||
|
size_t valcount = nn_getstacksize(C) - 1;
|
||||||
|
if(valcount > state->modem.maxValues) return NN_EBADCALL;
|
||||||
|
int cost = nn_countValueCost(C, valcount);
|
||||||
|
if(cost < 0) {
|
||||||
|
nn_setError(C, "invalid contents");
|
||||||
|
return NN_EBADCALL;
|
||||||
|
}
|
||||||
|
if(cost > state->modem.maxPacketSize) return NN_ELIMIT;
|
||||||
|
nn_EncodedNetworkContents data;
|
||||||
|
e = nn_encodeNetworkContents(C, &data, valcount);
|
||||||
|
if(e) return e;
|
||||||
|
mreq.action = NN_MODEM_SEND;
|
||||||
|
mreq.send.address = addr;
|
||||||
|
mreq.send.port = port;
|
||||||
|
mreq.send.contents = &data;
|
||||||
|
e = state->handler(&mreq);
|
||||||
|
nn_dropNetworkContents(&data);
|
||||||
|
if(!e) {
|
||||||
|
req->returnCount = 1;
|
||||||
|
e = nn_pushbool(C, true);
|
||||||
|
}
|
||||||
|
return e;
|
||||||
|
}
|
||||||
|
|
||||||
if(C) nn_setError(C, "modem: not implemented yet");
|
if(C) nn_setError(C, "modem: not implemented yet");
|
||||||
return NN_EBADCALL;
|
return NN_EBADCALL;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1657,10 +1657,15 @@ nn_Component *nn_createScreen(
|
|||||||
nn_ScreenHandler *handler
|
nn_ScreenHandler *handler
|
||||||
);
|
);
|
||||||
|
|
||||||
|
// Computes a CRC32 checksum
|
||||||
|
unsigned int nn_computeCRC32(const char *data, size_t datalen);
|
||||||
|
|
||||||
typedef struct nn_DataCard {
|
typedef struct nn_DataCard {
|
||||||
// The buffer size of the data card, limit in both input and output.
|
// The buffer size of the data card, limit in both input and output.
|
||||||
// This buffer is allocated on the heap before the call, thus setting it to be very large will lead to huge *spikes* in memory usage.
|
|
||||||
// In OC, this value is 1MiB regardless of tier.
|
// In OC, this value is 1MiB regardless of tier.
|
||||||
|
// As there is no out buffer and you are expected to push strings,
|
||||||
|
// the buffer is not pre-allocated. This is intentional, as memory
|
||||||
|
// would be wasted and it could be a potential attack vector otherwise.
|
||||||
size_t limit;
|
size_t limit;
|
||||||
|
|
||||||
// The maximum amount of secure random bytes that can be generated.
|
// The maximum amount of secure random bytes that can be generated.
|
||||||
@@ -1669,6 +1674,29 @@ typedef struct nn_DataCard {
|
|||||||
// as the amount of bytes needed is known perfectly.
|
// as the amount of bytes needed is known perfectly.
|
||||||
size_t maxRandom;
|
size_t maxRandom;
|
||||||
|
|
||||||
|
// for encoding/decoding. OC defaulted to 32
|
||||||
|
size_t base64PerTick;
|
||||||
|
// for deflate/inflate. OC defaulted to 4
|
||||||
|
size_t deflatingPerTick;
|
||||||
|
// OC defaulted to 32
|
||||||
|
size_t crc32PerTick;
|
||||||
|
// OC defaulted to 8
|
||||||
|
size_t md5PerTick;
|
||||||
|
// OC defaulted to 4
|
||||||
|
size_t sha256PerTick;
|
||||||
|
// for encrypt/decrypt. OC defaulted to 4
|
||||||
|
size_t encryptPerTick;
|
||||||
|
// for generateKeyPair. OC defaulted to 1
|
||||||
|
size_t genPerTick;
|
||||||
|
// for deserializeKey. OC defaulted to 8
|
||||||
|
size_t deserializePerTick;
|
||||||
|
// OC defaulted to 1
|
||||||
|
size_t ecdhPerTick;
|
||||||
|
// OC defaulted to 1
|
||||||
|
size_t ecdsaPerTick;
|
||||||
|
// OC defaults to 4
|
||||||
|
size_t randomPerTick;
|
||||||
|
|
||||||
// Capabilities
|
// Capabilities
|
||||||
bool canHash;
|
bool canHash;
|
||||||
bool canEncrypt;
|
bool canEncrypt;
|
||||||
@@ -1718,7 +1746,7 @@ typedef enum nn_DataCardAction {
|
|||||||
NN_DATA_DEFLATE,
|
NN_DATA_DEFLATE,
|
||||||
|
|
||||||
// Inflate. Should support the ZLIB format, as thats what OC uses, and GZIP support is optional.
|
// Inflate. Should support the ZLIB format, as thats what OC uses, and GZIP support is optional.
|
||||||
NN_DATA_INFALTE,
|
NN_DATA_INFLATE,
|
||||||
|
|
||||||
// Encrypt data with AES-128. The full algorithm is AES/CBC/PKCS5, as is use PKCS5 for padding, CBC for block sequences, and AES-128 for encrypting blocks.
|
// Encrypt data with AES-128. The full algorithm is AES/CBC/PKCS5, as is use PKCS5 for padding, CBC for block sequences, and AES-128 for encrypting blocks.
|
||||||
// It does also receive a 128-bit AES Initialization Vector, for better security.
|
// It does also receive a 128-bit AES Initialization Vector, for better security.
|
||||||
@@ -1752,6 +1780,39 @@ typedef struct nn_DataCardRequest {
|
|||||||
const nn_DataCard *dataCard;
|
const nn_DataCard *dataCard;
|
||||||
nn_DataCardAction action;
|
nn_DataCardAction action;
|
||||||
// TODO: the fields
|
// TODO: the fields
|
||||||
|
union {
|
||||||
|
struct {
|
||||||
|
const char *data;
|
||||||
|
size_t datalen;
|
||||||
|
char checksum[4];
|
||||||
|
} crc32;
|
||||||
|
struct {
|
||||||
|
const char *data;
|
||||||
|
size_t datalen;
|
||||||
|
char checksum[16];
|
||||||
|
} md5;
|
||||||
|
struct {
|
||||||
|
const char *data;
|
||||||
|
size_t datalen;
|
||||||
|
char checksum[32];
|
||||||
|
} sha256;
|
||||||
|
// for encrypt/decrypt
|
||||||
|
struct {
|
||||||
|
const char *data;
|
||||||
|
size_t datalen;
|
||||||
|
const char *key;
|
||||||
|
const char *iv;
|
||||||
|
} encrypt;
|
||||||
|
struct {
|
||||||
|
char *buf;
|
||||||
|
size_t buflen;
|
||||||
|
} randbuf;
|
||||||
|
// for deflate, inflate, encode64 and decode64
|
||||||
|
struct {
|
||||||
|
const char *data;
|
||||||
|
size_t datalen;
|
||||||
|
};
|
||||||
|
};
|
||||||
} nn_DataCardRequest;
|
} nn_DataCardRequest;
|
||||||
|
|
||||||
typedef nn_Exit (nn_DataCardHandler)(nn_DataCardRequest *req);
|
typedef nn_Exit (nn_DataCardHandler)(nn_DataCardRequest *req);
|
||||||
|
|||||||
Reference in New Issue
Block a user