github.com/deso-protocol/core@v1.2.9/lib/utils.go (about)

     1  package lib
     2  
     3  import (
     4  	"fmt"
     5  	"github.com/btcsuite/btcd/btcec"
     6  	"github.com/btcsuite/btcd/chaincfg"
     7  	"github.com/btcsuite/btcutil/hdkeychain"
     8  	"github.com/unrolled/secure"
     9  )
    10  
    11  const SECURE_MIDDLEWARE_RESTRICTIVE_CONTENT_SECURITY_POLICY = "default-src 'self'"
    12  
    13  // allowedHost is expected to be of the form "bitclout.com"
    14  // See comments in this function for a description of these params
    15  //
    16  // Note: FeaturePolicy is apparently renamed to PermissionsPolicy. Maybe we should fork
    17  // secure.go and add that. https://scotthelme.co.uk/goodbye-feature-policy-and-hello-permissions-policy/
    18  func InitializeSecureMiddleware(allowedHosts []string, isDevelopment bool, contentSecurityPolicy string) *secure.Secure {
    19  	// For more info about these fields, see:
    20  	//   https://github.com/unrolled/secure
    21  	//   https://blog.rapid7.com/2016/07/13/quick-security-wins-in-golang/
    22  	return secure.New(secure.Options{
    23  		AllowedHosts:          allowedHosts,                                    // AllowedHosts is a list of fully qualified domain names that are allowed. Default is empty list, which allows any and all host names.
    24  		AllowedHostsAreRegex:  true,                                            // AllowedHostsAreRegex determines, if the provided AllowedHosts slice contains valid regular expressions. Default is false.
    25  		HostsProxyHeaders:     []string{"X-Forwarded-Hosts"},                   // HostsProxyHeaders is a set of header keys that may hold a proxied hostname value for the request.
    26  		SSLRedirect:           false,                                           // If SSLRedirect is set to true, then only allow HTTPS requests. Default is false.
    27  		SSLTemporaryRedirect:  false,                                           // If SSLTemporaryRedirect is true, the a 302 will be used while redirecting. Default is false (301).
    28  		SSLHost:               "",                                              // SSLHost is the host name that is used to redirect HTTP requests to HTTPS. Default is "", which indicates to use the same host.
    29  		SSLHostFunc:           nil,                                             // SSLHostFunc is a function pointer, the return value of the function is the host name that has same functionality as `SSHost`. Default is nil. If SSLHostFunc is nil, the `SSLHost` option will be used.
    30  		SSLProxyHeaders:       map[string]string{"X-Forwarded-Proto": "https"}, // SSLProxyHeaders is set of header keys with associated values that would indicate a valid HTTPS request. Useful when using Nginx: `map[string]string{"X-Forwarded-Proto": "https"}`. Default is blank map.
    31  		STSSeconds:            31536000,                                        // STSSeconds is the max-age of the Strict-Transport-Security header. Default is 0, which would NOT include the header.
    32  		STSIncludeSubdomains:  true,                                            // If STSIncludeSubdomains is set to true, the `includeSubdomains` will be appended to the Strict-Transport-Security header. Default is false.
    33  		STSPreload:            false,                                           // If STSPreload is set to true, the `preload` flag will be appended to the Strict-Transport-Security header. Default is false. [TODO: this seems like a good security feature, but we'd have to submit our domain to Google]
    34  		ForceSTSHeader:        false,                                           // STS header is only included when the connection is HTTPS. If you want to force it to always be added, set to true. `IsDevelopment` still overrides this. Default is false.
    35  		FrameDeny:             true,                                            // If FrameDeny is set to true, adds the X-Frame-Options header with the value of `DENY`. Default is false.
    36  		ContentTypeNosniff:    true,                                            // If ContentTypeNosniff is true, adds the X-Content-Type-Options header with the value `nosniff`. Default is false.
    37  		BrowserXssFilter:      true,                                            // If BrowserXssFilter is true, adds the X-XSS-Protection header with the value `1; mode=block`. Default is false.
    38  		ContentSecurityPolicy: contentSecurityPolicy,                           // ContentSecurityPolicy allows the Content-Security-Policy header value to be set with a custom value. Default is "". Passing a template string will replace `$NONCE` with a dynamic nonce value of 16 bytes for each request which can be later retrieved using the Nonce function.
    39  		ReferrerPolicy:        "same-origin",                                   // ReferrerPolicy allows the Referrer-Policy header with the value to be set with a custom value. Default is "".
    40  		FeaturePolicy:         "",                                              // FeaturePolicy allows the Feature-Policy header with the value to be set with a custom value. Default is "".
    41  		IsDevelopment:         isDevelopment,                                   // This will cause the AllowedHosts, SSLRedirect, and STSSeconds/STSIncludeSubdomains options to be ignored during development. When deploying to production, be sure to set this to false.
    42  	})
    43  }
    44  
    45  func MinInt(a, b int) int {
    46  	if a < b {
    47  		return a
    48  	}
    49  	return b
    50  }
    51  
    52  func MinUint32(a, b uint32) uint32 {
    53  	if a < b {
    54  		return a
    55  	}
    56  	return b
    57  }
    58  
    59  func ComputeKeysFromSeed(seedBytes []byte, index uint32, params *DeSoParams) (_pubKey *btcec.PublicKey, _privKey *btcec.PrivateKey, _btcAddress string, _err error) {
    60  	isTestnet := params.NetworkType == NetworkType_TESTNET
    61  	return ComputeKeysFromSeedWithNet(seedBytes, index, isTestnet)
    62  }
    63  
    64  func ComputeKeysFromSeedWithNet(seedBytes []byte, index uint32, isTestnet bool) (_pubKey *btcec.PublicKey, _privKey *btcec.PrivateKey, _btcAddress string, _err error) {
    65  	// Get the pubkey and privkey from the seed. We use the Bitcoin parameters
    66  	// to generate them.
    67  	// TODO: We should get this from the DeSoParams, not reference them directly.
    68  	netParams := &chaincfg.MainNetParams
    69  	if isTestnet {
    70  		netParams = &chaincfg.TestNet3Params
    71  	}
    72  	masterKey, err := hdkeychain.NewMaster(seedBytes, netParams)
    73  	if err != nil {
    74  		return nil, nil, "", fmt.Errorf("ComputeKeyFromSeed: Error encountered generating 'masterKey' from seed (%v)", err)
    75  	}
    76  
    77  	// We follow BIP44 to generate the addresses. Recall it follows the following
    78  	// semantic hierarchy:
    79  	// * purpose' / coin_type' / account' / change / address_index
    80  	// For the derivation path we use: m/44'/0'/0'/0/0. Recall that 0' means we're
    81  	// computing a "hardened" key, which means the private key is present, and
    82  	// that 0 (no apostrophe) means we're computing an "unhardened" key which means
    83  	// the private key is not present.
    84  	//
    85  	// m/44'/0'/0'/0/0 also maps to the first
    86  	// address you'd get if you put the user's seed into most standard
    87  	// Bitcoin wallets (Mycelium, Electrum, Ledger, iancoleman, etc...).
    88  	purpose, err := masterKey.Child(hdkeychain.HardenedKeyStart + 44)
    89  	if err != nil {
    90  		return nil, nil, "", fmt.Errorf("ComputeKeyFromSeed: Error encountered generating 'purpose' from seed (%v)", err)
    91  	}
    92  	coinTypeKey, err := purpose.Child(hdkeychain.HardenedKeyStart + 0)
    93  	if err != nil {
    94  		return nil, nil, "", fmt.Errorf("ComputeKeyFromSeed: Error encountered generating 'coinType' from seed (%v)", err)
    95  	}
    96  	accountKey, err := coinTypeKey.Child(hdkeychain.HardenedKeyStart + 0)
    97  	if err != nil {
    98  		return nil, nil, "", fmt.Errorf("ComputeKeyFromSeed: Error encountered generating 'accountKey' from seed (%v)", err)
    99  	}
   100  	changeKey, err := accountKey.Child(0)
   101  	if err != nil {
   102  		return nil, nil, "", fmt.Errorf("ComputeKeyFromSeed: Error encountered generating 'changeKey' from seed (%v)", err)
   103  	}
   104  	addressKey, err := changeKey.Child(index)
   105  	if err != nil {
   106  		return nil, nil, "", fmt.Errorf("ComputeKeyFromSeed: Error encountered generating 'addressKey' from seed (%v)", err)
   107  	}
   108  
   109  	pubKey, err := addressKey.ECPubKey()
   110  	if err != nil {
   111  		return nil, nil, "", fmt.Errorf("ComputeKeyFromSeed: Error encountered generating 'pubKey' from seed (%v)", err)
   112  	}
   113  	privKey, err := addressKey.ECPrivKey()
   114  	if err != nil {
   115  		return nil, nil, "", fmt.Errorf("ComputeKeyFromSeed: Error encountered generating 'privKey' from seed (%v)", err)
   116  	}
   117  	addressObj, err := addressKey.Address(netParams)
   118  	if err != nil {
   119  		return nil, nil, "", fmt.Errorf("ComputeKeyFromSeed: Error encountered generating 'addressObj' from seed (%v)", err)
   120  	}
   121  	btcDepositAddress := addressObj.EncodeAddress()
   122  
   123  	return pubKey, privKey, btcDepositAddress, nil
   124  }