以optee的sign_encrypt.py为例讲解argparse命令解析模块

Argparse是 Python 标准库中推荐的命令行解析模块。该模块会自动生成提示信息,且在用户给程序传入非法参数时报错。

刚好最近在看optee的sign_encrypt.py,以它为例介绍python的argparse命令解析模块。

脚本参见:optee_os/scripts/sign_encrypt.py at master · OP-TEE/optee_os · GitHub

 一、一些基本用法使用示例

1、创建ArgumentParser解析器对象

parser = argparse.ArgumentParser(
        description='Sign and encrypt (optional) a Trusted Application ' +
        ' for OP-TEE.',
        usage='%(prog)s <command> ...',
        epilog='<command> -h for detailed help')

ArgumentParser 对象的参数有:

prog -- 程序的名称(默认:sys.argv[0])
usage -- 描述程序用途的字符串(默认值:从添加到解析器的参数生成)
description -- 在参数帮助文档之前显示的文本(默认值:无)。这个参数简要描述这个程序做什么以及怎么做。
epilog -- 在参数帮助文档之后显示的文本(默认值:无)
parents -- 一个 ArgumentParser 对象的列表,它们的参数也应包含在内
formatter_class -- 用于自定义帮助文档输出格式的类
prefix_chars -- 可选参数的前缀字符集合(默认值:’-’)
fromfile_prefix_chars -- 当需要从文件中读取其他参数时,用于标识文件名的前缀字符集合(默认值:None)
argument_default -- 参数的全局默认值(默认值: None)
conflict_handler -- 解决冲突选项的策略(通常是不必要的)
add_help -- 为解析器添加一个 -h/--help 选项(默认值: True)
allow_abbrev -- 如果缩写是无歧义的,则允许缩写长选项 (默认值:True)

exit_on_error -- 确定发生错误时 ArgumentParser 是否退出并显示错误信息

2、调用add_argument() 方法添加参数

添加参数是由add_argument() 方法完成的,它指定 ArgumentParser对象如何获取命令行字符串并将其转换为对象。这些信息将会在 parse_args() 调用时被存储和使用。例如:

    def arg_add_uuid(parser):
        parser.add_argument(
            '--uuid', required=True, type=uuid_parse,
            help='String UUID of the TA')

    def arg_add_key(parser):
        parser.add_argument(
            '--key', required=True, help='''
                Name of signing and verification key file (PEM format) or an
                Amazon Resource Name (arn:) of an AWS KMS asymmetric key.
                At least public key for the commands digest, stitch, and
                verify, else a private key''')

    def arg_add_enc_key(parser):
        parser.add_argument(
            '--enc-key', required=False, help='Encryption key string')

    def arg_add_enc_key_type(parser):
        parser.add_argument(
            '--enc-key-type', required=False,
            default='SHDR_ENC_KEY_DEV_SPECIFIC',
            choices=list(enc_key_type.keys()), help='''
                Encryption key type,
                Defaults to SHDR_ENC_KEY_DEV_SPECIFIC.''')

    def arg_add_ta_version(parser):
        parser.add_argument(
            '--ta-version', required=False, type=int_parse, default=0, help='''
                TA version stored as a 32-bit unsigned integer and used for
                rollback protection of TA install in the secure database.
                Defaults to 0.''')

    def arg_add_sig(parser):
        parser.add_argument(
            '--sig', required=True, dest='sigf',
            help='Name of signature input file, defaults to <UUID>.sig')

    def arg_add_dig(parser):
        parser.add_argument(
            '--dig', required=True, dest='digf',
            help='Name of digest output file, defaults to <UUID>.dig')

    def arg_add_in(parser):
        parser.add_argument(
            '--in', required=False, dest='inf', help='''
                Name of application input file, defaults to
                <UUID>.stripped.elf''')

    def arg_add_out(parser):
        parser.add_argument(
            '--out', required=True, dest='outf',
            help='Name of application output file, defaults to <UUID>.ta')

    def arg_add_algo(parser):
        parser.add_argument(
            '--algo', required=False, choices=list(sig_tee_alg.keys()),
            default='TEE_ALG_RSASSA_PKCS1_PSS_MGF1_SHA256', help='''
                The hash and signature algorithm.
                Defaults to TEE_ALG_RSASSA_PKCS1_PSS_MGF1_SHA256.''')

    def arg_add_subkey(parser):
        parser.add_argument(
            '--subkey', action=OnlyOne, help='Name of subkey input file')

    def arg_add_name(parser):
        parser.add_argument('--name',
                            help='Input name for subspace of a subkey')

    def arg_add_subkey_uuid_in(parser):
        parser.add_argument(
            '--in', required=True, dest='inf',
            help='Name of subkey input file')

    def arg_add_max_depth(parser):
        parser.add_argument(
            '--max-depth', required=False, type=int_parse, help='''
            Max depth of subkeys below this subkey''')

    def arg_add_name_size(parser):
        parser.add_argument(
            '--name-size', required=True, type=int_parse, help='''
            Size of (unsigned) input name for subspace of a subkey.
            Set to 0 to create an identity subkey (a subkey having
            the same UUID as the next subkey or TA)''')

    def arg_add_subkey_version(parser):
        parser.add_argument(
            '--subkey-version', required=False, type=int_parse, default=0,
            help='Subkey version used for rollback protection')

    def arg_add_subkey_in(parser):
        parser.add_argument(
            '--in', required=True, dest='inf', help='''
            Name of PEM file with the public key of the new subkey''')

    def arg_add_subkey_out(parser):
        parser.add_argument(
            '--out', required=True, dest='outf',
            help='Name of subkey output file')

3、使用 parse_args() 解析添加的参数

parse_args() 方法检查命令行,把每个参数转换为适当的类型然后调用相应的操作。

parsed = parser.parse_args(argv)

if parsed.command is None:
     parser.print_help()
     sys.exit(1)

4、使用add_subparsers()方法去创建子命令

功能比较多的命令端程序常常将功能分解到不同子命令中。

subparsers = parser.add_subparsers(
            title='valid commands, with possible aliases in ()',
            dest='command', metavar='')

 5、使用add_parser添加子命令

parser_sign_enc = subparsers.add_parser(
        'sign-enc', prog=parser.prog + ' sign-enc',
        help='Generate signed and optionally encrypted loadable TA image file')

arg_add_uuid(parser_sign_enc)
arg_add_ta_version(parser_sign_enc)
arg_add_in(parser_sign_enc)
arg_add_out(parser_sign_enc)
arg_add_key(parser_sign_enc)
arg_add_subkey(parser_sign_enc)
arg_add_name(parser_sign_enc)
arg_add_enc_key(parser_sign_enc)
arg_add_enc_key_type(parser_sign_enc)
arg_add_algo(parser_sign_enc)

6、使用set_defaults()绑定子命令默认函数

argparse提供了一个一个方法set_defaults(),可以将子命令绑定特定的函数。

parser_sign_enc.set_defaults(func=command_sign_enc)

综上,sign_encrypt.py脚本有以下7个子命令,对应7个功能点:

sign-enc、digest、stitch、verify、display、subkey_uuid、sign_subkey

即:

$python3 sign_encrypt.py -h
usage: sign_encrypt.py <command> ...

Sign and encrypt (optional) a Trusted Application for OP-TEE.

options:
  -h, --help            show this help message and exit

valid commands, with possible aliases in ():

    sign-enc            Generate signed and optionally encrypted loadable TA image file
    digest (generate-digest)
                        Generate loadable TA binary image digest for offline signing
    stitch (stitch-ta)  Generate loadable signed and encrypted TA binary image file from TA raw image and its signature
    verify              Verify signed TA binary
    display             Parses and displays a signed TA binary
    subkey-uuid         calculate the UUID of next TA or subkey
    sign-subkey         Sign a subkey

<command> -h for detailed help

二、参考资料

Argparse 教程 — Python 3.11.4 文档

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

趣多多代言人

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值