static size_t der_sizeof_cloud_parameters(SecKeyRef publicKey, CFDataRef paramters, CFErrorRef* error) { size_t public_key_size = der_sizeof_public_bytes(publicKey, error); size_t parameters_size = der_sizeof_data_or_null(paramters, error); return ccder_sizeof(CCDER_CONSTRUCTED_SEQUENCE, public_key_size + parameters_size); }
size_t der_sizeof_string(CFStringRef str, CFErrorRef *error) { const CFIndex str_length = CFStringGetLength(str); const CFIndex maximum = CFStringGetMaximumSizeForEncoding(str_length, kCFStringEncodingUTF8); CFIndex encodedLen = 0; CFIndex converted = CFStringGetBytes(str, CFRangeMake(0, str_length), kCFStringEncodingUTF8, 0, false, NULL, maximum, &encodedLen); return ccder_sizeof(CCDER_UTF8_STRING, (converted == str_length) ? encodedLen : 0); }
static size_t der_sizeof_key_value(CFTypeRef key, CFTypeRef value, CFErrorRef *error) { size_t key_size = der_sizeof_plist(key, error); if (key_size == 0) { return 0; } size_t value_size = der_sizeof_plist(value, error); if (value_size == 0) { return 0; } return ccder_sizeof(CCDER_CONSTRUCTED_SEQUENCE, key_size + value_size); }
static size_t der_sizeof_pbkdf2_params(size_t saltLen, const uint8_t *salt, unsigned long iterationCount, unsigned long keyLength) { size_t body_size = ccder_sizeof_raw_octet_string(saltLen) + ccder_sizeof_uint64(iterationCount) + ccder_sizeof_uint64(keyLength) + der_sizeof_SecAsn1Oid(&CSSMOID_PKCS5_HMAC_SHA1); return ccder_sizeof(CCDER_CONSTRUCTED_SEQUENCE, body_size); }
size_t der_sizeof_RecoveryKeyBag(SOSRecoveryKeyBagRef RecoveryKeyBag, CFErrorRef *error) { size_t result = 0; if(RecoveryKeyBag && RecoveryKeyBag->recoveryKeyBag && RecoveryKeyBag->accountDSID && RecoveryKeyBag->generation) { size_t partSize = der_sizeof_string(RecoveryKeyBag->accountDSID, NULL); partSize += SOSGenCountGetDEREncodedSize(RecoveryKeyBag->generation, NULL); partSize += ccder_sizeof_uint64(RecoveryKeyBag->rkbVersion); partSize += der_sizeof_data(RecoveryKeyBag->recoveryKeyBag, NULL); result = ccder_sizeof(CCDER_CONSTRUCTED_SEQUENCE, partSize); } else { SOSCreateError(kSOSErrorEncodeFailure, CFSTR("Null RecoveryKeyBag"), NULL, error); } return result; }
size_t ccder_encode_rsa_priv_size(const ccrsa_full_ctx_t key) { ccrsa_priv_ctx_t privk = ccrsa_ctx_private(key); cc_size n = ccrsa_ctx_n(key); cc_unit version_0[ccn_nof(1)] = {0x00}; return ccder_sizeof(CCDER_CONSTRUCTED_SEQUENCE, ccder_sizeof_integer(ccn_nof(1), version_0) + ccder_sizeof_integer(n, ccrsa_ctx_m(key)) + ccder_sizeof_integer(n, ccrsa_ctx_e(key)) + ccder_sizeof_integer(n, ccrsa_ctx_d(key)) + ccder_sizeof_integer(cczp_n(ccrsa_ctx_private_zp(privk)), cczp_prime(ccrsa_ctx_private_zp(privk))) + ccder_sizeof_integer(cczp_n(ccrsa_ctx_private_zq(privk)), cczp_prime(ccrsa_ctx_private_zq(privk))) + ccder_sizeof_integer(cczp_n(ccrsa_ctx_private_zp(privk)), ccrsa_ctx_private_dp(privk)) + ccder_sizeof_integer(cczp_n(ccrsa_ctx_private_zq(privk)), ccrsa_ctx_private_dq(privk)) + ccder_sizeof_integer(cczp_n(ccrsa_ctx_private_zp(privk)), ccrsa_ctx_private_qinv(privk)) ); }
static size_t SOSCoderGetDEREncodedSize(SOSCoderRef coder, CFErrorRef *error) { size_t encoded_size = 0; CFMutableDataRef otr_state = sessSerialized(coder, error); if (otr_state) { size_t data_size = der_sizeof_data(otr_state, error); size_t waiting_size = der_sizeof_bool(coder->waitingForDataPacket); size_t pending_size = der_sizeof_optional_data(coder->pendingResponse); if ((data_size != 0) && (waiting_size != 0)) { encoded_size = ccder_sizeof(CCDER_CONSTRUCTED_SEQUENCE, data_size + waiting_size + pending_size); } CFReleaseSafe(otr_state); } return encoded_size; }
size_t der_sizeof_null(CFNullRef data __unused, CFErrorRef *error) { return ccder_sizeof(CCDER_NULL, 0); }
size_t der_sizeof_generalizedtime(CFAbsoluteTime at, CFErrorRef *error) { return ccder_sizeof(CCDER_GENERALIZED_TIME, der_sizeof_generalizedtime_body(at, error)); }
size_t ccder_sizeof_bool(bool value __unused, CFErrorRef *error) { return ccder_sizeof(CCDER_BOOLEAN, 1); }
size_t der_sizeof_dictionary(CFDictionaryRef dict, CFErrorRef *error) { struct size_context context = { .success = true, .size = 0, .error = error }; CFDictionaryApplyFunction(dict, add_key_value_size, &context); if (!context.success) return 0; return ccder_sizeof(CCDER_CONSTRUCTED_SET, context.size); } static uint8_t* der_encode_key_value(CFPropertyListRef key, CFPropertyListRef value, CFErrorRef *error, const uint8_t* der, uint8_t *der_end) { return ccder_encode_constructed_tl(CCDER_CONSTRUCTED_SEQUENCE, der_end, der, der_encode_plist(key, error, der, der_encode_plist(value, error, der, der_end))); } struct encode_context { bool success; CFErrorRef * error; CFMutableArrayRef list; CFAllocatorRef allocator; }; static void add_sequence_to_array(const void *key_void, const void *value_void, void *context_void) { struct encode_context *context = (struct encode_context *) context_void; if (context->success) { CFTypeRef key = (CFTypeRef) key_void; CFTypeRef value = (CFTypeRef) value_void; size_t der_size = der_sizeof_key_value(key, value, context->error); if (der_size == 0) { context-> success = false; } else { CFMutableDataRef encoded_kv = CFDataCreateMutable(context->allocator, der_size); CFDataSetLength(encoded_kv, der_size); uint8_t* const encode_begin = CFDataGetMutableBytePtr(encoded_kv); uint8_t* encode_end = encode_begin + der_size; encode_end = der_encode_key_value(key, value, context->error, encode_begin, encode_end); if (encode_end != NULL) { CFDataDeleteBytes(encoded_kv, CFRangeMake(0, (encode_end - encode_begin))); CFArrayAppendValue(context->list, encoded_kv); } else { context-> success = false; } CFReleaseNull(encoded_kv); } } } static CFComparisonResult cfdata_compare_contents(const void *val1, const void *val2, void *context __unused) { return CFDataCompare((CFDataRef) val1, (CFDataRef) val2); } uint8_t* der_encode_dictionary(CFDictionaryRef dictionary, CFErrorRef *error, const uint8_t *der, uint8_t *der_end) { CFMutableArrayRef elements = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks); struct encode_context context = { .success = true, .error = error, .list = elements }; CFDictionaryApplyFunction(dictionary, add_sequence_to_array, &context); if (!context.success) { CFReleaseNull(elements); return NULL; } CFRange allOfThem = CFRangeMake(0, CFArrayGetCount(elements)); CFArraySortValues(elements, allOfThem, cfdata_compare_contents, NULL); uint8_t* original_der_end = der_end; for(CFIndex position = CFArrayGetCount(elements); position > 0;) { --position; CFDataRef data = CFArrayGetValueAtIndex(elements, position); der_end = ccder_encode_body(CFDataGetLength(data), CFDataGetBytePtr(data), der, der_end); } CFReleaseNull(elements); return ccder_encode_constructed_tl(CCDER_CONSTRUCTED_SET, original_der_end, der, der_end); }
static size_t der_sizeof_SecAsn1Oid(const SecAsn1Oid* secasn_oid) { return ccder_sizeof(CCDER_OBJECT_IDENTIFIER, secasn_oid->Length); }
static size_t der_sizeof_bool(bool value) { return ccder_sizeof(CCDER_BOOLEAN, 1); }