Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Snyk upgrade d641b1e67fbe80ebfd3941f00379564e #41

Merged
merged 7 commits into from
Jan 1, 2024
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
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,7 @@ const isValid = await checkTokenValidness(

## Changelog

- 0.1.30: Fix support for adhoc jwks
- 0.1.26: Remove fetchJwksWithUri, remove node-fetch dependency
- 0.1.20: Improve Cloudflare Workers compatibility for verify
- 0.1.19: Export `getKeyPair`
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "keylab",
"version": "0.1.27",
"version": "0.1.30",
"source": "src/index.ts",
"main": "dist/index.js",
"description": "keylab is a library aiming to create and validate JSON Web Tokens without hussle or prerequisitie cryptography knowledge.",
Expand Down
5 changes: 3 additions & 2 deletions src/enums.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,13 +18,14 @@ export enum JwtAlgorithmsEnum {
ES256K = "ES256K",
Ed25519 = "Ed25519",
X25519 = "X25519",
Ed448 = "Ed448",
X448 = "X448",
// web crypto
RSA_PKCS1 = "RSASSA-PKCS1-v1_5",
RSA_PSS = "RSA-PSS", // similar to RSAPSS
EC_P256 = "PS256",
EC_P384 = "PS384",
EC_P521 = "PS512",

EC_P521 = "PS512"
}

// https://datatracker.ietf.org/doc/html/rfc7517#section-4.2
Expand Down
3 changes: 2 additions & 1 deletion src/errors/messages.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,4 +34,5 @@ export const INVALID_SCOPE_FIELD_TYPE = "Invalid scp field type";

export const INVALID_PEM_STRING = "Invalid PEM string";

export const INVALID_PUBLIC_KEY_FORMAT = "Invalid public key format (must be PEM, JWK, adhoc JWks or JWKs URI)"
export const INVALID_PUBLIC_KEY_FORMAT =
"Invalid public key format (must be PEM, JWK, adhoc JWks or JWKs URI)";
66 changes: 65 additions & 1 deletion src/vendors/jwks/jwks.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import { JwtAlgorithmsEnum as Algs, JwtKeyTypes as Kty } from "../../enums";
import { default as nock } from "nock";

import * as c from "../../constants";
import { SignJWT, jwtVerify } from "jose";
const AUTHDOG_API_ROOT = "https://api.authdog.xyz";

it("verifies token with public key - es256k", async () => {
Expand Down Expand Up @@ -396,7 +397,7 @@ it("verifies token with public key - EdDSA", async () => {
});
});

it("THROWS an error: verifies token with public key - ES256k / pem", async () => {
it("verifies token with public key - ES256k / pem", async () => {
const keyPairES256k = await getKeyPair({
keyFormat: "pem",
algorithmIdentifier: Algs.ES256K,
Expand All @@ -423,6 +424,69 @@ it("THROWS an error: verifies token with public key - ES256k / pem", async () =>
).toBeTruthy();
});

// Ed25519 is the EdDSA signature scheme using SHA-512 (SHA-2) and Curve25519
it("signs with Ed25519 key pair", async () => {
const crypto = require("crypto");
const { publicKey, privateKey } = crypto.generateKeyPairSync("ed25519");

expect(publicKey).toBeTruthy();
expect(privateKey).toBeTruthy();

const protectedHeaders = {
alg: "EdDSA",
typ: "JWT"
};

const payload = {
urn: "urn:test:test"
};

const jwt = await new SignJWT(payload)
.setProtectedHeader(protectedHeaders)
.sign(privateKey);

expect(jwt).toBeTruthy();

const verifiedPayload = await jwtVerify(jwt, publicKey);

expect(verifiedPayload).toBeTruthy();

expect(verifiedPayload?.payload).toMatchObject(payload);
expect(verifiedPayload?.protectedHeader).toMatchObject(protectedHeaders);

});
it("verifies Ed448 Key pair", async () => {
const crypto = require("crypto");
const { publicKey, privateKey } = crypto.generateKeyPairSync("ed448");
expect(publicKey).toBeTruthy();
expect(privateKey).toBeTruthy();

const protectedHeaders = {
alg: "EdDSA", // Ed448 uses the EdDSA algorithm
typ: "JWT"
};

const payload = {
urn: "urn:test:test"
};

const jwt = await new SignJWT(payload)
.setProtectedHeader(protectedHeaders)
.sign(privateKey);

expect(jwt).toBeTruthy();

const verifiedPayload = await jwtVerify(jwt, publicKey);

expect(verifiedPayload).toBeTruthy();

expect(verifiedPayload?.payload).toMatchObject(payload);
expect(verifiedPayload?.protectedHeader).toMatchObject(protectedHeaders);
});




it("verifies correctly token with public uri", async () => {
const tenantUuid2 = "d84ddef4-81dd-4ce6-9594-03ac52cac367";
const applicationUuid2 = "b867db48-4e11-4cae-bb03-086dc97c8ddd";
Expand Down
10 changes: 6 additions & 4 deletions src/vendors/jwks/jwks.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import {
JWK
} from "jose";
import { extractAlgFromJwtHeader } from "../jwt";
import {INVALID_PUBLIC_KEY_FORMAT} from "../../errors/messages"
import { INVALID_PUBLIC_KEY_FORMAT } from "../../errors/messages";

export interface IJwksClient {
jwksUri?: string; // required for RS256
Expand Down Expand Up @@ -88,7 +88,7 @@ export const verifyTokenWithPublicKey = async (
let JWKS = null;
let decoded = null;

if (publicKey || adhocJwks) {
if (publicKey || opts?.adhoc || adhocJwks) {
let jwk;
if (typeof publicKey === "string") {
const alg = extractAlgFromJwtHeader(token);
Expand All @@ -103,11 +103,13 @@ export const verifyTokenWithPublicKey = async (
jwk = publicKey;
}

let adhocKeys = opts?.adhoc || adhocJwks;

JWKS = createLocalJWKSet({
keys: !!adhocJwks ? adhocJwks: [jwk]
keys: adhocKeys ? <JWK[]>adhocKeys : [jwk]
});
} else if (opts?.jwksUri) {
JWKS = createRemoteJWKSet(new URL(opts?.jwksUri))
JWKS = createRemoteJWKSet(new URL(opts?.jwksUri));
} else {
throw new Error(INVALID_PUBLIC_KEY_FORMAT);
}
Expand Down
6 changes: 3 additions & 3 deletions src/vendors/jwt/jwt-verify.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ export const checkTokenValidness = async (
requiredScopes,
publicKey
}: IcheckTokenValidnessCredentials
): Promise<boolean|any> => {
): Promise<boolean | any> => {
const algorithm = getAlgorithmJwt(token);
const missingCredentials = [];
let extractedPayload: ITokenExtractedWithPubKey | any = null;
Expand Down Expand Up @@ -139,7 +139,7 @@ export const verifyHSTokenWithSecretString = async (
}
} catch (e) {}

return isVerified ? decoded?.payload: null;
return isVerified ? decoded?.payload : null;
};

export const checkJwtFields = (
Expand Down Expand Up @@ -316,6 +316,6 @@ export const extractAlgFromJwtHeader = (jwt: string) => {
// Split the JWT into its three parts: header, payload, and signature
const parts = jwt.split(".");
const headerJson = atob(parts[0]);
const {alg} = JSON.parse(headerJson);
const { alg } = JSON.parse(headerJson);
return alg;
};
Loading