@@ -2,9 +2,6 @@ package storage
2
2
3
3
import (
4
4
"context"
5
- "crypto"
6
- "encoding/json"
7
- "io"
8
5
"io/fs"
9
6
"path/filepath"
10
7
"strings"
@@ -30,64 +27,24 @@ func SignatureZipFilename(manifest *VSIXManifest) string {
30
27
31
28
// Signature is a storage wrapper that can sign extensions on demand.
32
29
type Signature struct {
33
- // Signer if provided, will be used to sign extensions. If not provided,
34
- // no extensions will be signed.
35
- Signer crypto.Signer
36
- Logger slog.Logger
37
- // SaveSigZips is a flag that will save the signed extension to disk.
38
- // This is useful for debugging, but the server will never use this file.
39
- saveSigZips bool
30
+ Logger slog.Logger
31
+ IncludeEmptySignatures bool
40
32
Storage
41
33
}
42
34
43
- func NewSignatureStorage (logger slog.Logger , signer crypto.Signer , s Storage ) * Signature {
44
- return & Signature {
45
- Signer : signer ,
46
- Storage : s ,
35
+ func NewSignatureStorage (logger slog.Logger , includeEmptySignatures bool , s Storage ) * Signature {
36
+ if includeEmptySignatures {
37
+ logger .Info (context .Background (), "Signature storage enabled, if using VSCode on Windows, this will not work." )
47
38
}
48
- }
49
-
50
- func (s * Signature ) SaveSigZips () {
51
- if ! s .saveSigZips {
52
- s .Logger .Info (context .Background (), "extension signatures will be saved to disk, do not use this in production" )
39
+ return & Signature {
40
+ Logger : logger ,
41
+ IncludeEmptySignatures : includeEmptySignatures ,
42
+ Storage : s ,
53
43
}
54
- s .saveSigZips = true
55
44
}
56
45
57
46
func (s * Signature ) SigningEnabled () bool {
58
- return s .Signer != nil
59
- }
60
-
61
- // AddExtension includes the signature manifest of the vsix. Signing happens on
62
- // demand, so leave the manifest unsigned. This is safe to do even if
63
- // 'signExtensions' is disabled, as these files lay dormant until signed.
64
- func (s * Signature ) AddExtension (ctx context.Context , manifest * VSIXManifest , vsix []byte , extra ... File ) (string , error ) {
65
- sigManifest , err := extensionsign .GenerateSignatureManifest (vsix )
66
- if err != nil {
67
- return "" , xerrors .Errorf ("generate signature manifest: %w" , err )
68
- }
69
-
70
- sigManifestJSON , err := json .Marshal (sigManifest )
71
- if err != nil {
72
- return "" , xerrors .Errorf ("encode signature manifest: %w" , err )
73
- }
74
-
75
- if s .SigningEnabled () && s .saveSigZips {
76
- signed , err := s .SigZip (ctx , vsix , sigManifestJSON )
77
- if err != nil {
78
- s .Logger .Error (ctx , "signing manifest" , slog .Error (err ))
79
- return "" , xerrors .Errorf ("sign and zip manifest: %w" , err )
80
- }
81
- extra = append (extra , File {
82
- RelativePath : SignatureZipFilename (manifest ),
83
- Content : signed ,
84
- })
85
- }
86
-
87
- return s .Storage .AddExtension (ctx , manifest , vsix , append (extra , File {
88
- RelativePath : sigManifestName ,
89
- Content : sigManifestJSON ,
90
- })... )
47
+ return s .IncludeEmptySignatures
91
48
}
92
49
93
50
func (s * Signature ) Manifest (ctx context.Context , publisher , name string , version Version ) (* VSIXManifest , error ) {
@@ -116,60 +73,22 @@ func (s *Signature) Manifest(ctx context.Context, publisher, name string, versio
116
73
// Open will intercept requests for signed extensions payload.
117
74
// It does this by looking for 'SigzipFileExtension' or p7s.sig.
118
75
//
119
- // The signed payload and signing process is taken from:
120
- // https://github.com/filiptronicek/node-ovsx-sign
76
+ // The signed payload is completely empty. Nothing it actually signed.
121
77
//
122
78
// Some notes:
123
79
//
124
80
// - VSCodium requires a signature to exist, but it does appear to actually read
125
81
// the signature. Meaning the signature could be empty, incorrect, or a
126
82
// picture of cat and it would work. There is no signature verification.
127
83
//
128
- // - VSCode requires a signature payload to exist, but the context appear
129
- // to be somewhat optional.
130
- // Following another open source implementation, it appears the '.signature.p7s'
131
- // file must exist, but it can be empty.
132
- // The signature is stored in a '.signature.sig' file, although it is unclear
133
- // is VSCode ever reads this file.
134
- // TODO: Properly implement the p7s file, and diverge from the other open
135
- // source implementation. Ideally this marketplace would match Microsoft's
136
- // marketplace API.
84
+ // - VSCode requires a signature payload to exist, but the content is optional
85
+ // for linux users.
86
+ // For windows users, the signature must be valid, and this implementation
87
+ // will not work.
137
88
func (s * Signature ) Open (ctx context.Context , fp string ) (fs.File , error ) {
138
89
if s .SigningEnabled () && strings .HasSuffix (filepath .Base (fp ), SigzipFileExtension ) {
139
- base := filepath .Base (fp )
140
- vsixPath := strings .TrimSuffix (base , SigzipFileExtension )
141
-
142
- // hijack this request, sign the sig manifest
143
- manifest , err := s .Storage .Open (ctx , filepath .Join (filepath .Dir (fp ), sigManifestName ))
144
- if err != nil {
145
- // If this file is missing, it means the extension was added before
146
- // signatures were handled by the marketplace.
147
- // TODO: Generate the sig manifest payload and insert it?
148
- return nil , xerrors .Errorf ("open signature manifest: %w" , err )
149
- }
150
- defer manifest .Close ()
151
-
152
- manifestData , err := io .ReadAll (manifest )
153
- if err != nil {
154
- return nil , xerrors .Errorf ("read signature manifest: %w" , err )
155
- }
156
-
157
- vsix , err := s .Storage .Open (ctx , filepath .Join (filepath .Dir (fp ), vsixPath + ".vsix" ))
158
- if err != nil {
159
- // If this file is missing, it means the extension was added before
160
- // signatures were handled by the marketplace.
161
- // TODO: Generate the sig manifest payload and insert it?
162
- return nil , xerrors .Errorf ("open signature manifest: %w" , err )
163
- }
164
- defer vsix .Close ()
165
-
166
- vsixData , err := io .ReadAll (vsix )
167
- if err != nil {
168
- return nil , xerrors .Errorf ("read signature manifest: %w" , err )
169
- }
170
-
171
- // TODO: Fetch the VSIX payload from the storage
172
- signed , err := s .SigZip (ctx , vsixData , manifestData )
90
+ // hijack this request, return an empty signature payload
91
+ signed , err := extensionsign .IncludeEmptySignature ()
173
92
if err != nil {
174
93
return nil , xerrors .Errorf ("sign and zip manifest: %w" , err )
175
94
}
@@ -181,12 +100,3 @@ func (s *Signature) Open(ctx context.Context, fp string) (fs.File, error) {
181
100
182
101
return s .Storage .Open (ctx , fp )
183
102
}
184
-
185
- func (s * Signature ) SigZip (ctx context.Context , vsix []byte , sigManifest []byte ) ([]byte , error ) {
186
- signed , err := extensionsign .SignAndZipManifest (s .Signer , vsix , sigManifest )
187
- if err != nil {
188
- s .Logger .Error (ctx , "signing manifest" , slog .Error (err ))
189
- return nil , xerrors .Errorf ("sign and zip manifest: %w" , err )
190
- }
191
- return signed , nil
192
- }
0 commit comments