-
Notifications
You must be signed in to change notification settings - Fork 0
/
helper.js
128 lines (98 loc) · 3.42 KB
/
helper.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
'use strict';
const bufferToString = (buff) => {
var enc = new TextDecoder(); // always utf-8 for decoding
return enc.decode(buff)
}
const getEndian = () => {
let arrayBuffer = new ArrayBuffer(2);
let uint8Array = new Uint8Array(arrayBuffer);
let uint16array = new Uint16Array(arrayBuffer);
uint8Array[0] = 0xAA; // set first byte
uint8Array[1] = 0xBB; // set second byte
if(uint16array[0] === 0xBBAA)
return 'little';
else
return 'big';
}
const readBE16 = (buffer) => {
if(buffer.length !== 2)
throw new Error('Only 2byte buffer allowed!');
if(getEndian() !== 'big')
buffer = buffer.reverse();
return new Uint16Array(buffer.buffer)[0]
}
const readBE32 = (buffer) => {
if(buffer.length !== 4)
throw new Error('Only 4byte buffers allowed!');
if(getEndian() !== 'big')
buffer = buffer.reverse();
return new Uint32Array(buffer.buffer)[0]
}
const bufToHex = (buffer) => { // buffer is an ArrayBuffer
return Array.prototype.map.call(new Uint8Array(buffer), x => ('00' + x.toString(16)).slice(-2)).join('');
}
const parseAuthData = (buffer) => {
let rpIdHash = buffer.slice(0, 32); buffer = buffer.slice(32);
let flagsBuf = buffer.slice(0, 1); buffer = buffer.slice(1);
let flagsInt = flagsBuf[0];
let flags = {
up: !!(flagsInt & 0x01),
uv: !!(flagsInt & 0x04),
at: !!(flagsInt & 0x40),
ed: !!(flagsInt & 0x80),
flagsInt
}
let counterBuf = buffer.slice(0, 4); buffer = buffer.slice(4);
let counter = readBE32(counterBuf);
let aaguid = undefined;
let credID = undefined;
let COSEPublicKey = undefined;
if(flags.at) {
aaguid = buffer.slice(0, 16); buffer = buffer.slice(16);
let credIDLenBuf = buffer.slice(0, 2); buffer = buffer.slice(2);
let credIDLen = readBE16(credIDLenBuf);
credID = buffer.slice(0, credIDLen); buffer = buffer.slice(credIDLen);
COSEPublicKey = buffer;
}
return {rpIdHash, flagsBuf, flags, counter, counterBuf, aaguid, credID, COSEPublicKey}
}
const generateRandomBuffer = (length) => {
if(!length)
length = 32;
var randomBuff = new Uint8Array(length);
window.crypto.getRandomValues(randomBuff);
return randomBuff
}
const publicKeyCredentialToJSON = (pubKeyCred) => {
if(pubKeyCred instanceof Array) {
let arr = [];
for(let i of pubKeyCred)
arr.push(publicKeyCredentialToJSON(i));
return arr
}
if(pubKeyCred instanceof ArrayBuffer) {
return base64url.encode(pubKeyCred)
}
if(pubKeyCred instanceof Object) {
let obj = {};
for (let key in pubKeyCred) {
obj[key] = publicKeyCredentialToJSON(pubKeyCred[key])
}
return obj
}
return pubKeyCred
}
const preformatMakeCredReq = (makeCredReq) => {
makeCredReq.challenge = base64url.decode(makeCredReq.challenge);
makeCredReq.user.id = base64url.decode(makeCredReq.user.id);
return makeCredReq
}
const preformatGetAssertReq = (getAssert) => {
getAssert.challenge = base64url.decode(getAssert.challenge);
if(getAssert.allowCredentials) {
for(let allowCred of getAssert.allowCredentials) {
allowCred.id = base64url.decode(allowCred.id);
}
}
return getAssert
}