Example #1
0
static int
DH_check_pub_key_rfc(const DH *dh, BN_CTX *ctx, int *ret)
{
    BIGNUM *bn = NULL;
    int ok = 0;
    const BIGNUM *pub_key, *p, *q, *g;

    check((dh && ret), "Invalid arguments");

    BN_CTX_start(ctx);

    DH_get0_key(dh, &pub_key, NULL);
    DH_get0_pqg(dh, &p, &q, &g);

    /* Verify that y lies within the interval [2,p-1]. */
    if (!DH_check_pub_key(dh, pub_key, ret))
        goto err;

    /* If the DH is conform to RFC 2631 it should have a non-NULL q.
     * Others (like the DHs generated from OpenSSL) might have a problem with
     * this check. */
    if (q) {
        /* Compute y^q mod p. If the result == 1, the key is valid. */
        bn = BN_CTX_get(ctx);
        if (!bn || !BN_mod_exp(bn, pub_key, q, p, ctx))
            goto err;
        if (!BN_is_one(bn))
            *ret |= DH_CHECK_PUBKEY_INVALID;
    }
    ok = 1;

err:
    BN_CTX_end(ctx);
    return ok;
}
Example #2
0
// Set from OpenSSL representation
void OSSLDHPublicKey::setFromOSSL(const DH* inDH)
{
	const BIGNUM* bn_p = NULL;
	const BIGNUM* bn_g = NULL;
	const BIGNUM* bn_pub_key = NULL;

	DH_get0_pqg(inDH, &bn_p, NULL, &bn_g);
	DH_get0_key(inDH, &bn_pub_key, NULL);

	if (bn_p)
	{
		ByteString inP = OSSL::bn2ByteString(bn_p);
		setP(inP);
	}
	if (bn_g)
	{
		ByteString inG = OSSL::bn2ByteString(bn_g);
		setG(inG);
	}
	if (bn_pub_key)
	{
		ByteString inY = OSSL::bn2ByteString(bn_pub_key);
		setY(inY);
	}
}
Example #3
0
/**
  Generates DH parameter.

  Given generator g, and length of prime number p in bits, this function generates p,
  and sets DH context according to value of g and p.

  Before this function can be invoked, pseudorandom number generator must be correctly
  initialized by RandomSeed().

  If DhContext is NULL, then return FALSE.
  If Prime is NULL, then return FALSE.

  @param[in, out]  DhContext    Pointer to the DH context.
  @param[in]       Generator    Value of generator.
  @param[in]       PrimeLength  Length in bits of prime to be generated.
  @param[out]      Prime        Pointer to the buffer to receive the generated prime number.

  @retval TRUE   DH parameter generation succeeded.
  @retval FALSE  Value of Generator is not supported.
  @retval FALSE  PRNG fails to generate random prime number with PrimeLength.

**/
BOOLEAN
EFIAPI
DhGenerateParameter (
  IN OUT  VOID   *DhContext,
  IN      UINTN  Generator,
  IN      UINTN  PrimeLength,
  OUT     UINT8  *Prime
  )
{
  BOOLEAN RetVal;
  BIGNUM  *BnP;

  //
  // Check input parameters.
  //
  if (DhContext == NULL || Prime == NULL || PrimeLength > INT_MAX) {
    return FALSE;
  }

  if (Generator != DH_GENERATOR_2 && Generator != DH_GENERATOR_5) {
    return FALSE;
  }

  RetVal = (BOOLEAN) DH_generate_parameters_ex (DhContext, (UINT32) PrimeLength, (UINT32) Generator, NULL);
  if (!RetVal) {
    return FALSE;
  }

  DH_get0_pqg (DhContext, (const BIGNUM **)&BnP, NULL, NULL);
  BN_bn2bin (BnP, Prime);

  return TRUE;
}
Example #4
0
int
dh_gen_key(DH *dh, int need)
{
	int pbits;
	const BIGNUM *p, *pub_key, *priv_key;

	DH_get0_pqg(dh, &p, NULL, NULL);

	if (need < 0 || p == NULL ||
	    (pbits = BN_num_bits(p)) <= 0 ||
	    need > INT_MAX / 2 || 2 * need > pbits)
		return SSH_ERR_INVALID_ARGUMENT;
	if (need < 256)
		need = 256;
	/*
	 * Pollard Rho, Big step/Little Step attacks are O(sqrt(n)),
	 * so double requested need here.
	 */
	DH_set_length(dh, MIN(need * 2, pbits - 1));
	if (DH_generate_key(dh) == 0) {
		return SSH_ERR_LIBCRYPTO_ERROR;
	}
	DH_get0_key(dh, &pub_key, &priv_key);
	if (!dh_pub_is_valid(dh, pub_key)) {
#if 0
		BN_clear(priv_key);
#endif
		return SSH_ERR_LIBCRYPTO_ERROR;
	}
	return 0;
}
Example #5
0
DH *
DHparams_dup_with_q(DH *dh)
{
    const BIGNUM *p, *q, *g;

    DH *dup = DHparams_dup(dh);
    DH_get0_pqg(dh, &p, &q, &g);
    DH_set0_pqg(dup, BN_dup(p), BN_dup(q), BN_dup(g));

    return dup;
}
Example #6
0
static const BIGNUM *s2n_get_p_dh_param(struct s2n_dh_params *dh_params)
{
    const BIGNUM *p = NULL;
    #if OPENSSL_VERSION_NUMBER < 0x10100000L || defined LIBRESSL_VERSION_NUMBER
        p = dh_params->dh->p;
    #else
        DH_get0_pqg(dh_params->dh, &p, NULL, NULL);
    #endif

    return p;
}
Example #7
0
static const BIGNUM *s2n_get_g_dh_param(struct s2n_dh_params *dh_params)
{
    const BIGNUM *g = NULL;
    #if OPENSSL_VERSION_NUMBER < 0x10100000L || defined LIBRESSL_VERSION_NUMBER
        g = dh_params->dh->g;
    #else
        DH_get0_pqg(dh_params->dh, NULL, NULL, &g);
    #endif

    return g;
}
Example #8
0
int HsOpenSSL_DH_length(DH *dh) {
#if OPENSSL_VERSION_NUMBER >= 0x10100000L
    const BIGNUM** p = 0;
    const BIGNUM** q = 0;
    const BIGNUM** g = 0;
    DH_get0_pqg(dh, p, q, g);
    return BN_num_bits(*p);
#else
    return BN_num_bits(dh->p);
#endif
}
Example #9
0
int
dh_pub_is_valid(const DH *dh, const BIGNUM *dh_pub)
{
	int i;
	int n = BN_num_bits(dh_pub);
	int bits_set = 0;
	BIGNUM *tmp;
	const BIGNUM *p;

	if (BN_is_negative(dh_pub)) {
		logit("invalid public DH value: negative");
		return 0;
	}
	if (BN_cmp(dh_pub, BN_value_one()) != 1) {	/* pub_exp <= 1 */
		logit("invalid public DH value: <= 1");
		return 0;
	}

	if ((tmp = BN_new()) == NULL) {
		error("%s: BN_new failed", __func__);
		return 0;
	}
	DH_get0_pqg(dh, &p, NULL, NULL);
	if (!BN_sub(tmp, p, BN_value_one()) ||
	    BN_cmp(dh_pub, tmp) != -1) {		/* pub_exp > p-2 */
		BN_clear_free(tmp);
		logit("invalid public DH value: >= p-1");
		return 0;
	}
	BN_clear_free(tmp);

	for (i = 0; i <= n; i++)
		if (BN_is_bit_set(dh_pub, i))
			bits_set++;
	debug2("bits set: %d/%d", bits_set, BN_num_bits(p));

	/*
	 * if g==2 and bits_set==1 then computing log_g(dh_pub) is trivial
	 */
	if (bits_set < 4) {
		logit("invalid public DH value (%d/%d)",
		   bits_set, BN_num_bits(p));
		return 0;
	}
	return 1;
}
Example #10
0
   bool diffie_hellman::generate_params( int s, uint8_t g )
   {
        ssl_dh dh;
        DH_generate_parameters_ex(dh.obj, s, g, NULL);
#if OPENSSL_VERSION_NUMBER >= 0x10100000L
        ssl_bignum bn_p;
        DH_get0_pqg(dh.obj, (const BIGNUM**)&bn_p.obj, NULL, NULL);
        p.resize( BN_num_bytes( bn_p ) );
        if( p.size() )
            BN_bn2bin( bn_p, (unsigned char*)&p.front()  );
#else
        p.resize( BN_num_bytes( dh->p ) );
        if( p.size() )
            BN_bn2bin( dh->p, (unsigned char*)&p.front()  );
#endif
        this->g = g;
        return fc::validate( dh, valid );
   }
Example #11
0
BIGNUM *
DH_get_q(const DH *dh, BN_CTX *ctx)
{
    BIGNUM *q_new = NULL, *bn = NULL;
    int i;
    const BIGNUM *p, *q;

    check(dh, "Invalid arguments");

    DH_get0_pqg(dh, &p, &q, NULL);
    if (!q) {
        q_new = BN_new();
        bn = BN_dup(p);

        /* DH primes should be strong, based on a Sophie Germain prime q
         * p=(2*q)+1 or (p-1)/2=q */
        if (!q_new || !bn ||
                !BN_sub_word(bn, 1) ||
                !BN_rshift1(q_new, bn)) {
            goto err;
        }
    } else {
        q_new = BN_dup(q);
    }

    /* q should always be prime */
    i = BN_is_prime_ex(q_new, BN_prime_checks, ctx, NULL);
    if (i <= 0) {
       if (i == 0)
          log_err("Unable to get Sophie Germain prime");
       goto err;
    }

    return q_new;

err:
    if (bn)
        BN_clear_free(bn);
    if (q_new)
        BN_clear_free(q_new);

    return NULL;
}
Example #12
0
/*
 *  call-seq:
 *     dh.params -> hash
 *
 * Stores all parameters of key to the hash
 * INSECURE: PRIVATE INFORMATIONS CAN LEAK OUT!!!
 * Don't use :-)) (I's up to you)
 */
static VALUE
ossl_dh_get_params(VALUE self)
{
    DH *dh;
    VALUE hash;
    const BIGNUM *p, *q, *g, *pub_key, *priv_key;

    GetDH(self, dh);
    DH_get0_pqg(dh, &p, &q, &g);
    DH_get0_key(dh, &pub_key, &priv_key);

    hash = rb_hash_new();
    rb_hash_aset(hash, rb_str_new2("p"), ossl_bn_new(p));
    rb_hash_aset(hash, rb_str_new2("q"), ossl_bn_new(q));
    rb_hash_aset(hash, rb_str_new2("g"), ossl_bn_new(g));
    rb_hash_aset(hash, rb_str_new2("pub_key"), ossl_bn_new(pub_key));
    rb_hash_aset(hash, rb_str_new2("priv_key"), ossl_bn_new(priv_key));

    return hash;
}
Example #13
0
/*
 *  call-seq:
 *     dh.compute_key(pub_bn) -> aString
 *
 * Returns a String containing a shared secret computed from the other party's public value.
 * See DH_compute_key() for further information.
 *
 * === Parameters
 * * +pub_bn+ is a OpenSSL::BN, *not* the DH instance returned by
 * DH#public_key as that contains the DH parameters only.
 */
static VALUE
ossl_dh_compute_key(VALUE self, VALUE pub)
{
    DH *dh;
    const BIGNUM *pub_key, *dh_p;
    VALUE str;
    int len;

    GetDH(self, dh);
    DH_get0_pqg(dh, &dh_p, NULL, NULL);
    if (!dh_p)
	ossl_raise(eDHError, "incomplete DH");
    pub_key = GetBNPtr(pub);
    len = DH_size(dh);
    str = rb_str_new(0, len);
    if ((len = DH_compute_key((unsigned char *)RSTRING_PTR(str), pub_key, dh)) < 0) {
	ossl_raise(eDHError, NULL);
    }
    rb_str_set_len(str, len);

    return str;
}
Example #14
0
BIGNUM *
DH_get_order(const DH *dh, BN_CTX *ctx)
{
    BIGNUM *order = NULL, *bn = NULL;
    const BIGNUM *p, *g;

    check(dh && ctx, "Invalid argument");

    BN_CTX_start(ctx);

    DH_get0_pqg(dh, &p, NULL, &g);

    /* suppose the order of g is q-1 */
    order = DH_get_q(dh, ctx);
    bn = BN_CTX_get(ctx);
    if (!bn || !order || !BN_sub_word(order, 1)
          || !BN_mod_exp(bn, g, order, p, ctx))
        goto err;

    if (BN_cmp(bn, BN_value_one()) != 0) {
        /* if bn != 1, then q-1 is not the order of g, but p-1 should be */
        if (!BN_sub(order, p, BN_value_one()) ||
              !BN_mod_exp(bn, g, order, p, ctx))
           goto err;
        check(BN_cmp(bn, BN_value_one()) == 0, "Unable to get order");
    }

    BN_CTX_end(ctx);

    return order;

err:
    if (order)
        BN_clear_free(order);
    BN_CTX_end(ctx);

    return NULL;
}
Example #15
0
static LUA_FUNCTION(openssl_dh_parse)
{
    const BIGNUM *p = NULL, *q = NULL, *g = NULL, *pub = NULL, *pri = NULL;
    DH* dh = CHECK_OBJECT(1, DH, "openssl.dh");
    lua_newtable(L);

    lua_pushinteger(L, DH_size(dh));
    lua_setfield(L, -2, "size");

    lua_pushinteger(L, DH_bits(dh));
    lua_setfield(L, -2, "bits");

    DH_get0_pqg(dh, &p, &q, &g);
    DH_get0_key(dh, &pub, &pri);

    OPENSSL_PKEY_GET_BN(p, p);
    OPENSSL_PKEY_GET_BN(q, q);
    OPENSSL_PKEY_GET_BN(g, g);
    OPENSSL_PKEY_GET_BN(pub, priv_key);
    OPENSSL_PKEY_GET_BN(pri, pub_key);

    return 1;
}
Example #16
0
int dhparam_main(int argc, char **argv)
{
    BIO *in = NULL, *out = NULL;
    DH *dh = NULL;
    char *infile = NULL, *outfile = NULL, *prog, *inrand = NULL;
#ifndef OPENSSL_NO_DSA
    int dsaparam = 0;
#endif
    int i, text = 0, C = 0, ret = 1, num = 0, g = 0;
    int informat = FORMAT_PEM, outformat = FORMAT_PEM, check = 0, noout = 0;
    OPTION_CHOICE o;

    prog = opt_init(argc, argv, dhparam_options);
    while ((o = opt_next()) != OPT_EOF) {
        switch (o) {
        case OPT_EOF:
        case OPT_ERR:
 opthelp:
            BIO_printf(bio_err, "%s: Use -help for summary.\n", prog);
            goto end;
        case OPT_HELP:
            opt_help(dhparam_options);
            ret = 0;
            goto end;
        case OPT_INFORM:
            if (!opt_format(opt_arg(), OPT_FMT_PEMDER, &informat))
                goto opthelp;
            break;
        case OPT_OUTFORM:
            if (!opt_format(opt_arg(), OPT_FMT_PEMDER, &outformat))
                goto opthelp;
            break;
        case OPT_IN:
            infile = opt_arg();
            break;
        case OPT_OUT:
            outfile = opt_arg();
            break;
        case OPT_ENGINE:
            (void)setup_engine(opt_arg(), 0);
            break;
        case OPT_CHECK:
            check = 1;
            break;
        case OPT_TEXT:
            text = 1;
            break;
        case OPT_DSAPARAM:
#ifndef OPENSSL_NO_DSA
            dsaparam = 1;
#endif
            break;
        case OPT_C:
            C = 1;
            break;
        case OPT_2:
            g = 2;
            break;
        case OPT_5:
            g = 5;
            break;
        case OPT_NOOUT:
            noout = 1;
            break;
        case OPT_RAND:
            inrand = opt_arg();
            break;
        }
    }
    argc = opt_num_rest();
    argv = opt_rest();

    if (argv[0] && (!opt_int(argv[0], &num) || num <= 0))
        goto end;

    if (g && !num)
        num = DEFBITS;

# ifndef OPENSSL_NO_DSA
    if (dsaparam && g) {
        BIO_printf(bio_err,
                   "generator may not be chosen for DSA parameters\n");
        goto end;
    }
# endif
    /* DH parameters */
    if (num && !g)
        g = 2;

    if (num) {

        BN_GENCB *cb;
        cb = BN_GENCB_new();
        if (cb == NULL) {
            ERR_print_errors(bio_err);
            goto end;
        }

        BN_GENCB_set(cb, dh_cb, bio_err);
        if (!app_RAND_load_file(NULL, 1) && inrand == NULL) {
            BIO_printf(bio_err,
                       "warning, not much extra random data, consider using the -rand option\n");
        }
        if (inrand != NULL)
            BIO_printf(bio_err, "%ld semi-random bytes loaded\n",
                       app_RAND_load_files(inrand));

# ifndef OPENSSL_NO_DSA
        if (dsaparam) {
            DSA *dsa = DSA_new();

            BIO_printf(bio_err,
                       "Generating DSA parameters, %d bit long prime\n", num);
            if (dsa == NULL
                || !DSA_generate_parameters_ex(dsa, num, NULL, 0, NULL, NULL,
                                               cb)) {
                DSA_free(dsa);
                BN_GENCB_free(cb);
                ERR_print_errors(bio_err);
                goto end;
            }

            dh = DSA_dup_DH(dsa);
            DSA_free(dsa);
            if (dh == NULL) {
                BN_GENCB_free(cb);
                ERR_print_errors(bio_err);
                goto end;
            }
        } else
# endif
        {
            dh = DH_new();
            BIO_printf(bio_err,
                       "Generating DH parameters, %d bit long safe prime, generator %d\n",
                       num, g);
            BIO_printf(bio_err, "This is going to take a long time\n");
            if (dh == NULL || !DH_generate_parameters_ex(dh, num, g, cb)) {
                BN_GENCB_free(cb);
                ERR_print_errors(bio_err);
                goto end;
            }
        }

        BN_GENCB_free(cb);
        app_RAND_write_file(NULL);
    } else {

        in = bio_open_default(infile, 'r', informat);
        if (in == NULL)
            goto end;

# ifndef OPENSSL_NO_DSA
        if (dsaparam) {
            DSA *dsa;

            if (informat == FORMAT_ASN1)
                dsa = d2i_DSAparams_bio(in, NULL);
            else                /* informat == FORMAT_PEM */
                dsa = PEM_read_bio_DSAparams(in, NULL, NULL, NULL);

            if (dsa == NULL) {
                BIO_printf(bio_err, "unable to load DSA parameters\n");
                ERR_print_errors(bio_err);
                goto end;
            }

            dh = DSA_dup_DH(dsa);
            DSA_free(dsa);
            if (dh == NULL) {
                ERR_print_errors(bio_err);
                goto end;
            }
        } else
# endif
        {
            if (informat == FORMAT_ASN1)
                dh = d2i_DHparams_bio(in, NULL);
            else                /* informat == FORMAT_PEM */
                dh = PEM_read_bio_DHparams(in, NULL, NULL, NULL);

            if (dh == NULL) {
                BIO_printf(bio_err, "unable to load DH parameters\n");
                ERR_print_errors(bio_err);
                goto end;
            }
        }

        /* dh != NULL */
    }

    out = bio_open_default(outfile, 'w', outformat);
    if (out == NULL)
        goto end;

    if (text) {
        DHparams_print(out, dh);
    }

    if (check) {
        if (!DH_check(dh, &i)) {
            ERR_print_errors(bio_err);
            goto end;
        }
        if (i & DH_CHECK_P_NOT_PRIME)
            BIO_printf(bio_err, "WARNING: p value is not prime\n");
        if (i & DH_CHECK_P_NOT_SAFE_PRIME)
            BIO_printf(bio_err, "WARNING: p value is not a safe prime\n");
        if (i & DH_CHECK_Q_NOT_PRIME)
            BIO_printf(bio_err, "WARNING: q value is not a prime\n");
        if (i & DH_CHECK_INVALID_Q_VALUE)
            BIO_printf(bio_err, "WARNING: q value is invalid\n");
        if (i & DH_CHECK_INVALID_J_VALUE)
            BIO_printf(bio_err, "WARNING: j value is invalid\n");
        if (i & DH_UNABLE_TO_CHECK_GENERATOR)
            BIO_printf(bio_err,
                       "WARNING: unable to check the generator value\n");
        if (i & DH_NOT_SUITABLE_GENERATOR)
            BIO_printf(bio_err, "WARNING: the g value is not a generator\n");
        if (i == 0)
            BIO_printf(bio_err, "DH parameters appear to be ok.\n");
        if (num != 0 && i != 0) {
            /*
             * We have generated parameters but DH_check() indicates they are
             * invalid! This should never happen!
             */
            BIO_printf(bio_err, "ERROR: Invalid parameters generated\n");
            goto end;
        }
    }
    if (C) {
        unsigned char *data;
        int len, bits;
        const BIGNUM *pbn, *gbn;

        len = DH_size(dh);
        bits = DH_bits(dh);
        DH_get0_pqg(dh, &pbn, NULL, &gbn);
        data = app_malloc(len, "print a BN");
        BIO_printf(out, "#ifndef HEADER_DH_H\n"
                        "# include <openssl/dh.h>\n"
                        "#endif\n"
                        "\n");
        BIO_printf(out, "DH *get_dh%d()\n{\n", bits);
        print_bignum_var(out, pbn, "dhp", bits, data);
        print_bignum_var(out, gbn, "dhg", bits, data);
        BIO_printf(out, "    DH *dh = DH_new();\n"
                        "    BIGNUM *dhp_bn, *dhg_bn;\n"
                        "\n"
                        "    if (dh == NULL)\n"
                        "        return NULL;\n");
        BIO_printf(out, "    dhp_bn = BN_bin2bn(dhp_%d, sizeof (dhp_%d), NULL);\n",
                   bits, bits);
        BIO_printf(out, "    dhg_bn = BN_bin2bn(dhg_%d, sizeof (dhg_%d), NULL);\n",
                   bits, bits);
        BIO_printf(out, "    if (dhp_bn == NULL || dhg_bn == NULL\n"
                        "            || !DH_set0_pqg(dh, dhp_bn, NULL, dhg_bn)) {\n"
                        "        DH_free(dh);\n"
                        "        BN_free(dhp_bn);\n"
                        "        BN_free(dhg_bn);\n"
                        "        return NULL;\n"
                        "    }\n");
        if (DH_get_length(dh) > 0)
            BIO_printf(out,
                        "    if (!DH_set_length(dh, %ld)) {\n"
                        "        DH_free(dh);\n"
                        "    }\n", DH_get_length(dh));
        BIO_printf(out, "    return dh;\n}\n");
        OPENSSL_free(data);
    }

    if (!noout) {
        const BIGNUM *q;
        DH_get0_pqg(dh, NULL, &q, NULL);
        if (outformat == FORMAT_ASN1)
            i = i2d_DHparams_bio(out, dh);
        else if (q != NULL)
            i = PEM_write_bio_DHxparams(out, dh);
        else
            i = PEM_write_bio_DHparams(out, dh);
        if (!i) {
            BIO_printf(bio_err, "unable to write DH parameters\n");
            ERR_print_errors(bio_err);
            goto end;
        }
    }
    ret = 0;
 end:
    BIO_free(in);
    BIO_free_all(out);
    DH_free(dh);
    return (ret);
}
Example #17
0
static int dh_test(void)
{
    BN_GENCB *_cb = NULL;
    DH *a = NULL;
    DH *b = NULL;
    const BIGNUM *ap = NULL, *ag = NULL, *apub_key = NULL;
    const BIGNUM *bpub_key = NULL;
    BIGNUM *bp = NULL, *bg = NULL;
    unsigned char *abuf = NULL;
    unsigned char *bbuf = NULL;
    int i, alen, blen, aout, bout;
    int ret = 0;

    RAND_seed(rnd_seed, sizeof rnd_seed);

    if (!TEST_ptr(_cb = BN_GENCB_new()))
        goto err;
    BN_GENCB_set(_cb, &cb, NULL);
    if (!TEST_ptr(a = DH_new())
            || !TEST_true(DH_generate_parameters_ex(a, 64,
                                                    DH_GENERATOR_5, _cb)))
        goto err;

    if (!DH_check(a, &i))
        goto err;
    if (!TEST_false(i & DH_CHECK_P_NOT_PRIME)
            || !TEST_false(i & DH_CHECK_P_NOT_SAFE_PRIME)
            || !TEST_false(i & DH_UNABLE_TO_CHECK_GENERATOR)
            || !TEST_false(i & DH_NOT_SUITABLE_GENERATOR))
        goto err;

    DH_get0_pqg(a, &ap, NULL, &ag);

    if (!TEST_ptr(b = DH_new()))
        goto err;

    if (!TEST_ptr(bp = BN_dup(ap))
            || !TEST_ptr(bg = BN_dup(ag))
            || !TEST_true(DH_set0_pqg(b, bp, NULL, bg)))
        goto err;
    bp = bg = NULL;

    if (!DH_generate_key(a))
        goto err;
    DH_get0_key(a, &apub_key, NULL);

    if (!DH_generate_key(b))
        goto err;
    DH_get0_key(b, &bpub_key, NULL);

    alen = DH_size(a);
    if (!TEST_ptr(abuf = OPENSSL_malloc(alen))
            || !TEST_true((aout = DH_compute_key(abuf, bpub_key, a)) != -1))
        goto err;

    blen = DH_size(b);
    if (!TEST_ptr(bbuf = OPENSSL_malloc(blen))
            || !TEST_true((bout = DH_compute_key(bbuf, apub_key, b)) != -1))
        goto err;

    if (!TEST_true(aout >= 4)
            || !TEST_mem_eq(abuf, aout, bbuf, bout))
        goto err;

    ret = 1;

 err:
    OPENSSL_free(abuf);
    OPENSSL_free(bbuf);
    DH_free(b);
    DH_free(a);
    BN_free(bp);
    BN_free(bg);
    BN_GENCB_free(_cb);
    return ret;
}
Example #18
0
int
get_USM_DH_key(netsnmp_variable_list *vars, netsnmp_variable_list *dhvar,
               size_t outkey_len,
               netsnmp_pdu *pdu, const char *keyname,
               oid *keyoid, size_t keyoid_len) {
    u_char *dhkeychange;
    DH *dh;
    const BIGNUM *p, *g, *pub_key;
    BIGNUM *other_pub;
    u_char *key;
    size_t key_len;
            
    dhkeychange = (u_char *) malloc(2 * vars->val_len * sizeof(char));
    if (!dhkeychange)
        return SNMPERR_GENERR;
    
    memcpy(dhkeychange, vars->val.string, vars->val_len);

    {
        const unsigned char *cp = dhvar->val.string;
        dh = d2i_DHparams(NULL, &cp, dhvar->val_len);
    }

    if (dh)
        DH_get0_pqg(dh, &p, NULL, &g);

    if (!dh || !g || !p) {
        SNMP_FREE(dhkeychange);
        return SNMPERR_GENERR;
    }

    if (!DH_generate_key(dh)) {
        SNMP_FREE(dhkeychange);
        return SNMPERR_GENERR;
    }

    DH_get0_key(dh, &pub_key, NULL);
    if (vars->val_len != (unsigned int)BN_num_bytes(pub_key)) {
        SNMP_FREE(dhkeychange);
        fprintf(stderr,"incorrect diffie-helman lengths (%lu != %d)\n",
                (unsigned long)vars->val_len, BN_num_bytes(pub_key));
        return SNMPERR_GENERR;
    }

    BN_bn2bin(pub_key, dhkeychange + vars->val_len);

    key_len = DH_size(dh);
    if (!key_len) {
        SNMP_FREE(dhkeychange);
        return SNMPERR_GENERR;
    }
    key = (u_char *) malloc(key_len * sizeof(u_char));

    if (!key) {
        SNMP_FREE(dhkeychange);
        return SNMPERR_GENERR;
    }

    other_pub = BN_bin2bn(vars->val.string, vars->val_len, NULL);
    if (!other_pub) {
        SNMP_FREE(dhkeychange);
        SNMP_FREE(key);
        return SNMPERR_GENERR;
    }

    if (DH_compute_key(key, other_pub, dh)) {
        u_char *kp;

        printf("new %s key: 0x", keyname);
        for(kp = key + key_len - outkey_len;
            kp - key < (int)key_len;  kp++) {
            printf("%02x", (unsigned char) *kp);
        }
        printf("\n");
    }

    snmp_pdu_add_variable(pdu, keyoid, keyoid_len,
                          ASN_OCTET_STR, dhkeychange,
                          2 * vars->val_len);

    SNMP_FREE(dhkeychange);
    SNMP_FREE(other_pub);
    SNMP_FREE(key);

    return SNMPERR_SUCCESS;
}
Example #19
0
int main(int argc, char *argv[])
{
    BN_GENCB *_cb = NULL;
    DH *a = NULL;
    DH *b = NULL;
    BIGNUM *ap = NULL, *ag = NULL, *bp = NULL, *bg = NULL, *apub_key = NULL;
    BIGNUM *bpub_key = NULL, *priv_key = NULL;
    char buf[12] = {0};
    unsigned char *abuf = NULL;
    unsigned char *bbuf = NULL;
    int i, alen, blen, aout, bout;
    int ret = 1;
    BIO *out = NULL;

    CRYPTO_set_mem_debug(1);
    CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_ON);

    RAND_seed(rnd_seed, sizeof rnd_seed);

    out = BIO_new(BIO_s_file());
    if (out == NULL)
        EXIT(1);
    BIO_set_fp(out, stdout, BIO_NOCLOSE | BIO_FP_TEXT);

    _cb = BN_GENCB_new();
    if (_cb == NULL)
        goto err;
    BN_GENCB_set(_cb, &cb, out);
    if (((a = DH_new()) == NULL)
        || (!DH_generate_parameters_ex(a, 64, DH_GENERATOR_5, _cb)))
        goto err;

    if (!DH_check(a, &i))
        goto err;
    if (i & DH_CHECK_P_NOT_PRIME)
        BIO_puts(out, "p value is not prime\n");
    if (i & DH_CHECK_P_NOT_SAFE_PRIME)
        BIO_puts(out, "p value is not a safe prime\n");
    if (i & DH_UNABLE_TO_CHECK_GENERATOR)
        BIO_puts(out, "unable to check the generator value\n");
    if (i & DH_NOT_SUITABLE_GENERATOR)
        BIO_puts(out, "the g value is not a generator\n");

    DH_get0_pqg(a, &ap, NULL, &ag);
    BIO_puts(out, "\np    =");
    BN_print(out, ap);
    BIO_puts(out, "\ng    =");
    BN_print(out, ag);
    BIO_puts(out, "\n");

    b = DH_new();
    if (b == NULL)
        goto err;

    bp = BN_dup(ap);
    bg = BN_dup(ag);
    if ((bp == NULL) || (bg == NULL) || !DH_set0_pqg(b, bp, NULL, bg))
        goto err;
    bp = bg = NULL;

    if (!DH_generate_key(a))
        goto err;
    DH_get0_key(a, &apub_key, &priv_key);
    BIO_puts(out, "pri 1=");
    BN_print(out, priv_key);
    BIO_puts(out, "\npub 1=");
    BN_print(out, apub_key);
    BIO_puts(out, "\n");

    if (!DH_generate_key(b))
        goto err;
    DH_get0_key(b, &bpub_key, &priv_key);
    BIO_puts(out, "pri 2=");
    BN_print(out, priv_key);
    BIO_puts(out, "\npub 2=");
    BN_print(out, bpub_key);
    BIO_puts(out, "\n");

    alen = DH_size(a);
    abuf = OPENSSL_malloc(alen);
    if (abuf == NULL)
        goto err;

    aout = DH_compute_key(abuf, bpub_key, a);

    BIO_puts(out, "key1 =");
    for (i = 0; i < aout; i++) {
        sprintf(buf, "%02X", abuf[i]);
        BIO_puts(out, buf);
    }
    BIO_puts(out, "\n");

    blen = DH_size(b);
    bbuf = OPENSSL_malloc(blen);
    if (bbuf == NULL)
        goto err;

    bout = DH_compute_key(bbuf, apub_key, b);

    BIO_puts(out, "key2 =");
    for (i = 0; i < bout; i++) {
        sprintf(buf, "%02X", bbuf[i]);
        BIO_puts(out, buf);
    }
    BIO_puts(out, "\n");
    if ((aout < 4) || (bout != aout) || (memcmp(abuf, bbuf, aout) != 0)) {
        fprintf(stderr, "Error in DH routines\n");
        ret = 1;
    } else
        ret = 0;
    if (!run_rfc5114_tests())
        ret = 1;
 err:
    (void)BIO_flush(out);
    ERR_print_errors_fp(stderr);

    OPENSSL_free(abuf);
    OPENSSL_free(bbuf);
    DH_free(b);
    DH_free(a);
    BN_free(bp);
    BN_free(bg);
    BN_GENCB_free(_cb);
    BIO_free(out);

#ifndef OPENSSL_NO_CRYPTO_MDEBUG
    if (CRYPTO_mem_leaks_fp(stderr) <= 0)
        ret = 1;
#endif

    EXIT(ret);
}