Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- /////////////////////////////////////
- // Snippets from socket.service.ts //
- /////////////////////////////////////
- interface KeyPromise {
- resolve: Function;
- reject: Function;
- timeout: any;
- }
- private keyPromises = new Map<Nonce, KeyPromise>();
- private setupInternalListeners() {
- this.socket.on("key response", (keyResponse: KeyResponse) => {
- let keyPromise = this.keyPromises.get(keyResponse.nonce);
- if (!keyPromise) throw "Received unrequested key";
- clearTimeout(keyPromise.timeout);
- keyPromise.resolve(keyResponse);
- this.keyPromises.delete(keyResponse.nonce);
- });
- }
- private requestKey(id: string): Promise<KeyResponse> {
- let promise = new Promise<KeyResponse>(async (resolve, reject) => {
- let nonce: Nonce = await Crypto.generateNonce();
- let keyRequest: KeyRequest = {
- nonce: nonce,
- id: id
- };
- let timeout = setTimeout(() => {
- reject("Timed out");
- }, 10000);
- let keyPromise: KeyPromise = {
- resolve: resolve,
- reject: reject,
- timeout: timeout
- };
- this.keyPromises.set(nonce, keyPromise);
- this.socket.emit("key request", keyRequest);
- });
- return promise;
- }
- async sendMessage(message: Message) {
- // Get the public key
- let keyResponse: KeyResponse | void;
- let error: any;
- await this.requestKey(message.recipientId)
- .catch((_error) => { error = _error; })
- .then((_keyResponse) => { keyResponse = _keyResponse; })
- if (error) throw error;
- if (!keyResponse) throw "No public key received";
- // Encrypt message
- let secureMessage: SecureMessage | void;
- await Crypto.encryptMessage(keyResponse, message)
- .catch((_error) => { error = _error; })
- .then((_secureMessage) => { secureMessage = _secureMessage; })
- if (error) throw error;
- if (!keyResponse) throw "No encrypted message returned";
- // Send it
- this.socket.emit("message", secureMessage);
- }
- //////////////////////////////////
- // Entirety of crypto.module.ts //
- //////////////////////////////////
- import { Nonce, KeyPair, SecureMessage, KeyResponse } from "./crypto.types";
- import { Message } from "../gamma.types";
- import * as openpgp from "openpgp";
- import * as md5 from "js-md5";
- export module Crypto {
- openpgp.config.compression = openpgp.enums.compression.zip;
- const curve: string = "curve25519";
- // Source: National Security Agency
- const nsaNames: string[] = [
- "Paul M. Nakasone", // Director
- "George C. Barnes", // Deputy Director
- "Mark W. Westergren", // Deputy Chief
- "Harry Coker, Jr.", // Executive Director
- "Earnest Green" // Chief of Staff
- ];
- const nsaEmail: string = "nsapao@nsa.gov";
- /* A notice from our friends at the NSA
- "Unless a copyright or trademark is indicated, information on the
- National Security Agency Web site is in the public domain and may be reproduced,
- published or otherwise used without the National Security Agency's permission.
- We request only that the National Security Agency be cited as the source of
- information and that any photo credits or bylines be similarly credited to the
- photographer or author or NSA, as appropriate."
- https://www.nsa.gov/terms-of-use.shtml#copyright */
- export function resistFingerprinting(timestamp: number): number {
- return Math.round(timestamp * 0.01) / 0.01;
- }
- export async function generateNonce(): Promise<Nonce> {
- let data: Uint8Array = await openpgp.crypto.random.getRandomBytes(16);
- let timestamp = resistFingerprinting(Date.now());
- return {
- timestamp: timestamp,
- data: data
- };
- }
- export async function generateKeyPair(nonce: Nonce): Promise<KeyPair> {
- if(this.localKeyPairs.has(nonce)) throw "Invalid nonce";
- // Gets a random name from list of NSA leaders
- let name = nsaNames[Math.floor(Math.random() * nsaNames.length)];
- let options = {
- userIds: [{ name: name, email: nsaEmail }],
- curve: curve, // https://safecurves.cr.yp.to/
- passphrase: nonce.data.join("")
- };
- let keyPair: KeyPair;
- await openpgp.generateKey(options).then((key) => {
- keyPair = {
- private: key.privateKeyArmored,
- public: key.publicKeyArmored
- };
- });
- return keyPair;
- }
- export async function encryptMessage(keyResponse: KeyResponse, message: Message): Promise<SecureMessage> {
- let encrypted: string;
- let error: any;
- let encryptOptions = {
- data: message.text,
- publicKeys: openpgp.key
- .readArmored(keyResponse.publicKey).keys
- };
- await openpgp.encrypt(encryptOptions)
- .catch((_error) => { error = _error; })
- .then((_encrypted) => {
- encrypted = _encrypted.data;
- });
- if (error) throw error;
- if (!encrypted) throw "Failed to encrypt message";
- let hash: string = md5(message.text);
- message.text = encrypted;
- let secureMessage: SecureMessage = {
- nonce: keyResponse.nonce,
- hash: hash,
- message: message
- };
- return secureMessage;
- }
- }
- /////////////////////////////////
- // Entirety of crypto.types.ts //
- /////////////////////////////////
- import { Message } from "../gamma.types";
- export interface Nonce {
- timestamp: number;
- data: Uint8Array;
- }
- export interface KeyPair {
- private: string;
- public: string;
- }
- export interface SecureMessage {
- nonce: Nonce;
- hash: string;
- message: Message;
- }
- export interface KeyRequest {
- nonce: Nonce;
- id: string;
- }
- export interface KeyResponse {
- nonce: Nonce;
- publicKey: string;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement