/** * Get the certificate digest from the openssl command line pkcs12 */ LONGBOW_TEST_CASE(openssl_commandline, parcPkcs12KeyStore_GetCertificateDigest) { PARCPkcs12KeyStore *publicKeyStore = parcPkcs12KeyStore_Open("test_rsa.p12", "blueberry", PARC_HASH_SHA256); PARCKeyStore *keyStore = parcKeyStore_Create(publicKeyStore, PARCPkcs12KeyStoreAsKeyStore); parcPkcs12KeyStore_Release(&publicKeyStore); PARCPublicKeySigner *publicKeySigner = parcPublicKeySigner_Create(keyStore, PARCSigningAlgorithm_RSA, PARC_HASH_SHA256); parcKeyStore_Release(&keyStore); PARCSigner *signer = parcSigner_Create(publicKeySigner, PARCPublicKeySignerAsSigner); parcPublicKeySigner_Release(&publicKeySigner); assertNotNull(signer, "Got null result from opening openssl pkcs12 file"); PARCCryptoHash *cert_digest = parcKeyStore_GetCertificateDigest(parcSigner_GetKeyStore(signer)); assertNotNull(cert_digest, "got null public key digest for external pkcs12"); // read in the "truth" from the command line utilities int fd = open("test_rsa_crt_sha256.bin", O_RDONLY); uint8_t true_digest[SHA256_DIGEST_LENGTH]; ssize_t read_bytes = read(fd, true_digest, SHA256_DIGEST_LENGTH); close(fd); assertTrue(read_bytes == SHA256_DIGEST_LENGTH, "could not read %d byte digest from test_rsa_pub_sha256.bin", SHA256_DIGEST_LENGTH); const uint8_t *bb_buffer = parcByteArray_Array(parcBuffer_Array(parcCryptoHash_GetDigest(cert_digest))); size_t bb_length = parcBuffer_Remaining(parcCryptoHash_GetDigest(cert_digest)); assertTrue(bb_length == SHA256_DIGEST_LENGTH, "Incorrect digest length returned from GetCertificateDigest: %zu", bb_length); assertTrue(memcmp(bb_buffer, true_digest, SHA256_DIGEST_LENGTH) == 0, "digests did not match"); parcSigner_Release(&signer); parcCryptoHash_Release(&cert_digest); }
LONGBOW_TEST_CASE(Global, parcCryptoHash_GetDigest) { int fd_buffer = open("test_digest_bytes_128.bin", O_RDONLY); int fd_truth = open("test_digest_bytes_128.sha256", O_RDONLY); assertFalse(fd_buffer < 0, "Could not open %s: %s", "test_digest_bytes_128.bin", strerror(errno)); assertFalse(fd_truth < 0, "Could not open %s: %s", "test_digest_bytes_128.sha256", strerror(errno)); uint8_t scratch[bufferLength]; ssize_t read_length = read(fd_truth, scratch, bufferLength); PARCCryptoHash *hashTruth = parcCryptoHash_CreateFromArray(PARC_HASH_SHA256, scratch, read_length); read_length = read(fd_buffer, scratch, bufferLength); PARCCryptoHasher *hasher = parcCryptoHasher_Create(PARC_HASH_SHA256); parcCryptoHasher_Init(hasher); parcCryptoHasher_UpdateBytes(hasher, scratch, read_length); PARCCryptoHash *hashTest = parcCryptoHasher_Finalize(hasher); assertTrue(parcBuffer_Equals(parcCryptoHash_GetDigest(hashTruth), parcCryptoHash_GetDigest(hashTest)), "Expected to be true"); parcCryptoHasher_Release(&hasher); parcCryptoHash_Release(&hashTruth); parcCryptoHash_Release(&hashTest); close(fd_buffer); close(fd_truth); }
LONGBOW_TEST_CASE(ccnx_internal, parcPkcs12KeyStore_GetCertificateDigest) { // create a file and open it const char *password = "******"; const char *subject = "alice"; bool result; result = parcPkcs12KeyStore_CreateFile(filename, password, subject, 1024, 32); assertTrue(result, "got error from parcPkcs12KeyStore_CreatePkcs12File"); PARCPkcs12KeyStore *publicKeyStore = parcPkcs12KeyStore_Open(filename, password, PARC_HASH_SHA256); assertNotNull(publicKeyStore, "Got null result from opening openssl pkcs12 file"); PARCKeyStore *keyStore = parcKeyStore_Create(publicKeyStore, PARCPkcs12KeyStoreAsKeyStore); parcPkcs12KeyStore_Release(&publicKeyStore); PARCCryptoHash *cert_digest = parcKeyStore_GetCertificateDigest(keyStore); assertNotNull(cert_digest, "got null public key digest for external pkcs12"); size_t bb_length = parcBuffer_Remaining(parcCryptoHash_GetDigest(cert_digest)); assertTrue(bb_length == SHA256_DIGEST_LENGTH, "Incorrect digest length returned from GetPublicKeyDigest: %zu", bb_length); parcKeyStore_Release(&keyStore); parcCryptoHash_Release(&cert_digest); }
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); }
CCNxInterestPayloadId * ccnxInterestPayloadId_CreateAsSHA256Hash(const PARCBuffer *data) { CCNxInterestPayloadId *result = parcObject_CreateInstance(CCNxInterestPayloadId); PARCCryptoHasher *hasher = parcCryptoHasher_Create(PARCCryptoHashType_SHA256); parcCryptoHasher_Init(hasher); parcCryptoHasher_UpdateBuffer(hasher, data); PARCCryptoHash *hash = parcCryptoHasher_Finalize(hasher); parcCryptoHasher_Release(&hasher); PARCBuffer *hashData = parcCryptoHash_GetDigest(hash); PARCBuffer *codedHash = parcBuffer_Allocate(parcBuffer_Capacity(hashData) + 1); parcBuffer_PutUint8(codedHash, CCNxInterestPayloadId_TypeCode_RFC6920_SHA256); parcBuffer_PutBuffer(codedHash, hashData); parcBuffer_Flip(codedHash); result->nameSegment = ccnxNameSegment_CreateTypeValue(CCNxNameLabelType_PAYLOADID, codedHash); parcBuffer_Release(&codedHash); parcCryptoHash_Release(&hash); return result; }
static PARCSignature * _SignDigest(PARCPublicKeySigner *signer, const PARCCryptoHash *digestToSign) { parcSecurity_AssertIsInitialized(); assertNotNull(signer, "Parameter must be non-null CCNxFileKeystore"); assertNotNull(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); 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, keySize); parcBuffer_Release(&privateKeyBuffer); RSA *rsa = EVP_PKEY_get1_RSA(privateKey); int opensslDigestType; switch (parcCryptoHash_GetDigestType(digestToSign)) { case PARCCryptoHashType_SHA256: opensslDigestType = NID_sha256; break; case PARCCryptoHashType_SHA512: opensslDigestType = NID_sha512; break; default: trapUnexpectedState("Unknown digest type: %s", parcCryptoHashType_ToString(parcCryptoHash_GetDigestType(digestToSign))); } uint8_t *sig = parcMemory_Allocate(RSA_size(rsa)); assertNotNull(sig, "parcMemory_Allocate(%u) returned NULL", RSA_size(rsa)); unsigned sigLength = 0; PARCBuffer *bb_digest = parcCryptoHash_GetDigest(digestToSign); int result = RSA_sign(opensslDigestType, (unsigned char *) parcByteArray_Array(parcBuffer_Array(bb_digest)), (int) parcBuffer_Remaining(bb_digest), sig, &sigLength, rsa); assertTrue(result == 1, "Got error from RSA_sign: %d", result); RSA_free(rsa); PARCBuffer *bbSign = parcBuffer_Allocate(sigLength); parcBuffer_Flip(parcBuffer_PutArray(bbSign, sigLength, sig)); parcMemory_Deallocate((void **) &sig); PARCSignature *signature = parcSignature_Create(_GetSigningAlgorithm(signer), parcCryptoHash_GetDigestType(digestToSign), bbSign ); parcBuffer_Release(&bbSign); return signature; }
/** * wrap the HMAC in digestToSign in a PARCSignature * * @param hashToSign is the HMAC computed by the our PARCCryptoHasher. */ static PARCSignature * _signDigest(void *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; }
/** * Return if the signature and key verify with the local hash. * * PRECONDITION: * - You know the signature and key are RSA. * * Example: * @code * <#example#> * @endcode */ static bool _parcInMemoryVerifier_RSAKey_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; RSA *rsa = EVP_PKEY_get1_RSA(unwrapped_key); if (rsa != NULL) { int openssl_digest_type; switch (parcCryptoHash_GetDigestType(localHash)) { case PARC_HASH_SHA256: openssl_digest_type = NID_sha256; break; case PARC_HASH_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 = RSA_verify(openssl_digest_type, (unsigned char *) parcByteArray_Array(parcBuffer_Array(parcCryptoHash_GetDigest(localHash))), (unsigned) parcBuffer_Remaining(parcCryptoHash_GetDigest(localHash)), sigbuffer + signatureOffset, signatureLength, rsa); RSA_free(rsa); } EVP_PKEY_free(unwrapped_key); if (success) { return true; } } return false; }