5
5
package gen
6
6
7
7
import (
8
+ stdlibx509 "crypto/x509"
9
+ "encoding/pem"
8
10
"fmt"
9
11
"io/fs"
10
12
"os"
@@ -45,7 +47,7 @@ var genSecurebootUKICmd = &cobra.Command{
45
47
Long : `` ,
46
48
Args : cobra .NoArgs ,
47
49
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 )
49
51
},
50
52
}
51
53
@@ -56,7 +58,7 @@ var genSecurebootPCRCmd = &cobra.Command{
56
58
Long : `` ,
57
59
Args : cobra .NoArgs ,
58
60
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 )
60
62
},
61
63
}
62
64
@@ -97,7 +99,8 @@ func checkedWrite(path string, data []byte, perm fs.FileMode) error { //nolint:u
97
99
return os .WriteFile (path , data , perm )
98
100
}
99
101
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 {
101
104
currentTime := time .Now ()
102
105
103
106
opts := []x509.Option {
@@ -118,6 +121,12 @@ func generateSigningCerts(path, prefix, commonName string, rsaBits int, outputCe
118
121
if err = checkedWrite (filepath .Join (path , prefix + "-signing-cert.pem" ), signingKey .CrtPEM , 0o600 ); err != nil {
119
122
return err
120
123
}
124
+
125
+ if outputDER {
126
+ if err = saveAsDER (filepath .Join (path , prefix + "-signing-cert.der" ), signingKey .CrtPEM ); err != nil {
127
+ return err
128
+ }
129
+ }
121
130
}
122
131
123
132
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
137
146
if err = checkedWrite (filepath .Join (path , prefix + "-signing-public-key.pem" ), privKey .PublicKeyPEM , 0o600 ); err != nil {
138
147
return err
139
148
}
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
+ }
140
155
}
141
156
142
157
return nil
143
158
}
144
159
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
+
145
169
// generateSecureBootDatabase generates a UEFI database to enroll the signing certificate.
146
170
//
147
171
// ref: https://blog.hansenpartnership.com/the-meaning-of-all-the-uefi-keys/
@@ -232,3 +256,17 @@ func init() {
232
256
& genSecurebootDatabaseCmdFlags .signingKeyPath , "signing-key" , helpers .ArtifactPath (constants .SecureBootSigningKeyAsset ), "path to the key used to sign the database" )
233
257
genSecurebootCmd .AddCommand (genSecurebootDatabaseCmd )
234
258
}
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