/*
 * Copyright 2004-2021 The OpenSSL Project Authors. All Rights Reserved.
 * Copyright (c) 2004, EdelKey Project. All Rights Reserved.
 *
 * Licensed under the Apache License 2.0 (the "License").  You may not use
 * this file except in compliance with the License.  You can obtain a copy
 * in the file LICENSE in the source distribution or at
 * https://www.openssl.org/source/license.html
 *
 * Originally written by Christophe Renou and Peter Sylvester,
 * for the EdelKey project.
 */

/* All the SRP APIs in this file are deprecated */
#define OPENSSL_SUPPRESS_DEPRECATED

#ifndef OPENSSL_NO_SRP
# include "internal/cryptlib.h"
# include "crypto/evp.h"
# include <openssl/sha.h>
# include <openssl/srp.h>
# include <openssl/evp.h>
# include <openssl/buffer.h>
# include <openssl/rand.h>
# include <openssl/txt_db.h>
# include <openssl/err.h>

# define SRP_RANDOM_SALT_LEN 20
# define MAX_LEN 2500

/*
 * Note that SRP uses its own variant of base 64 encoding. A different base64
 * alphabet is used and no padding '=' characters are added. Instead we pad to
 * the front with 0 bytes and subsequently strip off leading encoded padding.
 * This variant is used for compatibility with other SRP implementations -
 * notably libsrp, but also others. It is also required for backwards
 * compatibility in order to load verifier files from other OpenSSL versions.
 */

/*
 * Convert a base64 string into raw byte array representation.
 * Returns the length of the decoded data, or -1 on error.
 */
static int t_fromb64(unsigned char *a, size_t alen, const char *src)
{
    EVP_ENCODE_CTX *ctx;
    int outl = 0, outl2 = 0;
    size_t size, padsize;
    const unsigned char *pad = (const unsigned char *)"00";

    while (*src == ' ' || *src == '\t' || *src == '\n')
        ++src;
    size = strlen(src);
    padsize = 4 - (size & 3);
    padsize &= 3;

    /* Four bytes in src become three bytes output. */
    if (size > INT_MAX || ((size + padsize) / 4) * 3 > alen)
        return -1;

    ctx = EVP_ENCODE_CTX_new();
    if (ctx == NULL)
        return -1;

    /*
     * This should never occur because 1 byte of data always requires 2 bytes of
     * encoding, i.e.
     *  0 bytes unencoded = 0 bytes encoded
     *  1 byte unencoded  = 2 bytes encoded
     *  2 bytes unencoded = 3 bytes encoded
     *  3 bytes unencoded = 4 bytes encoded
     *  4 bytes unencoded = 6 bytes encoded
     *  etc
     */
    if (padsize == 3) {
        outl = -1;
        goto err;
    }

    /* Valid padsize values are now 0, 1 or 2 */

    EVP_DecodeInit(ctx);
    evp_encode_ctx_set_flags(ctx, EVP_ENCODE_CTX_USE_SRP_ALPHABET);

    /* Add any encoded padding that is required */
    if (padsize != 0
            && EVP_DecodeUpdate(ctx, a, &outl, pad, padsize) < 0) {
        outl = -1;
        goto err;
    }
    if (EVP_DecodeUpdate(ctx, a, &outl2, (const unsigned char *)src, size) < 0) {
        outl = -1;
        goto err;
    }
    outl += outl2;
    EVP_DecodeFinal(ctx, a + outl, &outl2);
    outl += outl2;

    /* Strip off the leading padding */
    if (padsize != 0) {
        if ((int)padsize >= outl) {
            outl = -1;
            goto err;
        }

        /*
         * If we added 1 byte of padding prior to encoding then we have 2 bytes
         * of "real" data which gets spread across 4 encoded bytes like this:
         *   (6 bits pad)(2 bits pad | 4 bits data)(6 bits data)(6 bits data)
         * So 1 byte of pre-encoding padding results in 1 full byte of encoded
         * padding.
         * If we added 2 bytes of padding prior to encoding this gets encoded
         * as:
         *   (6 bits pad)(6 bits pad)(4 bits pad | 2 bits data)(6 bits data)
         * So 2 bytes of pre-encoding padding results in 2 full bytes of encoded
         * padding, i.e. we have to strip the same number of bytes of padding
         * from the encoded data as we added to the pre-encoded data.
         */
        memmove(a, a + padsize, outl - padsize);
        outl -= padsize;
    }

 err:
    EVP_ENCODE_CTX_free(ctx);

    return outl;
}

/*
 * Convert a raw byte string into a null-terminated base64 ASCII string.
 * Returns 1 on success or 0 on error.
 */
static int t_tob64(char *dst, const unsigned char *src, int size)
{
    EVP_ENCODE_CTX *ctx = EVP_ENCODE_CTX_new();
    int outl = 0, outl2 = 0;
    unsigned char pad[2] = {0, 0};
    size_t leadz = 0;

    if (ctx == NULL)
        return 0;

    EVP_EncodeInit(ctx);
    evp_encode_ctx_set_flags(ctx, EVP_ENCODE_CTX_NO_NEWLINES
                                  | EVP_ENCODE_CTX_USE_SRP_ALPHABET);

    /*
     * We pad at the front with zero bytes until the length is a multiple of 3
     * so that EVP_EncodeUpdate/EVP_EncodeFinal does not add any of its own "="
     * padding
     */
    leadz = 3 - (size % 3);
    if (leadz != 3
            && !EVP_EncodeUpdate(ctx, (unsigned char *)dst, &outl, pad,
                                 leadz)) {
        EVP_ENCODE_CTX_free(ctx);
        return 0;
    }

    if (!EVP_EncodeUpdate(ctx, (unsigned char *)dst + outl, &outl2, src,
                          size)) {
        EVP_ENCODE_CTX_free(ctx);
        return 0;
    }
    outl += outl2;
    EVP_EncodeFinal(ctx, (unsigned char *)dst + outl, &outl2);
    outl += outl2;

    /* Strip the encoded padding at the front */
    if (leadz != 3) {
        memmove(dst, dst + leadz, outl - leadz);
        dst[outl - leadz] = '\0';
    }

    EVP_ENCODE_CTX_free(ctx);
    return 1;
}

void SRP_user_pwd_free(SRP_user_pwd *user_pwd)
{
    if (user_pwd == NULL)
        return;
    BN_free(user_pwd->s);
    BN_clear_free(user_pwd->v);
    OPENSSL_free(user_pwd->id);
    OPENSSL_free(user_pwd->info);
    OPENSSL_free(user_pwd);
}

SRP_user_pwd *SRP_user_pwd_new(void)
{
    SRP_user_pwd *ret;

    if ((ret = OPENSSL_malloc(sizeof(*ret))) == NULL) {
        /* ERR_raise(ERR_LIB_SRP, ERR_R_MALLOC_FAILURE); */ /*ckerr_ignore*/
        return NULL;
    }
    ret->N = NULL;
    ret->g = NULL;
    ret->s = NULL;
    ret->v = NULL;
    ret->id = NULL;
    ret->info = NULL;
    return ret;
}

void SRP_user_pwd_set_gN(SRP_user_pwd *vinfo, const BIGNUM *g,
                         const BIGNUM *N)
{
    vinfo->N = N;
    vinfo->g = g;
}

int SRP_user_pwd_set1_ids(SRP_user_pwd *vinfo, const char *id,
                          const char *info)
{
    OPENSSL_free(vinfo->id);
    OPENSSL_free(vinfo->info);
    if (id != NULL && NULL == (vinfo->id = OPENSSL_strdup(id)))
        return 0;
    return (info == NULL || NULL != (vinfo->info = OPENSSL_strdup(info)));
}

static int SRP_user_pwd_set_sv(SRP_user_pwd *vinfo, const char *s,
                               const char *v)
{
    unsigned char tmp[MAX_LEN];
    int len;

    vinfo->v = NULL;
    vinfo->s = NULL;

    len = t_fromb64(tmp, sizeof(tmp), v);
    if (len < 0)
        return 0;
    if (NULL == (vinfo->v = BN_bin2bn(tmp, len, NULL)))
        return 0;
    len = t_fromb64(tmp, sizeof(tmp), s);
    if (len < 0)
        goto err;
    vinfo->s = BN_bin2bn(tmp, len, NULL);
    if (vinfo->s == NULL)
        goto err;
    return 1;
 err:
    BN_free(vinfo->v);
    vinfo->v = NULL;
    return 0;
}

int SRP_user_pwd_set0_sv(SRP_user_pwd *vinfo, BIGNUM *s, BIGNUM *v)
{
    BN_free(vinfo->s);
    BN_clear_free(vinfo->v);
    vinfo->v = v;
    vinfo->s = s;
    return (vinfo->s != NULL && vinfo->v != NULL);
}

static SRP_user_pwd *srp_user_pwd_dup(SRP_user_pwd *src)
{
    SRP_user_pwd *ret;

    if (src == NULL)
        return NULL;
    if ((ret = SRP_user_pwd_new()) == NULL)
        return NULL;

    SRP_user_pwd_set_gN(ret, src->g, src->N);
    if (!SRP_user_pwd_set1_ids(ret, src->id, src->info)
        || !SRP_user_pwd_set0_sv(ret, BN_dup(src->s), BN_dup(src->v))) {
            SRP_user_pwd_free(ret);
            return NULL;
    }
    return ret;
}

SRP_VBASE *SRP_VBASE_new(char *seed_key)
{
    SRP_VBASE *vb = OPENSSL_malloc(sizeof(*vb));

    if (vb == NULL)
        return NULL;
    if ((vb->users_pwd = sk_SRP_user_pwd_new_null()) == NULL
        || (vb->gN_cache = sk_SRP_gN_cache_new_null()) == NULL) {
        OPENSSL_free(vb);
        return NULL;
    }
    vb->default_g = NULL;
    vb->default_N = NULL;
    vb->seed_key = NULL;
    if ((seed_key != NULL) && (vb->seed_key = OPENSSL_strdup(seed_key)) == NULL) {
        sk_SRP_user_pwd_free(vb->users_pwd);
        sk_SRP_gN_cache_free(vb->gN_cache);
        OPENSSL_free(vb);
        return NULL;
    }
    return vb;
}

void SRP_VBASE_free(SRP_VBASE *vb)
{
    if (!vb)
        return;
    sk_SRP_user_pwd_pop_free(vb->users_pwd, SRP_user_pwd_free);
    sk_SRP_gN_cache_free(vb->gN_cache);
    OPENSSL_free(vb->seed_key);
    OPENSSL_free(vb);
}

static SRP_gN_cache *SRP_gN_new_init(const char *ch)
{
    unsigned char tmp[MAX_LEN];
    int len;
    SRP_gN_cache *newgN = OPENSSL_malloc(sizeof(*newgN));

    if (newgN == NULL)
        return NULL;

    len = t_fromb64(tmp, sizeof(tmp), ch);
    if (len < 0)
        goto err;

    if ((newgN->b64_bn = OPENSSL_strdup(ch)) == NULL)
        goto err;

    if ((newgN->bn = BN_bin2bn(tmp, len, NULL)))
        return newgN;

    OPENSSL_free(newgN->b64_bn);
 err:
    OPENSSL_free(newgN);
    return NULL;
}

static void SRP_gN_free(SRP_gN_cache *gN_cache)
{
    if (gN_cache == NULL)
        return;
    OPENSSL_free(gN_cache->b64_bn);
    BN_free(gN_cache->bn);
    OPENSSL_free(gN_cache);
}

static SRP_gN *SRP_get_gN_by_id(const char *id, STACK_OF(SRP_gN) *gN_tab)
{
    int i;

    SRP_gN *gN;
    if (gN_tab != NULL) {
        for (i = 0; i < sk_SRP_gN_num(gN_tab); i++) {
            gN = sk_SRP_gN_value(gN_tab, i);
            if (gN && (id == NULL || strcmp(gN->id, id) == 0))
                return gN;
        }
    }

    return SRP_get_default_gN(id);
}

static BIGNUM *SRP_gN_place_bn(STACK_OF(SRP_gN_cache) *gN_cache, char *ch)
{
    int i;
    if (gN_cache == NULL)
        return NULL;

    /* search if we have already one... */
    for (i = 0; i < sk_SRP_gN_cache_num(gN_cache); i++) {
        SRP_gN_cache *cache = sk_SRP_gN_cache_value(gN_cache, i);
        if (strcmp(cache->b64_bn, ch) == 0)
            return cache->bn;
    }
    {                           /* it is the first time that we find it */
        SRP_gN_cache *newgN = SRP_gN_new_init(ch);
        if (newgN) {
            if (sk_SRP_gN_cache_insert(gN_cache, newgN, 0) > 0)
                return newgN->bn;
            SRP_gN_free(newgN);
        }
    }
    return NULL;
}

/*
 * This function parses the verifier file generated by the srp app.
 * The format for each entry is:
 * V base64(verifier) base64(salt) username gNid userinfo(optional)
 * or
 * I base64(N) base64(g)
 * Note that base64 is the SRP variant of base64 encoding described
 * in t_fromb64().
 */

int SRP_VBASE_init(SRP_VBASE *vb, char *verifier_file)
{
    int error_code;
    STACK_OF(SRP_gN) *SRP_gN_tab = sk_SRP_gN_new_null();
    char *last_index = NULL;
    int i;
    char **pp;

    SRP_gN *gN = NULL;
    SRP_user_pwd *user_pwd = NULL;

    TXT_DB *tmpdb = NULL;
    BIO *in = BIO_new(BIO_s_file());

    error_code = SRP_ERR_OPEN_FILE;

    if (in == NULL || BIO_read_filename(in, verifier_file) <= 0)
        goto err;

    error_code = SRP_ERR_VBASE_INCOMPLETE_FILE;

    if ((tmpdb = TXT_DB_read(in, DB_NUMBER)) == NULL)
        goto err;

    error_code = SRP_ERR_MEMORY;

    if (vb->seed_key) {
        last_index = SRP_get_default_gN(NULL)->id;
    }
    for (i = 0; i < sk_OPENSSL_PSTRING_num(tmpdb->data); i++) {
        pp = sk_OPENSSL_PSTRING_value(tmpdb->data, i);
        if (pp[DB_srptype][0] == DB_SRP_INDEX) {
            /*
             * we add this couple in the internal Stack
             */

            if ((gN = OPENSSL_malloc(sizeof(*gN))) == NULL)
                goto err;

            if ((gN->id = OPENSSL_strdup(pp[DB_srpid])) == NULL
                || (gN->N = SRP_gN_place_bn(vb->gN_cache, pp[DB_srpverifier]))
                        == NULL
                || (gN->g = SRP_gN_place_bn(vb->gN_cache, pp[DB_srpsalt]))
                        == NULL
                || sk_SRP_gN_insert(SRP_gN_tab, gN, 0) == 0)
                goto err;

            gN = NULL;

            if (vb->seed_key != NULL) {
                last_index = pp[DB_srpid];
            }
        } else if (pp[DB_srptype][0] == DB_SRP_VALID) {
            /* it is a user .... */
            const SRP_gN *lgN;

            if ((lgN = SRP_get_gN_by_id(pp[DB_srpgN], SRP_gN_tab)) != NULL) {
                error_code = SRP_ERR_MEMORY;
                if ((user_pwd = SRP_user_pwd_new()) == NULL)
                    goto err;

                SRP_user_pwd_set_gN(user_pwd, lgN->g, lgN->N);
                if (!SRP_user_pwd_set1_ids
                    (user_pwd, pp[DB_srpid], pp[DB_srpinfo]))
                    goto err;

                error_code = SRP_ERR_VBASE_BN_LIB;
                if (!SRP_user_pwd_set_sv
                    (user_pwd, pp[DB_srpsalt], pp[DB_srpverifier]))
                    goto err;

                if (sk_SRP_user_pwd_insert(vb->users_pwd, user_pwd, 0) == 0)
                    goto err;
                user_pwd = NULL; /* abandon responsibility */
            }
        }
    }

    if (last_index != NULL) {
        /* this means that we want to simulate a default user */

        if (((gN = SRP_get_gN_by_id(last_index, SRP_gN_tab)) == NULL)) {
            error_code = SRP_ERR_VBASE_BN_LIB;
            goto err;
        }
        vb->default_g = gN->g;
        vb->default_N = gN->N;
        gN = NULL;
    }
    error_code = SRP_NO_ERROR;

 err:
    /*
     * there may be still some leaks to fix, if this fails, the application
     * terminates most likely
     */

    if (gN != NULL) {
        OPENSSL_free(gN->id);
        OPENSSL_free(gN);
    }

    SRP_user_pwd_free(user_pwd);

    TXT_DB_free(tmpdb);
    BIO_free_all(in);

    sk_SRP_gN_free(SRP_gN_tab);

    return error_code;

}

static SRP_user_pwd *find_user(SRP_VBASE *vb, char *username)
{
    int i;
    SRP_user_pwd *user;

    if (vb == NULL)
        return NULL;

    for (i = 0; i < sk_SRP_user_pwd_num(vb->users_pwd); i++) {
        user = sk_SRP_user_pwd_value(vb->users_pwd, i);
        if (strcmp(user->id, username) == 0)
            return user;
    }

    return NULL;
}

int SRP_VBASE_add0_user(SRP_VBASE *vb, SRP_user_pwd *user_pwd)
{
    if (sk_SRP_user_pwd_push(vb->users_pwd, user_pwd) <= 0)
        return 0;
    return 1;
}

# ifndef OPENSSL_NO_DEPRECATED_1_1_0
/*
 * DEPRECATED: use SRP_VBASE_get1_by_user instead.
 * This method ignores the configured seed and fails for an unknown user.
 * Ownership of the returned pointer is not released to the caller.
 * In other words, caller must not free the result.
 */
SRP_user_pwd *SRP_VBASE_get_by_user(SRP_VBASE *vb, char *username)
{
    return find_user(vb, username);
}
# endif

/*
 * Ownership of the returned pointer is released to the caller.
 * In other words, caller must free the result once done.
 */
SRP_user_pwd *SRP_VBASE_get1_by_user(SRP_VBASE *vb, char *username)
{
    SRP_user_pwd *user;
    unsigned char digv[SHA_DIGEST_LENGTH];
    unsigned char digs[SHA_DIGEST_LENGTH];
    EVP_MD_CTX *ctxt = NULL;
    EVP_MD *md = NULL;

    if (vb == NULL)
        return NULL;

    if ((user = find_user(vb, username)) != NULL)
        return srp_user_pwd_dup(user);

    if ((vb->seed_key == NULL) ||
        (vb->default_g == NULL) || (vb->default_N == NULL))
        return NULL;

/* if the user is unknown we set parameters as well if we have a seed_key */

    if ((user = SRP_user_pwd_new()) == NULL)
        return NULL;

    SRP_user_pwd_set_gN(user, vb->default_g, vb->default_N);

    if (!SRP_user_pwd_set1_ids(user, username, NULL))
        goto err;

    if (RAND_priv_bytes(digv, SHA_DIGEST_LENGTH) <= 0)
        goto err;
    md = EVP_MD_fetch(NULL, SN_sha1, NULL);
    if (md == NULL)
        goto err;
    ctxt = EVP_MD_CTX_new();
    if (ctxt == NULL
        || !EVP_DigestInit_ex(ctxt, md, NULL)
        || !EVP_DigestUpdate(ctxt, vb->seed_key, strlen(vb->seed_key))
        || !EVP_DigestUpdate(ctxt, username, strlen(username))
        || !EVP_DigestFinal_ex(ctxt, digs, NULL))
        goto err;
    EVP_MD_CTX_free(ctxt);
    ctxt = NULL;
    EVP_MD_free(md);
    md = NULL;
    if (SRP_user_pwd_set0_sv(user,
                             BN_bin2bn(digs, SHA_DIGEST_LENGTH, NULL),
                             BN_bin2bn(digv, SHA_DIGEST_LENGTH, NULL)))
        return user;

 err:
    EVP_MD_free(md);
    EVP_MD_CTX_free(ctxt);
    SRP_user_pwd_free(user);
    return NULL;
}

/*
 * create a verifier (*salt,*verifier,g and N are in base64)
 */
char *SRP_create_verifier_ex(const char *user, const char *pass, char **salt,
                             char **verifier, const char *N, const char *g,
                             OSSL_LIB_CTX *libctx, const char *propq)
{
    int len;
    char *result = NULL, *vf = NULL;
    const BIGNUM *N_bn = NULL, *g_bn = NULL;
    BIGNUM *N_bn_alloc = NULL, *g_bn_alloc = NULL, *s = NULL, *v = NULL;
    unsigned char tmp[MAX_LEN];
    unsigned char tmp2[MAX_LEN];
    char *defgNid = NULL;
    int vfsize = 0;

    if ((user == NULL) ||
        (pass == NULL) || (salt == NULL) || (verifier == NULL))
        goto err;

    if (N) {
        if ((len = t_fromb64(tmp, sizeof(tmp), N)) <= 0)
            goto err;
        N_bn_alloc = BN_bin2bn(tmp, len, NULL);
        if (N_bn_alloc == NULL)
            goto err;
        N_bn = N_bn_alloc;
        if ((len = t_fromb64(tmp, sizeof(tmp), g)) <= 0)
            goto err;
        g_bn_alloc = BN_bin2bn(tmp, len, NULL);
        if (g_bn_alloc == NULL)
            goto err;
        g_bn = g_bn_alloc;
        defgNid = "*";
    } else {
        SRP_gN *gN = SRP_get_default_gN(g);
        if (gN == NULL)
            goto err;
        N_bn = gN->N;
        g_bn = gN->g;
        defgNid = gN->id;
    }

    if (*salt == NULL) {
        if (RAND_bytes_ex(libctx, tmp2, SRP_RANDOM_SALT_LEN, 0) <= 0)
            goto err;

        s = BN_bin2bn(tmp2, SRP_RANDOM_SALT_LEN, NULL);
    } else {
        if ((len = t_fromb64(tmp2, sizeof(tmp2), *salt)) <= 0)
            goto err;
        s = BN_bin2bn(tmp2, len, NULL);
    }
    if (s == NULL)
        goto err;

    if (!SRP_create_verifier_BN_ex(user, pass, &s, &v, N_bn, g_bn, libctx,
                                   propq))
        goto err;

    if (BN_bn2bin(v, tmp) < 0)
        goto err;
    vfsize = BN_num_bytes(v) * 2;
    if (((vf = OPENSSL_malloc(vfsize)) == NULL))
        goto err;
    if (!t_tob64(vf, tmp, BN_num_bytes(v)))
        goto err;

    if (*salt == NULL) {
        char *tmp_salt;

        if ((tmp_salt = OPENSSL_malloc(SRP_RANDOM_SALT_LEN * 2)) == NULL) {
            goto err;
        }
        if (!t_tob64(tmp_salt, tmp2, SRP_RANDOM_SALT_LEN)) {
            OPENSSL_free(tmp_salt);
            goto err;
        }
        *salt = tmp_salt;
    }

    *verifier = vf;
    vf = NULL;
    result = defgNid;

 err:
    BN_free(N_bn_alloc);
    BN_free(g_bn_alloc);
    OPENSSL_clear_free(vf, vfsize);
    BN_clear_free(s);
    BN_clear_free(v);
    return result;
}

char *SRP_create_verifier(const char *user, const char *pass, char **salt,
                          char **verifier, const char *N, const char *g)
{
    return SRP_create_verifier_ex(user, pass, salt, verifier, N, g, NULL, NULL);
}

/*
 * create a verifier (*salt,*verifier,g and N are BIGNUMs). If *salt != NULL
 * then the provided salt will be used. On successful exit *verifier will point
 * to a newly allocated BIGNUM containing the verifier and (if a salt was not
 * provided) *salt will be populated with a newly allocated BIGNUM containing a
 * random salt.
 * The caller is responsible for freeing the allocated *salt and *verifier
 * BIGNUMS.
 */
int SRP_create_verifier_BN_ex(const char *user, const char *pass, BIGNUM **salt,
                              BIGNUM **verifier, const BIGNUM *N,
                              const BIGNUM *g, OSSL_LIB_CTX *libctx,
                              const char *propq)
{
    int result = 0;
    BIGNUM *x = NULL;
    BN_CTX *bn_ctx = BN_CTX_new_ex(libctx);
    unsigned char tmp2[MAX_LEN];
    BIGNUM *salttmp = NULL, *verif;

    if ((user == NULL) ||
        (pass == NULL) ||
        (salt == NULL) ||
        (verifier == NULL) || (N == NULL) || (g == NULL) || (bn_ctx == NULL))
        goto err;

    if (*salt == NULL) {
        if (RAND_bytes_ex(libctx, tmp2, SRP_RANDOM_SALT_LEN, 0) <= 0)
            goto err;

        salttmp = BN_bin2bn(tmp2, SRP_RANDOM_SALT_LEN, NULL);
        if (salttmp == NULL)
            goto err;
    } else {
        salttmp = *salt;
    }

    x = SRP_Calc_x_ex(salttmp, user, pass, libctx, propq);
    if (x == NULL)
        goto err;

    verif = BN_new();
    if (verif == NULL)
        goto err;

    if (!BN_mod_exp(verif, g, x, N, bn_ctx)) {
        BN_clear_free(verif);
        goto err;
    }

    result = 1;
    *salt = salttmp;
    *verifier = verif;

 err:
    if (salt != NULL && *salt != salttmp)
        BN_clear_free(salttmp);
    BN_clear_free(x);
    BN_CTX_free(bn_ctx);
    return result;
}

int SRP_create_verifier_BN(const char *user, const char *pass, BIGNUM **salt,
                           BIGNUM **verifier, const BIGNUM *N,
                           const BIGNUM *g)
{
    return SRP_create_verifier_BN_ex(user, pass, salt, verifier, N, g, NULL,
                                     NULL);
}
#endif
