manifest/mfg_manifest.go (149 lines of code) (raw):

/** * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you 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. */ package manifest import ( "encoding/hex" "encoding/json" "io/ioutil" "github.com/apache/mynewt-artifact/errors" "github.com/apache/mynewt-artifact/flash" "github.com/apache/mynewt-artifact/sec" ) type MfgManifestTarget struct { Name string `json:"name"` Offset int `json:"offset"` Size int `json:"size"` BinPath string `json:"bin_path,omitempty"` ImagePath string `json:"image_path,omitempty"` HexPath string `json:"hex_path,omitempty"` ManifestPath string `json:"manifest_path"` Extra map[string]interface{} `json:"extra,omitempty"` } type MfgManifestRaw struct { Filename string `json:"filename"` Offset int `json:"offset"` Size int `json:"size"` BinPath string `json:"bin_path"` Extra map[string]interface{} `json:"extra,omitempty"` } type MfgManifestMetaMmr struct { Area string `json:"area"` Device int `json:"_device"` EndOffset int `json:"_end_offset"` } type MfgManifestMeta struct { EndOffset int `json:"end_offset"` Size int `json:"size"` Hash bool `json:"hash_present"` FlashMap bool `json:"flash_map_present"` Mmrs []MfgManifestMetaMmr `json:"mmrs,omitempty"` } type MfgManifestSig struct { Type string `json:"type"` Key string `json:"key"` Sig string `json:"sig"` } type MfgManifest struct { Name string `json:"name"` BuildTime string `json:"build_time"` Format int `json:"format"` MfgHash string `json:"mfg_hash"` Version string `json:"version"` Device int `json:"device"` BinPath string `json:"bin_path"` HexPath string `json:"hex_path"` Bsp string `json:"bsp"` EraseVal byte `json:"erase_val"` Signatures []MfgManifestSig `json:"signatures,omitempty"` FlashAreas []flash.FlashArea `json:"flash_map"` FlashNames []string `json:"flash_names",omitempty` Targets []MfgManifestTarget `json:"targets"` Raws []MfgManifestRaw `json:"raws"` Meta *MfgManifestMeta `json:"meta,omitempty"` } // ReadMfgManifest reads a JSON mfg manifest from a byte slice and produces an // MfgManifest object. func ParseMfgManifest(jsonText []byte) (MfgManifest, error) { m := MfgManifest{ // Backwards compatibility: assume 0xff if unspecified. EraseVal: 0xff, } if err := json.Unmarshal(jsonText, &m); err != nil { return m, errors.Wrapf(err, "failure decoding mfg manifest") } return m, nil } // ReadMfgManifest reads a JSON mfg manifest from a file and produces an // MfgManifest object. func ReadMfgManifest(path string) (MfgManifest, error) { content, err := ioutil.ReadFile(path) if err != nil { return MfgManifest{}, errors.Wrapf(err, "failed to read mfg manifest file") } m, err := ParseMfgManifest(content) if err != nil { return m, errors.Wrapf(err, "path=%s", path) } return m, nil } // IsBoot indicates whether an mfg manifest target is a boot loader. func (mt *MfgManifestTarget) IsBoot() bool { return mt.BinPath != "" } // MarshalJson produces a JSON representation of an mfg manifest. func (m *MfgManifest) MarshalJson() ([]byte, error) { buffer, err := json.MarshalIndent(m, "", " ") if err != nil { return nil, errors.Wrapf(err, "cannot encode mfg manifest") } return buffer, nil } // FindFlashAreaDevOff searches an mfg manifest for a flash area with the // specified device and offset. func (m *MfgManifest) FindFlashAreaDevOff(device int, offset int) *flash.FlashArea { for i, _ := range m.FlashAreas { fa := &m.FlashAreas[i] if fa.Device == device && fa.Offset == offset { return fa } } return nil } // FindWithinFlashAreaDevOff searches an mfg manifest for a flash area with the // specified device that contains the given offset. func (m *MfgManifest) FindWithinFlashAreaDevOff(device int, offset int) *flash.FlashArea { for i, _ := range m.FlashAreas { fa := &m.FlashAreas[i] if fa.Device == device { end := fa.Offset + fa.Size if offset >= fa.Offset && offset < end { return fa } } } return nil } // FindFlashAreaName searches an mfg manifest for a flash area with the // specified name. func (m *MfgManifest) FindFlashAreaName(name string) *flash.FlashArea { for i, _ := range m.FlashAreas { fa := &m.FlashAreas[i] if fa.Name == name { return fa } } return nil } // SecSig converts the provided mfg manifest signature into a sec.Sig object. func (ms *MfgManifestSig) SecSig() (sec.Sig, error) { keyHash, err := hex.DecodeString(ms.Key) if err != nil { return sec.Sig{}, errors.Errorf( "invalid hex-encoded key hash: %s", ms.Key) } data, err := hex.DecodeString(ms.Sig) if err != nil { return sec.Sig{}, errors.Errorf( "invalid hex-encoded signature: %s", ms.Sig) } return sec.Sig{ KeyHash: keyHash, Data: data, }, nil } // SecSigs converts all the signutures in the provided mfg manifest into // sec.Sig objects. func (m *MfgManifest) SecSigs() ([]sec.Sig, error) { var sigs []sec.Sig for _, ms := range m.Signatures { s, err := ms.SecSig() if err != nil { return nil, err } sigs = append(sigs, s) } return sigs, nil }