* Re: SSL Certificate management - proposed REST APIs
[not found] <mailman.863.1533082376.30117.openbmc@lists.ozlabs.org>
@ 2018-08-01 13:40 ` Joseph Reynolds
2018-08-06 21:33 ` Ed Tanous
0 siblings, 1 reply; 2+ messages in thread
From: Joseph Reynolds @ 2018-08-01 13:40 UTC (permalink / raw)
To: openbmc
[-- Attachment #1: Type: text/plain, Size: 4007 bytes --]
> Message: 4
> Date: Tue, 31 Jul 2018 20:19:38 +0530
> From: Jayanth Othayoth <ojayanth@gmail.com>
> To: openbmc@lists.ozlabs.org, bradleyb@fuzziesquirrel.com,
> ed.tanous@intel.com
> Subject: SSL Certificate management proposal.
> Message-ID:
> <CACkAXSrxyf819dQc+LEOfwahpcrK2QRH1AkXump-D9Ae+yaKBQ@mail.gmail.com>
> Content-Type: text/plain; charset="utf-8"
>
> This proposal provides a mechanism to replace the self signed certificate
> with CA signed certificate based on BMC generated CSR.
> [...snip...]
>
> How to update a signed certificate on the BMC ?
> [...snip...]
>
> In order to support the above workflow, the BMC shall provide the
> following
> REST APIs:
> [...snip...]
> - Upload digitally signed certificate.
> - Activate digitally signed certificates
> - Download digitally signed certificate
> [...snip...]
>
> Note: REST/D-bus details not included here.
Straw-man proposal for SSL certificate REST APIs
URIs:
/xyz/openbmc_project/certificates/ssl/{index}
Represents a SSL certificate
Supports GET, PUT, POST, DELETE
JSON { "certificate": "..." }
/xyz/openbmc_project/certificates/ssl/active
Represents which certificate is used by SSL
Supports GET, PUT, DELETE
JSON { "data": "/xyz/openbmc_project/certificates/ssl/1" }
See the magic below.
Notes:
- These represent a collection of SSL certificates and optionally an
active one.
- The number of certificates can be zero or more.
- The certificate numbering ({index}) must be stable across API
operations.
- The implementation can impose a maximum limit (16 is plenty?).
- Duplicate certificates are allowed and are not detected.
- Expired certificates are allowed and are not detected.
- Mal-formed certificates are detected? TODO
- The certificates and active certificate info persists across rebooting.
Magic for the active SSL certificate:
- When SSL is started with no active certificate:
+ A certificate is created and used to sign itself.
+ The new certificate becomes the active certificate.
+ TODO: What if you already have the maximum number of certificates
allowed?
- When you attempt to delete the active certificate:
+ This is allowed. TODO: Or maybe not allowed.
+ There will be no active certificate (see implementation note).
+ /xyz/openbmc_project/certificates/ssl/active is deleted.
+ The underlying certificate is not deleted.
- When you PUT (replace) the active certificate:
+ This is allowed. TODO: Or maybe not allowed.
+ The newly put certificate becomes active (see implementation note).
+ /xyz/openbmc_project/certificates/ssl/active does not change.
Implementation note: When you change the active certificate while SSL is
running, does the behavior of SSL change immediately, or only for new
connections? How does this work? TODO.
Ideas to support future behaviors:
1. To support future certificate types, the ssl element was used. Ideas:
/xyz/openbmc_project/certificates/ssl
/xyz/openbmc_project/certificates/host
/xyz/openbmc_project/certificates/rootoftrust
2. There are two options to articulate the content of each certificate
(such as an associated private key or certificate signing request): JSON
and URIs:
JSON:
{ "certificate": "...", "privatekey": "...", "expiration": "DATE" }
URIs:
/xyz/openbmc_project/certificates/ssl/1/certificate
/xyz/openbmc_project/certificates/ssl/1/privatekey
/xyz/openbmc_project/certificates/ssl/1/csr
The JSON approach seems way easier.
3. The URIs for certificate signing requests (CSR) could be:
/xyz/openbmc_project/certificates/csr/{index}
/xyz/openbmc_project/certificates/ssl/csr
/xyz/openbmc_project/certificates/ssl/csr/{index}
depending on how many CSRs you wanted to support. (But let's not debate
that now).
[-- Attachment #2: Type: text/html, Size: 6195 bytes --]
^ permalink raw reply [flat|nested] 2+ messages in thread
* Re: SSL Certificate management - proposed REST APIs
2018-08-01 13:40 ` SSL Certificate management - proposed REST APIs Joseph Reynolds
@ 2018-08-06 21:33 ` Ed Tanous
0 siblings, 0 replies; 2+ messages in thread
From: Ed Tanous @ 2018-08-06 21:33 UTC (permalink / raw)
To: openbmc
On 08/01/2018 06:40 AM, Joseph Reynolds wrote:
>> Message: 4
>> Date: Tue, 31 Jul 2018 20:19:38 +0530
>> From: Jayanth Othayoth <ojayanth@gmail.com>
>> To: openbmc@lists.ozlabs.org, bradleyb@fuzziesquirrel.com,
>> ed.tanous@intel.com
>> Subject: SSL Certificate management proposal.
>> Message-ID:
>> <CACkAXSrxyf819dQc+LEOfwahpcrK2QRH1AkXump-D9Ae+yaKBQ@mail.gmail.com>
>> Content-Type: text/plain; charset="utf-8"
>>
>> This proposal provides a mechanism to replace the self signed certificate
>> with CA signed certificate based on BMC generated CSR.
>> [...snip...]
>>
>> How to update a signed certificate on the BMC ?
>> [...snip...]
>>
>> In order to support the above workflow, the BMC shall provide the
>> following
>> REST APIs:
>> [...snip...]
>> - Upload digitally signed certificate.
>> - Activate digitally signed certificates
>> - Download digitally signed certificate
>> [...snip...]
>>
>> Note: REST/D-bus details not included here.
>
> Straw-man proposal for SSL certificate REST APIs
>
> URIs:
> /xyz/openbmc_project/certificates/ssl/{index}
> Represents a SSL certificate
> Supports GET, PUT, POST, DELETE
This endpoint really shouldn't support POST, as that would be a creation
action. You can't create an already created object, and we shouldn't
really support creation of new certificate types at runtime. GET is
bad, because it implies that we allow download of the cert once it's on
the BMC, which we shouldn't do. I suspect this API should support PUT
and possibly DELETE (to revert back to a self signed cert).
> JSON { "certificate": "..." }
This field exist in a GET response. Once uploaded, I don't think we
should expose the key through any external interfaces. You could do
something similar to the redfish AccountService schema, where it
specifies that that field (like password) will be nullptr on responses,
but I'm not sure what value it provides. Alternatively you could return
some of the data fields that aren't considered secret (expiration date,
common name, ect), but again, I'm not really sure how useful that is.
> /xyz/openbmc_project/certificates/ssl/active
> Represents which certificate is used by SSL
> Supports GET, PUT, DELETE
> JSON { "data": "/xyz/openbmc_project/certificates/ssl/1" }
> See the magic below.
Why even support a collection and an activate? Testing a REST
collection is much more difficult than testing a single endpoint that
allows uploading a key, and reduces the number of things you need to
specify. For example, how many certificates should we allow storing?
Should we store them all in nonvolatile or temporal storage? When a
delete is issued, how do we ensure the unique id (1 in the above case)
doesn't change?
An API like below seems a lot easier to understand and use
/xyz/openbmc_project/certificates/ssl
Supports PUT, DELETE
PUT JSON { "data": "<CERTIFICATE DATA>" }
POST would upload the certificate, verify it, and restart the webserver.
DELETE would remove the previously uploaded certificate and replace with
the "default" certificate. In the case of ssl, it would replace it with
the self signed key.
>
> Notes:
> - These represent a collection of SSL certificates and optionally an
> active one.
> - The number of certificates can be zero or more.
Given some of the other requirements, should it ever be zero? Shouldn't
we always at least have a self signed cert? Baring that, does the
number of keys we support even change at runtime? I suspect we can just
come up with a list of well known names (ssl, ldap, ect) at compile
time, and avoid the concept of uploading and naming certificates
alltogether.
> - The certificate numbering ({index}) must be stable across API
> operations.
> - The implementation can impose a maximum limit (16 is plenty?).
> - Duplicate certificates are allowed and are not detected.
> - Expired certificates are allowed and are not detected.
> - Mal-formed certificates are detected? TODO
> - The certificates and active certificate info persists across rebooting.
>
If we removed the collection aspect, most of these requirements (and
associated test cases) go away, and the interface becomes much easier to
use. I believe this is the path we should go down.
> Magic for the active SSL certificate:
> - When SSL is started with no active certificate:
> + A certificate is created and used to sign itself.
> + The new certificate becomes the active certificate.
> + TODO: What if you already have the maximum number of certificates
> allowed?
> - When you attempt to delete the active certificate:
> + This is allowed. TODO: Or maybe not allowed.
> + There will be no active certificate (see implementation note).
> + /xyz/openbmc_project/certificates/ssl/active is deleted.
> + The underlying certificate is not deleted.
> - When you PUT (replace) the active certificate:
> + This is allowed. TODO: Or maybe not allowed.
> + The newly put certificate becomes active (see implementation note).
> + /xyz/openbmc_project/certificates/ssl/active does not change.
>
> Implementation note: When you change the active certificate while SSL is
> running, does the behavior of SSL change immediately, or only for new
> connections? How does this work? TODO.
I don't know of a way to persist TLS sessions on a key change, without
keeping a second OpenSSL context around. I suspect we need to complete
the TLS session with the existing key (to give the uploader the correct
response) then drain and close the connection pool, and restart the server.
>
> Ideas to support future behaviors:
>
> 1. To support future certificate types, the ssl element was used. Ideas:
> /xyz/openbmc_project/certificates/ssl
> /xyz/openbmc_project/certificates/host
> /xyz/openbmc_project/certificates/rootoftrust
I like this, as it makes it very explicit what keys are supported to a
user, although I suspect root of trust certificates will take a
different form.
>
> 2. There are two options to articulate the content of each certificate
> (such as an associated private key or certificate signing request): JSON
> and URIs:
> JSON:
> { "certificate": "...", "privatekey": "...", "expiration": "DATE" }
> URIs:
> /xyz/openbmc_project/certificates/ssl/1/certificate
> /xyz/openbmc_project/certificates/ssl/1/privatekey
> /xyz/openbmc_project/certificates/ssl/1/csr
Private key should never be hosted from an outbound interface. Doing so
defeats the entire purpose of generating the CSR on the bmc in the first
case. These APIs could be POST only, in which case it would be much
better, but in that case, you don't necessarily need CSR.
> The JSON approach seems way easier.
>
> 3. The URIs for certificate signing requests (CSR) could be:
> /xyz/openbmc_project/certificates/csr/{index}
> /xyz/openbmc_project/certificates/ssl/csr
> /xyz/openbmc_project/certificates/ssl/csr/{index}
> depending on how many CSRs you wanted to support. (But let's not debate
> that now).
>
:) Can we debate 1 versus >1? I don't know of any use cases that would
require multiple CSRs per interface, and single CSR, with persistence
until the next reboot is much easier to design and test than a multiple
certificate store kept persistently.
^ permalink raw reply [flat|nested] 2+ messages in thread
end of thread, other threads:[~2018-08-06 21:36 UTC | newest]
Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
[not found] <mailman.863.1533082376.30117.openbmc@lists.ozlabs.org>
2018-08-01 13:40 ` SSL Certificate management - proposed REST APIs Joseph Reynolds
2018-08-06 21:33 ` Ed Tanous
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).