Springe zum Hauptinhalt

Really Verifying LineageOS Build Authenticity

Re-establish the chain of trust after the way to verify public builds has changed

LineageOS Logo (Quelle: Wikipedia)

The Lineage team has changed the way they sign the public builds. Unfortunately this change is not yet well communicated: The "Verifying Build Authenticity" wiki page as of today only describes the old method. Well, after some "startpaging" (how I call searching the internet) I found a patch and a pull-request describing the new method.

Formerly the Java-based "keytool" was used, which prints out some checksums the user has to compare her/himself. The new tool is Python-based and just says "verified successfully".

While this user-friendly, it leaves open how to verify the provided public key? How to build a chain of trust from the checksums published on the wiki to the public key included in thenew tool'sarchive? Here is how-to.

The basic idea is to extract the public key from an installation archive we could verify using the old method and check if the public key in the new tool's archive matches the one used in the old installation archive.

In detail:

  1. Download and verify aninstallationarchive using the old method, e.g. lineage-14.1-20180803-nightly-i9100-signed.zip

  2. Get the checksums from https://wiki.lineageos.org/verifying-builds.html respective commit 8dca5e117efc77be9bfcfeb39c6f69c1dce041ed (which as far as I can tell was the very first commit of this wiki-page and thus shall be our trust anchor). Define shell-variables to have them at hand:

    You may want to pick the values from the aforementioned links so you don't need to trust me.

  3. Extract the X.509 certificate from the installation archive
    unzip -j lineage-14.1-20180803-nightly-i9100-signed.zip META-INF/com/android/otacert
  4. This will extract the certificate otacert into the current directory (unzip -j means: junk paths).

  5. Manually verify the fingerprints using different methods
    echo $SHA1 | tr -d ':' ; \
    openssl x509 -fingerprint -noout -in otacert | sed 's/.*=//' | tr -d ':' ; \
    openssl x509 -outform DER -in otacert | sha1sum --binary | tr '[:lower:]' '[:upper:]'
    echo $SHA256 | tr -d ':'  ; \
    openssl x509 -outform DER -in otacert | sha256sum --binary | tr '[:lower:]' '[:upper:]'

    Line 1 will print the SHA1 check-sum picked from the wiki with colons removed. It's easer to remove the colons then inserting them in line 3. Line 2 will print the SHA1 check-sum using openssl x509 -fingerprint, again colons removed. This line is basically to verify our line 3 is correct. And line 3 calculates the SHA1 check-sum using the tool sha1sum.

    Lines 5 and 6 basically do the same, just using SHA256 check-sums. I did not find a way to make openssl x509 -fingerprint use SHA256 check-sums. This is why this step is missing here and why I'm using the external tools at all.

  6. Now we have verified the certificate within the installation archive is the correct one. Fine.

  7. Extract the public key from the certificate and convert into format used by the public key provided in the new tool's archive:

    openssl x509 -in otacert -noout -pubkey | openssl rsa -pubin -RSAPublicKey_out > otacert.pub
  8. Check if the two files are the same

    diff otacert.pub lineageos_pubkey && echo okay
  9. q.e.d.

For reference, here is the otacert.pub file:

Portrait von Hartmut Goebel
Hartmut Goebel
Diplom-Informatiker, CISSP, CSSLP, ISO 27001 Lead Implementer

Haben Sie noch Fragen?
Anruf oder Mail genügt:
Telefon:   +49 871 6606-318
Mobil:   +49 175 29 78 072
E-Mail:   h.goebel@goebel-consult.de