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; }
PARCHashCode parcBuffer_HashCode(const PARCBuffer *buffer) { PARCHashCode result = 0; size_t remaining = parcBuffer_Remaining(buffer); if (remaining > 0) { result = parcHashCode_Hash(parcBuffer_Overlay((PARCBuffer *) buffer, 0), parcBuffer_Remaining(buffer)); } return result; }
PARCBuffer * parcBuffer_PutBuffer(PARCBuffer *result, const PARCBuffer *buffer) { parcBuffer_OptionalAssertValid(buffer); assertTrue(parcBuffer_Remaining(result) >= parcBuffer_Remaining(buffer), "Buffer overflow. %zd bytes remaining, %zd required.", parcBuffer_Remaining(result), parcBuffer_Remaining(buffer)); size_t length = parcBuffer_Remaining(buffer); parcByteArray_ArrayCopy(result->array, _effectivePosition(result), buffer->array, _effectivePosition(buffer), length); parcBuffer_SetPosition(result, parcBuffer_Position(result) + length); 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; }
/** * Given a CCNxName, a directory path, and a requested chunk number, create a directory listing and return the specified * chunk of the directory listing as the payload of a newly created CCNxContentObject. * The new CCnxContentObject must eventually be released by calling ccnxContentObject_Release(). * * @param [in] name The CCNxName to use when creating the new CCNxContentObject. * @param [in] directoryPath The directory whose contents are being listed. * @param [in] requestedChunkNumber The number of the requested chunk from the complete directory listing. * * @return A new CCNxContentObject instance containing the request chunk of the directory listing. */ static CCNxContentObject * _createListResponse(CCNxName *name, const char *directoryPath, uint64_t requestedChunkNumber) { CCNxContentObject *result = NULL; PARCBuffer *directoryList = tutorialFileIO_CreateDirectoryListing(directoryPath); uint64_t totalChunksInDirList = _getNumberOfChunksRequired(parcBuffer_Limit(directoryList), tutorialCommon_ChunkSize); if (requestedChunkNumber < totalChunksInDirList) { // Set the buffer's position to the start of the desired chunk. parcBuffer_SetPosition(directoryList, (requestedChunkNumber * tutorialCommon_ChunkSize)); // See if we have more than 1 chunk's worth of data to in the buffer. If so, set the buffer's limit // to the end of the chunk. size_t chunkLen = parcBuffer_Remaining(directoryList); if (chunkLen > tutorialCommon_ChunkSize) { parcBuffer_SetLimit(directoryList, parcBuffer_Position(directoryList) + tutorialCommon_ChunkSize); } printf("tutorialServer: Responding to 'list' command with chunk %ld/%ld\n", (unsigned long) requestedChunkNumber, (unsigned long) totalChunksInDirList); // Calculate the final chunk number uint64_t finalChunkNumber = (totalChunksInDirList > 0) ? totalChunksInDirList - 1 : 0; // the final chunk, 0-based // At this point, dirListBuf has its position and limit set to the beginning and end of the // specified chunk. result = _createContentObject(name, directoryList, finalChunkNumber); } parcBuffer_Release(&directoryList); return result; }
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(ccnx_internal, parcPkcs12KeyStore_GetEncodedCertificate) { // 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); PARCBuffer *certificate_der = parcKeyStore_GetDEREncodedCertificate(keyStore); assertNotNull(certificate_der, "got null public key digest for external pkcs12"); // 557 (64-bit) and 553 (32-bit) are pre-etermined sizes of how big a DER encoded // certificate with a 1024-bit key should be size_t expectedMinimumLength = 545; size_t expectedMaximumLength = 560; size_t bb_length = parcBuffer_Remaining(certificate_der); assertTrue(expectedMinimumLength <= bb_length && bb_length <= expectedMaximumLength, "Digest unexpected size: got %zu expected %zu - %zu", bb_length, expectedMinimumLength, expectedMaximumLength); parcKeyStore_Release(&keyStore); parcBuffer_Release(&certificate_der); }
static PARCBufferComposer * _buildStringString(const PARCJSONValue *value, PARCBufferComposer *composer, bool compact) { parcBufferComposer_PutChar(composer, '"'); while (parcBuffer_Remaining(value->value.string)) { uint8_t c = parcBuffer_GetUint8(value->value.string); if (c == '"') { parcBufferComposer_PutString(composer, "\\\""); } else if (c == '\b') { parcBufferComposer_PutString(composer, "\\b"); } else if (c == '\f') { parcBufferComposer_PutString(composer, "\\f"); } else if (c == '\n') { parcBufferComposer_PutString(composer, "\\n"); } else if (c == '\r') { parcBufferComposer_PutString(composer, "\\r"); } else if (c == '\t') { parcBufferComposer_PutString(composer, "\\t"); } else if ((c == '/') && !compact) { parcBufferComposer_PutString(composer, "\\/"); } else if (c == '\\') { parcBufferComposer_PutString(composer, "\\\\"); } else { parcBufferComposer_PutChar(composer, c); } } parcBuffer_Rewind(value->value.string); parcBufferComposer_PutChar(composer, '"'); return composer; }
LONGBOW_TEST_CASE(Object, parcRandomAccessFile_Read) { char *fname = "tmpfile"; PARCFile *file = parcFile_Create(fname); parcFile_CreateNewFile(file); FILE *fp = fopen(fname, "w"); fseek(fp, 0, SEEK_SET); uint8_t data[128]; for (int i = 0; i < 128; i++) { data[i] = i; } fwrite(data, 1, 128, fp); fclose(fp); PARCRandomAccessFile *instance = parcRandomAccessFile_Open(file); parcFile_Release(&file); PARCBuffer *buffer = parcBuffer_Allocate(128); size_t numBytes = parcRandomAccessFile_Read(instance, buffer); assertTrue(numBytes == 128, "Expected 128 bytes to be read, but got %zu", numBytes); parcBuffer_Flip(buffer); uint8_t *bytes = parcBuffer_Overlay(buffer, parcBuffer_Remaining(buffer)); assertTrue(memcmp(data, bytes, 128) == 0, "Expected buffers to be equal"); parcBuffer_Release(&buffer); parcRandomAccessFile_Close(instance); parcRandomAccessFile_Release(&instance); }
/** * Gets the DER encoded public key */ LONGBOW_TEST_CASE(openssl_commandline, parcPkcs12KeyStore_GetEncodedPublicKey) { 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"); PARCBuffer *pubkey_der = parcKeyStore_GetDEREncodedPublicKey(parcSigner_GetKeyStore(signer)); assertNotNull(pubkey_der, "got null public key der for external pkcs12"); // read in the "truth" from the command line utilities int fd = open("test_rsa_pub.der", O_RDONLY); uint8_t true_der[1024]; ssize_t read_bytes = read(fd, true_der, 1024); close(fd); assertTrue(read_bytes == 162, "could not read %d byte digest from test_rsa_pub_sha256.bin", 162); const uint8_t *bb_buffer = parcByteArray_Array(parcBuffer_Array(pubkey_der)); size_t bb_length = parcBuffer_Remaining(pubkey_der); assertTrue(bb_length == read_bytes, "Incorrect digest length returned from GetCertificateDigest: %zu", bb_length); assertTrue(memcmp(bb_buffer, true_der, read_bytes) == 0, "digests did not match"); parcSigner_Release(&signer); parcBuffer_Release(&pubkey_der); }
bool parcBuffer_HasRemaining(const PARCBuffer *buffer) { parcBuffer_OptionalAssertValid(buffer); return parcBuffer_Remaining(buffer) != 0; }
size_t parcJSONParser_Remaining(const PARCJSONParser *parser) { parcJSONParser_OptionalAssertValid(parser); return parcBuffer_Remaining(parser->buffer); }
LONGBOW_TEST_CASE(ContentObject, PayloadType) { // The payload type is translated from the wire format value to the CCNxPayloadType value, // so this test cannot use the automated framework as the value in the dictionary will not // be the same as the value in the wire format TestData *data = longBowTestCase_GetClipBoardData(testCase); bool decodeSuccess = ccnxCodecSchemaV1MessageDecoder_Decode(data->decoder, data->dictionary); assertTrue(decodeSuccess, "failure on ccnxCodecSchemaV1MessageDecoder_Decode"); CCNxPayloadType testPayloadType = (CCNxPayloadType) _getPayloadType(data->dictionary); // look up the true name buffer from the truth table TlvExtent extent = getTruthTableExtent(data->truthTable, V1_MANIFEST_OBJ_PAYLOADTYPE); PARCBuffer *truthbuffer = parcBuffer_Wrap(data->packet, data->packetLength, extent.offset, extent.offset + extent.length); uint64_t truthvalue = -2; ccnxCodecTlvUtilities_GetVarInt(truthbuffer, parcBuffer_Remaining(truthbuffer), &truthvalue); CCNxPayloadType truthPayloadType = -1; bool success = _translateWirePayloadTypeToCCNxPayloadType((CCNxCodecSchemaV1Types_PayloadType) truthvalue, &truthPayloadType); assertTrue(success, "failure in _translateWirePayloadTypeToCCNxPayloadType for wireFormatValue %" PRId64, truthvalue); parcBuffer_Release(&truthbuffer); assertTrue(truthPayloadType == testPayloadType, "Wrong value, got %d expected %d", testPayloadType, truthPayloadType); }
static void * _InitForward(PARCBufferChunker *chunker) { _ChunkerState *state = parcMemory_Allocate(sizeof(_ChunkerState)); state->chunkNumber = 0; state->direction = 0; state->position = 0; state->atEnd = false; if (parcBuffer_Remaining(chunker->data) < chunker->chunkSize) { state->nextChunkSize = parcBuffer_Remaining(chunker->data); } else { state->nextChunkSize = chunker->chunkSize; } return state; }
PARCBuffer * parcBuffer_PutUint16(PARCBuffer *buffer, uint16_t value) { assertTrue(parcBuffer_Remaining(buffer) >= sizeof(uint16_t), "Buffer overflow"); parcBuffer_PutUint8(buffer, (value >> 8) & 0xFF); parcBuffer_PutUint8(buffer, value & 0xFF); return buffer; }
PARCBuffer * parcBuffer_PutArray(PARCBuffer *buffer, size_t arrayLength, const uint8_t array[arrayLength]) { parcBuffer_OptionalAssertValid(buffer); assertTrue(parcBuffer_Remaining(buffer) >= arrayLength, "Buffer overflow"); parcByteArray_PutBytes(buffer->array, _effectivePosition(buffer), arrayLength, array); return parcBuffer_SetPosition(buffer, parcBuffer_Position(buffer) + arrayLength); }
size_t tutorialFileIO_AppendFileChunk(const char *fileName, const PARCBuffer *chunk) { size_t numBytesWritten = 0; FILE *file = fopen(fileName, "a"); // Open for appending. Create if it doesn't exist. assertNotNull(file, "Could not open file '%s' - stopping.", fileName); const void *buffer = parcBuffer_Overlay((PARCBuffer *) chunk, 0); // We're un-const'ing for parcBuffer_Overlay, but we do not change the buffer state. numBytesWritten = fwrite(buffer, 1, parcBuffer_Remaining(chunk), file); assertTrue(numBytesWritten == parcBuffer_Remaining(chunk), "Couldn't write requested chunk to file: %s", fileName); fclose(file); return numBytesWritten; }
PARCBuffer * parcBuffer_PutUint8(PARCBuffer *buffer, uint8_t value) { parcBuffer_OptionalAssertValid(buffer); assertTrue(parcBuffer_Remaining(buffer) >= 1, "Buffer overflow"); parcByteArray_PutByte(buffer->array, _effectivePosition(buffer), value); buffer->position++; return buffer; }
static void * _hmacCreate(void *env) { PARCSymmetricKeySigner *signer = (PARCSymmetricKeySigner *) env; // HMAC_Init_ex seems to overrun the size of HMAC_CTX, so make it bigger HMAC_CTX *ctx = parcMemory_Allocate(sizeof(HMAC_CTX) * 2); assertNotNull(ctx, "parcMemory_Allocate(%zu) returned NULL for HMAC_CTX", sizeof(HMAC_CTX) * 2); HMAC_CTX_init(ctx); // Now initialize it with our digest and key, so in hmac_init we can avoid using those PARCBuffer *secretKey = parcSymmetricKeyStore_GetKey(signer->keyStore); assertTrue(parcBuffer_Remaining(secretKey) < 512, "The keystore secret key cannot be longer than %d", 512); HMAC_Init_ex(ctx, parcByteArray_Array(parcBuffer_Array(secretKey)), (int) parcBuffer_Remaining(secretKey), signer->opensslMd, NULL); return ctx; }
bool parcBuffer_SkipOver(PARCBuffer *buffer, size_t length, const uint8_t bytesToSkipOver[length]) { while (parcBuffer_Remaining(buffer) > 0) { uint8_t character = parcBuffer_GetUint8(buffer); if (memchr(bytesToSkipOver, character, length) == NULL) { parcBuffer_SetPosition(buffer, parcBuffer_Position(buffer) - 1); return true; } } return false; }
PARCBuffer * parcBuffer_PutUint64(PARCBuffer *buffer, uint64_t value) { assertTrue(parcBuffer_Remaining(buffer) >= sizeof(uint64_t), "Buffer overflow"); for (int i = sizeof(uint64_t) - 1; i > 0; i--) { uint8_t b = value >> (i * 8) & 0xFF; parcBuffer_PutUint8(buffer, b); } parcBuffer_PutUint8(buffer, value & 0xFF); return buffer; }
int parcBuffer_Compare(const PARCBuffer *x, const PARCBuffer *y) { if (x == y) { return 0; } if (x == NULL) { return -1; } if (y == NULL) { return +1; } size_t count = parcBuffer_Remaining(x); if (count > parcBuffer_Remaining(y)) { count = parcBuffer_Remaining(y); } int result = 0; if (count > 0) { result = memcmp(parcBuffer_Overlay((PARCBuffer *) x, 0), parcBuffer_Overlay((PARCBuffer *) y, 0), count); } if (result == 0) { // This is when one buffer is longer than the other, and they are equivalent thus far. ssize_t difference = parcBuffer_Remaining(x) - parcBuffer_Remaining(y); if (difference > 0) { result = +1; } else if (difference < 0) { result = -1; } } return result; }
uint64_t parcBuffer_ParseHexNumber(PARCBuffer *buffer) { char *bytes = parcBuffer_Overlay(buffer, 0); int start = 0; if (parcBuffer_Remaining(buffer) > 2) { if (bytes[0] == '0' && bytes[1] == 'x') { start = 2; } } unsigned count = 0; uint64_t result = 0; for (int i = start; i < parcBuffer_Remaining(buffer) && isxdigit(bytes[i]); i++) { result = (result * 16) + _digittoint(bytes[i]); count++; } parcBuffer_SetPosition(buffer, parcBuffer_Position(buffer) + start + count); return result; }
static void _advanceStateForward(PARCBufferChunker *chunker, _ChunkerState *state) { state->position += state->nextChunkSize; size_t remaining = parcBuffer_Remaining(chunker->data); if (remaining == 0) { state->atEnd = true; } else if (remaining > chunker->chunkSize) { state->nextChunkSize = chunker->chunkSize; } else { state->nextChunkSize = remaining; } }
bool parcBuffer_SkipTo(PARCBuffer *buffer, size_t length, const uint8_t bytesToSkipTo[length]) { bool result = false; while (parcBuffer_Remaining(buffer) > 0) { uint8_t character = parcBuffer_GetUint8(buffer); if (memchr(bytesToSkipTo, character, length) != NULL) { parcBuffer_SetPosition(buffer, parcBuffer_Position(buffer) - 1); result = true; break; } } return result; }
uint64_t parcBuffer_ParseNumeric(PARCBuffer *buffer) { uint64_t result = 0; char *bytes = parcBuffer_Overlay(buffer, 0); if (parcBuffer_Remaining(buffer) > 2 && bytes[0] == '0' && bytes[1] == 'x') { result = parcBuffer_ParseHexNumber(buffer); } else { result = parcBuffer_ParseDecimalNumber(buffer); } return result; }
char * parcBuffer_ToString(const PARCBuffer *buffer) { size_t remaining = parcBuffer_Remaining(buffer); char *result = parcMemory_Allocate(remaining + 1); if (remaining > 0) { assertNotNull(result, "parcMemory_Allocate returned NULL"); if (result != NULL) { memcpy(result, parcBuffer_Overlay((PARCBuffer *) buffer, 0), remaining); } } result[remaining] = 0; return result; }
PARCBuffer * parcJSONParser_ParseString(PARCJSONParser *parser) { PARCBuffer *result = NULL; PARCBuffer *buffer = _getBuffer(parser); if (parcBuffer_GetUint8(buffer) == '"') { // skip the initial '"' character starting the string. PARCBufferComposer *composer = parcBufferComposer_Create(); while (parcBuffer_Remaining(buffer)) { uint8_t c = parcBuffer_GetUint8(buffer); if (c == '"') { // This is the only successful way to exit this while loop. result = parcBufferComposer_ProduceBuffer(composer); break; } else if (c == '\\') { c = parcBuffer_GetUint8(buffer); if (c == '"') { // this special character passes directly into the composed string. } else if (c == '\\') { // this special character passes directly into the composed string. } else if (c == '/') { // this special character passes directly into the composed string. } else if (c == 'b') { c = '\b'; } else if (c == 'f') { c = '\f'; } else if (c == 'n') { c = '\n'; } else if (c == 'r') { c = '\r'; } else if (c == 't') { c = '\t'; } else if (c == 'u') { // Not supporting unicode at this point. trapNotImplemented("Unicode is not supported."); } } else if (iscntrl(c)) { // !! Syntax Error. break; } parcBufferComposer_PutChar(composer, c); } parcBufferComposer_Release(&composer); } return result; }
PARCHashCode ccnxNameSegment_HashCode(const CCNxNameSegment *segment) { PARCHash32Bits *hash = parcHash32Bits_Create(); parcHash32Bits_Update(hash, &segment->type, sizeof(segment->type)); if (parcBuffer_Remaining(segment->value) > 0) { parcHash32Bits_UpdateUint32(hash, parcBuffer_HashCode(segment->value)); } uint32_t result = parcHash32Bits_Hash(hash); parcHash32Bits_Release(&hash); return result; }
bool ccnxCodecTlvUtilities_GetVarInt(PARCBuffer *input, size_t length, uint64_t *output) { assertNotNull(input, "Parameter input must be non-null"); assertNotNull(output, "Parameter output must be non-null"); bool success = false; if (length >= 1 && length <= 8 && parcBuffer_Remaining(input) >= length) { uint64_t value = 0; for (int i = 0; i < length; i++) { value = value << 8 | parcBuffer_GetUint8(input); } *output = value; success = true; } return success; }