I think there might be some confusion.
The "parameters" files are a legacy from when cryptosystems using "custom"
domains were not widely deprecated.
Such parameter files were required for any instance of key generation, to
make sure that a key was generated in the defined custom domain, and were
part of any key serialization because in cryptosystems that define domain
parameters a keypair is generally void of operational meaning if it isn't
associated with a domain in which that keypair can be used to perform
operations and also because when two or more peers are involved we need to
make sure that exchanged keys belonged to the same domain in which we chose
to operate.
Nowadays the experts discourage "custom" domains (see e.g. RFC 8422), as
they bring way more disadvantages than advantages, especially considering
that the disadvantages include potential serious security pitfalls.
Historically you needed to pregenerate a domain parameters file for
ephemeral DH used in the key exchange part of the TLS handshake, because
key generation is a relatively cheap operation, but generating the big
random primes required for creating new domain parameters is a quite
demanding process: this was the params file that was provided to the
SSL/TLS backend and needed to be saved alongside keys and certificates.
With ECDH, parameter generation for custom domains is even more involved,
error prone, and the validation of custom parameters received from a peer
is very expensive and littered with risks for the overall security if not
done properly.
That being said, recommending "use named curves" just means to use
well-established and studied set of parameters that standardizing bodies
deemed recommendable for secure use: this way both peers refer to a set of
parameters with a given common name rather than explicit parameters, and
the clients can trust the evaluation done by experts rather than having to
verify the received parameters for complex mathematical properties.
Now, to the commands in your email, it must be clear that there are a few
cryptosystems involved in a generic TLS handshake:
1. key exchange: usually ephemeral ECDH
2. digital signature (to validate the handshake with the server
credentials): commonly RSA, ECDSA or EdDSA (depending on the server key
type)
3. digital signature (to validate the certificate where the CA states "this
public key belongs to this subject"): commonly RSA, ECDSA or EdDSA
(depending on the CA key type)
(We should note that 3 does not necessarily require a `verify()` operation
for every handshake, because both the issuer and the subject credentials
are static, so a certificate for a server could be validated once and
cached for later use).
1)
Ephemeral ECDH generates a new keypair for every handshake, so the parties
need to agree on which domain parameters to use.
We negotiate named curves rather than explicit parameters, and that is what
`status = SSL_CTX_set1_curves_list(ctx, "P-521:P-384:P-256");` does: both
parties specify a list of supported curves, and one in common is picked
(preference on multiple hits is an irrelevant detail here).
So no need for a parameters file here, we use a list of names, and this is
independent from the cryptosystem picked for the two digital signature
operations.
2)
The server needs to have its own keypair, this means a one-time-only keygen
operation for which parameters are necessary if we pick ECDSA as the
cryptosystem of our choice.
You can do this using explicit parameters or a named curve, and the latter
is preferred. In any case there is no need to store a parameters file after
the key has been generated, as the key parameters are saved in the key
serialization anyway, both for named and for custom curves.
There is no harm in generating an intermediary params file, but it is
superfluous, and also the fact that there is no need to create such a file
should answer to your original question about where/how it is best to store
the parameter file.
To generate such a private key without the need for an intermediate params
file you could run:
~~~sh
curve_name=prime256v1
privkey_file=mykeyout.pem
openssl genpkey \
-algorithm EC -pkeyopt ec_paramgen_curve:$curve_name \
-pkeyopt ec_param_enc:named_curve \
-outform pem -out $privkey_file
~~~
Once you have a private key you could generate a certificate signing
request (CSR) for your CA to issue a certificate for your server:
~~~sh
csr_file=mycsrout.pem
csr_config=/etc/ssl/openssl.cnf
openssl req -sha256 \
-key $privkey_file \
-new -out $csr_file -outform pem \
-config $csr_config
~~~
Your CA upon receiving your CSR would do its due diligence to verify this
is a valid request, that you are indeed entitled to request such a
certificate for the requested subject, and all kinds of checks.
If the CSR meets all the CA criteria, they will proceed to generate a
certificate out of your CSR. The CA key type is often RSA, so it wouldn't
be uncommon to obtain a certificate in which th