binman: Support generation of x509 certificates
And a new entry type which supports generation of x509 certificates.
This uses a new 'openssl' btool with just one operation so far.
Signed-off-by: Simon Glass <sjg@chromium.org>
diff --git a/tools/binman/btool/openssl.py b/tools/binman/btool/openssl.py
new file mode 100644
index 0000000..3a4dbdd
--- /dev/null
+++ b/tools/binman/btool/openssl.py
@@ -0,0 +1,94 @@
+# SPDX-License-Identifier: GPL-2.0+
+# Copyright 2022 Google LLC
+#
+"""Bintool implementation for openssl
+
+openssl provides a number of features useful for signing images
+
+Documentation is at https://www.coreboot.org/CBFS
+
+Source code is at https://www.openssl.org/
+"""
+
+import hashlib
+
+from binman import bintool
+from u_boot_pylib import tools
+
+class Bintoolopenssl(bintool.Bintool):
+ """openssl tool
+
+ This bintool supports creating new openssl certificates.
+
+ It also supports fetching a binary openssl
+
+ Documentation about openssl is at https://www.openssl.org/
+ """
+ def __init__(self, name):
+ super().__init__(
+ name, 'openssl cryptography toolkit',
+ version_regex=r'OpenSSL (.*) \(', version_args='version')
+
+ def x509_cert(self, cert_fname, input_fname, key_fname, cn, revision,
+ config_fname):
+ """Create a certificate
+
+ Args:
+ cert_fname (str): Filename of certificate to create
+ input_fname (str): Filename containing data to sign
+ key_fname (str): Filename of .pem file
+ cn (str): Common name
+ revision (int): Revision number
+ config_fname (str): Filename to write fconfig into
+
+ Returns:
+ str: Tool output
+ """
+ indata = tools.read_file(input_fname)
+ hashval = hashlib.sha512(indata).hexdigest()
+ with open(config_fname, 'w', encoding='utf-8') as outf:
+ print(f'''[ req ]
+distinguished_name = req_distinguished_name
+x509_extensions = v3_ca
+prompt = no
+dirstring_type = nobmp
+
+[ req_distinguished_name ]
+CN = {cert_fname}
+
+[ v3_ca ]
+basicConstraints = CA:true
+1.3.6.1.4.1.294.1.3 = ASN1:SEQUENCE:swrv
+1.3.6.1.4.1.294.1.34 = ASN1:SEQUENCE:sysfw_image_integrity
+
+[ swrv ]
+swrv = INTEGER:{revision}
+
+[ sysfw_image_integrity ]
+shaType = OID:2.16.840.1.101.3.4.2.3
+shaValue = FORMAT:HEX,OCT:{hashval}
+imageSize = INTEGER:{len(indata)}
+''', file=outf)
+ args = ['req', '-new', '-x509', '-key', key_fname, '-nodes',
+ '-outform', 'DER', '-out', cert_fname, '-config', config_fname,
+ '-sha512']
+ return self.run_cmd(*args)
+
+ def fetch(self, method):
+ """Fetch handler for openssl
+
+ This installs the openssl package using the apt utility.
+
+ Args:
+ method (FETCH_...): Method to use
+
+ Returns:
+ True if the file was fetched and now installed, None if a method
+ other than FETCH_BIN was requested
+
+ Raises:
+ Valuerror: Fetching could not be completed
+ """
+ if method != bintool.FETCH_BIN:
+ return None
+ return self.apt_install('openssl')