Skip to content
This repository was archived by the owner on Jul 6, 2022. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions packages/encryption/src/Domain/Operator/001/Operator001.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import {
DecryptedPayloadInterface,
PayloadTimestampDefaults,
} from '@standardnotes/models'
import { SNPureCrypto } from '@standardnotes/sncrypto-common'
import { PureCryptoInterface } from '@standardnotes/sncrypto-common'
import { SNRootKey } from '../../RootKey/RootKey'
import { SNRootKeyParams } from '../../RootKey/RootKeyParams'
import { V001Algorithm } from '../../Algorithm'
Expand All @@ -34,9 +34,9 @@ const NO_IV = '00000000000000000000000000000000'
* A legacy operator no longer used to generate new accounts
*/
export class SNProtocolOperator001 implements AsynchronousOperator {
protected readonly crypto: SNPureCrypto
protected readonly crypto: PureCryptoInterface

constructor(crypto: SNPureCrypto) {
constructor(crypto: PureCryptoInterface) {
this.crypto = crypto
}

Expand Down
6 changes: 3 additions & 3 deletions packages/encryption/src/Domain/Operator/004/Operator004.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import {
ItemsKeyInterface,
PayloadTimestampDefaults,
} from '@standardnotes/models'
import { SNPureCrypto } from '@standardnotes/sncrypto-common'
import { PureCryptoInterface } from '@standardnotes/sncrypto-common'
import { SNRootKey } from '../../RootKey/RootKey'
import { SNRootKeyParams } from '../../RootKey/RootKeyParams'
import { V004Algorithm } from '../../Algorithm'
Expand All @@ -30,9 +30,9 @@ import { CreateNewRootKey } from '../../RootKey/Functions'
const PARTITION_CHARACTER = ':'

export class SNProtocolOperator004 implements SynchronousOperator {
protected readonly crypto: SNPureCrypto
protected readonly crypto: PureCryptoInterface

constructor(crypto: SNPureCrypto) {
constructor(crypto: PureCryptoInterface) {
this.crypto = crypto
}

Expand Down
4 changes: 2 additions & 2 deletions packages/encryption/src/Domain/Operator/Functions.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { SNPureCrypto } from '@standardnotes/sncrypto-common'
import { PureCryptoInterface } from '@standardnotes/sncrypto-common'
import { SNProtocolOperator001 } from '../Operator/001/Operator001'
import { SNProtocolOperator002 } from '../Operator/002/Operator002'
import { SNProtocolOperator003 } from '../Operator/003/Operator003'
Expand All @@ -7,7 +7,7 @@ import { AsynchronousOperator, SynchronousOperator } from '../Operator/Operator'
import { AnyOperator } from '../Operator/AnyOperator'
import { ProtocolVersion } from '@standardnotes/common'

export function createOperatorForVersion(version: ProtocolVersion, crypto: SNPureCrypto): AnyOperator {
export function createOperatorForVersion(version: ProtocolVersion, crypto: PureCryptoInterface): AnyOperator {
if (version === ProtocolVersion.V001) {
return new SNProtocolOperator001(crypto)
} else if (version === ProtocolVersion.V002) {
Expand Down
4 changes: 2 additions & 2 deletions packages/encryption/src/Domain/Operator/OperatorManager.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
import { SNPureCrypto } from '@standardnotes/sncrypto-common'
import { PureCryptoInterface } from '@standardnotes/sncrypto-common'
import { ProtocolVersion, ProtocolVersionLatest } from '@standardnotes/common'
import { createOperatorForVersion } from './Functions'
import { AnyOperator } from './AnyOperator'

export class OperatorManager {
private operators: Record<string, AnyOperator> = {}

constructor(private crypto: SNPureCrypto) {
constructor(private crypto: PureCryptoInterface) {
this.crypto = crypto
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import { findDefaultItemsKey } from '../Functions'
import { ItemsEncryptionService } from '../Items/ItemsEncryption'
import { KeyMode } from '../RootKey/KeyMode'
import { OperatorManager } from '../../Operator/OperatorManager'
import { SNPureCrypto } from '@standardnotes/sncrypto-common'
import { PureCryptoInterface } from '@standardnotes/sncrypto-common'
import { SNRootKey } from '../../RootKey/RootKey'
import { SNRootKeyParams } from '../../RootKey/RootKeyParams'
import { V001Algorithm, V002Algorithm } from '../../Algorithm'
Expand Down Expand Up @@ -86,7 +86,7 @@ export class EncryptionService extends Services.AbstractService<EncryptionServic
public deviceInterface: Services.DeviceInterface,
private storageService: Services.StorageServiceInterface,
private identifier: Common.ApplicationIdentifier,
public crypto: SNPureCrypto,
public crypto: PureCryptoInterface,
protected override internalEventBus: Services.InternalEventBusInterface,
) {
super(internalEventBus)
Expand Down
4 changes: 2 additions & 2 deletions packages/encryption/src/Domain/Vault/Vault.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { SNPureCrypto } from '@standardnotes/sncrypto-common'
import { PureCryptoInterface } from '@standardnotes/sncrypto-common'

export async function vaultToEmail(
crypto: SNPureCrypto,
crypto: PureCryptoInterface,
name: string,
userphrase: string,
): Promise<string | undefined> {
Expand Down
17 changes: 17 additions & 0 deletions packages/sncrypto-common/src/AES-GCM/Aes256GcmEncrypted.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import { Base64String } from '../Types/Base64String'
import { HexString } from '../Types/HexString'

/**
* @param iv initialization vector as a hex string
* @param tag authentication tag as a hex string
* @param ciphertext as a base64 string
* @param encoding that will be applied after decrypting
* @param aad additional authenticated data as a hex string
*/
export type Aes256GcmEncrypted<EncodingType> = {
iv: HexString
tag: HexString
ciphertext: Base64String
encoding: EncodingType
aad: HexString
}
15 changes: 15 additions & 0 deletions packages/sncrypto-common/src/AES-GCM/Aes256GcmInput.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import { HexString } from '../Types/HexString'
import { Unencrypted } from '../Types/Unencrypted'

/**
* @param unencrypted -- UTF-8 string or a `string` with `encoding`
* @param iv initialization vector as a hex string
* @param key encryption key as a hex string
* @param aad additional authenticated data as a hex string
*/
export type Aes256GcmInput<EncodingType> = {
unencrypted: Unencrypted<EncodingType>
iv: HexString
key: HexString
aad?: HexString
}
20 changes: 20 additions & 0 deletions packages/sncrypto-common/src/AES-GCM/CryptoAes256GcmInterface.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import { HexString } from '../Types/HexString'
import { Aes256GcmEncrypted } from './Aes256GcmEncrypted'
import { Aes256GcmInput } from './Aes256GcmInput'

export interface CryptoAes256GcmInterface<EncodingType> {
/**
* Encrypts a string using AES-GCM.
* @param input
* @returns An object which can be run through aes256GcmDecrypt to retrieve the input text.
*/
aes256GcmEncrypt(input: Aes256GcmInput<EncodingType>): Promise<Aes256GcmEncrypted<EncodingType>>

/**
* Decrypts a string using AES-GCM.
* @param encrypted
* @param key - encryption key as a hex string
* @returns A string encoded with encoding provided in the input
*/
aes256GcmDecrypt(encrypted: Aes256GcmEncrypted<EncodingType>, key: HexString): Promise<string>
}
25 changes: 25 additions & 0 deletions packages/sncrypto-common/src/Base64/CryptoBase64Interface.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import { Base64String } from '../Types/Base64String'
import { Utf8String } from '../Types/Utf8String'

export interface CryptoBase64Interface {
/**
* Converts a plain string into base64
* @param text - A plain string
* @returns A base64 encoded string
*/
base64Encode(text: Utf8String): Base64String

/**
* Converts a plain string into url-safe base64
* @param text - A plain string
* @returns A base64 encoded string
*/
base64URLEncode(text: Utf8String): Base64String

/**
* Converts a base64 string into a plain string
* @param base64String - A base64 encoded string
* @returns A plain string
*/
base64Decode(base64String: Base64String): Utf8String
}
Original file line number Diff line number Diff line change
@@ -1,39 +1,14 @@
export type HexString = string
export type Utf8String = string
export type Base64String = string

type SodiumStateAddress = unknown

export type StreamEncryptor = {
state: SodiumStateAddress
header: Base64String
}

export type StreamDecryptor = {
state: SodiumStateAddress
}

export type StreamDecryptorResult = {
message: Uint8Array
tag: SodiumConstant
}

export enum SodiumConstant {
CRYPTO_SECRETSTREAM_XCHACHA20POLY1305_STATEBYTES = 52,
CRYPTO_SECRETSTREAM_XCHACHA20POLY1305_ABYTES = 17,
CRYPTO_SECRETSTREAM_XCHACHA20POLY1305_HEADERBYTES = 24,
CRYPTO_SECRETSTREAM_XCHACHA20POLY1305_KEYBYTES = 32,
CRYPTO_SECRETSTREAM_XCHACHA20POLY1305_TAG_PUSH = 0,
CRYPTO_SECRETSTREAM_XCHACHA20POLY1305_TAG_PULL = 1,
CRYPTO_SECRETSTREAM_XCHACHA20POLY1305_TAG_REKEY = 2,
CRYPTO_SECRETSTREAM_XCHACHA20POLY1305_TAG_FINAL = 3,
CRYPTO_SECRETSTREAM_XCHACHA20POLY1305_MESSAGEBYTES_MAX = 0x3fffffff80,
}
import { Base64String } from '../Types/Base64String'
import { HexString } from '../Types/HexString'
import { SodiumConstant } from '../Types/SodiumConstant'
import { StreamDecryptor } from '../Types/StreamDecryptor'
import { StreamEncryptor } from '../Types/StreamEncryptor'
import { Utf8String } from '../Types/Utf8String'

/**
* Interface that clients have to implement to use snjs
*/
export interface SNPureCrypto {
export interface PureCryptoInterface {
initialize(): Promise<void>

/**
Expand Down
6 changes: 6 additions & 0 deletions packages/sncrypto-common/src/SHA/CryptoSha256Interface.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
import { HexString } from '../Types/HexString'
import { Utf8String } from '../Types/Utf8String'

export interface CryptoSha256Interface {
sha256(text: Utf8String): HexString
}
52 changes: 0 additions & 52 deletions packages/sncrypto-common/src/SnCryptoAes256Gcm.ts

This file was deleted.

1 change: 1 addition & 0 deletions packages/sncrypto-common/src/Types/Base64String.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export type Base64String = string
1 change: 1 addition & 0 deletions packages/sncrypto-common/src/Types/HexString.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export type HexString = string
11 changes: 11 additions & 0 deletions packages/sncrypto-common/src/Types/SodiumConstant.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
export enum SodiumConstant {
CRYPTO_SECRETSTREAM_XCHACHA20POLY1305_STATEBYTES = 52,
CRYPTO_SECRETSTREAM_XCHACHA20POLY1305_ABYTES = 17,
CRYPTO_SECRETSTREAM_XCHACHA20POLY1305_HEADERBYTES = 24,
CRYPTO_SECRETSTREAM_XCHACHA20POLY1305_KEYBYTES = 32,
CRYPTO_SECRETSTREAM_XCHACHA20POLY1305_TAG_PUSH = 0,
CRYPTO_SECRETSTREAM_XCHACHA20POLY1305_TAG_PULL = 1,
CRYPTO_SECRETSTREAM_XCHACHA20POLY1305_TAG_REKEY = 2,
CRYPTO_SECRETSTREAM_XCHACHA20POLY1305_TAG_FINAL = 3,
CRYPTO_SECRETSTREAM_XCHACHA20POLY1305_MESSAGEBYTES_MAX = 0x3fffffff80,
}
1 change: 1 addition & 0 deletions packages/sncrypto-common/src/Types/SodiumStateAddress.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export type SodiumStateAddress = unknown
5 changes: 5 additions & 0 deletions packages/sncrypto-common/src/Types/StreamDecryptor.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import { SodiumStateAddress } from './SodiumStateAddress'

export type StreamDecryptor = {
state: SodiumStateAddress
}
6 changes: 6 additions & 0 deletions packages/sncrypto-common/src/Types/StreamDecryptorResult.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
import { SodiumConstant } from './SodiumConstant'

export type StreamDecryptorResult = {
message: Uint8Array
tag: SodiumConstant
}
7 changes: 7 additions & 0 deletions packages/sncrypto-common/src/Types/StreamEncryptor.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import { Base64String } from './Base64String'
import { SodiumStateAddress } from './SodiumStateAddress'

export type StreamEncryptor = {
state: SodiumStateAddress
header: Base64String
}
6 changes: 6 additions & 0 deletions packages/sncrypto-common/src/Types/Unencrypted.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
import { Utf8String } from './Utf8String'

/**
* Either a plaintext (UTF-8 string) or a `string` with an `encoding`.
*/
export type Unencrypted<EncodingType> = Utf8String | { string: string; encoding: EncodingType }
1 change: 1 addition & 0 deletions packages/sncrypto-common/src/Types/Utf8String.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export type Utf8String = string
23 changes: 20 additions & 3 deletions packages/sncrypto-common/src/index.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,20 @@
export * from './pure_crypto'
export * from './utils'
export * from './SnCryptoAes256Gcm'
export * from './AES-GCM/Aes256GcmEncrypted'
export * from './AES-GCM/Aes256GcmInput'
export * from './AES-GCM/CryptoAes256GcmInterface'

export * from './Base64/CryptoBase64Interface'

export * from './Common/PureCryptoInterface'
export * from './Common/Utils'

export * from './SHA/CryptoSha256Interface'

export * from './Types/Base64String'
export * from './Types/HexString'
export * from './Types/SodiumConstant'
export * from './Types/SodiumStateAddress'
export * from './Types/StreamDecryptor'
export * from './Types/StreamDecryptorResult'
export * from './Types/StreamEncryptor'
export * from './Types/Unencrypted'
export * from './Types/Utf8String'
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { SnCryptoNode } from './crypto'
import { SnCryptoNode } from './SnCryptoNode'

describe('crypto operations', function () {
describe('SnCryptoNode', function () {
const crypto = new SnCryptoNode()

it('aes gcm', async function () {
Expand Down Expand Up @@ -155,4 +155,22 @@ describe('crypto operations', function () {
expect(decrypted).toEqual(string)
}
})

it('should encrypt data with SHA256', () => {
expect(crypto.sha256('hello world 🌍')).toEqual(
'e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855'
)
})

it ('should base64 encode a utf8 string', () => {
expect(crypto.base64Encode('Hello World')).toEqual('SGVsbG8gV29ybGQ=')
})

it ('should base64 encode a utf8 string with url safe option', () => {
expect(crypto.base64URLEncode('Hello World')).toEqual('SGVsbG8gV29ybGQ')
})

it ('should base64 decode a utf8 string', () => {
expect(crypto.base64Decode('SGVsbG8gV29ybGQ=')).toEqual('Hello World')
})
})
Loading