Merge lp:~apw/launchpad/signing-fit into lp:launchpad
- signing-fit
- Merge into devel
Proposed by
Andy Whitcroft
Status: | Superseded | ||||
---|---|---|---|---|---|
Proposed branch: | lp:~apw/launchpad/signing-fit | ||||
Merge into: | lp:launchpad | ||||
Diff against target: |
876 lines (+442/-35) 2 files modified
lib/lp/archivepublisher/signing.py (+81/-26) lib/lp/archivepublisher/tests/test_signing.py (+361/-9) |
||||
To merge this branch: | bzr merge lp:~apw/launchpad/signing-fit | ||||
Related bugs: |
|
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Launchpad code reviewers | Pending | ||
Review via email: mp+368276@code.launchpad.net |
This proposal has been superseded by a proposal from 2019-06-03.
Commit message
Add u-boot Flat Image Tree signing support. u-boot supports generation and verification of FIT images in a similar fashion to secure boot. These signatures are expressed as signature nodes in the DTB contained within the FIT image. Add support for performing FIT signing against *.fit files in the signing custom uploads.
Description of the change
To post a comment you must log in.
Preview Diff
[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1 | === modified file 'lib/lp/archivepublisher/signing.py' | |||
2 | --- lib/lp/archivepublisher/signing.py 2018-08-03 16:10:41 +0000 | |||
3 | +++ lib/lp/archivepublisher/signing.py 2019-06-03 14:59:55 +0000 | |||
4 | @@ -95,6 +95,10 @@ | |||
5 | 95 | self.kmod_x509 = None | 95 | self.kmod_x509 = None |
6 | 96 | self.opal_pem = None | 96 | self.opal_pem = None |
7 | 97 | self.opal_x509 = None | 97 | self.opal_x509 = None |
8 | 98 | self.sipl_pem = None | ||
9 | 99 | self.sipl_x509 = None | ||
10 | 100 | self.fit_key = None | ||
11 | 101 | self.fit_cert = None | ||
12 | 98 | self.autokey = False | 102 | self.autokey = False |
13 | 99 | else: | 103 | else: |
14 | 100 | self.uefi_key = os.path.join(pubconf.signingroot, "uefi.key") | 104 | self.uefi_key = os.path.join(pubconf.signingroot, "uefi.key") |
15 | @@ -103,6 +107,13 @@ | |||
16 | 103 | self.kmod_x509 = os.path.join(pubconf.signingroot, "kmod.x509") | 107 | self.kmod_x509 = os.path.join(pubconf.signingroot, "kmod.x509") |
17 | 104 | self.opal_pem = os.path.join(pubconf.signingroot, "opal.pem") | 108 | self.opal_pem = os.path.join(pubconf.signingroot, "opal.pem") |
18 | 105 | self.opal_x509 = os.path.join(pubconf.signingroot, "opal.x509") | 109 | self.opal_x509 = os.path.join(pubconf.signingroot, "opal.x509") |
19 | 110 | self.sipl_pem = os.path.join(pubconf.signingroot, "sipl.pem") | ||
20 | 111 | self.sipl_x509 = os.path.join(pubconf.signingroot, "sipl.x509") | ||
21 | 112 | # Note: the signature tool allows a collection of keys and takes | ||
22 | 113 | # a directory name with all valid keys. Avoid mixing the | ||
23 | 114 | # other signing types' keys with the fit keys. | ||
24 | 115 | self.fit_key = os.path.join(pubconf.signingroot, "fit", "fit.key") | ||
25 | 116 | self.fit_cert = os.path.join(pubconf.signingroot, "fit", "fit.crt") | ||
26 | 106 | self.autokey = pubconf.signingautokey | 117 | self.autokey = pubconf.signingautokey |
27 | 107 | 118 | ||
28 | 108 | self.setComponents(tarfile_path) | 119 | self.setComponents(tarfile_path) |
29 | @@ -176,6 +187,10 @@ | |||
30 | 176 | yield (os.path.join(dirpath, filename), self.signKmod) | 187 | yield (os.path.join(dirpath, filename), self.signKmod) |
31 | 177 | elif filename.endswith(".opal"): | 188 | elif filename.endswith(".opal"): |
32 | 178 | yield (os.path.join(dirpath, filename), self.signOpal) | 189 | yield (os.path.join(dirpath, filename), self.signOpal) |
33 | 190 | elif filename.endswith(".sipl"): | ||
34 | 191 | yield (os.path.join(dirpath, filename), self.signSipl) | ||
35 | 192 | elif filename.endswith(".fit"): | ||
36 | 193 | yield (os.path.join(dirpath, filename), self.signFit) | ||
37 | 179 | 194 | ||
38 | 180 | def getKeys(self, which, generate, *keynames): | 195 | def getKeys(self, which, generate, *keynames): |
39 | 181 | """Validate and return the uefi key and cert for encryption.""" | 196 | """Validate and return the uefi key and cert for encryption.""" |
40 | @@ -207,29 +222,33 @@ | |||
41 | 207 | common_name = "PPA %s %s" % (owner, archive) | 222 | common_name = "PPA %s %s" % (owner, archive) |
42 | 208 | return common_name[0:64 - len(suffix)] + suffix | 223 | return common_name[0:64 - len(suffix)] + suffix |
43 | 209 | 224 | ||
47 | 210 | def generateUefiKeys(self): | 225 | def generateKeyCrtPair(self, key_type, key_filename, cert_filename): |
48 | 211 | """Generate new UEFI Keys for this archive.""" | 226 | """Generate new Key/Crt key pairs.""" |
49 | 212 | directory = os.path.dirname(self.uefi_key) | 227 | directory = os.path.dirname(key_filename) |
50 | 213 | if not os.path.exists(directory): | 228 | if not os.path.exists(directory): |
51 | 214 | os.makedirs(directory) | 229 | os.makedirs(directory) |
52 | 215 | 230 | ||
53 | 216 | common_name = self.generateKeyCommonName( | 231 | common_name = self.generateKeyCommonName( |
55 | 217 | self.archive.owner.name, self.archive.name) | 232 | self.archive.owner.name, self.archive.name, key_type) |
56 | 218 | subject = '/CN=' + common_name + '/' | 233 | subject = '/CN=' + common_name + '/' |
57 | 219 | 234 | ||
58 | 220 | old_mask = os.umask(0o077) | 235 | old_mask = os.umask(0o077) |
59 | 221 | try: | 236 | try: |
60 | 222 | new_key_cmd = [ | 237 | new_key_cmd = [ |
61 | 223 | 'openssl', 'req', '-new', '-x509', '-newkey', 'rsa:2048', | 238 | 'openssl', 'req', '-new', '-x509', '-newkey', 'rsa:2048', |
64 | 224 | '-subj', subject, '-keyout', self.uefi_key, | 239 | '-subj', subject, '-keyout', key_filename, |
65 | 225 | '-out', self.uefi_cert, '-days', '3650', '-nodes', '-sha256', | 240 | '-out', cert_filename, '-days', '3650', '-nodes', '-sha256', |
66 | 226 | ] | 241 | ] |
68 | 227 | self.callLog("UEFI keygen", new_key_cmd) | 242 | self.callLog(key_type + " keygen", new_key_cmd) |
69 | 228 | finally: | 243 | finally: |
70 | 229 | os.umask(old_mask) | 244 | os.umask(old_mask) |
71 | 230 | 245 | ||
74 | 231 | if os.path.exists(self.uefi_cert): | 246 | if os.path.exists(cert_filename): |
75 | 232 | os.chmod(self.uefi_cert, 0o644) | 247 | os.chmod(cert_filename, 0o644) |
76 | 248 | |||
77 | 249 | def generateUefiKeys(self): | ||
78 | 250 | """Generate new UEFI Keys for this archive.""" | ||
79 | 251 | self.generateKeyCrtPair("UEFI", self.uefi_key, self.uefi_cert) | ||
80 | 233 | 252 | ||
81 | 234 | def signUefi(self, image): | 253 | def signUefi(self, image): |
82 | 235 | """Attempt to sign an image.""" | 254 | """Attempt to sign an image.""" |
83 | @@ -242,7 +261,7 @@ | |||
84 | 242 | cmdl = ["sbsign", "--key", key, "--cert", cert, image] | 261 | cmdl = ["sbsign", "--key", key, "--cert", cert, image] |
85 | 243 | return self.callLog("UEFI signing", cmdl) | 262 | return self.callLog("UEFI signing", cmdl) |
86 | 244 | 263 | ||
88 | 245 | openssl_config_opal = textwrap.dedent(""" | 264 | openssl_config_base = textwrap.dedent(""" |
89 | 246 | [ req ] | 265 | [ req ] |
90 | 247 | default_bits = 4096 | 266 | default_bits = 4096 |
91 | 248 | distinguished_name = req_distinguished_name | 267 | distinguished_name = req_distinguished_name |
92 | @@ -260,37 +279,35 @@ | |||
93 | 260 | authorityKeyIdentifier=keyid | 279 | authorityKeyIdentifier=keyid |
94 | 261 | """) | 280 | """) |
95 | 262 | 281 | ||
97 | 263 | openssl_config_kmod = openssl_config_opal + textwrap.dedent(""" | 282 | openssl_config_opal = "# OPAL openssl config" + openssl_config_base |
98 | 283 | |||
99 | 284 | openssl_config_kmod = "# KMOD openssl config" + openssl_config_base + \ | ||
100 | 285 | textwrap.dedent(""" | ||
101 | 264 | # codeSigning: specifies that this key is used to sign code. | 286 | # codeSigning: specifies that this key is used to sign code. |
102 | 265 | # 1.3.6.1.4.1.2312.16.1.2: defines this key as used for | 287 | # 1.3.6.1.4.1.2312.16.1.2: defines this key as used for |
103 | 266 | # module signing only. See https://lkml.org/lkml/2015/8/26/741. | 288 | # module signing only. See https://lkml.org/lkml/2015/8/26/741. |
104 | 267 | extendedKeyUsage = codeSigning,1.3.6.1.4.1.2312.16.1.2 | 289 | extendedKeyUsage = codeSigning,1.3.6.1.4.1.2312.16.1.2 |
105 | 268 | """) | 290 | """) |
106 | 269 | 291 | ||
114 | 270 | def generateOpensslConfig(self, key_type, common_name): | 292 | openssl_config_sipl = "# SIPL openssl config" + openssl_config_base |
115 | 271 | if key_type == 'Kmod': | 293 | |
116 | 272 | genkey_tmpl = self.openssl_config_kmod | 294 | def generateOpensslConfig(self, key_type, genkey_tmpl): |
117 | 273 | elif key_type == 'Opal': | 295 | # Truncate name to 64 character maximum. |
118 | 274 | genkey_tmpl = self.openssl_config_opal | 296 | common_name = self.generateKeyCommonName( |
119 | 275 | else: | 297 | self.archive.owner.name, self.archive.name, key_type) |
113 | 276 | raise ValueError("unknown key_type " + key_type) | ||
120 | 277 | 298 | ||
121 | 278 | return genkey_tmpl.format(common_name=common_name) | 299 | return genkey_tmpl.format(common_name=common_name) |
122 | 279 | 300 | ||
124 | 280 | def generatePemX509Pair(self, key_type, pem_filename, x509_filename): | 301 | def generatePemX509Pair(self, key_type, genkey_text, pem_filename, |
125 | 302 | x509_filename): | ||
126 | 281 | """Generate new pem/x509 key pairs.""" | 303 | """Generate new pem/x509 key pairs.""" |
127 | 282 | directory = os.path.dirname(pem_filename) | 304 | directory = os.path.dirname(pem_filename) |
128 | 283 | if not os.path.exists(directory): | 305 | if not os.path.exists(directory): |
129 | 284 | os.makedirs(directory) | 306 | os.makedirs(directory) |
130 | 285 | 307 | ||
131 | 286 | # Truncate name to 64 character maximum. | ||
132 | 287 | common_name = self.generateKeyCommonName( | ||
133 | 288 | self.archive.owner.name, self.archive.name, key_type) | ||
134 | 289 | |||
135 | 290 | old_mask = os.umask(0o077) | 308 | old_mask = os.umask(0o077) |
136 | 291 | try: | 309 | try: |
137 | 292 | with tempfile.NamedTemporaryFile(suffix='.keygen') as tf: | 310 | with tempfile.NamedTemporaryFile(suffix='.keygen') as tf: |
138 | 293 | genkey_text = self.generateOpensslConfig(key_type, common_name) | ||
139 | 294 | print(genkey_text, file=tf) | 311 | print(genkey_text, file=tf) |
140 | 295 | 312 | ||
141 | 296 | # Close out the underlying file so we know it is complete. | 313 | # Close out the underlying file so we know it is complete. |
142 | @@ -318,7 +335,8 @@ | |||
143 | 318 | 335 | ||
144 | 319 | def generateKmodKeys(self): | 336 | def generateKmodKeys(self): |
145 | 320 | """Generate new Kernel Signing Keys for this archive.""" | 337 | """Generate new Kernel Signing Keys for this archive.""" |
147 | 321 | self.generatePemX509Pair("Kmod", self.kmod_pem, self.kmod_x509) | 338 | config = self.generateOpensslConfig("Kmod", self.openssl_config_kmod) |
148 | 339 | self.generatePemX509Pair("Kmod", config, self.kmod_pem, self.kmod_x509) | ||
149 | 322 | 340 | ||
150 | 323 | def signKmod(self, image): | 341 | def signKmod(self, image): |
151 | 324 | """Attempt to sign a kernel module.""" | 342 | """Attempt to sign a kernel module.""" |
152 | @@ -333,7 +351,8 @@ | |||
153 | 333 | 351 | ||
154 | 334 | def generateOpalKeys(self): | 352 | def generateOpalKeys(self): |
155 | 335 | """Generate new Opal Signing Keys for this archive.""" | 353 | """Generate new Opal Signing Keys for this archive.""" |
157 | 336 | self.generatePemX509Pair("Opal", self.opal_pem, self.opal_x509) | 354 | config = self.generateOpensslConfig("Opal", self.openssl_config_opal) |
158 | 355 | self.generatePemX509Pair("Opal", config, self.opal_pem, self.opal_x509) | ||
159 | 337 | 356 | ||
160 | 338 | def signOpal(self, image): | 357 | def signOpal(self, image): |
161 | 339 | """Attempt to sign a kernel image for Opal.""" | 358 | """Attempt to sign a kernel image for Opal.""" |
162 | @@ -346,6 +365,42 @@ | |||
163 | 346 | cmdl = ["kmodsign", "-D", "sha512", pem, cert, image, image + ".sig"] | 365 | cmdl = ["kmodsign", "-D", "sha512", pem, cert, image, image + ".sig"] |
164 | 347 | return self.callLog("Opal signing", cmdl) | 366 | return self.callLog("Opal signing", cmdl) |
165 | 348 | 367 | ||
166 | 368 | def generateSiplKeys(self): | ||
167 | 369 | """Generate new Sipl Signing Keys for this archive.""" | ||
168 | 370 | config = self.generateOpensslConfig("Sipl", self.openssl_config_sipl) | ||
169 | 371 | self.generatePemX509Pair("Sipl", config, self.sipl_pem, self.sipl_x509) | ||
170 | 372 | |||
171 | 373 | def signSipl(self, image): | ||
172 | 374 | """Attempt to sign a kernel image for Sipl.""" | ||
173 | 375 | remove_if_exists("%s.sig" % image) | ||
174 | 376 | (pem, cert) = self.getKeys('Sipl Kernel', self.generateSiplKeys, | ||
175 | 377 | self.sipl_pem, self.sipl_x509) | ||
176 | 378 | if not pem or not cert: | ||
177 | 379 | return | ||
178 | 380 | self.publishPublicKey(cert) | ||
179 | 381 | cmdl = ["kmodsign", "-D", "sha512", pem, cert, image, image + ".sig"] | ||
180 | 382 | return self.callLog("Sipl signing", cmdl) | ||
181 | 383 | |||
182 | 384 | def generateFitKeys(self): | ||
183 | 385 | """Generate new Fit Keys for this archive.""" | ||
184 | 386 | self.generateKeyCrtPair("Fit", self.fit_key, self.fit_cert) | ||
185 | 387 | |||
186 | 388 | def signFit(self, image): | ||
187 | 389 | """Attempt to sign an image.""" | ||
188 | 390 | image_signed = "%s.signed" % image | ||
189 | 391 | remove_if_exists(image_signed) | ||
190 | 392 | (key, cert) = self.getKeys('Fit', self.generateFitKeys, | ||
191 | 393 | self.fit_key, self.fit_cert) | ||
192 | 394 | if not key or not cert: | ||
193 | 395 | return | ||
194 | 396 | self.publishPublicKey(cert) | ||
195 | 397 | # Make a copy of the image as mkimage signs in place and in | ||
196 | 398 | # signed-only mode we will remove the original file. | ||
197 | 399 | shutil.copy(image, image_signed) | ||
198 | 400 | cmdl = ["mkimage", "-F", "-k", os.path.dirname(key), "-r", | ||
199 | 401 | image_signed] | ||
200 | 402 | return self.callLog("Fit signing", cmdl) | ||
201 | 403 | |||
202 | 349 | def convertToTarball(self): | 404 | def convertToTarball(self): |
203 | 350 | """Convert unpacked output to signing tarball.""" | 405 | """Convert unpacked output to signing tarball.""" |
204 | 351 | tarfilename = os.path.join(self.tmpdir, "signed.tar.gz") | 406 | tarfilename = os.path.join(self.tmpdir, "signed.tar.gz") |
205 | 352 | 407 | ||
206 | === modified file 'lib/lp/archivepublisher/tests/test_signing.py' | |||
207 | --- lib/lp/archivepublisher/tests/test_signing.py 2019-05-24 11:10:38 +0000 | |||
208 | +++ lib/lp/archivepublisher/tests/test_signing.py 2019-06-03 14:59:55 +0000 | |||
209 | @@ -85,12 +85,17 @@ | |||
210 | 85 | self.callers = { | 85 | self.callers = { |
211 | 86 | "UEFI signing": 0, | 86 | "UEFI signing": 0, |
212 | 87 | "UEFI keygen": 0, | 87 | "UEFI keygen": 0, |
213 | 88 | "Fit signing": 0, | ||
214 | 89 | "Fit keygen": 0, | ||
215 | 88 | "Kmod signing": 0, | 90 | "Kmod signing": 0, |
216 | 89 | "Kmod keygen key": 0, | 91 | "Kmod keygen key": 0, |
217 | 90 | "Kmod keygen cert": 0, | 92 | "Kmod keygen cert": 0, |
218 | 91 | "Opal signing": 0, | 93 | "Opal signing": 0, |
219 | 92 | "Opal keygen key": 0, | 94 | "Opal keygen key": 0, |
220 | 93 | "Opal keygen cert": 0, | 95 | "Opal keygen cert": 0, |
221 | 96 | "Sipl signing": 0, | ||
222 | 97 | "Sipl keygen key": 0, | ||
223 | 98 | "Sipl keygen cert": 0, | ||
224 | 94 | } | 99 | } |
225 | 95 | 100 | ||
226 | 96 | def __call__(self, *args, **kwargs): | 101 | def __call__(self, *args, **kwargs): |
227 | @@ -108,6 +113,15 @@ | |||
228 | 108 | write_file(self.upload.uefi_key, b"") | 113 | write_file(self.upload.uefi_key, b"") |
229 | 109 | write_file(self.upload.uefi_cert, b"") | 114 | write_file(self.upload.uefi_cert, b"") |
230 | 110 | 115 | ||
231 | 116 | elif description == "Fit signing": | ||
232 | 117 | filename = cmdl[-1] | ||
233 | 118 | if filename.endswith(".fit"): | ||
234 | 119 | write_file(filename + ".signed", b"") | ||
235 | 120 | |||
236 | 121 | elif description == "Fit keygen": | ||
237 | 122 | write_file(self.upload.fit_key, b"") | ||
238 | 123 | write_file(self.upload.fit_cert, b"") | ||
239 | 124 | |||
240 | 111 | elif description == "Kmod signing": | 125 | elif description == "Kmod signing": |
241 | 112 | filename = cmdl[-1] | 126 | filename = cmdl[-1] |
242 | 113 | if filename.endswith(".ko.sig"): | 127 | if filename.endswith(".ko.sig"): |
243 | @@ -130,9 +144,20 @@ | |||
244 | 130 | elif description == "Opal keygen key": | 144 | elif description == "Opal keygen key": |
245 | 131 | write_file(self.upload.opal_pem, b"") | 145 | write_file(self.upload.opal_pem, b"") |
246 | 132 | 146 | ||
247 | 147 | elif description == "Sipl signing": | ||
248 | 148 | filename = cmdl[-1] | ||
249 | 149 | if filename.endswith(".sipl.sig"): | ||
250 | 150 | write_file(filename, b"") | ||
251 | 151 | |||
252 | 152 | elif description == "Sipl keygen cert": | ||
253 | 153 | write_file(self.upload.sipl_x509, b"") | ||
254 | 154 | |||
255 | 155 | elif description == "Sipl keygen key": | ||
256 | 156 | write_file(self.upload.sipl_pem, b"") | ||
257 | 157 | |||
258 | 133 | else: | 158 | else: |
261 | 134 | raise AssertionError("unknown command executed cmd=(%s)" % | 159 | raise AssertionError("unknown command executed description=(%s) " |
262 | 135 | " ".join(cmdl)) | 160 | "cmd=(%s)" % (description, " ".join(cmdl))) |
263 | 136 | 161 | ||
264 | 137 | return 0 | 162 | return 0 |
265 | 138 | 163 | ||
266 | @@ -177,7 +202,7 @@ | |||
267 | 177 | purpose=ArchivePurpose.PPA) | 202 | purpose=ArchivePurpose.PPA) |
268 | 178 | self.signing_dir = os.path.join( | 203 | self.signing_dir = os.path.join( |
269 | 179 | self.temp_dir, "signing", "signing-owner", "testing") | 204 | self.temp_dir, "signing", "signing-owner", "testing") |
271 | 180 | self.testcase_cn = '/CN=PPA signing-owner testing/' | 205 | self.testcase_cn = 'PPA signing-owner testing' |
272 | 181 | pubconf = getPubConfig(self.archive) | 206 | pubconf = getPubConfig(self.archive) |
273 | 182 | if not os.path.exists(pubconf.temproot): | 207 | if not os.path.exists(pubconf.temproot): |
274 | 183 | os.makedirs(pubconf.temproot) | 208 | os.makedirs(pubconf.temproot) |
275 | @@ -197,6 +222,15 @@ | |||
276 | 197 | write_file(self.key, b"") | 222 | write_file(self.key, b"") |
277 | 198 | write_file(self.cert, b"") | 223 | write_file(self.cert, b"") |
278 | 199 | 224 | ||
279 | 225 | def setUpFitKeys(self, create=True): | ||
280 | 226 | # We expect and need the fit keys to be in their own | ||
281 | 227 | # directory as part of key protection for mkimage. | ||
282 | 228 | self.fit_key = os.path.join(self.signing_dir, "fit", "fit.key") | ||
283 | 229 | self.fit_cert = os.path.join(self.signing_dir, "fit", "fit.crt") | ||
284 | 230 | if create: | ||
285 | 231 | write_file(self.fit_key, b"") | ||
286 | 232 | write_file(self.fit_cert, b"") | ||
287 | 233 | |||
288 | 200 | def setUpKmodKeys(self, create=True): | 234 | def setUpKmodKeys(self, create=True): |
289 | 201 | self.kmod_pem = os.path.join(self.signing_dir, "kmod.pem") | 235 | self.kmod_pem = os.path.join(self.signing_dir, "kmod.pem") |
290 | 202 | self.kmod_x509 = os.path.join(self.signing_dir, "kmod.x509") | 236 | self.kmod_x509 = os.path.join(self.signing_dir, "kmod.x509") |
291 | @@ -211,6 +245,13 @@ | |||
292 | 211 | write_file(self.opal_pem, b"") | 245 | write_file(self.opal_pem, b"") |
293 | 212 | write_file(self.opal_x509, b"") | 246 | write_file(self.opal_x509, b"") |
294 | 213 | 247 | ||
295 | 248 | def setUpSiplKeys(self, create=True): | ||
296 | 249 | self.sipl_pem = os.path.join(self.signing_dir, "sipl.pem") | ||
297 | 250 | self.sipl_x509 = os.path.join(self.signing_dir, "sipl.x509") | ||
298 | 251 | if create: | ||
299 | 252 | write_file(self.sipl_pem, b"") | ||
300 | 253 | write_file(self.sipl_x509, b"") | ||
301 | 254 | |||
302 | 214 | def openArchive(self, loader_type, version, arch): | 255 | def openArchive(self, loader_type, version, arch): |
303 | 215 | self.path = os.path.join( | 256 | self.path = os.path.join( |
304 | 216 | self.temp_dir, "%s_%s_%s.tar.gz" % (loader_type, version, arch)) | 257 | self.temp_dir, "%s_%s_%s.tar.gz" % (loader_type, version, arch)) |
305 | @@ -234,6 +275,7 @@ | |||
306 | 234 | upload = SigningUpload() | 275 | upload = SigningUpload() |
307 | 235 | # Under no circumstances is it safe to execute actual commands. | 276 | # Under no circumstances is it safe to execute actual commands. |
308 | 236 | self.fake_call = FakeMethod(result=0) | 277 | self.fake_call = FakeMethod(result=0) |
309 | 278 | self.fake_copyfile = FakeMethod(result=0) | ||
310 | 237 | upload.callLog = FakeMethodCallLog(upload=upload) | 279 | upload.callLog = FakeMethodCallLog(upload=upload) |
311 | 238 | self.useFixture(MonkeyPatch("subprocess.call", self.fake_call)) | 280 | self.useFixture(MonkeyPatch("subprocess.call", self.fake_call)) |
312 | 239 | upload.process(self.archive, self.path, self.suite) | 281 | upload.process(self.archive, self.path, self.suite) |
313 | @@ -247,6 +289,8 @@ | |||
314 | 247 | upload.signUefi = FakeMethod() | 289 | upload.signUefi = FakeMethod() |
315 | 248 | upload.signKmod = FakeMethod() | 290 | upload.signKmod = FakeMethod() |
316 | 249 | upload.signOpal = FakeMethod() | 291 | upload.signOpal = FakeMethod() |
317 | 292 | upload.signSipl = FakeMethod() | ||
318 | 293 | upload.signFit = FakeMethod() | ||
319 | 250 | # Under no circumstances is it safe to execute actual commands. | 294 | # Under no circumstances is it safe to execute actual commands. |
320 | 251 | fake_call = FakeMethod(result=0) | 295 | fake_call = FakeMethod(result=0) |
321 | 252 | self.useFixture(MonkeyPatch("subprocess.call", fake_call)) | 296 | self.useFixture(MonkeyPatch("subprocess.call", fake_call)) |
322 | @@ -267,6 +311,8 @@ | |||
323 | 267 | self.tarfile.add_file("1.0/empty.efi", b"") | 311 | self.tarfile.add_file("1.0/empty.efi", b"") |
324 | 268 | self.tarfile.add_file("1.0/empty.ko", b"") | 312 | self.tarfile.add_file("1.0/empty.ko", b"") |
325 | 269 | self.tarfile.add_file("1.0/empty.opal", b"") | 313 | self.tarfile.add_file("1.0/empty.opal", b"") |
326 | 314 | self.tarfile.add_file("1.0/empty.sipl", b"") | ||
327 | 315 | self.tarfile.add_file("1.0/empty.fit", b"") | ||
328 | 270 | upload = self.process_emulate() | 316 | upload = self.process_emulate() |
329 | 271 | self.assertContentEqual([], upload.callLog.caller_list()) | 317 | self.assertContentEqual([], upload.callLog.caller_list()) |
330 | 272 | 318 | ||
331 | @@ -277,6 +323,8 @@ | |||
332 | 277 | self.tarfile.add_file("1.0/empty.efi", b"") | 323 | self.tarfile.add_file("1.0/empty.efi", b"") |
333 | 278 | self.tarfile.add_file("1.0/empty.ko", b"") | 324 | self.tarfile.add_file("1.0/empty.ko", b"") |
334 | 279 | self.tarfile.add_file("1.0/empty.opal", b"") | 325 | self.tarfile.add_file("1.0/empty.opal", b"") |
335 | 326 | self.tarfile.add_file("1.0/empty.sipl", b"") | ||
336 | 327 | self.tarfile.add_file("1.0/empty.fit", b"") | ||
337 | 280 | upload = self.process_emulate() | 328 | upload = self.process_emulate() |
338 | 281 | self.assertContentEqual([], upload.callLog.caller_list()) | 329 | self.assertContentEqual([], upload.callLog.caller_list()) |
339 | 282 | 330 | ||
340 | @@ -289,6 +337,8 @@ | |||
341 | 289 | self.tarfile.add_file("1.0/empty.efi", b"") | 337 | self.tarfile.add_file("1.0/empty.efi", b"") |
342 | 290 | self.tarfile.add_file("1.0/empty.ko", b"") | 338 | self.tarfile.add_file("1.0/empty.ko", b"") |
343 | 291 | self.tarfile.add_file("1.0/empty.opal", b"") | 339 | self.tarfile.add_file("1.0/empty.opal", b"") |
344 | 340 | self.tarfile.add_file("1.0/empty.sipl", b"") | ||
345 | 341 | self.tarfile.add_file("1.0/empty.fit", b"") | ||
346 | 292 | upload = self.process_emulate() | 342 | upload = self.process_emulate() |
347 | 293 | expected_callers = [ | 343 | expected_callers = [ |
348 | 294 | ('UEFI signing', 1), | 344 | ('UEFI signing', 1), |
349 | @@ -304,6 +354,8 @@ | |||
350 | 304 | self.tarfile.add_file("1.0/empty.efi", b"") | 354 | self.tarfile.add_file("1.0/empty.efi", b"") |
351 | 305 | self.tarfile.add_file("1.0/empty.ko", b"") | 355 | self.tarfile.add_file("1.0/empty.ko", b"") |
352 | 306 | self.tarfile.add_file("1.0/empty.opal", b"") | 356 | self.tarfile.add_file("1.0/empty.opal", b"") |
353 | 357 | self.tarfile.add_file("1.0/empty.sipl", b"") | ||
354 | 358 | self.tarfile.add_file("1.0/empty.fit", b"") | ||
355 | 307 | upload = self.process_emulate() | 359 | upload = self.process_emulate() |
356 | 308 | expected_callers = [ | 360 | expected_callers = [ |
357 | 309 | ('UEFI keygen', 1), | 361 | ('UEFI keygen', 1), |
358 | @@ -311,9 +363,14 @@ | |||
359 | 311 | ('Kmod keygen cert', 1), | 363 | ('Kmod keygen cert', 1), |
360 | 312 | ('Opal keygen key', 1), | 364 | ('Opal keygen key', 1), |
361 | 313 | ('Opal keygen cert', 1), | 365 | ('Opal keygen cert', 1), |
362 | 366 | ('Sipl keygen key', 1), | ||
363 | 367 | ('Sipl keygen cert', 1), | ||
364 | 368 | ('Fit keygen', 1), | ||
365 | 314 | ('UEFI signing', 1), | 369 | ('UEFI signing', 1), |
366 | 315 | ('Kmod signing', 1), | 370 | ('Kmod signing', 1), |
367 | 316 | ('Opal signing', 1), | 371 | ('Opal signing', 1), |
368 | 372 | ('Sipl signing', 1), | ||
369 | 373 | ('Fit signing', 1), | ||
370 | 317 | ] | 374 | ] |
371 | 318 | self.assertContentEqual(expected_callers, upload.callLog.caller_list()) | 375 | self.assertContentEqual(expected_callers, upload.callLog.caller_list()) |
372 | 319 | 376 | ||
373 | @@ -387,16 +444,22 @@ | |||
374 | 387 | self.setUpUefiKeys() | 444 | self.setUpUefiKeys() |
375 | 388 | self.setUpKmodKeys() | 445 | self.setUpKmodKeys() |
376 | 389 | self.setUpOpalKeys() | 446 | self.setUpOpalKeys() |
377 | 447 | self.setUpSiplKeys() | ||
378 | 448 | self.setUpFitKeys() | ||
379 | 390 | self.openArchive("test", "1.0", "amd64") | 449 | self.openArchive("test", "1.0", "amd64") |
380 | 391 | self.tarfile.add_file("1.0/empty.efi", b"") | 450 | self.tarfile.add_file("1.0/empty.efi", b"") |
381 | 392 | self.tarfile.add_file("1.0/empty.ko", b"") | 451 | self.tarfile.add_file("1.0/empty.ko", b"") |
382 | 393 | self.tarfile.add_file("1.0/empty.opal", b"") | 452 | self.tarfile.add_file("1.0/empty.opal", b"") |
383 | 453 | self.tarfile.add_file("1.0/empty.sipl", b"") | ||
384 | 454 | self.tarfile.add_file("1.0/empty.fit", b"") | ||
385 | 394 | self.process_emulate() | 455 | self.process_emulate() |
386 | 395 | self.assertThat(self.getSignedPath("test", "amd64"), SignedMatches([ | 456 | self.assertThat(self.getSignedPath("test", "amd64"), SignedMatches([ |
387 | 396 | "1.0/SHA256SUMS", | 457 | "1.0/SHA256SUMS", |
388 | 397 | "1.0/empty.efi", "1.0/empty.efi.signed", "1.0/control/uefi.crt", | 458 | "1.0/empty.efi", "1.0/empty.efi.signed", "1.0/control/uefi.crt", |
389 | 398 | "1.0/empty.ko", "1.0/empty.ko.sig", "1.0/control/kmod.x509", | 459 | "1.0/empty.ko", "1.0/empty.ko.sig", "1.0/control/kmod.x509", |
390 | 399 | "1.0/empty.opal", "1.0/empty.opal.sig", "1.0/control/opal.x509", | 460 | "1.0/empty.opal", "1.0/empty.opal.sig", "1.0/control/opal.x509", |
391 | 461 | "1.0/empty.sipl", "1.0/empty.sipl.sig", "1.0/control/sipl.x509", | ||
392 | 462 | "1.0/empty.fit", "1.0/empty.fit.signed", "1.0/control/fit.crt", | ||
393 | 400 | ])) | 463 | ])) |
394 | 401 | 464 | ||
395 | 402 | def test_options_tarball(self): | 465 | def test_options_tarball(self): |
396 | @@ -405,11 +468,15 @@ | |||
397 | 405 | self.setUpUefiKeys() | 468 | self.setUpUefiKeys() |
398 | 406 | self.setUpKmodKeys() | 469 | self.setUpKmodKeys() |
399 | 407 | self.setUpOpalKeys() | 470 | self.setUpOpalKeys() |
400 | 471 | self.setUpSiplKeys() | ||
401 | 472 | self.setUpFitKeys() | ||
402 | 408 | self.openArchive("test", "1.0", "amd64") | 473 | self.openArchive("test", "1.0", "amd64") |
403 | 409 | self.tarfile.add_file("1.0/control/options", b"tarball") | 474 | self.tarfile.add_file("1.0/control/options", b"tarball") |
404 | 410 | self.tarfile.add_file("1.0/empty.efi", b"") | 475 | self.tarfile.add_file("1.0/empty.efi", b"") |
405 | 411 | self.tarfile.add_file("1.0/empty.ko", b"") | 476 | self.tarfile.add_file("1.0/empty.ko", b"") |
406 | 412 | self.tarfile.add_file("1.0/empty.opal", b"") | 477 | self.tarfile.add_file("1.0/empty.opal", b"") |
407 | 478 | self.tarfile.add_file("1.0/empty.sipl", b"") | ||
408 | 479 | self.tarfile.add_file("1.0/empty.fit", b"") | ||
409 | 413 | self.process_emulate() | 480 | self.process_emulate() |
410 | 414 | self.assertThat(self.getSignedPath("test", "amd64"), SignedMatches([ | 481 | self.assertThat(self.getSignedPath("test", "amd64"), SignedMatches([ |
411 | 415 | "1.0/SHA256SUMS", | 482 | "1.0/SHA256SUMS", |
412 | @@ -425,6 +492,10 @@ | |||
413 | 425 | '1.0/empty.ko', '1.0/empty.ko.sig', '1.0/control/kmod.x509', | 492 | '1.0/empty.ko', '1.0/empty.ko.sig', '1.0/control/kmod.x509', |
414 | 426 | '1.0/empty.opal', '1.0/empty.opal.sig', | 493 | '1.0/empty.opal', '1.0/empty.opal.sig', |
415 | 427 | '1.0/control/opal.x509', | 494 | '1.0/control/opal.x509', |
416 | 495 | '1.0/empty.sipl', '1.0/empty.sipl.sig', | ||
417 | 496 | '1.0/control/sipl.x509', | ||
418 | 497 | '1.0/empty.fit', '1.0/empty.fit.signed', | ||
419 | 498 | '1.0/control/fit.crt', | ||
420 | 428 | ], tarball.getnames()) | 499 | ], tarball.getnames()) |
421 | 429 | 500 | ||
422 | 430 | def test_options_signed_only(self): | 501 | def test_options_signed_only(self): |
423 | @@ -433,17 +504,23 @@ | |||
424 | 433 | self.setUpUefiKeys() | 504 | self.setUpUefiKeys() |
425 | 434 | self.setUpKmodKeys() | 505 | self.setUpKmodKeys() |
426 | 435 | self.setUpOpalKeys() | 506 | self.setUpOpalKeys() |
427 | 507 | self.setUpSiplKeys() | ||
428 | 508 | self.setUpFitKeys() | ||
429 | 436 | self.openArchive("test", "1.0", "amd64") | 509 | self.openArchive("test", "1.0", "amd64") |
430 | 437 | self.tarfile.add_file("1.0/control/options", b"signed-only") | 510 | self.tarfile.add_file("1.0/control/options", b"signed-only") |
431 | 438 | self.tarfile.add_file("1.0/empty.efi", b"") | 511 | self.tarfile.add_file("1.0/empty.efi", b"") |
432 | 439 | self.tarfile.add_file("1.0/empty.ko", b"") | 512 | self.tarfile.add_file("1.0/empty.ko", b"") |
433 | 440 | self.tarfile.add_file("1.0/empty.opal", b"") | 513 | self.tarfile.add_file("1.0/empty.opal", b"") |
434 | 514 | self.tarfile.add_file("1.0/empty.sipl", b"") | ||
435 | 515 | self.tarfile.add_file("1.0/empty.fit", b"") | ||
436 | 441 | self.process_emulate() | 516 | self.process_emulate() |
437 | 442 | self.assertThat(self.getSignedPath("test", "amd64"), SignedMatches([ | 517 | self.assertThat(self.getSignedPath("test", "amd64"), SignedMatches([ |
438 | 443 | "1.0/SHA256SUMS", "1.0/control/options", | 518 | "1.0/SHA256SUMS", "1.0/control/options", |
439 | 444 | "1.0/empty.efi.signed", "1.0/control/uefi.crt", | 519 | "1.0/empty.efi.signed", "1.0/control/uefi.crt", |
440 | 445 | "1.0/empty.ko.sig", "1.0/control/kmod.x509", | 520 | "1.0/empty.ko.sig", "1.0/control/kmod.x509", |
441 | 446 | "1.0/empty.opal.sig", "1.0/control/opal.x509", | 521 | "1.0/empty.opal.sig", "1.0/control/opal.x509", |
442 | 522 | "1.0/empty.sipl.sig", "1.0/control/sipl.x509", | ||
443 | 523 | "1.0/empty.fit.signed", "1.0/control/fit.crt", | ||
444 | 447 | ])) | 524 | ])) |
445 | 448 | 525 | ||
446 | 449 | def test_options_tarball_signed_only(self): | 526 | def test_options_tarball_signed_only(self): |
447 | @@ -453,11 +530,15 @@ | |||
448 | 453 | self.setUpUefiKeys() | 530 | self.setUpUefiKeys() |
449 | 454 | self.setUpKmodKeys() | 531 | self.setUpKmodKeys() |
450 | 455 | self.setUpOpalKeys() | 532 | self.setUpOpalKeys() |
451 | 533 | self.setUpSiplKeys() | ||
452 | 534 | self.setUpFitKeys() | ||
453 | 456 | self.openArchive("test", "1.0", "amd64") | 535 | self.openArchive("test", "1.0", "amd64") |
454 | 457 | self.tarfile.add_file("1.0/control/options", b"tarball\nsigned-only") | 536 | self.tarfile.add_file("1.0/control/options", b"tarball\nsigned-only") |
455 | 458 | self.tarfile.add_file("1.0/empty.efi", b"") | 537 | self.tarfile.add_file("1.0/empty.efi", b"") |
456 | 459 | self.tarfile.add_file("1.0/empty.ko", b"") | 538 | self.tarfile.add_file("1.0/empty.ko", b"") |
457 | 460 | self.tarfile.add_file("1.0/empty.opal", b"") | 539 | self.tarfile.add_file("1.0/empty.opal", b"") |
458 | 540 | self.tarfile.add_file("1.0/empty.sipl", b"") | ||
459 | 541 | self.tarfile.add_file("1.0/empty.fit", b"") | ||
460 | 461 | self.process_emulate() | 542 | self.process_emulate() |
461 | 462 | self.assertThat(self.getSignedPath("test", "amd64"), SignedMatches([ | 543 | self.assertThat(self.getSignedPath("test", "amd64"), SignedMatches([ |
462 | 463 | "1.0/SHA256SUMS", | 544 | "1.0/SHA256SUMS", |
463 | @@ -471,12 +552,18 @@ | |||
464 | 471 | '1.0/empty.efi.signed', '1.0/control/uefi.crt', | 552 | '1.0/empty.efi.signed', '1.0/control/uefi.crt', |
465 | 472 | '1.0/empty.ko.sig', '1.0/control/kmod.x509', | 553 | '1.0/empty.ko.sig', '1.0/control/kmod.x509', |
466 | 473 | '1.0/empty.opal.sig', '1.0/control/opal.x509', | 554 | '1.0/empty.opal.sig', '1.0/control/opal.x509', |
467 | 555 | '1.0/empty.sipl.sig', '1.0/control/sipl.x509', | ||
468 | 556 | '1.0/empty.fit.signed', '1.0/control/fit.crt', | ||
469 | 474 | ], tarball.getnames()) | 557 | ], tarball.getnames()) |
470 | 475 | 558 | ||
471 | 476 | def test_no_signed_files(self): | 559 | def test_no_signed_files(self): |
472 | 477 | # Tarballs containing no *.efi files are extracted without complaint. | 560 | # Tarballs containing no *.efi files are extracted without complaint. |
473 | 478 | # Nothing is signed. | 561 | # Nothing is signed. |
474 | 479 | self.setUpUefiKeys() | 562 | self.setUpUefiKeys() |
475 | 563 | self.setUpKmodKeys() | ||
476 | 564 | self.setUpOpalKeys() | ||
477 | 565 | self.setUpSiplKeys() | ||
478 | 566 | self.setUpFitKeys() | ||
479 | 480 | self.openArchive("empty", "1.0", "amd64") | 567 | self.openArchive("empty", "1.0", "amd64") |
480 | 481 | self.tarfile.add_file("1.0/hello", b"world") | 568 | self.tarfile.add_file("1.0/hello", b"world") |
481 | 482 | upload = self.process() | 569 | upload = self.process() |
482 | @@ -484,6 +571,9 @@ | |||
483 | 484 | self.getSignedPath("empty", "amd64"), "1.0", "hello"))) | 571 | self.getSignedPath("empty", "amd64"), "1.0", "hello"))) |
484 | 485 | self.assertEqual(0, upload.signUefi.call_count) | 572 | self.assertEqual(0, upload.signUefi.call_count) |
485 | 486 | self.assertEqual(0, upload.signKmod.call_count) | 573 | self.assertEqual(0, upload.signKmod.call_count) |
486 | 574 | self.assertEqual(0, upload.signOpal.call_count) | ||
487 | 575 | self.assertEqual(0, upload.signSipl.call_count) | ||
488 | 576 | self.assertEqual(0, upload.signFit.call_count) | ||
489 | 487 | 577 | ||
490 | 488 | def test_already_exists(self): | 578 | def test_already_exists(self): |
491 | 489 | # If the target directory already exists, processing fails. | 579 | # If the target directory already exists, processing fails. |
492 | @@ -551,7 +641,71 @@ | |||
493 | 551 | args = fake_call.calls[0][0][0] | 641 | args = fake_call.calls[0][0][0] |
494 | 552 | expected_cmd = [ | 642 | expected_cmd = [ |
495 | 553 | 'openssl', 'req', '-new', '-x509', '-newkey', 'rsa:2048', | 643 | 'openssl', 'req', '-new', '-x509', '-newkey', 'rsa:2048', |
497 | 554 | '-subj', self.testcase_cn, '-keyout', self.key, '-out', self.cert, | 644 | '-subj', '/CN=' + self.testcase_cn + ' UEFI/', |
498 | 645 | '-keyout', self.key, '-out', self.cert, | ||
499 | 646 | '-days', '3650', '-nodes', '-sha256', | ||
500 | 647 | ] | ||
501 | 648 | self.assertEqual(expected_cmd, args) | ||
502 | 649 | |||
503 | 650 | def test_correct_fit_signing_command_executed(self): | ||
504 | 651 | # Check that calling signFit() will generate the expected command | ||
505 | 652 | # when appropriate keys are present. | ||
506 | 653 | self.setUpFitKeys() | ||
507 | 654 | fake_call = FakeMethod(result=0) | ||
508 | 655 | self.useFixture(MonkeyPatch("subprocess.call", fake_call)) | ||
509 | 656 | fake_copy = FakeMethod(result=0) | ||
510 | 657 | self.useFixture(MonkeyPatch("shutil.copy", fake_copy)) | ||
511 | 658 | upload = SigningUpload() | ||
512 | 659 | upload.generateFitKeys = FakeMethod() | ||
513 | 660 | upload.setTargetDirectory( | ||
514 | 661 | self.archive, "test_1.0_amd64.tar.gz", "distroseries") | ||
515 | 662 | upload.signFit('t.fit') | ||
516 | 663 | # Confirm the copy was performed. | ||
517 | 664 | self.assertEqual(1, fake_copy.call_count) | ||
518 | 665 | args = fake_copy.calls[0][0] | ||
519 | 666 | expected_copy = ('t.fit', 't.fit.signed') | ||
520 | 667 | self.assertEqual(expected_copy, args) | ||
521 | 668 | # Assert command form. | ||
522 | 669 | args = fake_call.calls[0][0][0] | ||
523 | 670 | expected_cmd = [ | ||
524 | 671 | 'mkimage', '-F', '-k', os.path.dirname(self.fit_key), '-r', | ||
525 | 672 | 't.fit.signed', | ||
526 | 673 | ] | ||
527 | 674 | self.assertEqual(expected_cmd, args) | ||
528 | 675 | self.assertEqual(0, upload.generateFitKeys.call_count) | ||
529 | 676 | |||
530 | 677 | def test_correct_fit_signing_command_executed_no_keys(self): | ||
531 | 678 | # Check that calling signFit() will generate no commands when | ||
532 | 679 | # no keys are present. | ||
533 | 680 | self.setUpFitKeys(create=False) | ||
534 | 681 | fake_call = FakeMethod(result=0) | ||
535 | 682 | self.useFixture(MonkeyPatch("subprocess.call", fake_call)) | ||
536 | 683 | upload = SigningUpload() | ||
537 | 684 | upload.generateFitKeys = FakeMethod() | ||
538 | 685 | upload.setTargetDirectory( | ||
539 | 686 | self.archive, "test_1.0_amd64.tar.gz", "distroseries") | ||
540 | 687 | upload.signUefi('t.fit') | ||
541 | 688 | self.assertEqual(0, fake_call.call_count) | ||
542 | 689 | self.assertEqual(0, upload.generateFitKeys.call_count) | ||
543 | 690 | |||
544 | 691 | def test_correct_fit_keygen_command_executed(self): | ||
545 | 692 | # Check that calling generateFitKeys() will generate the | ||
546 | 693 | # expected command. | ||
547 | 694 | self.setUpPPA() | ||
548 | 695 | self.setUpFitKeys(create=False) | ||
549 | 696 | fake_call = FakeMethod(result=0) | ||
550 | 697 | self.useFixture(MonkeyPatch("subprocess.call", fake_call)) | ||
551 | 698 | upload = SigningUpload() | ||
552 | 699 | upload.setTargetDirectory( | ||
553 | 700 | self.archive, "test_1.0_amd64.tar.gz", "distroseries") | ||
554 | 701 | upload.generateFitKeys() | ||
555 | 702 | self.assertEqual(1, fake_call.call_count) | ||
556 | 703 | # Assert the actual command matches. | ||
557 | 704 | args = fake_call.calls[0][0][0] | ||
558 | 705 | expected_cmd = [ | ||
559 | 706 | 'openssl', 'req', '-new', '-x509', '-newkey', 'rsa:2048', | ||
560 | 707 | '-subj', '/CN=' + self.testcase_cn + ' Fit/', | ||
561 | 708 | '-keyout', self.fit_key, '-out', self.fit_cert, | ||
562 | 555 | '-days', '3650', '-nodes', '-sha256', | 709 | '-days', '3650', '-nodes', '-sha256', |
563 | 556 | ] | 710 | ] |
564 | 557 | self.assertEqual(expected_cmd, args) | 711 | self.assertEqual(expected_cmd, args) |
565 | @@ -559,15 +713,20 @@ | |||
566 | 559 | def test_correct_kmod_openssl_config(self): | 713 | def test_correct_kmod_openssl_config(self): |
567 | 560 | # Check that calling generateOpensslConfig() will return an appropriate | 714 | # Check that calling generateOpensslConfig() will return an appropriate |
568 | 561 | # openssl configuration. | 715 | # openssl configuration. |
569 | 716 | self.setUpPPA() | ||
570 | 562 | upload = SigningUpload() | 717 | upload = SigningUpload() |
572 | 563 | text = upload.generateOpensslConfig('Kmod', 'something-unique') | 718 | upload.setTargetDirectory( |
573 | 719 | self.archive, "test_1.0_amd64.tar.gz", "distroseries") | ||
574 | 720 | text = upload.generateOpensslConfig('Kmod', upload.openssl_config_kmod) | ||
575 | 564 | 721 | ||
577 | 565 | cn_re = re.compile(r'\bCN\s*=\s*something-unique\b') | 722 | id_re = re.compile(r'^# KMOD openssl config\b') |
578 | 723 | cn_re = re.compile(r'\bCN\s*=\s*' + self.testcase_cn + '\s+Kmod') | ||
579 | 566 | eku_re = re.compile( | 724 | eku_re = re.compile( |
580 | 567 | r'\bextendedKeyUsage\s*=\s*' | 725 | r'\bextendedKeyUsage\s*=\s*' |
581 | 568 | r'codeSigning,1.3.6.1.4.1.2312.16.1.2\s*\b') | 726 | r'codeSigning,1.3.6.1.4.1.2312.16.1.2\s*\b') |
582 | 569 | 727 | ||
583 | 570 | self.assertIn('[ req ]', text) | 728 | self.assertIn('[ req ]', text) |
584 | 729 | self.assertIsNotNone(id_re.search(text)) | ||
585 | 571 | self.assertIsNotNone(cn_re.search(text)) | 730 | self.assertIsNotNone(cn_re.search(text)) |
586 | 572 | self.assertIsNotNone(eku_re.search(text)) | 731 | self.assertIsNotNone(eku_re.search(text)) |
587 | 573 | 732 | ||
588 | @@ -640,12 +799,17 @@ | |||
589 | 640 | def test_correct_opal_openssl_config(self): | 799 | def test_correct_opal_openssl_config(self): |
590 | 641 | # Check that calling generateOpensslConfig() will return an appropriate | 800 | # Check that calling generateOpensslConfig() will return an appropriate |
591 | 642 | # openssl configuration. | 801 | # openssl configuration. |
592 | 802 | self.setUpPPA() | ||
593 | 643 | upload = SigningUpload() | 803 | upload = SigningUpload() |
595 | 644 | text = upload.generateOpensslConfig('Opal', 'something-unique') | 804 | upload.setTargetDirectory( |
596 | 805 | self.archive, "test_1.0_amd64.tar.gz", "distroseries") | ||
597 | 806 | text = upload.generateOpensslConfig('Opal', upload.openssl_config_opal) | ||
598 | 645 | 807 | ||
600 | 646 | cn_re = re.compile(r'\bCN\s*=\s*something-unique\b') | 808 | id_re = re.compile(r'^# OPAL openssl config\b') |
601 | 809 | cn_re = re.compile(r'\bCN\s*=\s*' + self.testcase_cn + '\s+Opal') | ||
602 | 647 | 810 | ||
603 | 648 | self.assertIn('[ req ]', text) | 811 | self.assertIn('[ req ]', text) |
604 | 812 | self.assertIsNotNone(id_re.search(text)) | ||
605 | 649 | self.assertIsNotNone(cn_re.search(text)) | 813 | self.assertIsNotNone(cn_re.search(text)) |
606 | 650 | self.assertNotIn('extendedKeyUsage', text) | 814 | self.assertNotIn('extendedKeyUsage', text) |
607 | 651 | 815 | ||
608 | @@ -715,6 +879,89 @@ | |||
609 | 715 | ] | 879 | ] |
610 | 716 | self.assertEqual(expected_cmd, args) | 880 | self.assertEqual(expected_cmd, args) |
611 | 717 | 881 | ||
612 | 882 | def test_correct_sipl_openssl_config(self): | ||
613 | 883 | # Check that calling generateOpensslConfig() will return an appropriate | ||
614 | 884 | # openssl configuration. | ||
615 | 885 | self.setUpPPA() | ||
616 | 886 | upload = SigningUpload() | ||
617 | 887 | upload.setTargetDirectory( | ||
618 | 888 | self.archive, "test_1.0_amd64.tar.gz", "distroseries") | ||
619 | 889 | text = upload.generateOpensslConfig('Sipl', upload.openssl_config_sipl) | ||
620 | 890 | |||
621 | 891 | id_re = re.compile(r'^# SIPL openssl config\b') | ||
622 | 892 | cn_re = re.compile(r'\bCN\s*=\s*' + self.testcase_cn + '\s+Sipl') | ||
623 | 893 | |||
624 | 894 | self.assertIn('[ req ]', text) | ||
625 | 895 | self.assertIsNotNone(id_re.search(text)) | ||
626 | 896 | self.assertIsNotNone(cn_re.search(text)) | ||
627 | 897 | self.assertNotIn('extendedKeyUsage', text) | ||
628 | 898 | |||
629 | 899 | def test_correct_sipl_signing_command_executed(self): | ||
630 | 900 | # Check that calling signSipl() will generate the expected command | ||
631 | 901 | # when appropriate keys are present. | ||
632 | 902 | self.setUpSiplKeys() | ||
633 | 903 | fake_call = FakeMethod(result=0) | ||
634 | 904 | self.useFixture(MonkeyPatch("subprocess.call", fake_call)) | ||
635 | 905 | upload = SigningUpload() | ||
636 | 906 | upload.generateSiplKeys = FakeMethod() | ||
637 | 907 | upload.setTargetDirectory( | ||
638 | 908 | self.archive, "test_1.0_amd64.tar.gz", "distroseries") | ||
639 | 909 | upload.signSipl('t.sipl') | ||
640 | 910 | self.assertEqual(1, fake_call.call_count) | ||
641 | 911 | # Assert command form. | ||
642 | 912 | args = fake_call.calls[0][0][0] | ||
643 | 913 | expected_cmd = [ | ||
644 | 914 | 'kmodsign', '-D', 'sha512', self.sipl_pem, self.sipl_x509, | ||
645 | 915 | 't.sipl', 't.sipl.sig' | ||
646 | 916 | ] | ||
647 | 917 | self.assertEqual(expected_cmd, args) | ||
648 | 918 | self.assertEqual(0, upload.generateSiplKeys.call_count) | ||
649 | 919 | |||
650 | 920 | def test_correct_sipl_signing_command_executed_no_keys(self): | ||
651 | 921 | # Check that calling signSipl() will generate no commands when | ||
652 | 922 | # no keys are present. | ||
653 | 923 | self.setUpSiplKeys(create=False) | ||
654 | 924 | fake_call = FakeMethod(result=0) | ||
655 | 925 | self.useFixture(MonkeyPatch("subprocess.call", fake_call)) | ||
656 | 926 | upload = SigningUpload() | ||
657 | 927 | upload.generateSiplKeys = FakeMethod() | ||
658 | 928 | upload.setTargetDirectory( | ||
659 | 929 | self.archive, "test_1.0_amd64.tar.gz", "distroseries") | ||
660 | 930 | upload.signOpal('t.sipl') | ||
661 | 931 | self.assertEqual(0, fake_call.call_count) | ||
662 | 932 | self.assertEqual(0, upload.generateSiplKeys.call_count) | ||
663 | 933 | |||
664 | 934 | def test_correct_sipl_keygen_command_executed(self): | ||
665 | 935 | # Check that calling generateSiplKeys() will generate the | ||
666 | 936 | # expected command. | ||
667 | 937 | self.setUpPPA() | ||
668 | 938 | self.setUpSiplKeys(create=False) | ||
669 | 939 | fake_call = FakeMethod(result=0) | ||
670 | 940 | self.useFixture(MonkeyPatch("subprocess.call", fake_call)) | ||
671 | 941 | upload = SigningUpload() | ||
672 | 942 | upload.setTargetDirectory( | ||
673 | 943 | self.archive, "test_1.0_amd64.tar.gz", "distroseries") | ||
674 | 944 | upload.generateSiplKeys() | ||
675 | 945 | self.assertEqual(2, fake_call.call_count) | ||
676 | 946 | # Assert the actual command matches. | ||
677 | 947 | args = fake_call.calls[0][0][0] | ||
678 | 948 | # Sanitise the keygen tmp file. | ||
679 | 949 | if args[11].endswith('.keygen'): | ||
680 | 950 | args[11] = 'XXX.keygen' | ||
681 | 951 | expected_cmd = [ | ||
682 | 952 | 'openssl', 'req', '-new', '-nodes', '-utf8', '-sha512', | ||
683 | 953 | '-days', '3650', '-batch', '-x509', | ||
684 | 954 | '-config', 'XXX.keygen', '-outform', 'PEM', | ||
685 | 955 | '-out', self.sipl_pem, '-keyout', self.sipl_pem | ||
686 | 956 | ] | ||
687 | 957 | self.assertEqual(expected_cmd, args) | ||
688 | 958 | args = fake_call.calls[1][0][0] | ||
689 | 959 | expected_cmd = [ | ||
690 | 960 | 'openssl', 'x509', '-in', self.sipl_pem, '-outform', 'DER', | ||
691 | 961 | '-out', self.sipl_x509 | ||
692 | 962 | ] | ||
693 | 963 | self.assertEqual(expected_cmd, args) | ||
694 | 964 | |||
695 | 718 | def test_signs_uefi_image(self): | 965 | def test_signs_uefi_image(self): |
696 | 719 | # Each image in the tarball is signed. | 966 | # Each image in the tarball is signed. |
697 | 720 | self.setUpUefiKeys() | 967 | self.setUpUefiKeys() |
698 | @@ -723,6 +970,14 @@ | |||
699 | 723 | upload = self.process() | 970 | upload = self.process() |
700 | 724 | self.assertEqual(1, upload.signUefi.call_count) | 971 | self.assertEqual(1, upload.signUefi.call_count) |
701 | 725 | 972 | ||
702 | 973 | def test_signs_fit_image(self): | ||
703 | 974 | # Each image in the tarball is signed. | ||
704 | 975 | self.setUpFitKeys() | ||
705 | 976 | self.openArchive("test", "1.0", "amd64") | ||
706 | 977 | self.tarfile.add_file("1.0/empty.fit", b"") | ||
707 | 978 | upload = self.process() | ||
708 | 979 | self.assertEqual(1, upload.signFit.call_count) | ||
709 | 980 | |||
710 | 726 | def test_signs_kmod_image(self): | 981 | def test_signs_kmod_image(self): |
711 | 727 | # Each image in the tarball is signed. | 982 | # Each image in the tarball is signed. |
712 | 728 | self.setUpKmodKeys() | 983 | self.setUpKmodKeys() |
713 | @@ -739,9 +994,16 @@ | |||
714 | 739 | upload = self.process() | 994 | upload = self.process() |
715 | 740 | self.assertEqual(1, upload.signOpal.call_count) | 995 | self.assertEqual(1, upload.signOpal.call_count) |
716 | 741 | 996 | ||
717 | 997 | def test_signs_sipl_image(self): | ||
718 | 998 | # Each image in the tarball is signed. | ||
719 | 999 | self.setUpSiplKeys() | ||
720 | 1000 | self.openArchive("test", "1.0", "amd64") | ||
721 | 1001 | self.tarfile.add_file("1.0/empty.sipl", b"") | ||
722 | 1002 | upload = self.process() | ||
723 | 1003 | self.assertEqual(1, upload.signSipl.call_count) | ||
724 | 1004 | |||
725 | 742 | def test_signs_combo_image(self): | 1005 | def test_signs_combo_image(self): |
726 | 743 | # Each image in the tarball is signed. | 1006 | # Each image in the tarball is signed. |
727 | 744 | self.setUpKmodKeys() | ||
728 | 745 | self.openArchive("test", "1.0", "amd64") | 1007 | self.openArchive("test", "1.0", "amd64") |
729 | 746 | self.tarfile.add_file("1.0/empty.efi", b"") | 1008 | self.tarfile.add_file("1.0/empty.efi", b"") |
730 | 747 | self.tarfile.add_file("1.0/empty.ko", b"") | 1009 | self.tarfile.add_file("1.0/empty.ko", b"") |
731 | @@ -749,10 +1011,21 @@ | |||
732 | 749 | self.tarfile.add_file("1.0/empty.opal", b"") | 1011 | self.tarfile.add_file("1.0/empty.opal", b"") |
733 | 750 | self.tarfile.add_file("1.0/empty2.opal", b"") | 1012 | self.tarfile.add_file("1.0/empty2.opal", b"") |
734 | 751 | self.tarfile.add_file("1.0/empty3.opal", b"") | 1013 | self.tarfile.add_file("1.0/empty3.opal", b"") |
735 | 1014 | self.tarfile.add_file("1.0/empty.sipl", b"") | ||
736 | 1015 | self.tarfile.add_file("1.0/empty2.sipl", b"") | ||
737 | 1016 | self.tarfile.add_file("1.0/empty3.sipl", b"") | ||
738 | 1017 | self.tarfile.add_file("1.0/empty4.sipl", b"") | ||
739 | 1018 | self.tarfile.add_file("1.0/empty.fit", b"") | ||
740 | 1019 | self.tarfile.add_file("1.0/empty2.fit", b"") | ||
741 | 1020 | self.tarfile.add_file("1.0/empty3.fit", b"") | ||
742 | 1021 | self.tarfile.add_file("1.0/empty4.fit", b"") | ||
743 | 1022 | self.tarfile.add_file("1.0/empty5.fit", b"") | ||
744 | 752 | upload = self.process() | 1023 | upload = self.process() |
745 | 753 | self.assertEqual(1, upload.signUefi.call_count) | 1024 | self.assertEqual(1, upload.signUefi.call_count) |
746 | 754 | self.assertEqual(2, upload.signKmod.call_count) | 1025 | self.assertEqual(2, upload.signKmod.call_count) |
747 | 755 | self.assertEqual(3, upload.signOpal.call_count) | 1026 | self.assertEqual(3, upload.signOpal.call_count) |
748 | 1027 | self.assertEqual(4, upload.signSipl.call_count) | ||
749 | 1028 | self.assertEqual(5, upload.signFit.call_count) | ||
750 | 756 | 1029 | ||
751 | 757 | def test_installed(self): | 1030 | def test_installed(self): |
752 | 758 | # Files in the tarball are installed correctly. | 1031 | # Files in the tarball are installed correctly. |
753 | @@ -824,6 +1097,43 @@ | |||
754 | 824 | self.assertEqual(stat.S_IMODE(os.stat(self.key).st_mode), 0o600) | 1097 | self.assertEqual(stat.S_IMODE(os.stat(self.key).st_mode), 0o600) |
755 | 825 | self.assertEqual(stat.S_IMODE(os.stat(self.cert).st_mode), 0o644) | 1098 | self.assertEqual(stat.S_IMODE(os.stat(self.cert).st_mode), 0o644) |
756 | 826 | 1099 | ||
757 | 1100 | def test_create_fit_keys_autokey_off(self): | ||
758 | 1101 | # Keys are not created. | ||
759 | 1102 | self.setUpFitKeys(create=False) | ||
760 | 1103 | self.assertFalse(os.path.exists(self.fit_key)) | ||
761 | 1104 | self.assertFalse(os.path.exists(self.fit_cert)) | ||
762 | 1105 | fake_call = FakeMethod(result=0) | ||
763 | 1106 | self.useFixture(MonkeyPatch("subprocess.call", fake_call)) | ||
764 | 1107 | upload = SigningUpload() | ||
765 | 1108 | upload.callLog = FakeMethodCallLog(upload=upload) | ||
766 | 1109 | upload.setTargetDirectory( | ||
767 | 1110 | self.archive, "test_1.0_amd64.tar.gz", "distroseries") | ||
768 | 1111 | upload.signFit(os.path.join(self.makeTemporaryDirectory(), 'fit')) | ||
769 | 1112 | self.assertEqual(0, upload.callLog.caller_count('Fit keygen')) | ||
770 | 1113 | self.assertFalse(os.path.exists(self.fit_key)) | ||
771 | 1114 | self.assertFalse(os.path.exists(self.fit_cert)) | ||
772 | 1115 | |||
773 | 1116 | def test_create_fit_keys_autokey_on(self): | ||
774 | 1117 | # Keys are created on demand. | ||
775 | 1118 | self.setUpPPA() | ||
776 | 1119 | self.setUpFitKeys(create=False) | ||
777 | 1120 | self.assertFalse(os.path.exists(self.fit_key)) | ||
778 | 1121 | self.assertFalse(os.path.exists(self.fit_cert)) | ||
779 | 1122 | fake_call = FakeMethod(result=0) | ||
780 | 1123 | self.useFixture(MonkeyPatch("subprocess.call", fake_call)) | ||
781 | 1124 | fake_copy = FakeMethod(result=0) | ||
782 | 1125 | self.useFixture(MonkeyPatch("shutil.copy", fake_copy)) | ||
783 | 1126 | upload = SigningUpload() | ||
784 | 1127 | upload.callLog = FakeMethodCallLog(upload=upload) | ||
785 | 1128 | upload.setTargetDirectory( | ||
786 | 1129 | self.archive, "test_1.0_amd64.tar.gz", "distroseries") | ||
787 | 1130 | upload.signFit(os.path.join(self.makeTemporaryDirectory(), 't.fit')) | ||
788 | 1131 | self.assertEqual(1, upload.callLog.caller_count('Fit keygen')) | ||
789 | 1132 | self.assertTrue(os.path.exists(self.fit_key)) | ||
790 | 1133 | self.assertTrue(os.path.exists(self.fit_cert)) | ||
791 | 1134 | self.assertEqual(stat.S_IMODE(os.stat(self.fit_key).st_mode), 0o600) | ||
792 | 1135 | self.assertEqual(stat.S_IMODE(os.stat(self.fit_cert).st_mode), 0o644) | ||
793 | 1136 | |||
794 | 827 | def test_create_kmod_keys_autokey_off(self): | 1137 | def test_create_kmod_keys_autokey_off(self): |
795 | 828 | # Keys are not created. | 1138 | # Keys are not created. |
796 | 829 | self.setUpKmodKeys(create=False) | 1139 | self.setUpKmodKeys(create=False) |
797 | @@ -898,16 +1208,55 @@ | |||
798 | 898 | self.assertEqual(stat.S_IMODE(os.stat(self.opal_pem).st_mode), 0o600) | 1208 | self.assertEqual(stat.S_IMODE(os.stat(self.opal_pem).st_mode), 0o600) |
799 | 899 | self.assertEqual(stat.S_IMODE(os.stat(self.opal_x509).st_mode), 0o644) | 1209 | self.assertEqual(stat.S_IMODE(os.stat(self.opal_x509).st_mode), 0o644) |
800 | 900 | 1210 | ||
801 | 1211 | def test_create_sipl_keys_autokey_off(self): | ||
802 | 1212 | # Keys are not created. | ||
803 | 1213 | self.setUpSiplKeys(create=False) | ||
804 | 1214 | self.assertFalse(os.path.exists(self.sipl_pem)) | ||
805 | 1215 | self.assertFalse(os.path.exists(self.sipl_x509)) | ||
806 | 1216 | fake_call = FakeMethod(result=0) | ||
807 | 1217 | self.useFixture(MonkeyPatch("subprocess.call", fake_call)) | ||
808 | 1218 | upload = SigningUpload() | ||
809 | 1219 | upload.callLog = FakeMethodCallLog(upload=upload) | ||
810 | 1220 | upload.setTargetDirectory( | ||
811 | 1221 | self.archive, "test_1.0_amd64.tar.gz", "distroseries") | ||
812 | 1222 | upload.signOpal(os.path.join(self.makeTemporaryDirectory(), 't.sipl')) | ||
813 | 1223 | self.assertEqual(0, upload.callLog.caller_count('Sipl keygen key')) | ||
814 | 1224 | self.assertEqual(0, upload.callLog.caller_count('Sipl keygen cert')) | ||
815 | 1225 | self.assertFalse(os.path.exists(self.sipl_pem)) | ||
816 | 1226 | self.assertFalse(os.path.exists(self.sipl_x509)) | ||
817 | 1227 | |||
818 | 1228 | def test_create_sipl_keys_autokey_on(self): | ||
819 | 1229 | # Keys are created on demand. | ||
820 | 1230 | self.setUpPPA() | ||
821 | 1231 | self.setUpSiplKeys(create=False) | ||
822 | 1232 | self.assertFalse(os.path.exists(self.sipl_pem)) | ||
823 | 1233 | self.assertFalse(os.path.exists(self.sipl_x509)) | ||
824 | 1234 | fake_call = FakeMethod(result=0) | ||
825 | 1235 | self.useFixture(MonkeyPatch("subprocess.call", fake_call)) | ||
826 | 1236 | upload = SigningUpload() | ||
827 | 1237 | upload.callLog = FakeMethodCallLog(upload=upload) | ||
828 | 1238 | upload.setTargetDirectory( | ||
829 | 1239 | self.archive, "test_1.0_amd64.tar.gz", "distroseries") | ||
830 | 1240 | upload.signSipl(os.path.join(self.makeTemporaryDirectory(), 't.sipl')) | ||
831 | 1241 | self.assertEqual(1, upload.callLog.caller_count('Sipl keygen key')) | ||
832 | 1242 | self.assertEqual(1, upload.callLog.caller_count('Sipl keygen cert')) | ||
833 | 1243 | self.assertTrue(os.path.exists(self.sipl_pem)) | ||
834 | 1244 | self.assertTrue(os.path.exists(self.sipl_x509)) | ||
835 | 1245 | self.assertEqual(stat.S_IMODE(os.stat(self.sipl_pem).st_mode), 0o600) | ||
836 | 1246 | self.assertEqual(stat.S_IMODE(os.stat(self.sipl_x509).st_mode), 0o644) | ||
837 | 1247 | |||
838 | 901 | def test_checksumming_tree(self): | 1248 | def test_checksumming_tree(self): |
839 | 902 | # Specifying no options should leave us with an open tree, | 1249 | # Specifying no options should leave us with an open tree, |
840 | 903 | # confirm it is checksummed. | 1250 | # confirm it is checksummed. |
841 | 904 | self.setUpUefiKeys() | 1251 | self.setUpUefiKeys() |
842 | 905 | self.setUpKmodKeys() | 1252 | self.setUpKmodKeys() |
843 | 906 | self.setUpOpalKeys() | 1253 | self.setUpOpalKeys() |
844 | 1254 | self.setUpSiplKeys() | ||
845 | 907 | self.openArchive("test", "1.0", "amd64") | 1255 | self.openArchive("test", "1.0", "amd64") |
846 | 908 | self.tarfile.add_file("1.0/empty.efi", b"") | 1256 | self.tarfile.add_file("1.0/empty.efi", b"") |
847 | 909 | self.tarfile.add_file("1.0/empty.ko", b"") | 1257 | self.tarfile.add_file("1.0/empty.ko", b"") |
848 | 910 | self.tarfile.add_file("1.0/empty.opal", b"") | 1258 | self.tarfile.add_file("1.0/empty.opal", b"") |
849 | 1259 | self.tarfile.add_file("1.0/empty.sipl", b"") | ||
850 | 911 | self.process_emulate() | 1260 | self.process_emulate() |
851 | 912 | sha256file = os.path.join(self.getSignedPath("test", "amd64"), | 1261 | sha256file = os.path.join(self.getSignedPath("test", "amd64"), |
852 | 913 | "1.0", "SHA256SUMS") | 1262 | "1.0", "SHA256SUMS") |
853 | @@ -926,6 +1275,7 @@ | |||
854 | 926 | self.tarfile.add_file("1.0/empty.efi", b"") | 1275 | self.tarfile.add_file("1.0/empty.efi", b"") |
855 | 927 | self.tarfile.add_file("1.0/empty.ko", b"") | 1276 | self.tarfile.add_file("1.0/empty.ko", b"") |
856 | 928 | self.tarfile.add_file("1.0/empty.opal", b"") | 1277 | self.tarfile.add_file("1.0/empty.opal", b"") |
857 | 1278 | self.tarfile.add_file("1.0/empty.sipl", b"") | ||
858 | 929 | self.process_emulate() | 1279 | self.process_emulate() |
859 | 930 | sha256file = os.path.join(self.getSignedPath("test", "amd64"), | 1280 | sha256file = os.path.join(self.getSignedPath("test", "amd64"), |
860 | 931 | "1.0", "SHA256SUMS") | 1281 | "1.0", "SHA256SUMS") |
861 | @@ -949,6 +1299,7 @@ | |||
862 | 949 | self.tarfile.add_file("1.0/empty.efi", b"") | 1299 | self.tarfile.add_file("1.0/empty.efi", b"") |
863 | 950 | self.tarfile.add_file("1.0/empty.ko", b"") | 1300 | self.tarfile.add_file("1.0/empty.ko", b"") |
864 | 951 | self.tarfile.add_file("1.0/empty.opal", b"") | 1301 | self.tarfile.add_file("1.0/empty.opal", b"") |
865 | 1302 | self.tarfile.add_file("1.0/empty.sipl", b"") | ||
866 | 952 | self.process_emulate() | 1303 | self.process_emulate() |
867 | 953 | sha256file = os.path.join(self.getSignedPath("test", "amd64"), | 1304 | sha256file = os.path.join(self.getSignedPath("test", "amd64"), |
868 | 954 | "1.0", "SHA256SUMS") | 1305 | "1.0", "SHA256SUMS") |
869 | @@ -982,6 +1333,7 @@ | |||
870 | 982 | self.tarfile.add_file("1.0/empty.efi", "") | 1333 | self.tarfile.add_file("1.0/empty.efi", "") |
871 | 983 | self.tarfile.add_file("1.0/empty.ko", "") | 1334 | self.tarfile.add_file("1.0/empty.ko", "") |
872 | 984 | self.tarfile.add_file("1.0/empty.opal", "") | 1335 | self.tarfile.add_file("1.0/empty.opal", "") |
873 | 1336 | self.tarfile.add_file("1.0/empty.sipl", "") | ||
874 | 985 | self.process_emulate() | 1337 | self.process_emulate() |
875 | 986 | sha256file = os.path.join(self.getSignedPath("test", "amd64"), | 1338 | sha256file = os.path.join(self.getSignedPath("test", "amd64"), |
876 | 987 | "1.0", "SHA256SUMS") | 1339 | "1.0", "SHA256SUMS") |