From 63e47cd7180a46635ed08a80e3b1bcb17c3b8a58 Mon Sep 17 00:00:00 2001 From: Alberto Compagno Date: Wed, 13 Feb 2019 16:34:18 +0100 Subject: Reintroduced for backward compatibility the old api for signing packets that allocates the buffer holding the signature. Change-Id: I7ee9089b5cb1ec21fd0c5c27f9ee391cc294266b Signed-off-by: Alberto Compagno --- libparc/parc/security/parc_CryptoSuite.c | 2 +- libparc/parc/security/parc_Pkcs12KeyStore.c | 2 +- libparc/parc/security/parc_PublicKeySigner.c | 89 +++++++++++++++++++++++-- libparc/parc/security/parc_Signer.c | 15 ++++- libparc/parc/security/parc_Signer.h | 54 +++++++++++++-- libparc/parc/security/parc_SymmetricKeySigner.c | 21 +++++- 6 files changed, 165 insertions(+), 18 deletions(-) diff --git a/libparc/parc/security/parc_CryptoSuite.c b/libparc/parc/security/parc_CryptoSuite.c index 7d7920f5..71a4531b 100644 --- a/libparc/parc/security/parc_CryptoSuite.c +++ b/libparc/parc/security/parc_CryptoSuite.c @@ -54,7 +54,7 @@ parcCryptoSuite_GetSignatureSizeBytes(PARCCryptoSuite suite, int keyLengthBits) return keyLengthBytes; case PARCCryptoSuite_ECDSA_SHA256: - return keyLengthBytes*2 + 8; //Overhead added by ECDSA + return keyLengthBytes*2 + 8; //Overhead added by ECDSA case PARCCryptoSuite_HMAC_SHA256: // fallthrough case PARCCryptoSuite_HMAC_SHA512: // fallthrough diff --git a/libparc/parc/security/parc_Pkcs12KeyStore.c b/libparc/parc/security/parc_Pkcs12KeyStore.c index 12246593..55e5e9b5 100644 --- a/libparc/parc/security/parc_Pkcs12KeyStore.c +++ b/libparc/parc/security/parc_Pkcs12KeyStore.c @@ -255,7 +255,7 @@ parcPkcs12KeyStore_CreateFile( default: return result; } - + if (pkcs12 != NULL) { int fd = open(filename, O_CREAT | O_WRONLY | O_TRUNC, 0600); if (fd != -1) { diff --git a/libparc/parc/security/parc_PublicKeySigner.c b/libparc/parc/security/parc_PublicKeySigner.c index c44a9158..7d274398 100644 --- a/libparc/parc/security/parc_PublicKeySigner.c +++ b/libparc/parc/security/parc_PublicKeySigner.c @@ -165,7 +165,7 @@ _GetKeyStore(PARCPublicKeySigner *signer) return signer->keyStore; } -static inline int _SignDigestRSA(const PARCCryptoHash *digestToSign, PARCBuffer *privateKeyBuffer, int opensslDigestType, uint8_t * sig, uint32_t supplied_siglen, unsigned * sigLength) +static inline int _SignDigestRSA(const PARCCryptoHash *digestToSign, PARCBuffer *privateKeyBuffer, int opensslDigestType, uint8_t * sig, unsigned * sigLength) { EVP_PKEY *privateKey = NULL; size_t keySize = parcBuffer_Remaining(privateKeyBuffer); @@ -173,7 +173,6 @@ static inline int _SignDigestRSA(const PARCCryptoHash *digestToSign, PARCBuffer privateKey = d2i_PrivateKey(EVP_PKEY_RSA, &privateKey, (const unsigned char **) &bytes, (long)keySize); RSA *rsa = EVP_PKEY_get1_RSA(privateKey); - //*sig = parcMemory_Allocate(RSA_size(rsa)); parcAssertNotNull(sig, "Expected pointer to a memory region for storing the signature %u. Pointer is NULL", RSA_size(rsa)); @@ -191,7 +190,7 @@ static inline int _SignDigestRSA(const PARCCryptoHash *digestToSign, PARCBuffer return result; } -static inline int _SignDigestECDSA(const PARCCryptoHash *digestToSign, PARCBuffer *privateKeyBuffer, int opensslDigestType, uint8_t * sig, uint32_t supplied_siglen, unsigned * sigLength) +static inline int _SignDigestECDSA(const PARCCryptoHash *digestToSign, PARCBuffer *privateKeyBuffer, int opensslDigestType, uint8_t * sig, unsigned * sigLength) { EVP_PKEY *privateKey = NULL; size_t keySize = parcBuffer_Remaining(privateKeyBuffer); @@ -216,7 +215,7 @@ static inline int _SignDigestECDSA(const PARCCryptoHash *digestToSign, PARCBuffe } static PARCSignature * -_SignDigest(PARCPublicKeySigner *signer, const PARCCryptoHash *digestToSign, uint8_t * signature_buf, uint32_t sig_len) +_SignDigestNoAlloc(PARCPublicKeySigner *signer, const PARCCryptoHash *digestToSign, uint8_t * signature_buf, uint32_t sig_len) { parcSecurity_AssertIsInitialized(); @@ -244,10 +243,10 @@ _SignDigest(PARCPublicKeySigner *signer, const PARCCryptoHash *digestToSign, uin switch (signer->signingAlgorithm) { case PARCSigningAlgorithm_RSA: - _SignDigestRSA(digestToSign, privateKeyBuffer, opensslDigestType, signature_buf, sig_len, &signLenght); + _SignDigestRSA(digestToSign, privateKeyBuffer, opensslDigestType, signature_buf, &signLenght); break; case PARCSigningAlgorithm_ECDSA: - _SignDigestECDSA(digestToSign, privateKeyBuffer, opensslDigestType, signature_buf, sig_len, &signLenght); + _SignDigestECDSA(digestToSign, privateKeyBuffer, opensslDigestType, signature_buf, &signLenght); break; default: return NULL; @@ -265,6 +264,81 @@ _SignDigest(PARCPublicKeySigner *signer, const PARCCryptoHash *digestToSign, uin return signature; } +static PARCSignature * +_SignDigest(PARCPublicKeySigner *signer, const PARCCryptoHash *digestToSign) +{ + parcSecurity_AssertIsInitialized(); + + parcAssertNotNull(signer, "Parameter must be non-null CCNxFileKeystore"); + parcAssertNotNull(digestToSign, "Buffer to sign must not be null"); + + // TODO: what is the best way to expose this? + PARCKeyStore *keyStore = signer->keyStore; + PARCBuffer *privateKeyBuffer = parcKeyStore_GetDEREncodedPrivateKey(keyStore); + + int opensslDigestType; + unsigned signLenght; + + uint8_t * signature_buf; + + switch (parcCryptoHash_GetDigestType(digestToSign)) { + case PARCCryptoHashType_SHA256: + opensslDigestType = NID_sha256; + break; + case PARCCryptoHashType_SHA512: + opensslDigestType = NID_sha512; + break; + default: + parcTrapUnexpectedState("Unknown digest type: %s", + parcCryptoHashType_ToString(parcCryptoHash_GetDigestType(digestToSign))); + } + + switch (signer->signingAlgorithm) { + case PARCSigningAlgorithm_RSA: + { + EVP_PKEY *privateKey = NULL; + size_t keySize = parcBuffer_Remaining(privateKeyBuffer); + uint8_t *bytes = parcBuffer_Overlay(privateKeyBuffer, keySize); + privateKey = d2i_PrivateKey(EVP_PKEY_RSA, &privateKey, (const unsigned char **) &bytes, (long)keySize); + + RSA *rsa = EVP_PKEY_get1_RSA(privateKey); + + uint8_t * sig = parcMemory_Allocate(RSA_size(rsa)); + _SignDigestRSA(digestToSign, privateKeyBuffer, opensslDigestType, signature_buf, &signLenght); + RSA_free(rsa); + break; + } + case PARCSigningAlgorithm_ECDSA: + { + //Need to retrieve the public key to know how much to allocate to hold the signature + EVP_PKEY *privateKey = NULL; + size_t keySize = parcBuffer_Remaining(privateKeyBuffer); + uint8_t *bytes = parcBuffer_Overlay(privateKeyBuffer, keySize); + privateKey = d2i_PrivateKey(EVP_PKEY_EC, &privateKey, (const unsigned char **) &bytes, (long)keySize); + + EC_KEY *ec_key = EVP_PKEY_get1_EC_KEY(privateKey); + + uint8_t * sig = parcMemory_Allocate(ECDSA_size(ec_key)); + _SignDigestECDSA(digestToSign, privateKeyBuffer, opensslDigestType, signature_buf, &signLenght); + EC_KEY_free(ec_key); + break; + } + default: + return NULL; + } + + PARCBuffer *bbSign = parcBuffer_Wrap(signature_buf, signLenght, 0, signLenght); + + PARCSignature *signature = + parcSignature_Create(_GetSigningAlgorithm(signer), + parcCryptoHash_GetDigestType(digestToSign), + bbSign + ); + parcBuffer_Release(&bbSign); + parcBuffer_Release(&privateKeyBuffer); + return signature; +} + static size_t _GetSignatureSize(PARCPublicKeySigner *signer) { @@ -313,7 +387,8 @@ _GetSignatureSize(PARCPublicKeySigner *signer) PARCSigningInterface *PARCPublicKeySignerAsSigner = &(PARCSigningInterface) { .GetCryptoHasher = (PARCCryptoHasher * (*)(void *))_GetCryptoHasher, - .SignDigest = (PARCSignature * (*)(void *, const PARCCryptoHash *, uint8_t *, uint32_t))_SignDigest, + .SignDigestNoAlloc = (PARCSignature * (*)(void *, const PARCCryptoHash *, uint8_t *, uint32_t))_SignDigestNoAlloc, + .SignDigest = (PARCSignature * (*)(void *, const PARCCryptoHash *))_SignDigest, .GetSigningAlgorithm = (PARCSigningAlgorithm (*)(void *))_GetSigningAlgorithm, .GetCryptoHashType = (PARCCryptoHashType (*)(void *))_GetCryptoHashType, .GetKeyStore = (PARCKeyStore * (*)(void *))_GetKeyStore, diff --git a/libparc/parc/security/parc_Signer.c b/libparc/parc/security/parc_Signer.c index 2d3c7465..4015875a 100644 --- a/libparc/parc/security/parc_Signer.c +++ b/libparc/parc/security/parc_Signer.c @@ -108,12 +108,21 @@ parcSigner_GetCryptoHasher(const PARCSigner *signer) } PARCSignature * -parcSigner_SignDigest(const PARCSigner *signer, const PARCCryptoHash *parcDigest, uint8_t * signature, uint32_t sig_len) +parcSigner_SignDigestNoAlloc(const PARCSigner *signer, const PARCCryptoHash *parcDigest, uint8_t * signature, uint32_t sig_len) { parcSigner_OptionalAssertValid(signer); parcAssertNotNull(parcDigest, "parcDigest to sign must not be null"); - return signer->interface->SignDigest(signer->instance, parcDigest, signature, sig_len); + return signer->interface->SignDigestNoAlloc(signer->instance, parcDigest, signature, sig_len); +} + +PARCSignature * +parcSigner_SignDigest(const PARCSigner *signer, const PARCCryptoHash *parcDigest) +{ + parcSigner_OptionalAssertValid(signer); + + parcAssertNotNull(parcDigest, "parcDigest to sign must not be null"); + return signer->interface->SignDigest(signer->instance, parcDigest); } PARCSignature * @@ -129,7 +138,7 @@ parcSigner_SignBuffer(const PARCSigner *signer, const PARCBuffer *buffer, uint8_ PARCCryptoHash *hash = parcCryptoHasher_Finalize(hasher); parcCryptoHasher_Release(&hasher); - PARCSignature *signature = parcSigner_SignDigest(signer, hash, signature_buf, sig_len); + PARCSignature *signature = parcSigner_SignDigestNoAlloc(signer, hash, signature_buf, sig_len); parcCryptoHash_Release(&hash); return signature; diff --git a/libparc/parc/security/parc_Signer.h b/libparc/parc/security/parc_Signer.h index 9bb0c6a1..3e9fb592 100644 --- a/libparc/parc/security/parc_Signer.h +++ b/libparc/parc/security/parc_Signer.h @@ -77,7 +77,8 @@ typedef struct parc_signer_interface { PARCCryptoHasher *(*GetCryptoHasher)(void *interfaceContext); /** - * Compute the signature of the given PARCCryptoHash. + * Compute the signature of the given PARCCryptoHash. This api Does not allocate the buffer holding the signature, it must + * be passed from the caller. * * Equivalent of (for rsa/sha256) * openssl rsautl -sign -inkey test_rsa_key.pem -in infile_digest -out infile.sig @@ -89,7 +90,22 @@ typedef struct parc_signer_interface { * * @return A pointer to a PARCSignature instance that must be released via parcSignature_Release() */ - PARCSignature *(*SignDigest)(void *interfaceContext, const PARCCryptoHash * parcDigest, uint8_t * signature, uint32_t sign_len); + PARCSignature *(*SignDigestNoAlloc)(void *interfaceContext, const PARCCryptoHash * parcDigest, uint8_t * signature, uint32_t sign_len); + + /** + * Compute the signature of the given PARCCryptoHash. This api allocate the buffer for the signature + * + * Equivalent of (for rsa/sha256) + * openssl rsautl -sign -inkey test_rsa_key.pem -in infile_digest -out infile.sig + * + * @param [in] interfaceContextPtr A pointer to a concrete PARCSigner instance. + * @param [in] hashToSign The output of the given digest to sign + * @param [in] signature Portion of memory that will contain the signature (expected to be large enough to contain the signature) + * @param [in] sig_len Size in bytes of the supplied buffer + * + * @return A pointer to a PARCSignature instance that must be released via parcSignature_Release() + */ + PARCSignature *(*SignDigest)(void *interfaceContext, const PARCCryptoHash * parcDigest); /** * Return the PARSigningAlgorithm used for signing with the given `PARCSigner` @@ -278,7 +294,37 @@ PARCKey *parcSigner_CreatePublicKey(PARCSigner *signer); PARCCryptoHasher *parcSigner_GetCryptoHasher(const PARCSigner *signer); /** - * Compute the signature of the given PARCCryptoHash. + * Compute the signature of the given PARCCryptoHash. This api Does not allocate the buffer holding the signature, it must + * be passed from the caller. + * + * Equivalent of (for rsa/sha256) + * openssl rsautl -sign -inkey test_rsa_key.pem -in infile_digest -out infile.sig + * + * @param [in] signer A pointer to a PARCSigner instance. + * @param [in] hashToSign The output of the given digest + * @param [in] signature Portion of memory that will contain the signature (expected to be large enough to contain the signature) + * @param [in] sig_len Size in bytes of the supplied buffer + * + * @return A pointer to a PARCSignature instance that must be released via parcSignature_Release() + * + * Example: + * @code + * { + * PARCSigner *signer = parcSigner_Create(publicKeySigner, PARCRSASignerAsSigner); + * + * PARCCryptoHasher *hasher = parcSigner_GetCryptoHasher(signer); + * parcCryptoHasher_Init(hasher); + * parcCryptoHasher_Update_Bytes(hasher, &block->memory[relativePosition], length); + * PARCCryptoHash *hashToSign = parcCryptoHasher_Finalize(hasher); + * + * PARCSignature signature = parcSigner_SignDigest(signer, hashToSign); + * } + * @endcode + */ +PARCSignature *parcSigner_SignDigestNoAlloc(const PARCSigner *signer, const PARCCryptoHash *hashToSign, uint8_t * signature, uint32_t sig_len); + +/** + * Compute the signature of the given PARCCryptoHash. This function allocate the buffer holding the signature. * * Equivalent of (for rsa/sha256) * openssl rsautl -sign -inkey test_rsa_key.pem -in infile_digest -out infile.sig @@ -304,7 +350,7 @@ PARCCryptoHasher *parcSigner_GetCryptoHasher(const PARCSigner *signer); * } * @endcode */ -PARCSignature *parcSigner_SignDigest(const PARCSigner *signer, const PARCCryptoHash *hashToSign, uint8_t * signature, uint32_t sig_len); +PARCSignature *parcSigner_SignDigest(const PARCSigner *signer, const PARCCryptoHash *hashToSign); /** * Compute the signature of a given `PARCBuffer`. diff --git a/libparc/parc/security/parc_SymmetricKeySigner.c b/libparc/parc/security/parc_SymmetricKeySigner.c index bfb98e42..5c2db778 100644 --- a/libparc/parc/security/parc_SymmetricKeySigner.c +++ b/libparc/parc/security/parc_SymmetricKeySigner.c @@ -261,7 +261,7 @@ _GetSignatureSize(PARCSymmetricKeySigner *signer) * @param hashToSign is the HMAC computed by the our PARCCryptoHasher. */ static PARCSignature * -_signDigest(PARCSymmetricKeySigner *interfaceContext, const PARCCryptoHash *hashToSign, uint8_t * signature, uint32_t sig_len) +_signDigestNoAlloc(PARCSymmetricKeySigner *interfaceContext, const PARCCryptoHash *hashToSign, uint8_t * signature, uint32_t sig_len) { // The digest computed via our hash function (hmac) is the actual signature. // just need to wrap it up with the right parameters. @@ -271,10 +271,27 @@ _signDigest(PARCSymmetricKeySigner *interfaceContext, const PARCCryptoHash *hash return result; } +/** + * wrap the HMAC in digestToSign in a PARCSignature. Allocate the buffer for the hash. + * + * @param hashToSign is the HMAC computed by the our PARCCryptoHasher. + */ +static PARCSignature * +_signDigest(PARCSymmetricKeySigner *interfaceContext, const PARCCryptoHash *hashToSign) +{ + // The digest computed via our hash function (hmac) is the actual signature. + // just need to wrap it up with the right parameters. + PARCBuffer *signatureBits = parcBuffer_Copy(parcCryptoHash_GetDigest(hashToSign)); + PARCSignature *result = parcSignature_Create(_getSigningAlgorithm(interfaceContext), parcCryptoHash_GetDigestType(hashToSign), signatureBits); + parcBuffer_Release(&signatureBits); + return result; +} + PARCSigningInterface *PARCSymmetricKeySignerAsSigner = &(PARCSigningInterface) { .GetCryptoHashType = (PARCCryptoHashType (*)(void *))_getCryptoHashType, .GetCryptoHasher = (PARCCryptoHasher * (*)(void *))_getCryptoHasher, - .SignDigest = (PARCSignature * (*)(void *, const PARCCryptoHash *, uint8_t *, uint32_t))_signDigest, + .SignDigestNoAlloc = (PARCSignature * (*)(void *, const PARCCryptoHash *, uint8_t *, uint32_t))_signDigestNoAlloc, + .SignDigest = (PARCSignature * (*)(void *, const PARCCryptoHash *))_signDigest, .GetSigningAlgorithm = (PARCSigningAlgorithm (*)(void *))_getSigningAlgorithm, .GetKeyStore = (PARCKeyStore * (*)(void *))_getKeyStore, .GetSignatureSize = (size_t (*)(void *))_GetSignatureSize -- cgit 1.2.3-korg