@ -0,0 +1 @@ |
|||||
|
keys.json |
@ -0,0 +1,3 @@ |
|||||
|
{ |
||||
|
"directory": "bower_components" |
||||
|
} |
@ -0,0 +1,2 @@ |
|||||
|
bower_components |
||||
|
node_modules |
@ -0,0 +1,84 @@ |
|||||
|
'use strict'; |
||||
|
|
||||
|
var urlapi = "http://127.0.0.1:3130/"; |
||||
|
var clientapi = "http://127.0.0.1:4100/"; |
||||
|
|
||||
|
// Declare app level module which depends on views, and components
|
||||
|
angular.module('app', [ |
||||
|
'ngRoute', |
||||
|
'ngMessages', |
||||
|
'angularBootstrapMaterial', |
||||
|
'ui.bootstrap', |
||||
|
'toastr', |
||||
|
'app.navbar', |
||||
|
'app.main', |
||||
|
'app.signup', |
||||
|
'app.login' |
||||
|
]). |
||||
|
config(['$locationProvider', '$routeProvider', function($locationProvider, $routeProvider) { |
||||
|
$locationProvider.hashPrefix('!'); |
||||
|
|
||||
|
if ((localStorage.getItem('blid_token'))) { |
||||
|
console.log(window.location.hash); |
||||
|
if ((window.location.hash === '#!/login') || (window.location.hash === '#!/signup')) { |
||||
|
window.location = '#!/main'; |
||||
|
} |
||||
|
|
||||
|
$routeProvider.otherwise({ |
||||
|
redirectTo: '/main' |
||||
|
}); |
||||
|
} else { |
||||
|
if ((window.location !== '#!/login') || (window.location !== '#!/signup')) { |
||||
|
console.log('app, user no logged'); |
||||
|
|
||||
|
localStorage.removeItem('blid_token'); |
||||
|
localStorage.removeItem('blid_userdata'); |
||||
|
window.location = '#!/login'; |
||||
|
$routeProvider.otherwise({ |
||||
|
redirectTo: '/login' |
||||
|
}); |
||||
|
} |
||||
|
} |
||||
|
}]) |
||||
|
.config(function(toastrConfig) { |
||||
|
angular.extend(toastrConfig, { |
||||
|
autoDismiss: false, |
||||
|
containerId: 'toast-container', |
||||
|
maxOpened: 0, |
||||
|
newestOnTop: true, |
||||
|
positionClass: 'toast-bottom-right', |
||||
|
preventDuplicates: false, |
||||
|
preventOpenDuplicates: false, |
||||
|
target: 'body' |
||||
|
}); |
||||
|
}) |
||||
|
.factory('httpInterceptor', function httpInterceptor() { |
||||
|
return { |
||||
|
request: function(config) { |
||||
|
return config; |
||||
|
}, |
||||
|
|
||||
|
requestError: function(config) { |
||||
|
return config; |
||||
|
}, |
||||
|
|
||||
|
response: function(res) { |
||||
|
return res; |
||||
|
}, |
||||
|
|
||||
|
responseError: function(res) { |
||||
|
return res; |
||||
|
} |
||||
|
}; |
||||
|
}) |
||||
|
.factory('api', function($http) { |
||||
|
return { |
||||
|
init: function() { |
||||
|
/*$http.defaults.headers.common['X-Access-Token'] = localStorage.getItem('block_webapp_token'); |
||||
|
$http.defaults.headers.post['X-Access-Token'] = localStorage.getItem('block_webapp_token');*/ |
||||
|
} |
||||
|
}; |
||||
|
}) |
||||
|
.run(function(api) { |
||||
|
api.init(); |
||||
|
}); |
@ -0,0 +1,18 @@ |
|||||
|
{ |
||||
|
"name": "angular-seed", |
||||
|
"description": "A starter project for AngularJS", |
||||
|
"version": "0.0.0", |
||||
|
"homepage": "", |
||||
|
"license": "MIT", |
||||
|
"private": true, |
||||
|
"dependencies": { |
||||
|
"angular": "^1.6.2", |
||||
|
"angular-route": "^1.6.1", |
||||
|
"angular-messages": "^1.6.5", |
||||
|
"angular-bootstrap-material": "abm#^0.1.4", |
||||
|
"angular-bootstrap": "^2.5.0", |
||||
|
"components-font-awesome": "^4.7.0", |
||||
|
"angular-toastr": "^2.1.1", |
||||
|
"cssMaterialColors": "*" |
||||
|
} |
||||
|
} |
@ -0,0 +1,9 @@ |
|||||
|
body { |
||||
|
background: #000000!important; |
||||
|
color: #ffffff!important; |
||||
|
} |
||||
|
.card { |
||||
|
background: #000000!important; |
||||
|
color: #ffffff!important; |
||||
|
border: 1px solid #ffffff!important; |
||||
|
} |
@ -0,0 +1 @@ |
|||||
|
|
@ -0,0 +1,69 @@ |
|||||
|
<!DOCTYPE html> |
||||
|
<html lang="en" ng-app="app" ng-cloak> |
||||
|
|
||||
|
<head> |
||||
|
<meta charset="utf-8"> |
||||
|
<title>blockchainIDsystem</title> |
||||
|
<meta name="viewport" content="width=device-width, initial-scale=1"> |
||||
|
|
||||
|
<link rel="icon" type="image/png" href="img/blockchainIDsystem-logo-black.png"> |
||||
|
|
||||
|
<link rel="stylesheet" href="bower_components/components-font-awesome/css/font-awesome.min.css"> |
||||
|
|
||||
|
<link rel="stylesheet" href="css/own.css"> |
||||
|
<link rel="stylesheet" href="css/bootstrapMaterial-dark-overwrite.css"> |
||||
|
|
||||
|
<link href="bower_components/cssMaterialColors/colors.css" rel="stylesheet"> |
||||
|
</head> |
||||
|
|
||||
|
<body ng-app="webapp"> |
||||
|
<div ng-include="'views/navbar.html'"></div> |
||||
|
<br><br><br><br><br> |
||||
|
<div ng-view></div> |
||||
|
|
||||
|
|
||||
|
|
||||
|
|
||||
|
|
||||
|
<!-- ELECTRON |
||||
|
Insert this line above script imports |
||||
|
Works for both browser and electron with the same code --> |
||||
|
<script>if (typeof module === 'object') {window.module = module; module = undefined;}</script> |
||||
|
|
||||
|
<!-- Angular js --> |
||||
|
<script src="bower_components/angular/angular.js"></script> |
||||
|
<script src="bower_components/angular-route/angular-route.js"></script> |
||||
|
<script src="bower_components/angular-messages/angular-messages.js"></script> |
||||
|
|
||||
|
|
||||
|
<!-- Bootstrap --> |
||||
|
<link rel="stylesheet" href="bower_components/bootstrap/dist/css/bootstrap.css"> |
||||
|
<!-- Bootstrap Material Design --> |
||||
|
<link rel="stylesheet" href="bower_components/bootstrap-material-design/dist/css/bootstrap-material-design.css"> |
||||
|
<link rel="stylesheet" href="bower_components/bootstrap-material-design/dist/css/ripples.css"> |
||||
|
|
||||
|
<script src="bower_components/angular-bootstrap/ui-bootstrap-tpls.js"></script> |
||||
|
<script src="bower_components/angular-bootstrap-material/dist/angular-bootstrap-material.js"></script> |
||||
|
|
||||
|
<!-- jQuery for Bootstrap --> |
||||
|
<script src="bower_components/jquery/dist/jquery.min.js"></script> |
||||
|
|
||||
|
<!-- toastr --> |
||||
|
<link rel="stylesheet" type="text/css" href="bower_components/angular-toastr/dist/angular-toastr.css" /> |
||||
|
<script type="text/javascript" src="bower_components/angular-toastr/dist/angular-toastr.tpls.js"></script> |
||||
|
|
||||
|
<!-- app's js --> |
||||
|
<script src="app.js"></script> |
||||
|
<script src="views/navbar.js"></script> |
||||
|
<script src="views/main/main.js"></script> |
||||
|
<script src="views/signup/signup.js"></script> |
||||
|
<script src="views/login/login.js"></script> |
||||
|
|
||||
|
|
||||
|
<!-- ELECTRON |
||||
|
Insert this line after script imports --> |
||||
|
<script>if (window.module) module = window.module;</script> |
||||
|
|
||||
|
</body> |
||||
|
|
||||
|
</html> |
@ -0,0 +1,72 @@ |
|||||
|
const electron = require('electron') |
||||
|
// Module to control application life.
|
||||
|
const app = electron.app |
||||
|
// Module to create native browser window.
|
||||
|
const BrowserWindow = electron.BrowserWindow |
||||
|
|
||||
|
const Tray = electron.Tray |
||||
|
const Menu = electron.Menu |
||||
|
|
||||
|
// Keep a global reference of the window object, if you don't, the window will
|
||||
|
// be closed automatically when the JavaScript object is garbage collected.
|
||||
|
let mainWindow |
||||
|
|
||||
|
|
||||
|
function createWindow () { |
||||
|
// Create the browser window.
|
||||
|
mainWindow = new BrowserWindow({ |
||||
|
width: 850, |
||||
|
height: 600, |
||||
|
icon: 'icon.png' |
||||
|
}) |
||||
|
tray = new Tray('icon.png') |
||||
|
const contextMenu = Menu.buildFromTemplate([ |
||||
|
{label: 'Obre la finestra', type: 'radio'}, |
||||
|
{label: 'javascript madness', type: 'radio'}, |
||||
|
{label: 'Tanca', type: 'radio'} |
||||
|
//{label: 'Tanca', type: 'radio', checked: true}
|
||||
|
]) |
||||
|
tray.setToolTip('Panopticon, projectNSA') |
||||
|
tray.setContextMenu(contextMenu) |
||||
|
|
||||
|
//mainWindow.setMenu(null);
|
||||
|
|
||||
|
// and load the index.html of the app.
|
||||
|
mainWindow.loadURL(`file://${__dirname}/index.html`) |
||||
|
|
||||
|
// Open the DevTools.
|
||||
|
//mainWindow.webContents.openDevTools()
|
||||
|
|
||||
|
// Emitted when the window is closed.
|
||||
|
mainWindow.on('closed', function () { |
||||
|
// Dereference the window object, usually you would store windows
|
||||
|
// in an array if your app supports multi windows, this is the time
|
||||
|
// when you should delete the corresponding element.
|
||||
|
mainWindow = null |
||||
|
}) |
||||
|
} |
||||
|
|
||||
|
// This method will be called when Electron has finished
|
||||
|
// initialization and is ready to create browser windows.
|
||||
|
// Some APIs can only be used after this event occurs.
|
||||
|
app.on('ready', createWindow) |
||||
|
|
||||
|
// Quit when all windows are closed.
|
||||
|
app.on('window-all-closed', function () { |
||||
|
// On OS X it is common for applications and their menu bar
|
||||
|
// to stay active until the user quits explicitly with Cmd + Q
|
||||
|
if (process.platform !== 'darwin') { |
||||
|
app.quit() |
||||
|
} |
||||
|
}) |
||||
|
|
||||
|
app.on('activate', function () { |
||||
|
// On OS X it's common to re-create a window in the app when the
|
||||
|
// dock icon is clicked and there are no other windows open.
|
||||
|
if (mainWindow === null) { |
||||
|
createWindow() |
||||
|
} |
||||
|
}) |
||||
|
|
||||
|
// In this file you can include the rest of your app's specific main process
|
||||
|
// code. You can also put them in separate files and require them here.
|
@ -0,0 +1,15 @@ |
|||||
|
{ |
||||
|
"name": "blockchainIDsystem-clientApp", |
||||
|
"version": "1.0.0", |
||||
|
"description": "frontend desktop app for blockchainIDsystem", |
||||
|
"main": "main.js", |
||||
|
"scripts": { |
||||
|
"postinstall": "bower install", |
||||
|
"prestart": "npm install", |
||||
|
"start": "electron ." |
||||
|
}, |
||||
|
"devDependencies": { |
||||
|
"electron-prebuilt": "^1.2.0" |
||||
|
}, |
||||
|
"license": "MIT" |
||||
|
} |
@ -0,0 +1,27 @@ |
|||||
|
<div class="container"> |
||||
|
<div class="row"> |
||||
|
<div class="col-sm-4"> |
||||
|
|
||||
|
</div> |
||||
|
<div class="col-sm-4"> |
||||
|
<div class="card"> |
||||
|
<div class="card-body"> |
||||
|
<h4 class="card-title"> |
||||
|
blockchainIDsystem |
||||
|
</h4> |
||||
|
|
||||
|
<input ng-model="user.email" class="form-control" placeholder="Email" type="text"> |
||||
|
<input ng-model="user.password" class="form-control" placeholder="Password" type="password"> |
||||
|
|
||||
|
|
||||
|
<div ng-click="login()" class="btn btn-raised c_indigo300 pull-right">Login</div> |
||||
|
</div> |
||||
|
</div> |
||||
|
</div> |
||||
|
|
||||
|
|
||||
|
<div class="col-sm-4"> |
||||
|
|
||||
|
</div> |
||||
|
</div> |
||||
|
</div> |
@ -0,0 +1,44 @@ |
|||||
|
'use strict'; |
||||
|
|
||||
|
angular.module('app.login', ['ngRoute']) |
||||
|
|
||||
|
.config(['$routeProvider', function($routeProvider) { |
||||
|
$routeProvider.when('/login', { |
||||
|
templateUrl: 'views/login/login.html', |
||||
|
controller: 'LoginCtrl' |
||||
|
}); |
||||
|
}]) |
||||
|
|
||||
|
.controller('LoginCtrl', function($scope, $http, $routeParams, toastr) { |
||||
|
$scope.user = {}; |
||||
|
$scope.login = function() { |
||||
|
console.log('Doing login', $scope.user); |
||||
|
console.log(urlapi + "login"); |
||||
|
$http({ |
||||
|
url: urlapi + 'login', |
||||
|
method: "POST", |
||||
|
headers: { |
||||
|
"Content-Type": undefined |
||||
|
}, |
||||
|
data: $scope.user |
||||
|
}) |
||||
|
.then(function(data) { |
||||
|
console.log("data: "); |
||||
|
console.log(data.data); |
||||
|
if (data.data.token) { |
||||
|
localStorage.setItem("blid_token", data.data.token); |
||||
|
localStorage.setItem("blid_user", JSON.stringify(data.data)); |
||||
|
window.location.reload(); |
||||
|
} else { |
||||
|
console.log("login failed"); |
||||
|
toastr.error('Login failed'); |
||||
|
} |
||||
|
|
||||
|
|
||||
|
}, |
||||
|
function(data) { |
||||
|
console.log(data); |
||||
|
}); |
||||
|
|
||||
|
}; |
||||
|
}); |
@ -0,0 +1,31 @@ |
|||||
|
<div class="container"> |
||||
|
<div class="row"> |
||||
|
<div class="col-sm-4"> |
||||
|
|
||||
|
</div> |
||||
|
<div class="col-sm-4"> |
||||
|
<div class="card"> |
||||
|
<div class="card-body"> |
||||
|
<h4 class="card-title"> |
||||
|
blockchainIDsystem |
||||
|
</h4> |
||||
|
|
||||
|
<div ng-click="newID()" class="btn btn-raised c_o_cyan300">Create new ID</div> |
||||
|
</div> |
||||
|
<hr> |
||||
|
<div class="card-body"> |
||||
|
<h4 class="card-title"> |
||||
|
Current IDs |
||||
|
</h4> |
||||
|
<p ng-repeat="id in ids"> |
||||
|
{{id}} <div ng-click="" class="btn btn-raised c_o_indigo300">Verify</div> |
||||
|
</p> |
||||
|
</div> |
||||
|
</div> |
||||
|
</div> |
||||
|
<div class="col-sm-4"> |
||||
|
|
||||
|
</div> |
||||
|
|
||||
|
</div> |
||||
|
</div> |
@ -0,0 +1,35 @@ |
|||||
|
'use strict'; |
||||
|
|
||||
|
angular.module('app.main', ['ngRoute']) |
||||
|
|
||||
|
.config(['$routeProvider', function($routeProvider) { |
||||
|
$routeProvider.when('/main', { |
||||
|
templateUrl: 'views/main/main.html', |
||||
|
controller: 'MainCtrl' |
||||
|
}); |
||||
|
}]) |
||||
|
|
||||
|
.controller('MainCtrl', function($scope, $http) { |
||||
|
$scope.ids = []; |
||||
|
$http.get(clientapi + 'ids') |
||||
|
.then(function(data) { |
||||
|
console.log('data success'); |
||||
|
console.log(data); |
||||
|
$scope.ids = data.data; |
||||
|
|
||||
|
}, function(data) { |
||||
|
console.log('data error'); |
||||
|
}); |
||||
|
|
||||
|
$scope.newID = function() { |
||||
|
$http.get(clientapi + 'newid') |
||||
|
.then(function(data) { |
||||
|
console.log('data success'); |
||||
|
console.log(data); |
||||
|
$scope.ids = data.data; |
||||
|
|
||||
|
}, function(data) { |
||||
|
console.log('data error'); |
||||
|
}); |
||||
|
}; |
||||
|
}); |
@ -0,0 +1,30 @@ |
|||||
|
<div ng-controller="NavbarCtrl" ng-show="user"> |
||||
|
<nav class="navbar navbar-fixed-top c_cyanG500to300"> |
||||
|
<div class="container-fluid"> |
||||
|
<div class="navbar-header"> |
||||
|
<button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-responsive-collapse"> |
||||
|
<span class="icon-bar"></span> |
||||
|
<span class="icon-bar"></span> |
||||
|
<span class="icon-bar"></span> |
||||
|
</button> |
||||
|
<a class="navbar-brand" href="/" title="blockchainIDsystem"> |
||||
|
<img src="img/blockchainIDsystem-logo-white.png" style="width:30px;height:30px;display:inline;" alt=""> <b>blockchainIDsystem</b> |
||||
|
</a> |
||||
|
</div> |
||||
|
<div class="navbar-collapse collapse navbar-responsive-collapse"> |
||||
|
<ul class="nav navbar-nav navbar-right"> |
||||
|
<li> |
||||
|
<a href=""> |
||||
|
<i title="User" class="fa fa-user fa-1x"></i> {{user.email}} |
||||
|
</a> |
||||
|
</li> |
||||
|
<li> |
||||
|
<a href="" ng-click="logout()"> |
||||
|
<i title="Exit" class="fa fa-power-off fa-1x"></i> |
||||
|
</a> |
||||
|
</li> |
||||
|
</ul> |
||||
|
</div> |
||||
|
</div> |
||||
|
</nav> |
||||
|
</div> |
@ -0,0 +1,22 @@ |
|||||
|
'use strict'; |
||||
|
|
||||
|
angular.module('app.navbar', ['ngRoute']) |
||||
|
|
||||
|
.config(['$routeProvider', function($routeProvider) { |
||||
|
$routeProvider.when('/navbar', { |
||||
|
templateUrl: 'views/navbar.html', |
||||
|
controller: 'NavbarCtrl' |
||||
|
}); |
||||
|
}]) |
||||
|
|
||||
|
.controller('NavbarCtrl', function($scope, $http, $routeParams, $location) { |
||||
|
|
||||
|
$scope.user = JSON.parse(localStorage.getItem("blid_user")); |
||||
|
|
||||
|
$scope.logout = function() { |
||||
|
localStorage.removeItem("blid_token"); |
||||
|
localStorage.removeItem("blid_user"); |
||||
|
window.location.reload(); |
||||
|
}; |
||||
|
|
||||
|
}); |
@ -0,0 +1,41 @@ |
|||||
|
<div class="container"> |
||||
|
<div class="row"> |
||||
|
<div class="col-sm-4"> |
||||
|
|
||||
|
</div> |
||||
|
<div class="col-sm-4"> |
||||
|
<div class="panel"> |
||||
|
<div class="panel-heading c_deepPurpleG500to300"> |
||||
|
<h3 class="panel-title">Signup</h3> |
||||
|
</div> |
||||
|
<div class="panel-body"> |
||||
|
<div class="form-group label-floating"> |
||||
|
<input ng-model="user.username" abmFormControl class="form-control" id="inputUsername" placeholder="Username" type="text"> |
||||
|
</div> |
||||
|
<div class="form-group"> |
||||
|
<input ng-model="user.password" abmFormControl class="form-control" id="inputPassword" placeholder="Password" type="password"> |
||||
|
</div> |
||||
|
<div class="form-group label-floating"> |
||||
|
<input ng-model="user.email" abmFormControl class="form-control" id="inputEmail" placeholder="Email" type="text"> |
||||
|
</div> |
||||
|
<div class="form-group label-floating"> |
||||
|
<input ng-model="user.phone" abmFormControl class="form-control" id="inputPhone" placeholder="Phone" type="text"> |
||||
|
</div> |
||||
|
<div class="form-group row"> |
||||
|
<label for="staticEmail" class="col-sm-1 col-form-label">@</label> |
||||
|
<div class="col-sm-10"> |
||||
|
<input ng-model="user.telegram" abmFormControl class="form-control" id="inputTelegram" placeholder="Telegram" type="text"> |
||||
|
</div> |
||||
|
</div> |
||||
|
<a ng-href="#!/login" class="btn btn-raised c_grey500">Back</a> |
||||
|
<div ng-click="doSignup()" class="btn btn-raised c_deepPurple300 pull-right">Signup</div> |
||||
|
</div> |
||||
|
</div> |
||||
|
</div> |
||||
|
|
||||
|
|
||||
|
<div class="col-sm-4"> |
||||
|
|
||||
|
</div> |
||||
|
</div> |
||||
|
</div> |
@ -0,0 +1,43 @@ |
|||||
|
'use strict'; |
||||
|
|
||||
|
angular.module('app.signup', ['ngRoute']) |
||||
|
|
||||
|
.config(['$routeProvider', function($routeProvider) { |
||||
|
$routeProvider.when('/signup', { |
||||
|
templateUrl: 'views/signup/signup.html', |
||||
|
controller: 'SignupCtrl' |
||||
|
}); |
||||
|
}]) |
||||
|
|
||||
|
.controller('SignupCtrl', function($scope, $http, $routeParams) { |
||||
|
$scope.user = {}; |
||||
|
$scope.doSignup = function() { |
||||
|
console.log('Doing login', $scope.user); |
||||
|
|
||||
|
$http({ |
||||
|
url: urlapi + 'signup', |
||||
|
method: "POST", |
||||
|
data: $scope.user |
||||
|
}) |
||||
|
.then(function(response) { |
||||
|
console.log("response: "); |
||||
|
console.log(response.data); |
||||
|
if (response.data.success == true) |
||||
|
{ |
||||
|
localStorage.setItem("cr_webapp_token", response.data.token); |
||||
|
localStorage.setItem("cr_webapp_userdata", JSON.stringify(response.data.user)); |
||||
|
window.location.reload(); |
||||
|
}else{ |
||||
|
console.log("signup failed"); |
||||
|
toastr.error('Signup failed'); |
||||
|
} |
||||
|
|
||||
|
|
||||
|
}, |
||||
|
function(response) { // optional
|
||||
|
// failed
|
||||
|
console.log(response); |
||||
|
}); |
||||
|
|
||||
|
}; |
||||
|
}); |
@ -0,0 +1,5 @@ |
|||||
|
# serverIDsign |
||||
|
|
||||
|
- The server where the user creates a non anonymous account |
||||
|
- Also is the server that blind signs the Anonymous ID of the users |
||||
|
- Have the webapp (frontend) to interact through a GUI interface |
@ -0,0 +1,42 @@ |
|||||
|
package main |
||||
|
|
||||
|
import ( |
||||
|
"encoding/json" |
||||
|
"fmt" |
||||
|
"net/http" |
||||
|
|
||||
|
ownrsa "./ownrsa" |
||||
|
) |
||||
|
|
||||
|
//generate key pair
|
||||
|
//blind m
|
||||
|
//unblind m
|
||||
|
|
||||
|
func Index(w http.ResponseWriter, r *http.Request) { |
||||
|
fmt.Fprintln(w, "serverIDsigner") |
||||
|
} |
||||
|
|
||||
|
func IDs(w http.ResponseWriter, r *http.Request) { |
||||
|
//read the keys stored in /keys directory
|
||||
|
keys := readKeys("keys.json") |
||||
|
saveKeys(keys, "keys.json") |
||||
|
|
||||
|
jResp, err := json.Marshal(keys) |
||||
|
check(err) |
||||
|
fmt.Fprintln(w, string(jResp)) |
||||
|
} |
||||
|
func NewID(w http.ResponseWriter, r *http.Request) { |
||||
|
//generate RSA keys pair
|
||||
|
newKey := ownrsa.GenerateKeyPair() |
||||
|
|
||||
|
key := ownrsa.PackKey(newKey) |
||||
|
fmt.Println(key) |
||||
|
|
||||
|
keys := readKeys("keys.json") |
||||
|
keys = append(keys, key) |
||||
|
saveKeys(keys, "keys.json") |
||||
|
|
||||
|
jResp, err := json.Marshal(keys) |
||||
|
check(err) |
||||
|
fmt.Fprintln(w, string(jResp)) |
||||
|
} |
@ -0,0 +1,4 @@ |
|||||
|
{ |
||||
|
"port": "4100", |
||||
|
"keysDirectory": "keys" |
||||
|
} |
@ -0,0 +1,15 @@ |
|||||
|
package main |
||||
|
|
||||
|
import ( |
||||
|
"log" |
||||
|
"runtime" |
||||
|
) |
||||
|
|
||||
|
func check(err error) { |
||||
|
if err != nil { |
||||
|
_, fn, line, _ := runtime.Caller(1) |
||||
|
log.Println(line) |
||||
|
log.Println(fn) |
||||
|
log.Println(err) |
||||
|
} |
||||
|
} |
@ -0,0 +1,26 @@ |
|||||
|
package main |
||||
|
|
||||
|
import ( |
||||
|
"encoding/json" |
||||
|
"io/ioutil" |
||||
|
|
||||
|
ownrsa "./ownrsa" |
||||
|
) |
||||
|
|
||||
|
func readKeys(path string) []ownrsa.PackRSA { |
||||
|
var keys []ownrsa.PackRSA |
||||
|
|
||||
|
file, err := ioutil.ReadFile(path) |
||||
|
check(err) |
||||
|
content := string(file) |
||||
|
json.Unmarshal([]byte(content), &keys) |
||||
|
|
||||
|
return keys |
||||
|
} |
||||
|
|
||||
|
func saveKeys(keys []ownrsa.PackRSA, path string) { |
||||
|
jsonKeys, err := json.Marshal(keys) |
||||
|
check(err) |
||||
|
err = ioutil.WriteFile(path, jsonKeys, 0644) |
||||
|
check(err) |
||||
|
} |
@ -0,0 +1,24 @@ |
|||||
|
package main |
||||
|
|
||||
|
import ( |
||||
|
"io" |
||||
|
"log" |
||||
|
"os" |
||||
|
"strings" |
||||
|
"time" |
||||
|
) |
||||
|
|
||||
|
func savelog() { |
||||
|
timeS := time.Now().String() |
||||
|
_ = os.Mkdir("logs", os.ModePerm) |
||||
|
//next 3 lines are to avoid windows filesystem errors
|
||||
|
timeS = strings.Replace(timeS, " ", "_", -1) |
||||
|
timeS = strings.Replace(timeS, ".", "-", -1) |
||||
|
timeS = strings.Replace(timeS, ":", "-", -1) |
||||
|
logFile, err := os.OpenFile("logs/log-"+timeS+".log", os.O_CREATE|os.O_APPEND|os.O_RDWR, 0666) |
||||
|
if err != nil { |
||||
|
panic(err) |
||||
|
} |
||||
|
mw := io.MultiWriter(os.Stdout, logFile) |
||||
|
log.SetOutput(mw) |
||||
|
} |
@ -0,0 +1,32 @@ |
|||||
|
package main |
||||
|
|
||||
|
import ( |
||||
|
"log" |
||||
|
"net/http" |
||||
|
|
||||
|
"github.com/fatih/color" |
||||
|
"github.com/gorilla/handlers" |
||||
|
) |
||||
|
|
||||
|
func main() { |
||||
|
color.Blue("Starting blockchainIDsystem clientApp") |
||||
|
|
||||
|
readConfig("config.json") |
||||
|
|
||||
|
//run thw webserver
|
||||
|
go GUI() |
||||
|
|
||||
|
//run API
|
||||
|
log.Println("api server running") |
||||
|
log.Print("port: ") |
||||
|
log.Println(config.Port) |
||||
|
router := NewRouter() |
||||
|
headersOk := handlers.AllowedHeaders([]string{"X-Requested-With", "Access-Control-Allow-Origin"}) |
||||
|
originsOk := handlers.AllowedOrigins([]string{"*"}) |
||||
|
methodsOk := handlers.AllowedMethods([]string{"GET", "HEAD", "POST", "PUT", "OPTIONS"}) |
||||
|
log.Fatal(http.ListenAndServe(":"+config.Port, handlers.CORS(originsOk, headersOk, methodsOk)(router))) |
||||
|
} |
||||
|
|
||||
|
func GUI() { |
||||
|
//here, run electron app
|
||||
|
} |
@ -0,0 +1,54 @@ |
|||||
|
package ownrsa |
||||
|
|
||||
|
import "math/rand" |
||||
|
|
||||
|
func randInt(min int, max int) int { |
||||
|
r := rand.Intn(max-min) + min |
||||
|
return r |
||||
|
} |
||||
|
func randPrime(min int, max int) int { |
||||
|
primes := sieveOfEratosthenes(max) |
||||
|
|
||||
|
randN := rand.Intn(len(primes)-0) + 0 |
||||
|
|
||||
|
return primes[randN] |
||||
|
|
||||
|
} |
||||
|
|
||||
|
// return list of primes less than N
|
||||
|
func sieveOfEratosthenes(N int) (primes []int) { |
||||
|
b := make([]bool, N) |
||||
|
for i := 2; i < N; i++ { |
||||
|
if b[i] == true { |
||||
|
continue |
||||
|
} |
||||
|
primes = append(primes, i) |
||||
|
for k := i * i; k < N; k += i { |
||||
|
b[k] = true |
||||
|
} |
||||
|
} |
||||
|
return |
||||
|
} |
||||
|
|
||||
|
func gcd(a, b int) int { |
||||
|
var bgcd func(a, b, res int) int |
||||
|
|
||||
|
bgcd = func(a, b, res int) int { |
||||
|
switch { |
||||
|
case a == b: |
||||
|
return res * a |
||||
|
case a%2 == 0 && b%2 == 0: |
||||
|
return bgcd(a/2, b/2, 2*res) |
||||
|
case a%2 == 0: |
||||
|
return bgcd(a/2, b, res) |
||||
|
case b%2 == 0: |
||||
|
return bgcd(a, b/2, res) |
||||
|
case a > b: |
||||
|
return bgcd(a-b, b, res) |
||||
|
default: |
||||
|
return bgcd(a, b-a, res) |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
return bgcd(a, b, 1) |
||||
|
} |
@ -0,0 +1,209 @@ |
|||||
|
package ownrsa |
||||
|
|
||||
|
import ( |
||||
|
"errors" |
||||
|
"fmt" |
||||
|
"math/big" |
||||
|
"math/rand" |
||||
|
"strings" |
||||
|
"time" |
||||
|
) |
||||
|
|
||||
|
type RSAPublicKey struct { |
||||
|
E *big.Int `json:"e"` |
||||
|
N *big.Int `json:"n"` |
||||
|
} |
||||
|
type RSAPublicKeyString struct { |
||||
|
E string `json:"e"` |
||||
|
N string `json:"n"` |
||||
|
} |
||||
|
type RSAPrivateKey struct { |
||||
|
D *big.Int `json:"d"` |
||||
|
N *big.Int `json:"n"` |
||||
|
} |
||||
|
|
||||
|
type RSA struct { |
||||
|
PubK RSAPublicKey |
||||
|
PrivK RSAPrivateKey |
||||
|
} |
||||
|
|
||||
|
const maxPrime = 500 |
||||
|
const minPrime = 100 |
||||
|
|
||||
|
func GenerateKeyPair() RSA { |
||||
|
|
||||
|
rand.Seed(time.Now().Unix()) |
||||
|
p := randPrime(minPrime, maxPrime) |
||||
|
q := randPrime(minPrime, maxPrime) |
||||
|
fmt.Print("p:") |
||||
|
fmt.Println(p) |
||||
|
fmt.Print("q:") |
||||
|
fmt.Println(q) |
||||
|
|
||||
|
n := p * q |
||||
|
phi := (p - 1) * (q - 1) |
||||
|
e := 65537 |
||||
|
var pubK RSAPublicKey |
||||
|
pubK.E = big.NewInt(int64(e)) |
||||
|
pubK.N = big.NewInt(int64(n)) |
||||
|
|
||||
|
d := new(big.Int).ModInverse(big.NewInt(int64(e)), big.NewInt(int64(phi))) |
||||
|
|
||||
|
var privK RSAPrivateKey |
||||
|
privK.D = d |
||||
|
privK.N = big.NewInt(int64(n)) |
||||
|
|
||||
|
var rsa RSA |
||||
|
rsa.PubK = pubK |
||||
|
rsa.PrivK = privK |
||||
|
return rsa |
||||
|
} |
||||
|
func Encrypt(m string, pubK RSAPublicKey) []int { |
||||
|
var c []int |
||||
|
mBytes := []byte(m) |
||||
|
for _, byte := range mBytes { |
||||
|
c = append(c, EncryptInt(int(byte), pubK)) |
||||
|
} |
||||
|
return c |
||||
|
} |
||||
|
func Decrypt(c []int, privK RSAPrivateKey) string { |
||||
|
var m string |
||||
|
var mBytes []byte |
||||
|
for _, indC := range c { |
||||
|
mBytes = append(mBytes, byte(DecryptInt(indC, privK))) |
||||
|
} |
||||
|
m = string(mBytes) |
||||
|
return m |
||||
|
} |
||||
|
|
||||
|
func EncryptBigInt(bigint *big.Int, pubK RSAPublicKey) *big.Int { |
||||
|
Me := new(big.Int).Exp(bigint, pubK.E, nil) |
||||
|
c := new(big.Int).Mod(Me, pubK.N) |
||||
|
return c |
||||
|
} |
||||
|
func DecryptBigInt(bigint *big.Int, privK RSAPrivateKey) *big.Int { |
||||
|
Cd := new(big.Int).Exp(bigint, privK.D, nil) |
||||
|
m := new(big.Int).Mod(Cd, privK.N) |
||||
|
return m |
||||
|
} |
||||
|
|
||||
|
func EncryptInt(char int, pubK RSAPublicKey) int { |
||||
|
charBig := big.NewInt(int64(char)) |
||||
|
Me := charBig.Exp(charBig, pubK.E, nil) |
||||
|
c := Me.Mod(Me, pubK.N) |
||||
|
return int(c.Int64()) |
||||
|
} |
||||
|
func DecryptInt(val int, privK RSAPrivateKey) int { |
||||
|
valBig := big.NewInt(int64(val)) |
||||
|
Cd := valBig.Exp(valBig, privK.D, nil) |
||||
|
m := Cd.Mod(Cd, privK.N) |
||||
|
return int(m.Int64()) |
||||
|
} |
||||
|
|
||||
|
func Blind(m []int, r int, pubK RSAPublicKey, privK RSAPrivateKey) []int { |
||||
|
var mBlinded []int |
||||
|
rBigInt := big.NewInt(int64(r)) |
||||
|
for i := 0; i < len(m); i++ { |
||||
|
mBigInt := big.NewInt(int64(m[i])) |
||||
|
rE := new(big.Int).Exp(rBigInt, pubK.E, nil) |
||||
|
mrE := new(big.Int).Mul(mBigInt, rE) |
||||
|
mrEmodN := new(big.Int).Mod(mrE, privK.N) |
||||
|
mBlinded = append(mBlinded, int(mrEmodN.Int64())) |
||||
|
} |
||||
|
return mBlinded |
||||
|
} |
||||
|
|
||||
|
func BlindSign(m []int, pubK RSAPublicKey, privK RSAPrivateKey) []int { |
||||
|
var r []int |
||||
|
for i := 0; i < len(m); i++ { |
||||
|
mBigInt := big.NewInt(int64(m[i])) |
||||
|
sigma := new(big.Int).Exp(mBigInt, privK.D, pubK.N) |
||||
|
r = append(r, int(sigma.Int64())) |
||||
|
} |
||||
|
return r |
||||
|
} |
||||
|
func Unblind(blindsigned []int, r int, pubK RSAPublicKey) []int { |
||||
|
var mSigned []int |
||||
|
rBigInt := big.NewInt(int64(r)) |
||||
|
for i := 0; i < len(blindsigned); i++ { |
||||
|
bsBigInt := big.NewInt(int64(blindsigned[i])) |
||||
|
//r1 := new(big.Int).Exp(rBigInt, big.NewInt(int64(-1)), nil)
|
||||
|
r1 := new(big.Int).ModInverse(rBigInt, pubK.N) |
||||
|
bsr := new(big.Int).Mul(bsBigInt, r1) |
||||
|
sig := new(big.Int).Mod(bsr, pubK.N) |
||||
|
mSigned = append(mSigned, int(sig.Int64())) |
||||
|
} |
||||
|
return mSigned |
||||
|
} |
||||
|
func Verify(msg []int, mSigned []int, pubK RSAPublicKey) bool { |
||||
|
if len(msg) != len(mSigned) { |
||||
|
return false |
||||
|
} |
||||
|
var mSignedDecrypted []int |
||||
|
for _, ms := range mSigned { |
||||
|
msBig := big.NewInt(int64(ms)) |
||||
|
//decrypt the mSigned with pubK
|
||||
|
Cd := new(big.Int).Exp(msBig, pubK.E, nil) |
||||
|
m := new(big.Int).Mod(Cd, pubK.N) |
||||
|
mSignedDecrypted = append(mSignedDecrypted, int(m.Int64())) |
||||
|
} |
||||
|
fmt.Print("msg signed decrypted: ") |
||||
|
fmt.Println(mSignedDecrypted) |
||||
|
r := true |
||||
|
//check if the mSignedDecrypted == msg
|
||||
|
for i := 0; i < len(msg); i++ { |
||||
|
if msg[i] != mSignedDecrypted[i] { |
||||
|
r = false |
||||
|
} |
||||
|
} |
||||
|
return r |
||||
|
} |
||||
|
|
||||
|
func HomomorphicMultiplication(c1 int, c2 int, pubK RSAPublicKey) int { |
||||
|
c1BigInt := big.NewInt(int64(c1)) |
||||
|
c2BigInt := big.NewInt(int64(c2)) |
||||
|
c1c2 := new(big.Int).Mul(c1BigInt, c2BigInt) |
||||
|
n2 := new(big.Int).Mul(pubK.N, pubK.N) |
||||
|
d := new(big.Int).Mod(c1c2, n2) |
||||
|
r := int(d.Int64()) |
||||
|
return r |
||||
|
} |
||||
|
|
||||
|
func PubKStringToBigInt(kS RSAPublicKeyString) (RSAPublicKey, error) { |
||||
|
var k RSAPublicKey |
||||
|
var ok bool |
||||
|
k.E, ok = new(big.Int).SetString(kS.E, 10) |
||||
|
if !ok { |
||||
|
return k, errors.New("error parsing big int E") |
||||
|
} |
||||
|
k.N, ok = new(big.Int).SetString(kS.N, 10) |
||||
|
if !ok { |
||||
|
return k, errors.New("error parsing big int N") |
||||
|
} |
||||
|
return k, nil |
||||
|
} |
||||
|
|
||||
|
type PackRSA struct { |
||||
|
PubK string `json:"pubK"` |
||||
|
PrivK string `json:"privK"` |
||||
|
} |
||||
|
|
||||
|
func PackKey(k RSA) PackRSA { |
||||
|
var p PackRSA |
||||
|
p.PubK = k.PubK.E.String() + "," + k.PubK.N.String() |
||||
|
p.PrivK = k.PrivK.D.String() + "," + k.PrivK.N.String() |
||||
|
return p |
||||
|
} |
||||
|
|
||||
|
func UnpackKey(p PackRSA) RSA { |
||||
|
var k RSA |
||||
|
var ok bool |
||||
|
k.PubK.E, ok = new(big.Int).SetString(strings.Split(p.PubK, ",")[0], 10) |
||||
|
k.PubK.N, ok = new(big.Int).SetString(strings.Split(p.PubK, ",")[1], 10) |
||||
|
k.PrivK.D, ok = new(big.Int).SetString(strings.Split(p.PrivK, ",")[0], 10) |
||||
|
k.PrivK.N, ok = new(big.Int).SetString(strings.Split(p.PrivK, ",")[1], 10) |
||||
|
if !ok { |
||||
|
fmt.Println("error on Unpacking Keys") |
||||
|
} |
||||
|
return k |
||||
|
} |
@ -0,0 +1,21 @@ |
|||||
|
package main |
||||
|
|
||||
|
import ( |
||||
|
"encoding/json" |
||||
|
"io/ioutil" |
||||
|
) |
||||
|
|
||||
|
//Config reads the config
|
||||
|
type Config struct { |
||||
|
Port string `json:"port"` |
||||
|
KeysDirectory string `json:"keysDirectory"` |
||||
|
} |
||||
|
|
||||
|
var config Config |
||||
|
|
||||
|
func readConfig(path string) { |
||||
|
file, err := ioutil.ReadFile(path) |
||||
|
check(err) |
||||
|
content := string(file) |
||||
|
json.Unmarshal([]byte(content), &config) |
||||
|
} |
@ -0,0 +1,47 @@ |
|||||
|
package main |
||||
|
|
||||
|
import ( |
||||
|
"log" |
||||
|
"net/http" |
||||
|
"time" |
||||
|
|
||||
|
"github.com/gorilla/mux" |
||||
|
) |
||||
|
|
||||
|
type Route struct { |
||||
|
Name string |
||||
|
Method string |
||||
|
Pattern string |
||||
|
HandlerFunc http.HandlerFunc |
||||
|
} |
||||
|
|
||||
|
func Logger(inner http.Handler, name string) http.Handler { |
||||
|
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { |
||||
|
start := time.Now() |
||||
|
|
||||
|
inner.ServeHTTP(w, r) |
||||
|
|
||||
|
log.Printf( |
||||
|
"%s\t%s\t%s\t%s", |
||||
|
r.Method, |
||||
|
r.RequestURI, |
||||
|
name, |
||||
|
time.Since(start), |
||||
|
) |
||||
|
}) |
||||
|
} |
||||
|
func NewRouter() *mux.Router { |
||||
|
router := mux.NewRouter().StrictSlash(true) |
||||
|
for _, route := range routes { |
||||
|
var handler http.Handler |
||||
|
handler = route.HandlerFunc |
||||
|
handler = Logger(handler, route.Name) |
||||
|
|
||||
|
router. |
||||
|
Methods(route.Method). |
||||
|
Path(route.Pattern). |
||||
|
Name(route.Name). |
||||
|
Handler(handler) |
||||
|
} |
||||
|
return router |
||||
|
} |
@ -0,0 +1,24 @@ |
|||||
|
package main |
||||
|
|
||||
|
type Routes []Route |
||||
|
|
||||
|
var routes = Routes{ |
||||
|
Route{ |
||||
|
"Index", |
||||
|
"GET", |
||||
|
"/", |
||||
|
Index, |
||||
|
}, |
||||
|
Route{ |
||||
|
"IDs", |
||||
|
"GET", |
||||
|
"/ids", |
||||
|
IDs, |
||||
|
}, |
||||
|
Route{ |
||||
|
"NewID", |
||||
|
"GET", |
||||
|
"/newid", |
||||
|
NewID, |
||||
|
}, |
||||
|
} |
@ -0,0 +1,20 @@ |
|||||
|
echo "" |
||||
|
echo "sending the signup, response:" |
||||
|
curl -X POST http://127.0.0.1:3130/signup -d '{"email": "user1@e.com", "password": "user1"}' |
||||
|
|
||||
|
echo "" |
||||
|
echo "sending the login, response:" |
||||
|
curl -X POST http://127.0.0.1:3130/login -d '{"email": "user1@e.com", "password": "user1"}' |
||||
|
|
||||
|
|
||||
|
echo "" |
||||
|
echo "send pubK and m to blind sign" |
||||
|
echo "json to send to the serverIDsigner:" |
||||
|
echo '{"pubKstring": {"e": "65537", "n": "139093"}, "m": "hola"}' |
||||
|
echo "serverIDsigner response:" |
||||
|
BLINDSIGNED=$(curl -X POST http://127.0.0.1:3130/blindsign -d '{"pubKstring": {"e": "65537", "n": "139093"}, "m": "hola"}') |
||||
|
echo "$BLINDSIGNED" |
||||
|
|
||||
|
echo "" |
||||
|
echo "send blindsigned to the serverIDsigner to verify" |
||||
|
curl -X POST http://127.0.0.1:3130/verifysign -d '{"m": "hola", "mSigned": "131898 40373 107552 34687"}' |