You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@mynewt.apache.org by ma...@apache.org on 2016/04/28 02:09:40 UTC
[13/32] incubator-mynewt-newt git commit: Start work on signed
images. Use PKCS1.5 w/RSA 2048 and SHA256.
Start work on signed images. Use PKCS1.5 w/RSA 2048 and SHA256.
Project: http://git-wip-us.apache.org/repos/asf/incubator-mynewt-newt/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-mynewt-newt/commit/9fcac247
Tree: http://git-wip-us.apache.org/repos/asf/incubator-mynewt-newt/tree/9fcac247
Diff: http://git-wip-us.apache.org/repos/asf/incubator-mynewt-newt/diff/9fcac247
Branch: refs/heads/master
Commit: 9fcac247ca800f29dc70e5e9075e104b13ac6172
Parents: 6897b05
Author: Marko Kiiskila <ma...@runtime.io>
Authored: Fri Apr 1 20:12:23 2016 -0700
Committer: Marko Kiiskila <ma...@runtime.io>
Committed: Fri Apr 1 20:13:08 2016 -0700
----------------------------------------------------------------------
newt/cli/image_cmds.go | 10 +++-
newt/image/image.go | 114 +++++++++++++++++++++++++++++++++++---------
2 files changed, 100 insertions(+), 24 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-newt/blob/9fcac247/newt/cli/image_cmds.go
----------------------------------------------------------------------
diff --git a/newt/cli/image_cmds.go b/newt/cli/image_cmds.go
index 910d10a..249577a 100644
--- a/newt/cli/image_cmds.go
+++ b/newt/cli/image_cmds.go
@@ -64,6 +64,13 @@ func createImageRunCmd(cmd *cobra.Command, args []string) {
NewtUsage(cmd, err)
}
+ if len(args) > 2 {
+ err = image.SetSigningKey(args[2])
+ if err != nil {
+ NewtUsage(cmd, err)
+ }
+ }
+
err = image.Generate()
if err != nil {
NewtUsage(cmd, err)
@@ -82,10 +89,11 @@ func createImageRunCmd(cmd *cobra.Command, args []string) {
func AddImageCommands(cmd *cobra.Command) {
createImageHelpText := "Create image by adding image header to created " +
"binary file for <target-name>. Version number in the header is set " +
- "to be <version>."
+ "to be <version>.\n\nTo sign the image give private key as <signing_key>."
createImageHelpEx := " newt create-image <target-name> <version>\n"
createImageHelpEx += " newt create-image my_target1 1.2.0\n"
createImageHelpEx += " newt create-image my_target1 1.2.0.3\n"
+ createImageHelpEx += " newt create-image my_target1 1.2.0.3 private.pem\n"
createImageCmd := &cobra.Command{
Use: "create-image",
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-newt/blob/9fcac247/newt/image/image.go
----------------------------------------------------------------------
diff --git a/newt/image/image.go b/newt/image/image.go
index 5ab749a..b466f76 100644
--- a/newt/image/image.go
+++ b/newt/image/image.go
@@ -21,11 +21,17 @@ package image
import (
"bytes"
+ "crypto"
+ "crypto/rand"
+ "crypto/rsa"
"crypto/sha256"
+ "crypto/x509"
"encoding/binary"
"encoding/json"
+ "encoding/pem"
"fmt"
"io"
+ "io/ioutil"
"os"
"path/filepath"
"sort"
@@ -54,6 +60,7 @@ type Image struct {
targetImg string
manifestFile string
version ImageVersion
+ signingKey *rsa.PrivateKey
hash []byte
}
@@ -85,15 +92,17 @@ const (
* Image header flags.
*/
const (
- IMAGE_F_PIC = 0x00000001
- IMAGE_F_HAS_SHA256 = 0x00000002 /* Image contains hash TLV */
+ IMAGE_F_PIC = 0x00000001
+ IMAGE_F_SHA256 = 0x00000002 /* Image contains hash TLV */
+ IMAGE_F_PKCS15_RSA2048_SHA256 = 0x00000004 /* PKCS15 w/RSA2048 and SHA256 */
)
/*
* Image trailer TLV types.
*/
const (
- IMAGE_TLV_SHA256 = 1
+ IMAGE_TLV_SHA256 = 1
+ IMAGE_TLV_RSA2048 = 2
)
/*
@@ -183,6 +192,31 @@ func (image *Image) SetVersion(versStr string) error {
return nil
}
+func (image *Image) SetSigningKey(fileName string) error {
+ data, err := ioutil.ReadFile(fileName)
+ if err != nil {
+ return util.NewNewtError(fmt.Sprintf("Error reading key file: %s", err))
+ }
+
+ block, _ := pem.Decode(data)
+ if block == nil || block.Type != "RSA PRIVATE KEY" {
+ return util.NewNewtError(fmt.Sprintf("No RSA private key in file"))
+ }
+
+ /*
+ * ParsePKCS1PrivateKey returns an RSA private key from its ASN.1 PKCS#1 DER
+ * encoded form.
+ */
+ privateKey, err := x509.ParsePKCS1PrivateKey(block.Bytes)
+ if err != nil {
+ return util.NewNewtError(fmt.Sprintf("Private key parsing failed: %s",
+ err))
+ }
+ image.signingKey = privateKey
+
+ return nil
+}
+
func (image *Image) Generate() error {
binFile, err := os.Open(image.sourceBin)
if err != nil {
@@ -215,13 +249,20 @@ func (image *Image) Generate() error {
*/
hdr := &ImageHdr{
Magic: IMAGE_MAGIC,
- TlvSz: 4 + 32,
+ TlvSz: 0,
HdrSz: IMAGE_HEADER_SIZE,
ImgSz: uint32(binInfo.Size()),
- Flags: IMAGE_F_HAS_SHA256,
+ Flags: 0,
Vers: image.version,
Pad: 0,
}
+ if image.signingKey != nil {
+ hdr.TlvSz = 4 + 256
+ hdr.Flags = IMAGE_F_PKCS15_RSA2048_SHA256
+ } else {
+ hdr.TlvSz = 4 + 32
+ hdr.Flags = IMAGE_F_SHA256
+ }
err = binary.Write(imgFile, binary.LittleEndian, hdr)
if err != nil {
@@ -261,25 +302,52 @@ func (image *Image) Generate() error {
image.hash = hash.Sum(nil)
- /*
- * Trailer with hash of the data
- */
- tlv := &ImageTrailerTlv{
- Type: IMAGE_TLV_SHA256,
- Pad: 0,
- Len: uint16(len(image.hash)),
- }
- err = binary.Write(imgFile, binary.LittleEndian, tlv)
- if err != nil {
- return util.NewNewtError(fmt.Sprintf("Failed to serialize image "+
- "trailer: %s", err.Error()))
- }
- _, err = imgFile.Write(image.hash)
- if err != nil {
- return util.NewNewtError(fmt.Sprintf("Failed to append hash: %s",
- err.Error()))
- }
+ if image.signingKey == nil {
+ /*
+ * Trailer with hash of the data
+ */
+ tlv := &ImageTrailerTlv{
+ Type: IMAGE_TLV_SHA256,
+ Pad: 0,
+ Len: uint16(len(image.hash)),
+ }
+ err = binary.Write(imgFile, binary.LittleEndian, tlv)
+ if err != nil {
+ return util.NewNewtError(fmt.Sprintf("Failed to serialize image "+
+ "trailer: %s", err.Error()))
+ }
+ _, err = imgFile.Write(image.hash)
+ if err != nil {
+ return util.NewNewtError(fmt.Sprintf("Failed to append hash: %s",
+ err.Error()))
+ }
+ } else {
+ /*
+ * If signing key was set, generate TLV for that.
+ */
+ tlv := &ImageTrailerTlv{
+ Type: IMAGE_TLV_RSA2048,
+ Pad: 0,
+ Len: 256, /* 2048 bits */
+ }
+ signature, err := rsa.SignPKCS1v15(rand.Reader, image.signingKey,
+ crypto.SHA256, image.hash)
+ if err != nil {
+ return util.NewNewtError(fmt.Sprintf(
+ "Failed to compute signature: %s", err))
+ }
+ err = binary.Write(imgFile, binary.LittleEndian, tlv)
+ if err != nil {
+ return util.NewNewtError(fmt.Sprintf("Failed to serialize image "+
+ "trailer: %s", err.Error()))
+ }
+ _, err = imgFile.Write(signature)
+ if err != nil {
+ return util.NewNewtError(fmt.Sprintf("Failed to append sig: %s",
+ err.Error()))
+ }
+ }
return nil
}