Skip to content

Commit

Permalink
wip
Browse files Browse the repository at this point in the history
  • Loading branch information
amydevs committed Sep 2, 2024
1 parent 963b229 commit 6c06e49
Show file tree
Hide file tree
Showing 6 changed files with 53 additions and 41 deletions.
3 changes: 2 additions & 1 deletion src/claims/payloads/claimNetworkAccess.ts
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,8 @@ function assertClaimNetworkAccess(
);
}
if (
claimNetworkAccess['signedClaimNetworkAuthorityEncoded'] != null && typeof claimNetworkAccess['signedClaimNetworkAuthorityEncoded'] !== 'string'
claimNetworkAccess['signedClaimNetworkAuthorityEncoded'] != null &&
typeof claimNetworkAccess['signedClaimNetworkAuthorityEncoded'] !== 'string'
) {
throw new validationErrors.ErrorParse(
'`signedClaimNetworkAuthorityEncoded` property must be an encoded signed token',
Expand Down
1 change: 0 additions & 1 deletion src/nodes/NodeConnection.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,6 @@ import * as nodesUtils from '../nodes/utils';
import { never } from '../utils';
import config from '../config';
import * as networkUtils from '../network/utils';
import * as keysUtils from '../keys/utils';

type AgentClientManifest = typeof agentClientManifest;

Expand Down
31 changes: 19 additions & 12 deletions src/nodes/NodeManager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ import * as nodesEvents from './events';
import * as nodesErrors from './errors';
import * as agentErrors from './agent/errors';
import NodeConnectionQueue from './NodeConnectionQueue';
import { assertClaimNetworkAuthority } from '../claims/payloads/claimNetworkAuthority';
import Token from '../tokens/Token';
import * as keysUtils from '../keys/utils';
import * as tasksErrors from '../tasks/errors';
Expand All @@ -58,8 +59,9 @@ import * as claimsErrors from '../claims/errors';
import * as utils from '../utils/utils';
import config from '../config';
import * as networkUtils from '../network/utils';
import { ClaimNetworkAccess, assertClaimNetworkAccess } from '../claims/payloads/claimNetworkAccess';
import { ClaimNetworkAuthority, assertClaimNetworkAuthority } from '@/claims/payloads/claimNetworkAuthority';
import {
assertClaimNetworkAccess,
} from '../claims/payloads/claimNetworkAccess';

const abortEphemeralTaskReason = Symbol('abort ephemeral task reason');
const abortSingletonTaskReason = Symbol('abort singleton task reason');
Expand Down Expand Up @@ -1575,13 +1577,18 @@ class NodeManager {
) {
throw new claimsErrors.ErrorDoublySignedClaimVerificationFailed();
}
if (token.payload.network === 'testnet.polykey.com' || token.payload.network === 'mainnet.polykey.com') {
if (
token.payload.network === 'testnet.polykey.com' ||
token.payload.network === 'mainnet.polykey.com'
) {
return { success: true };
}
if (token.payload.signedClaimNetworkAuthorityEncoded == null) {
throw new claimsErrors.ErrorDoublySignedClaimVerificationFailed();
}
const authorityToken = Token.fromEncoded(token.payload.signedClaimNetworkAuthorityEncoded);
const authorityToken = Token.fromEncoded(
token.payload.signedClaimNetworkAuthorityEncoded,
);
// Verify if the token is signed
if (
token.payload.iss !== authorityToken.payload.sub ||
Expand All @@ -1603,26 +1610,26 @@ class NodeManager {
for await (const [_, claim] of this.sigchain.getSignedClaims({})) {
try {
assertClaimNetworkAccess(claim.payload);
}
catch {
} catch {
continue;
}
if (claim.payload.signedClaimNetworkAuthorityEncoded == null) {
throw new claimsErrors.ErrorDoublySignedClaimVerificationFailed();
}
const tokenNetworkAuthority = Token.fromEncoded(claim.payload.signedClaimNetworkAuthorityEncoded);
const tokenNetworkAuthority = Token.fromEncoded(
claim.payload.signedClaimNetworkAuthorityEncoded,
);
try {
assertClaimNetworkAuthority(tokenNetworkAuthority.payload);
}
catch {
} catch {
continue;
}
// No need to check if local claims are correctly signed by an Network Authority.
if (
authorityToken.verifyWithPublicKey(
keysUtils.publicKeyFromNodeId(
nodesUtils.decodeNodeId(claim.payload.iss)!,
)
),
)
) {
success = true;
Expand All @@ -1636,7 +1643,7 @@ class NodeManager {

return {
success: true,
}
};
}

/**
Expand Down Expand Up @@ -1696,7 +1703,7 @@ class NodeManager {
);
}

// need to await node connection verification, if fail, need to reject connection.
// Need to await node connection verification, if fail, need to reject connection.

// When adding a node we need to handle 3 cases
// 1. The node already exists. We need to update it's last updated field
Expand Down
2 changes: 1 addition & 1 deletion src/nodes/agent/errors.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ class ErrorNodesConnectionSignalRelayVerificationFailed<

class ErrorNodesClaimNetworkVerificationFailed<T> extends ErrorAgent<T> {
static description = 'Failed to verify claim network message';
exitCode = sysexits.UNAVAILABLE
exitCode = sysexits.UNAVAILABLE;
}

export {
Expand Down
10 changes: 4 additions & 6 deletions src/nodes/agent/handlers/NodesClaimNetworkVerify.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,10 @@ import type {
AgentRPCResponseResult,
} from '../types';
import type NodeManager from '../../../nodes/NodeManager';
import type { Host, Port } from '../../../network/types';
import type { JSONValue } from '../../../types';
import { UnaryHandler } from '@matrixai/rpc';
import * as x509 from '@peculiar/x509';
import * as agentErrors from '../errors';
import * as agentUtils from '../utils';
import { never } from '../../../utils';
import * as keysUtils from '../../../keys/utils';
import * as ids from '../../../ids';

class NodesClaimNetworkVerify extends UnaryHandler<
{
Expand All @@ -30,7 +25,10 @@ class NodesClaimNetworkVerify extends UnaryHandler<
if (requestingNodeId == null) {
throw new agentErrors.ErrorAgentNodeIdMissing();
}
return this.container.nodeManager.handleVerifyClaimNetwork(requestingNodeId, input);
return this.container.nodeManager.handleVerifyClaimNetwork(
requestingNodeId,
input,
);
};
}

Expand Down
47 changes: 27 additions & 20 deletions tests/nodes/agent/handlers/nodesClaimNetworkVerify.test.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
import type NodeConnectionManager from '@/nodes/NodeConnectionManager';
import type { AgentClaimMessage } from '@/nodes/agent/types';
import type { NodeId } from '@/ids';
import type { ClaimLinkNode } from '@/claims/payloads';
import type { KeyPair } from '@/keys/types';
import type { SignedTokenEncoded } from '@/tokens/types';
import type { ClaimNetworkAuthority } from '@/claims/payloads/claimNetworkAuthority';
import type { ClaimNetworkAccess } from '@/claims/payloads/claimNetworkAccess';
import fs from 'fs';
import path from 'path';
import os from 'os';
Expand All @@ -26,9 +27,6 @@ import * as nodesUtils from '@/nodes/utils';
import { generateKeyPair } from '@/keys/utils/generate';
import * as networkUtils from '@/network/utils';
import * as tlsTestsUtils from '../../../utils/tls';
import { SignedTokenEncoded } from '@/tokens/types';
import { ClaimNetworkAuthority } from '@/claims/payloads/claimNetworkAuthority';
import { ClaimNetworkAccess } from '@/claims/payloads/claimNetworkAccess';

describe('nodesClaimNetworkVerify', () => {
const logger = new Logger('nodesClaimNetworkVerify test', LogLevel.WARN, [
Expand Down Expand Up @@ -227,9 +225,10 @@ describe('nodesClaimNetworkVerify', () => {
authorityNodeId = keysUtils.publicKeyToNodeId(authorityKeyPair.publicKey);
seedKeyPair = generateKeyPair();
seedNodeId = keysUtils.publicKeyToNodeId(seedKeyPair.publicKey);
const authorityClaimId = claimsUtils.createClaimIdGenerator(authorityNodeId)();
const authorityClaimId =
claimsUtils.createClaimIdGenerator(authorityNodeId)();
const authorityClaim: ClaimNetworkAuthority = {
typ: "ClaimNetworkAuthority",
typ: 'ClaimNetworkAuthority',
iss: nodesUtils.encodeNodeId(authorityNodeId),
sub: nodesUtils.encodeNodeId(seedNodeId),
jti: claimsUtils.encodeClaimId(authorityClaimId),
Expand All @@ -238,20 +237,27 @@ describe('nodesClaimNetworkVerify', () => {
seq: 0,
prevDigest: null,
prevClaimId: null,
}
};
const authorityToken = Token.fromPayload(authorityClaim);
authorityToken.signWithPrivateKey(authorityKeyPair.privateKey);
authorityToken.signWithPrivateKey(seedKeyPair.privateKey);
signedClaimNetworkAuthorityEncoded = claimsUtils.generateSignedClaim(authorityToken.toSigned())
await sigchain.addClaim({
typ: "ClaimNetworkAccess",
iss: nodesUtils.encodeNodeId(seedNodeId),
sub: nodesUtils.encodeNodeId(remoteNodeId),
signedClaimNetworkAuthorityEncoded,
}, new Date(), async (token) => {
token.signWithPrivateKey(seedKeyPair.privateKey);
return token;
});
signedClaimNetworkAuthorityEncoded = claimsUtils.generateSignedClaim(
authorityToken.toSigned(),
);
await sigchain.addClaim(
{
typ: 'ClaimNetworkAccess',
iss: nodesUtils.encodeNodeId(seedNodeId),
sub: nodesUtils.encodeNodeId(remoteNodeId),
signedClaimNetworkAuthorityEncoded,
network: '',
},
new Date(),
async (token) => {
token.signWithPrivateKey(seedKeyPair.privateKey);
return token;
},
);
});
afterEach(async () => {
await taskManager.stop();
Expand All @@ -276,7 +282,7 @@ describe('nodesClaimNetworkVerify', () => {
});
const accessClaimId = claimsUtils.createClaimIdGenerator(authorityNodeId)();
const accessClaim: ClaimNetworkAccess = {
typ: "ClaimNetworkAccess",
typ: 'ClaimNetworkAccess',
iss: nodesUtils.encodeNodeId(seedNodeId),
sub: nodesUtils.encodeNodeId(localNodeId),
jti: claimsUtils.encodeClaimId(accessClaimId),
Expand All @@ -286,7 +292,8 @@ describe('nodesClaimNetworkVerify', () => {
prevDigest: null,
prevClaimId: null,
signedClaimNetworkAuthorityEncoded,
}
network: '',
};
const accessToken = Token.fromPayload(accessClaim);
accessToken.signWithPrivateKey(seedKeyPair.privateKey);
accessToken.signWithPrivateKey(clientKeyPair.privateKey);
Expand Down

0 comments on commit 6c06e49

Please sign in to comment.