From 75a923f0ee362a039b51a141a719ce50597ca233 Mon Sep 17 00:00:00 2001 From: Devel Date: Thu, 12 Apr 2018 18:07:08 +0200 Subject: Added signature calculation and verification for ECDSA Change-Id: I946e146b9a6ae33ee294a09417e8366853faa502 Signed-off-by: Devel --- libparc/parc/security/test/test_parc_SignerEC.c | 312 ++++++++++++++++++++++++ 1 file changed, 312 insertions(+) create mode 100644 libparc/parc/security/test/test_parc_SignerEC.c (limited to 'libparc/parc/security/test/test_parc_SignerEC.c') diff --git a/libparc/parc/security/test/test_parc_SignerEC.c b/libparc/parc/security/test/test_parc_SignerEC.c new file mode 100644 index 00000000..2b6fc577 --- /dev/null +++ b/libparc/parc/security/test/test_parc_SignerEC.c @@ -0,0 +1,312 @@ +/* + * Copyright (c) 2017 Cisco and/or its affiliates. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include +#include +#include + +#include "../parc_Signer.c" + +#include +#include +#include + +#include +#include +#include +#include + +#define FAKE_SIGNATURE "signature" + +typedef struct { + PARCCryptoHasher *hasher; + PARCKeyStore *keyStore; +} _MockSigner; + +static PARCSignature * +_SignDigest(PARCSigner *interfaceContext) +{ + PARCBuffer *buffer = parcBuffer_WrapCString(FAKE_SIGNATURE); + PARCSignature *signature = parcSignature_Create(PARCSigningAlgorithm_ECDSA, PARCCryptoHashType_SHA256, buffer); + parcBuffer_Release(&buffer); + return signature; +} + +static PARCSigningAlgorithm +_GetSigningAlgorithm(PARCSigner *interfaceContext) +{ + return PARCSigningAlgorithm_ECDSA; +} + +static PARCCryptoHashType +_GetCryptoHashType(PARCSigner *signer) +{ + return PARCCryptoHashType_SHA256; +} + +static PARCCryptoHasher * +_GetCryptoHasher(_MockSigner *signer) +{ + return signer->hasher; +} + +static PARCKeyStore * +_GetKeyStore(_MockSigner *signer) +{ + return signer->keyStore; +} + +static bool +_releaseSigner(_MockSigner **signer) +{ + parcCryptoHasher_Release(&((*signer)->hasher)); + parcKeyStore_Release(&((*signer)->keyStore)); + return true; +} + +parcObject_ImplementAcquire(_mockSigner, _MockSigner); +parcObject_ImplementRelease(_mockSigner, _MockSigner); + +parcObject_Override(_MockSigner, PARCObject, + .destructor = (PARCObjectDestructor *) _releaseSigner); + +static _MockSigner * +_createSigner() +{ + const char *filename = "/tmp/test_ecdsa.p12"; + const char *password = "12345"; + const char *subject = "alice"; + _MockSigner *signer = parcObject_CreateInstance(_MockSigner); + + signer->hasher = parcCryptoHasher_Create(PARCCryptoHashType_SHA256); + + bool res = parcPkcs12KeyStore_CreateFile(filename, password, subject, PARCSigningAlgorithm_ECDSA, 256, 180); + assertTrue(res, "Unable to create an ECDSA key"); + + PARCPkcs12KeyStore *publicKeyStore = parcPkcs12KeyStore_Open("test_ec.p12", "blueberry", PARCCryptoHashType_SHA256); + + assertNotNull(publicKeyStore, "Got null result from opening openssl pkcs12 file"); + + signer->keyStore = parcKeyStore_Create(publicKeyStore, PARCPkcs12KeyStoreAsKeyStore); + parcPkcs12KeyStore_Release(&publicKeyStore); + + return signer; +} + +static PARCSigningInterface *_MockSignerInterface = &(PARCSigningInterface) { + .GetCryptoHasher = (PARCCryptoHasher * (*)(void *))_GetCryptoHasher, + .SignDigest = (PARCSignature * (*)(void *, const PARCCryptoHash *))_SignDigest, + .GetSigningAlgorithm = (PARCSigningAlgorithm (*)(void *))_GetSigningAlgorithm, + .GetCryptoHashType = (PARCCryptoHashType (*)(void *))_GetCryptoHashType, + .GetKeyStore = (PARCKeyStore * (*)(void *))_GetKeyStore, +}; + +LONGBOW_TEST_RUNNER(parc_Signer) +{ + LONGBOW_RUN_TEST_FIXTURE(Global); +} + +// The Test Runner calls this function once before any Test Fixtures are run. +LONGBOW_TEST_RUNNER_SETUP(parc_Signer) +{ + parcMemory_SetInterface(&PARCSafeMemoryAsPARCMemory); + return LONGBOW_STATUS_SUCCEEDED; +} + +// The Test Runner calls this function once after all the Test Fixtures are run. +LONGBOW_TEST_RUNNER_TEARDOWN(parc_Signer) +{ + return LONGBOW_STATUS_SUCCEEDED; +} + +LONGBOW_TEST_FIXTURE(Global) +{ + LONGBOW_RUN_TEST_CASE(Global, parcSigner_Create); + LONGBOW_RUN_TEST_CASE(Global, parcSigner_AcquireRelease); + LONGBOW_RUN_TEST_CASE(Global, parcSigner_CreateKeyId); + LONGBOW_RUN_TEST_CASE(Global, parcSigner_CreatePublicKey); + LONGBOW_RUN_TEST_CASE(Global, parcSigner_GetCryptoHasher); + LONGBOW_RUN_TEST_CASE(Global, parcSigner_SignDigest); + LONGBOW_RUN_TEST_CASE(Global, parcSigner_GetSigningAlgorithm); + LONGBOW_RUN_TEST_CASE(Global, parcSigner_GetCryptoHashType); + LONGBOW_RUN_TEST_CASE(Global, parcSigner_GetKeyStore); +} + +LONGBOW_TEST_FIXTURE_SETUP(Global) +{ + parcSecurity_Init(); + return LONGBOW_STATUS_SUCCEEDED; +} + +LONGBOW_TEST_FIXTURE_TEARDOWN(Global) +{ + parcSecurity_Fini(); + if (parcSafeMemory_ReportAllocation(STDOUT_FILENO) != 0) { + printf("('%s' leaks memory by %d (allocs - frees)) ", longBowTestCase_GetName(testCase), parcMemory_Outstanding()); + return LONGBOW_STATUS_MEMORYLEAK; + } + return LONGBOW_STATUS_SUCCEEDED; +} + +LONGBOW_TEST_CASE(Global, parcSigner_Create) +{ + _MockSigner *mock = _createSigner(); + PARCSigner *signer = parcSigner_Create(mock, _MockSignerInterface); + _mockSigner_Release(&mock); + + assertNotNull(signer, "Expected non-null signer"); + + parcSigner_Release(&signer); +} + +LONGBOW_TEST_CASE(Global, parcSigner_AcquireRelease) +{ + _MockSigner *mock = _createSigner(); + PARCSigner *signer = parcSigner_Create(mock, _MockSignerInterface); + _mockSigner_Release(&mock); + + assertNotNull(signer, "Expected non-null signer"); + + parcObjectTesting_AssertAcquireReleaseContract(parcSigner_Acquire, signer); + + parcSigner_Release(&signer); + assertNull(signer, "Expected null result from parcSigner_Release();"); +} + +LONGBOW_TEST_CASE(Global, parcSigner_CreateKeyId) +{ + _MockSigner *mock = _createSigner(); + PARCSigner *signer = parcSigner_Create(mock, _MockSignerInterface); + _mockSigner_Release(&mock); + + PARCKeyId *keyId = parcSigner_CreateKeyId(signer); + + assertNotNull(keyId, "Expected non-NULL PARCKeyId"); + + parcKeyId_Release(&keyId); + parcSigner_Release(&signer); +} + +LONGBOW_TEST_CASE(Global, parcSigner_CreatePublicKey) +{ + _MockSigner *mock = _createSigner(); + PARCSigner *signer = parcSigner_Create(mock, _MockSignerInterface); + + PARCKey *key = parcSigner_CreatePublicKey(signer); + + // Compute the real value + PARCCryptoHash *hash = parcKeyStore_GetVerifierKeyDigest(mock->keyStore); + PARCKeyId *keyid = parcKeyId_Create(parcCryptoHash_GetDigest(hash)); + PARCBuffer *derEncodedKey = parcKeyStore_GetDEREncodedPublicKey(mock->keyStore); + + PARCKey *expectedKey = parcKey_CreateFromDerEncodedPublicKey(keyid, + parcSigner_GetSigningAlgorithm(signer), + derEncodedKey); + + parcBuffer_Release(&derEncodedKey); + parcKeyId_Release(&keyid); + + parcCryptoHash_Release(&hash); + + assertTrue(parcKey_Equals(key, expectedKey), "Expected public keys to be computed equally."); + + parcKey_Release(&key); + parcKey_Release(&expectedKey); + parcSigner_Release(&signer); + _mockSigner_Release(&mock); +} + +LONGBOW_TEST_CASE(Global, parcSigner_GetCryptoHasher) +{ + _MockSigner *mock = _createSigner(); + PARCSigner *signer = parcSigner_Create(mock, _MockSignerInterface); + _mockSigner_Release(&mock); + + PARCCryptoHasher *hasher = parcSigner_GetCryptoHasher(signer); + + assertNotNull(hasher, "Expected non-NULL PARCCryptoHasher"); + + parcSigner_Release(&signer); +} + +LONGBOW_TEST_CASE(Global, parcSigner_SignDigest) +{ + _MockSigner *mock = _createSigner(); + PARCSigner *signer = parcSigner_Create(mock, _MockSignerInterface); + _mockSigner_Release(&mock); + + PARCBuffer *buffer = parcBuffer_Allocate(10); + PARCCryptoHash *hash = parcCryptoHash_Create(PARCCryptoHashType_SHA256, buffer); + PARCSignature *signature = parcSigner_SignDigest(signer, hash); + + assertNotNull(signature, "Expected non-NULL PARCSignature"); + + PARCBuffer *bits = parcSignature_GetSignature(signature); + char *bitstring = parcBuffer_ToString(bits); + char *expectedString = FAKE_SIGNATURE; + assertTrue(strcmp(bitstring, expectedString) == 0, "Expected the forced signature as output %s, got %s", expectedString, bitstring); + parcMemory_Deallocate(&bitstring); + + parcCryptoHash_Release(&hash); + parcBuffer_Release(&buffer); + parcSignature_Release(&signature); + parcSigner_Release(&signer); +} + +LONGBOW_TEST_CASE(Global, parcSigner_GetSigningAlgorithm) +{ + _MockSigner *mock = _createSigner(); + PARCSigner *signer = parcSigner_Create(mock, _MockSignerInterface); + _mockSigner_Release(&mock); + + PARCSigningAlgorithm alg = parcSigner_GetSigningAlgorithm(signer); + assertTrue(PARCSigningAlgorithm_ECDSA == alg, "Expected PARCSigningAlgorithm_ECDSA algorithm, got %d", alg); + + parcSigner_Release(&signer); +} + +LONGBOW_TEST_CASE(Global, parcSigner_GetCryptoHashType) +{ + _MockSigner *mock = _createSigner(); + PARCSigner *signer = parcSigner_Create(mock, _MockSignerInterface); + _mockSigner_Release(&mock); + + PARCCryptoHashType type = parcSigner_GetCryptoHashType(signer); + assertTrue(PARCCryptoHashType_SHA256 == type, "Expected PARCCryptoHashType_SHA256 algorithm, got %d", type); + + parcSigner_Release(&signer); +} + +LONGBOW_TEST_CASE(Global, parcSigner_GetKeyStore) +{ + _MockSigner *mock = _createSigner(); + PARCSigner *signer = parcSigner_Create(mock, _MockSignerInterface); + _mockSigner_Release(&mock); + + PARCKeyStore *keyStore = parcSigner_GetKeyStore(signer); + assertNotNull(keyStore, "Expected non-NULL PARCKeyStore"); + + parcSigner_Release(&signer); +} + +int +main(int argc, char *argv[]) +{ + LongBowRunner *testRunner = LONGBOW_TEST_RUNNER_CREATE(parc_Signer); + int exitStatus = LONGBOW_TEST_MAIN(argc, argv, testRunner); + longBowTestRunner_Destroy(&testRunner); + exit(exitStatus); +} -- cgit 1.2.3-korg