Newer
Older
SigningTool / register.c
/* SPDX-License-Identifier: LGPL-2.1-or-later */
/* Copyright: Jookia 2021 <contact@jookia.org> */

#include <stdio.h>
#include <fido.h>
#include <fido/es256.h>
#include <openssl/ec.h>
#include <openssl/pem.h>

unsigned char my_user_id[] = {
  0x15, 0xf9, 0x5d, 0x3e, 0xce, 0xe9, 0x17, 0x3e, 0x25, 0x8e, 0xe6, 0x20,
  0x92, 0xcf, 0xff, 0x9b, 0xe0, 0xcf, 0xf9, 0xca, 0x50, 0x8d, 0x1f, 0x24,
  0xf1, 0xa7, 0xeb, 0x68, 0x7d, 0xb7, 0x82, 0x5d
};
unsigned int my_user_id_len = 32;
unsigned char cd_hash[] = {
  0xc0, 0x9e, 0xfa, 0x40, 0x30, 0x66, 0x31, 0xbd, 0xd9, 0x3a, 0xcf, 0xbd,
  0xab, 0x8d, 0x63, 0xc4, 0x0c, 0x99, 0x43, 0x43, 0xe4, 0x13, 0x85, 0x20,
  0xe2, 0x59, 0x2d, 0x41, 0xe9, 0xa0, 0xdd, 0xb1
};
unsigned int cd_hash_len = 32;

#define MAX_FIDO_DEVICES 8

#define FIDO_CHECK(x) do { int err = x; if(err != FIDO_OK) { printf("FIDO ERR %i %s line %i\n", err, fido_strerr(err), __LINE__); exit(1); } } while(0)

int main(void) {
  printf("SigningTool register\n");
  fido_init(FIDO_DEBUG);
  printf("Searching for devices\n");
  fido_dev_info_t *devs = fido_dev_info_new(MAX_FIDO_DEVICES);
  FIDO_CHECK(!devs);
  size_t found = 0;
  FIDO_CHECK(fido_dev_info_manifest(devs, MAX_FIDO_DEVICES, &found));
  printf("Found %zu devices\n", found);
  const char *path;
  for(size_t i = 0; i < found; ++i) {
    fido_dev_info_t const *dev_info = fido_dev_info_ptr(devs, i);
    FIDO_CHECK(!dev_info);
    path = fido_dev_info_path(dev_info);
    printf("Device %zu is %s\n", i, path);
  }
  printf("Opening device\n");
  fido_dev_t *dev = fido_dev_new();
  FIDO_CHECK(!dev);
  FIDO_CHECK(fido_dev_open(dev, path));
  fido_dev_info_free(&devs, MAX_FIDO_DEVICES);
  printf("Forcing U2F\n");
  fido_dev_force_u2f(dev);
  printf("Making credential\n");
  fido_cred_t* cred = fido_cred_new();
  FIDO_CHECK(!cred);
  FIDO_CHECK(fido_cred_set_type(cred, COSE_ES256)); /* COSE_ES256, COSE_RS256, COSE_EDDSA */
  FIDO_CHECK(fido_cred_set_clientdata_hash(cred, cd_hash, cd_hash_len));
  FIDO_CHECK(fido_cred_set_user(cred, my_user_id, my_user_id_len, NULL, NULL, NULL));
  FIDO_CHECK(fido_cred_set_rp(cred, "id", "name"));
  FIDO_CHECK(fido_cred_set_fmt(cred, "packed"));
  printf("Generating credential\n");
  FIDO_CHECK(fido_dev_make_cred(dev, cred, NULL));
  fido_dev_close(dev);
  fido_dev_free(&dev);
  printf("Verifying attestation\n");
  FIDO_CHECK(fido_cred_verify(cred));
  printf("Getting generated data\n");
  unsigned char const *pubkey = fido_cred_pubkey_ptr(cred);
  unsigned char const *authdata = fido_cred_authdata_ptr(cred);
  unsigned char const *cred_id = fido_cred_id_ptr(cred);
  size_t pubkey_len = fido_cred_pubkey_len(cred);
  size_t authdata_len = fido_cred_authdata_len(cred);
  size_t cred_id_len = fido_cred_id_len(cred);
  FIDO_CHECK(!pubkey);
  FIDO_CHECK(!authdata);
  FIDO_CHECK(!cred_id);
  printf("Write generated data\n");
  FILE *file = fopen("cred_id.bin", "w");
  fwrite(cred_id, cred_id_len, 1, file);
  fclose(file);
  file = fopen("authdata.bin", "w");
  fwrite(authdata, authdata_len, 1, file);
  fclose(file);
  printf("Write pubkey\n");
  es256_pk_t *key = es256_pk_new();
  FIDO_CHECK(!key);
  FIDO_CHECK(es256_pk_from_ptr(key, pubkey, pubkey_len));
  EVP_PKEY *evp_pkey = es256_pk_to_EVP_PKEY(key);
  FIDO_CHECK(evp_pkey == 0);
  es256_pk_free(&key);
  file = fopen("pubkey.pem", "w");
  PEM_write_PUBKEY(file, evp_pkey);
  fclose(file);
  /* Cleanup */
  fido_cred_free(&cred);
  return 0;
}