Path: blob/main/contrib/libfido2/tools/assert_verify.c
39534 views
/*1* Copyright (c) 2018-2022 Yubico AB. All rights reserved.2* Use of this source code is governed by a BSD-style3* license that can be found in the LICENSE file.4* SPDX-License-Identifier: BSD-2-Clause5*/67#include <fido.h>8#include <fido/es256.h>9#include <fido/es384.h>10#include <fido/rs256.h>11#include <fido/eddsa.h>1213#include <stdio.h>14#include <stdlib.h>15#include <string.h>16#ifdef HAVE_UNISTD_H17#include <unistd.h>18#endif1920#include "../openbsd-compat/openbsd-compat.h"21#include "extern.h"2223static fido_assert_t *24prepare_assert(FILE *in_f, int flags)25{26fido_assert_t *assert = NULL;27struct blob cdh;28struct blob authdata;29struct blob sig;30char *rpid = NULL;31int r;3233memset(&cdh, 0, sizeof(cdh));34memset(&authdata, 0, sizeof(authdata));35memset(&sig, 0, sizeof(sig));3637r = base64_read(in_f, &cdh);38r |= string_read(in_f, &rpid);39r |= base64_read(in_f, &authdata);40r |= base64_read(in_f, &sig);41if (r < 0)42errx(1, "input error");4344if (flags & FLAG_DEBUG) {45fprintf(stderr, "client data hash:\n");46xxd(cdh.ptr, cdh.len);47fprintf(stderr, "relying party id: %s\n", rpid);48fprintf(stderr, "authenticator data:\n");49xxd(authdata.ptr, authdata.len);50fprintf(stderr, "signature:\n");51xxd(sig.ptr, sig.len);52}5354if ((assert = fido_assert_new()) == NULL)55errx(1, "fido_assert_new");56if ((r = fido_assert_set_count(assert, 1)) != FIDO_OK)57errx(1, "fido_assert_count: %s", fido_strerr(r));5859if ((r = fido_assert_set_clientdata_hash(assert, cdh.ptr,60cdh.len)) != FIDO_OK ||61(r = fido_assert_set_rp(assert, rpid)) != FIDO_OK ||62(r = fido_assert_set_authdata(assert, 0, authdata.ptr,63authdata.len)) != FIDO_OK ||64(r = fido_assert_set_sig(assert, 0, sig.ptr, sig.len)) != FIDO_OK)65errx(1, "fido_assert_set: %s", fido_strerr(r));6667if (flags & FLAG_UP) {68if ((r = fido_assert_set_up(assert, FIDO_OPT_TRUE)) != FIDO_OK)69errx(1, "fido_assert_set_up: %s", fido_strerr(r));70}71if (flags & FLAG_UV) {72if ((r = fido_assert_set_uv(assert, FIDO_OPT_TRUE)) != FIDO_OK)73errx(1, "fido_assert_set_uv: %s", fido_strerr(r));74}75if (flags & FLAG_HMAC) {76if ((r = fido_assert_set_extensions(assert,77FIDO_EXT_HMAC_SECRET)) != FIDO_OK)78errx(1, "fido_assert_set_extensions: %s",79fido_strerr(r));80}8182free(cdh.ptr);83free(authdata.ptr);84free(sig.ptr);85free(rpid);8687return (assert);88}8990static void *91load_pubkey(int type, const char *file)92{93EC_KEY *ec = NULL;94RSA *rsa = NULL;95EVP_PKEY *eddsa = NULL;96es256_pk_t *es256_pk = NULL;97es384_pk_t *es384_pk = NULL;98rs256_pk_t *rs256_pk = NULL;99eddsa_pk_t *eddsa_pk = NULL;100void *pk = NULL;101102switch (type) {103case COSE_ES256:104if ((ec = read_ec_pubkey(file)) == NULL)105errx(1, "read_ec_pubkey");106if ((es256_pk = es256_pk_new()) == NULL)107errx(1, "es256_pk_new");108if (es256_pk_from_EC_KEY(es256_pk, ec) != FIDO_OK)109errx(1, "es256_pk_from_EC_KEY");110pk = es256_pk;111EC_KEY_free(ec);112break;113case COSE_ES384:114if ((ec = read_ec_pubkey(file)) == NULL)115errx(1, "read_ec_pubkey");116if ((es384_pk = es384_pk_new()) == NULL)117errx(1, "es384_pk_new");118if (es384_pk_from_EC_KEY(es384_pk, ec) != FIDO_OK)119errx(1, "es384_pk_from_EC_KEY");120pk = es384_pk;121EC_KEY_free(ec);122break;123case COSE_RS256:124if ((rsa = read_rsa_pubkey(file)) == NULL)125errx(1, "read_rsa_pubkey");126if ((rs256_pk = rs256_pk_new()) == NULL)127errx(1, "rs256_pk_new");128if (rs256_pk_from_RSA(rs256_pk, rsa) != FIDO_OK)129errx(1, "rs256_pk_from_RSA");130pk = rs256_pk;131RSA_free(rsa);132break;133case COSE_EDDSA:134if ((eddsa = read_eddsa_pubkey(file)) == NULL)135errx(1, "read_eddsa_pubkey");136if ((eddsa_pk = eddsa_pk_new()) == NULL)137errx(1, "eddsa_pk_new");138if (eddsa_pk_from_EVP_PKEY(eddsa_pk, eddsa) != FIDO_OK)139errx(1, "eddsa_pk_from_EVP_PKEY");140pk = eddsa_pk;141EVP_PKEY_free(eddsa);142break;143default:144errx(1, "invalid type %d", type);145}146147return (pk);148}149150int151assert_verify(int argc, char **argv)152{153fido_assert_t *assert = NULL;154void *pk = NULL;155char *in_path = NULL;156FILE *in_f = NULL;157int type = COSE_ES256;158int flags = 0;159int ch;160int r;161162while ((ch = getopt(argc, argv, "dhi:pv")) != -1) {163switch (ch) {164case 'd':165flags |= FLAG_DEBUG;166break;167case 'h':168flags |= FLAG_HMAC;169break;170case 'i':171in_path = optarg;172break;173case 'p':174flags |= FLAG_UP;175break;176case 'v':177flags |= FLAG_UV;178break;179default:180usage();181}182}183184argc -= optind;185argv += optind;186187if (argc < 1 || argc > 2)188usage();189190in_f = open_read(in_path);191192if (argc > 1 && cose_type(argv[1], &type) < 0)193errx(1, "unknown type %s", argv[1]);194195fido_init((flags & FLAG_DEBUG) ? FIDO_DEBUG : 0);196197pk = load_pubkey(type, argv[0]);198assert = prepare_assert(in_f, flags);199if ((r = fido_assert_verify(assert, 0, type, pk)) != FIDO_OK)200errx(1, "fido_assert_verify: %s", fido_strerr(r));201fido_assert_free(&assert);202203fclose(in_f);204in_f = NULL;205206exit(0);207}208209210