Merge lp:~xnox/utah/uefi into lp:utah

Proposed by Dimitri John Ledkov
Status: Merged
Merged at revision: 871
Proposed branch: lp:~xnox/utah/uefi
Merge into: lp:utah
Diff against target: 132 lines (+80/-1)
4 files modified
debian/changelog (+1/-0)
debian/control (+1/-1)
utah/isotest/data/file_list_uefi (+3/-0)
utah/isotest/iso_static_validation.py (+75/-0)
To merge this branch: bzr merge lp:~xnox/utah/uefi
Reviewer Review Type Date Requested Status
Max Brustkern (community) Approve
Review via email: mp+159811@code.launchpad.net

Description of the change

This is partial support for additional EFI static validation. In particular EFI files are checked to be where expected and SecureBoot signatures are checked on amd64 images. I have tested that precise/raring desktop/server pass on amd64, and that EFI tests are correctly not executed on i386 (as those images do not have EFI support).

There are a couple of additional checks left to do. The EFI capable images also have a GPT partition table with a second EFI partition that should be checked for, and it's not checked for at the moment. I will be doing a separate merge proposal for that.

To post a comment you must log in.
Revision history for this message
Max Brustkern (nuclearbob) wrote :

When I run this against a precise desktop amd64 ISO (md5sum f6a647130152f9acf6d1a7eecc2507a4) I get:
DEBUG: Verifying UEFI shim
ERROR: test_efi_secure_boot_signatures (__main__.TestValidateISO)
ERROR: Traceback (most recent call last):
  File "/usr/lib/python2.7/unittest/case.py", line 332, in run
    testMethod()
  File "./iso_static_validation.py", line 477, in test_efi_secure_boot_signatures
    stderr=subprocess.PIPE)
  File "/usr/lib/python2.7/subprocess.py", line 679, in __init__
    errread, errwrite)
  File "/usr/lib/python2.7/subprocess.py", line 1259, in _execute_child
    raise child_exception
OSError: [Errno 2] No such file or directory

I'm investigating further.

Revision history for this message
Dimitri John Ledkov (xnox) wrote :

On 19 April 2013 15:10, Max Brustkern <email address hidden> wrote:
> When I run this against a precise desktop amd64 ISO (md5sum f6a647130152f9acf6d1a7eecc2507a4) I get:
> DEBUG: Verifying UEFI shim
> ERROR: test_efi_secure_boot_signatures (__main__.TestValidateISO)
> ERROR: Traceback (most recent call last):
> File "/usr/lib/python2.7/unittest/case.py", line 332, in run
> testMethod()
> File "./iso_static_validation.py", line 477, in test_efi_secure_boot_signatures
> stderr=subprocess.PIPE)
> File "/usr/lib/python2.7/subprocess.py", line 679, in __init__
> errread, errwrite)
> File "/usr/lib/python2.7/subprocess.py", line 1259, in _execute_child
> raise child_exception
> OSError: [Errno 2] No such file or directory
>
> I'm investigating further.

Please install a new dependency: sudo apt-get install sbsigntool

I added it to debian/control.

Regards,

Dmitrijs.

Revision history for this message
Max Brustkern (nuclearbob) wrote :

On 04/19/2013 10:46 AM, Dmitrijs Ledkovs wrote:
> On 19 April 2013 15:10, Max Brustkern <email address hidden> wrote:
>> When I run this against a precise desktop amd64 ISO (md5sum f6a647130152f9acf6d1a7eecc2507a4) I get:
>> DEBUG: Verifying UEFI shim
>> ERROR: test_efi_secure_boot_signatures (__main__.TestValidateISO)
>> ERROR: Traceback (most recent call last):
>> File "/usr/lib/python2.7/unittest/case.py", line 332, in run
>> testMethod()
>> File "./iso_static_validation.py", line 477, in test_efi_secure_boot_signatures
>> stderr=subprocess.PIPE)
>> File "/usr/lib/python2.7/subprocess.py", line 679, in __init__
>> errread, errwrite)
>> File "/usr/lib/python2.7/subprocess.py", line 1259, in _execute_child
>> raise child_exception
>> OSError: [Errno 2] No such file or directory
>>
>> I'm investigating further.
> Please install a new dependency: sudo apt-get install sbsigntool
>
> I added it to debian/control.
>
> Regards,
>
> Dmitrijs.
>
Derp. I even saw that change to control and investigated availability
in older versions. My bad.

Revision history for this message
Max Brustkern (nuclearbob) wrote :

With the proper dependencies installed, I can validate all types of image I'd expect to work. Looks good to me. Thanks!

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'debian/changelog'
2--- debian/changelog 2013-04-17 14:23:46 +0000
3+++ debian/changelog 2013-04-19 12:21:32 +0000
4@@ -3,6 +3,7 @@
5 [ Dmitrijs Ledkovs ]
6 * Check squashfs on the server images as well during ISO static
7 validation.
8+ * Check Secure Boot signatures on signed imaged (CD-ROM partition).
9
10 [ Javier Collado ]
11 * Use socket timeout in SSH commands instead of SIGALRM (LP: #1169510)
12
13=== modified file 'debian/control'
14--- debian/control 2013-04-01 11:19:35 +0000
15+++ debian/control 2013-04-19 12:21:32 +0000
16@@ -49,7 +49,7 @@
17 Package: utah-client
18 Architecture: all
19 Depends: ${misc:Depends}, ${python:Depends},
20- bzr, python-jsonschema (>= 0.5~), python-psutil, python-yaml, utah-common
21+ bzr, python-jsonschema (>= 0.5~), python-psutil, python-yaml, sbsigntool, utah-common
22 Recommends: git
23 Description: Ubuntu Test Automation Harness Client
24 Automation framework for testing in Ubuntu, client portion
25
26=== added file 'utah/isotest/data/file_list_uefi'
27--- utah/isotest/data/file_list_uefi 1970-01-01 00:00:00 +0000
28+++ utah/isotest/data/file_list_uefi 2013-04-19 12:21:32 +0000
29@@ -0,0 +1,3 @@
30+EFI/BOOT/BOOTx64.EFI
31+EFI/BOOT/grubx64.efi
32+boot/grub/x86_64-efi
33
34=== modified file 'utah/isotest/iso_static_validation.py'
35--- utah/isotest/iso_static_validation.py 2013-04-15 21:08:40 +0000
36+++ utah/isotest/iso_static_validation.py 2013-04-19 12:21:32 +0000
37@@ -64,6 +64,7 @@
38 lib_path = os.path.abspath('../')
39 sys.path.append(lib_path)
40 from utah.iso import ISO
41+from utah.client.vcs import BzrHandler
42
43
44 # Defaults
45@@ -123,6 +124,12 @@
46 else:
47 ubiquity_image = False
48
49+#Set a flag for UEFI&SecureBoot
50+if (st_variant in ('desktop', 'server', 'dvd') and st_arch == 'amd64'):
51+ uefi_image = True
52+else:
53+ uefi_image = False
54+
55 #Setup the path for data files
56 DATA_PATH = os.path.join(os.path.dirname(os.path.realpath(__file__)), 'data')
57
58@@ -427,6 +434,74 @@
59 self.assertEqual(stderr, '')
60 self.assertIn("created 1 directories", stdout)
61
62+ @unittest.skipUnless(uefi_image,
63+ "Test EFI files on ubuntu amd64 images")
64+ def test_efi_files_present(self):
65+ """Test if the relevant files are present in the ISO for UEFI."""
66+ (stdout, stderr) = self.iso.listfiles()
67+ logging.debug('Check for error in extracting file list from the iso')
68+ self.assertEqual(stderr, '')
69+ files_list = open(os.path.join(DATA_PATH, 'file_list_uefi'))
70+ logging.debug('Check if relevant files are present in the iso')
71+ for list_server in files_list:
72+ path = list_server.rstrip()
73+ self.assertIn(path, stdout)
74+
75+ @unittest.skipUnless(uefi_image,
76+ "Test Secure Boot UEFI signatures")
77+ def test_efi_secure_boot_signatures(self):
78+ logging.debug('Generating verification certificates')
79+
80+ keys = os.path.join(self.temp_dir, 'keys')
81+ keys_repo = "lp:qa-regression-testing/notes_testing/secure-boot/keys"
82+ export_bzr_keys = BzrHandler(keys_repo, branch=False, destination=keys)
83+ export_bzr_keys.get()
84+ cmd = ["make", "-C", keys]
85+ output = subprocess.Popen(cmd, stdout=subprocess.PIPE,
86+ stderr=subprocess.PIPE)
87+ (stdout, stderr) = output.communicate()
88+ self.assertEqual(stderr, '')
89+ microsoft = os.path.join(keys, 'microsoft-uefica-public.pem')
90+ canonical = os.path.join(keys, 'canonical-master-public.pem')
91+ canonical_chain = os.path.join(
92+ keys, 'canonical-master-signing-public-chain.pem')
93+
94+ logging.debug('Extracting UEFI boot and kernel images')
95+ shim = self.iso.extract('./EFI/BOOT/BOOTx64.EFI', self.temp_dir)
96+ grub = self.iso.extract('./EFI/BOOT/grubx64.efi', self.temp_dir)
97+ kernel = self.iso.extract(iso.kernelpath(), self.temp_dir)
98+
99+ logging.debug('Verifying UEFI shim')
100+ cmd = ['sbverify', '--cert', microsoft, shim]
101+ output = subprocess.Popen(cmd, stdout=subprocess.PIPE,
102+ stderr=subprocess.PIPE)
103+ (stdout, stderr) = output.communicate()
104+ self.assertEqual(stdout, 'Signature verification OK\n')
105+
106+ logging.debug('Verifying UEFI grub')
107+ cmd = ['sbverify', '--cert', canonical, grub]
108+ output = subprocess.Popen(cmd, stdout=subprocess.PIPE,
109+ stderr=subprocess.PIPE)
110+ (stdout, stderr) = output.communicate()
111+ self.assertEqual(stdout, 'Signature verification OK\n')
112+
113+ logging.debug('Detaching kernel signature')
114+ kernel_sig = os.path.join(self.temp_dir, 'vmlinuz.efi.signature')
115+ cmd = ['sbattach', '--detach', kernel_sig, kernel]
116+ output = subprocess.Popen(cmd, stdout=subprocess.PIPE,
117+ stderr=subprocess.PIPE)
118+ (stdout, stderr) = output.communicate()
119+ self.assertEqual(stdout, '')
120+ self.assertEqual(stderr, '')
121+
122+ logging.debug('Verifying kernel signature')
123+ cmd = ['sbverify', '--cert', canonical_chain,
124+ '--detached', kernel_sig, kernel]
125+ output = subprocess.Popen(cmd, stdout=subprocess.PIPE,
126+ stderr=subprocess.PIPE)
127+ (stdout, stderr) = output.communicate()
128+ self.assertEqual(stdout, 'Signature verification OK\n')
129+
130 # clean up
131 @classmethod
132 def tearDownClass(cls):

Subscribers

People subscribed via source and target branches