You cannot select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
		
			
		
			
				
	
	
		
			88 lines
		
	
	
		
			2.7 KiB
		
	
	
	
		
			TypeScript
		
	
			
		
		
	
	
			88 lines
		
	
	
		
			2.7 KiB
		
	
	
	
		
			TypeScript
		
	
| /**
 | |
|  * This file is used to pad message buffer and attachments
 | |
|  */
 | |
| const PADDING_BYTE = 0x00;
 | |
| 
 | |
| /**
 | |
|  * Unpad the buffer from its padding.
 | |
|  * An error is thrown if there is no padding.
 | |
|  * A padded buffer is
 | |
|  *  * whatever at start
 | |
|  *  * ends with 0x80 and any number of 0x00 until the end
 | |
|  */
 | |
| export function removeMessagePadding(paddedData: ArrayBuffer): ArrayBuffer {
 | |
|   const paddedPlaintext = new Uint8Array(paddedData);
 | |
|   window?.log.info('Removing message padding...');
 | |
|   for (let i = paddedPlaintext.length - 1; i >= 0; i -= 1) {
 | |
|     if (paddedPlaintext[i] === 0x80) {
 | |
|       const plaintext = new Uint8Array(i);
 | |
|       plaintext.set(paddedPlaintext.subarray(0, i));
 | |
|       return plaintext.buffer;
 | |
|     } else if (paddedPlaintext[i] !== PADDING_BYTE) {
 | |
|       window?.log.warn('got a message without padding... Letting it through for now');
 | |
|       return paddedPlaintext;
 | |
|     }
 | |
|   }
 | |
| 
 | |
|   throw new Error('Invalid padding');
 | |
| }
 | |
| 
 | |
| /**
 | |
|  * Add padding to a message buffer
 | |
|  * @param messageBuffer The buffer to add padding to.
 | |
|  */
 | |
| export function addMessagePadding(messageBuffer: Uint8Array): Uint8Array {
 | |
|   window?.log?.info('Adding message padding...');
 | |
| 
 | |
|   const plaintext = new Uint8Array(getPaddedMessageLength(messageBuffer.byteLength + 1) - 1);
 | |
|   plaintext.set(new Uint8Array(messageBuffer));
 | |
|   plaintext[messageBuffer.byteLength] = 0x80;
 | |
| 
 | |
|   return plaintext;
 | |
| }
 | |
| 
 | |
| function getPaddedMessageLength(originalLength: number): number {
 | |
|   const messageLengthWithTerminator = originalLength + 1;
 | |
|   let messagePartCount = Math.floor(messageLengthWithTerminator / 160);
 | |
| 
 | |
|   if (messageLengthWithTerminator % 160 !== 0) {
 | |
|     messagePartCount += 1;
 | |
|   }
 | |
| 
 | |
|   return messagePartCount * 160;
 | |
| }
 | |
| 
 | |
| /*
 | |
|  * If the attachment has padding, remove the padding and return the unpad attachment
 | |
|  */
 | |
| export function getUnpaddedAttachment(
 | |
|   data: ArrayBuffer,
 | |
|   unpaddedExpectedSize: number
 | |
| ): ArrayBuffer | null {
 | |
|   window?.log?.info('Removing attachment padding...');
 | |
| 
 | |
|   // to have a padding we must have a strictly longer length expected
 | |
|   if (data.byteLength <= unpaddedExpectedSize) {
 | |
|     return null;
 | |
|   }
 | |
|   // we now consider that anything coming after the expected size is padding, no matter what there is there
 | |
|   return data.slice(0, unpaddedExpectedSize);
 | |
| }
 | |
| 
 | |
| export function addAttachmentPadding(data: ArrayBuffer): ArrayBuffer {
 | |
|   const originalUInt = new Uint8Array(data);
 | |
|   window?.log.info('Adding attchment padding...');
 | |
| 
 | |
|   const paddedSize = Math.max(
 | |
|     541,
 | |
|     Math.floor(Math.pow(1.05, Math.ceil(Math.log(originalUInt.length) / Math.log(1.05))))
 | |
|   );
 | |
|   const paddedData = new ArrayBuffer(paddedSize);
 | |
|   const paddedUInt = new Uint8Array(paddedData);
 | |
| 
 | |
|   paddedUInt.fill(PADDING_BYTE, originalUInt.length);
 | |
|   paddedUInt.set(originalUInt);
 | |
| 
 | |
|   return paddedUInt.buffer;
 | |
| }
 |