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 0000000..dc84861 Binary files /dev/null and b/clientApp/GUI/img/blockchainIDsystem-logo-black.png differ diff --git a/clientApp/GUI/img/blockchainIDsystem-logo-white.png b/clientApp/GUI/img/blockchainIDsystem-logo-white.png new file mode 100644 index 0000000..ddadf84 Binary files /dev/null and b/clientApp/GUI/img/blockchainIDsystem-logo-white.png differ 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) }