123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241 |
- /*
- * Copyright 2015 The Chromium OS Authors. All rights reserved.
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
- #define OPENSSL_NO_SHA
- #include <openssl/pem.h>
- #include "2sysincludes.h"
- #include "2common.h"
- #include "2id.h"
- #include "2rsa.h"
- #include "2sha.h"
- #include "util_misc.h"
- #include "vb21_common.h"
- #include "host_common.h"
- #include "host_key2.h"
- #include "host_misc2.h"
- #include "file_type.h"
- #include "futility.h"
- int vb2_lookup_hash_alg(const char *str, enum vb2_hash_algorithm *alg)
- {
- const struct vb2_text_vs_enum *entry;
- uint32_t val;
- char *e;
- /* try string first */
- entry = vb2_lookup_by_name(vb2_text_vs_hash, str);
- if (entry) {
- *alg = entry->num;
- return 1;
- }
- /* fine, try number */
- val = strtoul(str, &e, 0);
- if (!*str || (e && *e))
- /* that's not a number */
- return 0;
- if (!vb2_lookup_by_num(vb2_text_vs_hash, val))
- /* That's not a valid alg */
- return 0;
- *alg = val;
- return 1;
- }
- enum futil_file_type ft_recognize_vb21_key(uint8_t *buf, uint32_t len)
- {
- struct vb2_public_key pubkey;
- struct vb2_private_key *privkey = 0;
- /* The pubkey points into buf, so nothing to free */
- if (VB2_SUCCESS == vb21_unpack_key(&pubkey, buf, len))
- return FILE_TYPE_VB2_PUBKEY;
- /* The private key unpacks into new structs */
- if (VB2_SUCCESS == vb21_private_key_unpack(&privkey, buf, len)) {
- vb2_private_key_free(privkey);
- return FILE_TYPE_VB2_PRIVKEY;
- }
- return FILE_TYPE_UNKNOWN;
- }
- static inline void vb2_print_bytes(const void *ptr, uint32_t len)
- {
- const uint8_t *buf = (const uint8_t *)ptr;
- int i;
- for (i = 0; i < len; i++)
- printf("%02x", *buf++);
- }
- static int vb2_public_key_sha1sum(struct vb2_public_key *key, uint8_t *digest)
- {
- struct vb21_packed_key *pkey;
- if (vb21_public_key_pack(&pkey, key))
- return 0;
- vb2_digest_buffer((uint8_t *)pkey + pkey->key_offset, pkey->key_size,
- VB2_HASH_SHA1, digest, VB2_SHA1_DIGEST_SIZE);
- free(pkey);
- return 1;
- }
- int ft_show_vb21_pubkey(const char *name, uint8_t *buf, uint32_t len,
- void *data)
- {
- struct vb2_public_key key;
- uint8_t sha1sum[VB2_SHA1_DIGEST_SIZE];
- /* The key's members will point into the state buffer after this. Don't
- * free anything. */
- if (VB2_SUCCESS != vb21_unpack_key(&key, buf, len))
- return 1;
- printf("Public Key file: %s\n", name);
- printf(" Vboot API: 2.1\n");
- printf(" Desc: \"%s\"\n", key.desc);
- printf(" Signature Algorithm: %d %s\n", key.sig_alg,
- vb2_get_sig_algorithm_name(key.sig_alg));
- printf(" Hash Algorithm: %d %s\n", key.hash_alg,
- vb2_get_hash_algorithm_name(key.hash_alg));
- printf(" Version: 0x%08x\n", key.version);
- printf(" ID: ");
- vb2_print_bytes(key.id, sizeof(*key.id));
- printf("\n");
- if (vb2_public_key_sha1sum(&key, sha1sum) &&
- memcmp(key.id, sha1sum, sizeof(*key.id))) {
- printf(" Key sha1sum: ");
- vb2_print_bytes(sha1sum, sizeof(sha1sum));
- printf("\n");
- }
- return 0;
- }
- static int vb2_private_key_sha1sum(struct vb2_private_key *key, uint8_t *digest)
- {
- uint8_t *buf;
- uint32_t buflen;
- if (vb_keyb_from_rsa(key->rsa_private_key, &buf, &buflen))
- return 0;
- vb2_digest_buffer(buf, buflen, VB2_HASH_SHA1, digest,
- VB2_SHA1_DIGEST_SIZE);
- free(buf);
- return 1;
- }
- int ft_show_vb21_privkey(const char *name, uint8_t *buf, uint32_t len,
- void *data)
- {
- struct vb2_private_key *key = 0;
- uint8_t sha1sum[VB2_SHA1_DIGEST_SIZE];
- if (VB2_SUCCESS != vb21_private_key_unpack(&key, buf, len))
- return 1;
- printf("Private key file: %s\n", name);
- printf(" Vboot API: 2.1\n");
- printf(" Desc: \"%s\"\n", key->desc ? key->desc : "");
- printf(" Signature Algorithm: %d %s\n", key->sig_alg,
- vb2_get_sig_algorithm_name(key->sig_alg));
- printf(" Hash Algorithm: %d %s\n", key->hash_alg,
- vb2_get_hash_algorithm_name(key->hash_alg));
- printf(" ID: ");
- vb2_print_bytes(&key->id, sizeof(key->id));
- printf("\n");
- if (vb2_private_key_sha1sum(key, sha1sum) &&
- memcmp(&key->id, sha1sum, sizeof(key->id))) {
- printf(" Key sha1sum: ");
- vb2_print_bytes(sha1sum, sizeof(sha1sum));
- printf("\n");
- }
- vb2_private_key_free(key);
- return 0;
- }
- static RSA *rsa_from_buffer(uint8_t *buf, uint32_t len)
- {
- BIO *bp;
- RSA *rsa_key;
- bp = BIO_new_mem_buf(buf, len);
- if (!bp)
- 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;
- }
- BIO_free(bp);
- return rsa_key;
- }
- enum futil_file_type ft_recognize_pem(uint8_t *buf, uint32_t len)
- {
- RSA *rsa_key = rsa_from_buffer(buf, len);
- if (rsa_key) {
- RSA_free(rsa_key);
- return FILE_TYPE_PEM;
- }
- return FILE_TYPE_UNKNOWN;
- }
- int ft_show_pem(const char *name, uint8_t *buf, uint32_t len, void *data)
- {
- RSA *rsa_key;
- uint8_t *keyb;
- uint8_t digest[VB2_SHA1_DIGEST_SIZE];
- uint32_t keyb_len;
- int i, bits;
- /* 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);
- if (vb_keyb_from_rsa(rsa_key, &keyb, &keyb_len)) {
- printf(" Key sha1sum: <error>");
- RSA_free(rsa_key);
- return 1;
- }
- printf(" Key sha1sum: ");
- vb2_digest_buffer(keyb, keyb_len, VB2_HASH_SHA1,
- digest, sizeof(digest));
- for (i = 0; i < sizeof(digest); i++)
- printf("%02x", digest[i]);
- printf("\n");
- free(keyb);
- RSA_free(rsa_key);
- return 0;
- }
|