Merge branch 'master' into feature/browser-tests, fix conflicts

This commit is contained in:
Braydon Fuller 2014-10-20 18:29:50 -04:00
commit 9b18c36b03
8 changed files with 73 additions and 17 deletions

4
.travis.yml Normal file
View File

@ -0,0 +1,4 @@
language: node_js
node_js:
- '0.10'

View File

@ -29,10 +29,10 @@ See https://en.bitcoin.it/wiki/Identity_protocol_v1 for complete details.
In each request, the client includes a nonce to prevent replay attacks. The client
signs the full url with the request body concatenated if there is one. The signature
is included in the x-signature header and the public key is included in the
x-pubkey header.
is included in the `x-signature` header and the public key is included in the
`x-identity` header.
The server verifies that the signature is valid and that it matches the public key.
The server verifies that the signature is valid and that it matches the identity (the public key).
It then computes the SIN from the public key, and sees whether that SIN has access
to the requested resource. The nonce is checked to make sure it is higher than
the previously used nonce.
@ -135,7 +135,7 @@ for(k in keys) {
var options = {
url: url,
headers: {
'x-pubkey': bitauth.getPublicKeyFromPrivateKey(keys[k]),
'x-identity': bitauth.getPublicKeyFromPrivateKey(keys[k]),
'x-signature': bitauth.sign(dataToSign, keys[k])
}
};
@ -161,7 +161,7 @@ for(k in keys) {
var options = {
url: url,
headers: {
'x-pubkey': bitauth.getPublicKeyFromPrivateKey(keys[k]),
'x-identity': bitauth.getPublicKeyFromPrivateKey(keys[k]),
'x-signature': bitauth.sign(dataToSign, keys[k])
},
json: data

View File

@ -15,7 +15,7 @@ for(k in keys) {
var options = {
url: url,
headers: {
'x-pubkey': bitauth.getPublicKeyFromPrivateKey(keys[k]),
'x-identity': bitauth.getPublicKeyFromPrivateKey(keys[k]),
'x-signature': bitauth.sign(dataToSign, keys[k])
}
};
@ -41,7 +41,7 @@ for(k in keys) {
var options = {
url: url,
headers: {
'x-pubkey': bitauth.getPublicKeyFromPrivateKey(keys[k]),
'x-identity': bitauth.getPublicKeyFromPrivateKey(keys[k]),
'x-signature': bitauth.sign(dataToSign, keys[k])
},
json: data
@ -55,4 +55,4 @@ for(k in keys) {
console.log(body);
}
});
}
}

View File

@ -32,4 +32,4 @@ app.get('/pizzas', function(req, res) {
res.send(200, pizzas);
});
app.listen(3000);
app.listen(3000);

View File

@ -1,4 +1,3 @@
var crypto = require('crypto');
var bitcore = require('bitcore');
var Key = bitcore.Key;
var SIN = bitcore.SIN;
@ -59,4 +58,19 @@ BitAuth.verifySignature = function(data, pubkey, signature, callback) {
}
};
BitAuth.validateSin = function(sin, callback) {
var s = new SIN(sin);
try {
s.validate()
} catch(err) {
if ( callback )
callback(err);
return false;
}
if ( callback )
callback(null);
return true;
};
module.exports = BitAuth;

View File

@ -1,24 +1,24 @@
var bitauth = require('../bitauth');
module.exports = function(req, res, next) {
if(req.headers && req.headers['x-pubkey'] && req.headers['x-signature']) {
if(req.headers && req.headers['x-identity'] && req.headers['x-signature']) {
// Check signature is valid
// First construct data to check signature on
var fullUrl = req.protocol + '://' + req.get('host') + req.url;
var data = fullUrl + req.rawBody;
bitauth.verifySignature(data, req.headers['x-pubkey'], req.headers['x-signature'], function(err, result) {
bitauth.verifySignature(data, req.headers['x-identity'], req.headers['x-signature'], function(err, result) {
if(err || !result) {
return res.send(400, {error: 'Invalid signature'});
}
// Get the SIN from the public key
var sin = bitauth.getSinFromPublicKey(req.headers['x-pubkey']);
if(!sin) return res.send(400, {error: 'Bad public key'});
var sin = bitauth.getSinFromPublicKey(req.headers['x-identity']);
if(!sin) return res.send(400, {error: 'Bad public key from identity'});
req.sin = sin;
next();
});
} else {
next();
}
};
};

View File

@ -1,3 +1,4 @@
{
"name": "bitauth",
"description": "Passwordless authentication using Bitcoin cryptography",
@ -5,6 +6,10 @@
"name": "Patrick Nagurny",
"email": "patrick@bitpay.com"
},
"repository": {
"type": "git",
"url": "https://github.com/bitpay/bitauth.git"
},
"contributors": [
{
"name": "Eric Martindale",
@ -26,8 +31,9 @@
},
"main": "index.js",
"version": "0.1.1",
"repository": "https://github.com/bitpay/bitauth.git",
"dependencies": {
"bitcore": ">= 0.1.9",
"bitcore": "0.1.32",
"request": "^2.36.0",
"express": "^4.3.1",
"base58-native": "^0.1.4",

View File

@ -13,6 +13,8 @@ describe('bitauth', function() {
var should = chai.should();
var keys = null;
var sin = 'Tf1Jc1xSbqasm5QLwwSQc5umddx2h7mAMHX';
var sinb = 'Tf1Jc1xSbqasm5QLwwSQc5umddx2h7mAMhX';
var contract = 'keyboard cat';
var secret = 'o hai, nsa. how i do teh cryptos?';
var password = 's4705hiru13z!';
@ -68,6 +70,37 @@ describe('bitauth', function() {
});
describe('#validateSinTrue', function() {
it('should validate the sin as true', function(done) {
var valid = bitauth.validateSin(sin);
should.equal(true, valid);
done();
});
});
describe('#validateSinFalse', function() {
it('should validate the sin as false', function(done) {
var valid = bitauth.validateSin(sinb);
should.equal(false, valid);
done();
});
});
describe('#validateSinCallback', function() {
it('should receive error callback', function(done) {
var valid = bitauth.validateSin(sinb, function(err){
should.exist(err);
done();
});
});
});
// node specific tests
if ( typeof(window) === 'undefined' ) {
@ -78,7 +111,6 @@ describe('bitauth', function() {
should.exist(enc);
done();
});
});
describe('#decrypt', function() {