static uint8_t *der_encode_pbkdf2_params(size_t saltLen, const uint8_t *salt,
                                         unsigned long iterationCount,
                                         unsigned long keyLength,
                                         const uint8_t *der, uint8_t *der_end)
{
    uint8_t* original_der_end = der_end;

    return ccder_encode_constructed_tl(CCDER_CONSTRUCTED_SEQUENCE, original_der_end, der,
           ccder_encode_raw_octet_string(saltLen, salt, der,
           ccder_encode_uint64(iterationCount, der,
           ccder_encode_uint64(keyLength, der,
           der_encode_SecAsn1Oid(&CSSMOID_PKCS5_HMAC_SHA1, der, der_end)))));
}
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;
}