Fail to verify certificate in development update calls

I am using localhost subdomains in development, so my URLs look like this: http://ryjl3-tyaaa-aaaaa-aaaba-cai.localhost:8000/

I need to do this to use ES modules natively while in development, because native ES modules do not set the Referer properly for the IC (there is no canisterId query parameter).

This has been working fine so far, but I just tried to do an update call for the first time from the frontend, and I keep getting this error message in response:

{
  "message": "Fail to verify certificate",
  "stack": "Error: Fail to verify certificate\n    at pollForResponse (http://ryjl3-tyaaa-aaaaa-aaaba-cai.localhost:8000/_snowpack/pkg/@dfinity/agent.js:13815:15)\n    at async caller (http://ryjl3-tyaaa-aaaaa-aaaba-cai.localhost:8000/_snowpack/pkg/@dfinity/agent.js:14000:35)\n    at async graphQLFetcher (http://ryjl3-tyaaa-aaaaa-aaaba-cai.localhost:8000/:39:21)"
}

I assume this is because I am using localhost subdomains, and the certificate verification process is not looking for thatā€¦perhaps?

More information about why I am using localhost subdomains: How does replica know which canister to serve from - #9 by nomeata

1 Like

Iā€™m pretty sure that this is caused by the new update that hardcodes the mainnet rootkey into the HttpAgent. After initializing, you can call agent.fetchRootKey() to use the signature of your local replica.

We have an open improvement item to automatically do this during local development, and I apologize for pushing that responsibility out onto the developer in the meantime

10 Likes

This worked! Thank you

Note that ideally you should not be calling .fetchRootKey() in the production build that you upload to the Internet Computer, else you lose the security properties of update call repsonses, i.e. a man-in-the-middle attack could forge the certificates.

5 Likes

Duly noted, thank you

Where should we put this call if we are running the local identity service? This is what Iā€™m running into with Running locally: Fail to verify certificate Ā· Issue #291 Ā· dfinity/internet-identity Ā· GitHub

I stuck it a couple of places in iiConnection.ts. Looks like it is routed around in prod and for some reason, the identity project builds in production mode.

Iā€™m not sure what your code looks like, but I put the call (itā€™s asynchronous so make sure to wait for the promise to resolve) before my own update call

Where we should call agent.fetchRootKey() kyle ?

import { Actor, HttpAgent } from ā€˜@dfinity/agentā€™;
import { idlFactory as hello_idl, canisterId as hello_id } from ā€˜dfx-generated/helloā€™;

const agent = new HttpAgent();

agent.fetchRootKey();
const hello = Actor.createActor(hello_idl, { agent, canisterId: hello_id });

document.getElementById(ā€œclickMeBtnā€).addEventListener(ā€œclickā€, async () => {
const name = document.getElementById(ā€œnameā€).value.toString();
const greeting = await hello.greet(name);

document.getElementById(ā€œgreetingā€).innerText = greeting;
});

Still throwing the same erro

Kindly reply

Try downgrading the @dfinity/agent package to 0.8.0 in your package.json.
I have no idea of what is happening, I just know that it solved this error for me.

2 Likes

Thanks seb. Let me try that.

Sorry for the delay here - Iā€™ve been really focused on upgrading DFX and improving the starter code.

My recommendation is now to try upgrading!

DFX_VERSION="0.7.7" sh -ci "$(curl -fsSL https://sdk.dfinity.org/install.sh)" along with js-agent 0.9.2 should be working fine, without needing to worry about calling the certificate anymore.

1 Like

FYI still got the error even though I am using sdk v0.7.7 and js-agent v0.9.2

If anybody had trouble running the whoami demo as described here Integrating with Internet Identity | Kyle Peacock's website locally I got It working with this:

as noted in the blogpost you need to add:

identityProvider: "http://localhost:8000?canisterId=LOCAL_INTERNET_IDENITY_CANISTER_ID"

to the authclient.login() argument

I also added:

 agent.fetchRootKey();

below

const agent = new HttpAgent({ identity });

in the handleAuthenticated function

furthermore I updated @dfinity/agent to 0.9.2 in the devdependencies and used dfx 0.7.7

and added a .env file in the auth-client-demo repo with CANISTER_ID=YOUR_WHOAMI_CANISTER_ID

good luck!

Take care not to use fetchRootKey() in production here, also if the project is updated to use 0.7.7 this should be taken care of for you in the canisterā€™s generated js file, so you shouldnā€™t need to add it yourself.

It didnā€™t work locally for me without the fetchRootKey() but maybe I did something wrong.

EDIT: this is probably because the web-auth-demo was still made for 0.7.2 be sure to check out this post Dfx 0.7.7 Changes | Kyle Peacock's website

1 Like

Iā€™ve updated the auth-client demo to 0.8.0 GitHub - krpeacock/auth-client-demo: Example demo of how to use https://www.npmjs.com/package/@dfinity/auth-client to make authenticated calls to an IC app. Still need to go back and make adjustments to the blog post, but I wanted the reference to be out there.

If youā€™ve already run it before, I recommend resetting things with git clean -dfx and then following the README directions

1 Like

So Iā€™m starting to get this exact error now Error: Fail to verify certificate in React Native. Iā€™m pretty sure it worked 2 months ago when I last enabled BLS signature validation. (I disabled it for the last 2 months until today, when I wanted to test it out again.)

FYI Iā€™m on dfx 0.7.1, and I do call await agent.fetchRootKey before making an update call.

Iā€™m also NOT using Internet Identity, and instead use an Identity that I construct from a private key that I get from a 3rd party, but it also doesnā€™t work with the AnonymousIdentity. Hereā€™s the code where I construct the Actor:

function createActor(identity?: Identity) {
  const agent = new HttpAgent({host: getHost(), identity});
  const actor = Actor.createActor<_SERVICE>(service_idl, {
    agent,
    canisterId: service_id,
  });
  return {agent, actor};
}

Also, I put a bunch of console.log statements in the verify function in the agent-js library, and it says thatā€¦

 LOG  rootHash: []
 LOG  derKey: []
 LOG  sig: [167, 104, 28, 190, 58, 122, 182, 218, 25, 197, 15, 41, 232, 84, 122, 112, 103, 42, 241, 195, 71, 163, 225, 88, 13, 144, 164, 240, 75, 252, 45, 115, 136, 200, 246, 201, 187, 175, 115, 57, 69, 220, 220, 245, 52, 211, 89, 23]
 LOG  key: []
 LOG  msg: []

Is it normal for everything but sig to be empty?

Thanks!

OK I identified the root cause.

Upgrading agent-js from 0.9.1 to 0.10.1 caused certificate validation to fail. I think itā€™s due to the removal of Buffer in favor of ArrayBuffer.

@kpeacock, have you seen this before? When I revert my code from 0.10.1 to 0.9.1, the BLS signature verification passes.

2 Likes