aboutsummaryrefslogtreecommitdiffstats
path: root/libparc/parc/security/parc_InMemoryVerifier.c
diff options
context:
space:
mode:
Diffstat (limited to 'libparc/parc/security/parc_InMemoryVerifier.c')
-rw-r--r--libparc/parc/security/parc_InMemoryVerifier.c82
1 files changed, 81 insertions, 1 deletions
diff --git a/libparc/parc/security/parc_InMemoryVerifier.c b/libparc/parc/security/parc_InMemoryVerifier.c
index e5a9ba06..e5946d33 100644
--- a/libparc/parc/security/parc_InMemoryVerifier.c
+++ b/libparc/parc/security/parc_InMemoryVerifier.c
@@ -34,6 +34,8 @@
#include <parc/algol/parc_Memory.h>
#include <openssl/x509v3.h>
+#include <openssl/ecdsa.h>
+
struct parc_inmemory_verifier {
PARCCryptoHasher *hasher_sha256;
@@ -124,6 +126,17 @@ _parcInMemoryVerifier_AllowedCryptoSuite(void *interfaceContext, PARCKeyId *keyi
}
break;
+ case PARCSigningAlgorithm_ECDSA:
+ switch (suite) {
+ case PARCCryptoSuite_ECDSA_SHA256:
+ return true;
+
+ default:
+ return false;
+ }
+ break;
+
+
case PARCSigningAlgorithm_DSA:
switch (suite) {
default:
@@ -152,6 +165,8 @@ _parcInMemoryVerifier_AllowedCryptoSuite(void *interfaceContext, PARCKeyId *keyi
static bool _parcInMemoryVerifier_RSAKey_Verify(PARCInMemoryVerifier *verifier, PARCCryptoHash *localHash,
PARCSignature *signatureToVerify, PARCBuffer *derEncodedKey);
+static bool _parcInMemoryVerifier_ECDSAKey_Verify(PARCInMemoryVerifier *verifier, PARCCryptoHash *localHash,
+ PARCSignature *signatureToVerify, PARCBuffer *derEncodedKey);
/**
* The signature verifies if:
* 0) we know the key for keyid
@@ -195,6 +210,9 @@ _parcInMemoryVerifier_VerifyDigest(void *interfaceContext, PARCKeyId *keyid, PAR
case PARCSigningAlgorithm_RSA:
return _parcInMemoryVerifier_RSAKey_Verify(verifier, locallyComputedHash, objectSignature, parcKey_GetKey(key));
+ case PARCSigningAlgorithm_ECDSA:
+ return _parcInMemoryVerifier_ECDSAKey_Verify(verifier, locallyComputedHash, objectSignature, parcKey_GetKey(key));
+
case PARCSigningAlgorithm_DSA:
trapNotImplemented("DSA not supported");
break;
@@ -295,7 +313,69 @@ _parcInMemoryVerifier_RSAKey_Verify(PARCInMemoryVerifier *verifier, PARCCryptoHa
}
EVP_PKEY_free(unwrapped_key);
- if (success) {
+ if (success == 1) {
+ return true;
+ }
+ }
+ return false;
+}
+
+/**
+ * Return if the signature and key verify with the local hash.
+ *
+ * PRECONDITION:
+ * - You know the signature and key are ECDSA.
+ *
+ * Example:
+ * @code
+ * <#example#>
+ * @endcode
+ */
+static bool
+_parcInMemoryVerifier_ECDSAKey_Verify(PARCInMemoryVerifier *verifier, PARCCryptoHash *localHash,
+ PARCSignature *signatureToVerify, PARCBuffer *derEncodedKey)
+{
+ const uint8_t *der_bytes = parcByteArray_Array(parcBuffer_Array(derEncodedKey));
+
+ long der_length = parcBuffer_Remaining(derEncodedKey);
+ EVP_PKEY *unwrapped_key = d2i_PUBKEY(NULL, &der_bytes, der_length);
+
+ if (unwrapped_key != NULL) {
+ int success = 0;
+ EC_KEY *ec_key = EVP_PKEY_get1_EC_KEY(unwrapped_key);
+
+ if (ec_key != NULL) {
+ int openssl_digest_type;
+
+ switch (parcCryptoHash_GetDigestType(localHash)) {
+ case PARCCryptoHashType_SHA256:
+ openssl_digest_type = NID_sha256;
+ break;
+ case PARCCryptoHashType_SHA512:
+ openssl_digest_type = NID_sha512;
+ break;
+ default:
+ trapUnexpectedState("Unknown digest type: %s",
+ parcCryptoHashType_ToString(parcCryptoHash_GetDigestType(localHash)));
+ }
+
+ PARCBuffer *sigbits = parcSignature_GetSignature(signatureToVerify);
+ PARCByteArray *bytearray = parcBuffer_Array(sigbits);
+ unsigned signatureLength = (unsigned) parcBuffer_Remaining(sigbits);
+ uint8_t *sigbuffer = parcByteArray_Array(bytearray);
+ size_t signatureOffset = parcBuffer_ArrayOffset(sigbits);
+
+ success = ECDSA_verify(openssl_digest_type,
+ (unsigned char *) parcByteArray_Array(parcBuffer_Array(parcCryptoHash_GetDigest(localHash))),
+ (unsigned) parcBuffer_Remaining(parcCryptoHash_GetDigest(localHash)),
+ sigbuffer + signatureOffset,
+ signatureLength,
+ ec_key);
+ EC_KEY_free(ec_key);
+ }
+ EVP_PKEY_free(unwrapped_key);
+
+ if (success == 1) {
return true;
}
}