Confirmation of what I believe to be true from docs and observation

classic Classic list List threaded Threaded
4 messages Options
Reply | Threaded
Open this post in threaded view
|

Confirmation of what I believe to be true from docs and observation

Karl Denninger

We start with a context that I load a dhparam file to (so I can take a DH connection) along with an edh curve, then set an acceptable cipher list for it to use.

Assume I next manually load both the CA store (using X509_STORE_add_cert as many times as necessary to load the intermediate components and the root of trust) and then load the cert/key pair (using SSL_CTX_use_certificate/SSL_CTX_use_PrivateKey)

I then create some number of SSLs from that context to perform communication with and all is well.

Now I want to rekey that context for some reason.  It appears that while I can add things to the CA chain trying to load the same component that is already in there returns a failure (somewhat-expected; that is, it does not overwrite but rather adds, and if you try to add what's already there you get an error back) and there's no call to CLEAR the certificate validation chain -- if I want to *replace* the validation chain I have to destroy the context and initialize a new one from scratch.

It appears, however, that I *can* load over the top of a certificate and private key of the same type and that's acceptable.  In other words, if I have an RSA key/cert pair in the context and I load another one, the first one is replaced.  This *looks* to be working ok as far as I can tell and it doesn't appear to leak memory doing that but it's not explicitly stated that this is considered acceptable (rather than destroying and re-creating the context.)

Is my understanding correct?

--
Karl Denninger
[hidden email]
The Market Ticker
[S/MIME encrypted email preferred]

--
openssl-users mailing list
To unsubscribe: https://mta.openssl.org/mailman/listinfo/openssl-users

smime.p7s (6K) Download Attachment
Reply | Threaded
Open this post in threaded view
|

Re: Confirmation of what I believe to be true from docs and observation

OpenSSL - User mailing list
On 01/10/2018 08:41 AM, Karl Denninger wrote:
>
> We start with a context that I load a dhparam file to (so I can take a
> DH connection) along with an edh curve, then set an acceptable cipher
> list for it to use.
>

Why not just use AUTO_DH (the only option for 1.1.0, IIRC)?

> Assume I next manually load both the CA store (using
> X509_STORE_add_cert as many times as necessary to load the
> intermediate components and the root of trust) and then load the
> cert/key pair (using SSL_CTX_use_certificate/SSL_CTX_use_PrivateKey)
>
> I then create some number of SSLs from that context to perform
> communication with and all is well.
>
> Now I want to rekey that context for some reason.  It appears that
> while I can add things to
>

Why do you need to rekey the context as opposed to making a new one?

In general, making configuration changes to an SSL_CTX after it has been
used to generate SSL objects is a risky proposition -- the locking model
does not really account for doing synchronization properly, and there
might be some latent race conditions.  In practice, some operations are
currently safe, but there is no authoritative list of which ones, and at
least my personal recommendation is to not try to rely on it.

> the CA chain trying to load the same component that is already in
> there returns a failure (somewhat-expected; that is, it does not
> overwrite but rather adds, and if you try to add what's already there
> you get an error back) and there's no call to CLEAR the certificate
> validation chain -- if I want to *replace* the validation chain I have
> to destroy the context and initialize a new one from scratch.
>

N.B. that the X509_STORE_add_cert behavior when presented with a
duplicate certificate changed in commit
c0452248ea1a59a41023a4765ef7d9825e80a62b (from returning an error to
doing nothing and returning success); this will be in 1.1.1.

As to the desired behavior, there does not seem to be an API to remove
an entry from an X509_STORE.  With the above caveat about thread-safety
in mind, couldn't you just make a call to SSL_CTX_set{1}_cert_store() to
replace the X509_STORE without tearing down the whole SSL_CTX?

> It appears, however, that I *can* load over the top of a certificate
> and private key of the same type and that's acceptable.  In other
> words, if I have an RSA key/cert pair in the context and I load
> another one, the first one is replaced.  This *looks* to be working ok
> as far as I can tell and it doesn't appear to leak memory doing that
> but it's not explicitly stated that this is considered acceptable
> (rather than destroying and re-creating the context.)
>

The leaf certificate and private key are stored as arrays (for different
types of certificates) of pointers in the associated CERT structure, and
the "set" routines do not currently check for and error out if there is
already one set.

> Is my understanding correct?
>
>

Mostly ... but I am not sure that your desired workflow is wise.

-Ben
--
openssl-users mailing list
To unsubscribe: https://mta.openssl.org/mailman/listinfo/openssl-users
Reply | Threaded
Open this post in threaded view
|

Re: Confirmation of what I believe to be true from docs and observation

Karl Denninger
On 1/10/2018 14:07, Benjamin Kaduk wrote:
On 01/10/2018 08:41 AM, Karl Denninger wrote:
We start with a context that I load a dhparam file to (so I can take a
DH connection) along with an edh curve, then set an acceptable cipher
list for it to use.

Why not just use AUTO_DH (the only option for 1.1.0, IIRC)?
That's a reasonable change (and I'll go ahead and make it); the dhparam was only there in the first place for those browsers and such that can't negotiate EC (which my cipher selection set prefers.)

      
Assume I next manually load both the CA store (using
X509_STORE_add_cert as many times as necessary to load the
intermediate components and the root of trust) and then load the
cert/key pair (using SSL_CTX_use_certificate/SSL_CTX_use_PrivateKey)

I then create some number of SSLs from that context to perform
communication with and all is well.

Now I want to rekey that context for some reason.  It appears that
while I can add things to

Why do you need to rekey the context as opposed to making a new one?
I could make a new one (or more-specifically, destroy the existing one and re-initialize it), but that is more-complicated as the application in question is multi-threaded -- and it's not at all clear from the documentation if I destroy a context that has SSLs that have been generated from it will cause "bad things" to happen (like a deference on a freed object!)

The reason I may want to rekey is that the cert/key pair used for that context may have changed.  The user's certificate may have expired for example (or been revoked) and I wish to reload it (and the matching key) without having to shut down the software and restart it.

In general, making configuration changes to an SSL_CTX after it has been
used to generate SSL objects is a risky proposition -- the locking model
does not really account for doing synchronization properly, and there
might be some latent race conditions.  In practice, some operations are
currently safe, but there is no authoritative list of which ones, and at
least my personal recommendation is to not try to rely on it.
Assuming that there are SSL objects that are in use and I destroy and re-generate the CTX from which it was generated, is *THAT* safe?  Or do I need to flag all the in-use descendants and wait for them to be closed (or force them closed and release them) before I can safely destroy the context?

      
the CA chain trying to load the same component that is already in
there returns a failure (somewhat-expected; that is, it does not
overwrite but rather adds, and if you try to add what's already there
you get an error back) and there's no call to CLEAR the certificate
validation chain -- if I want to *replace* the validation chain I have
to destroy the context and initialize a new one from scratch.

N.B. that the X509_STORE_add_cert behavior when presented with a
duplicate certificate changed in commit
c0452248ea1a59a41023a4765ef7d9825e80a62b (from returning an error to
doing nothing and returning success); this will be in 1.1.1.

As to the desired behavior, there does not seem to be an API to remove
an entry from an X509_STORE.  With the above caveat about thread-safety
in mind, couldn't you just make a call to SSL_CTX_set{1}_cert_store() to
replace the X509_STORE without tearing down the whole SSL_CTX?
Yeah, I didn't see one either.  I'm not particularly concerned about the verification chain being able to be modified while "in-use"; that ought not happen except in an extreme circumstance (e.g. the intermediate cert's key is compromised and thus both it and the cert have to be regenerated and re-distributed.)  If it DOES happen when the end-entity cert and key are reloaded (as they've been signed from the new intermediate) they'll fail to validate against the old chain and the user will get plenty of notice that there's trouble.
It appears, however, that I *can* load over the top of a certificate
and private key of the same type and that's acceptable.  In other
words, if I have an RSA key/cert pair in the context and I load
another one, the first one is replaced.  This *looks* to be working ok
as far as I can tell and it doesn't appear to leak memory doing that
but it's not explicitly stated that this is considered acceptable
(rather than destroying and re-creating the context.)

The leaf certificate and private key are stored as arrays (for different
types of certificates) of pointers in the associated CERT structure, and
the "set" routines do not currently check for and error out if there is
already one set.
Yes, but do they replace the pointer and, if they do, do they decrement the reference counter on the existing one before replacing it so it will get freed?   If yes then all is ok but if not then I need to destroy the context otherwise I'm going to be leaking memory.
Is my understanding correct?


Mostly ... but I am not sure that your desired workflow is wise.

-Ben
If it's safe to destroy a context with potential SSL options from it still in existence then it's pretty easy to do it the other way otherwise I have some work to do in order to make sure all the potential objects created from the parent have gone away before the old context is destroyed.

Thanks in advance.

--
Karl Denninger
[hidden email]
The Market Ticker
[S/MIME encrypted email preferred]

--
openssl-users mailing list
To unsubscribe: https://mta.openssl.org/mailman/listinfo/openssl-users

smime.p7s (6K) Download Attachment
Reply | Threaded
Open this post in threaded view
|

Re: Confirmation of what I believe to be true from docs and observation

OpenSSL - User mailing list
On 01/10/2018 02:37 PM, Karl Denninger wrote:

> On 1/10/2018 14:07, Benjamin Kaduk wrote:
>> On 01/10/2018 08:41 AM, Karl Denninger wrote:
>>> We start with a context that I load a dhparam file to (so I can take a
>>> DH connection) along with an edh curve, then set an acceptable cipher
>>> list for it to use.
>>>
>> Why not just use AUTO_DH (the only option for 1.1.0, IIRC)?
> That's a reasonable change (and I'll go ahead and make it); the
> dhparam was only there in the first place for those browsers and such
> that can't negotiate EC (which my cipher selection set prefers.)
>>> Assume I next manually load both the CA store (using
>>> X509_STORE_add_cert as many times as necessary to load the
>>> intermediate components and the root of trust) and then load the
>>> cert/key pair (using SSL_CTX_use_certificate/SSL_CTX_use_PrivateKey)
>>>
>>> I then create some number of SSLs from that context to perform
>>> communication with and all is well.
>>>
>>> Now I want to rekey that context for some reason.  It appears that
>>> while I can add things to
>>>
>> Why do you need to rekey the context as opposed to making a new one?
> I could make a new one (or more-specifically, destroy the existing one
> and re-initialize it), but that is more-complicated as the application
> in question is multi-threaded -- and it's not at all clear from the
> documentation if I destroy a context that has SSLs that have been
> generated from it will cause "bad things" to happen (like a deference
> on a freed object!)
>

Each SSL holds a reference on its parent SSL_CTX (and another reference
on its associated session_ctx, which starts out as the same SSL_CTX
object); SSL_CTX_free() does not do any deallocation until the refcount
drops to zero.

So, no "bad things" will happen if you SSL_CTX_free() the handle you
have in your application while SSL objects are still using that object.

> The reason I may want to rekey is that the cert/key pair used for that
> context may have changed.  The user's certificate may have expired for
> example (or been revoked) and I wish to reload it (and the matching
> key) without having to shut down the software and restart it.
>
>> In general, making configuration changes to an SSL_CTX after it has been
>> used to generate SSL objects is a risky proposition -- the locking model
>> does not really account for doing synchronization properly, and there
>> might be some latent race conditions.  In practice, some operations are
>> currently safe, but there is no authoritative list of which ones, and at
>> least my personal recommendation is to not try to rely on it.
> Assuming that there are SSL objects that are in use and I destroy and
> re-generate the CTX from which it was generated, is *THAT* safe?  Or
> do I need to flag all the in-use descendants and wait for them to be
> closed (or force them closed and release them) before I can safely
> destroy the context?

You do not need to flag and wait, due to the reference counting on the
SSL and SSL_CTX objects.

>>> the CA chain trying to load the same component that is already in
>>> there returns a failure (somewhat-expected; that is, it does not
>>> overwrite but rather adds, and if you try to add what's already there
>>> you get an error back) and there's no call to CLEAR the certificate
>>> validation chain -- if I want to *replace* the validation chain I have
>>> to destroy the context and initialize a new one from scratch.
>>>
>> N.B. that the X509_STORE_add_cert behavior when presented with a
>> duplicate certificate changed in commit
>> c0452248ea1a59a41023a4765ef7d9825e80a62b (from returning an error to
>> doing nothing and returning success); this will be in 1.1.1.
>>
>> As to the desired behavior, there does not seem to be an API to remove
>> an entry from an X509_STORE.  With the above caveat about thread-safety
>> in mind, couldn't you just make a call to SSL_CTX_set{1}_cert_store() to
>> replace the X509_STORE without tearing down the whole SSL_CTX?
> Yeah, I didn't see one either.  I'm not particularly concerned about
> the verification chain being able to be modified while "in-use"; that
> ought not happen except in an extreme circumstance (e.g. the
> intermediate cert's key is compromised and thus both it and the cert
> have to be regenerated and re-distributed.)  If it DOES happen when
> the end-entity cert and key are reloaded (as they've been signed from
> the new intermediate) they'll fail to validate against the old chain
> and the user will get plenty of notice that there's trouble.
>>> It appears, however, that I *can* load over the top of a certificate
>>> and private key of the same type and that's acceptable.  In other
>>> words, if I have an RSA key/cert pair in the context and I load
>>> another one, the first one is replaced.  This *looks* to be working ok
>>> as far as I can tell and it doesn't appear to leak memory doing that
>>> but it's not explicitly stated that this is considered acceptable
>>> (rather than destroying and re-creating the context.)
>>>
>> The leaf certificate and private key are stored as arrays (for different
>> types of certificates) of pointers in the associated CERT structure, and
>> the "set" routines do not currently check for and error out if there is
>> already one set.
> Yes, but do they replace the pointer and, if they do, do they
> decrement the reference counter on the existing one before replacing
> it so it will get freed?   If yes then all is ok but if not then I
> need to destroy the context otherwise I'm going to be leaking memory.

The underlying implementation (ssl_set_cert()) does call X509_free() and
EVP_PKEY_free() before doing the update, so there is no leak.

>>> Is my understanding correct?
>>>
>>>
>> Mostly ... but I am not sure that your desired workflow is wise.
>>
>> -Ben
> If it's safe to destroy a context with potential SSL options from it
> still in existence then it's pretty easy to do it the other way
> otherwise I have some work to do in order to make sure all the
> potential objects created from the parent have gone away before the
> old context is destroyed.

Yup, it's safe.

Good luck!

-Ben
--
openssl-users mailing list
To unsubscribe: https://mta.openssl.org/mailman/listinfo/openssl-users