imgtool: Add support for RSA keys
Add the possibility of "rsa-2048" as a "--key-type" argument to the
keygen command.
@@ -8,12 +8,14 @@ import (
"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 @@ func init() {
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 @@ func genEcdsaP256() ([]byte, error) {
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 @@ func doGetPub(cmd *cobra.Command, args []string) {
}
// 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 @@ const unsigned int ec_pub_key_len = %d;
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
