@ -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"}' |