Skip to content

Commit

Permalink
Merge branch 'dev' of github.com:Fr0ntierX/polaris-sdk into feature/i…
Browse files Browse the repository at this point in the history
…mplement-streaming-capabilities
  • Loading branch information
haltakov committed Feb 14, 2025
2 parents 917bf2e + 0117a6e commit 7455e22
Show file tree
Hide file tree
Showing 5 changed files with 360 additions and 4 deletions.
7 changes: 6 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@fr0ntier-x/polaris-sdk",
"version": "0.1.5",
"version": "0.1.7",
"main": "dist/index.js",
"bugs": {
"url": "https://github.com/Fr0ntierX/polaris-sdk/issues"
Expand All @@ -16,6 +16,7 @@
"compile": "tsc --noEmit",
"check": "yarn format && yarn lint && yarn compile",
"check:quiet": "yarn format && yarn lint:quiet && yarn compile",
"publish": "yarn check && yarn build && yarn npm publish",
"test": "jest",
"test:watch": "jest --watch",
"test:coverage": "jest --coverage",
Expand All @@ -26,10 +27,14 @@
"dependencies": {
"axios": "^1.7.9",
"buffer": "^6.0.3",
"jsonwebtoken": "^9.0.2",
"jwk-to-pem": "^2.0.7",
"pino": "^9.5.0"
},
"devDependencies": {
"@types/jest": "^29.5.14",
"@types/jsonwebtoken": "^9",
"@types/jwk-to-pem": "^2",
"@types/node": "^22.8.2",
"@types/pino": "^7.0.5",
"@typescript-eslint/eslint-plugin": "8.12.1",
Expand Down
42 changes: 42 additions & 0 deletions src/sdk/index.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,16 @@
import jwt from "jsonwebtoken";
import jwkToPem from "jwk-to-pem";

import { getKeysFromIssuer, performAzureChecks, performCustomChecks, performGCPChecks } from "./utils";

import { CryptoProviderBrowser } from "../crypto/providers/browser";
import { CryptoProviderNode } from "../crypto/providers/node";

import type { PolarisSDKInterface } from "./types";
import type { CryptoProvider } from "../crypto";
import type { AESEncryptionData, AESKey } from "../crypto/types";
import type { KeyHandler } from "../key/types";
import type { JwtPayload } from "jsonwebtoken";

export class PolarisSDK implements PolarisSDKInterface {
// Key handler used to get access to the private key
Expand Down Expand Up @@ -158,4 +164,40 @@ export class PolarisSDK implements PolarisSDKInterface {

return { key, iv, authTag: Buffer.from(authTag, "base64"), cipherText };
}

async verifyAttestationToken(token: string, customChecks: object = {}): Promise<boolean> {
try {
const decodedToken = jwt.decode(token, { complete: true });
const payload = decodedToken?.payload as JwtPayload;
const kid = decodedToken?.header.kid;
const iss = payload.iss;

if (!decodedToken || !kid || !iss) {
throw new Error("Invalid JWT token");
}

const keys = await getKeysFromIssuer(iss);
const jwk = keys.find((key: any) => key.kid === kid);
if (!jwk) {
throw new Error(`Key with kid ${kid} not found`);
}

const publicKey = jwkToPem(jwk);
const verifiedPayload = jwt.verify(token, publicKey, { algorithms: ["RS256"] }) as any;

if (verifiedPayload.iss.endsWith(".googleapis.com")) {
performGCPChecks(verifiedPayload);
} else if (verifiedPayload.iss.endsWith(".attest.azure.net")) {
performAzureChecks(verifiedPayload);
} else {
throw new Error("Unsupported issuer");
}
performCustomChecks(customChecks, verifiedPayload);

return true;
} catch (error: any) {
console.error("Token verification failed:", error.message);
return false;
}
}
}
9 changes: 9 additions & 0 deletions src/sdk/types/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,4 +40,13 @@ export interface PolarisSDKInterface {
* @returns The decrypted data
*/
decrypt(message: Buffer): Promise<Buffer>;

/**
* Verify an attestation token
*
* @param token The attestation token to verify
* @param customChecks Custom checks to perform on the token payload
* @returns True if the token is valid, false otherwise
*/
verifyAttestationToken(token: string, customChecks: object): Promise<boolean>;
}
64 changes: 64 additions & 0 deletions src/sdk/utils/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
import axios from "axios";

export const getKeysFromIssuer = async (iss: string): Promise<any[]> => {
const {
data: { jwks_uri },
} = await axios.get(`${iss}/.well-known/openid-configuration`);
const {
data: { keys },
} = await axios.get(jwks_uri);

if (!keys || keys.length === 0) {
throw new Error("No keys found in JWK response");
}

return keys;
};

export const performGCPChecks = (verifiedPayload: any) => {
if (
verifiedPayload.iss !== "https://confidentialcomputing.googleapis.com" ||
verifiedPayload.aud !== "https://sts.googleapis.com" ||
verifiedPayload.secboot !== true ||
verifiedPayload.hwmodel !== "GCP_AMD_SEV"
) {
throw new Error("Invalid payload values for Google Confidential Computing");
}
};

export const performAzureChecks = (verifiedPayload: any) => {
const attestationType = verifiedPayload["x-ms-attestation-type"];
const complianceStatus = verifiedPayload["x-ms-compliance-status"];
const isolationTee = verifiedPayload["x-ms-isolation-tee"]?.["x-ms-attestation-type"];

if (!verifiedPayload.iss.endsWith(".attest.azure.net")) {
throw new Error("Invalid issuer for Azure attestation");
}

if (attestationType === "azurevm") {
if (isolationTee !== "sevsnpvm" || complianceStatus !== "azure-compliant-cvm") {
throw new Error("Invalid payload values for Azure VM with SEV-SNP");
}
} else if (attestationType === "sevsnpvm") {
if (complianceStatus !== "azure-compliant-uvm") {
throw new Error("Invalid payload values for SEV-SNP VM in Azure");
}
} else {
throw new Error("Invalid or unsupported attestation type for Azure");
}
};

export const performCustomChecks = (customChecks: {}, verifiedPayload: any) => {
for (const [key, expectedValue] of Object.entries(customChecks)) {
const actualValue = key.split(".").reduce((acc, part) => acc && acc[part], verifiedPayload);

if (actualValue === undefined) {
throw new Error(`Custom check failed: ${key} is missing in the payload`);
}
if (actualValue !== expectedValue) {
throw new Error(
`Custom check failed: ${key} does not match expected value. Got ${actualValue}, expected ${expectedValue}`
);
}
}
};
Loading

0 comments on commit 7455e22

Please sign in to comment.