Skip to content

Instantly share code, notes, and snippets.

@KunalKumarSwift
Created January 10, 2025 05:04
Show Gist options
  • Save KunalKumarSwift/de8facc68bbc9f5c51786163b9a1a75b to your computer and use it in GitHub Desktop.
Save KunalKumarSwift/de8facc68bbc9f5c51786163b9a1a75b to your computer and use it in GitHub Desktop.
const cbor = require('cbor');
// Example base64-encoded attestation object (replace with your actual data)
const base64AttestationObject = "your_base64_encoded_attestation_object";
// Decode the Base64 string into a buffer
const attestationBuffer = Buffer.from(base64AttestationObject, 'base64');
// Decode the CBOR object
cbor.decodeFirst(attestationBuffer)
.then((decoded) => {
console.log("Decoded Attestation Object:", decoded);
// Extract the fields
const fmt = decoded.fmt; // Attestation format
const authData = decoded.authData; // Authenticator data
const attStmt = decoded.attStmt; // Attestation statement
console.log("Format (fmt):", fmt);
console.log("Authenticator Data (authData):", authData.toString('hex'));
if (attStmt) {
console.log("Attestation Statement (attStmt):", attStmt);
// Handle x5c (attestation certificate chain)
if (attStmt.x5c) {
const certificates = attStmt.x5c.map(cert => cert.toString('hex'));
console.log("Certificates (x5c):", certificates);
}
// Handle signature (sig)
if (attStmt.sig) {
console.log("Signature (sig):", attStmt.sig.toString('hex'));
}
}
// Parse the authData field for more details
parseAuthData(authData);
})
.catch((err) => {
console.error("Failed to decode CBOR:", err);
});
// Function to parse the authData field
function parseAuthData(authData) {
if (!authData || authData.length < 37) {
console.error("authData is invalid or too short");
return;
}
// RP ID hash (first 32 bytes)
const rpIdHash = authData.slice(0, 32);
console.log("RP ID Hash:", rpIdHash.toString('hex'));
// Flags (1 byte after RP ID hash)
const flags = authData[32];
console.log("Flags:", flags.toString(16));
// Sign count (4 bytes after flags)
const signCount = authData.readUInt32BE(33);
console.log("Sign Count:", signCount);
// Handle attested credential data if present (flag bit 6)
if (flags & 0x40) {
// AAGUID (16 bytes after RP ID hash and flags)
const aaguid = authData.slice(37, 53);
console.log("AAGUID:", aaguid.toString('hex'));
// Credential ID length (2 bytes after AAGUID)
const credentialIdLength = authData.readUInt16BE(53);
console.log("Credential ID Length:", credentialIdLength);
// Credential ID (variable length)
const credentialIdStart = 55;
const credentialIdEnd = credentialIdStart + credentialIdLength;
const credentialId = authData.slice(credentialIdStart, credentialIdEnd);
console.log("Credential ID:", credentialId.toString('hex'));
// Public key (CBOR-encoded, starts after Credential ID)
const publicKeyData = authData.slice(credentialIdEnd);
console.log("Public Key (CBOR):", publicKeyData.toString('hex'));
// Decode the CBOR-encoded public key
cbor.decodeFirst(publicKeyData)
.then((publicKey) => {
console.log("Decoded Public Key:", publicKey);
})
.catch((err) => {
console.error("Failed to decode public key CBOR:", err);
});
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment