You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@mynewt.apache.org by cc...@apache.org on 2019/10/24 16:45:16 UTC

[mynewt-artifact] branch master updated (8fa4247 -> b8ee251)

This is an automated email from the ASF dual-hosted git repository.

ccollins pushed a change to branch master
in repository https://gitbox.apache.org/repos/asf/mynewt-artifact.git.


    from 8fa4247  Add support for protected TLVs
     new 9d893f1  sec: Add function to get pub enc key from priv key
     new bd8b4b4  sec: Add `Type` field to `Sig` type
     new 267010c  sec: Add `EncType` type
     new 6a0584f  sec: Make GenerateSig() return a Sig object
     new 03992ce  sec: function to get the hash from a signing key
     new b8ee251  Add `Size` field to MfgManifestRaw

The 6 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.


Summary of changes:
 image/create.go          |  47 ++++++++++++++++-----
 image/image.go           |  39 ++++++++++++-----
 manifest/mfg_manifest.go |   6 ++-
 sec/encrypt.go           |  56 +++++++++++++++++++++++++
 sec/sign.go              | 106 +++++++++++++++++++++++++++++++++++++++--------
 5 files changed, 213 insertions(+), 41 deletions(-)


[mynewt-artifact] 01/06: sec: Add function to get pub enc key from priv key

Posted by cc...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

ccollins pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/mynewt-artifact.git

commit 9d893f19ec48ada9c7f3b1210df54c873253387c
Author: Christopher Collins <cc...@apache.org>
AuthorDate: Wed Oct 23 12:48:13 2019 -0700

    sec: Add function to get pub enc key from priv key
    
    func (key *PrivEncKey) PubEncKey() PubEncKey
---
 sec/encrypt.go | 6 ++++++
 1 file changed, 6 insertions(+)

diff --git a/sec/encrypt.go b/sec/encrypt.go
index b63ab8d..0fc83d1 100644
--- a/sec/encrypt.go
+++ b/sec/encrypt.go
@@ -90,6 +90,12 @@ func ParsePubEncKey(keyBytes []byte) (PubEncKey, error) {
 	return parsePubKePem(keyBytes)
 }
 
+func (key *PrivEncKey) PubEncKey() PubEncKey {
+	return PubEncKey{
+		Rsa: key.Rsa.Public().(*rsa.PublicKey),
+	}
+}
+
 func (key *PubEncKey) AssertValid() {
 	if key.Rsa == nil && key.Aes == nil {
 		panic("invalid public encryption key; neither RSA nor AES")


[mynewt-artifact] 05/06: sec: function to get the hash from a signing key

Posted by cc...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

ccollins pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/mynewt-artifact.git

commit 03992ce9f73dbccfc7d1f9206b2035a79b0c124e
Author: Christopher Collins <cc...@apache.org>
AuthorDate: Wed Oct 23 14:59:09 2019 -0700

    sec: function to get the hash from a signing key
    
    func (key *PubSignKey) Hash() ([]byte, error)
    
    This is just a convenience function.
---
 sec/sign.go | 14 +++++++++++---
 1 file changed, 11 insertions(+), 3 deletions(-)

diff --git a/sec/sign.go b/sec/sign.go
index 01a9cad..a718c8b 100644
--- a/sec/sign.go
+++ b/sec/sign.go
@@ -338,12 +338,20 @@ func (key *PubSignKey) SigType() (SigType, error) {
 	return 0, errors.Errorf("invalid key: no non-nil members")
 }
 
+func (key *PubSignKey) Hash() ([]byte, error) {
+	pubBytes, err := key.Bytes()
+	if err != nil {
+		return nil, errors.WithStack(err)
+	}
+
+	return RawKeyHash(pubBytes), nil
+}
+
 func checkOneKeyOneSig(k PubSignKey, sig Sig, hash []byte) (bool, error) {
-	pubBytes, err := k.Bytes()
+	keyHash, err := k.Hash()
 	if err != nil {
-		return false, errors.WithStack(err)
+		return false, err
 	}
-	keyHash := RawKeyHash(pubBytes)
 
 	if !bytes.Equal(keyHash, sig.KeyHash) {
 		return false, nil


[mynewt-artifact] 03/06: sec: Add `EncType` type

Posted by cc...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

ccollins pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/mynewt-artifact.git

commit 267010c1118567257abd8e7f56db369f81907ebe
Author: Christopher Collins <cc...@apache.org>
AuthorDate: Wed Oct 23 14:57:37 2019 -0700

    sec: Add `EncType` type
    
    Enumerate the list of encryption types and add the ability to query an
    encryption key for its type.
---
 sec/encrypt.go | 50 ++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 50 insertions(+)

diff --git a/sec/encrypt.go b/sec/encrypt.go
index 0fc83d1..b9a579e 100644
--- a/sec/encrypt.go
+++ b/sec/encrypt.go
@@ -34,6 +34,14 @@ import (
 	"github.com/apache/mynewt-artifact/errors"
 )
 
+type EncType int
+
+const (
+	ENC_TYPE_AES_128 EncType = iota
+	ENC_TYPE_AES_256
+	ENC_TYPE_RSA_2048
+)
+
 // XXX: Only RSA supported for now.
 type PrivEncKey struct {
 	Rsa *rsa.PrivateKey
@@ -44,6 +52,31 @@ type PubEncKey struct {
 	Aes cipher.Block
 }
 
+var encTypeNameMap = map[EncType]string{
+	ENC_TYPE_AES_128:  "aes128",
+	ENC_TYPE_AES_256:  "aes256",
+	ENC_TYPE_RSA_2048: "rsa2048",
+}
+
+func EncTypeString(typ EncType) string {
+	s := encTypeNameMap[typ]
+	if s == "" {
+		return "unknown"
+	} else {
+		return s
+	}
+}
+
+func EncStringType(s string) (EncType, error) {
+	for k, v := range encTypeNameMap {
+		if s == v {
+			return k, nil
+		}
+	}
+
+	return 0, errors.Errorf("unknown enc type name: \"%s\"", s)
+}
+
 func parsePubKePem(b []byte) (PubEncKey, error) {
 	key := PubEncKey{}
 
@@ -102,6 +135,23 @@ func (key *PubEncKey) AssertValid() {
 	}
 }
 
+func (key *PubEncKey) EncType() (EncType, error) {
+	if key.Rsa != nil {
+		return ENC_TYPE_RSA_2048, nil
+	} else if key.Aes != nil {
+		switch key.Aes.BlockSize() {
+		case 128 / 8:
+			return ENC_TYPE_AES_128, nil
+		case 256 / 8:
+			return ENC_TYPE_AES_256, nil
+		default:
+			return 0, errors.Errorf("illegal AES key block size: %d", key.Aes.BlockSize())
+		}
+	} else {
+		return 0, errors.Errorf("invalid enc key: all members nil")
+	}
+}
+
 func encryptRsa(pubk *rsa.PublicKey, plainSecret []byte) ([]byte, error) {
 	rng := rand.Reader
 	cipherSecret, err := rsa.EncryptOAEP(


[mynewt-artifact] 04/06: sec: Make GenerateSig() return a Sig object

Posted by cc...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

ccollins pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/mynewt-artifact.git

commit 6a0584f127bada7da36ac3f526139d899e39b0ec
Author: Christopher Collins <cc...@apache.org>
AuthorDate: Wed Oct 23 14:58:05 2019 -0700

    sec: Make GenerateSig() return a Sig object
    
    Before this commit, this function returned a []byte slice containing the
    raw signature.  Now the function returns a Sig object (which also
    contains the sig type and key hash).
---
 image/create.go | 47 +++++++++++++++++++++++++++++++++++++----------
 1 file changed, 37 insertions(+), 10 deletions(-)

diff --git a/image/create.go b/image/create.go
index c51cfe6..0ee3bb9 100644
--- a/image/create.go
+++ b/image/create.go
@@ -197,16 +197,43 @@ func GenerateSigEd25519(key sec.PrivSignKey, hash []byte) ([]byte, error) {
 	return sig, nil
 }
 
-func GenerateSig(key sec.PrivSignKey, hash []byte) ([]byte, error) {
-	key.AssertValid()
+func GenerateSig(key sec.PrivSignKey, hash []byte) (sec.Sig, error) {
+	pub := key.PubKey()
+	typ, err := pub.SigType()
+	if err != nil {
+		return sec.Sig{}, err
+	}
 
-	if key.Rsa != nil {
-		return GenerateSigRsa(key, hash)
-	} else if key.Ec != nil {
-		return GenerateSigEc(key, hash)
-	} else {
-		return GenerateSigEd25519(key, hash)
+	var data []byte
+
+	switch typ {
+	case sec.SIG_TYPE_RSA2048, sec.SIG_TYPE_RSA3072:
+		data, err = GenerateSigRsa(key, hash)
+
+	case sec.SIG_TYPE_ECDSA224, sec.SIG_TYPE_ECDSA256:
+		data, err = GenerateSigEc(key, hash)
+
+	case sec.SIG_TYPE_ED25519:
+		data, err = GenerateSigEd25519(key, hash)
+
+	default:
+		err = errors.Errorf("unknown sig type: %v", typ)
 	}
+
+	if err != nil {
+		return sec.Sig{}, err
+	}
+
+	keyHash, err := pub.Hash()
+	if err != nil {
+		return sec.Sig{}, err
+	}
+
+	return sec.Sig{
+		Type:    typ,
+		KeyHash: keyHash,
+		Data:    data,
+	}, nil
 }
 
 func BuildKeyHashTlv(keyBytes []byte) ImageTlv {
@@ -243,9 +270,9 @@ func BuildSigTlvs(keys []sec.PrivSignKey, hash []byte) ([]ImageTlv, error) {
 		tlv = ImageTlv{
 			Header: ImageTlvHdr{
 				Type: sigTlvType(key),
-				Len:  uint16(len(sig)),
+				Len:  uint16(len(sig.Data)),
 			},
-			Data: sig,
+			Data: sig.Data,
 		}
 		tlvs = append(tlvs, tlv)
 	}


[mynewt-artifact] 06/06: Add `Size` field to MfgManifestRaw

Posted by cc...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

ccollins pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/mynewt-artifact.git

commit b8ee2516bf8bb36d1bb2c5d939dedd5966d90e57
Author: Christopher Collins <cc...@apache.org>
AuthorDate: Wed Oct 23 17:31:27 2019 -0700

    Add `Size` field to MfgManifestRaw
---
 manifest/mfg_manifest.go | 1 +
 1 file changed, 1 insertion(+)

diff --git a/manifest/mfg_manifest.go b/manifest/mfg_manifest.go
index b423e59..0cde7f8 100644
--- a/manifest/mfg_manifest.go
+++ b/manifest/mfg_manifest.go
@@ -42,6 +42,7 @@ type MfgManifestTarget struct {
 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"`
 }


[mynewt-artifact] 02/06: sec: Add `Type` field to `Sig` type

Posted by cc...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

ccollins pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/mynewt-artifact.git

commit bd8b4b4e2a686da7253403eddf8e158a84e7a27b
Author: Christopher Collins <cc...@apache.org>
AuthorDate: Wed Oct 23 14:56:41 2019 -0700

    sec: Add `Type` field to `Sig` type
    
    It was not possible to determine the algorithm associated with a
    signature.  This commit adds this information to the Sig type.
---
 image/image.go           | 39 ++++++++++++++------
 manifest/mfg_manifest.go |  5 +--
 sec/sign.go              | 92 ++++++++++++++++++++++++++++++++++++++++--------
 3 files changed, 108 insertions(+), 28 deletions(-)

diff --git a/image/image.go b/image/image.go
index 9cba94a..eb571eb 100644
--- a/image/image.go
+++ b/image/image.go
@@ -82,6 +82,14 @@ var imageTlvTypeNameMap = map[uint8]string{
 	IMAGE_TLV_SECRET_ID: "SEC_KEY_ID",
 }
 
+var imageTlvTypeSigTypeMap = map[uint8]sec.SigType{
+	IMAGE_TLV_RSA2048:  sec.SIG_TYPE_RSA2048,
+	IMAGE_TLV_ECDSA224: sec.SIG_TYPE_ECDSA224,
+	IMAGE_TLV_ECDSA256: sec.SIG_TYPE_ECDSA256,
+	IMAGE_TLV_RSA3072:  sec.SIG_TYPE_RSA3072,
+	IMAGE_TLV_ED25519:  sec.SIG_TYPE_ED25519,
+}
+
 type ImageVersion struct {
 	Major    uint8
 	Minor    uint8
@@ -148,6 +156,11 @@ func ImageTlvTypeName(tlvType uint8) string {
 	return name
 }
 
+func ImageTlvTypeToSigType(tlvType uint8) (sec.SigType, bool) {
+	typ, ok := imageTlvTypeSigTypeMap[tlvType]
+	return typ, ok
+}
+
 func ImageTlvTypeIsSig(tlvType uint8) bool {
 	return tlvType == IMAGE_TLV_RSA2048 ||
 		tlvType == IMAGE_TLV_RSA3072 ||
@@ -468,18 +481,22 @@ func (img *Image) CollectSigs() ([]sec.Sig, error) {
 					"image contains keyhash tlv without subsequent signature")
 			}
 			keyHashTlv = t
-		} else if ImageTlvTypeIsSig(t.Header.Type) {
-			if keyHashTlv == nil {
-				return nil, errors.Errorf(
-					"image contains signature tlv without preceding keyhash")
+		} else {
+			sigType, ok := ImageTlvTypeToSigType(t.Header.Type)
+			if ok {
+				if keyHashTlv == nil {
+					return nil, errors.Errorf(
+						"image contains signature tlv without preceding keyhash")
+				}
+
+				sigs = append(sigs, sec.Sig{
+					Type:    sigType,
+					KeyHash: keyHashTlv.Data,
+					Data:    t.Data,
+				})
+
+				keyHashTlv = nil
 			}
-
-			sigs = append(sigs, sec.Sig{
-				KeyHash: keyHashTlv.Data,
-				Data:    t.Data,
-			})
-
-			keyHashTlv = nil
 		}
 	}
 
diff --git a/manifest/mfg_manifest.go b/manifest/mfg_manifest.go
index 0509f1a..b423e59 100644
--- a/manifest/mfg_manifest.go
+++ b/manifest/mfg_manifest.go
@@ -61,8 +61,9 @@ type MfgManifestMeta struct {
 }
 
 type MfgManifestSig struct {
-	Key string `json:"key"`
-	Sig string `json:"sig"`
+	Type string `json:"type"`
+	Key  string `json:"key"`
+	Sig  string `json:"sig"`
 }
 
 type MfgManifest struct {
diff --git a/sec/sign.go b/sec/sign.go
index 4189b68..01a9cad 100644
--- a/sec/sign.go
+++ b/sec/sign.go
@@ -33,6 +33,24 @@ import (
 	"golang.org/x/crypto/ed25519"
 )
 
+type SigType int
+
+const (
+	SIG_TYPE_RSA2048 SigType = iota
+	SIG_TYPE_RSA3072
+	SIG_TYPE_ECDSA224
+	SIG_TYPE_ECDSA256
+	SIG_TYPE_ED25519
+)
+
+var sigTypeNameMap = map[SigType]string{
+	SIG_TYPE_RSA2048:  "rsa2048",
+	SIG_TYPE_ECDSA224: "ecdsa224",
+	SIG_TYPE_ECDSA256: "ecdsa256",
+	SIG_TYPE_RSA3072:  "rsa3072",
+	SIG_TYPE_ED25519:  "ed25519",
+}
+
 type PrivSignKey struct {
 	// Only one of these members is non-nil.
 	Rsa     *rsa.PrivateKey
@@ -47,12 +65,32 @@ type PubSignKey struct {
 }
 
 type Sig struct {
+	Type    SigType
 	KeyHash []byte
 	Data    []byte
 }
 
 var oidPrivateKeyEd25519 = asn1.ObjectIdentifier{1, 3, 101, 112}
 
+func SigTypeString(typ SigType) string {
+	s := sigTypeNameMap[typ]
+	if s == "" {
+		return "unknown"
+	} else {
+		return s
+	}
+}
+
+func SigStringType(s string) (SigType, error) {
+	for k, v := range sigTypeNameMap {
+		if s == v {
+			return k, nil
+		}
+	}
+
+	return 0, errors.Errorf("unknown sig type name: \"%s\"", s)
+}
+
 func parsePrivSignKeyItf(keyBytes []byte) (interface{}, error) {
 	var privKey interface{}
 	var err error
@@ -249,31 +287,55 @@ func (key *PubSignKey) Bytes() ([]byte, error) {
 	var b []byte
 	var err error
 
-	if key.Rsa != nil {
+	typ, err := key.SigType()
+	if err != nil {
+		return nil, err
+	}
+
+	switch typ {
+	case SIG_TYPE_RSA2048, SIG_TYPE_RSA3072:
 		b, err = asn1.Marshal(*key.Rsa)
-		if err != nil {
-			return nil, err
+
+	case SIG_TYPE_ECDSA224, SIG_TYPE_ECDSA256:
+		b, err = x509.MarshalPKIXPublicKey(key.Ec)
+
+	case SIG_TYPE_ED25519:
+		b, err = marshalEd25519([]byte(key.Ed25519))
+
+	default:
+		err = errors.Errorf("unknown sig type: %v", typ)
+	}
+	if err != nil {
+		return nil, err
+	}
+
+	return b, nil
+}
+
+func (key *PubSignKey) SigType() (SigType, error) {
+	if key.Rsa != nil {
+		switch key.Rsa.Size() {
+		case 2048 / 8:
+			return SIG_TYPE_RSA2048, nil
+		case 3072 / 8:
+			return SIG_TYPE_RSA3072, nil
+		default:
+			return 0, errors.Errorf("unknown RSA key size (bytes): %d", key.Rsa.Size())
 		}
 	} else if key.Ec != nil {
 		switch key.Ec.Curve.Params().Name {
 		case "P-224":
-			fallthrough
+			return SIG_TYPE_ECDSA224, nil
 		case "P-256":
-			b, err = x509.MarshalPKIXPublicKey(key.Ec)
-			if err != nil {
-				return nil, err
-			}
+			return SIG_TYPE_ECDSA256, nil
 		default:
-			return nil, errors.Errorf("unsupported ECC curve")
-		}
-	} else {
-		b, err = marshalEd25519([]byte(key.Ed25519))
-		if err != nil {
-			return nil, err
+			return 0, errors.Errorf("unknown EC curve: %s", key.Ec.Curve.Params().Name)
 		}
+	} else if key.Ed25519 != nil {
+		return SIG_TYPE_ED25519, nil
 	}
 
-	return b, nil
+	return 0, errors.Errorf("invalid key: no non-nil members")
 }
 
 func checkOneKeyOneSig(k PubSignKey, sig Sig, hash []byte) (bool, error) {