Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

SUIT: Upgrade to draft-ietf-suit-manifest-09 #14436

Merged
merged 3 commits into from
Sep 24, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion dist/tools/flake8/check.sh
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ EXCLUDE="^(.+/vendor/\
|dist/tools/mcuboot\
|dist/tools/uhcpd\
|dist/tools/stm32loader\
|dist/tools/suit_v3/suit-manifest-generator)\
|dist/tools/suit/suit-manifest-generator)\
|dist/tools/esptool"
FILEREGEX='(\.py$|pyterm$)'
FILES=$(FILEREGEX=${FILEREGEX} EXCLUDE=${EXCLUDE} changed_files)
Expand Down
File renamed without changes.
File renamed without changes.
Original file line number Diff line number Diff line change
Expand Up @@ -144,6 +144,8 @@ The `suit-tool` supports three sub-commands:
* `create` generates a new manifest.
* `sign` signs a manifest.
* `parse` parses an existing manifest into cbor-debug or a json representation.
* `keygen` Create a signing key. Not for production use.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is that a private key? And why not for production use?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ahh, crap, this was not supposed to be reviewed, everything under dist/tools/suit/suit-manifest-generator is imported from ARMmbed/suit-manifest-generator and will be migrated to a package when the spec is stabilized.
I'd rather not start fixing nitpicks in "external" code and only fix the bare minimum required for integration.

* `pubkey` Get the public key for a supplied private key in uECC-compatible C definition.

The `suit-tool` has a configurable log level, specified with `-l`:

Expand Down Expand Up @@ -178,7 +180,7 @@ To add a component to the manifest from the command-line, use the following synt

The supported fields are:

* `file` the path to a file to use as a payload file.
* `file` the path fo a file to use as a payload file.
benpicco marked this conversation as resolved.
Show resolved Hide resolved
* `inst` the `install-id`.
* `uri` the URI where the file will be found.

Expand Down Expand Up @@ -207,3 +209,28 @@ suit-tool parse -m MANIFEST
```

If a json-representation is needed, add the '-j' flag.

## Keygen

Create an asymmetric keypair for non-production use. Production systems should use closely guarded keys, such as keys stored in an HSM.
benpicco marked this conversation as resolved.
Show resolved Hide resolved

```sh
suit-tool keygen [-t TYPE] -o KEYFILE
```

`suit-tool keygen` defaults to creating SECP256r1 keys. To create another type of key, use `-t`followed by one of:

* `secp256r1`
* `secp384r1`
* `secp521r1`
* `ed25519`

## UECC public key

Derive a public key in the format used by micro ECC. The input is a PEM private key.

```sh
suit-tool pubkey -k FILE
```

The tool will then print the public key in micro ECC format.
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
# ----------------------------------------------------------------------------
# Copyright 2016-2019 ARM Limited or its affiliates
# Copyright 2016-2020 ARM Limited or its affiliates
#
# SPDX-License-Identifier: Apache-2.0
#
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,8 @@
install_requires = [
'cbor>=1.0.0',
'colorama>=0.4.0',
'cryptography>=2.8'
'cryptography>=2.8',
'pyhsslms>=1.0.0',
],
classifiers = [
"Programming Language :: Python :: 3",
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
#!/usr/bin/python3
# -*- coding: utf-8 -*-
# ----------------------------------------------------------------------------
# Copyright 2016-2019 ARM Limited or its affiliates
Expand All @@ -17,4 +16,4 @@
# See the License for the specific language governing permissions and
# limitations under the License.
#
__version__ = '0.0.1'
__version__ = '0.0.2'
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
#!/usr/bin/python3
# -*- coding: utf-8 -*-
# ----------------------------------------------------------------------------
# Copyright 2019-2020 ARM Limited or its affiliates
Expand All @@ -17,22 +16,23 @@
# See the License for the specific language governing permissions and
# limitations under the License.
# ----------------------------------------------------------------------------
import sys
import argparse
import sys, argparse, os
from suit_tool import __version__
from suit_tool import keygen
from suit_tool import get_pubkey
import json
import re


def str_to_component(s):
types = {
'file' : ('file', lambda x : str(x.strip('"'))),
# 'desc' : ('component-description', lambda x : str(x.strip('"'))),
'inst' : ('install-id', lambda x : [ str(y) for y in eval(x) ]),
'uri' : ('uri', lambda x : str(x.strip('"')))
}
d = {types[k][0]:types[k][1](v) for k,v in [ re.split(r'=',e, maxsplit=1) for e in re.split(r''',\s*(?=["']?[a-zA-Z0-9_-]+["']?=)''', s)]}
return d


class MainArgumentParser(object):

def __init__(self):
Expand All @@ -54,7 +54,7 @@ def _make_parser(self):

# create_parser.add_argument('-v', '--manifest-version', choices=['1'], default='1')
create_parser.add_argument('-i', '--input-file', metavar='FILE', type=argparse.FileType('r'),
help='An input file describing the update. The file must be formatted as JSON. The overal structure is described in README.')
help='An input file describing the update. The file must be formated as JSON. The overal structure is described in README.')
create_parser.add_argument('-o', '--output-file', metavar='FILE', type=argparse.FileType('wb'), required=True)
create_parser.add_argument('-f', '--format', metavar='FMT', choices=['suit', 'suit-debug', 'json'], default='suit')
create_parser.add_argument('-s', '--severable', action='store_true', help='Convert large elements to severable fields.')
Expand All @@ -72,9 +72,25 @@ def _make_parser(self):
parse_parser.add_argument('-m', '--manifest', metavar='FILE', type=argparse.FileType('rb'), required=True)
parse_parser.add_argument('-j', '--json-output', default=False, action='store_true', dest='json')

get_uecc_pubkey_parser = subparsers.add_parser('pubkey', help='Get the public key for a supplied private key in uECC-compatible C definition.')
get_pubkey_parser = subparsers.add_parser('pubkey', help='Get the public key for a supplied private key.')

get_pubkey_parser.add_argument('-k', '--private-key', metavar='FILE', type=argparse.FileType('rb'), required=True)
get_pubkey_parser.add_argument('-f', '--output-format', choices=get_pubkey.OutputFormaters.keys(), default='pem')
get_pubkey_parser.add_argument('-o', '--output-file', metavar='FILE', type=argparse.FileType('wb'), default=sys.stdout)

keygen_parser = subparsers.add_parser('keygen', help='Create a signing key. Not for production use')

keygen_parser.add_argument('-t', '--type', choices=keygen.KeyGenerators.keys(),
default='secp256r1', help='The type of the key to generate')
keygen_parser.add_argument('-o', '--output-file', metavar='FILE', type=argparse.FileType('wb'), default=sys.stdout)
keygen_parser.add_argument('-f', '--output-format', choices=keygen.OutputFormaters.keys(), default='pem')
keygen_parser.add_argument('-l', '--levels', help='The number of hss-lms levels', type=int, default=2)

get_uecc_pubkey_parser.add_argument('-k', '--private-key', metavar='FILE', type=argparse.FileType('rb'), required=True)
sever_parser = subparsers.add_parser('sever', help='Remove one or more severable elements from the manifest, if present.')
sever_parser.add_argument('-m', '--manifest', metavar='FILE', type=argparse.FileType('rb'), required=True)
sever_parser.add_argument('-o', '--output-file', metavar='FILE', type=argparse.FileType('wb'), required=True)
sever_parser.add_argument('-e', '--element', action='append', type=str, dest='elements', default=[])
sever_parser.add_argument('-a', '--all', action='store_true', default=False)

return parser

Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
#!/usr/bin/python3
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
# ----------------------------------------------------------------------------
# Copyright 2018-2020 ARM Limited or its affiliates
Expand All @@ -17,21 +17,19 @@
# See the License for the specific language governing permissions and
# limitations under the License.
# ----------------------------------------------------------------------------
import logging
import sys
import logging, sys

from suit_tool.argparser import MainArgumentParser
from suit_tool import create, sign, parse, get_uecc_pubkey
from suit_tool import create, sign, parse, get_pubkey, keygen, sever #, verify, cert, init

LOG = logging.getLogger(__name__)
LOG_FORMAT = '[%(levelname)s] %(asctime)s - %(name)s - %(message)s'

LOG = logging.getLogger(__name__)
LOG_FORMAT='[%(levelname)s] %(asctime)s - %(name)s - %(message)s'

def main():
driver = CLIDriver()
return driver.main()


class CLIDriver(object):

def __init__(self):
Expand All @@ -46,6 +44,10 @@ def __init__(self):
logging.basicConfig(level=log_level,
format=LOG_FORMAT,
datefmt='%Y-%m-%d %H:%M:%S')
logging.addLevelName( logging.INFO, "\033[1;32m%s\033[1;0m" % logging.getLevelName(logging.INFO))
logging.addLevelName( logging.WARNING, "\033[1;93m%s\033[1;0m" % logging.getLevelName(logging.WARNING))
logging.addLevelName( logging.CRITICAL, "\033[1;31m%s\033[1;0m" % logging.getLevelName(logging.CRITICAL))

LOG.debug('CLIDriver created. Arguments parsed and logging setup.')

def main(self):
Expand All @@ -56,8 +58,10 @@ def main(self):
# "cert": cert.main,
# "init": init.main,
# "update" : update.main,
"pubkey": get_uecc_pubkey.main,
"sign": sign.main
"pubkey": get_pubkey.main,
"sign": sign.main,
"keygen": keygen.main,
"sever" : sever.main,
}[self.options.action](self.options) or 0

sys.exit(rc)
Loading