#!/usr/bin/env python3

"""Mbed TLS configuration file manipulation library and tool

Basic usage, to read the Mbed TLS or Mbed Crypto configuration:
    config = ConfigFile()
    if 'MBEDTLS_RSA_C' in config: print('RSA is enabled')
"""

## Copyright The Mbed TLS Contributors
## SPDX-License-Identifier: Apache-2.0
##
## Licensed under the Apache License, Version 2.0 (the "License"); you may
## not use this file except in compliance with the License.
## You may obtain a copy of the License at
##
## http://www.apache.org/licenses/LICENSE-2.0
##
## Unless required by applicable law or agreed to in writing, software
## distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
## WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
## See the License for the specific language governing permissions and
## limitations under the License.

import os
import re

class Setting:
    """Representation of one Mbed TLS mbedtls_config.h setting.

    Fields:
    * name: the symbol name ('MBEDTLS_xxx').
    * value: the value of the macro. The empty string for a plain #define
      with no value.
    * active: True if name is defined, False if a #define for name is
      present in mbedtls_config.h but commented out.
    * section: the name of the section that contains this symbol.
    """
    # pylint: disable=too-few-public-methods
    def __init__(self, active, name, value='', section=None):
        self.active = active
        self.name = name
        self.value = value
        self.section = section

class Config:
    """Representation of the Mbed TLS configuration.

    In the documentation of this class, a symbol is said to be *active*
    if there is a #define for it that is not commented out, and *known*
    if there is a #define for it whether commented out or not.

    This class supports the following protocols:
    * `name in config` is `True` if the symbol `name` is active, `False`
      otherwise (whether `name` is inactive or not known).
    * `config[name]` is the value of the macro `name`. If `name` is inactive,
      raise `KeyError` (even if `name` is known).
    * `config[name] = value` sets the value associated to `name`. `name`
      must be known, but does not need to be set. This does not cause
      name to become set.
    """

    def __init__(self):
        self.settings = {}

    def __contains__(self, name):
        """True if the given symbol is active (i.e. set).

        False if the given symbol is not set, even if a definition
        is present but commented out.
        """
        return name in self.settings and self.settings[name].active

    def all(self, *names):
        """True if all the elements of names are active (i.e. set)."""
        return all(self.__contains__(name) for name in names)

    def any(self, *names):
        """True if at least one symbol in names are active (i.e. set)."""
        return any(self.__contains__(name) for name in names)

    def known(self, name):
        """True if a #define for name is present, whether it's commented out or not."""
        return name in self.settings

    def __getitem__(self, name):
        """Get the value of name, i.e. what the preprocessor symbol expands to.

        If name is not known, raise KeyError. name does not need to be active.
        """
        return self.settings[name].value

    def get(self, name, default=None):
        """Get the value of name. If name is inactive (not set), return default.

        If a #define for name is present and not commented out, return
        its expansion, even if this is the empty string.

        If a #define for name is present but commented out, return default.
        """
        if name in self.settings:
            return self.settings[name].value
        else:
            return default

    def __setitem__(self, name, value):
        """If name is known, set its value.

        If name is not known, raise KeyError.
        """
        self.settings[name].value = value

    def set(self, name, value=None):
        """Set name to the given value and make it active.

        If value is None and name is already known, don't change its value.
        If value is None and name is not known, set its value to the empty
        string.
        """
        if name in self.settings:
            if value is not None:
                self.settings[name].value = value
            self.settings[name].active = True
        else:
            self.settings[name] = Setting(True, name, value=value)

    def unset(self, name):
        """Make name unset (inactive).

        name remains known if it was known before.
        """
        if name not in self.settings:
            return
        self.settings[name].active = False

    def adapt(self, adapter):
        """Run adapter on each known symbol and (de)activate it accordingly.

        `adapter` must be a function that returns a boolean. It is called as
        `adapter(name, active, section)` for each setting, where `active` is
        `True` if `name` is set and `False` if `name` is known but unset,
        and `section` is the name of the section containing `name`. If
        `adapter` returns `True`, then set `name` (i.e. make it active),
        otherwise unset `name` (i.e. make it known but inactive).
        """
        for setting in self.settings.values():
            setting.active = adapter(setting.name, setting.active,
                                     setting.section)

    def change_matching(self, regexs, enable):
        """Change all symbols matching one of the regexs to the desired state."""
        if not regexs:
            return
        regex = re.compile('|'.join(regexs))
        for setting in self.settings.values():
            if regex.search(setting.name):
                setting.active = enable

def is_full_section(section):
    """Is this section affected by "config.py full" and friends?"""
    return section.endswith('support') or section.endswith('modules')

def realfull_adapter(_name, active, section):
    """Activate all symbols found in the system and feature sections."""
    if not is_full_section(section):
        return active
    return True

# The goal of the full configuration is to have everything that can be tested
# together. This includes deprecated or insecure options. It excludes:
# * Options that require additional build dependencies or unusual hardware.
# * Options that make testing less effective.
# * Options that are incompatible with other options, or more generally that
#   interact with other parts of the code in such a way that a bulk enabling
#   is not a good way to test them.
# * Options that remove features.
EXCLUDE_FROM_FULL = frozenset([
    #pylint: disable=line-too-long
    'MBEDTLS_CTR_DRBG_USE_128_BIT_KEY', # interacts with ENTROPY_FORCE_SHA256
    'MBEDTLS_DEPRECATED_REMOVED', # conflicts with deprecated options
    'MBEDTLS_DEPRECATED_WARNING', # conflicts with deprecated options
    'MBEDTLS_ECDH_VARIANT_EVEREST_ENABLED', # influences the use of ECDH in TLS
    'MBEDTLS_ECP_NO_FALLBACK', # removes internal ECP implementation
    'MBEDTLS_ECP_RESTARTABLE', # incompatible with USE_PSA_CRYPTO
    'MBEDTLS_ENTROPY_FORCE_SHA256', # interacts with CTR_DRBG_128_BIT_KEY
    'MBEDTLS_HAVE_SSE2', # hardware dependency
    'MBEDTLS_MEMORY_BACKTRACE', # depends on MEMORY_BUFFER_ALLOC_C
    'MBEDTLS_MEMORY_BUFFER_ALLOC_C', # makes sanitizers (e.g. ASan) less effective
    'MBEDTLS_MEMORY_DEBUG', # depends on MEMORY_BUFFER_ALLOC_C
    'MBEDTLS_NO_64BIT_MULTIPLICATION', # influences anything that uses bignum
    'MBEDTLS_NO_DEFAULT_ENTROPY_SOURCES', # removes a feature
    'MBEDTLS_NO_PLATFORM_ENTROPY', # removes a feature
    'MBEDTLS_NO_UDBL_DIVISION', # influences anything that uses bignum
    'MBEDTLS_PLATFORM_NO_STD_FUNCTIONS', # removes a feature
    'MBEDTLS_PSA_CRYPTO_CONFIG', # toggles old/new style PSA config
    'MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG', # behavior change + build dependency
    'MBEDTLS_PSA_CRYPTO_KEY_ID_ENCODES_OWNER', # incompatible with USE_PSA_CRYPTO
    'MBEDTLS_PSA_CRYPTO_SPM', # platform dependency (PSA SPM)
    'MBEDTLS_PSA_INJECT_ENTROPY', # build dependency (hook functions)
    'MBEDTLS_RSA_NO_CRT', # influences the use of RSA in X.509 and TLS
    'MBEDTLS_TEST_CONSTANT_FLOW_MEMSAN', # build dependency (clang+memsan)
    'MBEDTLS_TEST_CONSTANT_FLOW_VALGRIND', # build dependency (valgrind headers)
    'MBEDTLS_X509_REMOVE_INFO', # removes a feature
])

def is_seamless_alt(name):
    """Whether the xxx_ALT symbol should be included in the full configuration.

    Include alternative implementations of platform functions, which are
    configurable function pointers that default to the built-in function.
    This way we test that the function pointers exist and build correctly
    without changing the behavior, and tests can verify that the function
    pointers are used by modifying those pointers.

    Exclude alternative implementations of library functions since they require
    an implementation of the relevant functions and an xxx_alt.h header.
    """
    if name == 'MBEDTLS_PLATFORM_SETUP_TEARDOWN_ALT':
        # Similar to non-platform xxx_ALT, requires platform_alt.h
        return False
    return name.startswith('MBEDTLS_PLATFORM_')

def include_in_full(name):
    """Rules for symbols in the "full" configuration."""
    if name in EXCLUDE_FROM_FULL:
        return False
    if name.endswith('_ALT'):
        return is_seamless_alt(name)
    return True

def full_adapter(name, active, section):
    """Config adapter for "full"."""
    if not is_full_section(section):
        return active
    return include_in_full(name)

# The baremetal configuration excludes options that require a library or
# operating system feature that is typically not present on bare metal
# systems. Features that are excluded from "full" won't be in "baremetal"
# either (unless explicitly turned on in baremetal_adapter) so they don't
# need to be repeated here.
EXCLUDE_FROM_BAREMETAL = frozenset([
    #pylint: disable=line-too-long
    'MBEDTLS_ENTROPY_NV_SEED', # requires a filesystem and FS_IO or alternate NV seed hooks
    'MBEDTLS_FS_IO', # requires a filesystem
    'MBEDTLS_HAVE_TIME', # requires a clock
    'MBEDTLS_HAVE_TIME_DATE', # requires a clock
    'MBEDTLS_NET_C', # requires POSIX-like networking
    'MBEDTLS_PLATFORM_FPRINTF_ALT', # requires FILE* from stdio.h
    'MBEDTLS_PLATFORM_NV_SEED_ALT', # requires a filesystem and ENTROPY_NV_SEED
    'MBEDTLS_PLATFORM_TIME_ALT', # requires a clock and HAVE_TIME
    'MBEDTLS_PSA_CRYPTO_SE_C', # requires a filesystem and PSA_CRYPTO_STORAGE_C
    'MBEDTLS_PSA_CRYPTO_STORAGE_C', # requires a filesystem
    'MBEDTLS_PSA_ITS_FILE_C', # requires a filesystem
    'MBEDTLS_THREADING_C', # requires a threading interface
    'MBEDTLS_THREADING_PTHREAD', # requires pthread
    'MBEDTLS_TIMING_C', # requires a clock
])

def keep_in_baremetal(name):
    """Rules for symbols in the "baremetal" configuration."""
    if name in EXCLUDE_FROM_BAREMETAL:
        return False
    return True

def baremetal_adapter(name, active, section):
    """Config adapter for "baremetal"."""
    if not is_full_section(section):
        return active
    if name == 'MBEDTLS_NO_PLATFORM_ENTROPY':
        # No OS-provided entropy source
        return True
    return include_in_full(name) and keep_in_baremetal(name)

def include_in_crypto(name):
    """Rules for symbols in a crypto configuration."""
    if name.startswith('MBEDTLS_X509_') or \
       name.startswith('MBEDTLS_SSL_') or \
       name.startswith('MBEDTLS_KEY_EXCHANGE_'):
        return False
    if name in [
            'MBEDTLS_DEBUG_C', # part of libmbedtls
            'MBEDTLS_NET_C', # part of libmbedtls
    ]:
        return False
    return True

def crypto_adapter(adapter):
    """Modify an adapter to disable non-crypto symbols.

    ``crypto_adapter(adapter)(name, active, section)`` is like
    ``adapter(name, active, section)``, but unsets all X.509 and TLS symbols.
    """
    def continuation(name, active, section):
        if not include_in_crypto(name):
            return False
        if adapter is None:
            return active
        return adapter(name, active, section)
    return continuation

def no_deprecated_adapter(adapter):
    """Modify an adapter to disable deprecated symbols.

    ``no_deprecated_adapter(adapter)(name, active, section)`` is like
    ``adapter(name, active, section)``, but unsets all deprecated symbols
    and sets ``MBEDTLS_DEPRECATED_REMOVED``.
    """
    def continuation(name, active, section):
        if name == 'MBEDTLS_DEPRECATED_REMOVED':
            return True
        if adapter is None:
            return active
        return adapter(name, active, section)
    return continuation

class ConfigFile(Config):
    """Representation of the Mbed TLS configuration read for a file.

    See the documentation of the `Config` class for methods to query
    and modify the configuration.
    """

    _path_in_tree = 'include/mbedtls/mbedtls_config.h'
    default_path = [_path_in_tree,
                    os.path.join(os.path.dirname(__file__),
                                 os.pardir,
                                 _path_in_tree),
                    os.path.join(os.path.dirname(os.path.abspath(os.path.dirname(__file__))),
                                 _path_in_tree)]

    def __init__(self, filename=None):
        """Read the Mbed TLS configuration file."""
        if filename is None:
            for candidate in self.default_path:
                if os.path.lexists(candidate):
                    filename = candidate
                    break
            else:
                raise Exception('Mbed TLS configuration file not found',
                                self.default_path)
        super().__init__()
        self.filename = filename
        self.current_section = 'header'
        with open(filename, 'r', encoding='utf-8') as file:
            self.templates = [self._parse_line(line) for line in file]
        self.current_section = None

    def set(self, name, value=None):
        if name not in self.settings:
            self.templates.append((name, '', '#define ' + name + ' '))
        super().set(name, value)

    _define_line_regexp = (r'(?P<indentation>\s*)' +
                           r'(?P<commented_out>(//\s*)?)' +
                           r'(?P<define>#\s*define\s+)' +
                           r'(?P<name>\w+)' +
                           r'(?P<arguments>(?:\((?:\w|\s|,)*\))?)' +
                           r'(?P<separator>\s*)' +
                           r'(?P<value>.*)')
    _section_line_regexp = (r'\s*/?\*+\s*[\\@]name\s+SECTION:\s*' +
                            r'(?P<section>.*)[ */]*')
    _config_line_regexp = re.compile(r'|'.join([_define_line_regexp,
                                                _section_line_regexp]))
    def _parse_line(self, line):
        """Parse a line in mbedtls_config.h and return the corresponding template."""
        line = line.rstrip('\r\n')
        m = re.match(self._config_line_regexp, line)
        if m is None:
            return line
        elif m.group('section'):
            self.current_section = m.group('section')
            return line
        else:
            active = not m.group('commented_out')
            name = m.group('name')
            value = m.group('value')
            template = (name,
                        m.group('indentation'),
                        m.group('define') + name +
                        m.group('arguments') + m.group('separator'))
            self.settings[name] = Setting(active, name, value,
                                          self.current_section)
            return template

    def _format_template(self, name, indent, middle):
        """Build a line for mbedtls_config.h for the given setting.

        The line has the form "<indent>#define <name> <value>"
        where <middle> is "#define <name> ".
        """
        setting = self.settings[name]
        value = setting.value
        if value is None:
            value = ''
        # Normally the whitespace to separte the symbol name from the
        # value is part of middle, and there's no whitespace for a symbol
        # with no value. But if a symbol has been changed from having a
        # value to not having one, the whitespace is wrong, so fix it.
        if value:
            if middle[-1] not in '\t ':
                middle += ' '
        else:
            middle = middle.rstrip()
        return ''.join([indent,
                        '' if setting.active else '//',
                        middle,
                        value]).rstrip()

    def write_to_stream(self, output):
        """Write the whole configuration to output."""
        for template in self.templates:
            if isinstance(template, str):
                line = template
            else:
                line = self._format_template(*template)
            output.write(line + '\n')

    def write(self, filename=None):
        """Write the whole configuration to the file it was read from.

        If filename is specified, write to this file instead.
        """
        if filename is None:
            filename = self.filename
        with open(filename, 'w', encoding='utf-8') as output:
            self.write_to_stream(output)

if __name__ == '__main__':
    def main():
        """Command line mbedtls_config.h manipulation tool."""
        parser = argparse.ArgumentParser(description="""
        Mbed TLS and Mbed Crypto configuration file manipulation tool.
        """)
        parser.add_argument('--file', '-f',
                            help="""File to read (and modify if requested).
                            Default: {}.
                            """.format(ConfigFile.default_path))
        parser.add_argument('--force', '-o',
                            action='store_true',
                            help="""For the set command, if SYMBOL is not
                            present, add a definition for it.""")
        parser.add_argument('--write', '-w', metavar='FILE',
                            help="""File to write to instead of the input file.""")
        subparsers = parser.add_subparsers(dest='command',
                                           title='Commands')
        parser_get = subparsers.add_parser('get',
                                           help="""Find the value of SYMBOL
                                           and print it. Exit with
                                           status 0 if a #define for SYMBOL is
                                           found, 1 otherwise.
                                           """)
        parser_get.add_argument('symbol', metavar='SYMBOL')
        parser_set = subparsers.add_parser('set',
                                           help="""Set SYMBOL to VALUE.
                                           If VALUE is omitted, just uncomment
                                           the #define for SYMBOL.
                                           Error out of a line defining
                                           SYMBOL (commented or not) is not
                                           found, unless --force is passed.
                                           """)
        parser_set.add_argument('symbol', metavar='SYMBOL')
        parser_set.add_argument('value', metavar='VALUE', nargs='?',
                                default='')
        parser_set_all = subparsers.add_parser('set-all',
                                               help="""Uncomment all #define
                                               whose name contains a match for
                                               REGEX.""")
        parser_set_all.add_argument('regexs', metavar='REGEX', nargs='*')
        parser_unset = subparsers.add_parser('unset',
                                             help="""Comment out the #define
                                             for SYMBOL. Do nothing if none
                                             is present.""")
        parser_unset.add_argument('symbol', metavar='SYMBOL')
        parser_unset_all = subparsers.add_parser('unset-all',
                                                 help="""Comment out all #define
                                                 whose name contains a match for
                                                 REGEX.""")
        parser_unset_all.add_argument('regexs', metavar='REGEX', nargs='*')

        def add_adapter(name, function, description):
            subparser = subparsers.add_parser(name, help=description)
            subparser.set_defaults(adapter=function)
        add_adapter('baremetal', baremetal_adapter,
                    """Like full, but exclude features that require platform
                    features such as file input-output.""")
        add_adapter('full', full_adapter,
                    """Uncomment most features.
                    Exclude alternative implementations and platform support
                    options, as well as some options that are awkward to test.
                    """)
        add_adapter('full_no_deprecated', no_deprecated_adapter(full_adapter),
                    """Uncomment most non-deprecated features.
                    Like "full", but without deprecated features.
                    """)
        add_adapter('realfull', realfull_adapter,
                    """Uncomment all boolean #defines.
                    Suitable for generating documentation, but not for building.""")
        add_adapter('crypto', crypto_adapter(None),
                    """Only include crypto features. Exclude X.509 and TLS.""")
        add_adapter('crypto_baremetal', crypto_adapter(baremetal_adapter),
                    """Like baremetal, but with only crypto features,
                    excluding X.509 and TLS.""")
        add_adapter('crypto_full', crypto_adapter(full_adapter),
                    """Like full, but with only crypto features,
                    excluding X.509 and TLS.""")

        args = parser.parse_args()
        config = ConfigFile(args.file)
        if args.command is None:
            parser.print_help()
            return 1
        elif args.command == 'get':
            if args.symbol in config:
                value = config[args.symbol]
                if value:
                    sys.stdout.write(value + '\n')
            return 0 if args.symbol in config else 1
        elif args.command == 'set':
            if not args.force and args.symbol not in config.settings:
                sys.stderr.write("A #define for the symbol {} "
                                 "was not found in {}\n"
                                 .format(args.symbol, config.filename))
                return 1
            config.set(args.symbol, value=args.value)
        elif args.command == 'set-all':
            config.change_matching(args.regexs, True)
        elif args.command == 'unset':
            config.unset(args.symbol)
        elif args.command == 'unset-all':
            config.change_matching(args.regexs, False)
        else:
            config.adapt(args.adapter)
        config.write(args.write)
        return 0

    # Import modules only used by main only if main is defined and called.
    # pylint: disable=wrong-import-position
    import argparse
    import sys
    sys.exit(main())
