Begin work on converting to bitcore 0.8.

This commit is contained in:
Eric Martindale 2014-10-06 22:13:24 -04:00
parent 9e54ccdae3
commit 92405b3a90
7 changed files with 152 additions and 110 deletions

View File

@ -1,22 +1,49 @@
var request = require('request');
var bitauth = require('../lib/bitauth');
var BitAuth = require('../lib/bitauth');
var bitauth = new BitAuth();
// These can be generated with bitauth.generateSin()
// These can be generated with bitauth.generateIdentity()
var keys = {
alice: '38f93bdda21a5c4a7bae4eb75bb7811cbc3eb627176805c1009ff2099263c6ad',
bob: '09880c962437080d72f72c8c63a69efd65d086c9e7851a87b76373eb6ce9aab5'
alice: 'L1i9Xe5gVdg78Cc1U1aCUGG8ZjZ5qieL9axpmKxwjak8FFbSnfYQ',
bob: 'KxpMscE4vhkdTbVHFDuWjYh73APHGATLy1ZndDdL5jCy5d9Kv166'
};
console.log('Alice:')
var alice = new BitAuth();
alice.generateIdentity();
console.log( alice._keypair.privkey.toString() );
console.log( alice._keypair.pubkey.toString() );
console.log( 'pubDER:' , alice._keypair.pubkey.toDER().toString('hex') );
console.log( alice._identity.toString() );
console.log('Bob:')
var bob = new BitAuth();
bob.generateIdentity();
console.log( bob._keypair.privkey.toString() );
console.log( bob._keypair.pubkey.toString() );
console.log( 'pubDER:' , bob._keypair.pubkey.toDER().toString('hex') );
console.log( bob._identity.toString() );
var keys = {
alice: alice,
bob: bob
}
console.log('keys', keys);
// GET
for(k in keys) {
console.log( keys[k]._keypair.privkey )
var url = 'http://localhost:3000/user';
var dataToSign = url;
var options = {
url: url,
headers: {
'x-identity': bitauth.getPublicKeyFromPrivateKey(keys[k]),
'x-signature': bitauth.sign(dataToSign, keys[k])
'x-identity': keys[k]._identity.toString() ,
'x-signature': bitauth.sign( dataToSign , keys[k]._keypair )
}
};
@ -41,8 +68,8 @@ for(k in keys) {
var options = {
url: url,
headers: {
'x-identity': bitauth.getPublicKeyFromPrivateKey(keys[k]),
'x-signature': bitauth.sign(dataToSign, keys[k])
'x-identity': keys[k]._identity.toString(),
'x-signature': bitauth.sign( dataToSign , keys[k]._keypair )
},
json: data
};

View File

@ -4,26 +4,27 @@ var rawBody = require('../lib/middleware/rawbody');
var bitauth = require('../lib/middleware/bitauth');
var users = {
'Tf7UNQnxB8SccfoyZScQmb34V2GdEtQkzDz': {name: 'Alice'},
'Tf22EUFxHWh4wmA3sDuw151W5C5g32jgph2': {name: 'Bob'}
'Tf7Rm1ETjHRiUWZoJTXwVA3nXEQiih35vp3': {name: 'Alice'},
'TexKrSDV87wMhVzTUda5gz92L2joMuwo17m': {name: 'Bob'}
};
var pizzas = [];
var app = express();
app.use(rawBody);
app.use(bodyParser());
app.use(bodyParser.raw());
app.get('/user', bitauth, function(req, res) {
if(!req.sin || !users[req.sin]) return res.send(401, {error: 'Unauthorized'});
res.send(200, users[req.sin]);
console.log('req.identity' , req.identity);
if(!req.identity || !users[req.identity]) return res.send(401, {error: 'Unauthorized'});
res.send(200, users[req.identity]);
});
app.post('/pizzas', bitauth, function(req, res) {
if(!req.sin || !users[req.sin]) return res.send(401, {error: 'Unauthorized'});
if(!req.identity || !users[req.identity]) return res.send(401, {error: 'Unauthorized'});
var pizza = req.body;
pizza.owner = users[req.sin].name;
pizza.owner = users[req.identity].name;
pizzas.push(pizza);
res.send(200, req.body);
});

View File

@ -1,9 +1,12 @@
'use strict';
// get base functionality
var bitauth = require('./lib/bitauth');
var BitAuth = require('./lib/bitauth');
var bitauth = new BitAuth();
// add node-specific encrypt/decrypt
bitauth.encrypt = require('./lib/encrypt');
bitauth.decrypt = require('./lib/decrypt');
bitauth.encrypt = require('./lib/encrypt');
bitauth.decrypt = require('./lib/decrypt');
bitauth.middleware = require('./lib/middleware/bitauth');
module.exports = bitauth;

View File

@ -1,76 +1,84 @@
var util = require('util');
var bitcore = require('bitcore');
var Key = bitcore.Key;
var SIN = bitcore.SIN;
var SINKey = bitcore.SINKey
var util = bitcore.util;
var Keypair = bitcore.Keypair;
var Privkey = bitcore.Privkey;
var Identity = bitcore.Identity;
var Message = bitcore.Message;
var Hash = bitcore.Hash;
var BitAuth = {};
BitAuth.generateSin = function() {
var sk = new SINKey();
sk.generate();
return sk.storeObj();
var BitAuth = function() {
this._identity = null;
this._keypair = null;
};
BitAuth.getPublicKeyFromPrivateKey = function(privkey) {
try {
var key = new Key();
BitAuth.prototype.generateIdentity = function( keypair ) {
var self = this;
if (!keypair) var keypair = new Keypair().fromRandom();
key.private = new Buffer(privkey, 'hex');
key.regenerateSync();
self._keypair = keypair;
self._identity = new Identity().fromPubkey( self._keypair.pubkey );
return key.public.toString('hex');
} catch (err) {
console.log(err);
return null;
}
return self;
};
BitAuth.getSinFromPublicKey = function(pubkey) {
var pubkeyHash = util.sha256ripe160(new Buffer(pubkey, 'hex'));
var sin = new SIN(SIN.SIN_EPHEM, pubkeyHash);
return sin.toString();
}
BitAuth.sign = function(data, privkey) {
var hash = util.sha256(data);
try {
var key = new Key();
key.private = new Buffer(privkey, 'hex');
return key.signSync(hash).toString('hex');
} catch (err) {
console.log(err.stack);
console.log(err);
return null;
}
BitAuth.prototype.sign = function(data, privkey) {
var self = this;
var signature = Message.sign( new Buffer( data ) , privkey );
return signature;
};
BitAuth.verifySignature = function(data, pubkey, signature, callback) {
var hash = util.sha256(data);
BitAuth.prototype.getIdentityFromPublicKey = function( pubkey ) {
var identity = new Identity( pubkey );
return identity.toString();
};
BitAuth.prototype.getPublicKeyFromPrivateKey = function( privkey ) {
var keypair = Keypair().fromString( JSON.stringify({ privkey : privkey }) );
return keypair.pubkey.toString();
};
BitAuth.prototype.getPublicKeyFromIdentity = function( identity ) {
var identity = Identity().fromString( identity );
console.log('pubkeyfromident, ident:' , identity );
return identity.toPubkey();
};
BitAuth.prototype.verifySignature = function(data, identity, signature, callback) {
var self = this;
console.log('verifySignature', identity , signature );
var pubkey = self.getPublicKeyFromIdentity( identity );
console.log('pubkey', pubkey );
var messageBuffer = new Buffer( data );
var signature = Message.sign( messageBuffer , identity._keypair );
console.log('verifySig', identity);
try {
var key = new Key();
key.public = new Buffer(pubkey, 'hex');
key.verifySignature(hash, new Buffer(signature, 'hex'), callback);
Message.verify( messageBuffer , signature , identity );
callback();
} catch (err) {
callback(err, false);
}
};
BitAuth.validateSin = function(sin, callback) {
var s = new SIN(sin);
BitAuth.prototype.validateIdentity = function( identity , callback ) {
var s = new Identity( identity );
try {
s.validate()
s.validate();
callback();
} catch(err) {
if ( callback )
callback(err);
return false;
callback(err);
}
if ( callback )
callback(null);
return true;
};
module.exports = BitAuth;

View File

@ -1,21 +1,25 @@
var bitauth = require('../bitauth');
var BitAuth = require('../bitauth');
var bitauth = new BitAuth();
var bitcore = require('bitcore');
var Identity = bitcore.Identity;
module.exports = function(req, res, next) {
if(req.headers && req.headers['x-identity'] && 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-identity'], 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-identity']);
if(!sin) return res.send(400, {error: 'Bad public key from identity'});
req.sin = sin;
// Get the Identity from the public key
var identity = bitauth.getIdentityFromPublicKey(req.headers['x-identity']);
if(!identity) return res.send(400, {error: 'Bad public key from identity'});
req.identity = identity;
next();
});
} else {

View File

@ -1,15 +1,11 @@
{
"name": "bitauth",
"description": "Passwordless authentication using Bitcoin cryptography",
"author": {
"name": "Patrick Nagurny",
"email": "patrick@bitpay.com"
},
"repository": {
"type": "git",
"url": "https://github.com/bitpay/bitauth.git"
"name": "BitPay",
"email": "dev@bitpay.com"
},
"repository": "https://github.com/bitpay/bitauth.git",
"contributors": [
{
"name": "Eric Martindale",
@ -18,6 +14,10 @@
{
"name": "Gordon Hall",
"email": "gordon@bitpay.com"
},
{
"name": "Patrick Nagurny",
"email": "patrick@bitpay.com"
}
],
"scripts": {
@ -26,14 +26,13 @@
"postinstall": "npm run make-dist"
},
"main": "index.js",
"version": "0.1.1",
"repository": "https://github.com/bitpay/bitauth.git",
"version": "0.2.0",
"dependencies": {
"bitcore": "0.1.32",
"request": "^2.36.0",
"express": "^4.3.1",
"base58-native": "^0.1.4",
"body-parser": "^1.2.0"
"bitcore": "bitcore",
"body-parser": "^1.2.0",
"express": "^4.3.1",
"request": "^2.36.0"
},
"devDependencies": {
"uglify-js": "~2.4.14",

View File

@ -5,22 +5,22 @@ var bitauth = require('../index');
describe('bitauth', function() {
var keys = null;
var sin = 'Tf1Jc1xSbqasm5QLwwSQc5umddx2h7mAMHX';
var sinb = 'Tf1Jc1xSbqasm5QLwwSQc5umddx2h7mAMhX';
var identity = 'Tf1Jc1xSbqasm5QLwwSQc5umddx2h7mAMHX';
var identityb = 'Tf1Jc1xSbqasm5QLwwSQc5umddx2h7mAMhX';
var contract = 'keyboard cat';
var secret = 'o hai, nsa. how i do teh cryptos?';
var password = 's4705hiru13z!';
var signature = null;
var enc = null;
describe('#generateSin', function() {
describe('#generateIdentity', function() {
it('should generate a sin object', function(done) {
keys = bitauth.generateSin();
it('should generate a identity object', function(done) {
keys = bitauth.generateIdentity()._keypair;
should.exist(keys);
should.exist(keys.pub);
should.exist(keys.priv);
should.exist(keys.sin);
should.exist(keys._keypair.pubkey);
should.exist(keys._keypair.privkey);
should.exist(keys._identity);
done();
});
@ -35,10 +35,10 @@ describe('bitauth', function() {
});
describe('#getSinFromPublicKey', function() {
describe('#getIdentityFromPublicKey', function() {
it('should properly get the sin', function(done) {
bitauth.getSinFromPublicKey(keys.pub).should.equal(keys.sin);
it('should properly get the identity', function(done) {
bitauth.getIdentityFromPublicKey(keys.pub).should.equal(keys.identity);
done();
});
@ -62,31 +62,31 @@ describe('bitauth', function() {
});
describe('#validateSinTrue', function() {
describe('#validateIdentityTrue', function() {
it('should validate the sin as true', function(done) {
var valid = bitauth.validateSin(sin);
it('should validate the identity as true', function(done) {
var valid = bitauth.validateIdentity(identity);
should.equal(true, valid);
done();
});
});
describe('#validateSinFalse', function() {
describe('#validateIdentityFalse', function() {
it('should validate the sin as false', function(done) {
var valid = bitauth.validateSin(sinb);
it('should validate the identity as false', function(done) {
var valid = bitauth.validateIdentity(identityb);
should.equal(false, valid);
done();
});
});
describe('#validateSinCallback', function() {
describe('#validateIdentityCallback', function() {
var received;
var valid = bitauth.validateSin(sinb, function(err){
var valid = bitauth.validateIdentity(identityb, function(err){
if ( err && typeof(err) == 'object' ) {
received = true;
}