Skip to content

Instantly share code, notes, and snippets.

@Demon000
Last active September 21, 2023 17:11
Show Gist options
  • Save Demon000/dcc99cc1c4506b5094bb7416e9622265 to your computer and use it in GitHub Desktop.
Save Demon000/dcc99cc1c4506b5094bb7416e9622265 to your computer and use it in GitHub Desktop.
tls
import { Cryptor, DataBuffer } from '@web-auto/android-auto';
import DuplexPair from 'native-duplexpair';
import { Duplex, Readable, Writable } from 'node:stream';
import { TLSSocket, connect } from 'node:tls';
export class NodeCryptor extends Cryptor {
private connected = false;
private securePair: {
cleartext: TLSSocket;
encrypted: Duplex;
};
private duplexpair: DuplexPair;
private operationCount = 0;
public constructor(
protected certificateBuffer: Buffer,
protected privateKeyBuffer: Buffer,
) {
super(certificateBuffer, privateKeyBuffer);
this.duplexpair = new DuplexPair();
this.securePair = {
cleartext: connect({
socket: this.duplexpair.socket1,
key: this.privateKeyBuffer,
cert: this.certificateBuffer,
rejectUnauthorized: false,
}),
encrypted: this.duplexpair.socket2,
};
this.securePair.cleartext.once('secure', () => {
const cipher = this.securePair.cleartext.getCipher();
console.log(`connected, cipher: ${cipher.name} ${cipher.version}`);
this.connected = true;
});
}
public init(): void {}
public deinit(): void {}
public doHandshake(): boolean {
return this.connected;
}
public async readHandshakeBuffer(): Promise<DataBuffer> {
const count = this.operationCount++;
console.log();
const buffer = await this.readEncrypted(count);
console.log(count, 'read handshake buffer', buffer);
return buffer;
}
public async writeHandshakeBuffer(buffer: DataBuffer): Promise<void> {
const count = this.operationCount++;
console.log();
console.log(count, 'write handshake buffer', buffer);
await this.writeEncrypted(buffer, count);
}
private async readReadable(
readable: Readable,
count: number,
): Promise<DataBuffer> {
return new Promise((resolve, reject) => {
const read = () => {
const buffer = DataBuffer.empty();
let chunk;
while (null !== (chunk = readable.read())) {
console.log(count, 'read chunk', chunk);
const chunkBuffer = DataBuffer.fromBuffer(chunk);
buffer.appendBuffer(chunkBuffer);
}
return buffer;
};
const buffer = read();
if (buffer.size) {
console.log(count, 'read immediately', buffer);
resolve(buffer);
} else {
console.log(count, 'read later');
readable.once('readable', () => {
const buffer = read();
console.log(count, 'finished read later', buffer);
if (buffer.size) {
resolve(buffer);
} else {
console.log(count, 'read failed');
reject(buffer);
}
});
}
});
}
private async writeWriteable(
writeable: Writable,
buffer: DataBuffer,
count: number,
): Promise<void> {
return new Promise((resolve, reject) => {
console.log(count, 'starting write');
writeable.write(buffer.data, (err) => {
console.log(count, 'finished write');
if (err !== undefined && err !== null) {
console.log(count, 'error write');
return reject(err);
}
resolve();
});
});
}
private async readEncrypted(count: number): Promise<DataBuffer> {
const buffer = await this.readReadable(
this.securePair.encrypted,
count,
);
console.log(count, 'read encrypted', buffer);
return buffer;
}
private async readCleartext(count: number): Promise<DataBuffer> {
const buffer = await this.readReadable(
this.securePair.cleartext,
count,
);
console.log(count, 'read cleartext', buffer);
return buffer;
}
private async writeEncrypted(
buffer: DataBuffer,
count: number,
): Promise<void> {
console.log(count, 'write encrypted', buffer);
await this.writeWriteable(this.securePair.encrypted, buffer, count);
}
private async writeCleartext(
buffer: DataBuffer,
count: number,
): Promise<void> {
console.log(count, 'write cleartext', buffer);
await this.writeWriteable(this.securePair.cleartext, buffer, count);
}
public async encrypt(buffer: DataBuffer): Promise<DataBuffer> {
const count = this.operationCount++;
console.log();
console.log(count, 'encrypt', buffer);
await this.writeCleartext(buffer, count);
return this.readEncrypted(count);
}
public async decrypt(buffer: DataBuffer): Promise<DataBuffer> {
const count = this.operationCount++;
console.log();
console.log(count, 'decrypt', buffer);
await this.writeEncrypted(buffer, count);
return this.readCleartext(count);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment