From 92405b3a9088276f0b702243752657f13416c54f Mon Sep 17 00:00:00 2001 From: Eric Martindale Date: Mon, 6 Oct 2014 22:13:24 -0400 Subject: [PATCH] Begin work on converting to bitcore 0.8. --- examples/client.js | 43 ++++++++++++--- examples/server.js | 17 +++--- index.js | 9 ++- lib/bitauth.js | 112 ++++++++++++++++++++------------------ lib/middleware/bitauth.js | 18 +++--- package.json | 25 ++++----- test/bitauth.js | 38 ++++++------- 7 files changed, 152 insertions(+), 110 deletions(-) diff --git a/examples/client.js b/examples/client.js index ae678f0..62ada60 100644 --- a/examples/client.js +++ b/examples/client.js @@ -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 }; diff --git a/examples/server.js b/examples/server.js index cfa8e47..48ed3d1 100644 --- a/examples/server.js +++ b/examples/server.js @@ -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); }); diff --git a/index.js b/index.js index ac8a71e..6a54b80 100644 --- a/index.js +++ b/index.js @@ -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; diff --git a/lib/bitauth.js b/lib/bitauth.js index 3a6a886..3f331d1 100644 --- a/lib/bitauth.js +++ b/lib/bitauth.js @@ -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; diff --git a/lib/middleware/bitauth.js b/lib/middleware/bitauth.js index 7399e17..8c62abd 100644 --- a/lib/middleware/bitauth.js +++ b/lib/middleware/bitauth.js @@ -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 { diff --git a/package.json b/package.json index a214189..ec9f88d 100644 --- a/package.json +++ b/package.json @@ -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", diff --git a/test/bitauth.js b/test/bitauth.js index 384063b..0600418 100644 --- a/test/bitauth.js +++ b/test/bitauth.js @@ -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; }