imgtool: Add support for RSA keys

Add the possibility of "rsa-2048" as a "--key-type" argument to the
keygen command.
diff --git a/imgtool/imgtool.go b/imgtool/imgtool.go
index 14c90a0..b880244 100644
--- a/imgtool/imgtool.go
+++ b/imgtool/imgtool.go
@@ -8,12 +8,14 @@
 	"crypto/ecdsa"
 	"crypto/elliptic"
 	"crypto/rand"
+	"crypto/rsa"
 	"crypto/x509"
 	"encoding/asn1"
 	"encoding/pem"
 	"errors"
 	"fmt"
 	"io/ioutil"
+	"math/big"
 	"os"
 	"strings"
 	"text/template"
@@ -141,6 +143,14 @@
 		generate:    genEcdsaP224,
 	}
 	keyGens[kg.name] = kg
+
+	kg = &KeyGenerator{
+		name:        "rsa-2048",
+		description: "RSA 2048",
+		pemType:     "RSA PRIVATE KEY",
+		generate:    genRSA2048,
+	}
+	keyGens[kg.name] = kg
 }
 
 func genEcdsaP224() ([]byte, error) {
@@ -161,6 +171,15 @@
 	return x509.MarshalECPrivateKey(priv)
 }
 
+func genRSA2048() ([]byte, error) {
+	priv, err := rsa.GenerateKey(rand.Reader, 2048)
+	if err != nil {
+		return nil, err
+	}
+
+	return x509.MarshalPKCS1PrivateKey(priv), nil
+}
+
 func doGetPub(cmd *cobra.Command, args []string) {
 	data, err := ioutil.ReadFile(keyFile)
 	if err != nil {
@@ -177,10 +196,16 @@
 	}
 	// fmt.Printf("type=%q, headers=%v, data=\n%s", block.Type, block.Headers, hex.Dump(block.Bytes))
 
-	if block.Type != "EC PRIVATE KEY" {
-		log.Fatal("Only supports ECDSA keys")
+	if block.Type == "EC PRIVATE KEY" {
+		dumpECPub(block)
+	} else if block.Type == "RSA PRIVATE KEY" {
+		dumpRSAPub(block)
+	} else {
+		log.Fatal("Only supports ECDSA and RSA keys")
 	}
+}
 
+func dumpECPub(block *pem.Block) {
 	privateKey, err := x509.ParseECPrivateKey(block.Bytes)
 	if err != nil {
 		log.Fatal(err)
@@ -242,12 +267,42 @@
 		formatCData(asnBytes, 1), len(asnBytes))
 }
 
+func dumpRSAPub(block *pem.Block) {
+	privateKey, err := x509.ParsePKCS1PrivateKey(block.Bytes)
+	if err != nil {
+		log.Fatal(err)
+	}
+
+	pubKey := RSAPublicKey{
+		N: privateKey.N,
+		E: privateKey.E,
+	}
+
+	asnBytes, err := asn1.Marshal(pubKey)
+	if err != nil {
+		log.Fatal(err)
+	}
+
+	fmt.Printf(`/* Autogenerated, do not edit */
+
+const unsigned char rsa_pub_key[] = {
+	%s };
+const unsigned int ec_pub_key_len = %d;
+`,
+		formatCData(asnBytes, 1), len(asnBytes))
+}
+
 // ecPublicKey represents an ASN.1 Elliptic Curve Public Key structure
 type EcPublicKey struct {
 	Algorithm AlgorithmId
 	PubKey    asn1.BitString
 }
 
+type RSAPublicKey struct {
+	N *big.Int
+	E int
+}
+
 type AlgorithmId struct {
 	Algorithm asn1.ObjectIdentifier
 	Curve     asn1.ObjectIdentifier