Skip to content

Commit

Permalink
Merge pull request #43 from ARMmbed/dependency-support
Browse files Browse the repository at this point in the history
Add support for dependencies
  • Loading branch information
bremoran authored Dec 3, 2020
2 parents b5eb3d1 + 1b885e7 commit 959dd3f
Show file tree
Hide file tree
Showing 7 changed files with 169 additions and 77 deletions.
19 changes: 19 additions & 0 deletions examples/deps/example6a.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
{
"components" : [
{
"install-id" : ["00"],
"install-digest": {
"algorithm-id": "sha256",
"digest-bytes": "00112233445566778899aabbccddeeff0123456789abcdeffedcba9876543210"
},
"install-size" : 34768,
"uri": "http://example.com/file.bin",
"vendor-id" : "fa6b4a53-d5ad-5fdf-be9d-e663e4d41ffe",
"class-id" : "1492af14-2569-5e48-bf42-9b2d51f2ab45",
"bootable" : true,
"install-on-download" : true
}
],
"manifest-version": 1,
"manifest-sequence-number": 5
}
25 changes: 9 additions & 16 deletions examples/example6.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,24 +2,17 @@
"components" : [
{
"install-id" : ["00"],
"install-digest": {
"algorithm-id": "sha256",
"digest-bytes": "00112233445566778899aabbccddeeff0123456789abcdeffedcba9876543210"
},
"install-size" : 34768,
"uri": "http://example.com/file1.bin",
"uri": "http://server.local/file1.bin",
"vendor-id" : "fa6b4a53-d5ad-5fdf-be9d-e663e4d41ffe",
"class-id" : "1492af14-2569-5e48-bf42-9b2d51f2ab45",
"bootable" : true
},
"class-id" : "1492af14-2569-5e48-bf42-9b2d51f2ab45"
}
],
"dependencies":[
{
"install-id" : ["01"],
"install-digest": {
"algorithm-id": "sha256",
"digest-bytes": "0123456789abcdeffedcba987654321000112233445566778899aabbccddeeff"
},
"install-size" : 76834,
"uri": "http://example.com/file2.bin"
"src-file" : "deps/example6a.json",
"file" : "deps/example6a.suit",
"key-file" : "../private_key.pem",
"uri" : "http://server.local/example6a.suit"
}
],
"manifest-version": 1,
Expand Down
10 changes: 5 additions & 5 deletions parser_examples/suitloader/source/suit_parser.c
Original file line number Diff line number Diff line change
Expand Up @@ -701,14 +701,14 @@ PARSE_HANDLER(invoke_handler)
}

CBOR_KPARSE_ELEMENT_LIST(sequence_elements,
CBOR_KPARSE_ELEMENT_H(SUIT_CONDITION_VENDOR_ID, CBOR_TYPE_SIMPLE, vendor_match_handler, "vendor-match"),
CBOR_KPARSE_ELEMENT_H(SUIT_CONDITION_CLASS_ID, CBOR_TYPE_SIMPLE, class_match_handler, "class-match"),
CBOR_KPARSE_ELEMENT_H(SUIT_CONDITION_IMAGE_MATCH, CBOR_TYPE_SIMPLE, NULL, "image-match"),
CBOR_KPARSE_ELEMENT_H(SUIT_CONDITION_VENDOR_ID, CBOR_TYPE_UINT, vendor_match_handler, "vendor-match"),
CBOR_KPARSE_ELEMENT_H(SUIT_CONDITION_CLASS_ID, CBOR_TYPE_UINT, class_match_handler, "class-match"),
CBOR_KPARSE_ELEMENT_H(SUIT_CONDITION_IMAGE_MATCH, CBOR_TYPE_UINT, NULL, "image-match"),
// CBOR_KPARSE_ELEMENT(SUIT_DIRECTIVE_SET_COMP_IDX, CBOR_TYPE_UINT, set_component_handler),
CBOR_KPARSE_ELEMENT_C(SUIT_DIRECTIVE_SET_PARAMETERS, CBOR_TYPE_MAP, &parameter_handlers, "set-parameters"),
CBOR_KPARSE_ELEMENT_C(SUIT_DIRECTIVE_OVERRIDE_PARAMETERS, CBOR_TYPE_MAP, &parameter_handlers, "override-parameters"),
CBOR_KPARSE_ELEMENT(SUIT_DIRECTIVE_FETCH, CBOR_TYPE_SIMPLE, NULL, "Fetch"),
CBOR_KPARSE_ELEMENT_H(SUIT_DIRECTIVE_INVOKE, CBOR_TYPE_SIMPLE, invoke_handler, "invoke"),
CBOR_KPARSE_ELEMENT(SUIT_DIRECTIVE_FETCH, CBOR_TYPE_UINT, NULL, "Fetch"),
CBOR_KPARSE_ELEMENT_H(SUIT_DIRECTIVE_INVOKE, CBOR_TYPE_UINT, invoke_handler, "invoke"),
);


Expand Down
39 changes: 22 additions & 17 deletions suit_tool/compile.py
Original file line number Diff line number Diff line change
Expand Up @@ -159,13 +159,14 @@ def compile_manifest(options, m):
else:
cid_data[cid].append(c)

bootable_cid_data = OrderedDict( ( (cid,choices) for cid, choices in cid_data.items() if any([ c.get('bootable') for c in choices])))
for id, choices in cid_data.items():
for c in choices:
if 'file' in c:
digest, imgsize = hash_file(c['file'], hashes.SHA256())
c['install-digest'] = {
'algorithm-id' : 'sha256',
'digest-bytes' : binascii.b2a_hex(digest.finalize())
'digest-bytes' : binascii.b2a_hex(digest.finalize()).decode('utf-8')
}
c['install-size'] = imgsize

Expand Down Expand Up @@ -210,8 +211,6 @@ def compile_manifest(options, m):
with open(dep['src-file']) as input_fd:
with open(dep['file']+'.tmp','wb') as output_fd:
create_opts = type('',(object,),{
# 'input_file': open(dep['src-file']),
# 'output_file': open(dep['file']+'.tmp','wb'),
'input_file': input_fd,
'output_file': output_fd,
'format' : 'suit',
Expand Down Expand Up @@ -244,7 +243,7 @@ def compile_manifest(options, m):
mfst = cbor.loads(cmfst)
did = SUITDigest().from_json({
'algorithm-id' : 'sha256',
'digest-bytes' : binascii.b2a_hex(digest.finalize())
'digest-bytes' : binascii.b2a_hex(digest.finalize()).decode('utf-8')
})

Dependencies.append(SUITDependency().from_json({
Expand Down Expand Up @@ -279,8 +278,10 @@ def compile_manifest(options, m):
InstSeq = make_sequence(cid, choices, InstSeq, InstParams, InstCmds)
for cmd in DepRequiredSequences['install']:
InstSeq.append(cmd)
InstSeq.append(mkCommand(cid, 'directive-fetch', None))
InstSeq.append(mkCommand(cid, 'condition-image-match', None))

if any(['install-digest' in c for c in choices]):
InstSeq.append(mkCommand(cid, 'directive-fetch', None))
InstSeq.append(mkCommand(cid, 'condition-image-match', None))

elif any(['uri' in c for c in choices]):
FetchParams = {
Expand Down Expand Up @@ -332,9 +333,9 @@ def compile_manifest(options, m):
ValidateParams = {
}
ValidateSeq = make_sequence(cid, choices, ValidateSeq, ValidateParams, ValidateCmds)
ValidateSeq.append(mkCommand(cid, 'condition-image-match', None))
for cmd in DepRequiredSequences['validate']:
ValidateSeq.append(cmd)
ValidateSeq.append(mkCommand(cid, 'condition-image-match', None))
# if any([c.get('bootable', False) for c in choices]):
# TODO: Dependencies
# If there are dependencies
Expand All @@ -360,13 +361,18 @@ def compile_manifest(options, m):
LoadSeq.append(cmd)
LoadSeq.append(mkCommand(load_id, 'directive-copy', None))
LoadSeq.append(mkCommand(load_id, 'condition-image-match', None))
elif len(DepRequiredSequences['load']):
for cmd in DepRequiredSequences['load']:
LoadSeq.append(cmd)

# Generate image invocation section
bootable_components = [x for x in m['components'] if x.get('bootable')]
bootable_components = []
# Generate image invocation section
for cmd in DepRequiredSequences['run']:
RunSeq.append(cmd)
bootable_components = [x for x in m['components'] if x.get('bootable')]
for cid, choices in bootable_cid_data.items():
if len(bootable_components) == 1:
c = bootable_components[0]
for cmd in DepRequiredSequences['run']:
RunSeq.append(cmd)
RunSeq.append(SUITCommand().from_json({
'component-id' : runable_id(c),
'command-id' : 'directive-run',
Expand All @@ -380,7 +386,6 @@ def compile_manifest(options, m):
# t.append(
#
# )
#TODO: Text
# print('Common')
common = SUITCommon().from_json({
'components': [id.to_json() for id in ids.keys()],
Expand All @@ -398,16 +403,17 @@ def compile_manifest(options, m):

# for k,v in {'deres':DepSeq, 'fetch': FetchSeq, 'install':InstSeq, 'validate':ValidateSeq, 'run':RunSeq, 'load':LoadSeq}.items():
# # print('sequence:{}'.format(k))
# v.to_json()
# print(v.to_json())

jmanifest.update({k:v for k,v in {
'deres' : DepSeq.to_json(),
'fetch' : FetchSeq.to_json(),
'dependency-resolution' : DepSeq.to_json(),
'payload-fetch' : FetchSeq.to_json(),
'install' : InstSeq.to_json(),
'validate' : ValidateSeq.to_json(),
'run' : RunSeq.to_json(),
'load' : LoadSeq.to_json()
}.items() if v})
}.items() if len(v)})


mtext = {}
for k in ['manifest-description', 'update-description']:
Expand Down Expand Up @@ -449,7 +455,6 @@ def compile_manifest(options, m):
}})
jenvelope.update({'text' : mtext})

# print('building envelope')
wrapped_manifest = SUITEnvelope().from_json(jenvelope)

return wrapped_manifest
27 changes: 26 additions & 1 deletion suit_tool/create.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,12 +17,37 @@
# limitations under the License.
# ----------------------------------------------------------------------------
from suit_tool.compile import compile_manifest
from suit_tool.manifest import SUITEnvelope, SUITDigest
import binascii
import json
import cbor2 as cbor
import itertools
import textwrap
from collections import OrderedDict

from cryptography.hazmat.backends import default_backend
from cryptography.hazmat.primitives import hashes


def suit_mfst(mfst, options):
digest = {
'sha256' : hashes.Hash(hashes.SHA256(), backend=default_backend()),
'sha384' : hashes.Hash(hashes.SHA384(), backend=default_backend()),
'sha512' : hashes.Hash(hashes.SHA512(), backend=default_backend()),
}.get('sha256')

mfst_tmp = mfst.to_suit()
digest.update(cbor.dumps(mfst_tmp[SUITEnvelope.fields['manifest'].suit_key]))
mfst_tmp[SUITEnvelope.fields['auth'].suit_key] = cbor.dumps([
cbor.dumps(SUITDigest().from_json({
'algorithm-id' : 'sha256',
'digest-bytes' : binascii.b2a_hex(digest.finalize()).decode('utf-8')
}).to_suit(), canonical = True)
])

mfst_envelope = cbor.dumps(mfst_tmp, canonical=True)
return mfst_envelope

def main(options):
m = json.loads(options.input_file.read(), object_pairs_hook=OrderedDict)

Expand All @@ -31,7 +56,7 @@ def main(options):
if m.get('severable') or (hasattr(options, 'severable') and options.severable):
nm = nm.to_severable('sha256')
output = {
'suit' : lambda x: cbor.dumps(x.to_suit(), canonical=True),
'suit' : lambda x: suit_mfst(x,options),
'suit-debug' : lambda x: '\n'.join(itertools.chain.from_iterable(
map(textwrap.wrap, x.to_debug('').split('\n'))
)).encode('utf-8'),
Expand Down
Loading

0 comments on commit 959dd3f

Please sign in to comment.