Skip to content

Commit

Permalink
sets passphrase on client when joining session (#5545)
Browse files Browse the repository at this point in the history
instead of requiring a passphrase at the time of client construction, sets the
client passphrase only when starting or joining a session

moves usage of 'parseConnectionOptions' into session manager for sessions that
use the multisig broker server

prompts the user for sessionId and passphrase in 'startSession'. this will allow
for re-prompting if starting or joining the session fails
  • Loading branch information
hughy authored Oct 14, 2024
1 parent 5ced203 commit cf237e3
Show file tree
Hide file tree
Showing 8 changed files with 80 additions and 71 deletions.
20 changes: 5 additions & 15 deletions ironfish-cli/src/commands/wallet/multisig/dkg/create.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@ import path from 'path'
import { IronfishCommand } from '../../../../command'
import { RemoteFlags } from '../../../../flags'
import { LedgerMultiSigner } from '../../../../ledger'
import { MultisigBrokerUtils } from '../../../../multisigBroker'
import {
DkgSessionManager,
MultisigClientDkgSessionManager,
Expand Down Expand Up @@ -105,21 +104,12 @@ export class DkgCreateCommand extends IronfishCommand {

let sessionManager: DkgSessionManager
if (flags.server || flags.connection || flags.sessionId || flags.passphrase) {
const { hostname, port, sessionId, passphrase } =
await MultisigBrokerUtils.parseConnectionOptions({
connection: flags.connection,
hostname: flags.hostname,
port: flags.port,
sessionId: flags.sessionId,
passphrase: flags.passphrase,
logger: this.logger,
})

sessionManager = new MultisigClientDkgSessionManager({
hostname,
port,
passphrase,
sessionId,
connection: flags.connection,
hostname: flags.hostname,
port: flags.port,
passphrase: flags.passphrase,
sessionId: flags.sessionId,
tls: flags.tls ?? true,
logger: this.logger,
})
Expand Down
20 changes: 5 additions & 15 deletions ironfish-cli/src/commands/wallet/multisig/sign.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@ import { Flags, ux } from '@oclif/core'
import { IronfishCommand } from '../../../command'
import { RemoteFlags } from '../../../flags'
import { LedgerMultiSigner } from '../../../ledger'
import { MultisigBrokerUtils } from '../../../multisigBroker'
import {
MultisigClientSigningSessionManager,
MultisigSigningSessionManager,
Expand Down Expand Up @@ -128,22 +127,13 @@ export class SignMultisigTransactionCommand extends IronfishCommand {

let sessionManager: SigningSessionManager
if (flags.server || flags.connection || flags.sessionId || flags.passphrase) {
const { hostname, port, sessionId, passphrase } =
await MultisigBrokerUtils.parseConnectionOptions({
connection: flags.connection,
hostname: flags.hostname,
port: flags.port,
sessionId: flags.sessionId,
passphrase: flags.passphrase,
logger: this.logger,
})

sessionManager = new MultisigClientSigningSessionManager({
logger: this.logger,
hostname,
port,
passphrase,
sessionId,
connection: flags.connection,
hostname: flags.hostname,
port: flags.port,
passphrase: flags.passphrase,
sessionId: flags.sessionId,
tls: flags.tls,
})
} else {
Expand Down
21 changes: 13 additions & 8 deletions ironfish-cli/src/multisigBroker/clients/client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -63,11 +63,11 @@ export abstract class MultisigClient {
readonly onMultisigBrokerError = new Event<[MultisigBrokerMessageWithError]>()

sessionId: string | null = null
passphrase: string
passphrase: string | null = null

retries: Map<number, NodeJS.Timer> = new Map()

constructor(options: { hostname: string; port: number; passphrase: string; logger: Logger }) {
constructor(options: { hostname: string; port: number; logger: Logger }) {
this.logger = options.logger
this.version = 3
this.hostname = options.hostname
Expand All @@ -78,16 +78,14 @@ export abstract class MultisigClient {
this.connected = false
this.connectWarned = false
this.connectTimeout = null

this.passphrase = options.passphrase
}

get connectionString(): string {
return `tcp://${this.sessionId}:${this.passphrase}@${this.hostname}:${this.port}`
}

get key(): xchacha20poly1305.XChaCha20Poly1305Key {
if (!this.sessionId) {
if (!this.sessionId || !this.passphrase) {
throw new Error('Client must join a session before encrypting/decrypting messages')
}

Expand Down Expand Up @@ -162,19 +160,26 @@ export abstract class MultisigClient {
return this.connected
}

joinSession(sessionId: string): void {
joinSession(sessionId: string, passphrase: string): void {
this.sessionId = sessionId
this.passphrase = passphrase
this.send('join_session', {})
}

startDkgSession(maxSigners: number, minSigners: number): void {
startDkgSession(passphrase: string, maxSigners: number, minSigners: number): void {
this.sessionId = uuid()
this.passphrase = passphrase
const challenge = this.key.encrypt(Buffer.from('DKG')).toString('hex')
this.send('dkg.start_session', { maxSigners, minSigners, challenge })
}

startSigningSession(numSigners: number, unsignedTransaction: string): void {
startSigningSession(
passphrase: string,
numSigners: number,
unsignedTransaction: string,
): void {
this.sessionId = uuid()
this.passphrase = passphrase
const challenge = this.key.encrypt(Buffer.from('SIGNING')).toString('hex')
this.send('sign.start_session', { numSigners, unsignedTransaction, challenge })
}
Expand Down
3 changes: 1 addition & 2 deletions ironfish-cli/src/multisigBroker/clients/tcpClient.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,10 @@ import { MultisigClient } from './client'
export class MultisigTcpClient extends MultisigClient {
client: net.Socket | null = null

constructor(options: { hostname: string; port: number; passphrase: string; logger: Logger }) {
constructor(options: { hostname: string; port: number; logger: Logger }) {
super({
hostname: options.hostname,
port: options.port,
passphrase: options.passphrase,
logger: options.logger,
})
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,8 +40,22 @@ export class MultisigClientDkgSessionManager
minSigners?: number
ledger?: boolean
}): Promise<{ totalParticipants: number; minSigners: number }> {
if (!this.sessionId) {
this.sessionId = await ui.inputPrompt(
'Enter the ID of a multisig session to join, or press enter to start a new session',
false,
)
}

if (!this.passphrase) {
this.passphrase = await ui.inputPrompt(
'Enter the passphrase for the multisig session',
true,
)
}

if (this.sessionId) {
await this.joinSession(this.sessionId)
await this.joinSession(this.sessionId, this.passphrase)
return this.getSessionConfig()
}

Expand All @@ -54,7 +68,7 @@ export class MultisigClientDkgSessionManager

await this.connect()

this.client.startDkgSession(totalParticipants, minSigners)
this.client.startDkgSession(this.passphrase, totalParticipants, minSigners)
this.sessionId = this.client.sessionId

this.logger.info(`\nStarted new DKG session: ${this.sessionId}\n`)
Expand Down
23 changes: 18 additions & 5 deletions ironfish-cli/src/multisigBroker/sessionManagers/sessionManager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,24 +22,37 @@ export abstract class MultisigSessionManager {
export abstract class MultisigClientSessionManager extends MultisigSessionManager {
client: MultisigClient
sessionId: string | null
passphrase: string | null

constructor(options: {
logger: Logger
connection?: string
hostname: string
port: number
passphrase: string
passphrase?: string
sessionId?: string
tls?: boolean
}) {
super({ logger: options.logger })

this.client = MultisigBrokerUtils.createClient(options.hostname, options.port, {
const { hostname, port, sessionId, passphrase } =
MultisigBrokerUtils.parseConnectionOptions({
connection: options.connection,
hostname: options.hostname,
port: options.port,
sessionId: options.sessionId,
passphrase: options.passphrase,
logger: this.logger,
})

this.client = MultisigBrokerUtils.createClient(hostname, port, {
passphrase: options.passphrase,
tls: options.tls ?? true,
logger: this.logger,
})

this.sessionId = options.sessionId ?? null
this.sessionId = sessionId ?? null
this.passphrase = passphrase ?? null
}

protected async connect(): Promise<void> {
Expand All @@ -62,10 +75,10 @@ export abstract class MultisigClientSessionManager extends MultisigSessionManage
ux.action.stop()
}

async joinSession(sessionId: string): Promise<void> {
async joinSession(sessionId: string, passphrase: string): Promise<void> {
await this.connect()

this.client.joinSession(sessionId)
this.client.joinSession(sessionId, passphrase)

await this.waitForJoinedSession()
this.sessionId = sessionId
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,8 +32,22 @@ export class MultisigClientSigningSessionManager
numSigners?: number
unsignedTransaction?: string
}): Promise<{ numSigners: number; unsignedTransaction: UnsignedTransaction }> {
if (!this.sessionId) {
this.sessionId = await ui.inputPrompt(
'Enter the ID of a multisig session to join, or press enter to start a new session',
false,
)
}

if (!this.passphrase) {
this.passphrase = await ui.inputPrompt(
'Enter the passphrase for the multisig session',
true,
)
}

if (this.sessionId) {
await this.joinSession(this.sessionId)
await this.joinSession(this.sessionId, this.passphrase)
return this.getSessionConfig()
}

Expand All @@ -44,7 +58,7 @@ export class MultisigClientSigningSessionManager

await this.connect()

this.client.startSigningSession(numSigners, unsignedTransaction)
this.client.startSigningSession(this.passphrase, numSigners, unsignedTransaction)
this.sessionId = this.client.sessionId

this.logger.info(`\nStarting new signing session: ${this.sessionId}\n`)
Expand Down
28 changes: 6 additions & 22 deletions ironfish-cli/src/multisigBroker/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,22 +2,21 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
import { ErrorUtils, Logger } from '@ironfish/sdk'
import * as ui from '../ui'
import { MultisigClient, MultisigTcpClient, MultisigTlsClient } from './clients'

async function parseConnectionOptions(options: {
function parseConnectionOptions(options: {
connection?: string
hostname: string
port: number
sessionId?: string
passphrase?: string
logger: Logger
}): Promise<{
}): {
hostname: string
port: number
sessionId: string
passphrase: string
}> {
sessionId: string | undefined
passphrase: string | undefined
} {
let hostname
let port
let sessionId
Expand Down Expand Up @@ -48,19 +47,6 @@ async function parseConnectionOptions(options: {
hostname = hostname ?? options.hostname
port = port ?? options.port

sessionId = sessionId ?? options.sessionId
if (!sessionId) {
sessionId = await ui.inputPrompt(
'Enter the ID of a multisig session to join, or press enter to start a new session',
false,
)
}

passphrase = passphrase ?? options.passphrase
if (!passphrase) {
passphrase = await ui.inputPrompt('Enter the passphrase for the multisig session', true)
}

return {
hostname,
port,
Expand All @@ -72,20 +58,18 @@ async function parseConnectionOptions(options: {
function createClient(
hostname: string,
port: number,
options: { passphrase: string; tls: boolean; logger: Logger },
options: { passphrase?: string; tls: boolean; logger: Logger },
): MultisigClient {
if (options.tls) {
return new MultisigTlsClient({
hostname,
port,
passphrase: options.passphrase,
logger: options.logger,
})
} else {
return new MultisigTcpClient({
hostname,
port,
passphrase: options.passphrase,
logger: options.logger,
})
}
Expand Down

0 comments on commit cf237e3

Please sign in to comment.