Socket
Socket
Sign inDemoInstall

@trust/webcrypto

Package Overview
Dependencies
Maintainers
7
Versions
19
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@trust/webcrypto - npm Package Compare versions

Comparing version 0.3.0 to 0.4.0

2

package.json
{
"name": "@trust/webcrypto",
"version": "0.3.0",
"version": "0.4.0",
"description": "WebCrypto API for Node.js",

@@ -5,0 +5,0 @@ "main": "src/index.js",

@@ -87,4 +87,4 @@ # W3C Web Cryptography API _(@trust/webcrypto)_

|AES-CTR | _ | _ | | | | _ | | | _ | _ | _ | _ |
|AES-CBC | ✔ | ✔ | | | | ✔ | | | ✔ | ✔ | _ | _ |
|AES-GCM | ✔ | ✔ | | | | ✔ | | | ✔ | ✔ | _ | _ |
|AES-CBC | ✔ | ✔ | | | | ✔ | | | ✔ | ✔ | ✔ | ✔ |
|AES-GCM | ✔ | ✔ | | | | ✔ | | | ✔ | ✔ | ✔ | ✔ |
|AES-KW | | | | | | _ | | | _ | _ | _ | _ |

@@ -91,0 +91,0 @@ |HMAC | | | ✔ | ✔ | | ✔ | | | ✔ | ✔ | | |

@@ -256,3 +256,3 @@ /**

if (jwk.key_ops){
key_ops.forEach(op => {
jwk.key_ops.forEach(op => {
if (op !== 'encrypt'

@@ -328,3 +328,3 @@ && op !== 'decrypt'

// 2.2.1 Validate JsonWebKey
let jwk = new JsonWebKey(key)
let jwk = new JsonWebKey()

@@ -331,0 +331,0 @@ // 2.2.2 Set kty property

@@ -331,3 +331,3 @@ /**

if (jwk.key_ops){
key_ops.forEach(op => {
jwk.key_ops.forEach(op => {
if (op !== 'encrypt'

@@ -403,3 +403,3 @@ && op !== 'decrypt'

// 2.2.1 Validate JsonWebKey
let jwk = new JsonWebKey(key)
let jwk = new JsonWebKey()

@@ -406,0 +406,0 @@ // 2.2.2 Set kty property

@@ -134,3 +134,3 @@ /**

//supportedAlgorithms.define('AES-CBC', 'wrapKey', )
//supportedAlgorithms.define('AES-GCM', 'wrapKey', )
supportedAlgorithms.define('AES-GCM', 'wrapKey', '../algorithms/AES-GCM')
//supportedAlgorithms.define('AES-CFB', 'wrapKey', )

@@ -145,3 +145,3 @@ //supportedAlgorithms.define('AES-KW', 'wrapKey', )

//supportedAlgorithms.define('AES-CBC', 'unwrapKey', )
//supportedAlgorithms.define('AES-GCM', 'unwrapKey', )
supportedAlgorithms.define('AES-GCM', 'unwrapKey', '../algorithms/AES-GCM')
//supportedAlgorithms.define('AES-CFB', 'unwrapKey', )

@@ -148,0 +148,0 @@ //supportedAlgorithms.define('AES-KW', 'unwrapKey', )

@@ -10,2 +10,3 @@ /**

const {InvalidAccessError, NotSupportedError} = require('./errors')
const {TextEncoder,TextDecoder} = require('text-encoding')

@@ -367,3 +368,71 @@ /**

wrapKey (format, key, wrappingKey, wrapAlgorithm) {
return new Promise()
// 1. Parameters
// 2. Setup normalizedAlgorithm with op as 'unwrap'
let normalizedAlgorithm = supportedAlgorithms.normalize('wrapKey', wrapAlgorithm)
if (normalizedAlgorithm instanceof Error) {
// 3. If failed, then try again with op as 'encrypt'
normalizedAlgorithm = supportedAlgorithms.normalize('encrypt', wrapAlgorithm)
}
// 4. Otherwise reject outright
if (normalizedAlgorithm instanceof Error) {
return Promise.reject(normalizedAlgorithm)
}
// 5-6. Setup and asynchronously return a new promise
return new Promise((resolve, reject) => {
// 7. Try catch the following step...
// if anything goes wrong then reject the promise outright
try {
// 8. Validate normalizedAlgorithm name property
if (normalizedAlgorithm.name !== wrappingKey.algorithm.name) {
throw new InvalidAccessError('NormalizedAlgorthm name must be same as wrappingKey algorithm name')
}
// 9. Validate usages property contains wrap
if (!wrappingKey.usages.includes('wrapKey')) {
throw new InvalidAccessError('Wrapping key usages must include "wrapKey"')
}
// 10. Validate algorithm contains exportKey
let exportKeyAlgorithms = supportedAlgorithms['exportKey']
if (!exportKeyAlgorithms[key.algorithm.name]) {
throw new NotSupportedError(key.algorithm.name)
}
// 11. Validate extractable property
if (key.extractable === false) {
throw new InvalidAccessError('Key is not extractable')
}
// 12. Generate extracted key
return this.exportKey(format,key)
.then(exportedKey => {
let bytes
// 13.1. If format is "raw", "pkcs8", or "spki":
if (["raw", "pkcs8","spki"].includes(format)) {
bytes = exportedKey
}
// 13.2. If format is "jwk"
else if (format === "jwk"){
let json = JSON.stringify(exportedKey)
bytes = new TextEncoder().encode(json)
}
// 14.1. If the normalizedAlgorithm supports wrapKey then use it
if (normalizedAlgorithm['wrapKey']){
return normalizedAlgorithm.wrapKey(wrapAlgorithm,wrappingKey,new Uint8Array(bytes))
}
// 14.2. Otherwise try with encrypt
else if (normalizedAlgorithm['encrypt']){
return normalizedAlgorithm.encrypt(wrapAlgorithm,wrappingKey,new Uint8Array(bytes))
}
// 14.3. Otherwise throw error
else {
return reject (new NotSupportedError(normalizedAlgorithm.name))
}
})
// 15. Return the resulting promise
.then(resolve)
} catch (error) {
return reject(error)
}
})
}

@@ -386,4 +455,94 @@

*/
unwrapKey (format, wrappedKey, unwrappingKey, unwrapAlgorithm, unwrappedKeyAlgorithm, exractable, keyUsages) {
return new Promise()
unwrapKey (format, wrappedKey, unwrappingKey, unwrapAlgorithm, unwrappedKeyAlgorithm, extractable, keyUsages) {
// 1. Parameters
// 2. Ommited due to redundancy
// 3. Setup normalizedAlgorithm with op as 'unwrap'
let normalizedAlgorithm = supportedAlgorithms.normalize('unwrapKey', unwrapAlgorithm)
if (normalizedAlgorithm instanceof Error) {
// 4. If failed, then try again with op as 'encrypt'
normalizedAlgorithm = supportedAlgorithms.normalize('decrypt', unwrapAlgorithm)
}
// 5. Otherwise reject outright
if (normalizedAlgorithm instanceof Error) {
return Promise.reject(normalizedAlgorithm)
}
// 6. Setup normalizedKeyAlgorithm
let normalizedKeyAlgorithm = supportedAlgorithms.normalize('importKey', unwrapAlgorithm)
if (normalizedKeyAlgorithm instanceof Error) {
// 7. If failed, then try again with op as 'encrypt'
return Promise.reject(normalizedKeyAlgorithm)
}
// 8-9. Setup and asynchronously return a new promise
return new Promise((resolve, reject) => {
// 10. Try catch the following step...
// if anything goes wrong then reject the promise outright
try {
// 11. Validate normalizedAlgorithm name property
if (normalizedAlgorithm.name !== unwrappingKey.algorithm.name) {
throw new InvalidAccessError('NormalizedAlgorthm name must be same as unwrappingKey algorithm name')
}
// 12. Validate usages property contains unwrap
if (!unwrappingKey.usages.includes('unwrapKey')) {
throw new InvalidAccessError('Unwrapping key usages must include "unwrapKey"')
}
let keyPromise
// 13.1. If the normalizedAlgorithm supports unwrapKey then use it
if (normalizedAlgorithm['unwrapKey']){
keyPromise = this.unwrapKey(unwrapAlgorithm,unwrappingKey,wrappedKey)
}
// 13.2. Otherwise try with decrypt
else if (normalizedAlgorithm['decrypt']){
keyPromise = this.decrypt(unwrapAlgorithm,unwrappingKey,wrappedKey)
}
// 13.3. Otherwise throw error
else {
return reject (new NotSupportedError(normalizedAlgorithm.name))
}
return keyPromise.then( key => {
let bytes
// 14.1. If format is "raw", "pkcs8", or "spki":
if (["raw", "pkcs8","spki"].includes(format)) {
bytes = key
}
// 14.2. If format is "jwk"
else if (format === "jwk"){
bytes = JSON.parse(new TextDecoder().decode(key))
}
// 15. Import the resulting unwrapped content
// importKey (format, keyData, algorithm, extractable, keyUsages)
return normalizedKeyAlgorithm.importKey(format,
bytes,
unwrappedKeyAlgorithm,
extractable,
keyUsages)
}).then(result => {
// 16. Validate type parameters and usage length
if ((result.type === "secret" || result.type === "private") && result.usages.length === 0){
throw new SyntaxError("Usages cannot be empty")
}
// 17. Set extractable
result.extractable = extractable
// 18. Set usages
result.usages = keyUsages
// 19. Resolve promise
return resolve(result)
}).catch(console.log)
} catch (error) {
return reject(error)
}
})
}

@@ -395,2 +554,2 @@ }

*/
module.exports = SubtleCrypto
module.exports = SubtleCrypto

@@ -21,2 +21,3 @@ /**

const AES_CBC = require('../src/algorithms/AES-CBC')
const AES_GCM = require('../src/algorithms/AES-GCM')
const {TextEncoder,TextDecoder} = require('text-encoding')

@@ -36,3 +37,9 @@

/**
* Test code for AES-GCM
*/
const good_iv = Buffer.from([ 220, 29, 37, 164, 41, 84, 153, 197, 157, 122, 156, 254, 196, 161, 114, 74 ])
/**
* Tests

@@ -899,3 +906,181 @@ */

describe('wrapKey', () => {
it('should return a Promise')
describe('with invalid algorithm', () => {
let promise, error
beforeEach(() => {
let aes = new AES_GCM({ name: "AES-GCM", length: 256 })
let key = aes.importKey(
"jwk",
{
kty: "oct",
k: "Y0zt37HgOx-BY7SQjYVmrqhPkO44Ii2Jcb9yydUDPfE",
alg: "A256GCM",
ext: true,
},
{
name: "AES-GCM",
},
true,
["encrypt", "decrypt","wrapKey","unwrapKey"]
)
promise = crypto.subtle.wrapKey('jwk',key,key,{name: "AES-NONESENSE"})
promise.catch(err => error = err)
})
it('should return a promise', () => {
promise.should.be.instanceof(Promise)
})
it('should reject the promise', () => {
error.should.be.instanceof(Error)
error.message.should.include('is not a supported algorithm')
})
})
describe('with invalid name property', () => {
let promise, error
beforeEach( done => {
let aes = new AES_GCM({ name: "AES-GCM", length: 256 })
let key = aes.importKey(
"jwk",
{
kty: "oct",
k: "Y0zt37HgOx-BY7SQjYVmrqhPkO44Ii2Jcb9yydUDPfE",
alg: "A256GCM",
ext: true,
},
{
name: "AES-GCM",
},
true,
["encrypt", "decrypt","wrapKey","unwrapKey"]
)
let alg = {name: "AES-CBC",iv:good_iv} // Not GCM
promise = crypto.subtle.wrapKey('jwk',key,key,alg)
promise.catch(err => {
error = err
done()
})
})
it('should reject the promise', () => {
promise.should.be.rejected
error.should.be.instanceof(Error)
error.message.should.include('NormalizedAlgorthm name must be same as wrappingKey algorithm name')
})
})
describe('with invalid key ops', () => {
let promise, error
beforeEach(done => {
let aes = new AES_GCM({ name: "AES-GCM", length: 256 })
let key = aes.importKey(
"jwk",
{
kty: "oct",
k: "Y0zt37HgOx-BY7SQjYVmrqhPkO44Ii2Jcb9yydUDPfE",
alg: "A256GCM",
ext: true,
},
{
name: "AES-GCM",
},
true,
["encrypt", "decrypt"]
)
let alg = {name: "AES-GCM",iv:good_iv}
promise = crypto.subtle.wrapKey('jwk',key,key,alg)
promise.catch(err => {
error = err
done()
})
})
it('should reject the promise', () => {
promise.should.be.rejected
error.should.be.instanceof(Error)
error.message.should.include('Wrapping key usages must include "wrapKey"')
})
})
describe('with invalid extractable property', () => {
let promise, error
beforeEach(done => {
let aes = new AES_GCM({ name: "AES-GCM", length: 256 })
let key = aes.importKey(
"jwk",
{
kty: "oct",
k: "Y0zt37HgOx-BY7SQjYVmrqhPkO44Ii2Jcb9yydUDPfE",
alg: "A256GCM",
ext: true,
},
{
name: "AES-GCM",
},
false, // Incorrect
["encrypt", "decrypt","wrapKey"]
)
let alg = {name: "AES-GCM",iv:good_iv}
promise = crypto.subtle.wrapKey('jwk',key,key,alg)
promise.catch(err => {
error = err
done()
})
})
it('should reject the promise', () => {
promise.should.be.rejected
error.should.be.instanceof(Error)
error.message.should.include('Key is not extractable')
})
})
describe('with valid arguments', () => {
let promise, result, error
beforeEach(done => {
let aes = new AES_GCM({ name: "AES-GCM", length: 256 })
let key = aes.importKey(
"jwk",
{
kty: "oct",
k: "Y0zt37HgOx-BY7SQjYVmrqhPkO44Ii2Jcb9yydUDPfE",
alg: "A256GCM",
ext: true,
},
{
name: "AES-GCM",
},
true,
["encrypt", "decrypt","wrapKey"]
)
let alg = {name: "AES-GCM",iv:good_iv}
promise = crypto.subtle.wrapKey('jwk',key,key,alg)
promise.then(res => {
result = res
done()
})
.catch(err => {
error = err
done()
})
})
it('should return a promise', () => {
promise.should.be.instanceof(Promise)
})
it('should resolve the promise', () => {
result.should.be.instanceof(ArrayBuffer)
})
it('should not reject the promise', () => {
expect(error).to.be.undefined
})
})
})

@@ -907,4 +1092,225 @@

describe('unwrapKey', () => {
it('should return a Promise')
let wrappedKey
before (() => {
wrappedKey = new Uint8Array([
34,105,32,16,166,133,127,43,31,27,51,61,224,43,87,63,222,
207,113,84,80,101,73,170,5,67,147,1,16,76,204,98,165,66,
25,48,219,41,143,247,79,136,187,202,198,2,176,61,50,127,
32,227,5,15,115,49,174,204,21,201,34,37,45,36,68,51,55,
138,56,65,242,121,247,165,89,74,183,157,112,42,245,233,
236,138,177,94,14,151,55,134,166,103,181,77,59,234,225,
115,127,249,108,64,97,144,99,41,205,18,8,123,16,203,141,
104,145,133,96,15,25,97,109,66,16,32,120,207,212,230,175,
31,202,237,230,158,207,35,145,82,87,110,67,159,36,146,148,
147,222,172,81,162,70,16,152,136,228,100,27,111,138,171])
})
describe('with invalid algorithm', () => {
let promise, error
beforeEach(() => {
let aes = new AES_GCM({ name: "AES-GCM", length: 256 })
let key = aes.importKey(
"jwk",
{
kty: "oct",
k: "Y0zt37HgOx-BY7SQjYVmrqhPkO44Ii2Jcb9yydUDPfE",
alg: "A256GCM",
ext: true,
},
{
name: "AES-GCM",
},
true,
["encrypt", "decrypt","wrapKey","unwrapKey"]
)
promise = crypto.subtle.unwrapKey(
'jwk',
wrappedKey,
key,
{
name:"AES-NONSENSE",
iv: good_iv,
tagLength: 128
},
{
name: "AES-NONSENSE",
length: 256
},
true,
["encrypt","decrypt","wrapKey","unwrapKey"]
)
promise.catch(err => error = err)
})
it('should return a promise', () => {
promise.should.be.instanceof(Promise)
})
it('should reject the promise', () => {
error.should.be.instanceof(Error)
error.message.should.include('is not a supported algorithm')
})
})
describe('with invalid name property', () => {
let promise, result, error
before( done => {
let aes = new AES_GCM({ name: "AES-GCM", length: 256 })
let key = aes.importKey(
"jwk",
{
kty: "oct",
k: "Y0zt37HgOx-BY7SQjYVmrqhPkO44Ii2Jcb9yydUDPfE",
alg: "A256GCM",
ext: true,
},
{
name: "AES-GCM",
},
true,
["encrypt", "decrypt","wrapKey","unwrapKey"]
)
promise = crypto.subtle.unwrapKey(
'jwk',
wrappedKey,
key,
{
name:"AES-CBC", // Incorrect
iv: good_iv,
tagLength: 128
},
{
name: "AES-CBC", // Incorrect
length: 256
},
true,
["encrypt","decrypt","wrapKey","unwrapKey"]
)
promise
.then ( res => {
result = res
done()
})
.catch(err => {
error = err
done()
})
})
it('should reject the promise', () => {
promise.should.be.rejected
error.should.be.instanceof(Error)
error.message.should.include('NormalizedAlgorthm name must be same as unwrappingKey algorithm name')
})
})
describe('with invalid key ops', () => {
let promise, error
before(done => {
let aes = new AES_GCM({ name: "AES-GCM", length: 256 })
let key = aes.importKey(
"jwk",
{
kty: "oct",
k: "Y0zt37HgOx-BY7SQjYVmrqhPkO44Ii2Jcb9yydUDPfE",
alg: "A256GCM",
ext: true,
},
{
name: "AES-GCM",
},
true,
["encrypt", "decrypt"]
)
promise = crypto.subtle.unwrapKey(
'jwk',
wrappedKey,
key,
{
name:"AES-GCM",
iv: good_iv,
tagLength: 128
},
{
name: "AES-GCM",
length: 256
},
true,
["encrypt","decrypt"]
)
promise.catch(err => {
error = err
done()
})
})
it('should reject the promise', () => {
promise.should.be.rejected
error.should.be.instanceof(Error)
error.message.should.include('Unwrapping key usages must include "unwrapKey"')
})
})
describe('with valid arguments', () => {
let promise, result, error
before(done => {
let aes = new AES_GCM({ name: "AES-GCM", length: 256 })
let key = aes.importKey(
"jwk",
{
kty: "oct",
k: "Y0zt37HgOx-BY7SQjYVmrqhPkO44Ii2Jcb9yydUDPfE",
alg: "A256GCM",
ext: true,
},
{
name: "AES-GCM",
},
true,
["encrypt", "decrypt","wrapKey","unwrapKey"]
)
promise = crypto.subtle.unwrapKey(
'jwk',
wrappedKey,
key,
{
name:"AES-GCM",
iv: good_iv,
tagLength: 128
},
{
name: "AES-GCM",
length: 256
},
true,
["encrypt","decrypt","wrapKey","unwrapKey"]
)
promise
.then ( res => {
result = res
done()
})
.catch(err => {
error = err
done()
})
})
it('should return a promise', () => {
promise.should.be.instanceof(Promise)
})
it('should resolve the promise', () => {
result.should.be.instanceof(CryptoKey)
})
it('should not reject the promise', () => {
expect(error).to.be.undefined
})
})
})
})
SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc