import { X509Certificate } from "npm:@peculiar/x509"; import { AsnParser } from "npm:@peculiar/asn1-schema"; import { SubjectAlternativeName } from "npm:@peculiar/asn1-x509"; // Deno binding for the spire_ffi Rust crate if (Deno.build.arch !== "x86_64" && Deno.build.arch !== "aarch64") { throw new Error("Unsupported architecture"); } const libPath = (() => { if (Deno.build.os === "windows") return "./spire_ffi.dll"; if (Deno.build.os === "darwin") return "./libspire_ffi.dylib"; return "./libspire_ffi.so"; })(); let dylib: Deno.DynamicLibrary | null = null; try { dylib = Deno.dlopen(libPath, { fetch_svid: { parameters: ["pointer"], result: "pointer", nonblocking: true, }, free_svid: { parameters: ["pointer"], result: "void", }, }); } catch (_e) { console.warn( `Failed to load ${libPath}. Workload API fetching will be mocked/disabled if used.`, ); } export interface SvidResponse { spiffe_id: string; x509_svid: Uint8Array; x509_svid_key: Uint8Array; bundle: Uint8Array; } export async function fetchSpiffeIdentity( socketPath: string = "/var/run/spire/agent.sock", ): Promise { if (!dylib) { console.warn( `[SPIRE FFI] Dynamic library (${libPath}) is not loaded. Mocking SVID response for local development.`, ); return { spiffe_id: "spiffe://local.dev/mock", x509_svid: new Uint8Array(), x509_svid_key: new Uint8Array(), bundle: new Uint8Array(), }; } const encoder = new TextEncoder(); const encodedPath = encoder.encode(socketPath + "\0"); const pathPtr = Deno.UnsafePointer.of(encodedPath); const fetch_svid = dylib.symbols .fetch_svid as unknown as (( ptr: Deno.PointerValue, ) => Promise); const free_svid = dylib.symbols .free_svid as unknown as ((ptr: Deno.PointerValue) => void); const resPtr = await fetch_svid(pathPtr); if (resPtr === null) { throw new Error("fetch_svid returned a null pointer"); } const resView = new Deno.UnsafePointerView(resPtr); let errorMsg: string | null = null; let spiffe_id: string | null = null; let offset = 0; const ptrSize = 8; // 64-bit pointers const spiffe_id_ptr = resView.getPointer(offset); offset += ptrSize; const x509_svid_ptr = resView.getPointer(offset); offset += ptrSize; const x509_svid_len = Number(resView.getBigUint64(offset)); offset += ptrSize; const x509_svid_key_ptr = resView.getPointer(offset); offset += ptrSize; const x509_svid_key_len = Number(resView.getBigUint64(offset)); offset += ptrSize; const bundle_ptr = resView.getPointer(offset); offset += ptrSize; const bundle_len = Number(resView.getBigUint64(offset)); offset += ptrSize; const error_ptr = resView.getPointer(offset); if (error_ptr !== null) { errorMsg = new Deno.UnsafePointerView(error_ptr).getCString(); } if (errorMsg !== null) { free_svid(resPtr); throw new Error(errorMsg); } if (spiffe_id_ptr !== null) { spiffe_id = new Deno.UnsafePointerView(spiffe_id_ptr).getCString(); } if (!spiffe_id) { free_svid(resPtr); throw new Error("spiffe_id is null"); } const x509_svid = x509_svid_ptr !== null && x509_svid_len > 0 ? new Uint8Array( new Deno.UnsafePointerView(x509_svid_ptr).getArrayBuffer(x509_svid_len), ) : new Uint8Array(); const x509_svid_key = x509_svid_key_ptr !== null && x509_svid_key_len > 0 ? new Uint8Array( new Deno.UnsafePointerView(x509_svid_key_ptr).getArrayBuffer( x509_svid_key_len, ), ) : new Uint8Array(); const bundle = bundle_ptr !== null && bundle_len > 0 ? new Uint8Array( new Deno.UnsafePointerView(bundle_ptr).getArrayBuffer(bundle_len), ) : new Uint8Array(); // Create copies of the typed arrays before freeing the memory const svidData = { spiffe_id, x509_svid: new Uint8Array(x509_svid), x509_svid_key: new Uint8Array(x509_svid_key), bundle: new Uint8Array(bundle), }; // Free the memory on the Rust side free_svid(resPtr); return svidData; } /** * Extracts the SPIFFE ID from an incoming client TLS connection. */ export function extractSpiffeIdFromCert(certBundle: string): string | null { try { const cert = new X509Certificate(certBundle); const sanExtension = cert.extensions.find((ext) => ext.type === "2.5.29.17" ); // Subject Alternative Name if (!sanExtension) { return null; } const san = AsnParser.parse(sanExtension.value, SubjectAlternativeName); for (const name of san) { if ( name.uniformResourceIdentifier && name.uniformResourceIdentifier.startsWith("spiffe://") ) { return name.uniformResourceIdentifier; } } } catch (e) { console.error("Failed to parse certificate:", e); return null; } return null; }