Skip to content

Commit

Permalink
mkosi: port to python-cryptography
Browse files Browse the repository at this point in the history
This is mostly based on Jörg Behrmann's (@behrmann) work.
  • Loading branch information
poettering committed Sep 13, 2021
1 parent 993cab1 commit 0104c11
Showing 1 changed file with 28 additions and 28 deletions.
56 changes: 28 additions & 28 deletions mkosi/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -3700,12 +3700,6 @@ def insert_verity(
)


PKCS7_NOCERTS = 0x2 # Don't include signature certificates in result
PKCS7_DETACHED = 0x40 # Don't include data to sign in result
PKCS7_BINARY = 0x80 # Don't mangle newlines for MIME canonical format
PKCS7_NOATTR = 0x100 # Don't include signature time, … in result


def make_verity_sig(
args: CommandLineArguments, root_hash: Optional[str], do_run_build_script: bool, for_cache: bool
) -> Tuple[Optional[BinaryIO], Optional[bytes], Optional[str]]:
Expand All @@ -3717,35 +3711,41 @@ def make_verity_sig(

assert root_hash is not None

try:
from OpenSSL import crypto
except ImportError:
die("Python OpenSSL package is not installed.");
from cryptography import x509
from cryptography.hazmat.primitives import hashes
from cryptography.hazmat.primitives import serialization
from cryptography.hazmat.primitives.serialization import pkcs7

with complete_step("Signing verity root hash…"):

key = crypto.load_privatekey(crypto.FILETYPE_PEM, args.secure_boot_key.read_bytes())
certificate = crypto.load_certificate(crypto.FILETYPE_PEM, args.secure_boot_certificate.read_bytes())

# Note that the library returns the SHA256 digest in an
# uppecase format with : as byte separators. Let's convert to
# classic lowercase series of unseparated hex digits
fingerprint = certificate.digest("sha256").decode("ascii").replace(":", "").lower()

bio_in = crypto._new_mem_buf(root_hash.encode("utf-8"))
pkcs7 = crypto._lib.PKCS7_sign(
certificate._x509,
key._pkey,
crypto._ffi.NULL,
bio_in,
PKCS7_DETACHED | PKCS7_NOCERTS | PKCS7_NOATTR | PKCS7_BINARY,
key = serialization.load_pem_private_key(args.secure_boot_key.read_bytes(), password=None)
certificate = x509.load_pem_x509_certificate(args.secure_boot_certificate.read_bytes())

fingerprint = certificate.fingerprint(hashes.SHA256()).hex()

sigbytes = pkcs7.PKCS7SignatureBuilder().add_signer(
certificate,
key,
hashes.SHA256()
).set_data(
root_hash.encode("utf-8")
).sign(
options=[
pkcs7.PKCS7Options.DetachedSignature,
pkcs7.PKCS7Options.NoCerts,
pkcs7.PKCS7Options.NoAttributes,
pkcs7.PKCS7Options.Binary
],
encoding=serialization.Encoding.DER
)
bio_out = crypto._new_mem_buf()
crypto._lib.i2d_PKCS7_bio(bio_out, pkcs7)
sigbytes = crypto._bio_to_string(bio_out)

# We base64 the DER result, because we want to include it in
# JSON. This is not PEM (i.e. not header/footer line, no line
# breaks), but just base64 encapsulated DER).
b64encoded = base64.b64encode(sigbytes).decode("ascii")

print(b64encoded)

# This is supposed to be extensible, but care should be taken
# not to include unprotected data here.
j = json.dumps({
Expand Down

0 comments on commit 0104c11

Please sign in to comment.