mirror of
https://github.com/fluencelabs/js-libp2p-crypto
synced 2025-06-28 22:31:48 +00:00
fix: better error for missing web crypto
This PR simply detects missing web crypto and throws an error with an appropriate message. This is a stepping stone that will help users understand the problem until we have time to do a refactor of this module and of all the modules that use it to enable optionally passing your own crypto implementation. refs https://github.com/libp2p/js-libp2p-crypto/pull/149 refs https://github.com/libp2p/js-libp2p-crypto/pull/150 refs https://github.com/libp2p/js-libp2p-crypto/issues/105 refs https://github.com/ipfs/js-ipfs/issues/2153 refs https://github.com/ipfs/js-ipfs/issues/2017 License: MIT Signed-off-by: Alan Shaw <alan@tableflip.io>
This commit is contained in:
@ -1,6 +1,6 @@
|
||||
'use strict'
|
||||
|
||||
const webcrypto = require('../webcrypto.js')
|
||||
const webcrypto = require('../webcrypto')
|
||||
const lengths = require('./lengths')
|
||||
|
||||
const hashTypes = {
|
||||
@ -10,13 +10,13 @@ const hashTypes = {
|
||||
}
|
||||
|
||||
const sign = async (key, data) => {
|
||||
return Buffer.from(await webcrypto.subtle.sign({ name: 'HMAC' }, key, data))
|
||||
return Buffer.from(await webcrypto.get().subtle.sign({ name: 'HMAC' }, key, data))
|
||||
}
|
||||
|
||||
exports.create = async function (hashType, secret) {
|
||||
const hash = hashTypes[hashType]
|
||||
|
||||
const key = await webcrypto.subtle.importKey(
|
||||
const key = await webcrypto.get().subtle.importKey(
|
||||
'raw',
|
||||
secret,
|
||||
{
|
||||
|
@ -1,7 +1,7 @@
|
||||
'use strict'
|
||||
|
||||
const errcode = require('err-code')
|
||||
const webcrypto = require('../webcrypto.js')
|
||||
const webcrypto = require('../webcrypto')
|
||||
const BN = require('asn1.js').bignum
|
||||
const { toBase64, toBn } = require('../util')
|
||||
const validateCurveType = require('./validate-curve-type')
|
||||
@ -14,8 +14,7 @@ const bits = {
|
||||
|
||||
exports.generateEphmeralKeyPair = async function (curve) {
|
||||
validateCurveType(Object.keys(bits), curve)
|
||||
|
||||
const pair = await webcrypto.subtle.generateKey(
|
||||
const pair = await webcrypto.get().subtle.generateKey(
|
||||
{
|
||||
name: 'ECDH',
|
||||
namedCurve: curve
|
||||
@ -29,7 +28,7 @@ exports.generateEphmeralKeyPair = async function (curve) {
|
||||
let privateKey
|
||||
|
||||
if (forcePrivate) {
|
||||
privateKey = await webcrypto.subtle.importKey(
|
||||
privateKey = await webcrypto.get().subtle.importKey(
|
||||
'jwk',
|
||||
unmarshalPrivateKey(curve, forcePrivate),
|
||||
{
|
||||
@ -44,7 +43,7 @@ exports.generateEphmeralKeyPair = async function (curve) {
|
||||
}
|
||||
|
||||
const keys = [
|
||||
await webcrypto.subtle.importKey(
|
||||
await webcrypto.get().subtle.importKey(
|
||||
'jwk',
|
||||
unmarshalPublicKey(curve, theirPub),
|
||||
{
|
||||
@ -57,7 +56,7 @@ exports.generateEphmeralKeyPair = async function (curve) {
|
||||
privateKey
|
||||
]
|
||||
|
||||
return Buffer.from(await webcrypto.subtle.deriveBits(
|
||||
return Buffer.from(await webcrypto.get().subtle.deriveBits(
|
||||
{
|
||||
name: 'ECDH',
|
||||
namedCurve: curve,
|
||||
@ -68,7 +67,7 @@ exports.generateEphmeralKeyPair = async function (curve) {
|
||||
))
|
||||
}
|
||||
|
||||
const publicKey = await webcrypto.subtle.exportKey('jwk', pair.publicKey)
|
||||
const publicKey = await webcrypto.get().subtle.exportKey('jwk', pair.publicKey)
|
||||
|
||||
return {
|
||||
key: marshalPublicKey(publicKey),
|
||||
|
@ -1,12 +1,12 @@
|
||||
'use strict'
|
||||
|
||||
const webcrypto = require('../webcrypto.js')
|
||||
const webcrypto = require('../webcrypto')
|
||||
const randomBytes = require('../random-bytes')
|
||||
|
||||
exports.utils = require('./rsa-utils')
|
||||
|
||||
exports.generateKey = async function (bits) {
|
||||
const pair = await webcrypto.subtle.generateKey(
|
||||
const pair = await webcrypto.get().subtle.generateKey(
|
||||
{
|
||||
name: 'RSASSA-PKCS1-v1_5',
|
||||
modulusLength: bits,
|
||||
@ -27,7 +27,7 @@ exports.generateKey = async function (bits) {
|
||||
|
||||
// Takes a jwk key
|
||||
exports.unmarshalPrivateKey = async function (key) {
|
||||
const privateKey = await webcrypto.subtle.importKey(
|
||||
const privateKey = await webcrypto.get().subtle.importKey(
|
||||
'jwk',
|
||||
key,
|
||||
{
|
||||
@ -57,7 +57,7 @@ exports.unmarshalPrivateKey = async function (key) {
|
||||
exports.getRandomValues = randomBytes
|
||||
|
||||
exports.hashAndSign = async function (key, msg) {
|
||||
const privateKey = await webcrypto.subtle.importKey(
|
||||
const privateKey = await webcrypto.get().subtle.importKey(
|
||||
'jwk',
|
||||
key,
|
||||
{
|
||||
@ -68,7 +68,7 @@ exports.hashAndSign = async function (key, msg) {
|
||||
['sign']
|
||||
)
|
||||
|
||||
const sig = await webcrypto.subtle.sign(
|
||||
const sig = await webcrypto.get().subtle.sign(
|
||||
{ name: 'RSASSA-PKCS1-v1_5' },
|
||||
privateKey,
|
||||
Uint8Array.from(msg)
|
||||
@ -78,7 +78,7 @@ exports.hashAndSign = async function (key, msg) {
|
||||
}
|
||||
|
||||
exports.hashAndVerify = async function (key, sig, msg) {
|
||||
const publicKey = await webcrypto.subtle.importKey(
|
||||
const publicKey = await webcrypto.get().subtle.importKey(
|
||||
'jwk',
|
||||
key,
|
||||
{
|
||||
@ -89,7 +89,7 @@ exports.hashAndVerify = async function (key, sig, msg) {
|
||||
['verify']
|
||||
)
|
||||
|
||||
return webcrypto.subtle.verify(
|
||||
return webcrypto.get().subtle.verify(
|
||||
{ name: 'RSASSA-PKCS1-v1_5' },
|
||||
publicKey,
|
||||
sig,
|
||||
@ -99,13 +99,13 @@ exports.hashAndVerify = async function (key, sig, msg) {
|
||||
|
||||
function exportKey (pair) {
|
||||
return Promise.all([
|
||||
webcrypto.subtle.exportKey('jwk', pair.privateKey),
|
||||
webcrypto.subtle.exportKey('jwk', pair.publicKey)
|
||||
webcrypto.get().subtle.exportKey('jwk', pair.privateKey),
|
||||
webcrypto.get().subtle.exportKey('jwk', pair.publicKey)
|
||||
])
|
||||
}
|
||||
|
||||
function derivePublicFromPrivate (jwKey) {
|
||||
return webcrypto.subtle.importKey(
|
||||
return webcrypto.get().subtle.importKey(
|
||||
'jwk',
|
||||
{
|
||||
kty: jwKey.kty,
|
||||
|
@ -1,5 +1,24 @@
|
||||
/* global self */
|
||||
/* eslint-env browser */
|
||||
|
||||
'use strict'
|
||||
|
||||
module.exports = self.crypto || self.msCrypto
|
||||
// Check native crypto exists and is enabled (In insecure context `self.crypto`
|
||||
// exists but `self.crypto.subtle` does not).
|
||||
exports.get = (win = self) => {
|
||||
const nativeCrypto = win.crypto || win.msCrypto
|
||||
|
||||
if (!nativeCrypto || !nativeCrypto.subtle) {
|
||||
throw Object.assign(
|
||||
new Error(
|
||||
'Missing Web Crypto API. ' +
|
||||
'The most likely cause of this error is that this page is being accessed ' +
|
||||
'from an insecure context (i.e. not HTTPS). For more information and ' +
|
||||
'possible resolutions see ' +
|
||||
'https://github.com/libp2p/js-libp2p-crypto/blob/master/README.md#web-crypto-api'
|
||||
),
|
||||
{ code: 'ERR_MISSING_WEB_CRYPTO' }
|
||||
)
|
||||
}
|
||||
|
||||
return nativeCrypto
|
||||
}
|
||||
|
Reference in New Issue
Block a user