tBetter error handling - tordam - A library for peer discovery inside the Tor network HTML git clone https://git.parazyd.org/tordam DIR Log DIR Files DIR Refs DIR README DIR LICENSE --- DIR commit 4c0fbc7aca051d61ded56822b17e017798c92420 DIR parent 24156de26fb67ba8a61df74c94c7796ff98ebad2 HTML Author: parazyd <parazyd@dyne.org> Date: Fri, 8 Dec 2017 13:46:39 +0100 Better error handling Diffstat: M cmd/dam-client/main.go | 23 ++++++++++++++++------- M cmd/dam-dir/main.go | 1 - M pkg/lib/crypto.go | 80 +++++++++++++++++++++---------- M pkg/lib/helpers.go | 26 ++++++++++++++++++-------- 4 files changed, 89 insertions(+), 41 deletions(-) --- DIR diff --git a/cmd/dam-client/main.go b/cmd/dam-client/main.go t@@ -29,20 +29,27 @@ type msgStruct struct { func main() { if _, err := os.Stat("private.key"); os.IsNotExist(err) { - key := lib.GenRsa(Bits) - lib.SavePriv(Privpath, key) - //lib.SavePub(Pubpath, key.PublicKey) + key, err := lib.GenRsa(Bits) + lib.CheckError(err) + _, err = lib.SavePriv(Privpath, key) + lib.CheckError(err) + //_, err := lib.SavePub(Pubpath, key.PublicKey) + lib.CheckError(err) } key, err := lib.LoadKeyFromFile(Privpath) lib.CheckError(err) - sig := lib.SignMsg([]byte(Postmsg), key) + sig, err := lib.SignMsg([]byte(Postmsg), key) + lib.CheckError(err) encodedSig := base64.StdEncoding.EncodeToString(sig) + onionAddr, err := lib.OnionFromPubkey(key.PublicKey) + lib.CheckError(err) + vals := map[string]string{ "nodetype": "node", - "address": lib.OnionFromPubkey(key.PublicKey), + "address": string(onionAddr), "message": Postmsg, "signature": encodedSig, "secret": "", t@@ -54,7 +61,8 @@ func main() { lib.CheckError(err) log.Println("Sending request") - resp := lib.HTTPPost("http://localhost:8080/announce", jsonVal) + resp, err := lib.HTTPPost("http://localhost:8080/announce", jsonVal) + lib.CheckError(err) // Parse server's reply var m msgStruct t@@ -82,7 +90,8 @@ func main() { lib.CheckError(err) log.Println("Sending back decrypted secret.") - resp = lib.HTTPPost("http://localhost:8080/announce", jsonVal) + resp, err := lib.HTTPPost("http://localhost:8080/announce", jsonVal) + lib.CheckError(err) decoder = json.NewDecoder(resp.Body) err = decoder.Decode(&m) lib.CheckError(err) DIR diff --git a/cmd/dam-dir/main.go b/cmd/dam-dir/main.go t@@ -130,7 +130,6 @@ func handlePost(rw http.ResponseWriter, request *http.Request) { if len(req["secret"]) == 88 { // Client sent a decrypted secret. - var correct = false localSec, err := RedisCli.HGet(n.Address, "secret").Result() lib.CheckError(err) DIR diff --git a/pkg/lib/crypto.go b/pkg/lib/crypto.go t@@ -20,39 +20,50 @@ import ( ) // GenRsa generates a private RSA keypair of a given bitSize int. -func GenRsa(bitSize int) *rsa.PrivateKey { +func GenRsa(bitSize int) (*rsa.PrivateKey, error) { log.Printf("Generating %d-bit RSA keypair...\n", bitSize) rng := rand.Reader key, err := rsa.GenerateKey(rng, bitSize) - CheckError(err) - - return key + if err != nil { + return nil, err + } + return key, nil } // SavePub saves a given RSA public key to a given filename. -func SavePub(filename string, pubkey rsa.PublicKey) { +func SavePub(filename string, pubkey rsa.PublicKey) (bool, error) { log.Printf("Writing pubkey to %s\n", filename) outfile, err := os.Create(filename) - CheckError(err) defer outfile.Close() + if err != nil { + return false, err + } asn1Bytes, err := asn1.Marshal(pubkey) - CheckError(err) + if err != nil { + return false, err + } var pemkey = &pem.Block{ Type: "RSA PUBLIC KEY", Bytes: asn1Bytes, } + err = pem.Encode(outfile, pemkey) - CheckError(err) + if err != nil { + return false, err + } + return true, nil } // SavePriv saves a given RSA private key to a given filename. -func SavePriv(filename string, privkey *rsa.PrivateKey) { +func SavePriv(filename string, privkey *rsa.PrivateKey) (bool, error) { log.Printf("Writing private key to %s\n", filename) outfile, err := os.Create(filename) - CheckError(err) defer outfile.Close() + if err != nil { + return false, err + } var pemkey = &pem.Block{ Type: "RSA PRIVATE KEY", t@@ -60,14 +71,19 @@ func SavePriv(filename string, privkey *rsa.PrivateKey) { } err = pem.Encode(outfile, pemkey) - CheckError(err) + if err != nil { + return false, err + } + return true, nil } // LoadKeyFromFile loads a RSA private key from a given filename. func LoadKeyFromFile(filename string) (*rsa.PrivateKey, error) { log.Println("Loading RSA private key from", filename) dat, err := ioutil.ReadFile(filename) - CheckError(err) + if err != nil { + return nil, err + } block, _ := pem.Decode(dat) if block == nil { t@@ -75,21 +91,25 @@ func LoadKeyFromFile(filename string) (*rsa.PrivateKey, error) { } priv, err := x509.ParsePKCS1PrivateKey(block.Bytes) - CheckError(err) + if err != nil { + return nil, err + } return priv, nil } // SignMsg signs a given []byte message using a given RSA private key. -func SignMsg(message []byte, privkey *rsa.PrivateKey) []byte { +func SignMsg(message []byte, privkey *rsa.PrivateKey) ([]byte, error) { log.Println("Signing message...") rng := rand.Reader hashed := sha512.Sum512(message) sig, err := rsa.SignPKCS1v15(rng, privkey, crypto.SHA512, hashed[:]) - CheckError(err) + if err != nil { + return nil, err + } - return sig + return sig, nil } // EncryptMsg encrypts a given []byte message using a given RSA public key. t@@ -99,7 +119,9 @@ func EncryptMsg(message []byte, pubkey *rsa.PublicKey) ([]byte, error) { rng := rand.Reader msg, err := rsa.EncryptPKCS1v15(rng, pubkey, message) - CheckError(err) + if err != nil { + return nil, err + } return msg, nil } t@@ -111,7 +133,9 @@ func DecryptMsg(message []byte, privkey *rsa.PrivateKey) ([]byte, error) { rng := rand.Reader msg, err := rsa.DecryptPKCS1v15(rng, privkey, message) - CheckError(err) + if err != nil { + return nil, err + } return msg, nil } t@@ -124,8 +148,7 @@ func VerifyMsg(message []byte, signature []byte, pubkey *rsa.PublicKey) (bool, e hashed := sha512.Sum512(message) err := rsa.VerifyPKCS1v15(pubkey, crypto.SHA512, hashed[:], signature) if err != nil { - log.Println("Error:", err) - return false, nil + return false, err } log.Println("Signature valid") t@@ -133,17 +156,22 @@ func VerifyMsg(message []byte, signature []byte, pubkey *rsa.PublicKey) (bool, e } // OnionFromPubkey generates a valid onion address from a given RSA pubkey. -func OnionFromPubkey(pubkey rsa.PublicKey) string { +func OnionFromPubkey(pubkey rsa.PublicKey) ([]byte, error) { asn1Bytes, err := asn1.Marshal(pubkey) - CheckError(err) + if err != nil { + return nil, err + } hashed := sha1.New() _, err = hashed.Write(asn1Bytes) - CheckError(err) + if err != nil { + return nil, err + } encoded := strings.ToLower(base32.StdEncoding.EncodeToString(hashed.Sum(nil)))[:16] + encoded += ".onion" - return encoded + ".onion" + return []byte(encoded), nil } // ParsePubkey parses a []byte form of a RSA public key and returns the proper t@@ -154,7 +182,9 @@ func ParsePubkey(pubkey []byte) (*rsa.PublicKey, error) { block, _ := pem.Decode(pubkey) _, err := asn1.Unmarshal(block.Bytes, &pub) - CheckError(err) + if err != nil { + return nil, err + } ret = &pub return ret, nil DIR diff --git a/pkg/lib/helpers.go b/pkg/lib/helpers.go t@@ -23,7 +23,7 @@ const ProxyAddr = "127.0.0.1:9050" // CheckError is a handler for errors. func CheckError(err error) { if err != nil { - panic(err) + log.Fatalln(err) } } t@@ -101,11 +101,13 @@ func ValidateReq(req map[string]string) ([]byte, bool) { // HTTPPost sends an HTTP POST request to the given host. It sends data as // application/json. -func HTTPPost(host string, data []byte) *http.Response { +func HTTPPost(host string, data []byte) (*http.Response, error) { socksify := false parsedHost, err := url.Parse(host) - CheckError(err) + if err != nil { + return nil, err + } hostname := parsedHost.Hostname() if strings.HasSuffix(hostname, ".onion") { socksify = true t@@ -116,18 +118,24 @@ func HTTPPost(host string, data []byte) *http.Response { if socksify { log.Println("Detected a .onion request. Using SOCKS proxy.") dialer, err := proxy.SOCKS5("tcp", ProxyAddr, nil, proxy.Direct) - CheckError(err) + if err != nil { + return nil, err + } httpTransp.Dial = dialer.Dial } request, err := http.NewRequest("POST", host, bytes.NewBuffer(data)) - CheckError(err) + if err != nil { + return nil, err + } request.Header.Set("Content-Type", "application/json") resp, err := httpClient.Do(request) - CheckError(err) + if err != nil { + return nil, err + } - return resp + return resp, nil } // GenRandomASCII returns a random ASCII string of a given length. t@@ -138,7 +146,9 @@ func GenRandomASCII(length int) (string, error) { return res, nil } num, err := rand.Int(rand.Reader, big.NewInt(int64(127))) - CheckError(err) + if err != nil { + return "", err + } n := num.Int64() if n > 32 && n < 127 {