Skip to content

Commit 6f32d29

Browse files
committed
feat: add .der output talosctl gen secureboot pcr
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>
1 parent 87c40da commit 6f32d29

File tree

1 file changed

+41
-3
lines changed

1 file changed

+41
-3
lines changed

cmd/talosctl/cmd/mgmt/gen/secureboot.go

Lines changed: 41 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@
55
package gen
66

77
import (
8+
stdlibx509 "crypto/x509"
9+
"encoding/pem"
810
"fmt"
911
"io/fs"
1012
"os"
@@ -45,7 +47,7 @@ var genSecurebootUKICmd = &cobra.Command{
4547
Long: ``,
4648
Args: cobra.NoArgs,
4749
RunE: func(cmd *cobra.Command, args []string) error {
48-
return generateSigningCerts(genSecurebootCmdFlags.outputDirectory, "uki", genSecurebootUKICmdFlags.commonName, 4096, true)
50+
return generateSigningCerts(genSecurebootCmdFlags.outputDirectory, "uki", genSecurebootUKICmdFlags.commonName, 4096, true, false)
4951
},
5052
}
5153

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

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

100-
func generateSigningCerts(path, prefix, commonName string, rsaBits int, outputCert bool) error {
102+
//nolint:gocyclo
103+
func generateSigningCerts(path, prefix, commonName string, rsaBits int, outputCert, outputDER bool) error {
101104
currentTime := time.Now()
102105

103106
opts := []x509.Option{
@@ -118,6 +121,12 @@ func generateSigningCerts(path, prefix, commonName string, rsaBits int, outputCe
118121
if err = checkedWrite(filepath.Join(path, prefix+"-signing-cert.pem"), signingKey.CrtPEM, 0o600); err != nil {
119122
return err
120123
}
124+
125+
if outputDER {
126+
if err = saveAsDER(filepath.Join(path, prefix+"-signing-cert.der"), signingKey.CrtPEM); err != nil {
127+
return err
128+
}
129+
}
121130
}
122131

123132
if err = checkedWrite(filepath.Join(path, prefix+"-signing-key.pem"), signingKey.KeyPEM, 0o600); err != nil {
@@ -137,11 +146,26 @@ func generateSigningCerts(path, prefix, commonName string, rsaBits int, outputCe
137146
if err = checkedWrite(filepath.Join(path, prefix+"-signing-public-key.pem"), privKey.PublicKeyPEM, 0o600); err != nil {
138147
return err
139148
}
149+
150+
if outputDER {
151+
if err = saveAsDER(filepath.Join(path, prefix+"-signing-public-key.der"), privKey.PublicKeyPEM); err != nil {
152+
return err
153+
}
154+
}
140155
}
141156

142157
return nil
143158
}
144159

160+
func saveAsDER(file string, pem []byte) error {
161+
publicKeyDER, err := convertPEMToDER(pem)
162+
if err != nil {
163+
return err
164+
}
165+
166+
return checkedWrite(file, publicKeyDER, 0o600)
167+
}
168+
145169
// generateSecureBootDatabase generates a UEFI database to enroll the signing certificate.
146170
//
147171
// ref: https://blog.hansenpartnership.com/the-meaning-of-all-the-uefi-keys/
@@ -232,3 +256,17 @@ func init() {
232256
&genSecurebootDatabaseCmdFlags.signingKeyPath, "signing-key", helpers.ArtifactPath(constants.SecureBootSigningKeyAsset), "path to the key used to sign the database")
233257
genSecurebootCmd.AddCommand(genSecurebootDatabaseCmd)
234258
}
259+
260+
func convertPEMToDER(data []byte) ([]byte, error) {
261+
block, _ := pem.Decode(data)
262+
if block == nil {
263+
return nil, fmt.Errorf("failed to decode PEM data")
264+
}
265+
266+
key, err := stdlibx509.ParsePKIXPublicKey(block.Bytes)
267+
if err != nil {
268+
return nil, err
269+
}
270+
271+
return stdlibx509.MarshalPKIXPublicKey(key)
272+
}

0 commit comments

Comments
 (0)