Exemplo n.º 1
0
void openssl_dh_crypt()
{
	BIO *b;
	DH *d1, *d2;
	int i, len1, len2;
	unsigned char skey1[COMM_LEN], skey2[COMM_LEN];

	d1 = DH_new();
	d2 = DH_new();
	DH_generate_parameters_ex(d1, 64, DH_GENERATOR_2, NULL);
	DH_check(d1, &i);
	printf("\nDH key size: %d\n", DH_size(d1));
	DH_generate_key(d1);

	d2->p = BN_dup(d1->p);
	d2->g = BN_dup(d1->g);
	DH_generate_key(d2);
	DH_check_pub_key(d1, d1->pub_key, &i);
	len1 = DH_compute_key(skey1, d2->pub_key, d1);
	len2 = DH_compute_key(skey2, d1->pub_key, d2);
	if ((len1 != len2) || (memcmp(skey1, skey2, len1) != 0)) {
		printf("DH_compute_key err!\n");
		DH_free(d1);
		DH_free(d2);
		return;
	}

	b = BIO_new(BIO_s_file());
	BIO_set_fp(b, stdout, BIO_NOCLOSE);
	DHparams_print(b, d1);

	BIO_free(b);
	DH_free(d1);
	DH_free(d2);
}
Exemplo n.º 2
0
DH * dif_hel_setup()
{
    DH * new_dh = DH_new();
    if ( !new_dh )
    {
	printf("%s \n","Error:Creating new dh");
	error();
    }
    if ( !DH_generate_parameters_ex(new_dh,2,DH_GENERATOR_2,0))
    {
	printf("%s \n","Error:Generating paramters");
	error();
    }
    int dh_code = 0;
    if( !DH_check(new_dh,&dh_code))
    {
	printf("%s \n", "Error:Dh_check failed");
	error();
    }
    if(!DH_generate_key(new_dh))
    {
	printf("%s \n", "Error:Generating key failed");
	error();
    }
    return new_dh;
}
Exemplo n.º 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;
}
Exemplo n.º 4
0
static void *
dh_blocking_gen(void *arg)
{
    struct dh_blocking_gen_arg *gen = (struct dh_blocking_gen_arg *)arg;
    gen->result = DH_generate_parameters_ex(gen->dh, gen->size, gen->gen, gen->cb);
    return 0;
}
Exemplo n.º 5
0
int main(int arc, char *argv[])
{ 
	DH *dh = DH_new();

	BN_GENCB *(*cb)(BN_GENCB *, int, int);	
	cb = &callback;

	char buf[400];
	char *bufPtr = &buf[0];

	/* Load the human readable error strings for libcrypto */
	ERR_load_crypto_strings();
	/* Load all digest and cipher algorithms */
	OpenSSL_add_all_algorithms();
	/* Load config file, and other important initialisation */
	OPENSSL_config(NULL);

	/*
		use special PRNG if possible:
			* /dev/random
			* /dev/hwrng
			* ...
	*/

	/*
 		----------------------------	PARAMATER GEN	------------------------
	*/

	printf("start generation\n");
	DH_generate_parameters_ex(dh, 256, 2, NULL);
	printf("paramters DONE\n");

	if(dh->pub_key == NULL)
		printf("pubkey init to NULL\n");

	DH_generate_key(dh);
	printf("key DONE\n");
	bufPtr = BN_bn2hex(dh->p);
	printf ("prime    : %s\n", bufPtr);
	bufPtr = BN_bn2hex(dh->g);
	printf ("generator: %s\n", bufPtr);
	bufPtr = BN_bn2hex(dh->pub_key);
	printf ("pubkey   : %s\n", bufPtr);
	bufPtr = BN_bn2hex(dh->priv_key);
	printf ("privkey  : %s\n", bufPtr);

  /* Clean up */

  /* Removes all digests and ciphers */
  EVP_cleanup();

  /* if you omit the next, a small leak may be left when you make use of the BIO (low level API) for e.g. base64 transformations */
  CRYPTO_cleanup_all_ex_data();

  /* Remove error strings */
  ERR_free_strings();

  return 0;
}
Exemplo n.º 6
0
static int pkey_dh_paramgen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey)
{
    DH *dh = NULL;
    DH_PKEY_CTX *dctx = ctx->data;
    BN_GENCB *pcb, cb;
    int ret;
    if (dctx->rfc5114_param) {
        switch (dctx->rfc5114_param) {
        case 1:
            dh = DH_get_1024_160();
            break;

        case 2:
            dh = DH_get_2048_224();
            break;

        case 3:
            dh = DH_get_2048_256();
            break;

        default:
            return -2;
        }
        EVP_PKEY_assign(pkey, EVP_PKEY_DHX, dh);
        return 1;
    }

    if (ctx->pkey_gencb) {
        pcb = &cb;
        evp_pkey_set_cb_translate(pcb, ctx);
    } else
        pcb = NULL;
#ifndef OPENSSL_NO_DSA
    if (dctx->use_dsa) {
        DSA *dsa_dh;
        dsa_dh = dsa_dh_generate(dctx, pcb);
        if (!dsa_dh)
            return 0;
        dh = DSA_dup_DH(dsa_dh);
        DSA_free(dsa_dh);
        if (!dh)
            return 0;
        EVP_PKEY_assign(pkey, EVP_PKEY_DHX, dh);
        return 1;
    }
#endif
    dh = DH_new();
    if (!dh)
        return 0;
    ret = DH_generate_parameters_ex(dh,
                                    dctx->prime_len, dctx->generator, pcb);

    if (ret)
        EVP_PKEY_assign_DH(pkey, dh);
    else
        DH_free(dh);
    return ret;
}
Exemplo n.º 7
0
void OpenSSLGenerateDHParams()
{
	CachedDH = DH_new();
	if(CachedDH)
	{
		OpenSSLReseedRandom();
		DH_generate_parameters_ex(CachedDH, 512, DH_GENERATOR_5, 0); 
		//DH_check(CachedDH, &codes); 
	}
}
Exemplo n.º 8
0
static int ctx_set_dh(SSL_CTX *ctx, const char *dh_file,
                      const char *dh_special)
{
    DH *dh = NULL;
    FILE *fp = NULL;

    if (dh_special) {
        if (strcmp(dh_special, "NULL") == 0)
            return 1;
        if (strcmp(dh_special, "standard") == 0) {
            if ((dh = get_dh512()) == NULL) {
                fprintf(stderr, "Error, can't parse 'standard'"
                        " DH parameters\n");
                return 0;
            }
            fprintf(stderr, "Info, using 'standard' DH parameters\n");
            goto do_it;
        }
        if (strcmp(dh_special, "generate") != 0)
            /*
             * This shouldn't happen - screening values is handled in main().
             */
            abort();
        fprintf(stderr, "Info, generating DH parameters ... ");
        fflush(stderr);
        if (!(dh = DH_new()) || !DH_generate_parameters_ex(dh, 512,
                                                           DH_GENERATOR_5,
                                                           NULL)) {
            fprintf(stderr, "error!\n");
            if (dh)
                DH_free(dh);
            return 0;
        }
        fprintf(stderr, "complete\n");
        goto do_it;
    }
    /* So, we're loading dh_file */
    if ((fp = fopen(dh_file, "r")) == NULL) {
        fprintf(stderr, "Error, couldn't open '%s' for DH parameters\n",
                dh_file);
        return 0;
    }
    dh = PEM_read_DHparams(fp, NULL, NULL, NULL);
    fclose(fp);
    if (dh == NULL) {
        fprintf(stderr, "Error, could not parse DH parameters from '%s'\n",
                dh_file);
        return 0;
    }
    fprintf(stderr, "Info, using DH parameters from file '%s'\n", dh_file);
 do_it:
    SSL_CTX_set_tmp_dh(ctx, dh);
    DH_free(dh);
    return 1;
}
Exemplo n.º 9
0
/* DH: generate shared parameters
*/
static int dh_test()
{
    DH *dh;
    ERR_clear_error();
    dh = FIPS_dh_new();
    if (!dh)
        return 0;
    if (!DH_generate_parameters_ex(dh, 1024, 2, NULL))
        return 0;
    FIPS_dh_free(dh);
    return 1;
}
Exemplo n.º 10
0
/*
 *	Generate DH parameters.
 *
 *	Last resort if we can't load precomputed nor hardcoded
 *	parameters.
 */
static DH  *
generate_dh_parameters(int prime_len, int generator)
{
	DH		   *dh;

	if ((dh = DH_new()) == NULL)
		return NULL;

	if (DH_generate_parameters_ex(dh, prime_len, generator, NULL))
		return dh;

	DH_free(dh);
	return NULL;
}
Exemplo n.º 11
0
DH *DH_generate_parameters(int prime_len, int generator,
	     void (*callback)(int,int,void *), void *cb_arg)
	{
	BN_GENCB cb;
	DH *ret=NULL;

	if((ret=DH_new()) == NULL)
		return NULL;

	BN_GENCB_set_old(&cb, callback, cb_arg);

	if(DH_generate_parameters_ex(ret, prime_len, generator, &cb))
		return ret;
	DH_free(ret);
	return NULL;
	}
Exemplo n.º 12
0
std::string avjackif::async_client_hello(boost::asio::yield_context yield_context)
{
	proto::client_hello client_hello;
	client_hello.set_client("avim");
	client_hello.set_version(0001);

	unsigned char to[512];

	auto dh = DH_new();
	DH_generate_parameters_ex(dh,64,DH_GENERATOR_5,NULL);
	DH_generate_key(dh);

	// 把 g,p, pubkey 传过去
	client_hello.set_random_g((const void*)to, BN_bn2bin(dh->g, to));
	client_hello.set_random_p((const void*)to, BN_bn2bin(dh->p, to));
	client_hello.set_random_pub_key((const void*)to, BN_bn2bin(dh->pub_key, to));

	auto tobesend = av_router::encode(client_hello);

	boost::asio::async_write(*m_sock, boost::asio::buffer(tobesend), yield_context);

	// 解码
	std::unique_ptr<proto::server_hello> server_hello(
		(proto::server_hello*)async_read_protobuf_message(*m_sock, yield_context));

	m_remote_addr.reset(new proto::av_address(
		av_address_from_string(server_hello->server_av_address())));

	auto server_pubkey = BN_bin2bn((const unsigned char *) server_hello->random_pub_key().data(),
		server_hello->random_pub_key().length(), NULL);

	m_shared_key.resize(DH_size(dh));
	// 密钥就算出来啦!
	DH_compute_key(&m_shared_key[0], server_pubkey, dh);
	BN_free(server_pubkey);

    std::printf("key = 0x");
    for (int i=0; i<DH_size(dh); ++i)
	{
        std::printf("%x%x", (m_shared_key[i] >> 4) & 0xf, m_shared_key[i] & 0xf);
    }
    std::printf("\n");
	DH_free(dh);

	return server_hello->random_pub_key();
}
/*
 *	Generate DH parameters.
 *
 *	Last resort if we can't load precomputed nor hardcoded
 *	parameters.
 */
static DH  *
generate_dh_parameters(int prime_len, int generator)
{
#if (OPENSSL_VERSION_NUMBER >= 0x0090800fL)
	DH		   *dh;

	if ((dh = DH_new()) == NULL)
		return NULL;

	if (DH_generate_parameters_ex(dh, prime_len, generator, NULL))
		return dh;

	DH_free(dh);
	return NULL;
#else
	return DH_generate_parameters(prime_len, generator, NULL, NULL);
#endif
}
Exemplo n.º 14
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 );
   }
Exemplo n.º 15
0
Arquivo: 2cca.c Projeto: randunel/2cca
int generate_dhparam(int dh_bits)
{
    DH * dh ;
    char filename[FIELD_SZ+1];
    FILE * out;

    sprintf(filename, "dh%d.pem", dh_bits);
    if ((out=fopen(filename, "wb"))==NULL) {
        fprintf(stderr, "Cannot create %s: aborting\n", filename);
        return -1;
    }
    dh = DH_new();
    printf("Generating DH parameters (%d bits) -- this can take long\n", dh_bits);
    DH_generate_parameters_ex(dh, dh_bits, DH_GENERATOR_2, 0);
    PEM_write_DHparams(out, dh);
    fclose(out);
    printf("done\n");
    return 0;
}
Exemplo n.º 16
0
std::string SL::Remote_Access_Library::Crypto::Createdhparams(std::string savelocation, std::string filename, int bits)
{
	assert(INTERNAL::Started);//you must ensure proper startup of the encryption library!
	std::string saveloc = savelocation;
	if (saveloc.back() != '/' && saveloc.back() != '\\') saveloc += '/';
	assert(!saveloc.empty());

	DhParamRAII cry;
	auto keyloc = saveloc + filename + "_dhparams.pem";

	if (!DH_generate_parameters_ex(cry.dh, bits, 2, NULL)) return std::string("");
	cry.outfile = BIO_new(BIO_s_file());
	if (BIO_write_filename(cry.outfile, (void*)keyloc.c_str()) <= 0) return std::string("");
	int i = 0;
	if (cry.dh->q)
		i = PEM_write_bio_DHxparams(cry.outfile, cry.dh);
	else
		i = PEM_write_bio_DHparams(cry.outfile, cry.dh);
	if (!i) return std::string("");
	return keyloc;
}
Exemplo n.º 17
0
NOEXPORT void cron_dh_param(void) {
    SERVICE_OPTIONS *opt;
    DH *dh;

    if(!dh_needed)
        return;

    s_log(LOG_NOTICE, "Updating DH parameters");
#if OPENSSL_VERSION_NUMBER>=0x0090800fL
    /* generate 2048-bit DH parameters */
    dh=DH_new();
    if(!dh) {
        sslerror("DH_new");
        return;
    }
    if(!DH_generate_parameters_ex(dh, 2048, 2, NULL)) {
        DH_free(dh);
        sslerror("DH_generate_parameters_ex");
        return;
    }
#else /* OpenSSL older than 0.9.8 */
    dh=DH_generate_parameters(2048, 2, NULL, NULL);
    if(!dh) {
        sslerror("DH_generate_parameters");
        return;
    }
#endif

    /* update global dh_params for future configuration reloads */
    enter_critical_section(CRIT_DH); /* it only needs an rwlock here */
    DH_free(dh_params);
    dh_params=dh;
    leave_critical_section(CRIT_DH);

    /* set for all sections that require it */
    for(opt=service_options.next; opt; opt=opt->next)
        if(opt->option.dh_needed)
            SSL_CTX_set_tmp_dh(opt->ctx, dh);
    s_log(LOG_NOTICE, "DH parameters updated");
}
Exemplo n.º 18
0
static int pkey_dh_paramgen(EVP_PKEY_CTX *ctx, EVP_PKEY *pkey)
	{
	DH *dh = NULL;
	DH_PKEY_CTX *dctx = ctx->data;
	BN_GENCB *pcb, cb;
	int ret;
	if (ctx->pkey_gencb)
		{
		pcb = &cb;
		evp_pkey_set_cb_translate(pcb, ctx);
		}
	else
		pcb = NULL;
	dh = DH_new();
	if (!dh)
		return 0;
	ret = DH_generate_parameters_ex(dh,
					dctx->prime_len, dctx->generator, pcb);
	if (ret)
		EVP_PKEY_assign_DH(pkey, dh);
	else
		DH_free(dh);
	return ret;
	}
Exemplo n.º 19
0
DH *createPubkey(){

	DH *privkey;
	int codes;
	

	/* Generate the parameters to be used */
	if(NULL == (privkey = DH_new())) handleErrors();
	if(1 != DH_generate_parameters_ex(privkey, 512, DH_GENERATOR_2, NULL)) handleErrors();

	if(1 != DH_check(privkey, &codes)) handleErrors();
	if(codes != 0)
	{
	/* Problems have been found with the generated parameters */
	/* Handle these here - we'll just abort for this example */
	printf("DH_check failed\n");
	abort();
	}

	/* Generate the public and private key pair */
	if(1 != DH_generate_key(privkey)) handleErrors();
	return privkey;
	
}
Exemplo n.º 20
0
int
gendh_main(int argc, char **argv)
{
	BN_GENCB cb;
	DH *dh = NULL;
	int ret = 1, num = DEFBITS;
	int g = 2;
	char *outfile = NULL;
#ifndef OPENSSL_NO_ENGINE
	char *engine = NULL;
#endif
	BIO *out = NULL;

	BN_GENCB_set(&cb, dh_cb, bio_err);

	argv++;
	argc--;
	for (;;) {
		if (argc <= 0)
			break;
		if (strcmp(*argv, "-out") == 0) {
			if (--argc < 1)
				goto bad;
			outfile = *(++argv);
		} else if (strcmp(*argv, "-2") == 0)
			g = 2;
		/*
		 * else if (strcmp(*argv,"-3") == 0) g=3;
		 */
		else if (strcmp(*argv, "-5") == 0)
			g = 5;
#ifndef OPENSSL_NO_ENGINE
		else if (strcmp(*argv, "-engine") == 0) {
			if (--argc < 1)
				goto bad;
			engine = *(++argv);
		}
#endif
		else
			break;
		argv++;
		argc--;
	}
	if ((argc >= 1) && ((sscanf(*argv, "%d", &num) == 0) || (num < 0))) {
bad:
		BIO_printf(bio_err, "usage: gendh [args] [numbits]\n");
		BIO_printf(bio_err, " -out file - output the key to 'file\n");
		BIO_printf(bio_err, " -2        - use 2 as the generator value\n");
		/*
		 * BIO_printf(bio_err," -3        - use 3 as the generator
		 * value\n");
		 */
		BIO_printf(bio_err, " -5        - use 5 as the generator value\n");
#ifndef OPENSSL_NO_ENGINE
		BIO_printf(bio_err, " -engine e - use engine e, possibly a hardware device.\n");
#endif
		goto end;
	}
#ifndef OPENSSL_NO_ENGINE
	setup_engine(bio_err, engine, 0);
#endif

	out = BIO_new(BIO_s_file());
	if (out == NULL) {
		ERR_print_errors(bio_err);
		goto end;
	}
	if (outfile == NULL) {
		BIO_set_fp(out, stdout, BIO_NOCLOSE);
	} else {
		if (BIO_write_filename(out, outfile) <= 0) {
			perror(outfile);
			goto end;
		}
	}

	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 = DH_new()) == NULL) || !DH_generate_parameters_ex(dh, num, g, &cb))
		goto end;

	if (!PEM_write_bio_DHparams(out, dh))
		goto end;
	ret = 0;
end:
	if (ret != 0)
		ERR_print_errors(bio_err);
	if (out != NULL)
		BIO_free_all(out);
	if (dh != NULL)
		DH_free(dh);

	return (ret);
}
Exemplo n.º 21
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)
            printf("p value is not prime\n");
        if (i & DH_CHECK_P_NOT_SAFE_PRIME)
            printf("p value is not a safe prime\n");
        if (i & DH_UNABLE_TO_CHECK_GENERATOR)
            printf("unable to check the generator value\n");
        if (i & DH_NOT_SUITABLE_GENERATOR)
            printf("the g value is not a generator\n");
        if (i == 0)
            printf("DH parameters appear to be ok.\n");
    }
    if (C) {
        unsigned char *data;
        int len, bits;

        len = BN_num_bytes(dh->p);
        bits = BN_num_bits(dh->p);
        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, dh->p, "dhp", bits, data);
        print_bignum_var(out, dh->g, "dhg", bits, data);
        BIO_printf(out, "    DH *dh = DN_new();\n"
                        "\n"
                        "    if (dh == NULL)\n"
                        "        return NULL;\n");
        BIO_printf(out, "    dh->p = BN_bin2bn(dhp_%d, sizeof (dhp_%d), NULL);\n",
               bits, bits);
        BIO_printf(out, "    dh->g = BN_bin2bn(dhg_%d, sizeof (dhg_%d), NULL);\n",
               bits, bits);
        BIO_printf(out, "    if (!dh->p || !dh->g) {\n"
                        "        DH_free(dh);\n"
                        "        return NULL;\n"
                        "    }\n");
        if (dh->length)
            BIO_printf(out,
                        "    dh->length = %ld;\n", dh->length);
        BIO_printf(out, "    return dh;\n}\n");
        OPENSSL_free(data);
    }

    if (!noout) {
        if (outformat == FORMAT_ASN1)
            i = i2d_DHparams_bio(out, dh);
        else if (dh->q)
            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);
}
Exemplo n.º 22
0
int main(void)
{
    DH* dh_store;
    int codes;

    // Allocate and initialize a DH structure
    dh_store = DH_new();

    // If allocation failed
    if (dh_store == NULL)
    {
        fprintf(stderr, "Error allocating DH structure.\n");
        fprintf(stderr, "%s", ERR_reason_error_string(ERR_get_error()));
        return 1;
    }


    // Generate the prime, and and initialize the generator to be used for this exchange
    if (DH_generate_parameters_ex(dh_store, PRIME_LENGTH, DH_GENERATOR_2, NULL) != 1)
    {
        fprintf(stderr, "Error allocating parameters.\n");
        fprintf(stderr, "%s", ERR_reason_error_string(ERR_get_error()));
        return 1;
    }


    // Validate the generated prime (p) and the supplied generator (g).
    if (!DH_check(dh_store, &codes))
    {
        fprintf(stderr, "Could not perform check.\n");
        fprintf(stderr, "%s", ERR_reason_error_string(ERR_get_error()));
        return 1;
    }
    

    // Examine the results of the check performed earlier.
    if (codes != 0)
    {
        // Check and print out what kind of error was identified.
        if (codes & DH_UNABLE_TO_CHECK_GENERATOR)
            fprintf(stderr, "Generator must be either 2 or 5.\n");
        else if (codes & DH_NOT_SUITABLE_GENERATOR)
            fprintf(stderr, "Generator is not suitable.\n");
        else if (codes & DH_CHECK_P_NOT_PRIME)
            fprintf(stderr, "Non-prime value found in structure.");
        else if (codes & DH_CHECK_P_NOT_SAFE_PRIME)
            fprintf(stderr, "Unsafe prime found in structure.\n");
        else
            fprintf(stderr, "Unknown error.\n");
     
        fprintf(stderr, "%s", ERR_reason_error_string(ERR_get_error()));

        return 1;
    }


    // Generate the private value (aka private key) and the 
    // public value (aka public key).
    if (!DH_generate_key(dh_store))
    {
        fprintf(stderr, "Error generating public and private keys.");
        fprintf(stderr, "%s", ERR_reason_error_string(ERR_get_error()));        

        return 1;
    }

    printf("Generator:\n");
    BN_print_fp(stdout, dh_store->g);
    printf("\n\n");
    printf("Prime:\n");
    BN_print_fp(stdout, dh_store->p);
    printf("\n\n");
    printf("Private key:\n");
    BN_print_fp(stdout, dh_store->priv_key);
    printf("\n\n");
    printf("Public key:\n");
    BN_print_fp(stdout, dh_store->pub_key);
    printf("\n\n");

    // Free the DH structure.
    DH_free(dh_store);

    return 0;
}
Exemplo n.º 23
0
int
dhparam_main(int argc, char **argv)
{
	BIO *in = NULL, *out = NULL;
	char *num_bits = NULL;
	DH *dh = NULL;
	int num = 0;
	int ret = 1;
	int i;

	memset(&dhparam_config, 0, sizeof(dhparam_config));

	dhparam_config.informat = FORMAT_PEM;
	dhparam_config.outformat = FORMAT_PEM;

	if (options_parse(argc, argv, dhparam_options, &num_bits, NULL) != 0) {
		dhparam_usage();
		return (1);
	}

	if (num_bits != NULL) {
		if(sscanf(num_bits, "%d", &num) == 0 || num <= 0) {
			BIO_printf(bio_err, "invalid number of bits: %s\n",
			    num_bits);
			return (1);
		}
	}

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

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

	if (num) {

		BN_GENCB cb;
		BN_GENCB_set(&cb, dh_cb, bio_err);
		if (dhparam_config.dsaparam) {
			DSA *dsa = DSA_new();

			BIO_printf(bio_err, "Generating DSA parameters, %d bit long prime\n", num);
			if (!dsa || !DSA_generate_parameters_ex(dsa, num,
				NULL, 0, NULL, NULL, &cb)) {
				if (dsa)
					DSA_free(dsa);
				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 {
			dh = DH_new();
			BIO_printf(bio_err, "Generating DH parameters, %d bit long safe prime, generator %d\n", num, dhparam_config.g);
			BIO_printf(bio_err, "This is going to take a long time\n");
			if (!dh || !DH_generate_parameters_ex(dh, num, dhparam_config.g, &cb)) {
				ERR_print_errors(bio_err);
				goto end;
			}
		}
	} else {

		in = BIO_new(BIO_s_file());
		if (in == NULL) {
			ERR_print_errors(bio_err);
			goto end;
		}
		if (dhparam_config.infile == NULL)
			BIO_set_fp(in, stdin, BIO_NOCLOSE);
		else {
			if (BIO_read_filename(in, dhparam_config.infile) <= 0) {
				perror(dhparam_config.infile);
				goto end;
			}
		}

		if (dhparam_config.informat != FORMAT_ASN1 &&
		    dhparam_config.informat != FORMAT_PEM) {
			BIO_printf(bio_err, "bad input format specified\n");
			goto end;
		}
		if (dhparam_config.dsaparam) {
			DSA *dsa;

			if (dhparam_config.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
		{
			if (dhparam_config.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_new(BIO_s_file());
	if (out == NULL) {
		ERR_print_errors(bio_err);
		goto end;
	}
	if (dhparam_config.outfile == NULL) {
		BIO_set_fp(out, stdout, BIO_NOCLOSE);
	} else {
		if (BIO_write_filename(out, dhparam_config.outfile) <= 0) {
			perror(dhparam_config.outfile);
			goto end;
		}
	}


	if (dhparam_config.text) {
		DHparams_print(out, dh);
	}
	if (dhparam_config.check) {
		if (!DH_check(dh, &i)) {
			ERR_print_errors(bio_err);
			goto end;
		}
		if (i & DH_CHECK_P_NOT_PRIME)
			printf("p value is not prime\n");
		if (i & DH_CHECK_P_NOT_SAFE_PRIME)
			printf("p value is not a safe prime\n");
		if (i & DH_UNABLE_TO_CHECK_GENERATOR)
			printf("unable to check the generator value\n");
		if (i & DH_NOT_SUITABLE_GENERATOR)
			printf("the g value is not a generator\n");
		if (i == 0)
			printf("DH parameters appear to be ok.\n");
	}
	if (dhparam_config.C) {
		unsigned char *data;
		int len, l, bits;

		len = BN_num_bytes(dh->p);
		bits = BN_num_bits(dh->p);
		data = malloc(len);
		if (data == NULL) {
			perror("malloc");
			goto end;
		}
		printf("#ifndef HEADER_DH_H\n"
		    "#include <openssl/dh.h>\n"
		    "#endif\n");
		printf("DH *get_dh%d()\n\t{\n", bits);

		l = BN_bn2bin(dh->p, data);
		printf("\tstatic unsigned char dh%d_p[] = {", bits);
		for (i = 0; i < l; i++) {
			if ((i % 12) == 0)
				printf("\n\t\t");
			printf("0x%02X, ", data[i]);
		}
		printf("\n\t\t};\n");

		l = BN_bn2bin(dh->g, data);
		printf("\tstatic unsigned char dh%d_g[] = {", bits);
		for (i = 0; i < l; i++) {
			if ((i % 12) == 0)
				printf("\n\t\t");
			printf("0x%02X, ", data[i]);
		}
		printf("\n\t\t};\n");

		printf("\tDH *dh;\n\n");
		printf("\tif ((dh = DH_new()) == NULL) return(NULL);\n");
		printf("\tdh->p = BN_bin2bn(dh%d_p, sizeof(dh%d_p), NULL);\n",
		    bits, bits);
		printf("\tdh->g = BN_bin2bn(dh%d_g, sizeof(dh%d_g), NULL);\n",
		    bits, bits);
		printf("\tif ((dh->p == NULL) || (dh->g == NULL))\n");
		printf("\t\t{ DH_free(dh); return(NULL); }\n");
		if (dh->length)
			printf("\tdh->length = %ld;\n", dh->length);
		printf("\treturn(dh);\n\t}\n");
		free(data);
	}
	if (!dhparam_config.noout) {
		if (dhparam_config.outformat == FORMAT_ASN1)
			i = i2d_DHparams_bio(out, dh);
		else if (dhparam_config.outformat == FORMAT_PEM)
			i = PEM_write_bio_DHparams(out, dh);
		else {
			BIO_printf(bio_err, "bad output format specified for outfile\n");
			goto end;
		}
		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);
	if (out != NULL)
		BIO_free_all(out);
	if (dh != NULL)
		DH_free(dh);

	return (ret);
}
Exemplo n.º 24
0
int MAIN(int argc, char **argv)
{
    BIO *in = NULL, *out = NULL;
    char *infile, *outfile, *prog;
    char *inrand = NULL;
    char *id = NULL;

    apps_startup();

    if (bio_err == NULL)
        if ((bio_err = BIO_new(BIO_s_file())) != NULL)
            BIO_set_fp(bio_err, stderr, BIO_NOCLOSE | BIO_FP_TEXT);

    if (!load_config(bio_err, NULL))
        goto end;

    outfile = NULL;

    prog = argv[0];
    argc--;
    argv++;
    while (argc >= 1) {
        if (strcmp(*argv, "-inform") == 0) {
            if (--argc < 1)
                goto bad;
            informat = str2fmt(*(++argv));
        } else if (strcmp(*argv, "-outform") == 0) {
            if (--argc < 1)
                goto bad;
            outformat = str2fmt(*(++argv));
        } else if (strcmp(*argv, "-in") == 0) {
            if (--argc < 1)
                goto bad;
            infile = *(++argv);
        } else if (strcmp(*argv, "-out") == 0) {
            if (--argc < 1)
                goto bad;
            outfile = *(++argv);
        }
        else if (strcmp(*argv, "-check") == 0)
            check = 1;
        else if (strcmp(*argv, "-text") == 0)
            text = 1;
        else if (strcmp(*argv, "-dsaparam") == 0)
            dsaparam = 1;
        else if (strcmp(*argv, "-C") == 0)
            C = 1;
        else if (strcmp(*argv, "-noout") == 0)
            noout = 1;
        else if (strcmp(*argv, "-2") == 0)
            g = 2;
        else if (strcmp(*argv, "-5") == 0)
            g = 5;
        else if (strcmp(*argv, "-rand") == 0) {
            if (--argc < 1)
                goto bad;
            inrand = *(++argv);
        } else if (((sscanf(*argv, "%d", &num) == 0) || (num <= 0)))
            goto bad;
        argv++;
        argc--;
    }

    if (badops) {
 bad:
        BIO_printf(bio_err, "%s [options] [numbits]\n", prog);
        BIO_printf(bio_err, "where options are\n");
        BIO_printf(bio_err, " -inform arg   input format - one of DER PEM\n");
        BIO_printf(bio_err,
                   " -outform arg  output format - one of DER PEM\n");
        BIO_printf(bio_err, " -in arg       input file\n");
        BIO_printf(bio_err, " -out arg      output file\n");
        BIO_printf(bio_err,
                   " -dsaparam     read or generate DSA parameters, convert to DH\n");
        BIO_printf(bio_err, " -check        check the DH parameters\n");
        BIO_printf(bio_err,
                   " -text         print a text form of the DH parameters\n");
        BIO_printf(bio_err, " -C            Output C code\n");
        BIO_printf(bio_err,
                   " -2            generate parameters using  2 as the generator value\n");
        BIO_printf(bio_err,
                   " -5            generate parameters using  5 as the generator value\n");
        BIO_printf(bio_err,
                   " numbits       number of bits in to generate (default 2048)\n");
        BIO_printf(bio_err, " -rand file%cfile%c...\n", LIST_SEPARATOR_CHAR,
                   LIST_SEPARATOR_CHAR);
        BIO_printf(bio_err,
                   "               - load the file (or the files in the directory) into\n");
        BIO_printf(bio_err, "               the random number generator\n");
        BIO_printf(bio_err, " -noout        no output\n");
        goto end;
    }

    ERR_load_crypto_strings();

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

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

    if (num) {

        BN_GENCB cb;
        BN_GENCB_set(&cb, dh_cb, bio_err);
        if (!app_RAND_load_file(NULL, bio_err, 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
                || !DSA_generate_parameters_ex(dsa, num, NULL, 0, NULL, NULL,
                                               &cb)) {
                if (dsa)
                    DSA_free(dsa);
                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
        {
            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 || !DH_generate_parameters_ex(dh, num, g, &cb)) {
                ERR_print_errors(bio_err);
                goto end;
            }
        }

        app_RAND_write_file(NULL, bio_err);
    } else {

        in = BIO_new(BIO_s_file());
        if (in == NULL) {
            ERR_print_errors(bio_err);
            goto end;
        }
        if (infile == NULL)
            BIO_set_fp(in, stdin, BIO_NOCLOSE);
        else {
            if (BIO_read_filename(in, infile) <= 0) {
                perror(infile);
                goto end;
            }
        }

        if (informat != FORMAT_ASN1 && informat != FORMAT_PEM) {
            BIO_printf(bio_err, "bad input format specified\n");
            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_new(BIO_s_file());
    if (out == NULL) {
        ERR_print_errors(bio_err);
        goto end;
    }
    if (outfile == NULL) {
        BIO_set_fp(out, stdout, BIO_NOCLOSE);
    } else {
        if (BIO_write_filename(out, outfile) <= 0) {
            perror(outfile);
            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)
            printf("p value is not prime\n");
        if (i & DH_CHECK_P_NOT_SAFE_PRIME)
            printf("p value is not a safe prime\n");
        if (i & DH_UNABLE_TO_CHECK_GENERATOR)
            printf("unable to check the generator value\n");
        if (i & DH_NOT_SUITABLE_GENERATOR)
            printf("the g value is not a generator\n");
        if (i == 0)
            printf("DH parameters appear to be ok.\n");
    }
    if (C) {
        unsigned char *data;
        int len, l, bits;

        len = BN_num_bytes(dh->p);
        bits = BN_num_bits(dh->p);
        data = (unsigned char *)OPENSSL_malloc(len);
        if (data == NULL) {
            perror("OPENSSL_malloc");
            goto end;
        }
        printf("#ifndef HEADER_DH_H\n"
               "#include <openssl/dh.h>\n" "#endif\n");
        printf("DH *get_dh%d()\n\t{\n", bits);

        l = BN_bn2bin(dh->p, data);
        printf("\tstatic unsigned char dh%d_p[]={", bits);
        for (i = 0; i < l; i++) {
            if ((i % 12) == 0)
                printf("\n\t\t");
            printf("0x%02X,", data[i]);
        }
        printf("\n\t\t};\n");

        l = BN_bn2bin(dh->g, data);
        printf("\tstatic unsigned char dh%d_g[]={", bits);
        for (i = 0; i < l; i++) {
            if ((i % 12) == 0)
                printf("\n\t\t");
            printf("0x%02X,", data[i]);
        }
        printf("\n\t\t};\n");

        printf("\tDH *dh;\n\n");
        printf("\tif ((dh=DH_new()) == NULL) return(NULL);\n");
        printf("\tdh->p=BN_bin2bn(dh%d_p,sizeof(dh%d_p),NULL);\n",
               bits, bits);
        printf("\tdh->g=BN_bin2bn(dh%d_g,sizeof(dh%d_g),NULL);\n",
               bits, bits);
        printf("\tif ((dh->p == NULL) || (dh->g == NULL))\n");
        printf("\t\t{ DH_free(dh); return(NULL); }\n");
        if (dh->length)
            printf("\tdh->length = %ld;\n", dh->length);
        printf("\treturn(dh);\n\t}\n");
        OPENSSL_free(data);
    }

    if (!noout) {
        if (outformat == FORMAT_ASN1)
            i = i2d_DHparams_bio(out, dh);
        else if (outformat == FORMAT_PEM) {
            if (dh->q)
                i = PEM_write_bio_DHxparams(out, dh);
            else
                i = PEM_write_bio_DHparams(out, dh);
        } else {
            BIO_printf(bio_err, "bad output format specified for outfile\n");
            goto end;
        }
        if (!i) {
            BIO_printf(bio_err, "unable to write DH parameters\n");
            ERR_print_errors(bio_err);
            goto end;
        }
    }
    ret = 0;
 end:
    if (in != NULL)
        BIO_free(in);
    if (out != NULL)
        BIO_free_all(out);
    if (dh != NULL)
        DH_free(dh);
    apps_shutdown();
    OPENSSL_EXIT(ret);
}
Exemplo n.º 25
0
int MAIN(int argc, char **argv)
	{
	BN_GENCB cb;
	DH *dh=NULL;
	int ret=1,num=DEFBITS;
	int g=2;
	char *outfile=NULL;
	char *inrand=NULL;
#ifndef OPENSSL_NO_ENGINE
	char *engine=NULL;
#endif
	BIO *out=NULL;

	apps_startup();

	BN_GENCB_set(&cb, dh_cb, bio_err);
	if (bio_err == NULL)
		if ((bio_err=BIO_new(BIO_s_file())) != NULL)
			BIO_set_fp(bio_err,stderr,BIO_NOCLOSE|BIO_FP_TEXT);

	if (!load_config(bio_err, NULL))
		goto end;

	argv++;
	argc--;
	for (;;)
		{
		if (argc <= 0) break;
		if (strcmp(*argv,"-out") == 0)
			{
			if (--argc < 1) goto bad;
			outfile= *(++argv);
			}
		else if (strcmp(*argv,"-2") == 0)
			g=2;
	/*	else if (strcmp(*argv,"-3") == 0)
			g=3; */
		else if (strcmp(*argv,"-5") == 0)
			g=5;
#ifndef OPENSSL_NO_ENGINE
		else if (strcmp(*argv,"-engine") == 0)
			{
			if (--argc < 1) goto bad;
			engine= *(++argv);
			}
#endif
		else if (strcmp(*argv,"-rand") == 0)
			{
			if (--argc < 1) goto bad;
			inrand= *(++argv);
			}
		else
			break;
		argv++;
		argc--;
		}
	if ((argc >= 1) && ((sscanf(*argv,"%d",&num) == 0) || (num < 0)))
		{
bad:
		BIO_printf(bio_err,"usage: gendh [args] [numbits]\n");
		BIO_printf(bio_err," -out file - output the key to 'file\n");
		BIO_printf(bio_err," -2        - use 2 as the generator value\n");
	/*	BIO_printf(bio_err," -3        - use 3 as the generator value\n"); */
		BIO_printf(bio_err," -5        - use 5 as the generator value\n");
#ifndef OPENSSL_NO_ENGINE
		BIO_printf(bio_err," -engine e - use engine e, possibly a hardware device.\n");
#endif
		BIO_printf(bio_err," -rand file%cfile%c...\n", LIST_SEPARATOR_CHAR, LIST_SEPARATOR_CHAR);
		BIO_printf(bio_err,"           - load the file (or the files in the directory) into\n");
		BIO_printf(bio_err,"             the random number generator\n");
		goto end;
		}
		
#ifndef OPENSSL_NO_ENGINE
        setup_engine(bio_err, engine, 0);
#endif

	out=BIO_new(BIO_s_file());
	if (out == NULL)
		{
		ERR_print_errors(bio_err);
		goto end;
		}

	if (outfile == NULL)
		{
		BIO_set_fp(out,stdout,BIO_NOCLOSE);
#ifdef OPENSSL_SYS_VMS
		{
		BIO *tmpbio = BIO_new(BIO_f_linebuffer());
		out = BIO_push(tmpbio, out);
		}
#endif
		}
	else
		{
		if (BIO_write_filename(out,outfile) <= 0)
			{
			perror(outfile);
			goto end;
			}
		}

	if (!app_RAND_load_file(NULL, bio_err, 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));

	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 = DH_new()) == NULL) || !DH_generate_parameters_ex(dh, num, g, &cb))
		goto end;
		
	app_RAND_write_file(NULL, bio_err);

	if (!PEM_write_bio_DHparams(out,dh))
		goto end;
	ret=0;
end:
	if (ret != 0)
		ERR_print_errors(bio_err);
	if (out != NULL) BIO_free_all(out);
	if (dh != NULL) DH_free(dh);
	apps_shutdown();
	OPENSSL_EXIT(ret);
	}
Exemplo n.º 26
0
static isc_result_t
openssldh_generate(dst_key_t *key, int generator, void (*callback)(int)) {
	DH *dh = NULL;
#if OPENSSL_VERSION_NUMBER > 0x00908000L
	BN_GENCB *cb;
#if OPENSSL_VERSION_NUMBER < 0x10100000L
	BN_GENCB _cb;
#endif
	union {
		void *dptr;
		void (*fptr)(int);
	} u;
#else

	UNUSED(callback);
#endif

	if (generator == 0) {
		if (key->key_size == 768 ||
		    key->key_size == 1024 ||
		    key->key_size == 1536)
		{
			dh = DH_new();
			if (dh == NULL)
				return (dst__openssl_toresult(ISC_R_NOMEMORY));
			if (key->key_size == 768)
				dh->p = bn768;
			else if (key->key_size == 1024)
				dh->p = bn1024;
			else
				dh->p = bn1536;
			dh->g = bn2;
		} else
			generator = 2;
	}

	if (generator != 0) {
#if OPENSSL_VERSION_NUMBER > 0x00908000L
		dh = DH_new();
		if (dh == NULL)
			return (dst__openssl_toresult(ISC_R_NOMEMORY));
		cb = BN_GENCB_new();
#if OPENSSL_VERSION_NUMBER >= 0x10100000L
		if (cb == NULL) {
			DH_free(dh);
			return (dst__openssl_toresult(ISC_R_NOMEMORY));
		}
#endif
		if (callback == NULL) {
			BN_GENCB_set_old(cb, NULL, NULL);
		} else {
			u.fptr = callback;
			BN_GENCB_set(cb, &progress_cb, u.dptr);
		}

		if (!DH_generate_parameters_ex(dh, key->key_size, generator,
					       cb)) {
			DH_free(dh);
			BN_GENCB_free(cb);
			return (dst__openssl_toresult2(
					"DH_generate_parameters_ex",
					DST_R_OPENSSLFAILURE));
		}
		BN_GENCB_free(cb);
#else
		dh = DH_generate_parameters(key->key_size, generator,
					    NULL, NULL);
		if (dh == NULL)
			return (dst__openssl_toresult2(
					"DH_generate_parameters",
					DST_R_OPENSSLFAILURE));
#endif
	}

	if (DH_generate_key(dh) == 0) {
		DH_free(dh);
		return (dst__openssl_toresult2("DH_generate_key",
					       DST_R_OPENSSLFAILURE));
	}
	dh->flags &= ~DH_FLAG_CACHE_MONT_P;

	key->keydata.dh = dh;

	return (ISC_R_SUCCESS);
}
Exemplo n.º 27
0
static Ecore_Con_Ssl_Error
_ecore_con_ssl_server_prepare_openssl(Ecore_Con_Server *svr,
                                      int               ssl_type)
{
   long options;
   int dh = 0;

   if (ssl_type & ECORE_CON_USE_SSL2)
     return ECORE_CON_SSL_ERROR_SSL2_NOT_SUPPORTED;

   switch (ssl_type)
     {
      case ECORE_CON_USE_SSL3:
      case ECORE_CON_USE_SSL3 | ECORE_CON_LOAD_CERT:
        if (!svr->created)
          SSL_ERROR_CHECK_GOTO_ERROR(!(svr->ssl_ctx = SSL_CTX_new(SSLv3_client_method())));
        else
          SSL_ERROR_CHECK_GOTO_ERROR(!(svr->ssl_ctx = SSL_CTX_new(SSLv3_server_method())));
        break;

      case ECORE_CON_USE_TLS:
      case ECORE_CON_USE_TLS | ECORE_CON_LOAD_CERT:
        if (!svr->created)
          SSL_ERROR_CHECK_GOTO_ERROR(!(svr->ssl_ctx = SSL_CTX_new(TLSv1_client_method())));
        else
          SSL_ERROR_CHECK_GOTO_ERROR(!(svr->ssl_ctx = SSL_CTX_new(TLSv1_server_method())));
        break;

      case ECORE_CON_USE_MIXED:
      case ECORE_CON_USE_MIXED | ECORE_CON_LOAD_CERT:
        if (!svr->created)
          SSL_ERROR_CHECK_GOTO_ERROR(!(svr->ssl_ctx = SSL_CTX_new(SSLv23_client_method())));
        else
          SSL_ERROR_CHECK_GOTO_ERROR(!(svr->ssl_ctx = SSL_CTX_new(SSLv23_server_method())));
        options = SSL_CTX_get_options(svr->ssl_ctx);
        SSL_CTX_set_options(svr->ssl_ctx, options | SSL_OP_NO_SSLv2 | SSL_OP_SINGLE_DH_USE);
        break;

      default:
        return ECORE_CON_SSL_ERROR_NONE;
     }

   if ((!svr->use_cert) && svr->created)
     {
        DH *dh_params;
        INF("Generating DH params");
        SSL_ERROR_CHECK_GOTO_ERROR(!(dh_params = DH_new()));
        SSL_ERROR_CHECK_GOTO_ERROR(!DH_generate_parameters_ex(dh_params, 1024, DH_GENERATOR_5, NULL));
        SSL_ERROR_CHECK_GOTO_ERROR(!DH_check(dh_params, &dh));
        SSL_ERROR_CHECK_GOTO_ERROR((dh & DH_CHECK_P_NOT_PRIME) || (dh & DH_CHECK_P_NOT_SAFE_PRIME));
        SSL_ERROR_CHECK_GOTO_ERROR(!DH_generate_key(dh_params));
        SSL_ERROR_CHECK_GOTO_ERROR(!SSL_CTX_set_tmp_dh(svr->ssl_ctx, dh_params));
        DH_free(dh_params);
        INF("DH params successfully generated and applied!");
        SSL_ERROR_CHECK_GOTO_ERROR(!SSL_CTX_set_cipher_list(svr->ssl_ctx, "aNULL:!eNULL:!LOW:!EXPORT:@STRENGTH"));
     }
   else if (!svr->use_cert)
     SSL_ERROR_CHECK_GOTO_ERROR(!SSL_CTX_set_cipher_list(svr->ssl_ctx, "aNULL:!eNULL:!LOW:!EXPORT:!ECDH:RSA:AES:!PSK:@STRENGTH"));

   return ECORE_CON_SSL_ERROR_NONE;

error:
   if (dh)
     {
        if (dh & DH_CHECK_P_NOT_PRIME)
          ERR("openssl error: dh_params could not generate a prime!");
        else
          ERR("openssl error: dh_params could not generate a safe prime!");
     }
   else
     _openssl_print_errors();
   _ecore_con_ssl_server_shutdown_openssl(svr);
   return ECORE_CON_SSL_ERROR_SERVER_INIT_FAILED;
}
Exemplo n.º 28
0
int dhparam_main(int argc, char **argv)
{
    BIO *in = NULL, *out = NULL;
    DH *dh = NULL;
    char *infile = NULL, *outfile = NULL, *prog;
    ENGINE *e = 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:
            e = 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_R_CASES:
            if (!opt_rand(o))
                goto end;
            break;
        }
    }
    argc = opt_num_rest();
    argv = opt_rest();

    if (argv[0] != NULL && (!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

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

    /* 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);

# 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);
    } 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) {
                /*
                 * We have no PEM header to determine what type of DH params it
                 * is. We'll just try both.
                 */
                dh = d2i_DHparams_bio(in, NULL);
                /* BIO_reset() returns 0 for success for file BIOs only!!! */
                if (dh == NULL && BIO_reset(in) == 0)
                    dh = d2i_DHxparams_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 */
    }

    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, "static DH *get_dh%d(void)\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 *p, *g;\n"
                        "\n"
                        "    if (dh == NULL)\n"
                        "        return NULL;\n");
        BIO_printf(out, "    p = BN_bin2bn(dhp_%d, sizeof(dhp_%d), NULL);\n",
                   bits, bits);
        BIO_printf(out, "    g = BN_bin2bn(dhg_%d, sizeof(dhg_%d), NULL);\n",
                   bits, bits);
        BIO_printf(out, "    if (p == NULL || g == NULL\n"
                        "            || !DH_set0_pqg(dh, p, NULL, g)) {\n"
                        "        DH_free(dh);\n"
                        "        BN_free(p);\n"
                        "        BN_free(g);\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"
                        "        return NULL;\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) {
            if (q != NULL)
                i = i2d_DHxparams_bio(out, dh);
            else
                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);
    release_engine(e);
    return ret;
}
Exemplo n.º 29
0
int main(int argc, char *argv[])
	{
	BN_GENCB _cb;
	DH *a;
	DH *b=NULL;
	char buf[12];
	unsigned char *abuf=NULL,*bbuf=NULL;
	int i,alen,blen,aout,bout,ret=1;
	BIO *out;

	CRYPTO_malloc_debug_init();
	CRYPTO_dbg_set_options(V_CRYPTO_MDEBUG_ALL);
	CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_ON);

#ifdef OPENSSL_SYS_WIN32
	CRYPTO_malloc_init();
#endif

	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);

	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");

	BIO_puts(out,"\np    =");
	BN_print(out,a->p);
	BIO_puts(out,"\ng    =");
	BN_print(out,a->g);
	BIO_puts(out,"\n");

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

	b->p=BN_dup(a->p);
	b->g=BN_dup(a->g);
	if ((b->p == NULL) || (b->g == NULL)) goto err;

	/* Set a to run with normal modexp and b to use constant time */
	a->flags &= ~DH_FLAG_NO_EXP_CONSTTIME;
	b->flags |= DH_FLAG_NO_EXP_CONSTTIME;

	if (!DH_generate_key(a)) goto err;
	BIO_puts(out,"pri 1=");
	BN_print(out,a->priv_key);
	BIO_puts(out,"\npub 1=");
	BN_print(out,a->pub_key);
	BIO_puts(out,"\n");

	if (!DH_generate_key(b)) goto err;
	BIO_puts(out,"pri 2=");
	BN_print(out,b->priv_key);
	BIO_puts(out,"\npub 2=");
	BN_print(out,b->pub_key);
	BIO_puts(out,"\n");

	alen=DH_size(a);
	abuf=(unsigned char *)OPENSSL_malloc(alen);
	aout=DH_compute_key(abuf,b->pub_key,a);

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

	blen=DH_size(b);
	bbuf=(unsigned char *)OPENSSL_malloc(blen);
	bout=DH_compute_key(bbuf,a->pub_key,b);

	BIO_puts(out,"key2 =");
	for (i=0; i<bout; i++)
		{
		snprintf(buf, sizeof(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;
err:
	ERR_print_errors_fp(stderr);

	if (abuf != NULL) OPENSSL_free(abuf);
	if (bbuf != NULL) OPENSSL_free(bbuf);
	if(b != NULL) DH_free(b);
	if(a != NULL) DH_free(a);
	BIO_free(out);
#ifdef OPENSSL_SYS_NETWARE
    if (ret) printf("ERROR: %d\n", ret);
#endif
	EXIT(ret);
	return(ret);
	}
Exemplo n.º 30
0
bool avjackif::async_handshake(boost::asio::yield_context yield_context)
{
	proto::client_hello client_hello;
	client_hello.set_client("avim");
	client_hello.set_version(0001);

	unsigned char to[512];

	auto dh = DH_new();
	DH_generate_parameters_ex(dh,64,DH_GENERATOR_5,NULL);
	DH_generate_key(dh);

	// 把 g,p, pubkey 传过去
	client_hello.set_random_g((const void*)to, BN_bn2bin(dh->g, to));
	client_hello.set_random_p((const void*)to, BN_bn2bin(dh->p, to));
	client_hello.set_random_pub_key((const void*)to, BN_bn2bin(dh->pub_key, to));

	auto tobesend = av_router::encode(client_hello);

	boost::asio::async_write(*m_sock, boost::asio::buffer(tobesend), yield_context);

	std::uint32_t l;
	boost::asio::async_read(*m_sock, boost::asio::buffer(&l, sizeof(l)), boost::asio::transfer_exactly(4), yield_context);
	auto hostl = htonl(l);
	std::string  buf;

	buf.resize(hostl + 4);
	memcpy(&buf[0], &l, 4);
	hostl = boost::asio::async_read(*m_sock, boost::asio::buffer(&buf[4], hostl),
		boost::asio::transfer_exactly(hostl), yield_context);

	// 解码
	boost::scoped_ptr<proto::server_hello> server_hello((proto::server_hello*)av_router::decode(buf));

	m_remote_addr.reset(new proto::avAddress(
		av_address_from_string(server_hello->server_av_address())));

	auto server_pubkey = BN_bin2bn((const unsigned char *) server_hello->random_pub_key().data(),
		server_hello->random_pub_key().length(), NULL);

	m_shared_key.resize(DH_size(dh));
	// 密钥就算出来啦!
	DH_compute_key(&m_shared_key[0], server_pubkey, dh);
	BN_free(server_pubkey);

    std::printf("key = 0x");
    for (int i=0; i<DH_size(dh); ++i) {
        std::printf("%x%x", (m_shared_key[i] >> 4) & 0xf, m_shared_key[i] & 0xf);
    }
    std::printf("\n");
	DH_free(dh);

	// 接着私钥加密 随机数
	auto singned = RSA_private_encrypt(_rsa.get(), server_hello->random_pub_key());

	proto::login login_packet;
	login_packet.set_user_cert( i2d_X509(_x509.get()) );
	login_packet.set_encryped_radom_key(singned);

	boost::asio::async_write(*m_sock, boost::asio::buffer(av_router::encode(login_packet)),
		yield_context);

	// 读取回应
	boost::asio::async_read(*m_sock, boost::asio::buffer(&l, sizeof(l)),
		boost::asio::transfer_exactly(hostl), yield_context);

	hostl = htonl(l);
	buf.resize(htonl(l) + 4);
	memcpy(&buf[0], &l, 4);
	boost::asio::async_read(*m_sock, boost::asio::buffer(&buf[4], htonl(l)),
		boost::asio::transfer_exactly(hostl), yield_context);
	// 解码
	boost::scoped_ptr<proto::login_result> login_result((proto::login_result*)av_router::decode(buf));

	return login_result.get()->result() == proto::login_result_login_result_code_LOGIN_SUCCEED;
}