123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596 |
- var fernet = require('../fernet');
- //TokenFoctory
- module = module.exports = function (parent) {
- var Token = function Token(opts) {
- opts = opts || {};
- this.secret = opts.secret || parent.secret;
- this.ttl = opts.ttl || parent.ttl;
- if (opts.ttl === 0) this.ttl = 0;
- this.message = opts.message;
- this.cipherText = opts.cipherText;
- this.token = opts.token;
- this.version = opts.version || fernet.parseHex(parent.versionHex);
- this.optsIV = opts.iv;
- this.maxClockSkew = 60;
- if (opts.time) this.setTime(Date.parse(opts.time));
- else this.setTime();
- }
- Token.prototype = {
- setIV: fernet.setIV,
- setTime: function tokenSetTime(time) {
- this.time = fernet.timeBytes(time);
- },
- toString: function tokenToString() {
- if (this.encoded) {
- return this.token
- } else {
- return this.message
- }
- },
- encode: function encodeToken(message) {
- if (!this.secret) throw (new Error("Secret not set"));
- this.encoded = true;
- this.setIV(this.optsIV); //if null will always be a fresh IV
- this.message = message || this.message;
- this.cipherText = fernet.encryptMessage(this.message, this.secret.encryptionKey, this.iv);
- this.token = fernet.createToken(this.secret.signingKey, this.time, this.iv, this.cipherText)
- return this.token;
- },
- decode: function decodeToken(token) {
- if (!this.secret) throw (new Error("Secret not set"));
- this.encoded = false;
- this.token = token || this.token;
- var tokenString = fernet.decode64toHex(this.token);
- var versionOffset = fernet.hexBits(8);
- var timeOffset = versionOffset + fernet.hexBits(64);
- var ivOffset = timeOffset + fernet.hexBits(128);
- var hmacOffset = tokenString.length - fernet.hexBits(256);
- var timeInt = fernet.parseHex(tokenString.slice(versionOffset, timeOffset));
- this.version = fernet.parseHex(tokenString.slice(0, versionOffset));
- if (this.version != 128) {
- throw new Error("Invalid version");
- }
- this.time = new Date(timeInt * 1000);
- var currentTime = new Date()
- var timeDiff = (currentTime - this.time) / 1000;
- if (this.ttl > 0) {
- if (timeDiff > this.ttl) {
- throw new Error("Invalid Token: TTL");
- }
- if (((currentTime / 1000) + this.maxClockSkew) < timeInt) {
- throw new Error("far-future timestamp");
- }
- }
- this.ivHex = tokenString.slice(timeOffset, ivOffset);
- this.iv = fernet.Hex.parse(this.ivHex);
- this.cipherTextHex = tokenString.slice(ivOffset, hmacOffset);
- this.cipherText = fernet.Hex.parse(this.cipherTextHex);
- this.hmacHex = tokenString.slice(hmacOffset);
- var decodedHmac = fernet.createHmac(this.secret.signingKey, fernet.timeBytes(this.time), this.iv, this.cipherText);
- var decodedHmacHex = decodedHmac.toString(fernet.Hex);
- var accum = 0
- for (var i = 0; i < 64; i++) {
- accum += decodedHmacHex.charCodeAt(i) ^ this.hmacHex.charCodeAt(i)
- }
- if (accum != 0) throw new Error("Invalid Token: HMAC");
- this.message = fernet.decryptMessage(this.cipherText, this.secret.encryptionKey, this.iv)
- return this.message;
- }
- }
- return Token;
- }
- //exports = module.exports = Token;
|