Make dumpRSAPublicKey also accept a public key in PEM format

This change makes dumpRSAPublicKey directly accept a public key in PEM format. This makes it possible to avoid the unnecessary step of generating a self-signed certificate to dump the public key in .keyb format.

The old style certificate input is still accepted.

Using certs (as done previously):
dumpRSAPublicKey -cert <certfile>

Directly using public keys:
dumpRSAPublicKey -pub <pubfile>

Change-Id: Ic35b59aff6613d145d7947212650da281f734b74

BUG=7576
TEST=manual

$ openssl genrsa -F4 -out test.pem 4096
$ openssl rsa -in test.pem -out test.pub
$ dumpRSAPublicKey -pub test.pub >test.pub.keyb

Verify that this matches the output we get using the old style <cert> input.

$ openssl req -batch -new -x509 -key test.pem -out test.cert
$ dumpRSAPublicKey -cert test.cert >test.cert.keyb
$ diff test.pub.keyb test.cert.keyb
$

Review URL: http://codereview.chromium.org/4215006
diff --git a/tests/devkeys/create_new_keys.sh b/tests/devkeys/create_new_keys.sh
index 6faba53..625fbc6 100755
--- a/tests/devkeys/create_new_keys.sh
+++ b/tests/devkeys/create_new_keys.sh
@@ -42,7 +42,7 @@
   openssl req -batch -new -x509 -key "${base}_${len}.pem" \
     -out "${base}_${len}.crt"
   # generate pre-processed RSA public key
-  dumpRSAPublicKey "${base}_${len}.crt" > "${base}_${len}.keyb"
+  dumpRSAPublicKey -cert "${base}_${len}.crt" > "${base}_${len}.keyb"
 
   # wrap the public key
   vbutil_key \
diff --git a/tests/gen_test_keys.sh b/tests/gen_test_keys.sh
index 1bf995b..11545d2 100755
--- a/tests/gen_test_keys.sh
+++ b/tests/gen_test_keys.sh
@@ -32,7 +32,7 @@
       -out ${key_base}.crt
 
     # Generate pre-processed key for use by RSA signature verification code.
-    ${UTIL_DIR}/dumpRSAPublicKey ${key_base}.crt \
+    ${UTIL_DIR}/dumpRSAPublicKey -cert ${key_base}.crt \
       > ${key_base}.keyb
 
     alg_index=0
diff --git a/utility/dev_make_keypair b/utility/dev_make_keypair
index b055826..d1d34ad 100755
--- a/utility/dev_make_keypair
+++ b/utility/dev_make_keypair
@@ -53,7 +53,7 @@
   openssl req -batch -new -x509 -key "${base}_${len}.pem" \
     -out "${base}_${len}.crt"
   # generate pre-processed RSA public key
-  dumpRSAPublicKey "${base}_${len}.crt" > "${base}_${len}.keyb"
+  dumpRSAPublicKey -cert "${base}_${len}.crt" > "${base}_${len}.keyb"
 
   # wrap the public key
   vbutil_key \
diff --git a/utility/dumpRSAPublicKey.c b/utility/dumpRSAPublicKey.c
index 837303c..da8597a 100644
--- a/utility/dumpRSAPublicKey.c
+++ b/utility/dumpRSAPublicKey.c
@@ -136,40 +136,52 @@
 }
 
 int main(int argc, char* argv[]) {
+  int cert_mode = 0;
   FILE* fp;
   X509* cert = NULL;
   RSA* pubkey = NULL;
   EVP_PKEY* key;
 
-  if (argc != 2) {
-    fprintf(stderr, "Usage: %s <certfile>\n", argv[0]);
+  if (argc != 3 || (strcmp(argv[1], "-cert") && strcmp(argv[1], "-pub"))) {
+    fprintf(stderr, "Usage: %s <-cert | -pub> <file>\n", argv[0]);
     return -1;
   }
 
-  fp = fopen(argv[1], "r");
+  if (!strcmp(argv[1], "-cert"))
+    cert_mode = 1;
+
+  fp = fopen(argv[2], "r");
 
   if (!fp) {
-    fprintf(stderr, "Couldn't open certificate file!\n");
+    fprintf(stderr, "Couldn't open file %s!\n", argv[2]);
     return -1;
   }
 
-  /* Read the certificate */
-  if (!PEM_read_X509(fp, &cert, NULL, NULL)) {
-    fprintf(stderr, "Couldn't read certificate.\n");
-    goto fail;
-  }
+  if (cert_mode) {
+    /* Read the certificate */
+    if (!PEM_read_X509(fp, &cert, NULL, NULL)) {
+      fprintf(stderr, "Couldn't read certificate.\n");
+      goto fail;
+    }
 
-  /* Get the public key from the certificate. */
-  key = X509_get_pubkey(cert);
+    /* Get the public key from the certificate. */
+    key = X509_get_pubkey(cert);
 
-  /* Convert to a RSA_style key. */
-  if (!(pubkey = EVP_PKEY_get1_RSA(key))) {
-    fprintf(stderr, "Couldn't convert to a RSA style key.\n");
-    goto fail;
+    /* Convert to a RSA_style key. */
+    if (!(pubkey = EVP_PKEY_get1_RSA(key))) {
+      fprintf(stderr, "Couldn't convert to a RSA style key.\n");
+      goto fail;
+    }
+  } else {
+    /* Read the pubkey in .PEM format. */
+    if (!(pubkey = PEM_read_RSA_PUBKEY(fp, NULL, NULL, NULL))) {
+      fprintf(stderr, "Couldn't read public key file.\n");
+      goto fail;
+    }
   }
 
   if (check(pubkey)) {
-    output (pubkey);
+    output(pubkey);
   }
 
 fail: