From 91dc63ed96d0e1e7095700a69534a27bf96679ea Mon Sep 17 00:00:00 2001 From: arnaucode Date: Wed, 27 Dec 2017 20:25:03 +0100 Subject: [PATCH] started to implement clientApp (Go + Electron(with Angularjs)) --- clientApp/.gitignore | 1 + clientApp/GUI/.bowerrc | 3 + clientApp/GUI/.gitignore | 2 + clientApp/GUI/app.js | 84 +++++++ clientApp/GUI/bower.json | 18 ++ .../css/bootstrapMaterial-dark-overwrite.css | 9 + clientApp/GUI/css/own.css | 1 + .../GUI/img/blockchainIDsystem-logo-black.png | Bin 0 -> 16723 bytes .../GUI/img/blockchainIDsystem-logo-white.png | Bin 0 -> 17526 bytes clientApp/GUI/index.html | 69 ++++++ clientApp/GUI/main.js | 72 ++++++ clientApp/GUI/package.json | 15 ++ clientApp/GUI/views/login/login.html | 27 +++ clientApp/GUI/views/login/login.js | 44 ++++ clientApp/GUI/views/main/main.html | 31 +++ clientApp/GUI/views/main/main.js | 35 +++ clientApp/GUI/views/navbar.html | 30 +++ clientApp/GUI/views/navbar.js | 22 ++ clientApp/GUI/views/signup/signup.html | 41 ++++ clientApp/GUI/views/signup/signup.js | 43 ++++ clientApp/README.md | 5 + clientApp/clientAppRESTFunctions.go | 42 ++++ clientApp/config.json | 4 + clientApp/errors.go | 15 ++ clientApp/keys.go | 26 +++ clientApp/log.go | 24 ++ clientApp/main.go | 32 +++ clientApp/ownrsa/prime.go | 54 +++++ clientApp/ownrsa/rsa.go | 209 ++++++++++++++++++ clientApp/readConfig.go | 21 ++ clientApp/restConfig.go | 47 ++++ clientApp/restRoutes.go | 24 ++ clientApp/testUser.sh | 20 ++ serverIDsigner/main.go | 8 +- serverIDsigner/ownrsa/rsa.go | 26 +++ serverIDsigner/userRESTFunctions.go | 4 +- 36 files changed, 1102 insertions(+), 6 deletions(-) create mode 100644 clientApp/.gitignore create mode 100644 clientApp/GUI/.bowerrc create mode 100644 clientApp/GUI/.gitignore create mode 100644 clientApp/GUI/app.js create mode 100644 clientApp/GUI/bower.json create mode 100644 clientApp/GUI/css/bootstrapMaterial-dark-overwrite.css create mode 100644 clientApp/GUI/css/own.css create mode 100644 clientApp/GUI/img/blockchainIDsystem-logo-black.png create mode 100644 clientApp/GUI/img/blockchainIDsystem-logo-white.png create mode 100644 clientApp/GUI/index.html create mode 100644 clientApp/GUI/main.js create mode 100644 clientApp/GUI/package.json create mode 100755 clientApp/GUI/views/login/login.html create mode 100755 clientApp/GUI/views/login/login.js create mode 100755 clientApp/GUI/views/main/main.html create mode 100755 clientApp/GUI/views/main/main.js create mode 100755 clientApp/GUI/views/navbar.html create mode 100755 clientApp/GUI/views/navbar.js create mode 100755 clientApp/GUI/views/signup/signup.html create mode 100755 clientApp/GUI/views/signup/signup.js create mode 100644 clientApp/README.md create mode 100644 clientApp/clientAppRESTFunctions.go create mode 100755 clientApp/config.json create mode 100755 clientApp/errors.go create mode 100644 clientApp/keys.go create mode 100755 clientApp/log.go create mode 100644 clientApp/main.go create mode 100644 clientApp/ownrsa/prime.go create mode 100644 clientApp/ownrsa/rsa.go create mode 100755 clientApp/readConfig.go create mode 100755 clientApp/restConfig.go create mode 100755 clientApp/restRoutes.go create mode 100644 clientApp/testUser.sh diff --git a/clientApp/.gitignore b/clientApp/.gitignore new file mode 100644 index 0000000..34afe36 --- /dev/null +++ b/clientApp/.gitignore @@ -0,0 +1 @@ +keys.json diff --git a/clientApp/GUI/.bowerrc b/clientApp/GUI/.bowerrc new file mode 100644 index 0000000..baa91a3 --- /dev/null +++ b/clientApp/GUI/.bowerrc @@ -0,0 +1,3 @@ +{ + "directory": "bower_components" +} \ No newline at end of file diff --git a/clientApp/GUI/.gitignore b/clientApp/GUI/.gitignore new file mode 100644 index 0000000..7bf6eb1 --- /dev/null +++ b/clientApp/GUI/.gitignore @@ -0,0 +1,2 @@ +bower_components +node_modules diff --git a/clientApp/GUI/app.js b/clientApp/GUI/app.js new file mode 100644 index 0000000..78d5219 --- /dev/null +++ b/clientApp/GUI/app.js @@ -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(); + }); diff --git a/clientApp/GUI/bower.json b/clientApp/GUI/bower.json new file mode 100644 index 0000000..315b74d --- /dev/null +++ b/clientApp/GUI/bower.json @@ -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": "*" + } +} diff --git a/clientApp/GUI/css/bootstrapMaterial-dark-overwrite.css b/clientApp/GUI/css/bootstrapMaterial-dark-overwrite.css new file mode 100644 index 0000000..447b35a --- /dev/null +++ b/clientApp/GUI/css/bootstrapMaterial-dark-overwrite.css @@ -0,0 +1,9 @@ +body { + background: #000000!important; + color: #ffffff!important; +} +.card { + background: #000000!important; + color: #ffffff!important; + border: 1px solid #ffffff!important; +} diff --git a/clientApp/GUI/css/own.css b/clientApp/GUI/css/own.css new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/clientApp/GUI/css/own.css @@ -0,0 +1 @@ + diff --git a/clientApp/GUI/img/blockchainIDsystem-logo-black.png b/clientApp/GUI/img/blockchainIDsystem-logo-black.png new file mode 100644 index 0000000000000000000000000000000000000000..dc84861c15fbc5101d2c2fa3fbd386815dfdd4cd GIT binary patch literal 16723 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 CKR03k literal 0 HcmV?d00001 diff --git a/clientApp/GUI/index.html b/clientApp/GUI/index.html new file mode 100644 index 0000000..ba757bf --- /dev/null +++ b/clientApp/GUI/index.html @@ -0,0 +1,69 @@ + + + + + + blockchainIDsystem + + + + + + + + + + + + + +
+




+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/clientApp/GUI/main.js b/clientApp/GUI/main.js new file mode 100644 index 0000000..8c0fbf3 --- /dev/null +++ b/clientApp/GUI/main.js @@ -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. diff --git a/clientApp/GUI/package.json b/clientApp/GUI/package.json new file mode 100644 index 0000000..ec6fd96 --- /dev/null +++ b/clientApp/GUI/package.json @@ -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" +} diff --git a/clientApp/GUI/views/login/login.html b/clientApp/GUI/views/login/login.html new file mode 100755 index 0000000..57773ec --- /dev/null +++ b/clientApp/GUI/views/login/login.html @@ -0,0 +1,27 @@ +
+
+
+ +
+
+
+
+

+ blockchainIDsystem +

+ + + + + +
Login
+
+
+
+ + +
+ +
+
+
diff --git a/clientApp/GUI/views/login/login.js b/clientApp/GUI/views/login/login.js new file mode 100755 index 0000000..4b5a160 --- /dev/null +++ b/clientApp/GUI/views/login/login.js @@ -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); + }); + + }; + }); diff --git a/clientApp/GUI/views/main/main.html b/clientApp/GUI/views/main/main.html new file mode 100755 index 0000000..1565504 --- /dev/null +++ b/clientApp/GUI/views/main/main.html @@ -0,0 +1,31 @@ +
+
+
+ +
+
+
+
+

+ blockchainIDsystem +

+ +
Create new ID
+
+
+
+

+ Current IDs +

+

+ {{id}}

Verify
+

+
+
+
+
+ +
+ +
+
diff --git a/clientApp/GUI/views/main/main.js b/clientApp/GUI/views/main/main.js new file mode 100755 index 0000000..63c3d2a --- /dev/null +++ b/clientApp/GUI/views/main/main.js @@ -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'); + }); + }; + }); diff --git a/clientApp/GUI/views/navbar.html b/clientApp/GUI/views/navbar.html new file mode 100755 index 0000000..c350386 --- /dev/null +++ b/clientApp/GUI/views/navbar.html @@ -0,0 +1,30 @@ +
+ +
diff --git a/clientApp/GUI/views/navbar.js b/clientApp/GUI/views/navbar.js new file mode 100755 index 0000000..6da0b72 --- /dev/null +++ b/clientApp/GUI/views/navbar.js @@ -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(); + }; + + }); diff --git a/clientApp/GUI/views/signup/signup.html b/clientApp/GUI/views/signup/signup.html new file mode 100755 index 0000000..3245144 --- /dev/null +++ b/clientApp/GUI/views/signup/signup.html @@ -0,0 +1,41 @@ +
+
+
+ +
+
+
+
+

Signup

+
+
+
+ +
+
+ +
+
+ +
+
+ +
+
+ +
+ +
+
+ Back +
Signup
+
+
+
+ + +
+ +
+
+
diff --git a/clientApp/GUI/views/signup/signup.js b/clientApp/GUI/views/signup/signup.js new file mode 100755 index 0000000..dbcfa2c --- /dev/null +++ b/clientApp/GUI/views/signup/signup.js @@ -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); + }); + + }; +}); diff --git a/clientApp/README.md b/clientApp/README.md new file mode 100644 index 0000000..3fc8892 --- /dev/null +++ b/clientApp/README.md @@ -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 diff --git a/clientApp/clientAppRESTFunctions.go b/clientApp/clientAppRESTFunctions.go new file mode 100644 index 0000000..52d439a --- /dev/null +++ b/clientApp/clientAppRESTFunctions.go @@ -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)) +} diff --git a/clientApp/config.json b/clientApp/config.json new file mode 100755 index 0000000..911b302 --- /dev/null +++ b/clientApp/config.json @@ -0,0 +1,4 @@ +{ + "port": "4100", + "keysDirectory": "keys" +} diff --git a/clientApp/errors.go b/clientApp/errors.go new file mode 100755 index 0000000..b3cf6b2 --- /dev/null +++ b/clientApp/errors.go @@ -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) + } +} diff --git a/clientApp/keys.go b/clientApp/keys.go new file mode 100644 index 0000000..a5483ff --- /dev/null +++ b/clientApp/keys.go @@ -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) +} diff --git a/clientApp/log.go b/clientApp/log.go new file mode 100755 index 0000000..e8f391a --- /dev/null +++ b/clientApp/log.go @@ -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) +} diff --git a/clientApp/main.go b/clientApp/main.go new file mode 100644 index 0000000..03a1233 --- /dev/null +++ b/clientApp/main.go @@ -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 +} diff --git a/clientApp/ownrsa/prime.go b/clientApp/ownrsa/prime.go new file mode 100644 index 0000000..e5d214b --- /dev/null +++ b/clientApp/ownrsa/prime.go @@ -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) +} diff --git a/clientApp/ownrsa/rsa.go b/clientApp/ownrsa/rsa.go new file mode 100644 index 0000000..eff6848 --- /dev/null +++ b/clientApp/ownrsa/rsa.go @@ -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 +} diff --git a/clientApp/readConfig.go b/clientApp/readConfig.go new file mode 100755 index 0000000..19c59b7 --- /dev/null +++ b/clientApp/readConfig.go @@ -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) +} diff --git a/clientApp/restConfig.go b/clientApp/restConfig.go new file mode 100755 index 0000000..36a332e --- /dev/null +++ b/clientApp/restConfig.go @@ -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 +} diff --git a/clientApp/restRoutes.go b/clientApp/restRoutes.go new file mode 100755 index 0000000..6419009 --- /dev/null +++ b/clientApp/restRoutes.go @@ -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, + }, +} diff --git a/clientApp/testUser.sh b/clientApp/testUser.sh new file mode 100644 index 0000000..01b1ef7 --- /dev/null +++ b/clientApp/testUser.sh @@ -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"}' diff --git a/serverIDsigner/main.go b/serverIDsigner/main.go index 7af700f..1accfb8 100644 --- a/serverIDsigner/main.go +++ b/serverIDsigner/main.go @@ -15,7 +15,7 @@ import ( var userCollection *mgo.Collection -var serverRsa ownrsa.RSA +var serverRSA ownrsa.RSA func main() { color.Blue("Starting serverIDsigner") @@ -26,11 +26,11 @@ func main() { initializeToken() //initialize RSA - serverRsa = ownrsa.GenerateKeyPair() + serverRSA = ownrsa.GenerateKeyPair() color.Blue("Public Key:") - fmt.Println(serverRsa.PubK) + fmt.Println(serverRSA.PubK) color.Green("Private Key:") - fmt.Println(serverRsa.PrivK) + fmt.Println(serverRSA.PrivK) //mongodb session, err := getSession() diff --git a/serverIDsigner/ownrsa/rsa.go b/serverIDsigner/ownrsa/rsa.go index a1e5127..eff6848 100644 --- a/serverIDsigner/ownrsa/rsa.go +++ b/serverIDsigner/ownrsa/rsa.go @@ -5,6 +5,7 @@ import ( "fmt" "math/big" "math/rand" + "strings" "time" ) @@ -181,3 +182,28 @@ func PubKStringToBigInt(kS RSAPublicKeyString) (RSAPublicKey, error) { } 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 +} diff --git a/serverIDsigner/userRESTFunctions.go b/serverIDsigner/userRESTFunctions.go index d9142fc..c716b7c 100644 --- a/serverIDsigner/userRESTFunctions.go +++ b/serverIDsigner/userRESTFunctions.go @@ -125,7 +125,7 @@ func BlindSign(w http.ResponseWriter, r *http.Request) { m = append(m, int(byte)) } - sigma := ownrsa.BlindSign(m, askBlindSign.PubK, serverRsa.PrivK) //here the privK will be the CA privK, not the m emmiter's one. The pubK is the user's one + sigma := ownrsa.BlindSign(m, askBlindSign.PubK, serverRSA.PrivK) //here the privK will be the CA privK, not the m emmiter's one. The pubK is the user's one fmt.Print("Sigma': ") fmt.Println(sigma) @@ -164,7 +164,7 @@ func VerifySign(w http.ResponseWriter, r *http.Request) { mSignedInts = append(mSignedInts, i) } - verified := ownrsa.Verify(mOriginal, mSignedInts, serverRsa.PubK) + verified := ownrsa.Verify(mOriginal, mSignedInts, serverRSA.PubK) fmt.Fprintln(w, verified) }