kairos-io / enki

Building Kairos artifacts with ease
1 stars 2 forks source link

NewGenkeyCmd() doesn't allow bringing your own certificates #91

Open kreeuwijk opened 5 months ago

kreeuwijk commented 5 months ago

Enki's NewGenkeyCmd() function always generates new self-signed certificates with openssl. This is a problem when the customer wants to use their own CA to issue the PK, KEK and DB certificates.

We need to be able to take the provided certificates and the factory exported keys from a device as inputs and generate the rest from that:

secure-boot/public-keys/
  db.pem    <-- Delivered by customer from private CA
  PK.pem    <-- Delivered by customer from private CA
  KEK.pem   <-- Delivered by customer from private CA

secure-boot/enrollment
  PK.auth   <-- Generated by Kairos genkey
  PK.der    <-- Generated by Kairos genkey
  PK.esl    <-- Generated by Kairos genkey
  KEK.auth  <-- Generated by Kairos genkey
  KEK.esl   <-- Generated by Kairos genkey
  KEK.der   <-- Generated by Kairos genkey
  db.auth   <-- Generated by Kairos genkey
  db.esl    <-- Generated by Kairos genkey
  db.der    <-- Generated by Kairos genkey

secure-boot/private-keys
  PK.key                <-- Delivered by customer from private CA
  KEK.key               <-- Delivered by customer from private CA
  db.key                <-- Delivered by customer from private CA
  tpm2-pcr-private.pem  <-- Generated by Kairos genkey

secure-boot/exported-keys
  dbx.esl   <-- Exported by customer from device
  KEK.esl   <-- Exported by customer from device
  db.esl    <-- Exported by customer from device

enki already is able to take the factory exported keys (ESL) from a device and add those to its own generated secure boot keys, so that's good. What's missing is the ability to bring your own starting certificates.

Currently, the NewGenkeyCmd() function in enki always generates a fresh set of self-signed certificates, What needs to happen is that enki gets another switch that tells it to not run openssl to make new self-signed PK,KEK,DB certificates but instead read existing PK,KEK,DB certificates from disk and feed those to the rest of the process.

CanvOS places all files noted above in the /keys directory for enki, so it can expect to find the customer-provided certificate files there.

jimmykarily commented 5 months ago

@kreeuwijk let me know if this is a good description of what we are trying to achieve: https://github.com/Foxboron/sbctl/pull/303#issuecomment-2078881666

we are still investigating the possibility of replacing genkey commands completely with a set of sbctl commands to prepare the keys needed for build-uki command.

kreeuwijk commented 5 months ago

@jimmykarily sbctl happens later in the process. This request is not about the .esl or .auth files. This request is about the .pem and .key files that enki generates with openssl at the very start of the function.

jimmykarily commented 5 months ago

You are suggesting changes to a command that I'm suggesting it shouldn't exist enki genkey , am I wrong? @nianyush if you already have a flow that satisfies the scenario described here, can you please share the list of commands? I would then drop my PR in sbctl and all we need to do is document the process or simplify it with some script or something.

kreeuwijk commented 5 months ago

@jimmykarily agreed, if we can do all steps with sbctl than we can just switch to using that

kreeuwijk commented 5 months ago

I don't believe we require sbctl to be able to export the existing keys from a device's firmware though. That one-time export can already be done with efi-readvar or Get-SecureBootUEFI (PowerShell).

jimmykarily commented 5 months ago

True, it's not necessary but if it does, it:

If these are not very important, I can just drop the PR.

kreeuwijk commented 5 months ago

Many of the customers tend to be Windows-oriented, so I'd rather not standardize on having to use sbctl just to get the existing keys exported. We can put the efitools package with a small export script on a Linux ISO if we want. But most likely we will just put the needed command lines (for Linux and Windows) into our documentation for customers to follow.

That also results in the desired filenames and it works around the issue of figuring out a way to get the files off the device when you're booted from a read-only ISO. It's just easier to put a regular OS on the box and then have a couple command lines to run to get the files needed.

nianyush commented 5 months ago

Steps to run on the machine with key enrolled to generate auth/esl

  1. Prepare keys in following dir structure
    /workdir # tree
    .
    ├── KEK
    │   ├── KEK.key
    │   └── KEK.pem
    ├── PK
    │   ├── PK.key
    │   └── PK.pem
    └── db
    ├── db.key
    └── db.pem
  2. sbctl import-keys -d ./
  3. sbctl create-keys (to create GUID)
  4. sbctl enroll-keys --export auth --yes-this-might-brick-my-machine -a
  5. sbctl enroll-keys --export esl --yes-this-might-brick-my-machine -a
  6. keys will be under current work dir
    /usr/share/secureboot # ls -l
    total 28
    -rw-r--r--    1 root     root            36 Apr 26 08:12 GUID
    -rw-r--r--    1 root     root          2141 Apr 26 08:16 KEK.auth
    -rw-r--r--    1 root     root           825 Apr 26 08:17 KEK.esl
    -rw-r--r--    1 root     root          2141 Apr 26 08:16 PK.auth
    -rw-r--r--    1 root     root           825 Apr 26 08:17 PK.esl
    -rw-r--r--    1 root     root          2141 Apr 26 08:16 db.auth
    -rw-r--r--    1 root     root           825 Apr 26 08:17 db.esl
    drwxr-xr-x    1 root     root            14 Apr 26 07:56 keys

    i am also testing with already exported cert, so we dont need to install sbctl on host machine