From 75073d0a8478441cc97a6efa10b566c5fb1dac81 Mon Sep 17 00:00:00 2001 From: Colin Watson Date: Fri, 17 Apr 2020 20:57:17 +0100 Subject: New upstream version 1.4.0 --- src/cred.c | 122 ++++++++++++++++++++++++++----------------------------------- 1 file changed, 52 insertions(+), 70 deletions(-) (limited to 'src/cred.c') diff --git a/src/cred.c b/src/cred.c index c4e1edb..4ecbba8 100644 --- a/src/cred.c +++ b/src/cred.c @@ -76,8 +76,8 @@ fido_dev_make_cred_tx(fido_dev_t *dev, fido_cred_t *cred, const char *pin) } /* extensions */ - if (cred->ext) - if ((argv[5] = cbor_encode_extensions(cred->ext)) == NULL) { + if (cred->ext.mask) + if ((argv[5] = cbor_encode_extensions(&cred->ext)) == NULL) { fido_log_debug("%s: cbor_encode_extensions", __func__); r = FIDO_ERR_INTERNAL; goto fail; @@ -106,8 +106,8 @@ fido_dev_make_cred_tx(fido_dev_t *dev, fido_cred_t *cred, const char *pin) } /* framing and transmission */ - if (cbor_build_frame(CTAP_CBOR_MAKECRED, argv, 9, &f) < 0 || - fido_tx(dev, CTAP_FRAME_INIT | CTAP_CMD_CBOR, f.ptr, f.len) < 0) { + if (cbor_build_frame(CTAP_CBOR_MAKECRED, argv, nitems(argv), &f) < 0 || + fido_tx(dev, CTAP_CMD_CBOR, f.ptr, f.len) < 0) { fido_log_debug("%s: fido_tx", __func__); r = FIDO_ERR_TX; goto fail; @@ -126,14 +126,14 @@ fail: static int fido_dev_make_cred_rx(fido_dev_t *dev, fido_cred_t *cred, int ms) { - const uint8_t cmd = CTAP_FRAME_INIT | CTAP_CMD_CBOR; - unsigned char reply[2048]; + unsigned char reply[FIDO_MAXMSG]; int reply_len; int r; fido_cred_reset_rx(cred); - if ((reply_len = fido_rx(dev, cmd, &reply, sizeof(reply), ms)) < 0) { + if ((reply_len = fido_rx(dev, CTAP_CMD_CBOR, &reply, sizeof(reply), + ms)) < 0) { fido_log_debug("%s: fido_rx", __func__); return (FIDO_ERR_RX); } @@ -170,7 +170,8 @@ int fido_dev_make_cred(fido_dev_t *dev, fido_cred_t *cred, const char *pin) { if (fido_dev_is_fido2(dev) == false) { - if (pin != NULL || cred->rk == FIDO_OPT_TRUE || cred->ext != 0) + if (pin != NULL || cred->rk == FIDO_OPT_TRUE || + cred->ext.mask != 0) return (FIDO_ERR_UNSUPPORTED_OPTION); return (u2f_register(dev, cred, -1)); } @@ -179,15 +180,9 @@ fido_dev_make_cred(fido_dev_t *dev, fido_cred_t *cred, const char *pin) } static int -check_extensions(int authdata_ext, int ext) +check_extensions(const fido_cred_ext_t *authdata_ext, const fido_cred_ext_t *ext) { - if (authdata_ext != ext) { - fido_log_debug("%s: authdata_ext=0x%x != ext=0x%x", __func__, - authdata_ext, ext); - return (-1); - } - - return (0); + return (timingsafe_bcmp(authdata_ext, ext, sizeof(*authdata_ext))); } int @@ -207,48 +202,6 @@ fido_check_rp_id(const char *id, const unsigned char *obtained_hash) SHA256_DIGEST_LENGTH)); } -static int -get_signed_hash_packed(fido_blob_t *dgst, const fido_blob_t *clientdata, - const fido_blob_t *authdata_cbor) -{ - cbor_item_t *item = NULL; - unsigned char *authdata_ptr = NULL; - size_t authdata_len; - struct cbor_load_result cbor; - SHA256_CTX ctx; - int ok = -1; - - if ((item = cbor_load(authdata_cbor->ptr, authdata_cbor->len, - &cbor)) == NULL) { - fido_log_debug("%s: cbor_load", __func__); - goto fail; - } - - if (cbor_isa_bytestring(item) == false || - cbor_bytestring_is_definite(item) == false) { - fido_log_debug("%s: cbor type", __func__); - goto fail; - } - - authdata_ptr = cbor_bytestring_handle(item); - authdata_len = cbor_bytestring_length(item); - - if (dgst->len != SHA256_DIGEST_LENGTH || SHA256_Init(&ctx) == 0 || - SHA256_Update(&ctx, authdata_ptr, authdata_len) == 0 || - SHA256_Update(&ctx, clientdata->ptr, clientdata->len) == 0 || - SHA256_Final(dgst->ptr, &ctx) == 0) { - fido_log_debug("%s: sha256", __func__); - goto fail; - } - - ok = 0; -fail: - if (item != NULL) - cbor_decref(&item); - - return (ok); -} - static int get_signed_hash_u2f(fido_blob_t *dgst, const unsigned char *rp_id, size_t rp_id_len, const fido_blob_t *clientdata, const fido_blob_t *id, @@ -356,16 +309,16 @@ fido_cred_verify(const fido_cred_t *cred) goto out; } - if (check_extensions(cred->authdata_ext, cred->ext) < 0) { + if (check_extensions(&cred->authdata_ext, &cred->ext) != 0) { fido_log_debug("%s: check_extensions", __func__); r = FIDO_ERR_INVALID_PARAM; goto out; } if (!strcmp(cred->fmt, "packed")) { - if (get_signed_hash_packed(&dgst, &cred->cdh, + if (fido_get_signed_hash(COSE_ES256, &dgst, &cred->cdh, &cred->authdata_cbor) < 0) { - fido_log_debug("%s: get_signed_hash_packed", __func__); + fido_log_debug("%s: fido_get_signed_hash", __func__); r = FIDO_ERR_INTERNAL; goto out; } @@ -395,7 +348,7 @@ out: int fido_cred_verify_self(const fido_cred_t *cred) { - unsigned char buf[SHA256_DIGEST_LENGTH]; + unsigned char buf[1024]; /* XXX */ fido_blob_t dgst; int ok = -1; int r; @@ -431,16 +384,16 @@ fido_cred_verify_self(const fido_cred_t *cred) goto out; } - if (check_extensions(cred->authdata_ext, cred->ext) < 0) { + if (check_extensions(&cred->authdata_ext, &cred->ext) != 0) { fido_log_debug("%s: check_extensions", __func__); r = FIDO_ERR_INVALID_PARAM; goto out; } if (!strcmp(cred->fmt, "packed")) { - if (get_signed_hash_packed(&dgst, &cred->cdh, + if (fido_get_signed_hash(cred->attcred.type, &dgst, &cred->cdh, &cred->authdata_cbor) < 0) { - fido_log_debug("%s: get_signed_hash_packed", __func__); + fido_log_debug("%s: fido_get_signed_hash", __func__); r = FIDO_ERR_INTERNAL; goto out; } @@ -519,9 +472,9 @@ fido_cred_reset_tx(fido_cred_t *cred) memset(&cred->rp, 0, sizeof(cred->rp)); memset(&cred->user, 0, sizeof(cred->user)); memset(&cred->excl, 0, sizeof(cred->excl)); + memset(&cred->ext, 0, sizeof(cred->ext)); cred->type = 0; - cred->ext = 0; cred->rk = FIDO_OPT_OMIT; cred->uv = FIDO_OPT_OMIT; } @@ -810,10 +763,14 @@ fail: int fido_cred_set_extensions(fido_cred_t *cred, int ext) { - if (ext != 0 && ext != FIDO_EXT_HMAC_SECRET) - return (FIDO_ERR_INVALID_ARGUMENT); - - cred->ext = ext; + if (ext == 0) + cred->ext.mask = 0; + else { + if (ext != FIDO_EXT_HMAC_SECRET && + ext != FIDO_EXT_CRED_PROTECT) + return (FIDO_ERR_INVALID_ARGUMENT); + cred->ext.mask |= ext; + } return (FIDO_OK); } @@ -843,6 +800,25 @@ fido_cred_set_uv(fido_cred_t *cred, fido_opt_t uv) return (FIDO_OK); } +int +fido_cred_set_prot(fido_cred_t *cred, int prot) +{ + if (prot == 0) { + cred->ext.mask &= ~FIDO_EXT_CRED_PROTECT; + cred->ext.prot = 0; + } else { + if (prot != FIDO_CRED_PROT_UV_OPTIONAL && + prot != FIDO_CRED_PROT_UV_OPTIONAL_WITH_ID && + prot != FIDO_CRED_PROT_UV_REQUIRED) + return (FIDO_ERR_INVALID_ARGUMENT); + + cred->ext.mask |= FIDO_EXT_CRED_PROTECT; + cred->ext.prot = prot; + } + + return (FIDO_OK); +} + int fido_cred_set_fmt(fido_cred_t *cred, const char *fmt) { @@ -991,6 +967,12 @@ fido_cred_id_len(const fido_cred_t *cred) return (cred->attcred.id.len); } +int +fido_cred_prot(const fido_cred_t *cred) +{ + return (cred->ext.prot); +} + const char * fido_cred_fmt(const fido_cred_t *cred) { -- cgit v1.2.3