Skip to content

Commit 6ca131b

Browse files
committed
feat: export dashboard key; provide dash sig function
1 parent 81fa4e8 commit 6ca131b

File tree

2 files changed

+49
-18
lines changed

2 files changed

+49
-18
lines changed

js/vapid.js

Lines changed: 48 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -17,11 +17,12 @@ function chr(c){
1717
}
1818

1919
var vapid = {
20-
/* Generate and verify a VAPID token */
21-
22-
errs: {
23-
enus: {
20+
/* English:US */
21+
enus: {
22+
info: {
2423
OK_VAPID_KEYS: "VAPID Keys defined.",
24+
}
25+
errs: {
2526
ERR_VAPID_KEY: "VAPID generate keys error: ",
2627
ERR_PUB_R_KEY: "Invalid Public Key record. Please use a valid RAW Formatted record.",
2728
ERR_PUB_D_KEY: "Invalid Public Key record. Please use a valid DER Formatted record.",
@@ -35,9 +36,12 @@ var vapid = {
3536
}
3637
},
3738

39+
lang: this.enus;
40+
3841
_private_key: "",
3942
_public_key: "",
4043

44+
/* Generate and verify a VAPID token */
4145
generate_keys: function() {
4246
/* Generate the public and private keys
4347
*/
@@ -48,10 +52,10 @@ var vapid = {
4852
.then(keys => {
4953
this._private_key = keys.privateKey;
5054
this._public_key = keys.publicKey;
51-
console.info(this.errs.enus.OK_VAPID_KEYS);
55+
console.info(this.lang.info.OK_VAPID_KEYS);
5256
})
5357
.catch(fail => {
54-
console.error(this.errs.enus.ERR_VAPID_KEY, fail);
58+
console.error(this.lang.errs.ERR_VAPID_KEY, fail);
5559
});
5660
},
5761

@@ -150,11 +154,18 @@ var vapid = {
150154
});
151155
},
152156

157+
export_public_raw: function() {
158+
return webCrypto.exportKey('raw', this._public_key)
159+
.then( key => {
160+
return this.url_btoa(key);
161+
})
162+
},
163+
153164
import_public_raw: function(raw) {
154165
if (typeof(raw) == "string") {
155166
raw = this.url_atob(raw);
156167
}
157-
let err = new Error(this.errs.enus.ERR_PUB_KEY);
168+
let err = new Error(this.lang.errs.ERR_PUB_KEY);
158169

159170
// Raw is supposed to start with a 0x04, but some libraries don't. sigh.
160171
if (raw.length == 65 && raw[0] != 4) {
@@ -189,7 +200,7 @@ var vapid = {
189200
derArray = this.url_atob(derArray);
190201
}
191202
/* Super light weight public key import function */
192-
let err = new Error(this.errs.enus.ERR_PUB_D_KEY);
203+
let err = new Error(this.lang.errs.ERR_PUB_D_KEY);
193204
// Does the record begin with "\x30"
194205
if (derArray[0] != 48) { throw err}
195206
// is this an ECDSA record? (looking for \x2a and \x86
@@ -228,14 +239,14 @@ var vapid = {
228239
* to specify VAPID auth.
229240
*/
230241
if (this._public_key == "") {
231-
throw new Error(this.errs.enus.ERR_NO_KEYS);
242+
throw new Error(this.lang.errs.ERR_NO_KEYS);
232243
}
233244
if (!claims.hasOwnProperty("exp")) {
234245
claims.exp = parseInt(Date.now()*.001) + 86400;
235246
}
236247
["sub","aud"].forEach(function(key){
237248
if (! claims.hasOwnProperty(key)) {
238-
throw new Error(this.errs.enus.ERR_CLAIM_MIS, key);
249+
throw new Error(this.lang.errs.ERR_CLAIM_MIS, key);
239250
}
240251
})
241252
let alg = {name:"ECDSA", namedCurve: "P-256", hash:{name:"SHA-256"}};
@@ -266,10 +277,29 @@ var vapid = {
266277
})
267278
})
268279
.catch(err => {
269-
console.error(this.errs.enus.ERR_SIGN, err);
280+
console.error(this.lang.errs.ERR_SIGN, err);
270281
})
271282
},
272283

284+
validate: function(string) {
285+
/* Sign the token for the developer Dashboard */
286+
let alg = {name:"ECDSA", namedCurve: "P-256", hash:{name:"SHA-256"}};
287+
let t2v = this.url_atob(string);
288+
return webCrypto.sign(alg, this._private_key, t2v)
289+
.then(signed => {
290+
let sig = this.url_btoa(signed);
291+
return sig;
292+
});
293+
},
294+
295+
validateCheck: function(sig, string) {
296+
/* verify a given signature string matches */
297+
let alg = { name: "ECDSA", namedCurve: "P-256", hash:{name:"SHA-256"}};
298+
let vsig = this.url_atob(sig);
299+
let t2v = this.url_atob(string);
300+
return webCrypto.verify(alg, this._public_key, vsig, t2v);
301+
},
302+
273303
verify: function(token, public_key=null) {
274304
/* Verify a VAPID token.
275305
*
@@ -302,22 +332,22 @@ var vapid = {
302332
});
303333
}
304334
if (this._public_key == "") {
305-
throw new Error(this.errs.enus.ERR_NO_KEYS);
335+
throw new Error(this.lang.errs.ERR_NO_KEYS);
306336
}
307337

308-
let alg = { name: "ECDSA", namedCurve: "P-256", hash: "SHA-256" };
338+
let alg = { name: "ECDSA", namedCurve: "P-256", hash: {name: "SHA-256" }};
309339
let items = token.split('.');
310340
let signature;
311341
let key;
312342
try {
313343
signature = this.url_atob(items[2]);
314344
} catch (err) {
315-
throw new Error(this.errs.enus.ERR_VERIFY_SG + err.message);
345+
throw new Error(this.lang.errs.ERR_VERIFY_SG + err.message);
316346
}
317347
try {
318348
key = this.url_atob(items[1]);
319349
} catch (err) {
320-
throw new Error(this.errs.enus.ERR_VERIFY_KE + err.message);
350+
throw new Error(this.lang.errs.ERR_VERIFY_KE + err.message);
321351
}
322352
let content = items.slice(0,2).join('.');
323353
let signatory = this._str_to_array(content);
@@ -331,11 +361,11 @@ var vapid = {
331361
return JSON.parse(String.fromCharCode
332362
.apply(null, this.url_atob(items[1])))
333363
}
334-
throw new Error(this.errs.enus.ERR_SIGNATURE);
364+
throw new Error(this.lang.errs.ERR_SIGNATURE);
335365
})
336366
.catch(err => {
337-
console.error(this.errs.enus.ERR_VERIFY, err);
338-
throw new Error (this.errs.enus.ERR_VERIFY + ": " + err.message);
367+
console.error(this.lang.errs.ERR_VERIFY, err);
368+
throw new Error (this.lang.errs.ERR_VERIFY + ": " + err.message);
339369
});
340370
}
341371
}

python/vapid/__init__.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,7 @@ def save_public_key(self, key_file):
7878
file.close()
7979

8080
def validate(self, token):
81+
"""Sign a Valdiation token from the dashboard"""
8182
return base64.urlsafe_b64encode(self.private_key.sign(token))
8283

8384
def sign(self, claims, crypto_key=None):

0 commit comments

Comments
 (0)