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 }