static int vb2_make_keypair() { struct vb2_private_key *privkey = 0; struct vb2_public_key *pubkey = 0; RSA *rsa_key = 0; uint8_t *keyb_data = 0; uint32_t keyb_size; enum vb2_signature_algorithm sig_alg; uint8_t *pubkey_buf = 0; int has_priv = 0; FILE *fp; int ret = 1; fp = fopen(infile, "rb"); if (!fp) { fprintf(stderr, "Unable to open %s\n", infile); goto done; } rsa_key = PEM_read_RSAPrivateKey(fp, NULL, NULL, NULL); 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) { fprintf(stderr, "Unsupported sig algorithm in RSA 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; } } /* Create the public key */ if (vb2_public_key_alloc(&pubkey, sig_alg)) { fprintf(stderr, "Unable to allocate the public key\n"); goto done; } /* Extract the keyb blob */ if (vb_keyb_from_rsa(rsa_key, &keyb_data, &keyb_size)) { fprintf(stderr, "Couldn't extract the public key\n"); goto done; } /* * Copy the keyb blob to the public key's buffer, because that's where * vb2_unpack_key_data() and vb2_public_key_pack() expect to find it. */ pubkey_buf = vb2_public_key_packed_data(pubkey); memcpy(pubkey_buf, keyb_data, keyb_size); /* Fill in the internal struct pointers */ if (vb2_unpack_key_data(pubkey, pubkey_buf, keyb_size)) { fprintf(stderr, "Unable to unpack the public key blob\n"); goto done; } pubkey->hash_alg = opt_hash_alg; pubkey->version = opt_version; if (opt_desc && vb2_public_key_set_desc(pubkey, opt_desc)) { fprintf(stderr, "Unable to set pubkey description\n"); goto done; } /* Update the IDs */ if (!force_id) { uint8_t *digest = DigestBuf(keyb_data, keyb_size, SHA1_DIGEST_ALGORITHM); memcpy(&opt_id, digest, sizeof(opt_id)); free(digest); } memcpy((struct vb2_id *)pubkey->id, &opt_id, sizeof(opt_id)); /* Write them out */ 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); } strcpy(outext, ".vbpubk2"); if (vb2_public_key_write(pubkey, outfile)) { fprintf(stderr, "unable to write public key\n"); goto done; } fprintf(stderr, "wrote %s\n", outfile); ret = 0; done: RSA_free(rsa_key); if (privkey) /* prevent double-free */ privkey->rsa_private_key = 0; vb2_private_key_free(privkey); vb2_public_key_free(pubkey); free(keyb_data); return ret; }
static void keyblock_tests(const char *keys_dir) { struct vb2_public_key *pubk2048, *pubk4096, *pubk8192, pubkhash; struct vb2_private_key *prik4096, *prik8192; struct vb2_packed_key *pak, *pakgood; struct vb2_keyblock *kb; const struct vb2_private_key *prikhash; const struct vb2_private_key *prik[2]; char fname[1024]; const char test_desc[] = "Test keyblock"; uint8_t workbuf[VB2_KEY_BLOCK_VERIFY_WORKBUF_BYTES] __attribute__ ((aligned (VB2_WORKBUF_ALIGN))); struct vb2_workbuf wb; vb2_workbuf_init(&wb, workbuf, sizeof(workbuf)); /* Read keys */ sprintf(fname, "%s/key_rsa2048.keyb", keys_dir); TEST_SUCC(vb2_public_key_read_keyb(&pubk2048, fname), "Read public key 2"); vb2_public_key_set_desc(pubk2048, "Test RSA2048 public key"); pubk2048->hash_alg = VB2_HASH_SHA256; sprintf(fname, "%s/key_rsa4096.keyb", keys_dir); TEST_SUCC(vb2_public_key_read_keyb(&pubk4096, fname), "Read public key 1"); vb2_public_key_set_desc(pubk4096, "Test RSA4096 public key"); pubk4096->hash_alg = VB2_HASH_SHA256; sprintf(fname, "%s/key_rsa8192.keyb", keys_dir); TEST_SUCC(vb2_public_key_read_keyb(&pubk8192, fname), "Read public key 2"); vb2_public_key_set_desc(pubk8192, "Test RSA8192 public key"); pubk8192->hash_alg = VB2_HASH_SHA512; sprintf(fname, "%s/key_rsa4096.pem", keys_dir); TEST_SUCC(vb2_private_key_read_pem(&prik4096, fname), "Read private key 2"); vb2_private_key_set_desc(prik4096, "Test RSA4096 private key"); prik4096->sig_alg = VB2_SIG_RSA4096; prik4096->hash_alg = VB2_HASH_SHA256; sprintf(fname, "%s/key_rsa8192.pem", keys_dir); TEST_SUCC(vb2_private_key_read_pem(&prik8192, fname), "Read private key 1"); vb2_private_key_set_desc(prik8192, "Test RSA8192 private key"); prik8192->sig_alg = VB2_SIG_RSA8192; prik8192->hash_alg = VB2_HASH_SHA512; TEST_SUCC(vb2_private_key_hash(&prikhash, VB2_HASH_SHA512), "Create private hash key"); TEST_SUCC(vb2_public_key_hash(&pubkhash, VB2_HASH_SHA512), "Create public hash key"); TEST_SUCC(vb2_public_key_pack(&pakgood, pubk2048), "Test packed key"); /* Sign a keyblock with one key */ prik[0] = prik4096; TEST_SUCC(vb2_keyblock_create(&kb, pubk2048, prik, 1, 0x1234, NULL), "Keyblock single"); TEST_PTR_NEQ(kb, NULL, " kb_ptr"); TEST_SUCC(vb2_verify_keyblock(kb, kb->c.total_size, pubk4096, &wb), " verify"); TEST_EQ(strcmp(vb2_common_desc(kb), pubk2048->desc), 0, " desc"); TEST_EQ(kb->flags, 0x1234, " flags"); pak = (struct vb2_packed_key *)((uint8_t *)kb + kb->key_offset); TEST_EQ(0, memcmp(pak, pakgood, pakgood->c.total_size), " data key"); free(kb); /* Sign a keyblock with two keys */ prik[0] = prik8192; prik[1] = prikhash; TEST_SUCC(vb2_keyblock_create(&kb, pubk4096, prik, 2, 0, test_desc), "Keyblock multiple"); TEST_SUCC(vb2_verify_keyblock(kb, kb->c.total_size, pubk8192, &wb), " verify 1"); TEST_SUCC(vb2_verify_keyblock(kb, kb->c.total_size, &pubkhash, &wb), " verify 2"); TEST_EQ(strcmp(vb2_common_desc(kb), test_desc), 0, " desc"); TEST_EQ(kb->flags, 0, " flags"); free(kb); /* Test errors */ prik[0] = prik8192; prik8192->hash_alg = VB2_HASH_INVALID; TEST_EQ(vb2_keyblock_create(&kb, pubk4096, prik, 1, 0, NULL), VB2_KEYBLOCK_CREATE_SIG_SIZE, "Keyblock bad sig size"); TEST_PTR_EQ(kb, NULL, " kb_ptr"); prik[0] = prik4096; pubk4096->sig_alg = VB2_SIG_INVALID; TEST_EQ(vb2_keyblock_create(&kb, pubk4096, prik, 1, 0, NULL), VB2_KEYBLOCK_CREATE_DATA_KEY, "Keyblock bad data key"); /* Free keys */ free(pakgood); vb2_public_key_free(pubk2048); vb2_public_key_free(pubk4096); vb2_public_key_free(pubk8192); vb2_private_key_free(prik4096); vb2_private_key_free(prik8192); }
static int vb2_make_keypair() { struct vb2_private_key *privkey = 0; struct vb2_public_key *pubkey = 0; RSA *rsa_key = 0; uint8_t *keyb_data = 0; uint32_t keyb_size; enum vb2_signature_algorithm sig_alg; uint8_t *pubkey_buf = 0; FILE *fp; int ret = 1; fp = fopen(infile, "rb"); if (!fp) { fprintf(stderr, "Unable to open %s\n", infile); goto done; } rsa_key = PEM_read_RSAPrivateKey(fp, NULL, NULL, NULL); fclose(fp); if (!rsa_key) { fprintf(stderr, "Unable to read RSA key from %s\n", infile); goto done; } sig_alg = vb2_rsa_sig_alg(rsa_key); if (sig_alg == VB2_SIG_INVALID) { fprintf(stderr, "Unsupported sig algorithm in RSA key\n"); goto done; } /* 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; privkey->guid = opt_guid; if (opt_desc && vb2_private_key_set_desc(privkey, opt_desc)) { fprintf(stderr, "Unable to set the private key description\n"); goto done; } /* Write it out */ 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); /* Create the public key */ if (vb2_public_key_alloc(&pubkey, sig_alg)) { fprintf(stderr, "Unable to allocate the public key\n"); goto done; } /* Extract the keyb blob */ if (vb_keyb_from_rsa(rsa_key, &keyb_data, &keyb_size)) { fprintf(stderr, "Couldn't extract the public key\n"); goto done; } /* * Copy the keyb blob to the public key's buffer, because that's where * vb2_unpack_key_data() and vb2_public_key_pack() expect to find it. */ pubkey_buf = vb2_public_key_packed_data(pubkey); memcpy(pubkey_buf, keyb_data, keyb_size); /* Fill in the internal struct pointers */ if (vb2_unpack_key_data(pubkey, pubkey_buf, keyb_size)) { fprintf(stderr, "Unable to unpack the public key blob\n"); goto done; } pubkey->hash_alg = opt_hash_alg; pubkey->version = opt_version; memcpy((struct vb2_guid *)pubkey->guid, &opt_guid, sizeof(opt_guid)); if (opt_desc && vb2_public_key_set_desc(pubkey, opt_desc)) { fprintf(stderr, "Unable to set pubkey description\n"); goto done; } /* Write it out */ strcpy(outext, ".vbpubk2"); if (vb2_public_key_write(pubkey, outfile)) { fprintf(stderr, "unable to write public key\n"); goto done; } fprintf(stderr, "wrote %s\n", outfile); ret = 0; done: RSA_free(rsa_key); if (privkey) /* prevent double-free */ privkey->rsa_private_key = 0; vb2_private_key_free(privkey); vb2_public_key_free(pubkey); free(keyb_data); return ret; }