+
+CFDataRef CFDataCreateWithDER(CFAllocatorRef allocator, CFIndex size, uint8_t*(^operation)(size_t size, uint8_t *buffer)) {
+ __block CFMutableDataRef result = NULL;
+ if(!size) return NULL;
+ if((result = CFDataCreateMutableWithScratch(allocator, size)) == NULL) return NULL;
+ uint8_t *ptr = CFDataGetMutableBytePtr(result);
+ uint8_t *derptr = operation(size, ptr);
+ if(derptr == ptr) return result; // most probable case
+ if(!derptr || derptr < ptr) { // DER op failed - or derptr ended up prior to allocated buffer
+ CFReleaseNull(result);
+ } else if(derptr > ptr) { // This is a possible case where we don't end up using the entire allocated buffer
+ size_t diff = derptr - ptr; // The unused space ends up being the beginning of the allocation
+ CFDataDeleteBytes(result, CFRangeMake(0, diff));
+ }
+ return result;
+}