acme.js-ARCHIVED/lib/native.js

89 lines
2.1 KiB
JavaScript
Raw Normal View History

2019-10-21 19:45:47 +00:00
'use strict';
var native = module.exports;
var promisify = require('util').promisify;
var resolveTxt = promisify(require('dns').resolveTxt);
2019-10-25 10:54:40 +00:00
var crypto = require('crypto');
2019-10-21 19:45:47 +00:00
2020-07-28 21:53:50 +00:00
native._canCheck = function (me) {
2019-10-21 19:53:50 +00:00
me._canCheck = {};
2019-10-21 19:45:47 +00:00
me._canCheck['http-01'] = true;
me._canCheck['dns-01'] = true;
return Promise.resolve();
};
2020-07-28 21:53:50 +00:00
native._dns01 = function (me, ch) {
2019-10-21 19:45:47 +00:00
// TODO use digd.js
2020-07-28 21:53:50 +00:00
return resolveTxt(ch.dnsHost).then(function (records) {
2019-10-21 19:45:47 +00:00
return {
2020-07-28 21:53:50 +00:00
answer: records.map(function (rr) {
2019-10-21 19:45:47 +00:00
return {
data: rr
};
})
};
});
};
2020-07-28 21:53:50 +00:00
native._http01 = function (me, ch) {
2019-10-21 19:45:47 +00:00
return new me.request({
url: ch.challengeUrl
2020-07-28 21:53:50 +00:00
}).then(function (resp) {
2019-10-21 19:45:47 +00:00
return resp.body;
});
};
2019-10-25 10:54:40 +00:00
// the hashcash here is for browser parity only
// basically we ask the client to find a needle in a haystack
// (very similar to CloudFlare's api protection)
2020-07-28 21:53:50 +00:00
native._hashcash = function (ch) {
2019-10-25 10:54:40 +00:00
if (!ch || !ch.nonce) {
ch = { nonce: 'xxx' };
}
return Promise.resolve()
2020-07-28 21:53:50 +00:00
.then(function () {
2019-10-25 10:54:40 +00:00
// only get easy answers
var len = ch.needle.length;
var start = ch.start || 0;
var end = ch.end || Math.ceil(len / 2);
var window = parseInt(end - start, 10) || 0;
var maxLen = 6;
var maxTries = Math.pow(2, maxLen * 8);
if (
len > maxLen ||
window < Math.ceil(len / 2) ||
ch.needle.toLowerCase() !== ch.needle ||
ch.alg !== 'SHA-256'
) {
// bail unless the server is issuing very easy challenges
throw new Error('possible and easy answers only, please');
}
var haystack;
var i;
var answer;
var needle = Buffer.from(ch.needle, 'hex');
for (i = 0; i < maxTries; i += 1) {
answer = i.toString(16);
if (answer.length % 2) {
answer = '0' + answer;
}
haystack = crypto
.createHash('sha256')
.update(Buffer.from(ch.nonce + answer, 'hex'))
.digest()
.slice(ch.start, ch.end);
if (-1 !== haystack.indexOf(needle)) {
return ch.nonce + ':' + answer;
}
}
return ch.nonce + ':xxx';
})
2020-07-28 21:53:50 +00:00
.catch(function () {
2019-10-25 10:54:40 +00:00
//console.log('[debug]', err);
// ignore any error
return ch.nonce + ':xxx';
});
};