static RefPtr<CryptoAlgorithmParameters> createRsaKeyGenParams(ExecState& state, JSValue value)
{
    if (!value.isObject()) {
        throwTypeError(&state);
        return nullptr;
    }

    JSDictionary jsDictionary(&state, value.getObject());
    auto result = adoptRef(*new CryptoAlgorithmRsaKeyGenParams);

    JSValue modulusLengthValue = getProperty(&state, value.getObject(), "modulusLength");
    if (state.hadException())
        return nullptr;

    // FIXME: Why no EnforceRange? Filed as <https://www.w3.org/Bugs/Public/show_bug.cgi?id=23779>.
    result->modulusLength = convert<uint32_t>(state, modulusLengthValue, NormalConversion);
    if (state.hadException())
        return nullptr;

    JSValue publicExponentValue = getProperty(&state, value.getObject(), "publicExponent");
    if (state.hadException())
        return nullptr;

    RefPtr<Uint8Array> publicExponentArray = toUint8Array(publicExponentValue);
    if (!publicExponentArray) {
        throwTypeError(&state, "Expected a Uint8Array in publicExponent");
        return nullptr;
    }
    result->publicExponent.append(publicExponentArray->data(), publicExponentArray->byteLength());

    result->hasHash = getHashAlgorithm(jsDictionary, result->hash, HashRequirement::Optional); 

    return WTFMove(result);
}
static RefPtr<CryptoAlgorithmParameters> createRsaOaepParams(ExecState* exec, JSValue value)
{
    if (!value.isObject()) {
        throwTypeError(exec);
        return nullptr;
    }

    JSDictionary jsDictionary(exec, value.getObject());
    auto result = adoptRef(*new CryptoAlgorithmRsaOaepParams);

    if (!getHashAlgorithm(jsDictionary, result->hash, HashRequirement::Required)) {
        ASSERT(exec->hadException());
        return nullptr;
    }

    JSValue labelValue = getProperty(exec, value.getObject(), "label");
    if (exec->hadException())
        return nullptr;

    result->hasLabel = !labelValue.isUndefinedOrNull();
    if (!result->hasLabel)
        return WTFMove(result);

    CryptoOperationData labelData;
    if (!cryptoOperationDataFromJSValue(exec, labelValue, labelData)) {
        ASSERT(exec->hadException());
        return nullptr;
    }

    result->label.append(labelData.first, labelData.second);

    return WTFMove(result);
}
static RefPtr<CryptoAlgorithmParameters> createRsaSsaParams(ExecState& state, JSValue value)
{
    if (!value.isObject()) {
        throwTypeError(&state);
        return nullptr;
    }

    JSDictionary jsDictionary(&state, value.getObject());
    auto result = adoptRef(*new CryptoAlgorithmRsaSsaParams);

    if (!getHashAlgorithm(jsDictionary, result->hash, HashRequirement::Required)) {
        ASSERT(state.hadException());
        return nullptr;
    }

    return WTFMove(result);
}
static std::unique_ptr<CryptoAlgorithmParameters> createRsaSsaParams(ExecState* exec, JSValue value)
{
    if (!value.isObject()) {
        throwTypeError(exec);
        return nullptr;
    }

    JSDictionary jsDictionary(exec, value.getObject());
    auto result = std::make_unique<CryptoAlgorithmRsaSsaParams>();

    if (!getHashAlgorithm(jsDictionary, result->hash)) {
        ASSERT(exec->hadException());
        return nullptr;
    }

    return WTF::move(result);
}