tBetter error handling - tordam - A library for peer discovery inside the Tor network
 (HTM) git clone https://git.parazyd.org/tordam
 (DIR) Log
 (DIR) Files
 (DIR) Refs
 (DIR) README
 (DIR) LICENSE
       ---
 (DIR) commit 4c0fbc7aca051d61ded56822b17e017798c92420
 (DIR) parent 24156de26fb67ba8a61df74c94c7796ff98ebad2
 (HTM) 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 {