@@ -11,12 +11,11 @@ import (
1111 "crypto/rsa"
1212 "crypto/sha512"
1313 "crypto/x509"
14- "encoding/hex "
14+ "encoding/binary "
1515 "flag"
1616 "fmt"
1717 "io"
1818 "os"
19- "strconv"
2019
2120 "go.mozilla.org/pkcs7"
2221)
@@ -36,8 +35,10 @@ import (
3635const (
3736 // SignedModuleMagic is the magic string appended to the end of a signed module.
3837 SignedModuleMagic = "~Module signature appended~\n "
38+ // SignedModuleMagicLength is the length of the magic string.
39+ SignedModuleMagicLength = int64 (len (SignedModuleMagic ))
3940 // ModuleSignatureInfoLength is the length of the signature info.
40- ModuleSignatureInfoLength = 12
41+ ModuleSignatureInfoLength int64 = 12
4142)
4243
4344var (
@@ -72,56 +73,58 @@ func main() {
7273 fmt .Println (err )
7374 os .Exit (1 )
7475 }
76+ defer moduleData .Close () //nolint:errcheck
7577
7678 if err := verifyModule (crt , moduleData ); err != nil {
7779 fmt .Println (err )
78- os .Exit (1 )
80+ os .Exit (1 ) //nolint:gocritic
7981 }
8082}
8183
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 ) {
8391 if module == "-" {
8492 moduleData , err := io .ReadAll (os .Stdin )
8593 if err != nil {
8694 return nil , fmt .Errorf ("failed to read module from stdin: %w" , err )
8795 }
8896
89- return bytes .NewReader (moduleData ), nil
97+ return noOPCloser { bytes .NewReader (moduleData )} , nil
9098 }
9199
92- moduleData , err := os .ReadFile (module )
100+ moduleData , err := os .Open (module )
93101 if err != nil {
94102 return nil , fmt .Errorf ("failed to open file %s: %w" , module , err )
95103 }
96104
97- return bytes . NewReader ( moduleData ) , nil
105+ return moduleData , nil
98106}
99107
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 )
105110 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 )
107112 }
108113
109114 magicBytes := make ([]byte , len (SignedModuleMagic ))
110115
111116 _ , err = moduleData .Read (magicBytes )
112117 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 )
114119 }
115120
116121 if string (magicBytes ) != SignedModuleMagic {
117122 return fmt .Errorf ("file %s is not a signed module" , module )
118123 }
119124
120- signatureInfoStart := signedModuleMagicStart - ModuleSignatureInfoLength
121-
122- _ , err = moduleData .Seek (signatureInfoStart , 0 )
125+ _ , err = moduleData .Seek (- SignedModuleMagicLength - ModuleSignatureInfoLength , io .SeekCurrent )
123126 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 )
125128 }
126129
127130 signatureBytes := make ([]byte , ModuleSignatureInfoLength )
@@ -131,17 +134,13 @@ func verifyModule(crt *x509.Certificate, moduleData *bytes.Reader) error {
131134 return fmt .Errorf ("failed to read %d bytes from file %s: %w" , ModuleSignatureInfoLength , module , err )
132135 }
133136
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 ):]))
139140
140- signatureStart := signatureInfoStart - signatureLength
141-
142- _ , err = moduleData .Seek (signatureStart , 0 )
141+ _ , err = moduleData .Seek (- ModuleSignatureInfoLength - signatureLength , io .SeekCurrent )
143142 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 )
145144 }
146145
147146 signature := make ([]byte , signatureLength )
@@ -151,26 +150,16 @@ func verifyModule(crt *x509.Certificate, moduleData *bytes.Reader) error {
151150 return fmt .Errorf ("failed to read %d bytes from file %s: %w" , signatureLength , module , err )
152151 }
153152
154- moduleWithSignatureLength := fileLen - int64 (len (SignedModuleMagic ))
155-
156- _ , err = moduleData .Seek (0 , 0 )
153+ unsignedModuleLength , err := moduleData .Seek (- signatureLength , io .SeekCurrent )
157154 if err != nil {
158155 return fmt .Errorf ("failed to seek to %d in file %s: %w" , 0 , module , err )
159156 }
160157
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-
168158 _ , err = moduleData .Seek (0 , 0 )
169159 if err != nil {
170160 return fmt .Errorf ("failed to seek to %d in file %s: %w" , 0 , module , err )
171161 }
172162
173- unsignedModuleLength := fileLen - signatureLength - ModuleSignatureInfoLength - int64 (len (SignedModuleMagic ))
174163 unsignedModuleData := make ([]byte , unsignedModuleLength )
175164
176165 _ , err = moduleData .Read (unsignedModuleData )
0 commit comments