Latest Threat Research:SANDWORM_MODE: Shai-Hulud-Style npm Worm Hijacks CI Workflows and Poisons AI Toolchains.Details
Socket
Book a DemoInstallSign in
Socket

@turnkey/crypto

Package Overview
Dependencies
Maintainers
7
Versions
34
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@turnkey/crypto - npm Package Compare versions

Comparing version
2.8.2
to
2.8.3
+254
dist/proof.js
'use strict';
var encoding = require('@turnkey/encoding');
var p256 = require('@noble/curves/p256');
var sha2 = require('@noble/hashes/sha2');
var CBOR = require('cbor-js');
var x509 = require('@peculiar/x509');
var constants = require('./constants.js');
function _interopNamespaceDefault(e) {
var n = Object.create(null);
if (e) {
Object.keys(e).forEach(function (k) {
if (k !== 'default') {
var d = Object.getOwnPropertyDescriptor(e, k);
Object.defineProperty(n, k, d.get ? d : {
enumerable: true,
get: function () { return e[k]; }
});
}
});
}
n.default = e;
return Object.freeze(n);
}
var CBOR__namespace = /*#__PURE__*/_interopNamespaceDefault(CBOR);
var x509__namespace = /*#__PURE__*/_interopNamespaceDefault(x509);
const getCryptoInstance = async () => {
let cryptoInstance;
// Use globalThis.crypto.subtle if available
if (typeof globalThis !== "undefined" && globalThis.crypto?.subtle) {
cryptoInstance = globalThis.crypto;
x509__namespace.cryptoProvider.set(cryptoInstance);
return cryptoInstance;
}
try {
// Dynamic import to prevent bundling in environments that already have WebCrypto
const { Crypto: PeculiarCrypto } = await import('@peculiar/webcrypto');
cryptoInstance = new PeculiarCrypto();
x509__namespace.cryptoProvider.set(cryptoInstance);
return cryptoInstance;
}
catch {
// Happens usually on React Native
throw new Error("No WebCrypto implementation found. " +
"In React Native, please polyfill `global.crypto.subtle` (e.g., with `react-native-webcrypto`) " +
"before calling verify().");
}
};
/**
* Utility: SHA-256 digest → hex (uppercase)
*/
async function sha256Hex(data) {
const cryptoInstance = await getCryptoInstance();
const digest = await cryptoInstance.subtle.digest("SHA-256", data);
return encoding.uint8ArrayToHexString(new Uint8Array(digest)).toUpperCase();
}
/**
* Utility: Import SPKI public key for ECDSA verify
*/
async function importEcdsaPublicKey(spki) {
const cryptoInstance = await getCryptoInstance();
return cryptoInstance.subtle.importKey("spki", spki, { name: "ECDSA", namedCurve: "P-384" }, // AWS Nitro uses ES384
false, ["verify"]);
}
/**
* verify goes through the following verification steps for an app proof & boot proof pair:
* - Verify app proof signature
* - Verify the boot proof
* - Attestation doc was signed by AWS
* - Attestation doc's `user_data` is the hash of the qos manifest
* - Verify the connection between the app proof & boot proof i.e. that the ephemeral keys match
*
* For more information, check out https://whitepaper.turnkey.com/foundations
*/
async function verify(appProof, bootProof) {
// 1. Verify App Proof
verifyAppProofSignature(appProof);
// 2. Verify Boot Proof
// Parse attestation
const coseSign1Der = Uint8Array.from(atob(bootProof.awsAttestationDocB64)
.split("")
.map((c) => c.charCodeAt(0)));
const coseSign1 = CBOR__namespace.decode(coseSign1Der.buffer);
const [, , payload] = coseSign1;
const attestationDoc = CBOR__namespace.decode(new Uint8Array(payload).buffer);
// Verify cose sign1 signature
await verifyCoseSign1Sig(coseSign1, attestationDoc.certificate);
// Verify certificate chain
const appProofTimestampMs = parseInt(JSON.parse(appProof.proofPayload).timestampMs);
await verifyCertificateChain(attestationDoc.cabundle, constants.AWS_ROOT_CERT_PEM, attestationDoc.certificate, appProofTimestampMs);
// Verify manifest digest
const decodedBootProofManifest = Uint8Array.from(atob(bootProof.qosManifestB64)
.split("")
.map((c) => c.charCodeAt(0)));
const manifestDigest = sha2.sha256(decodedBootProofManifest);
if (!bytesEq(manifestDigest, attestationDoc.user_data)) {
throw new Error(`attestationDoc's user_data doesn't match the hash of the manifest. attestationDoc.user_data: ${attestationDoc.user_data} , manifest digest: ${manifestDigest}`);
}
// 3. Verify that all the ephemeral public keys match: app proof, boot proof structure, actual attestation doc
const publicKeyBytes = new Uint8Array(attestationDoc.public_key);
const attestationPubKey = encoding.uint8ArrayToHexString(publicKeyBytes);
if (appProof.publicKey !== attestationPubKey ||
attestationPubKey !== bootProof.ephemeralPublicKeyHex) {
throw new Error(`Ephemeral pub keys from app proof: ${appProof.publicKey}, boot proof structure ${bootProof.ephemeralPublicKeyHex}, and attestation doc ${attestationPubKey} should all match`);
}
}
/**
* Verify app proof signature with @noble/curves
*/
function verifyAppProofSignature(appProof) {
if (appProof.scheme !== "SIGNATURE_SCHEME_EPHEMERAL_KEY_P256") {
throw new Error("Unsupported signature scheme");
}
// Decode public key
let publicKeyBytes;
try {
publicKeyBytes = encoding.uint8ArrayFromHexString(appProof.publicKey);
}
catch {
throw new Error("Failed to decode public key");
}
if (publicKeyBytes.length !== 130) {
throw new Error(`Expected 130 bytes (encryption + signing pub keys), got ${publicKeyBytes.length} bytes`);
}
// Extract signing key (last 65 bytes, uncompressed P-256 point)
const signingKeyBytes = publicKeyBytes.slice(65);
if (signingKeyBytes.length !== 65 || signingKeyBytes[0] !== 0x04) {
throw new Error("Invalid signing key format: expected 65-byte uncompressed P-256 point (0x04||X||Y)");
}
// Validate it's a valid P-256 public key by attempting to create a point
try {
p256.p256.ProjectivePoint.fromHex(signingKeyBytes);
}
catch (error) {
throw new Error(`Invalid P-256 public key: ${error}`);
}
// Decode signature (64 bytes = 32 bytes r + 32 bytes s)
let signatureBytes;
try {
signatureBytes = encoding.uint8ArrayFromHexString(appProof.signature);
}
catch {
throw new Error("Failed to decode signature");
}
if (signatureBytes.length !== 64) {
throw new Error(`Expected 64 bytes signature (r||s), got ${signatureBytes.length} bytes`);
}
// Hash the proof payload
const payloadBytes = new TextEncoder().encode(appProof.proofPayload);
const payloadDigest = sha2.sha256(payloadBytes);
// Verify ECDSA signature
const isValid = p256.p256.verify(signatureBytes, payloadDigest, signingKeyBytes);
if (!isValid) {
throw new Error("Signature verification failed");
}
}
async function verifyCertificateChain(cabundle, rootCertPem, leafCert, timestampMs) {
try {
// Check root and assert fingerprint
const rootX509 = new x509__namespace.X509Certificate(rootCertPem);
const rootDer = new Uint8Array(rootX509.rawData);
const rootSha = await sha256Hex(rootDer);
if (rootSha !== constants.AWS_ROOT_CERT_SHA256) {
throw new Error(`Pinned AWS root fingerprint mismatch: expected=${constants.AWS_ROOT_CERT_SHA256} actual=${rootSha}`);
}
// Bundle starts with root certificate. We're replacing the root with our hardcoded known certificate, so remove first element
const bundleWithoutRoot = cabundle.slice(1);
const intermediatesX509 = bundleWithoutRoot.map((c) => {
if (!c)
throw new Error("Invalid certificate data in cabundle");
return new x509__namespace.X509Certificate(c);
});
const leaf = new x509__namespace.X509Certificate(leafCert);
// Build path leaf → intermediates → root, with our hardcoded known root certificate
const builder = new x509__namespace.X509ChainBuilder({
certificates: [rootX509, ...intermediatesX509],
});
const chain = await builder.build(leaf);
if (chain.length !== intermediatesX509.length + 2) {
throw new Error(`Incorrect number of certs in X509 Chain. Expected ${intermediatesX509.length + 2}, got ${chain.length}`);
}
const appProofDate = new Date(timestampMs);
for (let i = 0; i < chain.length; i++) {
const cert = chain[i];
if (!cert)
throw new Error("Invalid certificate in chain");
if (i === chain.length - 1) {
// is root
// Self-signature verification for root certificate
const ok = await cert.verify({
publicKey: cert.publicKey,
date: appProofDate,
});
if (!ok)
throw new Error("Pinned root failed self-signature verification");
}
else {
// Verify signature against issuer
const issuer = chain[i + 1];
if (!issuer)
throw new Error("Issuer can't be null");
// Attestation docs technically expire after 3 hours, so an app proof generated 3+ hours after an enclave
// boots up will fail verification due to certificate expiration. This is okay because enclaves are immutable;
// even if the cert is technically invalid, the code contained within it cannot change. To prevent the cert
// expiration failure, we set `signatureOnly: true`.
const ok = await cert.verify({
publicKey: issuer.publicKey,
signatureOnly: true,
date: appProofDate,
});
if (!ok) {
throw new Error(`Signature check failed: ${cert.subject} not signed by ${issuer?.subject}`);
}
}
}
}
catch (error) {
throw new Error(`Certificate chain verification failed: ${error instanceof Error ? error.message : String(error)}`);
}
}
async function verifyCoseSign1Sig(coseSign1, leaf) {
const [protectedHeaders, , payload, signature] = coseSign1;
const tbs = new Uint8Array(CBOR__namespace.encode([
"Signature1",
new Uint8Array(protectedHeaders),
new Uint8Array(0),
new Uint8Array(payload),
]));
const leafCert = new x509__namespace.X509Certificate(leaf);
const pubKey = await importEcdsaPublicKey(leafCert.publicKey.rawData);
const cryptoInstance = await getCryptoInstance();
const ok = await cryptoInstance.subtle.verify({ name: "ECDSA", hash: { name: "SHA-384" } }, pubKey, new Uint8Array(signature), tbs);
if (!ok)
throw new Error("COSE_Sign1 ES384 verification failed");
}
function bytesEq(a, b) {
const A = new Uint8Array(a), B = new Uint8Array(b);
if (A.length !== B.length)
return false;
for (let i = 0; i < A.length; i++)
if (A[i] !== B[i])
return false;
return true;
}
exports.getCryptoInstance = getCryptoInstance;
exports.verify = verify;
exports.verifyAppProofSignature = verifyAppProofSignature;
exports.verifyCertificateChain = verifyCertificateChain;
exports.verifyCoseSign1Sig = verifyCoseSign1Sig;
//# sourceMappingURL=proof.js.map
{"version":3,"file":"proof.js","sources":["../src/proof.ts"],"sourcesContent":[null],"names":["x509","uint8ArrayToHexString","CBOR","AWS_ROOT_CERT_PEM","sha256","uint8ArrayFromHexString","p256","AWS_ROOT_CERT_SHA256"],"mappings":"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"}
import { uint8ArrayToHexString, uint8ArrayFromHexString } from '@turnkey/encoding';
import { p256 } from '@noble/curves/p256';
import { sha256 } from '@noble/hashes/sha2';
import * as CBOR from 'cbor-js';
import * as x509 from '@peculiar/x509';
import { AWS_ROOT_CERT_PEM, AWS_ROOT_CERT_SHA256 } from './constants.mjs';
const getCryptoInstance = async () => {
let cryptoInstance;
// Use globalThis.crypto.subtle if available
if (typeof globalThis !== "undefined" && globalThis.crypto?.subtle) {
cryptoInstance = globalThis.crypto;
x509.cryptoProvider.set(cryptoInstance);
return cryptoInstance;
}
try {
// Dynamic import to prevent bundling in environments that already have WebCrypto
const { Crypto: PeculiarCrypto } = await import('@peculiar/webcrypto');
cryptoInstance = new PeculiarCrypto();
x509.cryptoProvider.set(cryptoInstance);
return cryptoInstance;
}
catch {
// Happens usually on React Native
throw new Error("No WebCrypto implementation found. " +
"In React Native, please polyfill `global.crypto.subtle` (e.g., with `react-native-webcrypto`) " +
"before calling verify().");
}
};
/**
* Utility: SHA-256 digest → hex (uppercase)
*/
async function sha256Hex(data) {
const cryptoInstance = await getCryptoInstance();
const digest = await cryptoInstance.subtle.digest("SHA-256", data);
return uint8ArrayToHexString(new Uint8Array(digest)).toUpperCase();
}
/**
* Utility: Import SPKI public key for ECDSA verify
*/
async function importEcdsaPublicKey(spki) {
const cryptoInstance = await getCryptoInstance();
return cryptoInstance.subtle.importKey("spki", spki, { name: "ECDSA", namedCurve: "P-384" }, // AWS Nitro uses ES384
false, ["verify"]);
}
/**
* verify goes through the following verification steps for an app proof & boot proof pair:
* - Verify app proof signature
* - Verify the boot proof
* - Attestation doc was signed by AWS
* - Attestation doc's `user_data` is the hash of the qos manifest
* - Verify the connection between the app proof & boot proof i.e. that the ephemeral keys match
*
* For more information, check out https://whitepaper.turnkey.com/foundations
*/
async function verify(appProof, bootProof) {
// 1. Verify App Proof
verifyAppProofSignature(appProof);
// 2. Verify Boot Proof
// Parse attestation
const coseSign1Der = Uint8Array.from(atob(bootProof.awsAttestationDocB64)
.split("")
.map((c) => c.charCodeAt(0)));
const coseSign1 = CBOR.decode(coseSign1Der.buffer);
const [, , payload] = coseSign1;
const attestationDoc = CBOR.decode(new Uint8Array(payload).buffer);
// Verify cose sign1 signature
await verifyCoseSign1Sig(coseSign1, attestationDoc.certificate);
// Verify certificate chain
const appProofTimestampMs = parseInt(JSON.parse(appProof.proofPayload).timestampMs);
await verifyCertificateChain(attestationDoc.cabundle, AWS_ROOT_CERT_PEM, attestationDoc.certificate, appProofTimestampMs);
// Verify manifest digest
const decodedBootProofManifest = Uint8Array.from(atob(bootProof.qosManifestB64)
.split("")
.map((c) => c.charCodeAt(0)));
const manifestDigest = sha256(decodedBootProofManifest);
if (!bytesEq(manifestDigest, attestationDoc.user_data)) {
throw new Error(`attestationDoc's user_data doesn't match the hash of the manifest. attestationDoc.user_data: ${attestationDoc.user_data} , manifest digest: ${manifestDigest}`);
}
// 3. Verify that all the ephemeral public keys match: app proof, boot proof structure, actual attestation doc
const publicKeyBytes = new Uint8Array(attestationDoc.public_key);
const attestationPubKey = uint8ArrayToHexString(publicKeyBytes);
if (appProof.publicKey !== attestationPubKey ||
attestationPubKey !== bootProof.ephemeralPublicKeyHex) {
throw new Error(`Ephemeral pub keys from app proof: ${appProof.publicKey}, boot proof structure ${bootProof.ephemeralPublicKeyHex}, and attestation doc ${attestationPubKey} should all match`);
}
}
/**
* Verify app proof signature with @noble/curves
*/
function verifyAppProofSignature(appProof) {
if (appProof.scheme !== "SIGNATURE_SCHEME_EPHEMERAL_KEY_P256") {
throw new Error("Unsupported signature scheme");
}
// Decode public key
let publicKeyBytes;
try {
publicKeyBytes = uint8ArrayFromHexString(appProof.publicKey);
}
catch {
throw new Error("Failed to decode public key");
}
if (publicKeyBytes.length !== 130) {
throw new Error(`Expected 130 bytes (encryption + signing pub keys), got ${publicKeyBytes.length} bytes`);
}
// Extract signing key (last 65 bytes, uncompressed P-256 point)
const signingKeyBytes = publicKeyBytes.slice(65);
if (signingKeyBytes.length !== 65 || signingKeyBytes[0] !== 0x04) {
throw new Error("Invalid signing key format: expected 65-byte uncompressed P-256 point (0x04||X||Y)");
}
// Validate it's a valid P-256 public key by attempting to create a point
try {
p256.ProjectivePoint.fromHex(signingKeyBytes);
}
catch (error) {
throw new Error(`Invalid P-256 public key: ${error}`);
}
// Decode signature (64 bytes = 32 bytes r + 32 bytes s)
let signatureBytes;
try {
signatureBytes = uint8ArrayFromHexString(appProof.signature);
}
catch {
throw new Error("Failed to decode signature");
}
if (signatureBytes.length !== 64) {
throw new Error(`Expected 64 bytes signature (r||s), got ${signatureBytes.length} bytes`);
}
// Hash the proof payload
const payloadBytes = new TextEncoder().encode(appProof.proofPayload);
const payloadDigest = sha256(payloadBytes);
// Verify ECDSA signature
const isValid = p256.verify(signatureBytes, payloadDigest, signingKeyBytes);
if (!isValid) {
throw new Error("Signature verification failed");
}
}
async function verifyCertificateChain(cabundle, rootCertPem, leafCert, timestampMs) {
try {
// Check root and assert fingerprint
const rootX509 = new x509.X509Certificate(rootCertPem);
const rootDer = new Uint8Array(rootX509.rawData);
const rootSha = await sha256Hex(rootDer);
if (rootSha !== AWS_ROOT_CERT_SHA256) {
throw new Error(`Pinned AWS root fingerprint mismatch: expected=${AWS_ROOT_CERT_SHA256} actual=${rootSha}`);
}
// Bundle starts with root certificate. We're replacing the root with our hardcoded known certificate, so remove first element
const bundleWithoutRoot = cabundle.slice(1);
const intermediatesX509 = bundleWithoutRoot.map((c) => {
if (!c)
throw new Error("Invalid certificate data in cabundle");
return new x509.X509Certificate(c);
});
const leaf = new x509.X509Certificate(leafCert);
// Build path leaf → intermediates → root, with our hardcoded known root certificate
const builder = new x509.X509ChainBuilder({
certificates: [rootX509, ...intermediatesX509],
});
const chain = await builder.build(leaf);
if (chain.length !== intermediatesX509.length + 2) {
throw new Error(`Incorrect number of certs in X509 Chain. Expected ${intermediatesX509.length + 2}, got ${chain.length}`);
}
const appProofDate = new Date(timestampMs);
for (let i = 0; i < chain.length; i++) {
const cert = chain[i];
if (!cert)
throw new Error("Invalid certificate in chain");
if (i === chain.length - 1) {
// is root
// Self-signature verification for root certificate
const ok = await cert.verify({
publicKey: cert.publicKey,
date: appProofDate,
});
if (!ok)
throw new Error("Pinned root failed self-signature verification");
}
else {
// Verify signature against issuer
const issuer = chain[i + 1];
if (!issuer)
throw new Error("Issuer can't be null");
// Attestation docs technically expire after 3 hours, so an app proof generated 3+ hours after an enclave
// boots up will fail verification due to certificate expiration. This is okay because enclaves are immutable;
// even if the cert is technically invalid, the code contained within it cannot change. To prevent the cert
// expiration failure, we set `signatureOnly: true`.
const ok = await cert.verify({
publicKey: issuer.publicKey,
signatureOnly: true,
date: appProofDate,
});
if (!ok) {
throw new Error(`Signature check failed: ${cert.subject} not signed by ${issuer?.subject}`);
}
}
}
}
catch (error) {
throw new Error(`Certificate chain verification failed: ${error instanceof Error ? error.message : String(error)}`);
}
}
async function verifyCoseSign1Sig(coseSign1, leaf) {
const [protectedHeaders, , payload, signature] = coseSign1;
const tbs = new Uint8Array(CBOR.encode([
"Signature1",
new Uint8Array(protectedHeaders),
new Uint8Array(0),
new Uint8Array(payload),
]));
const leafCert = new x509.X509Certificate(leaf);
const pubKey = await importEcdsaPublicKey(leafCert.publicKey.rawData);
const cryptoInstance = await getCryptoInstance();
const ok = await cryptoInstance.subtle.verify({ name: "ECDSA", hash: { name: "SHA-384" } }, pubKey, new Uint8Array(signature), tbs);
if (!ok)
throw new Error("COSE_Sign1 ES384 verification failed");
}
function bytesEq(a, b) {
const A = new Uint8Array(a), B = new Uint8Array(b);
if (A.length !== B.length)
return false;
for (let i = 0; i < A.length; i++)
if (A[i] !== B[i])
return false;
return true;
}
export { getCryptoInstance, verify, verifyAppProofSignature, verifyCertificateChain, verifyCoseSign1Sig };
//# sourceMappingURL=proof.mjs.map
{"version":3,"file":"proof.mjs","sources":["../src/proof.ts"],"sourcesContent":[null],"names":[],"mappings":"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"}
+9
-0
# @turnkey/crypto
## 2.8.3
### Patch Changes
- [#992](https://github.com/tkhq/sdk/pull/992) [`5c4495b`](https://github.com/tkhq/sdk/commit/5c4495bff1b0abfe3c427ead1b8e1a8d510c8186) Author [@amircheikh](https://github.com/amircheikh) - - `verify` function is now exposed and supports web platforms
- Updated dependencies [[`5c4495b`](https://github.com/tkhq/sdk/commit/5c4495bff1b0abfe3c427ead1b8e1a8d510c8186)]:
- @turnkey/sdk-types@0.6.3
## 2.8.2

@@ -4,0 +13,0 @@

@@ -33,4 +33,23 @@ 'use strict';

const PRODUCTION_ON_RAMP_CREDENTIALS_ENCRYPTION_PUBLIC_KEY = "02336ebd7e929ef64b87c776b72540255b4c7b41579a24b1e68fb060daa873f9f6";
// Pinned AWS Nitro Enclaves Root
const AWS_ROOT_CERT_PEM = `-----BEGIN CERTIFICATE-----
MIICETCCAZagAwIBAgIRAPkxdWgbkK/hHUbMtOTn+FYwCgYIKoZIzj0EAwMwSTEL
MAkGA1UEBhMCVVMxDzANBgNVBAoMBkFtYXpvbjEMMAoGA1UECwwDQVdTMRswGQYD
VQQDDBJhd3Mubml0cm8tZW5jbGF2ZXMwHhcNMTkxMDI4MTMyODA1WhcNNDkxMDI4
MTQyODA1WjBJMQswCQYDVQQGEwJVUzEPMA0GA1UECgwGQW1hem9uMQwwCgYDVQQL
DANBV1MxGzAZBgNVBAMMEmF3cy5uaXRyby1lbmNsYXZlczB2MBAGByqGSM49AgEG
BSuBBAAiA2IABPwCVOumCMHzaHDimtqQvkY4MpJzbolL//Zy2YlES1BR5TSksfbb
48C8WBoyt7F2Bw7eEtaaP+ohG2bnUs990d0JX28TcPQXCEPZ3BABIeTPYwEoCWZE
h8l5YoQwTcU/9KNCMEAwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUkCW1DdkF
R+eWw5b6cp3PmanfS5YwDgYDVR0PAQH/BAQDAgGGMAoGCCqGSM49BAMDA2kAMGYC
MQCjfy+Rocm9Xue4YnwWmNJVA44fA0P5W2OpYow9OYCVRaEevL8uO1XYru5xtMPW
rfMCMQCi85sWBbJwKKXdS6BptQFuZbT73o/gBh1qUxl/nNr12UO8Yfwr6wPLb+6N
IwLz3/Y=
-----END CERTIFICATE-----`;
// Official SHA-256 fingerprint
const AWS_ROOT_CERT_SHA256 = "641A0321A3E244EFE456463195D606317ED7CDCC3C1756E09893F3C68F79BB5B";
exports.AES_KEY_INFO = AES_KEY_INFO;
exports.AWS_ROOT_CERT_PEM = AWS_ROOT_CERT_PEM;
exports.AWS_ROOT_CERT_SHA256 = AWS_ROOT_CERT_SHA256;
exports.HPKE_VERSION = HPKE_VERSION;

@@ -37,0 +56,0 @@ exports.IV_INFO = IV_INFO;

+18
-1

@@ -31,4 +31,21 @@ const SUITE_ID_1 = new Uint8Array([75, 69, 77, 0, 16]); //KEM suite ID

const PRODUCTION_ON_RAMP_CREDENTIALS_ENCRYPTION_PUBLIC_KEY = "02336ebd7e929ef64b87c776b72540255b4c7b41579a24b1e68fb060daa873f9f6";
// Pinned AWS Nitro Enclaves Root
const AWS_ROOT_CERT_PEM = `-----BEGIN CERTIFICATE-----
MIICETCCAZagAwIBAgIRAPkxdWgbkK/hHUbMtOTn+FYwCgYIKoZIzj0EAwMwSTEL
MAkGA1UEBhMCVVMxDzANBgNVBAoMBkFtYXpvbjEMMAoGA1UECwwDQVdTMRswGQYD
VQQDDBJhd3Mubml0cm8tZW5jbGF2ZXMwHhcNMTkxMDI4MTMyODA1WhcNNDkxMDI4
MTQyODA1WjBJMQswCQYDVQQGEwJVUzEPMA0GA1UECgwGQW1hem9uMQwwCgYDVQQL
DANBV1MxGzAZBgNVBAMMEmF3cy5uaXRyby1lbmNsYXZlczB2MBAGByqGSM49AgEG
BSuBBAAiA2IABPwCVOumCMHzaHDimtqQvkY4MpJzbolL//Zy2YlES1BR5TSksfbb
48C8WBoyt7F2Bw7eEtaaP+ohG2bnUs990d0JX28TcPQXCEPZ3BABIeTPYwEoCWZE
h8l5YoQwTcU/9KNCMEAwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUkCW1DdkF
R+eWw5b6cp3PmanfS5YwDgYDVR0PAQH/BAQDAgGGMAoGCCqGSM49BAMDA2kAMGYC
MQCjfy+Rocm9Xue4YnwWmNJVA44fA0P5W2OpYow9OYCVRaEevL8uO1XYru5xtMPW
rfMCMQCi85sWBbJwKKXdS6BptQFuZbT73o/gBh1qUxl/nNr12UO8Yfwr6wPLb+6N
IwLz3/Y=
-----END CERTIFICATE-----`;
// Official SHA-256 fingerprint
const AWS_ROOT_CERT_SHA256 = "641A0321A3E244EFE456463195D606317ED7CDCC3C1756E09893F3C68F79BB5B";
export { AES_KEY_INFO, HPKE_VERSION, IV_INFO, LABEL_EAE_PRK, LABEL_SECRET, LABEL_SHARED_SECRET, PRODUCTION_NOTARIZER_SIGN_PUBLIC_KEY, PRODUCTION_ON_RAMP_CREDENTIALS_ENCRYPTION_PUBLIC_KEY, PRODUCTION_SIGNER_SIGN_PUBLIC_KEY, PRODUCTION_TLS_FETCHER_ENCRYPT_PUBLIC_KEY, QOS_ENCRYPTION_HMAC_MESSAGE, QUORUM_ENCRYPT_NONCE_LENGTH_BYTES, SUITE_ID_1, SUITE_ID_2, UNCOMPRESSED_PUB_KEY_LENGTH_BYTES };
export { AES_KEY_INFO, AWS_ROOT_CERT_PEM, AWS_ROOT_CERT_SHA256, HPKE_VERSION, IV_INFO, LABEL_EAE_PRK, LABEL_SECRET, LABEL_SHARED_SECRET, PRODUCTION_NOTARIZER_SIGN_PUBLIC_KEY, PRODUCTION_ON_RAMP_CREDENTIALS_ENCRYPTION_PUBLIC_KEY, PRODUCTION_SIGNER_SIGN_PUBLIC_KEY, PRODUCTION_TLS_FETCHER_ENCRYPT_PUBLIC_KEY, QOS_ENCRYPTION_HMAC_MESSAGE, QUORUM_ENCRYPT_NONCE_LENGTH_BYTES, SUITE_ID_1, SUITE_ID_2, UNCOMPRESSED_PUB_KEY_LENGTH_BYTES };
//# sourceMappingURL=constants.mjs.map
export * from "./crypto";
export * from "./turnkey";
export * from "./proof";
//# sourceMappingURL=index.d.ts.map

@@ -5,2 +5,3 @@ 'use strict';

var turnkey = require('./turnkey.js');
var proof = require('./proof.js');

@@ -35,2 +36,7 @@

exports.verifyStampSignature = turnkey.verifyStampSignature;
exports.getCryptoInstance = proof.getCryptoInstance;
exports.verify = proof.verify;
exports.verifyAppProofSignature = proof.verifyAppProofSignature;
exports.verifyCertificateChain = proof.verifyCertificateChain;
exports.verifyCoseSign1Sig = proof.verifyCoseSign1Sig;
//# sourceMappingURL=index.js.map
export { buildAdditionalAssociatedData, compressRawPublicKey, extractPrivateKeyFromPKCS8Bytes, formatHpkeBuf, fromDerSignature, generateP256KeyPair, getPublicKey, hpkeAuthEncrypt, hpkeDecrypt, hpkeEncrypt, quorumKeyEncrypt, toDerSignature, uncompressRawPublicKey } from './crypto.mjs';
export { Enclave, decryptCredentialBundle, decryptExportBundle, encryptOauth2ClientSecret, encryptOnRampSecret, encryptPrivateKeyToBundle, encryptToEnclave, encryptWalletToBundle, verifySessionJwtSignature, verifyStampSignature } from './turnkey.mjs';
export { getCryptoInstance, verify, verifyAppProofSignature, verifyCertificateChain, verifyCoseSign1Sig } from './proof.mjs';
//# sourceMappingURL=index.mjs.map
+6
-2
import type { v1AppProof, v1BootProof } from "@turnkey/sdk-types";
export declare const getCryptoInstance: () => Promise<Crypto>;
/**

@@ -10,8 +11,11 @@ * verify goes through the following verification steps for an app proof & boot proof pair:

*
* For more information, check out https://whitepaper.turnkey.com/foundations
* For more information, check out https://whitepaper.turnkey.com/foundations
*/
export declare function verify(appProof: v1AppProof, bootProof: v1BootProof): Promise<void>;
/**
* Verify app proof signature with @noble/curves
*/
export declare function verifyAppProofSignature(appProof: v1AppProof): void;
export declare function verifyCertificateChain(cabundle: Uint8Array[], rootCertPem: string, leafCert: Uint8Array, timestampMs: number): Promise<void>;
export declare function verifyCoseSign1Sig(coseSign1: any, leaf: Uint8Array): void;
export declare function verifyCoseSign1Sig(coseSign1: any, leaf: Uint8Array): Promise<void>;
//# sourceMappingURL=proof.d.ts.map
{
"name": "@turnkey/crypto",
"version": "2.8.2",
"version": "2.8.3",
"main": "./dist/index.js",

@@ -46,3 +46,3 @@ "module": "./dist/index.mjs",

"@turnkey/encoding": "0.6.0",
"@turnkey/sdk-types": "0.6.2"
"@turnkey/sdk-types": "0.6.3"
},

@@ -49,0 +49,0 @@ "devDependencies": {

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