@@ -11,12 +11,11 @@ import (
11
11
"crypto/rsa"
12
12
"crypto/sha512"
13
13
"crypto/x509"
14
- "encoding/hex "
14
+ "encoding/binary "
15
15
"flag"
16
16
"fmt"
17
17
"io"
18
18
"os"
19
- "strconv"
20
19
21
20
"go.mozilla.org/pkcs7"
22
21
)
@@ -36,8 +35,10 @@ import (
36
35
const (
37
36
// SignedModuleMagic is the magic string appended to the end of a signed module.
38
37
SignedModuleMagic = "~Module signature appended~\n "
38
+ // SignedModuleMagicLength is the length of the magic string.
39
+ SignedModuleMagicLength = int64 (len (SignedModuleMagic ))
39
40
// ModuleSignatureInfoLength is the length of the signature info.
40
- ModuleSignatureInfoLength = 12
41
+ ModuleSignatureInfoLength int64 = 12
41
42
)
42
43
43
44
var (
@@ -72,56 +73,58 @@ func main() {
72
73
fmt .Println (err )
73
74
os .Exit (1 )
74
75
}
76
+ defer moduleData .Close () //nolint:errcheck
75
77
76
78
if err := verifyModule (crt , moduleData ); err != nil {
77
79
fmt .Println (err )
78
- os .Exit (1 )
80
+ os .Exit (1 ) //nolint:gocritic
79
81
}
80
82
}
81
83
82
- func parseModuleInput (module string ) (* bytes.Reader , error ) {
84
+ type noOPCloser struct {
85
+ io.ReadSeeker
86
+ }
87
+
88
+ func (noOPCloser ) Close () error { return nil }
89
+
90
+ func parseModuleInput (module string ) (io.ReadSeekCloser , error ) {
83
91
if module == "-" {
84
92
moduleData , err := io .ReadAll (os .Stdin )
85
93
if err != nil {
86
94
return nil , fmt .Errorf ("failed to read module from stdin: %w" , err )
87
95
}
88
96
89
- return bytes .NewReader (moduleData ), nil
97
+ return noOPCloser { bytes .NewReader (moduleData )} , nil
90
98
}
91
99
92
- moduleData , err := os .ReadFile (module )
100
+ moduleData , err := os .Open (module )
93
101
if err != nil {
94
102
return nil , fmt .Errorf ("failed to open file %s: %w" , module , err )
95
103
}
96
104
97
- return bytes . NewReader ( moduleData ) , nil
105
+ return moduleData , nil
98
106
}
99
107
100
- func verifyModule (crt * x509.Certificate , moduleData * bytes.Reader ) error {
101
- fileLen := moduleData .Size ()
102
- signedModuleMagicStart := fileLen - int64 (len (SignedModuleMagic ))
103
-
104
- _ , err := moduleData .Seek (signedModuleMagicStart , 0 )
108
+ func verifyModule (crt * x509.Certificate , moduleData io.ReadSeeker ) error {
109
+ _ , err := moduleData .Seek (- SignedModuleMagicLength , io .SeekEnd )
105
110
if err != nil {
106
- return fmt .Errorf ("failed to seek to %d in file %s: %w" , signedModuleMagicStart , module , err )
111
+ return fmt .Errorf ("failed to seek to %d in file %s: %w" , - SignedModuleMagicLength , module , err )
107
112
}
108
113
109
114
magicBytes := make ([]byte , len (SignedModuleMagic ))
110
115
111
116
_ , err = moduleData .Read (magicBytes )
112
117
if err != nil {
113
- return fmt .Errorf ("failed to read %d bytes from file %s: %w" , len ( SignedModuleMagic ) , module , err )
118
+ return fmt .Errorf ("failed to read %d bytes from file %s: %w" , SignedModuleMagicLength , module , err )
114
119
}
115
120
116
121
if string (magicBytes ) != SignedModuleMagic {
117
122
return fmt .Errorf ("file %s is not a signed module" , module )
118
123
}
119
124
120
- signatureInfoStart := signedModuleMagicStart - ModuleSignatureInfoLength
121
-
122
- _ , err = moduleData .Seek (signatureInfoStart , 0 )
125
+ _ , err = moduleData .Seek (- SignedModuleMagicLength - ModuleSignatureInfoLength , io .SeekCurrent )
123
126
if err != nil {
124
- return fmt .Errorf ("failed to seek to %d in file %s: %w" , signatureInfoStart , module , err )
127
+ return fmt .Errorf ("failed to seek to %d in file %s: %w" , - SignedModuleMagicLength - ModuleSignatureInfoLength , module , err )
125
128
}
126
129
127
130
signatureBytes := make ([]byte , ModuleSignatureInfoLength )
@@ -131,17 +134,13 @@ func verifyModule(crt *x509.Certificate, moduleData *bytes.Reader) error {
131
134
return fmt .Errorf ("failed to read %d bytes from file %s: %w" , ModuleSignatureInfoLength , module , err )
132
135
}
133
136
134
- // The signature length is encoded in the last 2 bytes of the signature info.
135
- signatureLength , err := strconv .ParseInt (hex .EncodeToString (signatureBytes [(len (signatureBytes )- 2 ):]), 16 , 64 )
136
- if err != nil {
137
- return fmt .Errorf ("failed to parse signature length %w" , err )
138
- }
137
+ // The signature length is encoded in the last 4 bytes of the signature info.
138
+ // https://github.com/torvalds/linux/blob/master/scripts/sign-file.c#L62-L70
139
+ signatureLength := int64 (binary .BigEndian .Uint32 (signatureBytes [(len (signatureBytes ) - 4 ):]))
139
140
140
- signatureStart := signatureInfoStart - signatureLength
141
-
142
- _ , err = moduleData .Seek (signatureStart , 0 )
141
+ _ , err = moduleData .Seek (- ModuleSignatureInfoLength - signatureLength , io .SeekCurrent )
143
142
if err != nil {
144
- return fmt .Errorf ("failed to seek to %d in file %s: %w" , signatureStart , module , err )
143
+ return fmt .Errorf ("failed to seek to %d in file %s: %w" , - ModuleSignatureInfoLength - signatureLength , module , err )
145
144
}
146
145
147
146
signature := make ([]byte , signatureLength )
@@ -151,26 +150,16 @@ func verifyModule(crt *x509.Certificate, moduleData *bytes.Reader) error {
151
150
return fmt .Errorf ("failed to read %d bytes from file %s: %w" , signatureLength , module , err )
152
151
}
153
152
154
- moduleWithSignatureLength := fileLen - int64 (len (SignedModuleMagic ))
155
-
156
- _ , err = moduleData .Seek (0 , 0 )
153
+ unsignedModuleLength , err := moduleData .Seek (- signatureLength , io .SeekCurrent )
157
154
if err != nil {
158
155
return fmt .Errorf ("failed to seek to %d in file %s: %w" , 0 , module , err )
159
156
}
160
157
161
- moduleWithSignature := make ([]byte , moduleWithSignatureLength )
162
-
163
- _ , err = moduleData .Read (moduleWithSignature )
164
- if err != nil {
165
- return fmt .Errorf ("failed to read %d bytes from file %s: %w" , moduleWithSignatureLength , module , err )
166
- }
167
-
168
158
_ , err = moduleData .Seek (0 , 0 )
169
159
if err != nil {
170
160
return fmt .Errorf ("failed to seek to %d in file %s: %w" , 0 , module , err )
171
161
}
172
162
173
- unsignedModuleLength := fileLen - signatureLength - ModuleSignatureInfoLength - int64 (len (SignedModuleMagic ))
174
163
unsignedModuleData := make ([]byte , unsignedModuleLength )
175
164
176
165
_ , err = moduleData .Read (unsignedModuleData )
0 commit comments