Simon Glass | c3fe97f | 2023-03-02 17:02:45 -0700 | [diff] [blame] | 1 | # SPDX-License-Identifier: GPL-2.0+ |
| 2 | # Copyright 2022 Google LLC |
| 3 | # |
| 4 | """Bintool implementation for openssl |
| 5 | |
| 6 | openssl provides a number of features useful for signing images |
| 7 | |
| 8 | Documentation is at https://www.coreboot.org/CBFS |
| 9 | |
| 10 | Source code is at https://www.openssl.org/ |
| 11 | """ |
| 12 | |
| 13 | import hashlib |
| 14 | |
| 15 | from binman import bintool |
| 16 | from u_boot_pylib import tools |
| 17 | |
| 18 | class 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 ] |
| 51 | distinguished_name = req_distinguished_name |
| 52 | x509_extensions = v3_ca |
| 53 | prompt = no |
| 54 | dirstring_type = nobmp |
| 55 | |
| 56 | [ req_distinguished_name ] |
| 57 | CN = {cert_fname} |
| 58 | |
| 59 | [ v3_ca ] |
| 60 | basicConstraints = CA:true |
| 61 | 1.3.6.1.4.1.294.1.3 = ASN1:SEQUENCE:swrv |
| 62 | 1.3.6.1.4.1.294.1.34 = ASN1:SEQUENCE:sysfw_image_integrity |
| 63 | |
| 64 | [ swrv ] |
| 65 | swrv = INTEGER:{revision} |
| 66 | |
| 67 | [ sysfw_image_integrity ] |
| 68 | shaType = OID:2.16.840.1.101.3.4.2.3 |
| 69 | shaValue = FORMAT:HEX,OCT:{hashval} |
| 70 | imageSize = 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') |