static uint8_t* SOSCoderEncodeToDER(SOSCoderRef coder, CFErrorRef* error, const uint8_t* der, uint8_t* der_end) {
    if(!der_end) return NULL;
    uint8_t* result = NULL;
    CFMutableDataRef otr_state = sessSerialized(coder, error);
    
    if(otr_state) {
        result = ccder_encode_constructed_tl(CCDER_CONSTRUCTED_SEQUENCE, der_end, der,
                                             der_encode_data(otr_state, error, der,
                                             der_encode_bool(coder->waitingForDataPacket, der,
                                             der_encode_optional_data(coder->pendingResponse, error, der, der_end))));
        CFReleaseSafe(otr_state);
    }
    return result;
}
uint8_t* der_encode_RecoveryKeyBag(SOSRecoveryKeyBagRef RecoveryKeyBag, CFErrorRef *error,
                                   const uint8_t *der, uint8_t *der_end) {
    uint8_t *result = NULL;
    if (der_end == NULL) return der_end;
    if(RecoveryKeyBag && RecoveryKeyBag->recoveryKeyBag && RecoveryKeyBag->accountDSID && RecoveryKeyBag->generation) {
        der_end = ccder_encode_constructed_tl(CCDER_CONSTRUCTED_SEQUENCE, der_end, der,
                    der_encode_string(RecoveryKeyBag->accountDSID, error, der,
                    SOSGenCountEncodeToDER(RecoveryKeyBag->generation, error, der,
                    ccder_encode_uint64(RecoveryKeyBag->rkbVersion, der,
                    der_encode_data(RecoveryKeyBag->recoveryKeyBag, error, der, der_end)))));
        
        require_quiet(der_end == der, errOut);
        result = der_end;
    } else {
        SOSCreateError(kSOSErrorEncodeFailure, CFSTR("Null RecoveryKeyBag"), NULL, error);
    }
    
errOut:
    return result;
}
static uint8_t* der_encode_optional_data(CFDataRef data, CFErrorRef *error, const uint8_t* der, uint8_t* der_end) {
    return data ? der_encode_data(data, error, der, der_end) : der_end;
}