summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--meson.build1
-rw-r--r--src/ukify/test/example.signing.crt.base6423
-rw-r--r--src/ukify/test/example.signing.key.base6430
-rw-r--r--src/ukify/test/example.tpm2-pcr-private.pem.base6430
-rw-r--r--src/ukify/test/example.tpm2-pcr-private2.pem.base6430
-rw-r--r--src/ukify/test/example.tpm2-pcr-public.pem.base648
-rw-r--r--src/ukify/test/example.tpm2-pcr-public2.pem.base648
-rw-r--r--src/ukify/test/meson.build7
-rw-r--r--src/ukify/test/setup.cfg2
-rwxr-xr-xsrc/ukify/test/test_ukify.py372
10 files changed, 511 insertions, 0 deletions
diff --git a/meson.build b/meson.build
index 84b2a22ebe..9f8556ff96 100644
--- a/meson.build
+++ b/meson.build
@@ -2198,6 +2198,7 @@ subdir('src/test')
subdir('src/fuzz')
subdir('rules.d')
subdir('test')
+subdir('src/ukify/test') # needs to be last for test_env variable
############################################################
diff --git a/src/ukify/test/example.signing.crt.base64 b/src/ukify/test/example.signing.crt.base64
new file mode 100644
index 0000000000..694d13b5a6
--- /dev/null
+++ b/src/ukify/test/example.signing.crt.base64
@@ -0,0 +1,23 @@
+LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSURsVENDQW4yZ0F3SUJBZ0lVTzlqUWhhblhj
+b3ViOERzdXlMMWdZbksrR1lvd0RRWUpLb1pJaHZjTkFRRUwKQlFBd1dURUxNQWtHQTFVRUJoTUNX
+Rmd4RlRBVEJnTlZCQWNNREVSbFptRjFiSFFnUTJsMGVURWNNQm9HQTFVRQpDZ3dUUkdWbVlYVnNk
+Q0JEYjIxd1lXNTVJRXgwWkRFVk1CTUdBMVVFQXd3TWEyVjVJSE5wWjI1cGJtbG5NQ0FYCkRUSXlN
+VEF5T1RFM01qY3dNVm9ZRHpNd01qSXdNekF4TVRjeU56QXhXakJaTVFzd0NRWURWUVFHRXdKWVdE
+RVYKTUJNR0ExVUVCd3dNUkdWbVlYVnNkQ0JEYVhSNU1Sd3dHZ1lEVlFRS0RCTkVaV1poZFd4MElF
+TnZiWEJoYm5rZwpUSFJrTVJVd0V3WURWUVFEREF4clpYa2djMmxuYm1sdWFXY3dnZ0VpTUEwR0NT
+cUdTSWIzRFFFQkFRVUFBNElCCkR3QXdnZ0VLQW9JQkFRREtVeHR4Y0d1aGYvdUp1SXRjWEhvdW0v
+RE9RL1RJM3BzUWlaR0ZWRkJzbHBicU5wZDUKa2JDaUFMNmgrY1FYaGRjUmlOT1dBR0wyMFZ1T2Rv
+VTZrYzlkdklGQnFzKzc2NHhvWGY1UGd2SlhvQUxSUGxDZAp4YVdPQzFsOFFIRHpxZ09SdnREMWNI
+WFoveTkvZ1YxVU1GK1FlYm12aUhRN0U4eGw1T2h5MG1TQVZYRDhBTitsCjdpMUR6N0NuTzhrMVph
+alhqYXlpNWV1WEV0TnFSZXNuVktRRElTQ0t2STFueUxySWxHRU1GZmFuUmRLQWthZ3MKalJnTmVh
+T3N3aklHNjV6UzFVdjJTZXcxVFpIaFhtUmd5TzRVT0JySHZlSml2T2hObzU3UlRKd0M2K2lGY0FG
+aApSSnorVmM2QUlSSkI1ZWtJUmdCN3VDNEI5ZmwydXdZKytMODNBZ01CQUFHalV6QlJNQjBHQTFV
+ZERnUVdCQlFqCllIMnpzVFlPQU51MkcweXk1QkxlOHBvbWZUQWZCZ05WSFNNRUdEQVdnQlFqWUgy
+enNUWU9BTnUyRzB5eTVCTGUKOHBvbWZUQVBCZ05WSFJNQkFmOEVCVEFEQVFIL01BMEdDU3FHU0li
+M0RRRUJDd1VBQTRJQkFRQ2dxcmFXaE51dQptUmZPUjVxcURVcC83RkpIL1N6Zk1vaDBHL2lWRkhv
+OUpSS0tqMUZ2Q0VZc1NmeThYTmdaUDI5eS81Z0h4cmcrCjhwZWx6bWJLczdhUTRPK01TcmIzTm11
+V1IzT0M0alBoNENrM09ZbDlhQy9iYlJqSWFvMDJ6K29XQWNZZS9xYTEKK2ZsemZWVEUwMHJ5V1RM
+K0FJdDFEZEVqaG01WXNtYlgvbWtacUV1TjBtSVhhRXhSVE9walczUWRNeVRQaURTdApvanQvQWMv
+R2RUWDd0QkhPTk44Z3djaC91V293aVNORERMUm1wM2VScnlOZ3RPKzBISUd5Qm16ZWNsM0VlVEo2
+CnJzOGRWUFhqR1Z4dlZDb2tqQllrOWdxbkNGZEJCMGx4VXVNZldWdVkyRUgwSjI3aGh4SXNFc3ls
+VTNIR1EyK2MKN1JicVY4VTNSRzA4Ci0tLS0tRU5EIENFUlRJRklDQVRFLS0tLS0K
diff --git a/src/ukify/test/example.signing.key.base64 b/src/ukify/test/example.signing.key.base64
new file mode 100644
index 0000000000..88baedbcb6
--- /dev/null
+++ b/src/ukify/test/example.signing.key.base64
@@ -0,0 +1,30 @@
+LS0tLS1CRUdJTiBQUklWQVRFIEtFWS0tLS0tCk1JSUV2Z0lCQURBTkJna3Foa2lHOXcwQkFRRUZB
+QVNDQktnd2dnU2tBZ0VBQW9JQkFRREtVeHR4Y0d1aGYvdUoKdUl0Y1hIb3VtL0RPUS9USTNwc1Fp
+WkdGVkZCc2xwYnFOcGQ1a2JDaUFMNmgrY1FYaGRjUmlOT1dBR0wyMFZ1Twpkb1U2a2M5ZHZJRkJx
+cys3NjR4b1hmNVBndkpYb0FMUlBsQ2R4YVdPQzFsOFFIRHpxZ09SdnREMWNIWFoveTkvCmdWMVVN
+RitRZWJtdmlIUTdFOHhsNU9oeTBtU0FWWEQ4QU4rbDdpMUR6N0NuTzhrMVphalhqYXlpNWV1WEV0
+TnEKUmVzblZLUURJU0NLdkkxbnlMcklsR0VNRmZhblJkS0FrYWdzalJnTmVhT3N3aklHNjV6UzFV
+djJTZXcxVFpIaApYbVJneU80VU9Cckh2ZUppdk9oTm81N1JUSndDNitpRmNBRmhSSnorVmM2QUlS
+SkI1ZWtJUmdCN3VDNEI5ZmwyCnV3WSsrTDgzQWdNQkFBRUNnZ0VBQkhZQ28rU3JxdHJzaStQU3hz
+MlBNQm5tSEZZcFBvaVIrTEpmMEFYRTVEQUoKMGM0MFZzemNqU1hoRGljNHFLQWQxdGdpZWlzMkEy
+VW9WS0xPV3pVOTBqNUd4MURoMWEzaTRhWTQ1ajNuNUFDMgpMekRsakNVQWVucExsYzdCN3MxdjJM
+WFJXNmdJSVM5Y043NTlkVTYvdktyQ2FsbGkzcTZZRWlNUzhQMHNsQnZFCkZtdEc1elFsOVJjV0gr
+cHBqdzlIMTJSZ3BldUVJVEQ2cE0vd2xwcXZHRlUwcmZjM0NjMHhzaWdNTnh1Z1FJNGgKbnpjWDVs
+OEs0SHdvbmhOTG9TYkh6OU5BK3p3QkpuUlZVSWFaaEVjSThtaEVPWHRaRkpYc01aRnhjS2l3SHFS
+dApqUUVHOHJRa3lPLytXMmR5Z2czV1lNYXE1OWpUWVdIOUsrQmFyeEMzRVFLQmdRRFBNSFMycjgz
+ZUpRTTlreXpkCndDdnlmWGhQVlVtbVJnOGwyWng0aC9tci9mNUdDeW5SdzRzT2JuZGVQd29tZ1Iz
+cFBleFFGWlFFSExoZ1RGY3UKVk5uYXcrTzBFL1VnL01pRGswZDNXU0hVZXZPZnM1cEM2b3hYNjNT
+VENwNkVLT2VEZlpVMW9OeHRsZ0YyRVhjcgpmVlZpSzFKRGk3N2dtaENLcFNGcjBLK3gyUUtCZ1FE
+NS9VUC9hNU52clExdUhnKzR0SzJZSFhSK1lUOFREZG00Ck8xZmh5TU5lOHRYSkd5UUJjTktVTWg2
+M2VyR1MwWlRWdGdkNHlGS3RuOGtLU2U4TmlacUl1aitVUVIyZ3pEQVAKQ2VXcXl2Y2pRNmovU1Yw
+WjVvKzlTNytiOStpWWx5RTg2bGZobHh5Z21aNnptYisxUUNteUtNVUdBNis5VmUvMgo1MHhDMXBB
+L2p3S0JnUUNEOHA4UnpVcDFZK3I1WnVaVzN0RGVJSXZqTWpTeVFNSGE0QWhuTm1tSjREcjBUcDIy
+CmFpci82TmY2WEhsUlpqOHZVSEZUMnpvbG1FalBneTZ1WWZsUCtocmtqeVU0ZWVRVTcxRy9Mek45
+UjBRcCs4Nk4KT1NSaHhhQzdHRE0xaFh0VFlVSUtJa1RmUVgzeXZGTEJqcE0yN3RINEZHSmVWWitk
+UEdiWmE5REltUUtCZ1FENQpHTU5qeExiQnhhY25QYThldG5KdnE1SUR5RFRJY0xtc1dQMkZ6cjNX
+WTVSZzhybGE4aWZ5WVVxNE92cXNPRWZjCjk2ZlVVNUFHejd2TWs4VXZNUmtaK3JRVnJ4aXR2Q2g3
+STdxRkIvOWdWVEFWU080TE8vR29oczBqeGRBd0ZBK2IKbWtyOVQ4ekh2cXNqZlNWSW51bXRTL0Nl
+d0plaHl2cjBoSjg1em9Fbnd3S0JnR1h6UXVDSjJDb3NHVVhEdnlHKwpyRzVBd3pUZGd0bHg4YTBK
+NTg1OWtZbVd0cW5WYUJmbFdrRmNUcHNEaGZ2ZWVDUkswc29VRlNPWkcranpsbWJrCkpRL09aVkZJ
+dG9MSVZCeE9qeWVXNlhUSkJXUzFRSkVHckkwY0tTbXNKcENtUXVPdUxMVnZYczV0U21CVmc5RXQK
+MjZzUkZwcjVWWmsrZlNRa3RhbkM4NGV1Ci0tLS0tRU5EIFBSSVZBVEUgS0VZLS0tLS0K
diff --git a/src/ukify/test/example.tpm2-pcr-private.pem.base64 b/src/ukify/test/example.tpm2-pcr-private.pem.base64
new file mode 100644
index 0000000000..586b28ef9b
--- /dev/null
+++ b/src/ukify/test/example.tpm2-pcr-private.pem.base64
@@ -0,0 +1,30 @@
+LS0tLS1CRUdJTiBQUklWQVRFIEtFWS0tLS0tCk1JSUV2Z0lCQURBTkJna3Foa2lHOXcwQkFRRUZB
+QVNDQktnd2dnU2tBZ0VBQW9JQkFRQzVuOHFhbzVNZ1BJUVcKc0F5Y2R3dnB1bjdNNHlRSW9FL3I3
+ekFGTG1hZlBXclo3d2JaaUIyTkY1MVdHOEo4bnlDQkI3M0RLcmZaeWs5cwphQXdXVW5RR2t0dGFv
+RXpXRzZSRTM3dXdQOUpVM09YdklTNTBhcy9KSHVHNlJPYmE2V0NOOFp2TTdkZGpvTDFKCkZlYnBS
+SXI1Vi82VStMTFhrUnRNYVczUnZ6T0xYeU1NT2QzOEcxZ0d0VlRHcm90ejVldFgrTUNVU2lOVGFE
+OVUKN1dEZXVsZXVpMlRnK1I3TGRoSXg3ZTQ5cEhRM3d6a1NxeFQ4SGpoU3ZURWpITWVSNjIwaUhF
+ZW9uYzdsMXVnagpzY1pwTktHdk13bXUvU2ptWFp6UkpOdjVOU0txcEVnQll2RnFkS3dUdlc4MWl6
+SUFvN3paMkx6NDJYb25zSWJ2CjNrbGZqTG1mQWdNQkFBRUNnZ0VBQXozYm8yeTAzb3kvLzhkdVNQ
+TTVSWWtvdXJwQ3dGWFFYMzNyV0VQUnJmazgKR3ZjMkp1bGVIcjhwVTc0alhOcklqZ2hORTVIMDZQ
+eEQrOUFyV2Q1eHdVV2lTQWhobnlHWGNrNTM4Q0dGTWs4egpRc1JSRTk1anA0Ny9BU28vMzlYUWhs
+b1FUdmxlV0JLUUM2MHl2YU1oVEM1eHR6ZEtwRUlYK0hNazVGTlMrcDJVCmxtL3AzVE1YWDl1bmc5
+Mk9pTzUzV1VreFpQN2cwTVJHbGJrNzhqc1dkdjFYY0tLRjhuVmU5WC9NR1lTYlVLNy8KM2NYazFR
+WTRUdVZaQlBFSE12RFRpWWwxbmdDd1ZuL2MyY3JQU3hJRFdFWlhEdm90SFUwQkNQZURVckxGa0F5
+cQpDaloza3MzdEh4am42STkraEVNcUJDMzY1MHFjdDNkZ0RVV2loc2MzdVFLQmdRRG1mVTNKc29K
+QWFOdmxCbXgyClhzRDRqbXlXV1F2Z244cVNVNG03a2JKdmprcUJ6VnB0T0ZsYmk2ejZHOXR6ZHNX
+a0dJSjh3T0ZRb1hlM0dKOFIKSlVpeEFXTWZOM1JURGo5VjVXbzZJdE5EbzM1N3dNbVVYOW1qeThF
+YXp0RE1BckdSNGJva0Q5RjY3clhqSGdSMQpaZVcvSDlUWHFUV1l4VHl6UDB3ZDBQeUZ4d0tCZ1FE
+T0swWHVQS0o0WG00WmFCemN0OTdETXdDcFBSVmVvUWU3CmkzQjRJQ3orWFZ4cVM2amFTY2xNeEVm
+Nk5tM2tLNERDR1dwVkpXcm9qNjlMck1KWnQzTlI2VUJ5NzNqUVBSamsKRXk5N3YrR04yVGwwNjFw
+ZUxUM0dRS2RhT2VxWldpdElOcFc1dUxHL1poMGhoRUY5c1lSVTRtUFYwUWpla2kvdgp1bnVmcWx0
+TmFRS0JnQTl6TE1pdFg0L0R0NkcxZVlYQnVqdXZDRlpYcDdVcDRPRklHajVwZU1XRGl6a0NNK0tJ
+CldXMEtndERORnp1NUpXeG5mQyt5bWlmV2V2alovS2Vna1N2VVJQbXR0TzF3VWd5RzhVVHVXcXo1
+QTV4MkFzMGcKVTYxb0ZneWUrbDRDZkRha0k5OFE5R0RDS1kwTTBRMnhnK0g0MTBLUmhCYzJlV2dt
+Z1FxcW5KSzNBb0dCQU1rZgpnOWZXQlBVQndjdzlPYkxFR0tjNkVSSUlTZG1IbytCOE5kcXFJTnAv
+djFEZXdEazZ0QXFVakZiMlZCdTdxSjh4ClpmN3NRcS9ldzdaQ01WS09XUXgyVEc0VFdUdGo3dTFJ
+SGhGTjdiNlFRN0hnaXNiR3diV3VpdFBGSGl3OXYyMXgKK253MFJnb2VscHFFeDlMVG92R2Y3SjdB
+ampONlR4TkJTNnBGNlUzSkFvR0JBT0tnbHlRWDJpVG5oMXd4RG1TVQo4RXhoQVN3S09iNS8yRmx4
+aUhtUHVjNTZpS0tHY0lkV1cxMUdtbzdJakNzSTNvRm9iRkFjKzBXZkMvQTdMNWlmCjNBYVNWcmh0
+cThRRklRaUtyYUQ0YlRtRk9Famg5QVVtUHMrWnd1OE9lSXJBSWtwZDV3YmlhTEJLd0pRbVdtSFAK
+dUNBRTA3cXlSWXJ0c3QvcnVSSG5IdFA1Ci0tLS0tRU5EIFBSSVZBVEUgS0VZLS0tLS0K
diff --git a/src/ukify/test/example.tpm2-pcr-private2.pem.base64 b/src/ukify/test/example.tpm2-pcr-private2.pem.base64
new file mode 100644
index 0000000000..d21a3d6043
--- /dev/null
+++ b/src/ukify/test/example.tpm2-pcr-private2.pem.base64
@@ -0,0 +1,30 @@
+LS0tLS1CRUdJTiBQUklWQVRFIEtFWS0tLS0tCk1JSUV2QUlCQURBTkJna3Foa2lHOXcwQkFRRUZB
+QVNDQktZd2dnU2lBZ0VBQW9JQkFRQzJ2Nk1oZHg3a3VjUHIKbmtFNFIrY3FnV2Y5T3B1c2h2M2o3
+SG50K08wdi84d2l2T1BFNTlLMHYvRWJOOG94TDZEWUNXU0JCRU4vREJ5MgpMUTYwbldSdHBZN2Ju
+bEcrcEtVeTRvSDRNZXZCR2JqZUhrak9LU3dNYVVWNGs4UmVSSjg4cVZ1U1MxSnVORW1NCmd5SERF
+NGFPNG5ndG5UUFZZdzUydVBIcG1rN0E4VFdXN2lLZE5JWWZWOCtuR1pENXIzRWllekRsUUNORG54
+UkcKdm5uSFZ6VFhZR3RwY2xaeWlJclpVekpBNFFPZnRueXB5UDVrQS94NVM1MU9QeGFxWlA3eGtP
+S0NicUUvZmZvMApFTi9rTno0N0ZoUGUxbVBHUkZZWldHZXg0aWFPdHlLdHhnU1FYYkdlNEVoeVR4
+SjJlT3U4QUVoVklTdjh6UU9nClNtbWx2UGQvQWdNQkFBRUNnZ0VBUUFpRERRRlR3bG96QTVhMmpK
+VnBNdlFYNzF0L1c2TUxTRGMrZS90cWhKU1IKUHlUSGZHR3NhMmdMLy9qNjhHUWJiRWRTUDRDeWM4
+eFhMU0E1bEdESDVVR0svbm9KYzQ3MlVZK2JjYzl3SjMrdgpUcWoyNHNIN2JMZmdQMEVybjhwVXIy
+azZMRmNYSVlWUnRobm1sUmQ4NFFrS2loVVlxZTdsRFFWOXdsZ3V1eHpRCnBmVEtDTWk1bXJlYjIx
+OExHS0QrMUxjVmVYZjExamc3Z2JnMllLZ1dOQ2R3VmIyUzJ5V0hTTjBlT3hPd21kWXIKSUVCekpG
+eEc2MFJxSlJ1RzVIam9iemc2cy9ycUo1THFta3JhUWh6bHFPQVZLblpGOHppbG9vcDhXUXBQY3RN
+cwp0cHBjczhtYkFkWHpoSTVjN0U1VVpDM2NJcEd6SE4raDZLK0F3R3ZEeVFLQmdRRDRBOTdQM29v
+dGhoMHZHQmFWCnZWOXhHTm1YbW5TeUg0b29HcmJvaG1JWkkwVlhZdms5dWViSUJjbDZRMUx4WnN3
+UFpRMVh5TUhpTjY1Z0E1emgKai9HZGcrdDlvcU5CZml0TUFrUTl1aWxvaXlKVWhYblk5REMvRitl
+ZksycEpNbHdkci9qWEttRHpkQUZBVDgyWQpWRmJ3MlpLVi9GNEJNMUtCdDBZN0RPTmlad0tCZ1FD
+OG9kZk0waytqL25VSzQ4TEV2MGtGbVNMdWdnTVlkM3hVCmZibmx0cUhFTVpJZU45OFVHK2hBWEdw
+dU1Ya0JPM2Mwcm5ZRDVXZkNBRzFxT1V2ZTZzdHd6N0VuK3hWdlkvcWEKU3ZTaDRzMzhnZlBIeXhR
+aGJvNWRwQTZUT3pwT0MyVi9rVXBVRUdJSmVVVllhQ05uWXNpUjRWUGVWL1lvR1htSwpQV29KbnAw
+REtRS0JnQlk3cXBheDJXczVVWlp1TDJBZkNOWkhwd0hySzdqb0VPZUZkWTRrdGRpUkM5OUlsUlZP
+CmUvekVZQXBnektldFVtK3kzRjVaTmVCRW81SWg0TWRyc3ZvdTRFWno5UFNqRGRpVGYzQ1ZKcThq
+Z2VGWDBkTjgKR0g2WTh2K1cwY0ZjRFZ2djhYdkFaYzZOUUt0Mk8vVUM0b1JXek1nN1JtWVBKcjlR
+SWJDYmVDclRBb0dBTjdZbApJbDFMSUVoYkVTaExzZ2c4N09aWnBzL0hVa2FYOWV4Y0p6aFZkcmlk
+UzBkOUgxZE90Uk9XYTQwNUMrQWdTUEx0CjhDQ2xFR3RINVlPZW9Pdi93Z1hWY05WN2N6YTRJVEhh
+SnFYeDZJNEpEZzB3bU44cU5RWHJPQmphRTRyU0kyY3AKNk1JZDhtWmEwTTJSQjB2cHFRdy8xUDl0
+dUZJdHoySnNHd001cEdFQ2dZQVVnQVV3WENBcEtZVkZFRmxHNlBhYwpvdTBhdzdGNm1aMi9NNUcv
+ek9tMHFDYnNXdGFNU09TdUEvNmlVOXB0NDBaWUFONFUvd2ZxbncyVkVoRnA3dzFNCnpZWmJCRDBx
+ZVlkcDRmc1NuWXFMZmJBVmxQLzB6dmEzdkwwMlJFa25WalBVSnAvaGpKVWhBK21WN252VDZ5VjQK
+cTg4SWVvOEx3Q1c1c2Jtd2lyU3Btdz09Ci0tLS0tRU5EIFBSSVZBVEUgS0VZLS0tLS0K
diff --git a/src/ukify/test/example.tpm2-pcr-public.pem.base64 b/src/ukify/test/example.tpm2-pcr-public.pem.base64
new file mode 100644
index 0000000000..728a0f5362
--- /dev/null
+++ b/src/ukify/test/example.tpm2-pcr-public.pem.base64
@@ -0,0 +1,8 @@
+LS0tLS1CRUdJTiBQVUJMSUMgS0VZLS0tLS0KTUlJQklqQU5CZ2txaGtpRzl3MEJBUUVGQUFPQ0FR
+OEFNSUlCQ2dLQ0FRRUF1Wi9LbXFPVElEeUVGckFNbkhjTAo2YnArek9Na0NLQlA2Kzh3QlM1bW56
+MXEyZThHMllnZGpSZWRWaHZDZko4Z2dRZTl3eXEzMmNwUGJHZ01GbEowCkJwTGJXcUJNMWh1a1JO
+KzdzRC9TVk56bDd5RXVkR3JQeVI3aHVrVG0ydWxnamZHYnpPM1hZNkM5U1JYbTZVU0sKK1ZmK2xQ
+aXkxNUViVEdsdDBiOHppMThqRERuZC9CdFlCclZVeHE2TGMrWHJWL2pBbEVvalUyZy9WTzFnM3Jw
+WApyb3RrNFBrZXkzWVNNZTN1UGFSME44TTVFcXNVL0I0NFVyMHhJeHpIa2V0dEloeEhxSjNPNWRi
+b0k3SEdhVFNoCnJ6TUpydjBvNWwyYzBTVGIrVFVpcXFSSUFXTHhhblNzRTcxdk5Zc3lBS084MmRp
+OCtObDZKN0NHNzk1Slg0eTUKbndJREFRQUIKLS0tLS1FTkQgUFVCTElDIEtFWS0tLS0tCg==
diff --git a/src/ukify/test/example.tpm2-pcr-public2.pem.base64 b/src/ukify/test/example.tpm2-pcr-public2.pem.base64
new file mode 100644
index 0000000000..44bb3ee9ac
--- /dev/null
+++ b/src/ukify/test/example.tpm2-pcr-public2.pem.base64
@@ -0,0 +1,8 @@
+LS0tLS1CRUdJTiBQVUJMSUMgS0VZLS0tLS0KTUlJQklqQU5CZ2txaGtpRzl3MEJBUUVGQUFPQ0FR
+OEFNSUlCQ2dLQ0FRRUF0citqSVhjZTVMbkQ2NTVCT0VmbgpLb0ZuL1RxYnJJYjk0K3g1N2ZqdEwv
+L01JcnpqeE9mU3RML3hHemZLTVMrZzJBbGtnUVJEZnd3Y3RpME90SjFrCmJhV08yNTVSdnFTbE11
+S0IrREhyd1JtNDNoNUl6aWtzREdsRmVKUEVYa1NmUEtsYmtrdFNialJKaklNaHd4T0cKanVKNExa
+MHoxV01PZHJqeDZacE93UEUxbHU0aW5UU0dIMWZQcHhtUSthOXhJbnN3NVVBalE1OFVScjU1eDFj
+MAoxMkJyYVhKV2NvaUsyVk15UU9FRG43WjhxY2orWkFQOGVVdWRUajhXcW1UKzhaRGlnbTZoUDMz
+Nk5CRGY1RGMrCk94WVQzdFpqeGtSV0dWaG5zZUltanJjaXJjWUVrRjJ4bnVCSWNrOFNkbmpydkFC
+SVZTRXIvTTBEb0VwcHBiejMKZndJREFRQUIKLS0tLS1FTkQgUFVCTElDIEtFWS0tLS0tCg==
diff --git a/src/ukify/test/meson.build b/src/ukify/test/meson.build
new file mode 100644
index 0000000000..e39178f892
--- /dev/null
+++ b/src/ukify/test/meson.build
@@ -0,0 +1,7 @@
+# SPDX-License-Identifier: LGPL-2.1-or-later
+
+if want_ukify and want_tests != 'false'
+ test('test-ukify',
+ files('test_ukify.py'),
+ env : test_env)
+endif
diff --git a/src/ukify/test/setup.cfg b/src/ukify/test/setup.cfg
new file mode 100644
index 0000000000..1f655da834
--- /dev/null
+++ b/src/ukify/test/setup.cfg
@@ -0,0 +1,2 @@
+[tool:pytest]
+addopts = --flakes
diff --git a/src/ukify/test/test_ukify.py b/src/ukify/test/test_ukify.py
new file mode 100755
index 0000000000..292540bbde
--- /dev/null
+++ b/src/ukify/test/test_ukify.py
@@ -0,0 +1,372 @@
+#!/usr/bin/env python3
+# SPDX-License-Identifier: LGPL-2.1+
+
+# pylint: disable=missing-docstring,redefined-outer-name,invalid-name
+# pylint: disable=unused-import,import-outside-toplevel,useless-else-on-loop
+# pylint: disable=consider-using-with,wrong-import-position,unspecified-encoding
+
+import base64
+import json
+import os
+import pathlib
+import re
+import shutil
+import subprocess
+import sys
+import tempfile
+
+try:
+ import pytest
+except ImportError:
+ sys.exit(77)
+
+# We import ukify.py, which is a template file. But only __version__ is
+# substituted, which we don't care about here. Having the .py suffix makes it
+# easier to import the file.
+sys.path.append(os.path.dirname(__file__) + '/..')
+import ukify
+
+
+def test_guess_efi_arch():
+ arch = ukify.guess_efi_arch()
+ assert arch in ukify.EFI_ARCHES
+
+def test_shell_join():
+ assert ukify.shell_join(['a', 'b', ' ']) == "a b ' '"
+
+def test_round_up():
+ assert ukify.round_up(0) == 0
+ assert ukify.round_up(4095) == 4096
+ assert ukify.round_up(4096) == 4096
+ assert ukify.round_up(4097) == 8192
+
+def test_parse_args_minimal():
+ opts = ukify.parse_args('arg1 arg2'.split())
+ assert opts.linux == pathlib.Path('arg1')
+ assert opts.initrd == pathlib.Path('arg2')
+ assert opts.os_release in (pathlib.Path('/etc/os-release'),
+ pathlib.Path('/usr/lib/os-release'))
+
+def test_parse_args_many():
+ opts = ukify.parse_args(
+ ['/ARG1', '///ARG2',
+ '--cmdline=a b c',
+ '--os-release=K1=V1\nK2=V2',
+ '--devicetree=DDDDTTTT',
+ '--splash=splash',
+ '--pcrpkey=PATH',
+ '--uname=1.2.3',
+ '--stub=STUBPATH',
+ '--pcr-private-key=PKEY1',
+ '--pcr-public-key=PKEY2',
+ '--pcr-banks=SHA1,SHA256',
+ '--signing-engine=ENGINE',
+ '--secureboot-private-key=SBKEY',
+ '--secureboot-certificate=SBCERT',
+ '--sign-kernel',
+ '--no-sign-kernel',
+ '--tools=TOOLZ///',
+ '--output=OUTPUT',
+ '--measure',
+ '--no-measure',
+ ])
+ assert opts.linux == pathlib.Path('/ARG1')
+ assert opts.initrd == pathlib.Path('/ARG2')
+ assert opts.os_release == 'K1=V1\nK2=V2'
+ assert opts.devicetree == pathlib.Path('DDDDTTTT')
+ assert opts.splash == pathlib.Path('splash')
+ assert opts.pcrpkey == pathlib.Path('PATH')
+ assert opts.uname == '1.2.3'
+ assert opts.stub == pathlib.Path('STUBPATH')
+ assert opts.pcr_private_keys == [pathlib.Path('PKEY1')]
+ assert opts.pcr_public_keys == [pathlib.Path('PKEY2')]
+ assert opts.pcr_banks == ['SHA1', 'SHA256']
+ assert opts.signing_engine == 'ENGINE'
+ assert opts.sb_key == 'SBKEY'
+ assert opts.sb_cert == 'SBCERT'
+ assert opts.sign_kernel is False
+ assert opts.tools == pathlib.Path('TOOLZ/')
+ assert opts.output == pathlib.Path('OUTPUT')
+ assert opts.measure is False
+
+def test_parse_sections():
+ opts = ukify.parse_args(
+ ['/ARG1', '/ARG2',
+ '--section=test:TESTTESTTEST',
+ '--section=test2:@FILE',
+ ])
+
+ assert opts.linux == pathlib.Path('/ARG1')
+ assert opts.initrd == pathlib.Path('/ARG2')
+ assert len(opts.sections) == 2
+
+ assert opts.sections[0].name == 'test'
+ assert isinstance(opts.sections[0].content, pathlib.Path)
+ assert opts.sections[0].tmpfile
+ assert opts.sections[0].offset is None
+ assert opts.sections[0].measure is False
+
+ assert opts.sections[1].name == 'test2'
+ assert opts.sections[1].content == pathlib.Path('FILE')
+ assert opts.sections[1].tmpfile is None
+ assert opts.sections[1].offset is None
+ assert opts.sections[1].measure is False
+
+def test_help(capsys):
+ with pytest.raises(SystemExit):
+ ukify.parse_args(['--help'])
+ out = capsys.readouterr()
+ assert '--section' in out.out
+ assert not out.err
+
+def test_help_error(capsys):
+ with pytest.raises(SystemExit):
+ ukify.parse_args(['a', 'b', '--no-such-option'])
+ out = capsys.readouterr()
+ assert not out.out
+ assert '--no-such-option' in out.err
+ assert len(out.err.splitlines()) == 1
+
+@pytest.fixture(scope='session')
+def kernel_initrd():
+ try:
+ text = subprocess.check_output(['bootctl', 'list', '--json=short'],
+ text=True)
+ except subprocess.CalledProcessError:
+ return None
+
+ items = json.loads(text)
+
+ for item in items:
+ try:
+ linux = f"{item['root']}{item['linux']}"
+ initrd = f"{item['root']}{item['initrd'][0]}"
+ except (KeyError, IndexError):
+ pass
+ return [linux, initrd]
+ else:
+ return None
+
+def test_check_splash():
+ try:
+ # pyflakes: noqa
+ import PIL # noqa
+ except ImportError:
+ pytest.skip('PIL not available')
+
+ with pytest.raises(OSError):
+ ukify.check_splash(os.devnull)
+
+def test_basic_operation(kernel_initrd, tmpdir):
+ if kernel_initrd is None:
+ pytest.skip('linux+initrd not found')
+
+ output = f'{tmpdir}/basic.efi'
+ opts = ukify.parse_args(kernel_initrd + [f'--output={output}'])
+ try:
+ ukify.check_inputs(opts)
+ except OSError as e:
+ pytest.skip(str(e))
+
+ ukify.make_uki(opts)
+
+ # let's check that objdump likes the resulting file
+ subprocess.check_output(['objdump', '-h', output])
+
+def test_sections(kernel_initrd, tmpdir):
+ if kernel_initrd is None:
+ pytest.skip('linux+initrd not found')
+
+ output = f'{tmpdir}/basic.efi'
+ opts = ukify.parse_args([
+ *kernel_initrd,
+ f'--output={output}',
+ '--uname=1.2.3',
+ '--cmdline=ARG1 ARG2 ARG3',
+ '--os-release=K1=V1\nK2=V2\n',
+ '--section=.test:CONTENTZ',
+ ])
+
+ try:
+ ukify.check_inputs(opts)
+ except OSError as e:
+ pytest.skip(str(e))
+
+ ukify.make_uki(opts)
+
+ # let's check that objdump likes the resulting file
+ dump = subprocess.check_output(['objdump', '-h', output], text=True)
+
+ for sect in 'text osrel cmdline linux initrd uname test'.split():
+ assert re.search(fr'^\s*\d+\s+.{sect}\s+0', dump, re.MULTILINE)
+
+
+def unbase64(filename):
+ tmp = tempfile.NamedTemporaryFile()
+ base64.decode(filename.open('rb'), tmp)
+ tmp.flush()
+ return tmp
+
+
+def test_efi_signing(kernel_initrd, tmpdir):
+ if kernel_initrd is None:
+ pytest.skip('linux+initrd not found')
+ if not shutil.which('sbsign'):
+ pytest.skip('sbsign not found')
+
+ ourdir = pathlib.Path(__file__).parent
+ cert = unbase64(ourdir / 'example.signing.crt.base64')
+ key = unbase64(ourdir / 'example.signing.key.base64')
+
+ output = f'{tmpdir}/signed.efi'
+ opts = ukify.parse_args([
+ *kernel_initrd,
+ f'--output={output}',
+ '--uname=1.2.3',
+ '--cmdline=ARG1 ARG2 ARG3',
+ f'--secureboot-certificate={cert.name}',
+ f'--secureboot-private-key={key.name}',
+ ])
+
+ try:
+ ukify.check_inputs(opts)
+ except OSError as e:
+ pytest.skip(str(e))
+
+ ukify.make_uki(opts)
+
+ if shutil.which('sbverify'):
+ # let's check that sbverify likes the resulting file
+ dump = subprocess.check_output([
+ 'sbverify',
+ '--cert', cert.name,
+ output,
+ ], text=True)
+
+ assert 'Signature verification OK' in dump
+
+def test_pcr_signing(kernel_initrd, tmpdir):
+ if kernel_initrd is None:
+ pytest.skip('linux+initrd not found')
+ if os.getuid() != 0:
+ pytest.skip('must be root to access tpm2')
+ if subprocess.call(['systemd-creds', 'has-tpm2', '-q']) != 0:
+ pytest.skip('tpm2 is not available')
+
+ ourdir = pathlib.Path(__file__).parent
+ pub = unbase64(ourdir / 'example.tpm2-pcr-public.pem.base64')
+ priv = unbase64(ourdir / 'example.tpm2-pcr-private.pem.base64')
+
+ output = f'{tmpdir}/signed.efi'
+ opts = ukify.parse_args([
+ *kernel_initrd,
+ f'--output={output}',
+ '--uname=1.2.3',
+ '--cmdline=ARG1 ARG2 ARG3',
+ '--os-release=ID=foobar\n',
+ '--pcr-banks=sha1', # use sha1 as that is most likely to be supported
+ f'--pcrpkey={pub.name}',
+ f'--pcr-public-key={pub.name}',
+ f'--pcr-private-key={priv.name}',
+ ])
+
+ try:
+ ukify.check_inputs(opts)
+ except OSError as e:
+ pytest.skip(str(e))
+
+ ukify.make_uki(opts)
+
+ # let's check that objdump likes the resulting file
+ dump = subprocess.check_output(['objdump', '-h', output], text=True)
+
+ for sect in 'text osrel cmdline linux initrd uname pcrsig'.split():
+ assert re.search(fr'^\s*\d+\s+.{sect}\s+0', dump, re.MULTILINE)
+
+ # objcopy fails when called without an output argument (EPERM).
+ # It also fails when called with /dev/null (file truncated).
+ # It also fails when called with /dev/zero (because it reads the
+ # output file, infinitely in this case.)
+ # So let's just call it with a dummy output argument.
+ subprocess.check_call([
+ 'objcopy',
+ *(f'--dump-section=.{n}={tmpdir}/out.{n}' for n in (
+ 'pcrpkey', 'pcrsig', 'osrel', 'uname', 'cmdline')),
+ output,
+ tmpdir / 'dummy',
+ ],
+ text=True)
+
+ assert open(tmpdir / 'out.pcrpkey').read() == open(pub.name).read()
+ assert open(tmpdir / 'out.osrel').read() == 'ID=foobar\n'
+ assert open(tmpdir / 'out.uname').read() == '1.2.3'
+ assert open(tmpdir / 'out.cmdline').read() == 'ARG1 ARG2 ARG3'
+ sig = open(tmpdir / 'out.pcrsig').read()
+ sig = json.loads(sig)
+ assert list(sig.keys()) == ['sha1']
+ assert len(sig['sha1']) == 4 # four items for four phases
+
+def test_pcr_signing2(kernel_initrd, tmpdir):
+ if kernel_initrd is None:
+ pytest.skip('linux+initrd not found')
+ if os.getuid() != 0:
+ pytest.skip('must be root to access tpm2')
+ if subprocess.call(['systemd-creds', 'has-tpm2', '-q']) != 0:
+ pytest.skip('tpm2 is not available')
+
+ ourdir = pathlib.Path(__file__).parent
+ pub = unbase64(ourdir / 'example.tpm2-pcr-public.pem.base64')
+ priv = unbase64(ourdir / 'example.tpm2-pcr-private.pem.base64')
+ pub2 = unbase64(ourdir / 'example.tpm2-pcr-public2.pem.base64')
+ priv2 = unbase64(ourdir / 'example.tpm2-pcr-private2.pem.base64')
+
+ output = f'{tmpdir}/signed.efi'
+ opts = ukify.parse_args([
+ *kernel_initrd,
+ f'--output={output}',
+ '--uname=1.2.3',
+ '--cmdline=ARG1 ARG2 ARG3',
+ '--os-release=ID=foobar\n',
+ '--pcr-banks=sha1', # use sha1 as that is most likely to be supported
+ f'--pcrpkey={pub2.name}',
+ f'--pcr-public-key={pub.name}',
+ f'--pcr-private-key={priv.name}',
+ '--phases=enter-initrd enter-initrd:leave-initrd',
+ f'--pcr-public-key={pub2.name}',
+ f'--pcr-private-key={priv2.name}',
+ '--phases=sysinit ready shutdown final', # yes, those phase paths are not reachable
+ ])
+
+ try:
+ ukify.check_inputs(opts)
+ except OSError as e:
+ pytest.skip(str(e))
+
+ ukify.make_uki(opts)
+
+ # let's check that objdump likes the resulting file
+ dump = subprocess.check_output(['objdump', '-h', output], text=True)
+
+ for sect in 'text osrel cmdline linux initrd uname pcrsig'.split():
+ assert re.search(fr'^\s*\d+\s+.{sect}\s+0', dump, re.MULTILINE)
+
+ subprocess.check_call([
+ 'objcopy',
+ *(f'--dump-section=.{n}={tmpdir}/out.{n}' for n in (
+ 'pcrpkey', 'pcrsig', 'osrel', 'uname', 'cmdline')),
+ output,
+ tmpdir / 'dummy',
+ ],
+ text=True)
+
+ assert open(tmpdir / 'out.pcrpkey').read() == open(pub2.name).read()
+ assert open(tmpdir / 'out.osrel').read() == 'ID=foobar\n'
+ assert open(tmpdir / 'out.uname').read() == '1.2.3'
+ assert open(tmpdir / 'out.cmdline').read() == 'ARG1 ARG2 ARG3'
+ sig = open(tmpdir / 'out.pcrsig').read()
+ sig = json.loads(sig)
+ assert list(sig.keys()) == ['sha1']
+ assert len(sig['sha1']) == 6 # six items for six phases paths
+
+if __name__ == '__main__':
+ pytest.main([__file__, '-v'])