1# SPDX-License-Identifier: GPL-2.0+ 2# Copyright 2022 Google LLC 3# 4"""Bintool implementation for openssl 5 6openssl provides a number of features useful for signing images 7 8Documentation is at https://www.coreboot.org/CBFS 9 10Source code is at https://www.openssl.org/ 11""" 12 13import hashlib 14 15from binman import bintool 16from u_boot_pylib import tools 17 18class Bintoolopenssl(bintool.Bintool): 19 """openssl tool 20 21 This bintool supports creating new openssl certificates. 22 23 It also supports fetching a binary openssl 24 25 Documentation about openssl is at https://www.openssl.org/ 26 """ 27 def __init__(self, name): 28 super().__init__( 29 name, 'openssl cryptography toolkit', 30 version_regex=r'OpenSSL (.*) \(', version_args='version') 31 32 def x509_cert(self, cert_fname, input_fname, key_fname, cn, revision, 33 config_fname): 34 """Create a certificate 35 36 Args: 37 cert_fname (str): Filename of certificate to create 38 input_fname (str): Filename containing data to sign 39 key_fname (str): Filename of .pem file 40 cn (str): Common name 41 revision (int): Revision number 42 config_fname (str): Filename to write fconfig into 43 44 Returns: 45 str: Tool output 46 """ 47 indata = tools.read_file(input_fname) 48 hashval = hashlib.sha512(indata).hexdigest() 49 with open(config_fname, 'w', encoding='utf-8') as outf: 50 print(f'''[ req ] 51distinguished_name = req_distinguished_name 52x509_extensions = v3_ca 53prompt = no 54dirstring_type = nobmp 55 56[ req_distinguished_name ] 57CN = {cert_fname} 58 59[ v3_ca ] 60basicConstraints = CA:true 611.3.6.1.4.1.294.1.3 = ASN1:SEQUENCE:swrv 621.3.6.1.4.1.294.1.34 = ASN1:SEQUENCE:sysfw_image_integrity 63 64[ swrv ] 65swrv = INTEGER:{revision} 66 67[ sysfw_image_integrity ] 68shaType = OID:2.16.840.1.101.3.4.2.3 69shaValue = FORMAT:HEX,OCT:{hashval} 70imageSize = INTEGER:{len(indata)} 71''', file=outf) 72 args = ['req', '-new', '-x509', '-key', key_fname, '-nodes', 73 '-outform', 'DER', '-out', cert_fname, '-config', config_fname, 74 '-sha512'] 75 return self.run_cmd(*args) 76 77 def fetch(self, method): 78 """Fetch handler for openssl 79 80 This installs the openssl package using the apt utility. 81 82 Args: 83 method (FETCH_...): Method to use 84 85 Returns: 86 True if the file was fetched and now installed, None if a method 87 other than FETCH_BIN was requested 88 89 Raises: 90 Valuerror: Fetching could not be completed 91 """ 92 if method != bintool.FETCH_BIN: 93 return None 94 return self.apt_install('openssl') 95