aboutsummaryrefslogtreecommitdiff
path: root/tests/test.c
diff options
context:
space:
mode:
Diffstat (limited to 'tests/test.c')
-rw-r--r--tests/test.c321
1 files changed, 261 insertions, 60 deletions
diff --git a/tests/test.c b/tests/test.c
index 499ef50..d8fa89c 100644
--- a/tests/test.c
+++ b/tests/test.c
@@ -1,78 +1,136 @@
/*
* Copyright (c) 2024 Vaughn Nugent
*
-* Library: noscrypt
* Package: noscrypt
* File: test.c
*
-* noscrypt is free software: you can redistribute it and/or modify
-* it under the terms of the GNU General Public License as published
-* by the Free Software Foundation, either version 2 of the License,
-* or (at your option) any later version.
+* This library is free software; you can redistribute it and/or
+* modify it under the terms of the GNU Lesser General Public License
+* as published by the Free Software Foundation; either version 2.1
+* of the License, or (at your option) any later version.
*
-* noscrypt is distributed in the hope that it will be useful,
+* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-* General Public License for more details.
+* Lesser General Public License for more details.
*
-* You should have received a copy of the GNU General Public License
-* along with noscrypt. If not, see http://www.gnu.org/licenses/.
+* You should have received a copy of the GNU Lesser General Public License
+* along with NativeHeapApi. If not, see http://www.gnu.org/licenses/.
*/
#include <stdio.h>
#include <stdint.h>
#include <string.h>
+#include <stdlib.h>
-#include "../src/noscrypt.h"
-#include "../include/mbedtls/sha256.h"
+#include <noscrypt.h>
+#include <mbedtls/sha256.h>
+#include <mbedtls/platform_util.h>
#if defined(_MSC_VER) || defined(WIN32) || defined(_WIN32)
#define IS_WINDOWS
#endif
#ifdef IS_WINDOWS
-
- #include <windows.h>
+ #define WIN32_LEAN_AND_MEAN
+ #include <windows.h>
#include <wincrypt.h>
+#endif
- //Prints a string literal to the console
- #define PRINTL(x) printf(x); printf("\r\n");
- #define TEST(x) printf("Testing %s\n", #x); if(!(x)) { printf("Test failed!\n"); return 1; } else { printf("Test passed\n\n"); }
+#ifdef IS_WINDOWS
+ /*Asserts that an internal test condition is true, otherwise aborts the test process*/
#define TASSERT(x) if(!(x)) { printf("ERROR! Internal test assumption failed: %s.\n Aborting tests...\n", #x); ExitProcess(1); }
#else
- #include <stdlib.h>
-
- //Prints a string literal to the console
- #define PRINTL(x) printf(x); printf("\n");
- #define TEST(x) printf("Testing %s\n", #x); if(!(x)) { printf("Test failed!\n"); return 1; } else { printf("Test passed\n\n"); }
+ /*Asserts that an internal test condition is true, otherwise aborts the test process*/
#define TASSERT(x) if(!(x)) { printf("Internal assumption failed: %s\n", #x); exit(1); }
#endif
-static void FillRandomData(uint8_t* pbBuffer, size_t length);
-static int TestEcdsa(NCContext* context);
+/*Prints a string literal to the console*/
+#define PRINTL(x) printf(x); printf("\n");
+#define ENSURE(x) if(!(x)) { printf("Assumption failed!\n"); return 1; }
+#define TEST(x, expected) printf("\tTesting %s\n", #x); if(((long)x) != ((long)expected)) \
+{ printf("FAILED: Expected %ld but got %ld @ callsite %s. Line: %d \n", ((long)expected), ((long)x), #x, __LINE__); return 1; }
+
+
+#ifdef IS_WINDOWS
+ #define ZERO_FILL(x, size) SecureZeroMemory(x, size)
+#else
+ #define ZERO_FILL(x, size) memset(x, 0, size)
+#endif
+
+//Pre-computed constants for argument errors
+#define ARG_ERROR_POS_0 E_NULL_PTR
+#define ARG_ERROR_POS_1 NCResultWithArgPosition(E_NULL_PTR, 0x01)
+#define ARG_ERROR_POS_2 NCResultWithArgPosition(E_NULL_PTR, 0x02)
+#define ARG_ERROR_POS_3 NCResultWithArgPosition(E_NULL_PTR, 0x03)
+#define ARG_ERROR_POS_4 NCResultWithArgPosition(E_NULL_PTR, 0x04)
+#define ARG_ERROR_POS_5 NCResultWithArgPosition(E_NULL_PTR, 0x05)
+#define ARG_ERROR_POS_6 NCResultWithArgPosition(E_NULL_PTR, 0x06)
+
+#define ARG_RAMGE_ERROR_POS_0 E_ARGUMENT_OUT_OF_RANGE
+#define ARG_RAMGE_ERROR_POS_1 NCResultWithArgPosition(E_ARGUMENT_OUT_OF_RANGE, 0x01)
+#define ARG_RAMGE_ERROR_POS_2 NCResultWithArgPosition(E_ARGUMENT_OUT_OF_RANGE, 0x02)
+#define ARG_RAMGE_ERROR_POS_3 NCResultWithArgPosition(E_ARGUMENT_OUT_OF_RANGE, 0x03)
+#define ARG_RAMGE_ERROR_POS_4 NCResultWithArgPosition(E_ARGUMENT_OUT_OF_RANGE, 0x04)
+#define ARG_RAMGE_ERROR_POS_5 NCResultWithArgPosition(E_ARGUMENT_OUT_OF_RANGE, 0x05)
+#define ARG_RAMGE_ERROR_POS_6 NCResultWithArgPosition(E_ARGUMENT_OUT_OF_RANGE, 0x06)
+
+#define ARG_INVALID_ERROR_POS_0 E_INVALID_ARG
+#define ARG_INVALID_ERROR_POS_1 NCResultWithArgPosition(E_INVALID_ARG, 0x01)
+#define ARG_INVALID_ERROR_POS_2 NCResultWithArgPosition(E_INVALID_ARG, 0x02)
+#define ARG_INVALID_ERROR_POS_3 NCResultWithArgPosition(E_INVALID_ARG, 0x03)
+#define ARG_INVALID_ERROR_POS_4 NCResultWithArgPosition(E_INVALID_ARG, 0x04)
+#define ARG_INVALID_ERROR_POS_5 NCResultWithArgPosition(E_INVALID_ARG, 0x05)
+#define ARG_INVALID_ERROR_POS_6 NCResultWithArgPosition(E_INVALID_ARG, 0x06)
+
+
+
+static void FillRandomData(void* pbBuffer, size_t length);
+static int TestEcdsa(NCContext* context, NCSecretKey* secKey, NCPublicKey* pubKey);
+static int InitKepair(NCContext* context, NCSecretKey* secKey, NCPublicKey* pubKey);
+
+#ifndef NC_INPUT_VALIDATION_OFF
+static int TestPublicApiArgumentValidation(void);
+#endif
+
+static const uint8_t zero32[32] = { 0 };
+static const uint8_t zero64[64] = { 0 };
-int main(char* argv[], int argc)
+int main(void)
{
NCContext ctx;
uint8_t ctxRandom[32];
+ NCSecretKey secKey;
+ NCPublicKey pubKey;
PRINTL("Begining basic noscrypt tests\n")
FillRandomData(ctxRandom, 32);
//Context struct size should aways match the size of the struct returned by NCGetContextStructSize
- TEST(NCGetContextStructSize() == sizeof(NCContext))
+ TEST(NCGetContextStructSize(), sizeof(NCContext))
+ TEST(NCInitContext(&ctx, ctxRandom), NC_SUCCESS)
- TEST(NCInitContext(&ctx, ctxRandom) == NC_SUCCESS)
+ if (InitKepair(&ctx, &secKey, &pubKey) != 0)
+ {
+ return 1;
+ }
- if (TestEcdsa(&ctx) != 0)
+ if (TestEcdsa(&ctx, &secKey, &pubKey) != 0)
{
return 1;
}
+#ifndef NC_INPUT_VALIDATION_OFF
+ if(TestPublicApiArgumentValidation() != 0)
+ {
+ return 1;
+ }
+#endif
+
PRINTL("ECDSA tests passed\n")
- TEST(NCDestroyContext(&ctx) == NC_SUCCESS)
+ TEST(NCDestroyContext(&ctx), NC_SUCCESS)
return 0;
}
@@ -89,69 +147,212 @@ static void _sha256(const uint8_t* data, size_t length, uint8_t digest[32])
static const char* message = "Test message to sign";
-static int TestEcdsa(NCContext* context)
+static int InitKepair(NCContext* context, NCSecretKey* secKey, NCPublicKey* pubKey)
{
+ PRINTL("TEST: Keypair\n")
+
+ //Get random private key
+ FillRandomData(secKey, sizeof(NCSecretKey));
+
+ //Ensure not empty
+ ENSURE(memcmp(zero32, secKey, 32) != 0);
+
+ //Ensure the key is valid, result should be 1 on success
+ TEST(NCValidateSecretKey(context, secKey), 1);
+
+ //Generate a public key from the secret key
+ TEST(NCGetPublicKey(context, secKey, pubKey), NC_SUCCESS);
+
+ PRINTL("\nPASSED: Keypair tests completed\n")
+
+ return 0;
+}
+
+static int TestEcdsa(NCContext* context, NCSecretKey* secKey, NCPublicKey* pubKey)
+{
uint8_t digestToSign[32];
- uint8_t secretKey[NC_SEC_KEY_SIZE];
- uint8_t publicKey[NC_PUBKEY_SIZE];
uint8_t sigEntropy[32];
uint8_t invalidSig[64];
- NCSecretKey* secKey;
- NCPublicKey* pubKey;
-
- PRINTL("Begining basic Nostr ECDSA tests")
- //Convert to internal key structs
- secKey = NCToSecKey(secretKey);
- pubKey = NCToPubKey(publicKey);
-
- TEST((&secKey->key) == &secretKey);
+ PRINTL("TEST: Ecdsa\n")
//Init a new secret key with random data
- FillRandomData(secretKey, sizeof(secretKey));
FillRandomData(invalidSig, sizeof(invalidSig));
FillRandomData(sigEntropy, sizeof(sigEntropy));
- //Verify that the secret key is valid for the curve
- TEST(NCValidateSecretKey(context, secKey) == NC_SUCCESS);
-
- //Generate a public key from the secret key
- TEST(NCGetPublicKey(context, secKey, pubKey) == NC_SUCCESS);
+ //compute sha256 of the test string
+ _sha256((uint8_t*)message, strlen(message), digestToSign);
- //Sign and verify digest
+ //Sign and verify sig64
{
uint8_t sig[64];
-
- //compute sha256 of the test string
- _sha256((uint8_t*)message, strlen(message), digestToSign);
-
- TEST(NCSignDigest(context, secKey, sigEntropy, digestToSign, sig) == NC_SUCCESS);
- TEST(NCVerifyDigest(context, pubKey, digestToSign, sig) == NC_SUCCESS);
+ TEST(NCSignDigest(context, secKey, sigEntropy, digestToSign, sig), NC_SUCCESS);
+ TEST(NCVerifyDigest(context, pubKey, digestToSign, sig), NC_SUCCESS);
}
//Sign and verify raw data
{
uint8_t sig[64];
- TEST(NCSignData(context, secKey, sigEntropy, (uint8_t*)message, strlen(message), sig) == NC_SUCCESS);
- TEST(NCVerifyData(context, pubKey, (uint8_t*)message, strlen(message), sig) == NC_SUCCESS);
+ TEST(NCSignData(context, secKey, sigEntropy, (uint8_t*)message, strlen(message), sig), NC_SUCCESS);
+ TEST(NCVerifyData(context, pubKey, (uint8_t*)message, strlen(message), sig), NC_SUCCESS);
}
+ //ensure the signature is the same for signing data and sig64
+ {
+ uint8_t sig1[64];
+ uint8_t sig2[64];
+
+ //Ensure operations succeed but dont print them as test cases
+ ENSURE(NCSignData(context, secKey, sigEntropy, (uint8_t*)message, strlen(message), sig1) == NC_SUCCESS);
+ ENSURE(NCSignDigest(context, secKey, sigEntropy, digestToSign, sig2) == NC_SUCCESS);
+
+ //Perform test
+ TEST(memcmp(sig1, sig2, 64), 0);
+ }
+
+ //Try signing data then veriyfing the sig64
+ {
+ uint8_t sig[64];
+
+ ENSURE(NCSignData(context, secKey, sigEntropy, (uint8_t*)message, strlen(message), sig) == NC_SUCCESS);
+ TEST(NCVerifyDigest(context, pubKey, digestToSign, sig), NC_SUCCESS);
+
+ //Now invert test, zero signature to ensure its overwritten
+ ZERO_FILL(sig, sizeof(sig));
+
+ ENSURE(NCSignDigest(context, secKey, sigEntropy, digestToSign, sig) == NC_SUCCESS);
+ TEST(NCVerifyData(context, pubKey, (uint8_t*)message, strlen(message), sig), NC_SUCCESS);
+ }
+
//test verification of invalid signature
{
- TEST(NCVerifyDigest(context, pubKey, digestToSign, invalidSig) == E_INVALID_ARG);
+ TEST(NCVerifyDigest(context, pubKey, digestToSign, invalidSig), E_INVALID_ARG);
}
+ PRINTL("\nPASSED: Ecdsa tests completed\n")
return 0;
}
-static const char* encMessage = "Test message to encrypt";
+#ifndef NC_INPUT_VALIDATION_OFF
-static int TestEcdh(NCContext* ctx)
+static int TestPublicApiArgumentValidation(void)
{
- PRINTL("Begining basic Nostr Encryption tests")
+ NCContext ctx;
+ uint8_t ctxRandom[32];
+ uint8_t sig64[64];
+ NCSecretKey secKey;
+ NCPublicKey pubKey;
+ NCCryptoData cryptoData;
+
+ PRINTL("TEST: Public API argument validation tests\n")
+
+ FillRandomData(ctxRandom, 32);
+
+ //Test null context
+ TEST(NCInitContext(NULL, ctxRandom), ARG_ERROR_POS_0)
+ TEST(NCInitContext(&ctx, NULL), ARG_ERROR_POS_1)
+
+ //Test null context
+ TEST(NCDestroyContext(NULL), ARG_ERROR_POS_0)
+
+ //reinit
+ TEST(NCReInitContext(NULL, ctxRandom), ARG_ERROR_POS_0)
+ TEST(NCReInitContext(&ctx, NULL), ARG_ERROR_POS_1)
+
+ //Test null secret key
+ TEST(NCGetPublicKey(&ctx, NULL, &pubKey), ARG_ERROR_POS_1)
+ TEST(NCGetPublicKey(&ctx, &secKey, NULL), ARG_ERROR_POS_2)
+
+ //Test null secret key
+ TEST(NCValidateSecretKey(NULL, &secKey), ARG_ERROR_POS_0)
+ TEST(NCValidateSecretKey(&ctx, NULL), ARG_ERROR_POS_1)
+
+ //Verify sig64 args test
+ TEST(NCVerifyDigest(NULL, &pubKey, zero32, sig64), ARG_ERROR_POS_0)
+ TEST(NCVerifyDigest(&ctx, NULL, zero32, sig64), ARG_ERROR_POS_1)
+ TEST(NCVerifyDigest(&ctx, &pubKey, NULL, sig64), ARG_ERROR_POS_2)
+ TEST(NCVerifyDigest(&ctx, &pubKey, zero32, NULL), ARG_ERROR_POS_3)
+
+ //Test verify data args
+ TEST(NCVerifyData(NULL, &pubKey, zero32, 32, sig64), ARG_ERROR_POS_0)
+ TEST(NCVerifyData(&ctx, NULL, zero32, 32, sig64), ARG_ERROR_POS_1)
+ TEST(NCVerifyData(&ctx, &pubKey, NULL, 32, sig64), ARG_ERROR_POS_2)
+ TEST(NCVerifyData(&ctx, &pubKey, zero32, 0, sig64), ARG_RAMGE_ERROR_POS_3)
+ TEST(NCVerifyData(&ctx, &pubKey, zero32, 32, NULL), ARG_ERROR_POS_4)
+
+ //Test null sign data args
+ TEST(NCSignData(NULL, &secKey, zero32, zero32, 32, sig64), ARG_ERROR_POS_0)
+ TEST(NCSignData(&ctx, NULL, zero32, zero32, 32, sig64), ARG_ERROR_POS_1)
+ TEST(NCSignData(&ctx, &secKey, NULL, zero32, 32, sig64), ARG_ERROR_POS_2)
+ TEST(NCSignData(&ctx, &secKey, zero32, NULL, 32, sig64), ARG_ERROR_POS_3)
+ TEST(NCSignData(&ctx, &secKey, zero32, zero32, 0, sig64), ARG_RAMGE_ERROR_POS_4)
+ TEST(NCSignData(&ctx, &secKey, zero32, zero32, 32, NULL), ARG_ERROR_POS_5)
+
+ //Test null sign digest args
+ TEST(NCSignDigest(NULL, &secKey, zero32, zero32, sig64), ARG_ERROR_POS_0)
+ TEST(NCSignDigest(&ctx, NULL, zero32, zero32, sig64), ARG_ERROR_POS_1)
+ TEST(NCSignDigest(&ctx, &secKey, NULL, zero32, sig64), ARG_ERROR_POS_2)
+ TEST(NCSignDigest(&ctx, &secKey, zero32, NULL, sig64), ARG_ERROR_POS_3)
+ TEST(NCSignDigest(&ctx, &secKey, zero32, zero32, NULL), ARG_ERROR_POS_4)
+
+
+ //Encrypt
+ cryptoData.dataSize = 32;
+ cryptoData.inputData = zero32;
+ cryptoData.outputData = sig64;
+ FillRandomData(&cryptoData.nonce, 32);
+
+ TEST(NCEncrypt(NULL, &secKey, &pubKey, &cryptoData), ARG_ERROR_POS_0)
+ TEST(NCEncrypt(&ctx, NULL, &pubKey, &cryptoData), ARG_ERROR_POS_1)
+ TEST(NCEncrypt(&ctx, &secKey, NULL, &cryptoData), ARG_ERROR_POS_2)
+ TEST(NCEncrypt(&ctx, &secKey, &pubKey, NULL), ARG_ERROR_POS_3)
+
+ //Test invalid data size
+ cryptoData.dataSize = 0;
+ TEST(NCEncrypt(&ctx, &secKey, &pubKey, &cryptoData), ARG_RAMGE_ERROR_POS_3)
+
+ //Test null input data
+ cryptoData.dataSize = 32;
+ cryptoData.inputData = NULL;
+ TEST(NCEncrypt(&ctx, &secKey, &pubKey, &cryptoData), ARG_INVALID_ERROR_POS_3)
+
+ //Test null output data
+ cryptoData.inputData = zero32;
+ cryptoData.outputData = NULL;
+ TEST(NCEncrypt(&ctx, &secKey, &pubKey, &cryptoData), ARG_INVALID_ERROR_POS_3)
+
+ //Decrypt
+ cryptoData.dataSize = 32;
+ cryptoData.inputData = zero32;
+ cryptoData.outputData = sig64;
+
+ TEST(NCDecrypt(NULL, &secKey, &pubKey, &cryptoData), ARG_ERROR_POS_0)
+ TEST(NCDecrypt(&ctx, NULL, &pubKey, &cryptoData), ARG_ERROR_POS_1)
+ TEST(NCDecrypt(&ctx, &secKey, NULL, &cryptoData), ARG_ERROR_POS_2)
+ TEST(NCDecrypt(&ctx, &secKey, &pubKey, NULL), ARG_ERROR_POS_3)
+
+ //Test invalid data size
+ cryptoData.dataSize = 0;
+ TEST(NCDecrypt(&ctx, &secKey, &pubKey, &cryptoData), ARG_RAMGE_ERROR_POS_3)
+
+ //Test null input data
+ cryptoData.dataSize = 32;
+ cryptoData.inputData = NULL;
+ TEST(NCDecrypt(&ctx, &secKey, &pubKey, &cryptoData), ARG_INVALID_ERROR_POS_3)
+
+ //Test null output data
+ cryptoData.inputData = zero32;
+ cryptoData.outputData = NULL;
+ TEST(NCDecrypt(&ctx, &secKey, &pubKey, &cryptoData), ARG_INVALID_ERROR_POS_3)
+
+ PRINTL("\nPASSED: Public API argument validation tests completed\n")
+
+ return 0;
}
-static void FillRandomData(uint8_t* pbBuffer, size_t length)
+#endif
+
+static void FillRandomData(void* pbBuffer, size_t length)
{
#ifdef IS_WINDOWS