Reintroduced for backward compatibility the old api for signing packets that allocate... 70/17570/1
authorAlberto Compagno <[email protected]>
Wed, 13 Feb 2019 15:34:18 +0000 (16:34 +0100)
committerAlberto Compagno <[email protected]>
Wed, 13 Feb 2019 15:34:18 +0000 (16:34 +0100)
Change-Id: I7ee9089b5cb1ec21fd0c5c27f9ee391cc294266b
Signed-off-by: Alberto Compagno <[email protected]>
libparc/parc/security/parc_CryptoSuite.c
libparc/parc/security/parc_Pkcs12KeyStore.c
libparc/parc/security/parc_PublicKeySigner.c
libparc/parc/security/parc_Signer.c
libparc/parc/security/parc_Signer.h
libparc/parc/security/parc_SymmetricKeySigner.c

index 7d7920f..71a4531 100644 (file)
@@ -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
index 1224659..55e5e9b 100644 (file)
@@ -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) {
index c44a915..7d27439 100644 (file)
@@ -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,
index 2d3c746..4015875 100644 (file)
@@ -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;
index 9bb0c6a..3e9fb59 100644 (file)
@@ -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`.
index bfb98e4..5c2db77 100644 (file)
@@ -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