Skip to content

Commit

Permalink
Changes to the signing scheme
Browse files Browse the repository at this point in the history
  • Loading branch information
demondayza committed Jun 28, 2022
1 parent d291567 commit 021237c
Show file tree
Hide file tree
Showing 5 changed files with 64 additions and 84 deletions.
1 change: 0 additions & 1 deletion .env

This file was deleted.

85 changes: 24 additions & 61 deletions database/database.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ import (
"errors"
"fmt"
"io/ioutil"
"log"
"os"

"crypto/rand"
Expand Down Expand Up @@ -113,81 +112,47 @@ func doesFileExist(fileName string) bool {
}
}

func Sign(msg, secret []byte) <-chan string {
func Sign(domain []byte) <-chan string {
r := make(chan string)

go func() {
priv, pub := GenerateRsaKeyPair()

// Export the keys to pem string
priv_pem := ExportRsaPrivateKeyAsPemStr(priv)
pub_pem, _ := ExportRsaPublicKeyAsPemStr(pub)

// Import the keys from pem string
// priv_parsed, _ := ParseRsaPrivateKeyFromPemStr(priv_pem)
// pub_parsed, _ := ParseRsaPublicKeyFromPemStr(pub_pem)

// Before signing, we need to hash our message
// The hash is what we actually sign
msgHash := sha256.New()
_, err := msgHash.Write(msg)
if err != nil {
panic(err)
}
msgHashSum := msgHash.Sum(nil)

// In order to generate the signature, we provide a random number generator,
// our private key, the hashing algorithm that we used, and the hash sum
// of our message

signature, err := rsa.SignPSS(rand.Reader, priv, crypto.SHA256, msgHashSum, nil)
if err != nil {
panic(err)

}
// fmt.Println(string(priv_pem))
// fmt.Println(string(pub_pem))
filecheck := doesFileExist("private.txt")

if !filecheck {
fmt.Println("File Not Found")
priv_data := []byte(priv_pem)
pub_data := []byte(pub_pem)
ioerr := ioutil.WriteFile("private.txt", priv_data, 777)

if ioerr != nil {
log.Fatal(err)
}

ioerr2 := ioutil.WriteFile("public.txt", pub_data, 777)

if ioerr2 != nil {
log.Fatal(err)
}
}
if filecheck {
fmt.Println("File Found")
b, err := ioutil.ReadFile("private.txt") // just pass the file name
b, err := ioutil.ReadFile("private.txt")
if err != nil {
fmt.Print(err)
}

fmt.Println(b) // print the content as 'bytes'

str := string(b) // convert content to a 'string'
fmt.Println(str)
// priv_parsed, _ := ParseRsaPrivateKeyFromPemStr(str)
priv_parsed, _ := ParseRsaPrivateKeyFromPemStr(str)

msgHash := sha256.New()
_, hasherr := msgHash.Write(domain)
if hasherr != nil {
panic(err)
}
msgHashSum := msgHash.Sum(nil)

// In order to generate the signature, we provide a random number generator,
// our private key, the hashing algorithm that we used, and the hash sum
// of our message

signature, err := rsa.SignPSS(rand.Reader, priv_parsed, crypto.SHA256, msgHashSum, nil)
if err != nil {
panic(err)

if priv_pem != str {
fmt.Println("Failure: Export and Import did not result in same Keys")
} else {
fmt.Println("Success")
}

r <- hex.EncodeToString(signature)
}
if !filecheck {

// fmt.Println(hex.EncodeToString(signature))
r <- hex.EncodeToString(signature)
panic("Key not found for signing.")

}

}()

Expand All @@ -210,10 +175,8 @@ func GetAllWhitelisteDomains() ([]WhitelistDomain, error) {
func CreateWhitelistedDomain(name string, url string) (WhitelistDomain, error) {

msg := []byte(url)
key := []byte(os.Getenv("SECRETKEY"))

hash := <-Sign(msg, key)
fmt.Println("HASH:", hash)
hash := <-Sign(msg)

var newDomain = WhitelistDomain{Name: name, Url: url, Signature: hash}

Expand Down
48 changes: 33 additions & 15 deletions main.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,12 @@ import (
"crypto/rsa"
"crypto/x509"
"encoding/pem"
"fmt"
"io/ioutil"
"ixowhitelistdaemon/database"
whitelist_domain "ixowhitelistdaemon/whitelist"
"log"
"os"

"github.com/gofiber/fiber/v2"
"github.com/joho/godotenv"
Expand Down Expand Up @@ -56,6 +59,17 @@ func ExportRsaPublicKeyAsPemStr(pubkey *rsa.PublicKey) (string, error) {
return string(pubkey_pem), nil
}

func doesFileExist(fileName string) bool {
_, error := os.Stat(fileName)

// check if error is "file not exists"
if os.IsNotExist(error) {
return false
} else {
return true
}
}

func main() {
err := godotenv.Load()
if err != nil {
Expand All @@ -66,26 +80,30 @@ func main() {

//Setup server RSA Keys

// priv, pub := GenerateRsaKeyPair()

// Export the keys to pem string
// priv_pem := ExportRsaPrivateKeyAsPemStr(priv)
// pub_pem, _ := ExportRsaPublicKeyAsPemStr(pub)
filecheck := doesFileExist("private.txt")

// priv_data := []byte(priv_pem)
// pub_data := []byte(pub_pem)
//Check for local key
if !filecheck {
fmt.Println("File Not Found")
priv, pub := GenerateRsaKeyPair()

// ioerr := ioutil.WriteFile("private.txt", priv_data, 0)
// Export the keys to pem string
priv_pem := ExportRsaPrivateKeyAsPemStr(priv)
pub_pem, _ := ExportRsaPublicKeyAsPemStr(pub)
priv_data := []byte(priv_pem)
pub_data := []byte(pub_pem)
ioerr := ioutil.WriteFile("private.txt", priv_data, 777)

// if ioerr != nil {
// log.Fatal(err)
// }
if ioerr != nil {
log.Fatal(err)
}

// ioerr2 := ioutil.WriteFile("public.txt", pub_data, 0)
ioerr2 := ioutil.WriteFile("public.txt", pub_data, 777)

// if ioerr2 != nil {
// log.Fatal(err)
// }
if ioerr2 != nil {
log.Fatal(err)
}
}

if dbErr != nil {
panic(dbErr)
Expand Down
4 changes: 2 additions & 2 deletions readme.md
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
# IXOWhitelistDaemon

IXOWhitelistDaemon is a simple golang application to serve domain whitelists.
IXOWhitelistDaemon is a simple RSA PKSS based golang application to serve verifiable domain whitelists.

## Installation

Requires a local golang development setup then make server can be used to start a local copy.
The local .env file needs to be set with a local server secret to be shared with the partner organization for domain verification purposes.
Keys are generated at runtime unless a private.txt and public.txt is present in the local binary directory.



Expand Down
10 changes: 5 additions & 5 deletions specification.md
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@


## Cryptographic Package Standard
The HMAC package being used implements the following standard: Keyed-Hash Message Authentication Code (HMAC) as defined in U.S. Federal Information Processing Standards Publication 198.
The RSA PSS package being used implements the following standard: RSASSA-PSS signature scheme according to RFC 8017

## Package explanation
It is a Golang service api that stores a list of whitelisted domain urls each with their own signed hmac signature. The hmac signature uses a shared secret between two parties. In this case its Opera and IXO. The key of the mechanism is Opera can validate that the response from the whitelist server is cryptographically correct by comparing the hmac signature provided with their own signature generated using the urls in the response. They must match or there is likely a man in the middle attack occuring between the opera client and the ixo server. The server address is to be confirmed once a shared secret is agreed upon.
It is a Golang service api that stores a list of whitelisted domain urls each with their own signed RSA PSS signature. The RSA signature shares a public and private key between two parties, where the server holds the private key and the client holds the public key. In this case its Opera and IXO. The key of the mechanism is Opera can validate that the response from the whitelist server is cryptographically correct by comparing the RSA PSS signature provided with their own signature generated using the urls in the response. They must match or there is likely a man in the middle attack occuring between the opera client and the ixo server. The server address is to be confirmed once a set of RSA keys is agreed upon.

## Package Requirements
It defines a client server relationship where IXO (The server) shares a private secret key with Opera (The client) and Opera uses the key to verify the integrity of the messages being sent. The requirement on the Opera side is to have a hmac comparison function in line with the hmac standard defined above for comparison purposes.
It defines a client server relationship where IXO (The server) shares a public RSA key with client and the client uses the key to verify the integrity of the messages being sent. The requirement on the Client side is to have a RSA PSS verify function in line with the RSA standard defined above for comparison purposes.

## API Example Response Object
```json
Expand All @@ -17,10 +17,10 @@ It defines a client server relationship where IXO (The server) shares a private
ID: 1,
CreatedAt: "",
UpdatedAt: "",
DeletedAt: null,
DeletedAt: null, // This is for soft deletes in terms of domains in the process of leaving the whitelist
name: "examplename",
url: "exampleurl",
hash: "ExampleHmachash"
signature: "examplepksssignature"

}
message: "success"
Expand Down

0 comments on commit 021237c

Please sign in to comment.