@sphereon/ssi-sdk-ext.key-utils
Advanced tools
Comparing version 0.26.1-next.24 to 0.26.1-next.25
@@ -1,2 +0,2 @@ | ||
import { Hasher } from "@sphereon/ssi-types"; | ||
import { Hasher } from '@sphereon/ssi-types'; | ||
import { SupportedEncodings } from 'uint8arrays/to-string'; | ||
@@ -3,0 +3,0 @@ export type HashAlgorithm = 'SHA-256' | 'SHA-384' | 'SHA-512'; |
@@ -1,2 +0,2 @@ | ||
import { JWK } from "@sphereon/ssi-types"; | ||
import { JWK } from '@sphereon/ssi-types'; | ||
import type { ByteView } from 'multiformats/codecs/interface'; | ||
@@ -3,0 +3,0 @@ /** |
{ | ||
"name": "@sphereon/ssi-sdk-ext.key-utils", | ||
"description": "Sphereon SSI-SDK plugin for key creation.", | ||
"version": "0.26.1-next.24+696305c", | ||
"version": "0.26.1-next.25+2e4732d", | ||
"source": "src/index.ts", | ||
@@ -16,3 +16,3 @@ "main": "dist/index.js", | ||
"@noble/hashes": "1.6.1", | ||
"@sphereon/ssi-sdk-ext.x509-utils": "0.26.1-next.24+696305c", | ||
"@sphereon/ssi-sdk-ext.x509-utils": "0.26.1-next.25+2e4732d", | ||
"@sphereon/ssi-types": "0.30.2-feature.SDK.41.oidf.support.286", | ||
@@ -54,3 +54,3 @@ "@stablelib/ed25519": "^1.0.3", | ||
], | ||
"gitHead": "696305c89f5733b224b7ede3e38111fee666e78d" | ||
"gitHead": "2e4732ddfe4a6a4982cfd241882ee0212009e6ea" | ||
} |
@@ -1,6 +0,6 @@ | ||
import {sha256} from '@noble/hashes/sha256' | ||
import {sha384, sha512} from '@noble/hashes/sha512' | ||
import {Hasher} from "@sphereon/ssi-types"; | ||
import { sha256 } from '@noble/hashes/sha256' | ||
import { sha384, sha512 } from '@noble/hashes/sha512' | ||
import { Hasher } from '@sphereon/ssi-types' | ||
import * as u8a from 'uint8arrays' | ||
import {SupportedEncodings} from 'uint8arrays/to-string' | ||
import { SupportedEncodings } from 'uint8arrays/to-string' | ||
@@ -11,28 +11,28 @@ export type HashAlgorithm = 'SHA-256' | 'SHA-384' | 'SHA-512' | ||
export const digestMethodParams = ( | ||
hashAlgorithm: HashAlgorithm | ||
hashAlgorithm: HashAlgorithm | ||
): { hashAlgorithm: HashAlgorithm; digestMethod: TDigestMethod; hash: (data: Uint8Array) => Uint8Array } => { | ||
if (hashAlgorithm === 'SHA-256') { | ||
return {hashAlgorithm: 'SHA-256', digestMethod: sha256DigestMethod, hash: sha256} | ||
} else if (hashAlgorithm === 'SHA-384') { | ||
return {hashAlgorithm: 'SHA-384', digestMethod: sha384DigestMethod, hash: sha384} | ||
} else { | ||
return {hashAlgorithm: 'SHA-512', digestMethod: sha512DigestMethod, hash: sha512} | ||
} | ||
if (hashAlgorithm === 'SHA-256') { | ||
return { hashAlgorithm: 'SHA-256', digestMethod: sha256DigestMethod, hash: sha256 } | ||
} else if (hashAlgorithm === 'SHA-384') { | ||
return { hashAlgorithm: 'SHA-384', digestMethod: sha384DigestMethod, hash: sha384 } | ||
} else { | ||
return { hashAlgorithm: 'SHA-512', digestMethod: sha512DigestMethod, hash: sha512 } | ||
} | ||
} | ||
export const shaHasher: Hasher = (input: string, alg: string) : Uint8Array => { | ||
const hashAlgorithm: HashAlgorithm = alg.includes('384') ? 'SHA-384' : alg.includes('512') ? 'SHA-512' : 'SHA-256' | ||
return digestMethodParams(hashAlgorithm ).hash(u8a.fromString(input, 'utf-8')) | ||
export const shaHasher: Hasher = (input: string, alg: string): Uint8Array => { | ||
const hashAlgorithm: HashAlgorithm = alg.includes('384') ? 'SHA-384' : alg.includes('512') ? 'SHA-512' : 'SHA-256' | ||
return digestMethodParams(hashAlgorithm).hash(u8a.fromString(input, 'utf-8')) | ||
} | ||
const sha256DigestMethod = (input: string, encoding: SupportedEncodings = 'base16'): string => { | ||
return u8a.toString(sha256(u8a.fromString(input, 'utf-8')), encoding) | ||
return u8a.toString(sha256(u8a.fromString(input, 'utf-8')), encoding) | ||
} | ||
const sha384DigestMethod = (input: string, encoding: SupportedEncodings = 'base16'): string => { | ||
return u8a.toString(sha384(u8a.fromString(input, 'utf-8')), encoding) | ||
return u8a.toString(sha384(u8a.fromString(input, 'utf-8')), encoding) | ||
} | ||
const sha512DigestMethod = (input: string, encoding: SupportedEncodings = 'base16'): string => { | ||
return u8a.toString(sha512(u8a.fromString(input, 'utf-8')), encoding) | ||
return u8a.toString(sha512(u8a.fromString(input, 'utf-8')), encoding) | ||
} | ||
@@ -39,0 +39,0 @@ |
import { randomBytes } from '@ethersproject/random' | ||
// Do not change these require statements to imports before we change to ESM. Breaks external CJS packages depending on this module | ||
import {bls12_381} from "@noble/curves/bls12-381"; | ||
import {ed25519} from '@noble/curves/ed25519'; | ||
import {p256} from '@noble/curves/p256'; | ||
import {p384} from "@noble/curves/p384"; | ||
import {p521} from "@noble/curves/p521"; | ||
import {secp256k1} from '@noble/curves/secp256k1'; | ||
import { sha256, } from '@noble/hashes/sha256' | ||
import { bls12_381 } from '@noble/curves/bls12-381' | ||
import { ed25519 } from '@noble/curves/ed25519' | ||
import { p256 } from '@noble/curves/p256' | ||
import { p384 } from '@noble/curves/p384' | ||
import { p521 } from '@noble/curves/p521' | ||
import { secp256k1 } from '@noble/curves/secp256k1' | ||
import { sha256 } from '@noble/hashes/sha256' | ||
import { sha384, sha512 } from '@noble/hashes/sha512' | ||
@@ -701,3 +701,2 @@ import { generateRSAKeyAsPEM, hexToBase64, hexToPEM, PEMToJwk, privateKeyHexFromPEM } from '@sphereon/ssi-sdk-ext.x509-utils' | ||
export const globalCrypto = (setGlobal: boolean, suppliedCrypto?: Crypto): Crypto => { | ||
@@ -754,3 +753,3 @@ let webcrypto: Crypto | ||
const key = removeNulls(inputKey) | ||
validateJwk(key, {crvOptional: true}) | ||
validateJwk(key, { crvOptional: true }) | ||
const keyType = keyTypeFromCryptographicSuite({ crv: key.crv, kty: key.kty, alg: key.alg }) | ||
@@ -757,0 +756,0 @@ const publicKeyHex = await jwkToRawHexKey(key) |
@@ -1,4 +0,4 @@ | ||
import {JWK} from "@sphereon/ssi-types"; | ||
import type {ByteView} from 'multiformats/codecs/interface' | ||
import {TextDecoder, TextEncoder} from 'web-encoding' | ||
import { JWK } from '@sphereon/ssi-types' | ||
import type { ByteView } from 'multiformats/codecs/interface' | ||
import { TextDecoder, TextEncoder } from 'web-encoding' | ||
@@ -16,8 +16,8 @@ const textEncoder = new TextEncoder() | ||
function check(value: unknown, description: string, optional: boolean = false) { | ||
if (optional && !value) { | ||
return | ||
} | ||
if (typeof value !== 'string' || !value) { | ||
throw new Error(`${description} missing or invalid`) | ||
} | ||
if (optional && !value) { | ||
return | ||
} | ||
if (typeof value !== 'string' || !value) { | ||
throw new Error(`${description} missing or invalid`) | ||
} | ||
} | ||
@@ -31,5 +31,5 @@ | ||
function assertObject(value: unknown) { | ||
if (!value || typeof value !== 'object') { | ||
throw new Error('Value must be an object') | ||
} | ||
if (!value || typeof value !== 'object') { | ||
throw new Error('Value must be an object') | ||
} | ||
} | ||
@@ -47,33 +47,33 @@ | ||
export function validateJwk(jwk: any, opts?: { crvOptional?: boolean }) { | ||
assertObject(jwk) | ||
const {crvOptional = false} = opts ?? {} | ||
check(jwk.kty, '"kty" (Key Type) Parameter', false) | ||
assertObject(jwk) | ||
const { crvOptional = false } = opts ?? {} | ||
check(jwk.kty, '"kty" (Key Type) Parameter', false) | ||
// Check JWK required members based on the key type | ||
switch (jwk.kty) { | ||
/** | ||
* @see https://www.rfc-editor.org/rfc/rfc7518#section-6.2.1 | ||
*/ | ||
case 'EC': | ||
check(jwk.crv, '"crv" (Curve) Parameter', crvOptional) | ||
check(jwk.x, '"x" (X Coordinate) Parameter') | ||
check(jwk.y, '"y" (Y Coordinate) Parameter') | ||
break | ||
/** | ||
* @see https://www.rfc-editor.org/rfc/rfc8037#section-2 | ||
*/ | ||
case 'OKP': | ||
check(jwk.crv, '"crv" (Subtype of Key Pair) Parameter', crvOptional) // Shouldn't this one always be true as crv is not always present? | ||
check(jwk.x, '"x" (Public Key) Parameter') | ||
break | ||
/** | ||
* @see https://www.rfc-editor.org/rfc/rfc7518#section-6.3.1 | ||
*/ | ||
case 'RSA': | ||
check(jwk.e, '"e" (Exponent) Parameter') | ||
check(jwk.n, '"n" (Modulus) Parameter') | ||
break | ||
default: | ||
throw new Error('"kty" (Key Type) Parameter missing or unsupported') | ||
} | ||
// Check JWK required members based on the key type | ||
switch (jwk.kty) { | ||
/** | ||
* @see https://www.rfc-editor.org/rfc/rfc7518#section-6.2.1 | ||
*/ | ||
case 'EC': | ||
check(jwk.crv, '"crv" (Curve) Parameter', crvOptional) | ||
check(jwk.x, '"x" (X Coordinate) Parameter') | ||
check(jwk.y, '"y" (Y Coordinate) Parameter') | ||
break | ||
/** | ||
* @see https://www.rfc-editor.org/rfc/rfc8037#section-2 | ||
*/ | ||
case 'OKP': | ||
check(jwk.crv, '"crv" (Subtype of Key Pair) Parameter', crvOptional) // Shouldn't this one always be true as crv is not always present? | ||
check(jwk.x, '"x" (Public Key) Parameter') | ||
break | ||
/** | ||
* @see https://www.rfc-editor.org/rfc/rfc7518#section-6.3.1 | ||
*/ | ||
case 'RSA': | ||
check(jwk.e, '"e" (Exponent) Parameter') | ||
check(jwk.n, '"n" (Modulus) Parameter') | ||
break | ||
default: | ||
throw new Error('"kty" (Key Type) Parameter missing or unsupported') | ||
} | ||
} | ||
@@ -88,13 +88,13 @@ | ||
export function minimalJwk(jwk: any): JWK { | ||
// "default" case is not needed | ||
// eslint-disable-next-line default-case | ||
switch (jwk.kty) { | ||
case 'EC': | ||
return {...(jwk.crv && {crv: jwk.crv}), kty: jwk.kty, x: jwk.x, y: jwk.y} | ||
case 'OKP': | ||
return {...(jwk.crv && {crv: jwk.crv}), kty: jwk.kty, x: jwk.x} | ||
case 'RSA': | ||
return {e: jwk.e, kty: jwk.kty, n: jwk.n} | ||
} | ||
throw Error(`Unsupported key type (kty) provided: ${jwk.kty}`) | ||
// "default" case is not needed | ||
// eslint-disable-next-line default-case | ||
switch (jwk.kty) { | ||
case 'EC': | ||
return { ...(jwk.crv && { crv: jwk.crv }), kty: jwk.kty, x: jwk.x, y: jwk.y } | ||
case 'OKP': | ||
return { ...(jwk.crv && { crv: jwk.crv }), kty: jwk.kty, x: jwk.x } | ||
case 'RSA': | ||
return { e: jwk.e, kty: jwk.kty, n: jwk.n } | ||
} | ||
throw Error(`Unsupported key type (kty) provided: ${jwk.kty}`) | ||
} | ||
@@ -113,5 +113,5 @@ | ||
export function jwkJcsEncode(jwk: unknown): Uint8Array { | ||
validateJwk(jwk) | ||
const strippedJwk = minimalJwk(jwk) | ||
return textEncoder.encode(jcsCanonicalize(strippedJwk)) | ||
validateJwk(jwk) | ||
const strippedJwk = minimalJwk(jwk) | ||
return textEncoder.encode(jcsCanonicalize(strippedJwk)) | ||
} | ||
@@ -126,8 +126,8 @@ | ||
export function jwkJcsDecode(bytes: ByteView<JsonWebKey>): JsonWebKey { | ||
const jwk = JSON.parse(textDecoder.decode(bytes)) | ||
validateJwk(jwk) | ||
if (JSON.stringify(jwk) !== jcsCanonicalize(minimalJwk(jwk))) { | ||
throw new Error('The JWK embedded in the DID is not correctly formatted') | ||
} | ||
return jwk | ||
const jwk = JSON.parse(textDecoder.decode(bytes)) | ||
validateJwk(jwk) | ||
if (JSON.stringify(jwk) !== jcsCanonicalize(minimalJwk(jwk))) { | ||
throw new Error('The JWK embedded in the DID is not correctly formatted') | ||
} | ||
return jwk | ||
} | ||
@@ -137,55 +137,55 @@ | ||
export function jcsCanonicalize(object: any) { | ||
let buffer = '' | ||
serialize(object) | ||
return buffer | ||
let buffer = '' | ||
serialize(object) | ||
return buffer | ||
function serialize(object: any) { | ||
if (object === null || typeof object !== 'object' || object.toJSON != null) { | ||
///////////////////////////////////////////////// | ||
// Primitive type or toJSON - Use ES6/JSON // | ||
///////////////////////////////////////////////// | ||
buffer += JSON.stringify(object) | ||
} else if (Array.isArray(object)) { | ||
///////////////////////////////////////////////// | ||
// Array - Maintain element order // | ||
///////////////////////////////////////////////// | ||
buffer += '[' | ||
let next = false | ||
object.forEach((element) => { | ||
if (next) { | ||
buffer += ',' | ||
} | ||
next = true | ||
///////////////////////////////////////// | ||
// Array element - Recursive expansion // | ||
///////////////////////////////////////// | ||
serialize(element) | ||
}) | ||
buffer += ']' | ||
} else { | ||
///////////////////////////////////////////////// | ||
// Object - Sort properties before serializing // | ||
///////////////////////////////////////////////// | ||
buffer += '{' | ||
let next = false | ||
Object.keys(object) | ||
.sort() | ||
.forEach((property) => { | ||
if (next) { | ||
buffer += ',' | ||
} | ||
next = true | ||
/////////////////////////////////////////////// | ||
// Property names are strings - Use ES6/JSON // | ||
/////////////////////////////////////////////// | ||
buffer += JSON.stringify(property) | ||
buffer += ':' | ||
////////////////////////////////////////// | ||
// Property value - Recursive expansion // | ||
////////////////////////////////////////// | ||
serialize(object[property]) | ||
}) | ||
buffer += '}' | ||
function serialize(object: any) { | ||
if (object === null || typeof object !== 'object' || object.toJSON != null) { | ||
///////////////////////////////////////////////// | ||
// Primitive type or toJSON - Use ES6/JSON // | ||
///////////////////////////////////////////////// | ||
buffer += JSON.stringify(object) | ||
} else if (Array.isArray(object)) { | ||
///////////////////////////////////////////////// | ||
// Array - Maintain element order // | ||
///////////////////////////////////////////////// | ||
buffer += '[' | ||
let next = false | ||
object.forEach((element) => { | ||
if (next) { | ||
buffer += ',' | ||
} | ||
next = true | ||
///////////////////////////////////////// | ||
// Array element - Recursive expansion // | ||
///////////////////////////////////////// | ||
serialize(element) | ||
}) | ||
buffer += ']' | ||
} else { | ||
///////////////////////////////////////////////// | ||
// Object - Sort properties before serializing // | ||
///////////////////////////////////////////////// | ||
buffer += '{' | ||
let next = false | ||
Object.keys(object) | ||
.sort() | ||
.forEach((property) => { | ||
if (next) { | ||
buffer += ',' | ||
} | ||
next = true | ||
/////////////////////////////////////////////// | ||
// Property names are strings - Use ES6/JSON // | ||
/////////////////////////////////////////////// | ||
buffer += JSON.stringify(property) | ||
buffer += ':' | ||
////////////////////////////////////////// | ||
// Property value - Recursive expansion // | ||
////////////////////////////////////////// | ||
serialize(object[property]) | ||
}) | ||
buffer += '}' | ||
} | ||
} | ||
} |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Manifest confusion
Supply chain riskThis package has inconsistent metadata. This could be malicious or caused by an error when publishing the package.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Manifest confusion
Supply chain riskThis package has inconsistent metadata. This could be malicious or caused by an error when publishing the package.
Found 1 instance in 1 package
169909