Skip to content

Instantly share code, notes, and snippets.

@apowers313
Created May 16, 2018 15:12
Show Gist options
  • Save apowers313/8660902ffbcae31abcbc252220fce18d to your computer and use it in GitHub Desktop.
Save apowers313/8660902ffbcae31abcbc252220fce18d to your computer and use it in GitHub Desktop.
var challengeResponseAttestationTpmB64UrlMsg = {
"fmt": "tpm",
"authData": "ACH1_AuFzSLmBiO819HKSJSJCSSbR3brUVFU5XtmrhJFAAAAAAiYcFjK3EuBtuEw3lDcvpYAICichPudWAHSGBGutbra6sponHJq46QSqYSTvuECv9TypAEDAzkBACBZAQDIy_NkHfALX9bo4IcTFhfTYqiN5oTA6fLeYWSdYuRDl0Kc36xJlsmUn7684N-H1LiUjc2ikyVKQOEvcXWt_M_8m3hf9hnPF5srGVb9PJy7Hu_Al5c0AKvDW8MvuWQtLdoyqyjc_K2zufHb-p3JAwas-ASJmBNTKC5N5I372SUk4h_POnUIBcS2ILeANcrz1IMKwkMpPVbWviOoZBOmJlpHW-gmGStCgXNZkipAwIf_iyf3O9psN8aNY-2xq6iwBBkoK5RejNcJu29Hd5boCIpWN2eGrYb77EVI_tdpmgftwqdUkeF4f8eUIIB9EIF8bsCAAHQETDVoWaMVezcfwmsDIUMBAAE",
"attStmt": {
"ver": "2.0",
"alg": -262,
"sig": "ZJhH97wfhLNjAspXDakD_cW5ciDRPmKQf58PBSCAusj02nD49gRdDJVCk0-oDZ-z0yYSXL0Odyl2pTsAaIPyobFuN4LX4-WzoZzp1P93xQhE5IsRSTuk4R2K7FBu6VRQ10oc0GkEk_vniHtDkfssxjcolicVxHTrB2Ozs4GkJeiyz2I6H1apfZaUFJRJS8PbUTdEtSTEbKUGV9ZoxOgwTj0yeP0MxlZaA_xnrZEF3LH4XeOgTge1T4HRjkb0_68nFmnI7icqVe9YTdb2ItV2C2-FDBdyfhPPsQ95MAciDcNOe9JSjG3Mb9Wkkl6u-9YGfXUwA8rioISXGyuS1kCXVA",
"x5c": ["MIIEsjCCA5qgAwIBAgIQR5Ytn5Z0QAe2iJH35QrP1jANBgkqhkiG9w0BAQsFADBBMT8wPQYDVQQDEzZOQ1UtTlRDLUtFWUlELTE1OTFENEI2RUFGOThEMDEwNDg2NEI2OTAzQTQ4REQwMDI2MDc3RDMwHhcNMTcxMDE2MTg0MDQ0WhcNMjcxMDE2MTg0MDQ0WjAAMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAwYSx7L2yfVC-GKaX2Mbdw7TKUyRXb4ymOo4w967_UFx_S5uDMpM00dTGt_MsOlpAo_UVvSLyBs-4eOgOeGFj2LDmcYEOinUZuefyxYtLPgrd7sE2JBfrnRtR8rJ-_DGIbzV15hfkzaeKABbsgKNnMGraKcVVhDgENMoT-fmH-4nTtX1Gh9mKVO_693WGSNg29bP2KUGn6F2EBQq08YfswydfqEXlwF3nuy1V3bMoKr_uNatQk5Kk0nS5rvmfxbjku3bLJIKsA5hkYHD2sQJ708VQ5jeO_Pufaru_8a9Z1q5tErdAMjzTHFJ3UuTmpI_ZHHhZ-1ooHSKQYG3PvvFzVwIDAQABo4IB5TCCAeEwDgYDVR0PAQH_BAQDAgeAMAwGA1UdEwEB_wQCMAAwbQYDVR0gAQH_BGMwYTBfBgkrBgEEAYI3FR8wUjBQBggrBgEFBQcCAjBEHkIAVABDAFAAQQAgACAAVAByAHUAcwB0AGUAZAAgACAAUABsAGEAdABmAG8AcgBtACAAIABJAGQAZQBuAHQAaQB0AHkwEAYDVR0lBAkwBwYFZ4EFCAMwSgYDVR0RAQH_BEAwPqQ8MDoxODAOBgVngQUCAwwFaWQ6MTMwEAYFZ4EFAgIMB05QQ1Q2eHgwFAYFZ4EFAgEMC2lkOjRFNTQ0MzAwMB8GA1UdIwQYMBaAFMISqVvO-lb4wMFvsVvdAzRHs3qjMB0GA1UdDgQWBBRALYmx3IcOe-liGxJPle4H_d9BEDCBswYIKwYBBQUHAQEEgaYwgaMwgaAGCCsGAQUFBzAChoGTaHR0cHM6Ly9hemNzcHJvZG5jdWFpa3B1Ymxpc2guYmxvYi5jb3JlLndpbmRvd3MubmV0L25jdS1udGMta2V5aWQtMTU5MWQ0YjZlYWY5OGQwMTA0ODY0YjY5MDNhNDhkZDAwMjYwNzdkMy8zYjkxOGFlNC0wN2UxLTQwNTktOTQ5MS0wYWQyNDgxOTA4MTguY2VyMA0GCSqGSIb3DQEBCwUAA4IBAQCs7BOMAuiEPEM4cJ2AKzhNnJiQ9geUkhOXf7Ja0mO_9oe6c2ie4QswGccRYVIkY3sZCA54qVaGkVRp3bEDNHrwI57Q8oY9GpBVv04JtbTdmGeJmnlAV8qPUBMibraU2MaT0cRh1k3lZhax0KncAnPCrTyRInWdzKvItoHpBj1ybVWCDRUZFSxLFUMyk_afsAm-rK6R-EBl7uzsXB14lQx04FrLiYqCKab1zbdwcedM7G54Pm06wW5r59ZrkJtLMWTHugdCpr61M1h22bsAlr3HavZRoIg-dX0j6o0A8dDd7mKUeo7twWdZEwYjKK3yMxzOLleD3uFgIxxlbAag6r0S", "MIIF6DCCA9CgAwIBAgITMwAAAQDiBsSROVGXhwAAAAABADANBgkqhkiG9w0BAQsFADCBjDELMAkGA1UEBhMCVVMxEzARBgNVBAgTCldhc2hpbmd0b24xEDAOBgNVBAcTB1JlZG1vbmQxHjAcBgNVBAoTFU1pY3Jvc29mdCBDb3Jwb3JhdGlvbjE2MDQGA1UEAxMtTWljcm9zb2Z0IFRQTSBSb290IENlcnRpZmljYXRlIEF1dGhvcml0eSAyMDE0MB4XDTE3MDIwMTE3NDAyNFoXDTI5MTIzMTE3NDAyNFowQTE_MD0GA1UEAxM2TkNVLU5UQy1LRVlJRC0xNTkxRDRCNkVBRjk4RDAxMDQ4NjRCNjkwM0E0OEREMDAyNjA3N0QzMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA9IwUMSiQUbrQR0NLkKR-9RB8zfHYdlmDB0XN_m8qrNHKRJ__lBOR-mwU_h3MFRZF6X3ZZwka1DtwBdzLFV8lVu33bc15stjSd6B22HRRKQ3sIns5AYQxg0eX2PtWCJuIhxdM_jDjP2hq9Yvx-ibt1IO9UZwj83NGxXc7Gk2UvCs9lcFSp6U8zzl5fGFCKYcxIKH0qbPrzjlyVyZTKwGGSTeoMMEdsZiq-m_xIcrehYuHg-FAVaPLLTblS1h5cu80-ruFUm5Xzl61YjVU9tAV_Y4joAsJ5QP3VPocFhr5YVsBVYBiBcQtr5JFdJXZWWEgYcFLdAFUk8nJERS7-5xLuQIDAQABo4IBizCCAYcwCwYDVR0PBAQDAgGGMBsGA1UdJQQUMBIGCSsGAQQBgjcVJAYFZ4EFCAMwFgYDVR0gBA8wDTALBgkrBgEEAYI3FR8wEgYDVR0TAQH_BAgwBgEB_wIBADAdBgNVHQ4EFgQUwhKpW876VvjAwW-xW90DNEezeqMwHwYDVR0jBBgwFoAUeowKzi9IYhfilNGuVcFS7HF0pFYwcAYDVR0fBGkwZzBloGOgYYZfaHR0cDovL3d3dy5taWNyb3NvZnQuY29tL3BraW9wcy9jcmwvTWljcm9zb2Z0JTIwVFBNJTIwUm9vdCUyMENlcnRpZmljYXRlJTIwQXV0aG9yaXR5JTIwMjAxNC5jcmwwfQYIKwYBBQUHAQEEcTBvMG0GCCsGAQUFBzAChmFodHRwOi8vd3d3Lm1pY3Jvc29mdC5jb20vcGtpb3BzL2NlcnRzL01pY3Jvc29mdCUyMFRQTSUyMFJvb3QlMjBDZXJ0aWZpY2F0ZSUyMEF1dGhvcml0eSUyMDIwMTQuY3J0MA0GCSqGSIb3DQEBCwUAA4ICAQAKc9z1UUBAaybIVnK8yL1N1iGJFFFFw_PpkxW76hgQhUcCxNFQskfahfFzkBD05odVC1DKyk2PyOle0G86FCmZiJa14MtKNsiu66nVqk2hr8iIcu-cYEsgb446yIGd1NblQKA1C_28F2KHm8YRgcFtRSkWEMuDiVMa0HDU8aI6ZHO04Naj86nXeULJSZsA0pQwNJ04-QJP3MFQzxQ7md6D-pCx-LVA-WUdGxT1ofaO5NFxq0XjubnZwRjQazy_m93dKWp19tbBzTUKImgUKLYGcdmVWXAxUrkxHN2FbZGOYWfmE2TGQXS2Z-g4YAQo1PleyOav3HNB8ti7u5HpI3t9a73xuECy2gFcZQ24DJuBaQe4mU5I_hPiAa-822nPPL6w8m1eegxhHf7ziRW_hW8s1cvAZZ5Jpev96zL_zRv34MsRWhKwLbu2oOCSEYYh8D8DbQZjmsxlUYR_q1cP8JKiIo6NNJ85g7sjTZgXxeanA9wZwqwJB-P98VdVslC17PmVu0RHOqRtxrht7OFT7Z10ecz0tj9ODXrv5nmBktmbgHRirRMl84wp7-PJhTXdHbxZv-OoL4HP6FxyDbHxLB7QmR4-VoEZN0vsybb1A8KEj2pkNY_tmxHH6k87euM99bB8FHrW9FNrXCGL1p6-PYtiky52a5YQZGT8Hz-ZnxobTg"],
"certInfo": "_1RDR4AXACIACxHmjtRNtTcuFCluL4Ssx4OYdRiBkh4w_CKgb4tzx5RTABQaCtAxc_7NUMbYJrPXp-boJN_r-wAAAAFHcBdIVWl7S8aFYKUBc375jTRWVfsAIgALycjv5SUvmOS-5QCTo-NeCZEPrZ0sT2Otuqi_GKPJ5oIAIgAL0leq1oNrtzlP67MKHW9hh6epJPh2higlQCaOdtivlmE",
"pubArea": "AAEACwAGBHIAIJ3_y_NsODrmmfuYaNxty4nXFTiEvigDkiwSQVi_rSKuABAAEAgAAAAAAAEAyMvzZB3wC1_W6OCHExYX02KojeaEwOny3mFknWLkQ5dCnN-sSZbJlJ--vODfh9S4lI3NopMlSkDhL3F1rfzP_Jt4X_YZzxebKxlW_Tycux7vwJeXNACrw1vDL7lkLS3aMqso3Pyts7nx2_qdyQMGrPgEiZgTUyguTeSN-9klJOIfzzp1CAXEtiC3gDXK89SDCsJDKT1W1r4jqGQTpiZaR1voJhkrQoFzWZIqQMCH_4sn9zvabDfGjWPtsauosAQZKCuUXozXCbtvR3eW6AiKVjdnhq2G--xFSP7XaZoH7cKnVJHheH_HlCCAfRCBfG7AgAB0BEw1aFmjFXs3H8JrAw"
}
};
function tpmParseFn() {
var certInfo = coerceToArrayBuffer(challengeResponseAttestationTpmB64UrlMsg.attStmt.certInfo, "certInfo");
var pubArea = coerceToArrayBuffer(challengeResponseAttestationTpmB64UrlMsg.attStmt.pubArea, "pubArea");
parseCertInfo(certInfo);
parsePubArea(pubArea);
}
function parseCertInfo(certInfo) {
if (!(certInfo instanceof ArrayBuffer)) {
throw new Error("tpm attestation: expected certInfo to be ArrayBuffer");
}
var dv = new DataView(certInfo);
var offset = 0;
var ret;
var ci = new Map();
// TPM_GENERATED_VALUE magic number
ci.set("magic", dv.getUint32(offset));
offset += 4;
// TPMI_ST_ATTEST type
ci.set("type", dv.getUint16(offset));
offset += 2;
// TPM2B_NAME qualifiedSigner
ret = getTpm2bName(dv, offset);
ci.set("qualifiedSignerHashType", ret.hashType);
ci.set("qualifiedSigner", ret.nameHash);
offset = ret.offset;
// TPM2B_DATA extraData
ret = getSizedElement(dv, offset);
ci.set("extraData", ret.dv);
offset = ret.offset;
// TPMS_CLOCK_INFO clockInfo
// UINT64 clock
ci.set("clock", dv.buffer.slice(offset, offset + 8));
offset += 8;
// UINT32 resetCount
ci.set("resetCount", dv.getUint32(offset));
offset += 4;
// UINT32 restartCount
ci.set("restartCount", dv.getUint32(offset));
offset += 4;
// boolean safe
ci.set("safe", !!dv.getUint8(offset));
offset++;
// UINT64 firmwareVersion
ci.set("firmwareVersion", dv.buffer.slice(offset, offset + 8));
offset += 8;
// TPMU_ATTEST attested
// TPM2B_NAME name
ret = getTpm2bName(dv, offset);
ci.set("nameHashType", ret.hashType);
ci.set("name", ret.nameHash);
offset = ret.offset;
// TPM2B_NAME qualifiedName
ret = getTpm2bName(dv, offset);
ci.set("qualifiedNameHashType", ret.hashType);
ci.set("qualifiedName", ret.nameHash);
offset = ret.offset;
if (offset !== certInfo.byteLength) {
throw new Error("tpm attestation: left over bytes when parsing cert info");
}
return ci;
}
function parsePubArea(pubArea) {
if (!(pubArea instanceof ArrayBuffer)) {
throw new Error("tpm attestation: expected pubArea to be ArrayBuffer");
}
var dv = new DataView(pubArea);
var offset = 0;
var ret;
var pa = new Map();
// TPMI_ALG_PUBLIC type
pa.set("type", algIdToStr(dv.getUint16(offset)));
offset += 2;
// TPMI_ALG_HASH nameAlg
pa.set("nameAlg", algIdToStr(dv.getUint16(offset)));
offset += 2;
// TPMA_OBJECT objectAttributes
pa.set("objectAttributes", decodeObjectAttributes(dv.getUint32(offset)));
offset += 4;
// TPM2B_DIGEST authPolicy
ret = getSizedElement(dv, offset);
pa.set("authPolicy", ret.dv);
offset = ret.offset;
// TPMU_PUBLIC_PARMS parameters
pa.set("symmetric", algIdToStr(dv.getUint16(offset)));
offset += 2;
pa.set("scheme", algIdToStr(dv.getUint16(offset)));
offset += 2;
pa.set("keyBits", dv.getUint16(offset));
offset += 2;
pa.set("exponent", dv.getUint32(offset));
offset += 4;
// TPMU_PUBLIC_ID unique
ret = getSizedElement(dv, offset);
pa.set("unique", ret.dv);
offset = ret.offset;
if (offset !== pubArea.byteLength) {
throw new Error("tpm attestation: left over bytes when parsing public area");
}
return pa;
}
function decodeObjectAttributes(oa) {
var attrList = [
"RESERVED_0",
"FIXED_TPM",
"ST_CLEAR",
"RESERVED_3",
"FIXED_PARENT",
"SENSITIVE_DATA_ORIGIN",
"USER_WITH_AUTH",
"ADMIN_WITH_POLICY",
"RESERVED_8",
"RESERVED_9",
"NO_DA",
"ENCRYPTED_DUPLICATION",
"RESERVED_12",
"RESERVED_13",
"RESERVED_14",
"RESERVED_15",
"RESTRICTED",
"DECRYPT",
"SIGN_ENCRYPT",
"RESERVED_19",
"RESERVED_20",
"RESERVED_21",
"RESERVED_22",
"RESERVED_23",
"RESERVED_24",
"RESERVED_25",
"RESERVED_26",
"RESERVED_27",
"RESERVED_28",
"RESERVED_29",
"RESERVED_30",
"RESERVED_31"
];
var ret = new Set();
for (let i = 0; i < 32; i++) {
let bit = 1 << i;
if (oa & bit) {
ret.add(attrList[i]);
}
}
return ret;
}
function getSizedElement(dv, offset) {
var size = dv.getUint16(offset);
offset += 2;
var buf = dv.buffer.slice(offset, offset + size);
dv = new DataView(buf);
offset += size;
return {
size,
dv,
offset
};
}
function getTpm2bName(dvIn, oIn) {
var {
offset,
dv
} = getSizedElement(dvIn, oIn);
var hashType = algIdToStr(dv.getUint16(0));
var nameHash = dv.buffer.slice(2);
return {
hashType,
nameHash,
offset
};
}
function algIdToStr(hashType) {
var hashList = [
"TPM_ALG_ERROR", // 0
"TPM_ALG_RSA", // 1
null,
null,
"TPM_ALG_SHA1", // 4
"TPM_ALG_HMAC", // 5
"TPM_ALG_AES", // 6
"TPM_ALG_MGF1", // 7
null,
"TPM_ALG_KEYEDHASH", // 8
"TPM_ALG_XOR", // A
"TPM_ALG_SHA256", // B
"TPM_ALG_SHA384", // C
"TPM_ALG_SHA512", // D
null,
null,
"TPM_ALG_NULL", // 10
null,
"TPM_ALG_SM3_256", // 12
"TPM_ALG_SM4", // 13
"TPM_ALG_RSASSA", // 14
"TPM_ALG_RSAES", // 15
"TPM_ALG_RSAPSS", // 16
"TPM_ALG_OAEP", // 17
"TPM_ALG_ECDSA" // 18
];
return hashList[hashType];
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment