From 27c90708e63f5f042aa52de6bc1b89c282ca8c4a Mon Sep 17 00:00:00 2001 From: Vincent Palatin Date: Thu, 15 Oct 2015 17:54:34 -0700 Subject: futility: add support for .pem with public key Add support for PEM file containing a RSA Public key in futility "show" and "create" commands. When "futility create" is given a PEM file with only a RSA public key, generate the proper .vbpubk2 rather than failing. BRANCH=smaug BUG=none TEST=make runtests and run manually futility show tests/testkeys/key_rsa4096.pub.pem futility show tests/testkeys/key_rsa4096.pem Change-Id: I707ceca54c80ba21f53869ad86c86fa23b31e665 Reviewed-on: https://chromium-review.googlesource.com/306683 Commit-Ready: Vincent Palatin Tested-by: Vincent Palatin Reviewed-by: Bill Richardson --- futility/cmd_create.c | 52 ++++++++++++++++++++++++-------------- futility/vb2_helper.c | 11 ++++++-- tests/futility/test_create.sh | 12 +++++++++ tests/futility/test_file_types.sh | 1 + tests/testkeys/key_rsa1024.pub.pem | 6 +++++ tests/testkeys/key_rsa2048.pub.pem | 9 +++++++ tests/testkeys/key_rsa4096.pub.pem | 14 ++++++++++ tests/testkeys/key_rsa8192.pub.pem | 25 ++++++++++++++++++ 8 files changed, 109 insertions(+), 21 deletions(-) create mode 100644 tests/testkeys/key_rsa1024.pub.pem create mode 100644 tests/testkeys/key_rsa2048.pub.pem create mode 100644 tests/testkeys/key_rsa4096.pub.pem create mode 100644 tests/testkeys/key_rsa8192.pub.pem diff --git a/futility/cmd_create.c b/futility/cmd_create.c index 6da59a7f..143ea9ae 100644 --- a/futility/cmd_create.c +++ b/futility/cmd_create.c @@ -169,6 +169,7 @@ static int vb2_make_keypair() uint32_t keyb_size; enum vb2_signature_algorithm sig_alg; uint8_t *pubkey_buf = 0; + int has_priv = 0; FILE *fp; int ret = 1; @@ -180,12 +181,21 @@ static int vb2_make_keypair() } rsa_key = PEM_read_RSAPrivateKey(fp, NULL, NULL, NULL); - fclose(fp); + if (!rsa_key) { + /* Check if the PEM contains only a public key */ + fseek(fp, 0, SEEK_SET); + rsa_key = PEM_read_RSA_PUBKEY(fp, NULL, NULL, NULL); + } + fclose(fp); if (!rsa_key) { fprintf(stderr, "Unable to read RSA key from %s\n", infile); goto done; } + /* Public keys doesn't have the private exponent */ + has_priv = !!rsa_key->d; + if (!has_priv) + fprintf(stderr, "%s has a public key only.\n", infile); sig_alg = vb2_rsa_sig_alg(rsa_key); if (sig_alg == VB2_SIG_INVALID) { @@ -193,19 +203,21 @@ static int vb2_make_keypair() goto done; } - /* Create the private key */ - privkey = calloc(1, sizeof(*privkey)); - if (!privkey) { - fprintf(stderr, "Unable to allocate the private key\n"); - goto done; - } + if (has_priv) { + /* Create the private key */ + privkey = calloc(1, sizeof(*privkey)); + if (!privkey) { + fprintf(stderr, "Unable to allocate the private key\n"); + goto done; + } - privkey->rsa_private_key = rsa_key; - privkey->sig_alg = sig_alg; - privkey->hash_alg = opt_hash_alg; - if (opt_desc && vb2_private_key_set_desc(privkey, opt_desc)) { - fprintf(stderr, "Unable to set the private key description\n"); - goto done; + privkey->rsa_private_key = rsa_key; + privkey->sig_alg = sig_alg; + privkey->hash_alg = opt_hash_alg; + if (opt_desc && vb2_private_key_set_desc(privkey, opt_desc)) { + fprintf(stderr, "Unable to set the private key description\n"); + goto done; + } } /* Create the public key */ @@ -248,16 +260,18 @@ static int vb2_make_keypair() free(digest); } - privkey->id = opt_id; memcpy((struct vb2_id *)pubkey->id, &opt_id, sizeof(opt_id)); /* Write them out */ - strcpy(outext, ".vbprik2"); - if (vb2_private_key_write(privkey, outfile)) { - fprintf(stderr, "unable to write private key\n"); - goto done; + if (has_priv) { + privkey->id = opt_id; + strcpy(outext, ".vbprik2"); + if (vb2_private_key_write(privkey, outfile)) { + fprintf(stderr, "unable to write private key\n"); + goto done; + } + fprintf(stderr, "wrote %s\n", outfile); } - fprintf(stderr, "wrote %s\n", outfile); strcpy(outext, ".vbpubk2"); if (vb2_public_key_write(pubkey, outfile)) { diff --git a/futility/vb2_helper.c b/futility/vb2_helper.c index 4ee0a28b..51a78375 100644 --- a/futility/vb2_helper.c +++ b/futility/vb2_helper.c @@ -183,6 +183,11 @@ static RSA *rsa_from_buffer(uint8_t *buf, uint32_t len) return 0; rsa_key = PEM_read_bio_RSAPrivateKey(bp, NULL, NULL, NULL); + if (!rsa_key) { + if (BIO_reset(bp) < 0) + return 0; + rsa_key = PEM_read_bio_RSA_PUBKEY(bp, NULL, NULL, NULL); + } if (!rsa_key) { BIO_free(bp); return 0; @@ -212,13 +217,15 @@ int ft_show_pem(const char *name, uint8_t *buf, uint32_t len, void *data) uint32_t keyb_len; int i, bits; - printf("Private Key file: %s\n", name); - /* We're called only after ft_recognize_pem, so this should work. */ rsa_key = rsa_from_buffer(buf, len); if (!rsa_key) DIE; + /* Use to presence of the private exponent to decide if it's public */ + printf("%s Key file: %s\n", rsa_key->d ? "Private" : "Public", + name); + bits = BN_num_bits(rsa_key->n); printf(" Key length: %d\n", bits); diff --git a/tests/futility/test_create.sh b/tests/futility/test_create.sh index 662b2ddb..55c648c4 100755 --- a/tests/futility/test_create.sh +++ b/tests/futility/test_create.sh @@ -52,6 +52,18 @@ for sig in rsa1024 rsa2048 rsa4096 rsa8192; do [ "$pem_sum" = "$uniq_sums" ] done +# Demonstrate that we can create some vb21 public key from PEM containing +# only the pubkeypairs and verify it's the same as the one generated from +# the private key. +for sig in rsa1024 rsa2048 rsa4096 rsa8192; do + for hash in sha1 sha256 sha512; do + ${FUTILITY} --vb21 create --hash_alg "${hash}" \ + "${TESTKEYS}/key_${sig}.pub.pem" "${TMP}_key_${sig}.pubonly.${hash}" + cmp "${TMP}_key_${sig}.pubonly.${hash}.vbpubk2" \ + "${TMP}_key_${sig}.${hash}.vbpubk2" + done +done + # cleanup rm -rf ${TMP}* exit 0 diff --git a/tests/futility/test_file_types.sh b/tests/futility/test_file_types.sh index 470d6313..4b7a9fb6 100755 --- a/tests/futility/test_file_types.sh +++ b/tests/futility/test_file_types.sh @@ -43,6 +43,7 @@ test_case "prikey" "tests/devkeys/root_key.vbprivk" test_case "pubkey21" "tests/futility/data/sample.vbpubk2" test_case "prikey21" "tests/futility/data/sample.vbprik2" test_case "pem" "tests/testkeys/key_rsa2048.pem" +test_case "pem" "tests/testkeys/key_rsa8192.pub.pem" # Expect failure here. fail_case "/Sir/Not/Appearing/In/This/Film" diff --git a/tests/testkeys/key_rsa1024.pub.pem b/tests/testkeys/key_rsa1024.pub.pem new file mode 100644 index 00000000..85646f47 --- /dev/null +++ b/tests/testkeys/key_rsa1024.pub.pem @@ -0,0 +1,6 @@ +-----BEGIN PUBLIC KEY----- +MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCdYBOJIJvGX9vC4E5XD1jb9zJ9 +9FzR4G0n8HNyWy5ZKyy/hi80ibXpy6QdWcm4wqTvmVjU+20sP4AgzKC65fKyFvvA +HUiD4yGr1qWtg4YFUcBbUiXOCQ66W3AC4g2Ju9C16AzMpBk043bQsUQvxILEumQq +Q1VS33uM7Kq8dWpL6QIDAQAB +-----END PUBLIC KEY----- diff --git a/tests/testkeys/key_rsa2048.pub.pem b/tests/testkeys/key_rsa2048.pub.pem new file mode 100644 index 00000000..c45a80c8 --- /dev/null +++ b/tests/testkeys/key_rsa2048.pub.pem @@ -0,0 +1,9 @@ +-----BEGIN PUBLIC KEY----- +MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAlF3KFZo9kW2YYaUJTce1 +1BYEq9nTsP8E0+e+Tw5JUJ1M45s8UJSzOgKQeSLR3399TSq0WSqsSa8QFvBACv7L +mM7CgkgI4mMj2Zl96XJVyZP2+2c6hgvwRuB3eG6J5K2sW5YwiIz+5SQcPolp5F6r +17tMZzgidgIxrN32VvUZt5VplILTU4h7J9ZNaipoG3JdFloxqOqOda5Lksf8Cics +hGJqSiqgpvdx2zVNX9cjKNpqzEvZrNKPLKDteFzohPqrM7n2g+nKgAbwWLa9zELC +RG8h1qfbLOXOjrgVgy/g8t5ixWOrRBrbY5nQCv7eeKEetH8ru3ZMNtOgeWzOup0Q +1QIDAQAB +-----END PUBLIC KEY----- diff --git a/tests/testkeys/key_rsa4096.pub.pem b/tests/testkeys/key_rsa4096.pub.pem new file mode 100644 index 00000000..a36d44e0 --- /dev/null +++ b/tests/testkeys/key_rsa4096.pub.pem @@ -0,0 +1,14 @@ +-----BEGIN PUBLIC KEY----- +MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAm5v71oqFynujT4FVq5lK +aYxpmKfXdeBNKDmLzgu7fXLUKaEqTGEDsseE5qyaaP+dmTnQKfne7G31zgf46//Y +El+u5Gt/S4oAgYyvs3rjymzD5kVOLEAzgrIXAwyhDFARRzAFWos43hypunHGvu4f +DBAzZ3zGVulhjgAzD/gNjToVYCP7bj6kTaDx1u9siCKdYN09vGwSUt9WuV+yort7 +kns/B8ArVxt3bFSjsAxuWel/dJyLwCMQ9XAxdgWpg3RBUsK/KgekQybPLrhLYJn1 +AeOApwzJ4HoJSqU/1jCEaGrKA/KtCRXiurZz6lBi7sElsigjBvEZH0iCmmRgH3Oi +/cbpHIs1C6YHvCCbO90ntwgtDf0+2WJtFtbGt5Do3CXri0tcsXBWqISSK3VzzjHH +691BVwLuoBvF1XICMEjmq9aJ+MdbEe4E+GU8TV9NnRnuYyOUoxeisyXiArUUI9+1 +qL6pIgulTlY2Ch51QZY5n2aYY97PtosNotbSylMrLvWXGiiQWxux12eOnB3c/3wN +YWey8Km4cmOhEOYz7hLz2r1uIoC/SzM5wLnnTEQmaiUDNV9R3Gj3E3xkpTq3UNSS +PsV7k8lInMtWqzps6aTvBw1k6i6CUvWbEZqmt/0bimQHOEdg3OrJjQpwTKSp4ouS +yVu0IphDwy1yjKCfNWKRzrUCAwEAAQ== +-----END PUBLIC KEY----- diff --git a/tests/testkeys/key_rsa8192.pub.pem b/tests/testkeys/key_rsa8192.pub.pem new file mode 100644 index 00000000..616c955c --- /dev/null +++ b/tests/testkeys/key_rsa8192.pub.pem @@ -0,0 +1,25 @@ +-----BEGIN PUBLIC KEY----- +MIIEIjANBgkqhkiG9w0BAQEFAAOCBA8AMIIECgKCBAEA19BF/7el6ZXitFI71Glw +4/bjNiOWxRLO+zU2IKIJZYjatWWBOcB7pfnQQtoF6gtItnBT0/6NaCzucKd+TFb8 +Bz7pxK/ljSSJAFSOSf91b25mTcc4ohLkIvETX5g++jlaRuKDX5mnxUgEHUtMGvu5 +xMOSQi7UNM9Yxx26yRkIKaPNk2C5IeoXvKh9Xa4NS5hJSJnm3bG3oURAtugFS9ah +AAoM0+e21FrlAxCUiVzF/BJip7xN3COjo8noDda3RMDz12Udrwgrme+4xu0FOx1x +LGOIOgLzbP9HG56uGOMv58ExIem2YgTsMgHIbzqqnpymcnBes6DHhnRRK0jplIxF +pjqZqzSizYXUIY7vauiYXiZZnr5fpbrT+Y2b4Vza1PlPm68GkOgu39Cq4c+tjJJ3 +R/db9k+DWFfqfOLN4qqOO3szwnTtWQomj/4McZdpmapY5Fnofu01Rw9cg+V1OO/D +j1Q1BF7CqKmCEBICKT5Mk/oaTwZS4bWcgIJjPdBn9Im/bAulc9eGNg6Fo1Y+iVCj +DgLbQ+9SmFj6/JKlJRlAn21FburA+RaSirwF1IZ8eqMgUY6/Viu4eJNwbvWkeyaz +02Ss7hs6VRDhUSzJbg4OMIE4qjxNJcbuyAIbtQs39PtH/iIY/2kPaNFjKU+ah4CI +3kVIlgb/kgfqnUSQS4AHIubsZVpszUVE2A38R22OEGUenCLsljjWkv3snosY8gyJ +s9YumTGk2K/OiIAf0X8kXsv5Isq2ky+3T7PJYqQ67WjENCxEOi7AkDlJls7omAhT +8umGJPfF3R9izWYy5UJ4pNL2Cs8wv1vQcf9nDS5cpgqa6/w9sRo1bJjRlopi53Ph +6D+7CicoQP5M0tH2p3dD8qP6RZNqtWP0eOZ0el0DMFh5hjYXHDnxZaEL5fcpVX8F +drDltgFbUUYRDlJDr0j6/TXOdnAwyc6scAbwcWm9dKwJJQogRxXuvh11Yt8j8U3t +X95isL1QUIube3o8I7vXiMFRVRUg5NVM6sTgVsXRpybTecRsmDD76RerJEhi5vwf +mJz5qzLTSH9JgCY9EuI38WzmeGZ6F8kfRHEs9Gh5/XvOB7UsqZXaU5NTT5LBiiFX +IZoYFxnFpLl/crGc7oCP7JwsY0hW5CgK0829tY3aWLpY+a34Z2/wtc6dgKKA40Lj +7y3pKwwMFaPo+widtjVkCk3n9Rq0X6ubHi+uml42NYBRgvfoaZ4FbCTpRWV6kcGp +M76O3bqV63iS9wdOFK4IO0zrJ/QI73yHz9LU61BmQGVTze2+tSifYFersjvmoJrg +x703iljO9Xi1NfwoQpv0XwrdIgfHOSD1S3d1Id/R2tOBF7meHmCfki18KHOzk/2u +JQIDAQAB +-----END PUBLIC KEY----- -- cgit v1.2.1