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:18 UTC

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

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) {