DH_generate_key

Narayana, Sunil Kumar sanarayana at rbbn.com
Thu Dec 10 16:14:03 UTC 2020


Hi Matt,
                Thanks for the code sample. we understood the end to end flow to generate the DH key.
I wanted to understand one more aspect here, In our application we were obtaining two keys (pub_key/ priv_key) from the DH_generate_key() with single values of  dh->p/ dh->g.
But now in 3.0 equivalent, I guess we can get only one key from the p/g params right ? how to get equivalent pub_key / priv_key ? please suggest.


Regards,
Sunil
From: openssl-users <openssl-users-bounces at openssl.org> On Behalf Of openssl-users-request at openssl.org
Sent: 10 December 2020 17:46
To: openssl-users at openssl.org
Subject: openssl-users Digest, Vol 73, Issue 9

________________________________
NOTICE: This email was received from an EXTERNAL sender
________________________________

Send openssl-users mailing list submissions to
openssl-users at openssl.org<mailto:openssl-users at openssl.org>

To subscribe or unsubscribe via the World Wide Web, visit
https://mta.openssl.org/mailman/listinfo/openssl-users<https://mta.openssl.org/mailman/listinfo/openssl-users>
or, via email, send a message with subject or body 'help' to
openssl-users-request at openssl.org<mailto:openssl-users-request at openssl.org>

You can reach the person managing the list at
openssl-users-owner at openssl.org<mailto:openssl-users-owner at openssl.org>

When replying, please edit your Subject line so it is more specific
than "Re: Contents of openssl-users digest..."


Today's Topics:

1. Re: DH_generate_key (Matt Caswell)
2. Re: creating certificate by code / problems to load via
openssl x509 / pem format (Andreas Tengicki)
3. Re: creating certificate by code / problems to load via
openssl x509 / pem format (Tomas Mraz)
4. Re: DH_generate_key (Matt Caswell)


----------------------------------------------------------------------

Message: 1
Date: Wed, 9 Dec 2020 15:31:51 +0000
From: Matt Caswell <matt at openssl.org<mailto:matt at openssl.org>>
To: "Narayana, Sunil Kumar" <sanarayana at rbbn.com<mailto:sanarayana at rbbn.com>>,
"openssl-users at openssl.org<mailto:openssl-users at openssl.org>" <openssl-users at openssl.org<mailto:openssl-users at openssl.org>>
Subject: Re: DH_generate_key
Message-ID: <72867e9d-4e91-faa0-d329-1f92ed723b0e at openssl.org<mailto:72867e9d-4e91-faa0-d329-1f92ed723b0e at openssl.org>>
Content-Type: text/plain; charset=utf-8



On 08/12/2020 17:43, Narayana, Sunil Kumar wrote:
> Dear openssl team,
>
> ?
>
> ??????????????? While migrating from 1.0.2 to 3.0, ?we found that
> DH_generate_key() has be deprecated. And as per the man page, it is
> advised to use EVP_PKEY_derive_init
> <https://www.openssl.org/docs/manmaster/man3/EVP_PKEY_derive_init.html<https://www.openssl.org/docs/manmaster/man3/EVP_PKEY_derive_init.html>>
> ?& EVP_PKEY_derive
> <https://www.openssl.org/docs/manmaster/man3/EVP_PKEY_derive.html<https://www.openssl.org/docs/manmaster/man3/EVP_PKEY_derive.html>>
>

The reference to EVP_PKEY_derive_init/EVP_PKEY_derive is a bit
misleading, because those are replacements for DH_compute_key() not
DH_generate_key().

The equivalents for DH_generate_key() are EVP_PKEY_keygen_init() and
EVP_PKEY_gen().

https://www.openssl.org/docs/manmaster/man3/EVP_PKEY_gen.html<https://www.openssl.org/docs/manmaster/man3/EVP_PKEY_gen.html>



> our application creates a new DH and using DH_generate_key()

How do you set up the DH parameters? Do you load them from a file or
generate them in your application? Or some other way? Will it break your
application if you swap to using different parameters, or must you
retain support for the old ones?

The first step is to create an EVP_PKEY object containing the DH
parameters. How to do that depends on the answers to the above questions.


> creates
> pub_key/priv_key and uses it. how can we replace this exactly with EVP.
>


As noted by Daniel in this response to your question there are examples
on the EVP_PKEY-DH manual page.

https://www.openssl.org/docs/manmaster/man7/EVP_PKEY-DH.html<https://www.openssl.org/docs/manmaster/man7/EVP_PKEY-DH.html>

Assuming you have set up the parameters in an EVP_PKEY object
(param_key) then this is the relevant example:


EVP_PKEY *key = NULL;
EVP_PKEY_CTX *gctx = EVP_PKEY_CTX_new_from_pkey(NULL, param_key, NULL);

EVP_PKEY_keygen_init(gctx);
EVP_PKEY_gen(gctx, &key);
EVP_PKEY_print_private(bio_out, key, 0, NULL);
...
EVP_PKEY_free(key);
EVP_PKEY_CTX_free(gctx);


This gives you a generated DH key in the "key" object.


Matt


> And please suggest what EVP API?s should we use to generate pub/priv keys ?
>
> ?
>
> _Application code_
>
> _?_
>
> ??? dh = DH_new();
>
> ??? dh->p = BN_bin2bn(modSize, octet_len, NULL);
>
> ??? dh->g = BN_bin2bn(H235Bits_generator, H235Bits_generator_len / 8, NULL);
>
> ?
>
> ??? if ( ! DH_generate_key(dh) )
>
> ??? {
>
> ??????? return FAILURE;
>
> ??? }
>
> ??? n = (unsigned) BN_num_bytes(dh->pub_key);
>
> ??
>
> ????BN_bn2bin(dh->pub_key, p);
>
> ??? n = (unsigned) BN_num_bytes(dh->priv_key);
>
> ?
>
> ?
>
> Instead above logic can we do this ? is derive generated pub/priv keys ?
>
> ?
>
> //create ctx
>
> Ctx = EVP_PKEY_CTX_new_from_name (NULL, ?DM?, NULL);
>
> EVP_PKEY_derive_init (ctx)
>
> ?
>
> ?
>
> Regards,
>
> Sunil
>
>
>
> ------------------------------------------------------------------------
> Notice: This e-mail together with any attachments may contain
> information of Ribbon Communications Inc. that is confidential and/or
> proprietary for the sole use of the intended recipient. Any review,
> disclosure, reliance or distribution by others or forwarding without
> express permission is strictly prohibited. If you are not the intended
> recipient, please notify the sender immediately and then delete all
> copies, including any attachments.
> ------------------------------------------------------------------------


------------------------------

Message: 2
Date: Thu, 10 Dec 2020 10:39:06 +0100
From: Andreas Tengicki <tengicki at autopoll.de<mailto:tengicki at autopoll.de>>
To: openssl-users at openssl.org<mailto:openssl-users at openssl.org>
Subject: Re: creating certificate by code / problems to load via
openssl x509 / pem format
Message-ID: <009adab4-57a9-4132-f6f5-43d60946faf4 at autopoll.de<mailto:009adab4-57a9-4132-f6f5-43d60946faf4 at autopoll.de>>
Content-Type: text/plain; charset="utf-8"; Format="flowed"

The solution was to choice a EVP by signing the certificate

i = X509_sign(x, CApkey, EVP_sha256());

Best regards

? Andreas

Am 09.07.2020 um 11:09 schrieb Andreas Tengicki:
>
> Hello,
>
> your first help in this project, helps much, but now some weeks later,
> there is a new problem, and I cannot find any tipps via google.
>
> For all the coding a have looked into the openssl examples.
>
> I create a private key per code, the "openssl rsa -in
> test_privatekey.pem -check" is fine
>
> I create a certificate request per code, "openssl req -text -noout
> -verify -in test_request.pem" is fine
>
> I create a certifcate via this reqeust and store it with
> "PEM_write_bio_X509(out, crt);" like the others. (some more code below)
>
> Perhaps there is something wrong, but to detect this, I will use the
> validation, but it cannot load the certificate to validate it:
>
> >> openssl x509 -in test_certificate.pem -text
> unable to load certificate
> 140180222239872:error:0D07209B:asn1 encoding
> routines:ASN1_get_object:too long:../crypto/asn1/asn1_lib.c:91:
> 140180222239872:error:0D068066:asn1 encoding
> routines:asn1_check_tlen:bad object header:../crypto/asn1/tasn_dec.c:1118:
> 140180222239872:error:0D07803A:asn1 encoding
> routines:asn1_item_embed_d2i:nested asn1
> error:../crypto/asn1/tasn_dec.c:190:Type=ASN1_TIME
> 140180222239872:error:0D08303A:asn1 encoding
> routines:asn1_template_noexp_d2i:nested asn1
> error:../crypto/asn1/tasn_dec.c:627:Field=notBefore, Type=X509_VAL
> 140180222239872:error:0D08303A:asn1 encoding
> routines:asn1_template_noexp_d2i:nested asn1
> error:../crypto/asn1/tasn_dec.c:627:Field=validity, Type=X509_CINF
> 140180222239872:error:0D08303A:asn1 encoding
> routines:asn1_template_noexp_d2i:nested asn1
> error:../crypto/asn1/tasn_dec.c:627:Field=cert_info, Type=X509
> 140180222239872:error:0906700D:PEM routines:PEM_ASN1_read_bio:ASN1
> lib:../crypto/pem/pem_oth.c:33:
>
> Thanks for any help.
>
> Best regards
>
> ? Andreas
>
> ----
>
> ErrorHandling should be added in a second step, first debug outputs (I
> have deleted for here) says everything is created
>
> X509* certificate_create(const X509_REQ* req)
> {
> ? //openssl x509 -req -days 365 -sha256 -in server.csr -CA ca.crt
> -CAkey ca.key -CAcreateserial -out server.crt
>
> ? if ((crt = X509_new()) == NULL);
> ? //xca = load_cert(CAfile, CAformat, "CA Certificate");
> ? BIO *bio = NULL;
> ? bio = BIO_new_file(CAfile, "r");
> ? xca = PEM_read_bio_X509_AUX(bio, NULL, NULL, NULL);
> ? BIO_free(bio);
>
> ? upkey = X509_get0_pubkey(xca);
>
> ? char CAkeyile[] = "ca.key";
> ? int CAkeyformat = 5; //FORMAT_PEM
> ? char passin[] = "xyz";
>
> ? ENGINE *e = NULL;
> ? EVP_PKEY * CApkey = NULL;
> ? //CApkey = load_key(CAkeyfile, CAkeyformat, 0, passin, e, "CA
> Private Key");
> ? bio = BIO_new_file(CAkeyile, "r");
> ? CApkey = PEM_read_bio_PrivateKey(bio, NULL, NULL, passin);
> ? BIO_free(bio);
>
> ? EVP_PKEY_copy_parameters(upkey, CApkey);
>
> ? X509_STORE *ctx = NULL;
> ? ctx = X509_STORE_new();
>
> ? X509_STORE_CTX *xsc = NULL;
> ? xsc = X509_STORE_CTX_new();
> ? if (xsc == NULL || !X509_STORE_CTX_init(xsc, ctx, crt, NULL));
>
> ? ASN1_INTEGER *serialno = NULL;
> ? serialno = ASN1_INTEGER_new();
> ? BIGNUM *btmp = NULL;
> ? btmp = BN_new();
>
> ? # define SERIAL_RAND_BITS??????? 159
> ? if (!BN_rand(btmp, SERIAL_RAND_BITS, BN_RAND_TOP_ANY,
> BN_RAND_BOTTOM_ANY));
> ? if (!BN_to_ASN1_INTEGER(btmp, serialno));
> ? BN_free(btmp);
>
> X509_STORE_CTX_set_cert(xsc, crt);
> ? X509_STORE_CTX_set_flags(xsc, X509_V_FLAG_CHECK_SS_SIGNATURE);
>
> ? if (!X509_check_private_key(xca, CApkey)) ;
>
> ? if (!X509_set_issuer_name(crt, X509_get_subject_name(xca)));
> ? if (!X509_set_serialNumber(crt, serialno));
>
> ? int days = 365;
> ? if (X509_time_adj_ex(X509_getm_notAfter(crt), days, 0, NULL) == NULL);
>
> ? const char digestname[] = "sha256";
> ? const EVP_MD* md = EVP_get_digestbyname(digestname);
> ? EVP_MD_CTX *mctx = EVP_MD_CTX_new();
> ? EVP_PKEY_CTX *pkctx = NULL;
> ? EVP_DigestSignInit(mctx, &pkctx, md, NULL, CApkey); //ist CApkey
> hier der richtige private Key? sollte eigentlich
> ? int rv = (X509_sign_ctx(crt, mctx) > 0);
> ? EVP_MD_CTX_free(mctx);
>
> ? BIO *out = NULL;
> ? out = BIO_new_file("test_certificate.pem", "w");
> ? PEM_write_bio_X509(out, crt);
> ? BIO_free_all(out);
>
> ? ...some more frees ...
> ? return crt;
> }
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://mta.openssl.org/pipermail/openssl-users/attachments/20201210/897e5d1b/attachment-0001.html<https://mta.openssl.org/pipermail/openssl-users/attachments/20201210/897e5d1b/attachment-0001.html>>

------------------------------

Message: 3
Date: Thu, 10 Dec 2020 11:42:37 +0100
From: Tomas Mraz <tmraz at redhat.com<mailto:tmraz at redhat.com>>
To: Andreas Tengicki <tengicki at autopoll.de<mailto:tengicki at autopoll.de>>, openssl-users at openssl.org<mailto:openssl-users at openssl.org>
Subject: Re: creating certificate by code / problems to load via
openssl x509 / pem format
Message-ID:
<a5196a1bd4dcd8175448e8689d6396231d23097a.camel at redhat.com<mailto:a5196a1bd4dcd8175448e8689d6396231d23097a.camel at redhat.com>>
Content-Type: text/plain; charset="UTF-8"

On Thu, 2020-12-10 at 10:39 +0100, Andreas Tengicki wrote:
> The solution was to choice a EVP by signing the certificate
>
> i = X509_sign(x, CApkey, EVP_sha256());

I do not really think this was the problem. In the code below you do
not set the notBefore time which is actually indicated by the parsing
errors when you try to load the invalid certificate.

> Best regards
>
> Andreas
>
> Am 09.07.2020 um 11:09 schrieb Andreas Tengicki:
> > Hello,
> >
> > your first help in this project, helps much, but now some weeks
> > later, there is a new problem, and I cannot find any tipps via
> > google.
> >
> > For all the coding a have looked into the openssl examples.
> >
> > I create a private key per code, the "openssl rsa -in
> > test_privatekey.pem -check" is fine
> >
> > I create a certificate request per code, "openssl req -text -noout
> > -verify -in test_request.pem" is fine
> >
> > I create a certifcate via this reqeust and store it with
> > "PEM_write_bio_X509(out, crt);" like the others. (some more code
> > below)
> >
> > Perhaps there is something wrong, but to detect this, I will use
> > the validation, but it cannot load the certificate to validate it:
> >
> > >> openssl x509 -in test_certificate.pem -text
> > unable to load certificate
> > 140180222239872:error:0D07209B:asn1 encoding
> > routines:ASN1_get_object:too long:../crypto/asn1/asn1_lib.c:91:
> > 140180222239872:error:0D068066:asn1 encoding
> > routines:asn1_check_tlen:bad object
> > header:../crypto/asn1/tasn_dec.c:1118:
> > 140180222239872:error:0D07803A:asn1 encoding
> > routines:asn1_item_embed_d2i:nested asn1
> > error:../crypto/asn1/tasn_dec.c:190:Type=ASN1_TIME
> > 140180222239872:error:0D08303A:asn1 encoding
> > routines:asn1_template_noexp_d2i:nested asn1
> > error:../crypto/asn1/tasn_dec.c:627:Field=notBefore, Type=X509_VAL
> > 140180222239872:error:0D08303A:asn1 encoding
> > routines:asn1_template_noexp_d2i:nested asn1
> > error:../crypto/asn1/tasn_dec.c:627:Field=validity, Type=X509_CINF
> > 140180222239872:error:0D08303A:asn1 encoding
> > routines:asn1_template_noexp_d2i:nested asn1
> > error:../crypto/asn1/tasn_dec.c:627:Field=cert_info, Type=X509
> > 140180222239872:error:0906700D:PEM routines:PEM_ASN1_read_bio:ASN1
> > lib:../crypto/pem/pem_oth.c:33:
> >
> >
> > Thanks for any help.
> >
> > Best regards
> >
> > Andreas
> >
> > ----
> >
> > ErrorHandling should be added in a second step, first debug outputs
> > (I have deleted for here) says everything is created
> >
> > X509* certificate_create(const X509_REQ* req)
> > {
> > //openssl x509 -req -days 365 -sha256 -in server.csr -CA ca.crt
> > -CAkey ca.key -CAcreateserial -out server.crt
> >
> > if ((crt = X509_new()) == NULL);
> > //xca = load_cert(CAfile, CAformat, "CA Certificate");
> > BIO *bio = NULL;
> > bio = BIO_new_file(CAfile, "r");
> > xca = PEM_read_bio_X509_AUX(bio, NULL, NULL, NULL);
> > BIO_free(bio);
> >
> > upkey = X509_get0_pubkey(xca);
> >
> > char CAkeyile[] = "ca.key";
> > int CAkeyformat = 5; //FORMAT_PEM
> > char passin[] = "xyz";
> >
> > ENGINE *e = NULL;
> > EVP_PKEY * CApkey = NULL;
> > //CApkey = load_key(CAkeyfile, CAkeyformat, 0, passin, e, "CA
> > Private Key");
> > bio = BIO_new_file(CAkeyile, "r");
> > CApkey = PEM_read_bio_PrivateKey(bio, NULL, NULL, passin);
> > BIO_free(bio);
> >
> > EVP_PKEY_copy_parameters(upkey, CApkey);
> >
> > X509_STORE *ctx = NULL;
> > ctx = X509_STORE_new();
> >
> > X509_STORE_CTX *xsc = NULL;
> > xsc = X509_STORE_CTX_new();
> > if (xsc == NULL || !X509_STORE_CTX_init(xsc, ctx, crt, NULL));
> >
> > ASN1_INTEGER *serialno = NULL;
> > serialno = ASN1_INTEGER_new();
> > BIGNUM *btmp = NULL;
> > btmp = BN_new();
> >
> > # define SERIAL_RAND_BITS 159
> > if (!BN_rand(btmp, SERIAL_RAND_BITS, BN_RAND_TOP_ANY,
> > BN_RAND_BOTTOM_ANY));
> > if (!BN_to_ASN1_INTEGER(btmp, serialno));
> > BN_free(btmp);
> >
> > X509_STORE_CTX_set_cert(xsc, crt);
> > X509_STORE_CTX_set_flags(xsc, X509_V_FLAG_CHECK_SS_SIGNATURE);
> >
> > if (!X509_check_private_key(xca, CApkey)) ;
> >
> > if (!X509_set_issuer_name(crt, X509_get_subject_name(xca)));
> > if (!X509_set_serialNumber(crt, serialno));
> >
> > int days = 365;
> > if (X509_time_adj_ex(X509_getm_notAfter(crt), days, 0, NULL) ==
> > NULL);
> >
> > const char digestname[] = "sha256";
> > const EVP_MD* md = EVP_get_digestbyname(digestname);
> > EVP_MD_CTX *mctx = EVP_MD_CTX_new();
> > EVP_PKEY_CTX *pkctx = NULL;
> > EVP_DigestSignInit(mctx, &pkctx, md, NULL, CApkey); //ist CApkey
> > hier der richtige private Key? sollte eigentlich
> > int rv = (X509_sign_ctx(crt, mctx) > 0);
> > EVP_MD_CTX_free(mctx);
> >
> > BIO *out = NULL;
> > out = BIO_new_file("test_certificate.pem", "w");
> > PEM_write_bio_X509(out, crt);
> > BIO_free_all(out);
> >
> > ...some more frees ...
> > return crt;
> > }
> >
--
Tom?? Mr?z
No matter how far down the wrong road you've gone, turn back.
Turkish proverb
[You'll know whether the road is wrong if you carefully listen to your
conscience.]




------------------------------

Message: 4
Date: Thu, 10 Dec 2020 12:16:11 +0000
From: Matt Caswell <matt at openssl.org<mailto:matt at openssl.org>>
To: "Narayana, Sunil Kumar" <sanarayana at rbbn.com<mailto:sanarayana at rbbn.com>>,
"openssl-users at openssl.org<mailto:openssl-users at openssl.org>" <openssl-users at openssl.org<mailto:openssl-users at openssl.org>>
Subject: Re: DH_generate_key
Message-ID: <0d2eb472-d8d8-0272-e992-8e5c37082f0e at openssl.org<mailto:0d2eb472-d8d8-0272-e992-8e5c37082f0e at openssl.org>>
Content-Type: text/plain; charset=utf-8



On 09/12/2020 15:31, Matt Caswell wrote:
>> our application creates a new DH and using DH_generate_key()
>
> How do you set up the DH parameters? Do you load them from a file or
> generate them in your application? Or some other way? Will it break your
> application if you swap to using different parameters, or must you
> retain support for the old ones?
>
> The first step is to create an EVP_PKEY object containing the DH
> parameters. How to do that depends on the answers to the above questions.

Sunil emailed me directly (off list) and provided some code samples.

So you have some fixed "p" and "g" parameter values defined as static
unsigned char arrays, which you are currently converting to BIGNUMs
using "BN_bin2bn", and then assigning to "dh->p" and "dh->g" respectively.

The "g" value is just "2", so in the 3.0 equivalent you don't need to
convert that to a BIGNUM first. Some equivalent code to construct a DH
params object (called "param_key" in the code below) is:


EVP_PKEY_CTX *pctx = EVP_PKEY_CTX_new_from_name(NULL, "DH", NULL);
OSSL_PARAM_BLD *tmpl = NULL;
OSSL_PARAM *params = NULL;
EVP_PKEY *param_key = NULL;

if (pctx == NULL || !EVP_PKEY_key_fromdata_init(pctx))
goto err;

if ((tmpl = OSSL_PARAM_BLD_new()) == NULL
|| !OSSL_PARAM_BLD_push_BN(tmpl, OSSL_PKEY_PARAM_FFC_P, p)
|| !OSSL_PARAM_BLD_push_uint(tmpl, OSSL_PKEY_PARAM_FFC_G, 2))
goto err;

params = OSSL_PARAM_BLD_to_param(tmpl);
if (params == NULL || !EVP_PKEY_fromdata(pctx, &param_key, params))
goto err;
err:
EVP_PKEY_CTX_free(pctx);
OSSL_PARAM_BLD_free_params(params);
OSSL_PARAM_BLD_free(tmpl);


You can then generate the key using the code sample I gave in my
previous email:

EVP_PKEY *key = NULL;
EVP_PKEY_CTX *gctx = EVP_PKEY_CTX_new_from_pkey(NULL, param_key, NULL);

EVP_PKEY_keygen_init(gctx);
EVP_PKEY_gen(gctx, &key);
EVP_PKEY_print_private(bio_out, key, 0, NULL);
...
EVP_PKEY_free(key);
EVP_PKEY_CTX_free(gctx);



Hope that helps,

Matt


------------------------------

Subject: Digest Footer

_______________________________________________
openssl-users mailing list
openssl-users at openssl.org<mailto:openssl-users at openssl.org>
https://mta.openssl.org/mailman/listinfo/openssl-users<https://mta.openssl.org/mailman/listinfo/openssl-users>


------------------------------

End of openssl-users Digest, Vol 73, Issue 9
********************************************


-----------------------------------------------------------------------------------------------------------------------
Notice: This e-mail together with any attachments may contain information of Ribbon Communications Inc. that
is confidential and/or proprietary for the sole use of the intended recipient.  Any review, disclosure, reliance or
distribution by others or forwarding without express permission is strictly prohibited.  If you are not the intended
recipient, please notify the sender immediately and then delete all copies, including any attachments.
-----------------------------------------------------------------------------------------------------------------------
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://mta.openssl.org/pipermail/openssl-users/attachments/20201210/8a336b83/attachment-0001.html>


More information about the openssl-users mailing list