in src/js/openenclave.cpp [37:173]
static JSValue js_verify_open_enclave_evidence(
JSContext* ctx, JSValueConst, int argc, JSValueConst* argv)
{
if (argc != 2 && argc != 3)
return JS_ThrowTypeError(
ctx, "Passed %d arguments, but expected 2 or 3", argc);
js::Context& jsctx = *(js::Context*)JS_GetContextOpaque(ctx);
oe_uuid_t format_;
oe_uuid_t* format = nullptr;
if (!JS_IsUndefined(argv[0]))
{
auto format_str = jsctx.to_str(argv[0]);
if (!format_str)
{
js::js_dump_error(ctx);
return JS_EXCEPTION;
}
format_str = std::regex_replace(*format_str, std::regex("-"), "");
if (format_str->size() != 32)
{
auto e = JS_ThrowRangeError(
ctx, "format contains an invalid number of hex characters");
js::js_dump_error(ctx);
return e;
}
std::vector<uint8_t> format_v;
try
{
format_v = ds::from_hex(*format_str);
}
catch (std::exception& exc)
{
auto e = JS_ThrowRangeError(
ctx, "format could not be parsed as hex: %s", exc.what());
js::js_dump_error(ctx);
return e;
}
std::memcpy(format_.b, format_v.data(), format_v.size());
format = &format_;
}
size_t evidence_size;
uint8_t* evidence = JS_GetArrayBuffer(ctx, &evidence_size, argv[1]);
if (!evidence)
{
js::js_dump_error(ctx);
return JS_EXCEPTION;
}
size_t endorsements_size = 0;
uint8_t* endorsements = JS_GetArrayBuffer(ctx, &endorsements_size, argv[2]);
Claims claims;
auto rc = oe_verify_evidence(
format,
evidence,
evidence_size,
endorsements,
endorsements_size,
nullptr,
0,
&claims.data,
&claims.length);
if (rc != OE_OK)
{
auto e = JS_ThrowRangeError(
ctx, "Failed to verify evidence: %s", oe_result_str(rc));
js::js_dump_error(ctx);
return e;
}
std::unordered_map<std::string, std::vector<uint8_t>> out_claims,
out_custom_claims;
for (size_t i = 0; i < claims.length; i++)
{
auto& claim = claims.data[i];
std::string claim_name{claim.name};
if (claim_name == OE_CLAIM_CUSTOM_CLAIMS_BUFFER)
{
Claims custom_claims;
rc = oe_deserialize_custom_claims(
claim.value,
claim.value_size,
&custom_claims.data,
&custom_claims.length);
if (rc != OE_OK)
{
auto e = JS_ThrowRangeError(
ctx, "Failed to deserialise custom claims: %s", oe_result_str(rc));
js::js_dump_error(ctx);
return e;
}
for (size_t j = 0; j < custom_claims.length; j++)
{
auto& custom_claim = custom_claims.data[j];
std::string custom_claim_name{custom_claim.name};
std::vector<uint8_t> custom_claim_value{
custom_claim.value, custom_claim.value + custom_claim.value_size};
out_custom_claims.emplace(
std::move(custom_claim_name), std::move(custom_claim_value));
}
}
else
{
std::vector<uint8_t> claim_value{
claim.value, claim.value + claim.value_size};
out_claims.emplace(std::move(claim_name), std::move(claim_value));
}
}
auto js_claims = JS_NewObject(ctx);
for (auto& [name, val] : out_claims)
{
auto buf = JS_NewArrayBufferCopy(ctx, val.data(), val.size());
JS_SetPropertyStr(ctx, js_claims, name.c_str(), buf);
}
auto js_custom_claims = JS_NewObject(ctx);
for (auto& [name, val] : out_custom_claims)
{
auto buf = JS_NewArrayBufferCopy(ctx, val.data(), val.size());
JS_SetPropertyStr(ctx, js_custom_claims, name.c_str(), buf);
}
auto r = JS_NewObject(ctx);
JS_SetPropertyStr(ctx, r, "claims", js_claims);
JS_SetPropertyStr(ctx, r, "customClaims", js_custom_claims);
return r;
}