Skip to content

Commit cfadaf2

Browse files
committed
Merge pull request #6 from AnyPresence/feature-hpkp
Http Public Key Pinning added
2 parents 64d2851 + cd16fea commit cfadaf2

File tree

3 files changed

+136
-17
lines changed

3 files changed

+136
-17
lines changed

dist/ap_gateway.js

Lines changed: 77 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -139,7 +139,7 @@ extend(APCache.prototype, {
139139

140140

141141
module.exports = APCache;
142-
},{"../utils/bind":16,"../utils/extend":18,"./persistence/APMemoryStorage":3,"native-promise-only":20}],3:[function(require,module,exports){
142+
},{"../utils/bind":17,"../utils/extend":19,"./persistence/APMemoryStorage":3,"native-promise-only":21}],3:[function(require,module,exports){
143143
"use strict";
144144

145145
var Es6Promise = require("native-promise-only");
@@ -228,7 +228,7 @@ extend(APBrowserStorage.prototype, {
228228
});
229229

230230
module.exports = new APBrowserStorage();
231-
},{"../../utils/bind":16,"../../utils/extend":18,"native-promise-only":20}],4:[function(require,module,exports){
231+
},{"../../utils/bind":17,"../../utils/extend":19,"native-promise-only":21}],4:[function(require,module,exports){
232232
"use strict";
233233

234234
var Es6Promise = require("native-promise-only");
@@ -244,6 +244,7 @@ var XMLParser = require("../parsers/xml");
244244
var FormDataParser = require("../parsers/formData");
245245
var EncodeTransformation = require("./transformations/encode");
246246
var DecodeTransformation = require("./transformations/decode");
247+
var hpkp = require("../hpkp/hpkp");
247248

248249

249250
function APGateway(options) {
@@ -439,6 +440,12 @@ extend(APGateway.prototype, {
439440
}
440441
return this;
441442
},
443+
444+
hpkp: function(options) {
445+
var header = hpkp(options.sha256s, options.maxAge, options.includeSubdomains, options.reportOnly, options.reportUri);
446+
this.headers(header);
447+
return this;
448+
},
442449

443450
execute: function() {
444451
var i;
@@ -498,7 +505,7 @@ extend(APGateway.prototype, {
498505
});
499506

500507
module.exports = APGateway;
501-
},{"../cache/APCache":2,"../parsers/formData":7,"../parsers/json":8,"../parsers/xml":15,"../request/APRequest":9,"../response/APResponse":10,"../utils/bind":16,"../utils/copy":17,"../utils/extend":18,"./transformations/decode":5,"./transformations/encode":6,"native-promise-only":20,"url":14}],5:[function(require,module,exports){
508+
},{"../cache/APCache":2,"../hpkp/hpkp":7,"../parsers/formData":8,"../parsers/json":9,"../parsers/xml":16,"../request/APRequest":10,"../response/APResponse":11,"../utils/bind":17,"../utils/copy":18,"../utils/extend":19,"./transformations/decode":5,"./transformations/encode":6,"native-promise-only":21,"url":15}],5:[function(require,module,exports){
502509
"use strict";
503510

504511
function decode(response) {
@@ -557,6 +564,59 @@ module.exports = encode;
557564
},{}],7:[function(require,module,exports){
558565
"use strict";
559566

567+
function validateArguments(sha256s, maxAge, includeSubdomains, reportOnly, reportUri) {
568+
if(!sha256s || !(sha256s instanceof Array) || sha256s.length < 2) {
569+
return false;
570+
}
571+
if(!maxAge) {
572+
return false;
573+
}
574+
if(!!reportOnly && (!reportUri || typeof reportUri !== "string" || reportUri === "")) {
575+
return false;
576+
}
577+
return true;
578+
}
579+
580+
function headerName(reportOnly) {
581+
var name = "Public-Key-Pins";
582+
if(reportOnly) {
583+
name += "-Report-Only";
584+
}
585+
return name;
586+
}
587+
588+
function headerValue(sha256s, maxAge, includeSubdomains, reportUri) {
589+
var values = [];
590+
for(var i=0 ; i < sha256s.length ; i++) {
591+
values.push('pin-sha256="' + sha256s[i] + '"');
592+
}
593+
594+
values.push('max-age=' + Math.round(maxAge));
595+
596+
if(!!includeSubdomains) {
597+
values.push('includeSubdomains');
598+
}
599+
600+
if(reportUri) {
601+
values.push('report-uri="' + reportUri + '"');
602+
}
603+
604+
return values.join('; ');
605+
}
606+
607+
module.exports = function hpkp(sha256s, maxAge, includeSubdomains, reportOnly, reportUri) {
608+
if(validateArguments(sha256s, maxAge, includeSubdomains, reportOnly, reportUri)) {
609+
var headerName = headerName(reportOnly);
610+
var headerValue = headerValue(sha256s, maxAge, includeSubdomains, reportUri);
611+
var header = {};
612+
header[headerName] = headerValue;
613+
return header;
614+
}
615+
return {};
616+
};
617+
},{}],8:[function(require,module,exports){
618+
"use strict";
619+
560620
function encodeToFormData(data) {
561621
var urlEncodedData = "", urlEncodedDataPairs = [];
562622

@@ -583,7 +643,7 @@ module.exports = {
583643
return data;
584644
}
585645
};
586-
},{}],8:[function(require,module,exports){
646+
},{}],9:[function(require,module,exports){
587647
"use strict";
588648

589649
module.exports = {
@@ -600,7 +660,7 @@ module.exports = {
600660
return parsed;
601661
}
602662
};
603-
},{}],9:[function(require,module,exports){
663+
},{}],10:[function(require,module,exports){
604664
"use strict";
605665

606666
var Es6Promise = require("native-promise-only");
@@ -684,7 +744,7 @@ extend(APRequest.prototype, {
684744
});
685745

686746
module.exports = APRequest;
687-
},{"../response/APResponse":10,"../utils/bind":16,"../utils/copy":17,"../utils/extend":18,"http":13,"native-promise-only":20}],10:[function(require,module,exports){
747+
},{"../response/APResponse":11,"../utils/bind":17,"../utils/copy":18,"../utils/extend":19,"http":14,"native-promise-only":21}],11:[function(require,module,exports){
688748
"use strict";
689749

690750
var extend = require("../utils/extend");
@@ -707,7 +767,7 @@ APResponse.defaults = {
707767
};
708768

709769
module.exports = APResponse;
710-
},{"../utils/extend":18}],11:[function(require,module,exports){
770+
},{"../utils/extend":19}],12:[function(require,module,exports){
711771
"use strict";
712772

713773
var extend = require("../../utils/extend");
@@ -823,7 +883,7 @@ extend(HttpRequest.prototype, {
823883

824884

825885
module.exports = HttpRequest;
826-
},{"../../utils/bind":16,"../../utils/copy":17,"../../utils/extend":18,"./HttpResponse":12,"tiny-emitter":21}],12:[function(require,module,exports){
886+
},{"../../utils/bind":17,"../../utils/copy":18,"../../utils/extend":19,"./HttpResponse":13,"tiny-emitter":22}],13:[function(require,module,exports){
827887
"use strict";
828888

829889
var extend = require("../../utils/extend");
@@ -863,7 +923,7 @@ extend(HttpResponse.prototype, {
863923
});
864924

865925
module.exports = HttpResponse;
866-
},{"../../utils/extend":18,"tiny-emitter":21}],13:[function(require,module,exports){
926+
},{"../../utils/extend":19,"tiny-emitter":22}],14:[function(require,module,exports){
867927
"use strict";
868928

869929
var bind = require("../../utils/bind");
@@ -884,7 +944,7 @@ extend(Http, {
884944
});
885945

886946
module.exports = Http;
887-
},{"../../utils/bind":16,"../../utils/extend":18,"./HttpRequest":11}],14:[function(require,module,exports){
947+
},{"../../utils/bind":17,"../../utils/extend":19,"./HttpRequest":12}],15:[function(require,module,exports){
888948
"use strict";
889949

890950
var Url = {
@@ -909,7 +969,7 @@ var Url = {
909969

910970

911971
module.exports = Url;
912-
},{}],15:[function(require,module,exports){
972+
},{}],16:[function(require,module,exports){
913973
"use strict";
914974

915975
module.exports = {
@@ -941,7 +1001,7 @@ module.exports = {
9411001
}
9421002

9431003
};
944-
},{}],16:[function(require,module,exports){
1004+
},{}],17:[function(require,module,exports){
9451005
"use strict";
9461006

9471007
module.exports = function bind(context, fn) {
@@ -951,7 +1011,7 @@ module.exports = function bind(context, fn) {
9511011
};
9521012
}
9531013
};
954-
},{}],17:[function(require,module,exports){
1014+
},{}],18:[function(require,module,exports){
9551015
"use strict";
9561016

9571017
module.exports = function copy(src) {
@@ -970,7 +1030,7 @@ module.exports = function copy(src) {
9701030
}
9711031
return copied;
9721032
};
973-
},{}],18:[function(require,module,exports){
1033+
},{}],19:[function(require,module,exports){
9741034
"use strict";
9751035

9761036
var toArray = require("./toArray");
@@ -992,13 +1052,13 @@ module.exports = function extend() {
9921052

9931053
return dest;
9941054
};
995-
},{"./toArray":19}],19:[function(require,module,exports){
1055+
},{"./toArray":20}],20:[function(require,module,exports){
9961056
"use strict";
9971057

9981058
module.exports = function toArray(arr) {
9991059
return Array.prototype.slice.call(arr);
10001060
};
1001-
},{}],20:[function(require,module,exports){
1061+
},{}],21:[function(require,module,exports){
10021062
(function (global){
10031063
/*! Native Promise Only
10041064
v0.8.1 (c) Kyle Simpson
@@ -1375,7 +1435,7 @@ module.exports = function toArray(arr) {
13751435
});
13761436

13771437
}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
1378-
},{}],21:[function(require,module,exports){
1438+
},{}],22:[function(require,module,exports){
13791439
function E () {
13801440
// Keep this empty so it's easier to inherit from
13811441
// (via https://github.com/lipsmack from https://github.com/scottcorgan/tiny-emitter/issues/3)

lib/gateway/APGateway.js

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ var XMLParser = require("../parsers/xml");
1313
var FormDataParser = require("../parsers/formData");
1414
var EncodeTransformation = require("./transformations/encode");
1515
var DecodeTransformation = require("./transformations/decode");
16+
var hpkp = require("../hpkp/hpkp");
1617

1718

1819
function APGateway(options) {
@@ -208,6 +209,12 @@ extend(APGateway.prototype, {
208209
}
209210
return this;
210211
},
212+
213+
hpkp: function(options) {
214+
var header = hpkp(options.sha256s, options.maxAge, options.includeSubdomains, options.reportOnly, options.reportUri);
215+
this.headers(header);
216+
return this;
217+
},
211218

212219
execute: function() {
213220
var i;

lib/hpkp/hpkp.js

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
"use strict";
2+
3+
function validateArguments(sha256s, maxAge, includeSubdomains, reportOnly, reportUri) {
4+
if(!sha256s || !(sha256s instanceof Array) || sha256s.length < 2) {
5+
return false;
6+
}
7+
if(!maxAge) {
8+
return false;
9+
}
10+
if(!!reportOnly && (!reportUri || typeof reportUri !== "string" || reportUri === "")) {
11+
return false;
12+
}
13+
return true;
14+
}
15+
16+
function headerName(reportOnly) {
17+
var name = "Public-Key-Pins";
18+
if(reportOnly) {
19+
name += "-Report-Only";
20+
}
21+
return name;
22+
}
23+
24+
function headerValue(sha256s, maxAge, includeSubdomains, reportUri) {
25+
var values = [];
26+
for(var i=0 ; i < sha256s.length ; i++) {
27+
values.push('pin-sha256="' + sha256s[i] + '"');
28+
}
29+
30+
values.push('max-age=' + Math.round(maxAge));
31+
32+
if(!!includeSubdomains) {
33+
values.push('includeSubdomains');
34+
}
35+
36+
if(reportUri) {
37+
values.push('report-uri="' + reportUri + '"');
38+
}
39+
40+
return values.join('; ');
41+
}
42+
43+
module.exports = function hpkp(sha256s, maxAge, includeSubdomains, reportOnly, reportUri) {
44+
if(validateArguments(sha256s, maxAge, includeSubdomains, reportOnly, reportUri)) {
45+
var headerName = headerName(reportOnly);
46+
var headerValue = headerValue(sha256s, maxAge, includeSubdomains, reportUri);
47+
var header = {};
48+
header[headerName] = headerValue;
49+
return header;
50+
}
51+
return {};
52+
};

0 commit comments

Comments
 (0)