Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

@simplewebauthn/server

Package Overview
Dependencies
Maintainers
1
Versions
83
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@simplewebauthn/server - npm Package Compare versions

Comparing version 5.4.5 to 6.0.0

2

dist/authentication/verifyAuthenticationResponse.d.ts

@@ -34,3 +34,3 @@ /// <reference types="node" />

*/
export declare function verifyAuthenticationResponse(options: VerifyAuthenticationResponseOpts): VerifiedAuthenticationResponse;
export declare function verifyAuthenticationResponse(options: VerifyAuthenticationResponseOpts): Promise<VerifiedAuthenticationResponse>;
/**

@@ -37,0 +37,0 @@ * Result of authentication verification

@@ -10,3 +10,2 @@ "use strict";

const toHash_1 = require("../helpers/toHash");
const convertPublicKeyToPEM_1 = require("../helpers/convertPublicKeyToPEM");
const verifySignature_1 = require("../helpers/verifySignature");

@@ -35,3 +34,3 @@ const parseAuthenticatorData_1 = require("../helpers/parseAuthenticatorData");

*/
function verifyAuthenticationResponse(options) {
async function verifyAuthenticationResponse(options) {
const { credential, expectedChallenge, expectedOrigin, expectedRPID, authenticator, requireUserVerification, advancedFIDOConfig, } = options;

@@ -122,3 +121,3 @@ const { id, rawId, type: credentialType, response } = credential;

if (advancedFIDOConfig !== undefined) {
const { userVerification: fidoUserVerification, } = advancedFIDOConfig;
const { userVerification: fidoUserVerification } = advancedFIDOConfig;
/**

@@ -152,3 +151,2 @@ * Use FIDO Conformance-defined rules for verifying UP and UV flags

const signatureBase = Buffer.concat([authDataBuffer, clientDataHash]);
const publicKey = (0, convertPublicKeyToPEM_1.convertPublicKeyToPEM)(authenticator.credentialPublicKey);
const signature = base64url_1.default.toBuffer(response.signature);

@@ -164,3 +162,7 @@ if ((counter > 0 || authenticator.counter > 0) && counter <= authenticator.counter) {

const toReturn = {
verified: (0, verifySignature_1.verifySignature)(signature, signatureBase, publicKey),
verified: await (0, verifySignature_1.verifySignature)({
signature,
signatureBase,
credentialPublicKey: authenticator.credentialPublicKey,
}),
authenticationInfo: {

@@ -167,0 +169,0 @@ newCounter: counter,

/// <reference types="node" />
import type { SigningSchemeHash } from 'node-rsa';
import { COSEAlgorithmIdentifier } from '@simplewebauthn/typescript-types';

@@ -32,1 +31,6 @@ /**

};
/**
* Imported from node-rsa's types
*/
declare type SigningSchemeHash = 'pkcs1-ripemd160' | 'pkcs1-md4' | 'pkcs1-md5' | 'pkcs1-sha' | 'pkcs1-sha1' | 'pkcs1-sha224' | 'pkcs1-sha256' | 'pkcs1-sha384' | 'pkcs1-sha512' | 'pss-ripemd160' | 'pss-md4' | 'pss-md5' | 'pss-sha' | 'pss-sha1' | 'pss-sha224' | 'pss-sha256' | 'pss-sha384' | 'pss-sha512';
export {};

@@ -59,13 +59,14 @@ "use strict";

exports.COSEALGHASH = {
'-65535': 'sha1',
'-259': 'sha512',
'-258': 'sha384',
'-257': 'sha256',
'-258': 'sha384',
'-259': 'sha512',
'-65535': 'sha1',
'-39': 'sha512',
'-38': 'sha384',
'-37': 'sha256',
'-36': 'sha512',
'-35': 'sha384',
'-8': 'sha512',
'-7': 'sha256',
'-8': 'sha512',
'-36': 'sha512',
};
//# sourceMappingURL=convertCOSEtoPKCS.js.map
/// <reference types="node" />
declare type VerifySignatureOptsLeafCert = {
signature: Buffer;
signatureBase: Buffer;
leafCert: Buffer;
hashAlgorithm?: string;
};
declare type VerifySignatureOptsCredentialPublicKey = {
signature: Buffer;
signatureBase: Buffer;
credentialPublicKey: Buffer;
hashAlgorithm?: string;
};
/**

@@ -10,2 +22,3 @@ * Verify an authenticator's signature

*/
export declare function verifySignature(signature: Buffer, signatureBase: Buffer, publicKey: string, algo?: string): boolean;
export declare function verifySignature(opts: VerifySignatureOptsLeafCert | VerifySignatureOptsCredentialPublicKey): Promise<boolean>;
export {};

@@ -8,2 +8,7 @@ "use strict";

const crypto_1 = __importDefault(require("crypto"));
const cbor_1 = __importDefault(require("cbor"));
const ed25519_1 = require("@noble/ed25519");
const convertCOSEtoPKCS_1 = require("./convertCOSEtoPKCS");
const convertCertBufferToPEM_1 = require("./convertCertBufferToPEM");
const convertPublicKeyToPEM_1 = require("./convertPublicKeyToPEM");
/**

@@ -17,6 +22,55 @@ * Verify an authenticator's signature

*/
function verifySignature(signature, signatureBase, publicKey, algo = 'sha256') {
return crypto_1.default.createVerify(algo).update(signatureBase).verify(publicKey, signature);
async function verifySignature(opts) {
const { signature, signatureBase, hashAlgorithm = 'sha256' } = opts;
const _isLeafcertOpts = isLeafCertOpts(opts);
const _isCredPubKeyOpts = isCredPubKeyOpts(opts);
if (!_isLeafcertOpts && !_isCredPubKeyOpts) {
throw new Error('Must declare either "leafCert" or "credentialPublicKey"');
}
if (_isLeafcertOpts && _isCredPubKeyOpts) {
throw new Error('Must not declare both "leafCert" and "credentialPublicKey"');
}
let publicKeyPEM = '';
if (_isCredPubKeyOpts) {
const { credentialPublicKey } = opts;
// Decode CBOR to COSE
let struct;
try {
struct = cbor_1.default.decodeAllSync(credentialPublicKey)[0];
}
catch (err) {
const _err = err;
throw new Error(`Error decoding public key while converting to PEM: ${_err.message}`);
}
const kty = struct.get(convertCOSEtoPKCS_1.COSEKEYS.kty);
if (!kty) {
throw new Error('Public key was missing kty');
}
// Check key type
if (kty === convertCOSEtoPKCS_1.COSEKTY.OKP) {
// Verify Ed25519 slightly differently
const x = struct.get(convertCOSEtoPKCS_1.COSEKEYS.x);
if (!x) {
throw new Error('Public key was missing x (OKP)');
}
return (0, ed25519_1.verify)(signature, signatureBase, x);
}
else {
// Convert pubKey to PEM for ECC and RSA
publicKeyPEM = (0, convertPublicKeyToPEM_1.convertPublicKeyToPEM)(credentialPublicKey);
}
}
if (_isLeafcertOpts) {
const { leafCert } = opts;
publicKeyPEM = (0, convertCertBufferToPEM_1.convertCertBufferToPEM)(leafCert);
}
return crypto_1.default.createVerify(hashAlgorithm).update(signatureBase).verify(publicKeyPEM, signature);
}
exports.verifySignature = verifySignature;
function isLeafCertOpts(opts) {
return Object.keys(opts).indexOf('leafCert') >= 0;
}
function isCredPubKeyOpts(opts) {
return (Object.keys(opts).indexOf('credentialPublicKey') >= 0);
}
//# sourceMappingURL=verifySignature.js.map

@@ -227,4 +227,8 @@ "use strict";

// In the wise words of Yuriy Ackermann: "Get Martini friend, you are done!"
const leafCertPEM = (0, convertCertBufferToPEM_1.convertCertBufferToPEM)(x5c[0]);
return (0, verifySignature_1.verifySignature)(sig, certInfo, leafCertPEM, hashAlg);
return (0, verifySignature_1.verifySignature)({
signature: sig,
signatureBase: certInfo,
leafCert: x5c[0],
hashAlgorithm: hashAlg
});
}

@@ -231,0 +235,0 @@ exports.verifyAttestationTPM = verifyAttestationTPM;

@@ -83,7 +83,11 @@ "use strict";

const signatureBase = Buffer.concat([authData, clientDataHash]);
const leafCertPEM = (0, convertCertBufferToPEM_1.convertCertBufferToPEM)(x5c[0]);
const hashAlg = convertCOSEtoPKCS_1.COSEALGHASH[alg];
return (0, verifySignature_1.verifySignature)(sig, signatureBase, leafCertPEM, hashAlg);
return (0, verifySignature_1.verifySignature)({
signature: sig,
signatureBase,
leafCert: x5c[0],
hashAlgorithm: hashAlg
});
}
exports.verifyAttestationAndroidKey = verifyAttestationAndroidKey;
//# sourceMappingURL=verifyAttestationAndroidKey.js.map

@@ -106,4 +106,7 @@ "use strict";

const signatureBuffer = base64url_1.default.toBuffer(SIGNATURE);
const leafCertPEM = (0, convertCertBufferToPEM_1.convertCertBufferToPEM)(leafCertBuffer);
const verified = (0, verifySignature_1.verifySignature)(signatureBuffer, signatureBaseBuffer, leafCertPEM);
const verified = await (0, verifySignature_1.verifySignature)({
signature: signatureBuffer,
signatureBase: signatureBaseBuffer,
leafCert: leafCertBuffer,
});
/**

@@ -110,0 +113,0 @@ * END Verify Signature

@@ -42,6 +42,9 @@ "use strict";

}
const leafCertPEM = (0, convertCertBufferToPEM_1.convertCertBufferToPEM)(x5c[0]);
return (0, verifySignature_1.verifySignature)(sig, signatureBase, leafCertPEM);
return (0, verifySignature_1.verifySignature)({
signature: sig,
signatureBase,
leafCert: x5c[0],
});
}
exports.verifyAttestationFIDOU2F = verifyAttestationFIDOU2F;
//# sourceMappingURL=verifyAttestationFIDOU2F.js.map
"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.verifyAttestationPacked = void 0;
const elliptic_1 = __importDefault(require("elliptic"));
const node_rsa_1 = __importDefault(require("node-rsa"));
const convertCOSEtoPKCS_1 = require("../../helpers/convertCOSEtoPKCS");
const toHash_1 = require("../../helpers/toHash");
const convertCertBufferToPEM_1 = require("../../helpers/convertCertBufferToPEM");

@@ -15,3 +9,2 @@ const validateCertificatePath_1 = require("../../helpers/validateCertificatePath");

const verifySignature_1 = require("../../helpers/verifySignature");
const decodeCredentialPublicKey_1 = require("../../helpers/decodeCredentialPublicKey");
const metadataService_1 = require("../../services/metadataService");

@@ -33,5 +26,3 @@ const verifyAttestationWithMetadata_1 = require("../../metadata/verifyAttestationWithMetadata");

let verified = false;
const pkcsPublicKey = (0, convertCOSEtoPKCS_1.convertCOSEtoPKCS)(credentialPublicKey);
if (x5c) {
const leafCert = (0, convertCertBufferToPEM_1.convertCertBufferToPEM)(x5c[0]);
const { subject, basicConstraintsCA, version, notBefore, notAfter } = (0, getCertificateInfo_1.getCertificateInfo)(x5c[0]);

@@ -98,56 +89,16 @@ const { OU, CN, O, C } = subject;

}
verified = (0, verifySignature_1.verifySignature)(sig, signatureBase, leafCert);
verified = await (0, verifySignature_1.verifySignature)({
signature: sig,
signatureBase,
leafCert: x5c[0],
});
}
else {
const cosePublicKey = (0, decodeCredentialPublicKey_1.decodeCredentialPublicKey)(credentialPublicKey);
const kty = cosePublicKey.get(convertCOSEtoPKCS_1.COSEKEYS.kty);
if (!kty) {
throw new Error('COSE public key was missing kty (Packed|Self)');
}
const hashAlg = convertCOSEtoPKCS_1.COSEALGHASH[alg];
if (kty === convertCOSEtoPKCS_1.COSEKTY.EC2) {
const crv = cosePublicKey.get(convertCOSEtoPKCS_1.COSEKEYS.crv);
if (!crv) {
throw new Error('COSE public key was missing kty crv (Packed|EC2)');
}
const signatureBaseHash = (0, toHash_1.toHash)(signatureBase, hashAlg);
/**
* Instantiating the curve here is _very_ computationally heavy - a bit of profiling
* (in compiled JS, not TS) reported an average of ~125ms to execute this line. The elliptic
* README states, "better do it once and reuse it", so maybe there's a better way to handle
* this in a server context, when we can re-use an existing instance.
*
* For now, it's worth noting that this line is probably the reason why it can take
* 5-6 seconds to run tests.
*/
const ec = new elliptic_1.default.ec(convertCOSEtoPKCS_1.COSECRV[crv]);
const key = ec.keyFromPublic(pkcsPublicKey);
verified = key.verify(signatureBaseHash, sig);
}
else if (kty === convertCOSEtoPKCS_1.COSEKTY.RSA) {
const n = cosePublicKey.get(convertCOSEtoPKCS_1.COSEKEYS.n);
if (!n) {
throw new Error('COSE public key was missing n (Packed|RSA)');
}
const signingScheme = convertCOSEtoPKCS_1.COSERSASCHEME[alg];
// TODO: Verify this works
const key = new node_rsa_1.default();
key.setOptions({ signingScheme });
key.importKey({
n: n,
e: 65537,
}, 'components-public');
verified = key.verify(signatureBase, sig);
}
else if (kty === convertCOSEtoPKCS_1.COSEKTY.OKP) {
const x = cosePublicKey.get(convertCOSEtoPKCS_1.COSEKEYS.x);
if (!x) {
throw new Error('COSE public key was missing x (Packed|OKP)');
}
const signatureBaseHash = (0, toHash_1.toHash)(signatureBase, hashAlg);
const key = new elliptic_1.default.eddsa('ed25519');
key.keyFromPublic(x);
// TODO: is `publicKey` right here?
verified = key.verify(signatureBaseHash, sig, pkcsPublicKey);
}
verified = await (0, verifySignature_1.verifySignature)({
signature: sig,
signatureBase,
credentialPublicKey,
hashAlgorithm: hashAlg
});
}

@@ -154,0 +105,0 @@ return verified;

{
"name": "@simplewebauthn/server",
"version": "5.4.5",
"version": "6.0.0",
"description": "SimpleWebAuthn for Servers",

@@ -33,3 +33,3 @@ "main": "dist/index.js",

"engines": {
"node": ">=10.0.0"
"node": ">=14.0.0"
},

@@ -50,25 +50,22 @@ "scripts": {

"dependencies": {
"@noble/ed25519": "^1.6.1",
"@peculiar/asn1-android": "^2.1.7",
"@peculiar/asn1-schema": "^2.1.7",
"@peculiar/asn1-x509": "^2.1.7",
"@simplewebauthn/typescript-types": "^5.4.0",
"@simplewebauthn/typescript-types": "^6.0.0",
"base64url": "^3.0.1",
"cbor": "^5.1.0",
"debug": "^4.3.2",
"elliptic": "^6.5.3",
"jsrsasign": "^10.4.0",
"jwk-to-pem": "^2.0.4",
"node-fetch": "^2.6.0",
"node-rsa": "^1.1.1"
"node-fetch": "^2.6.0"
},
"gitHead": "d5fbeb340fb2610c86f102f184aa75a0d27cc243",
"gitHead": "95cb2107d15ae15994367cc99040720ae186c9bd",
"devDependencies": {
"@types/cbor": "^5.0.1",
"@types/debug": "^4.1.7",
"@types/elliptic": "^6.4.13",
"@types/jsrsasign": "^8.0.13",
"@types/jwk-to-pem": "^2.0.1",
"@types/node-fetch": "^2.5.12",
"@types/node-rsa": "^1.1.1"
"@types/node-fetch": "^2.5.12"
}
}

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

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

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