Skip to content

Commit

Permalink
feat: add .der output talosctl gen secureboot pcr
Browse files Browse the repository at this point in the history
Output the PCR public key in `.der` format in addition to the `.pem` format.

Closes #7742.

Signed-off-by: Utku Ozdemir <utku.ozdemir@siderolabs.com>
  • Loading branch information
utkuozdemir committed Nov 7, 2023
1 parent 87c40da commit 6f32d29
Showing 1 changed file with 41 additions and 3 deletions.
44 changes: 41 additions & 3 deletions cmd/talosctl/cmd/mgmt/gen/secureboot.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@
package gen

import (
stdlibx509 "crypto/x509"
"encoding/pem"
"fmt"
"io/fs"
"os"
Expand Down Expand Up @@ -45,7 +47,7 @@ var genSecurebootUKICmd = &cobra.Command{
Long: ``,
Args: cobra.NoArgs,
RunE: func(cmd *cobra.Command, args []string) error {
return generateSigningCerts(genSecurebootCmdFlags.outputDirectory, "uki", genSecurebootUKICmdFlags.commonName, 4096, true)
return generateSigningCerts(genSecurebootCmdFlags.outputDirectory, "uki", genSecurebootUKICmdFlags.commonName, 4096, true, false)
},
}

Expand All @@ -56,7 +58,7 @@ var genSecurebootPCRCmd = &cobra.Command{
Long: ``,
Args: cobra.NoArgs,
RunE: func(cmd *cobra.Command, args []string) error {
return generateSigningCerts(genSecurebootCmdFlags.outputDirectory, "pcr", "dummy", 2048, false)
return generateSigningCerts(genSecurebootCmdFlags.outputDirectory, "pcr", "dummy", 2048, false, true)
},
}

Expand Down Expand Up @@ -97,7 +99,8 @@ func checkedWrite(path string, data []byte, perm fs.FileMode) error { //nolint:u
return os.WriteFile(path, data, perm)
}

func generateSigningCerts(path, prefix, commonName string, rsaBits int, outputCert bool) error {
//nolint:gocyclo
func generateSigningCerts(path, prefix, commonName string, rsaBits int, outputCert, outputDER bool) error {
currentTime := time.Now()

opts := []x509.Option{
Expand All @@ -118,6 +121,12 @@ func generateSigningCerts(path, prefix, commonName string, rsaBits int, outputCe
if err = checkedWrite(filepath.Join(path, prefix+"-signing-cert.pem"), signingKey.CrtPEM, 0o600); err != nil {
return err
}

if outputDER {
if err = saveAsDER(filepath.Join(path, prefix+"-signing-cert.der"), signingKey.CrtPEM); err != nil {
return err
}
}
}

if err = checkedWrite(filepath.Join(path, prefix+"-signing-key.pem"), signingKey.KeyPEM, 0o600); err != nil {
Expand All @@ -137,11 +146,26 @@ func generateSigningCerts(path, prefix, commonName string, rsaBits int, outputCe
if err = checkedWrite(filepath.Join(path, prefix+"-signing-public-key.pem"), privKey.PublicKeyPEM, 0o600); err != nil {
return err
}

if outputDER {
if err = saveAsDER(filepath.Join(path, prefix+"-signing-public-key.der"), privKey.PublicKeyPEM); err != nil {
return err
}
}
}

return nil
}

func saveAsDER(file string, pem []byte) error {
publicKeyDER, err := convertPEMToDER(pem)
if err != nil {
return err
}

return checkedWrite(file, publicKeyDER, 0o600)
}

// generateSecureBootDatabase generates a UEFI database to enroll the signing certificate.
//
// ref: https://blog.hansenpartnership.com/the-meaning-of-all-the-uefi-keys/
Expand Down Expand Up @@ -232,3 +256,17 @@ func init() {
&genSecurebootDatabaseCmdFlags.signingKeyPath, "signing-key", helpers.ArtifactPath(constants.SecureBootSigningKeyAsset), "path to the key used to sign the database")
genSecurebootCmd.AddCommand(genSecurebootDatabaseCmd)
}

func convertPEMToDER(data []byte) ([]byte, error) {
block, _ := pem.Decode(data)
if block == nil {
return nil, fmt.Errorf("failed to decode PEM data")
}

key, err := stdlibx509.ParsePKIXPublicKey(block.Bytes)
if err != nil {
return nil, err
}

return stdlibx509.MarshalPKIXPublicKey(key)
}

0 comments on commit 6f32d29

Please sign in to comment.