Advertisement
Guest User

Untitled

a guest
May 16th, 2018
269
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. /////////////////////////////////////
  2. // Snippets from socket.service.ts //
  3. /////////////////////////////////////
  4.  
  5. interface KeyPromise {
  6.     resolve: Function;
  7.     reject: Function;
  8.     timeout: any;
  9. }
  10.  
  11. private keyPromises = new Map<Nonce, KeyPromise>();
  12.  
  13. private setupInternalListeners() {
  14.     this.socket.on("key response", (keyResponse: KeyResponse) => {
  15.         let keyPromise = this.keyPromises.get(keyResponse.nonce);
  16.  
  17.         if (!keyPromise) throw "Received unrequested key";
  18.  
  19.         clearTimeout(keyPromise.timeout);
  20.         keyPromise.resolve(keyResponse);
  21.         this.keyPromises.delete(keyResponse.nonce);
  22.     });
  23. }
  24.  
  25. private requestKey(id: string): Promise<KeyResponse> {
  26.     let promise = new Promise<KeyResponse>(async (resolve, reject) => {
  27.         let nonce: Nonce = await Crypto.generateNonce();
  28.  
  29.         let keyRequest: KeyRequest = {
  30.             nonce: nonce,
  31.             id: id
  32.         };
  33.  
  34.         let timeout = setTimeout(() => {
  35.             reject("Timed out");
  36.         }, 10000);
  37.  
  38.         let keyPromise: KeyPromise = {
  39.             resolve: resolve,
  40.             reject: reject,
  41.             timeout: timeout
  42.         };
  43.  
  44.         this.keyPromises.set(nonce, keyPromise);
  45.         this.socket.emit("key request", keyRequest);   
  46.     });
  47.  
  48.     return promise;
  49. }
  50.  
  51. async sendMessage(message: Message) {
  52.  
  53.     // Get the public key
  54.     let keyResponse: KeyResponse | void;
  55.     let error: any;
  56.    
  57.     await this.requestKey(message.recipientId)
  58.     .catch((_error) => { error = _error; })
  59.     .then((_keyResponse) => { keyResponse = _keyResponse; })
  60.  
  61.     if (error) throw error;
  62.     if (!keyResponse) throw "No public key received";
  63.  
  64.  
  65.     // Encrypt message
  66.     let secureMessage: SecureMessage | void;
  67.  
  68.     await Crypto.encryptMessage(keyResponse, message)
  69.     .catch((_error) => { error = _error; })
  70.     .then((_secureMessage) => { secureMessage = _secureMessage; })
  71.  
  72.     if (error) throw error;
  73.     if (!keyResponse) throw "No encrypted message returned";
  74.  
  75.  
  76.     // Send it
  77.     this.socket.emit("message", secureMessage);
  78. }
  79.  
  80.  
  81. //////////////////////////////////
  82. // Entirety of crypto.module.ts //
  83. //////////////////////////////////
  84.  
  85. import { Nonce, KeyPair, SecureMessage, KeyResponse } from "./crypto.types";
  86. import { Message } from "../gamma.types";
  87.  
  88. import * as openpgp from "openpgp";
  89. import * as md5 from "js-md5";
  90.  
  91. export module Crypto {
  92.  
  93.     openpgp.config.compression = openpgp.enums.compression.zip;
  94.     const curve: string = "curve25519";
  95.  
  96.     // Source: National Security Agency
  97.  
  98.     const nsaNames: string[] = [
  99.         "Paul M. Nakasone",   // Director
  100.         "George C. Barnes",   // Deputy Director
  101.         "Mark W. Westergren", // Deputy Chief
  102.         "Harry Coker, Jr.",   // Executive Director
  103.         "Earnest Green"       // Chief of Staff
  104.     ];
  105.  
  106.     const nsaEmail: string = "nsapao@nsa.gov";
  107.  
  108.     /* A notice from our friends at the NSA
  109.  
  110.     "Unless a copyright or trademark is indicated, information on the
  111.     National Security Agency Web site is in the public domain and may be reproduced,
  112.     published or otherwise used without the National Security Agency's permission.
  113.     We request only that the National Security Agency be cited as the source of
  114.     information and that any photo credits or bylines be similarly credited to the
  115.     photographer or author or NSA, as appropriate."
  116.    
  117.     https://www.nsa.gov/terms-of-use.shtml#copyright */
  118.  
  119.     export function resistFingerprinting(timestamp: number): number {
  120.         return Math.round(timestamp * 0.01) / 0.01;
  121.     }
  122.  
  123.     export async function generateNonce(): Promise<Nonce> {
  124.         let data: Uint8Array = await openpgp.crypto.random.getRandomBytes(16);
  125.         let timestamp = resistFingerprinting(Date.now());
  126.  
  127.         return {
  128.             timestamp: timestamp,
  129.             data: data
  130.         };
  131.     }
  132.  
  133.     export async function generateKeyPair(nonce: Nonce): Promise<KeyPair> {
  134.         if(this.localKeyPairs.has(nonce)) throw "Invalid nonce";
  135.  
  136.         // Gets a random name from list of NSA leaders
  137.         let name = nsaNames[Math.floor(Math.random() * nsaNames.length)];
  138.  
  139.         let options = {
  140.             userIds: [{ name: name, email: nsaEmail }],
  141.             curve: curve, // https://safecurves.cr.yp.to/
  142.             passphrase: nonce.data.join("")
  143.         };
  144.  
  145.         let keyPair: KeyPair;
  146.  
  147.         await openpgp.generateKey(options).then((key) => {
  148.             keyPair = {
  149.                 private: key.privateKeyArmored,
  150.                 public: key.publicKeyArmored
  151.             };
  152.         });
  153.  
  154.         return keyPair;
  155.     }
  156.  
  157.     export async function encryptMessage(keyResponse: KeyResponse, message: Message): Promise<SecureMessage> {
  158.         let encrypted: string;
  159.         let error: any;
  160.  
  161.         let encryptOptions = {
  162.             data: message.text,
  163.             publicKeys: openpgp.key
  164.                 .readArmored(keyResponse.publicKey).keys
  165.         };
  166.        
  167.         await openpgp.encrypt(encryptOptions)
  168.         .catch((_error) => { error = _error; })
  169.         .then((_encrypted) => {
  170.             encrypted = _encrypted.data;
  171.         });
  172.  
  173.         if (error) throw error;
  174.         if (!encrypted) throw "Failed to encrypt message";
  175.  
  176.         let hash: string = md5(message.text);
  177.         message.text = encrypted;
  178.  
  179.         let secureMessage: SecureMessage = {
  180.             nonce: keyResponse.nonce,
  181.             hash: hash,
  182.             message: message
  183.         };
  184.  
  185.         return secureMessage;
  186.     }
  187. }
  188.  
  189.  
  190. /////////////////////////////////
  191. // Entirety of crypto.types.ts //
  192. /////////////////////////////////
  193.  
  194. import { Message } from "../gamma.types";
  195.  
  196. export interface Nonce {
  197.     timestamp: number;
  198.     data: Uint8Array;
  199. }
  200.  
  201. export interface KeyPair {
  202.     private: string;
  203.     public: string;
  204. }
  205.  
  206. export interface SecureMessage {
  207.     nonce: Nonce;
  208.     hash: string;
  209.     message: Message;
  210. }
  211.  
  212. export interface KeyRequest {
  213.     nonce: Nonce;
  214.     id: string;
  215. }
  216.  
  217. export interface KeyResponse {
  218.     nonce: Nonce;
  219.     publicKey: string;
  220. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement