Skip to content

Commit

Permalink
feat: Expose connection params (#1139)
Browse files Browse the repository at this point in the history
  • Loading branch information
gnarea authored Jan 18, 2024
1 parent 05fe324 commit 2c852a5
Show file tree
Hide file tree
Showing 20 changed files with 340 additions and 98 deletions.
2 changes: 1 addition & 1 deletion chart/values.dev.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ logging:
ingress:
enableTls: false

internetAddress: gateway.tld
internetAddress: public-gateway-pohttp.default

# Skip the broker; post directly to the CloudEvents endpoint in development
queueChannel: http://public-gateway-queue
Expand Down
72 changes: 36 additions & 36 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -17,13 +17,13 @@
"dependencies": {
"@grpc/grpc-js": "^1.9.5",
"@redis/client": "^1.5.11",
"@relaycorp/awala-keystore-cloud": "^2.1.30",
"@relaycorp/awala-keystore-cloud": "^2.2.2",
"@relaycorp/awala-keystore-mongodb": "^1.1.25",
"@relaycorp/cloudevents-transport": "^2.0.6",
"@relaycorp/cogrpc": "^1.4.1",
"@relaycorp/object-storage": "^1.4.93",
"@relaycorp/pino-cloud": "^1.0.28",
"@relaycorp/relaynet-core": "^1.87.8",
"@relaycorp/relaynet-core": "^1.88.1",
"@relaycorp/relaynet-pohttp": "^1.7.76",
"@typegoose/typegoose": "^11.5.1",
"abortable-iterator": "^3.0.0",
Expand Down
45 changes: 10 additions & 35 deletions src/bin/generate-keypairs.ts
Original file line number Diff line number Diff line change
@@ -1,53 +1,28 @@
import { CertificationPath, issueGatewayCertificate } from '@relaycorp/relaynet-core';
import { MongoCertificateStore } from '@relaycorp/awala-keystore-mongodb';
import { addDays } from 'date-fns';
import { Connection } from 'mongoose';
import type { Connection } from 'mongoose';

import { createMongooseConnectionFromEnv } from '../backingServices/mongo';
import { initPrivateKeyStore } from '../backingServices/keystore';
import { CERTIFICATE_TTL_DAYS } from '../pki';
import { Config, ConfigKey } from '../utilities/config';
import { configureExitHandling } from '../utilities/exitHandling';
import { makeLogger } from '../utilities/logging';
import { InternetGatewayManager } from '../node/InternetGatewayManager';

const LOGGER = makeLogger();
configureExitHandling(LOGGER);

async function main(): Promise<void> {
const connection = await createMongooseConnectionFromEnv();
const connection = createMongooseConnectionFromEnv();
try {
const certificateStore = new MongoCertificateStore(connection);

const config = new Config(connection);
const currentId = await config.get(ConfigKey.CURRENT_ID);
if (currentId) {
LOGGER.info({ id: currentId }, `Gateway key pair already exists`);
} else {
await generateKeyPair(certificateStore, config, connection);
}
await bootstrap(connection);
} finally {
await connection.close();
}
}

async function generateKeyPair(
certificateStore: MongoCertificateStore,
config: Config,
connection: Connection,
): Promise<void> {
const privateKeyStore = initPrivateKeyStore(connection);
const { id, privateKey, publicKey } = await privateKeyStore.generateIdentityKeyPair();

const gatewayCertificate = await issueGatewayCertificate({
issuerPrivateKey: privateKey,
subjectPublicKey: publicKey,
validityEndDate: addDays(new Date(), CERTIFICATE_TTL_DAYS),
});
await certificateStore.save(new CertificationPath(gatewayCertificate, []), id);

await config.set(ConfigKey.CURRENT_ID, id);
LOGGER.info('Done');
}

LOGGER.info({ id }, 'Identity key pair was successfully generated');
async function bootstrap(connection: Connection): Promise<void> {
const manager = await InternetGatewayManager.init(connection);
const gateway = await manager.getOrCreateCurrent();
await gateway.makeInitialSessionKeyIfMissing();
}

main();
10 changes: 9 additions & 1 deletion src/functionalTests/poweb.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import {
generateRSAKeyPair,
issueDeliveryAuthorization,
issueEndpointCertificate,
NodeConnectionParams,
Parcel,
ParcelDeliverySigner,
PrivateNodeRegistrationRequest,
Expand All @@ -18,14 +19,21 @@ import uuid from 'uuid-random';

import { GeneratedParcel } from '../testUtils/awala';
import { ExternalPdaChain } from '../testUtils/pki';
import { GW_POWEB_HOST_PORT } from './utils/constants';
import { GW_INTERNET_ADDRESS, GW_POWEB_HOST_PORT } from './utils/constants';
import {
createAndRegisterPrivateGateway,
registerPrivateGateway,
} from './utils/gatewayRegistration';
import { extractPong, makePingParcel } from './utils/ping';
import { collectNextParcel, waitForNextParcel } from './utils/poweb';

test('Connection params should be available', async () => {
const response = await fetch(`http://127.0.0.1:${GW_POWEB_HOST_PORT}/connection-params.der`);

const params = await NodeConnectionParams.deserialize(await response.arrayBuffer());
expect(params.internetAddress).toBe(GW_INTERNET_ADDRESS);
});

describe('Node registration', () => {
test('Valid registration requests should be accepted', async () => {
const client = PoWebClient.initLocal(GW_POWEB_HOST_PORT);
Expand Down
1 change: 1 addition & 0 deletions src/functionalTests/utils/poweb.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { Parcel, ParcelCollectionHandshakeSigner, StreamingMode } from '@relaycorp/relaynet-core';
import { PoWebClient } from '@relaycorp/relaynet-poweb';
import { collect, pipeline, take } from 'streaming-iterables';

import { ExternalPdaChain } from '../../testUtils/pki';

/**
Expand Down
28 changes: 26 additions & 2 deletions src/node/InternetGateway.spec.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { Cargo, MockKeyStoreSet, SessionKeyPair } from '@relaycorp/relaynet-core';
import { Cargo, MockKeyStoreSet, type SessionKey, SessionKeyPair } from '@relaycorp/relaynet-core';
import {
CDACertPath,
generateCDACertificationPath,
Expand All @@ -7,10 +7,10 @@ import {
} from '@relaycorp/relaynet-testing';
import bufferToArray from 'buffer-to-arraybuffer';
import { addMinutes } from 'date-fns';
import { collect } from 'streaming-iterables';

import { arrayToAsyncIterable } from '../testUtils/iter';
import { InternetGateway } from './InternetGateway';
import { collect } from 'streaming-iterables';

let keyPairSet: NodeKeyPairSet;
let cdaChain: CDACertPath;
Expand Down Expand Up @@ -94,3 +94,27 @@ describe('getChannelFromCda', () => {
expect(channel.peer.internetAddress).toBeUndefined();
});
});

describe('makeInitialSessionKeyIfMissing', () => {
test('Key should be generated if there are no existing unbound keys', async () => {
await expect(
KEY_STORES.privateKeyStore.retrieveUnboundSessionPublicKey(internetGateway.id),
).resolves.toBeNull();

await expect(internetGateway.makeInitialSessionKeyIfMissing()).resolves.toBeTrue();

await expect(
KEY_STORES.privateKeyStore.retrieveUnboundSessionPublicKey(internetGateway.id),
).resolves.not.toBeNull();
});

test('Key should not be generated if there are existing unbound keys', async () => {
const preExistingKey = await internetGateway.generateSessionKey();

await expect(internetGateway.makeInitialSessionKeyIfMissing()).resolves.toBeFalse();

await expect(
KEY_STORES.privateKeyStore.retrieveUnboundSessionPublicKey(internetGateway.id),
).resolves.toSatisfy<SessionKey>((key) => key.keyId.equals(preExistingKey.keyId));
});
});
16 changes: 16 additions & 0 deletions src/node/InternetGateway.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,4 +22,20 @@ export class InternetGateway extends Gateway<undefined> {
};
return new InternetGatewayChannel(this, peer, new CertificationPath(cda, []), this.keyStores);
}

/**
* Generate the initial session key if it doesn't exist yet.
* @returns Whether the initial session key was created.
*/
public async makeInitialSessionKeyIfMissing(): Promise<boolean> {
const existingKey = await this.keyStores.privateKeyStore.retrieveUnboundSessionPublicKey(
this.id,
);
if (existingKey !== null) {
return false;
}

await this.generateSessionKey();
return true;
}
}
Loading

0 comments on commit 2c852a5

Please sign in to comment.