1package crypto 2 3import ( 4 "fmt" 5 6 "github.com/zclconf/go-cty/cty" 7 "github.com/zclconf/go-cty/cty/function" 8 "github.com/zclconf/go-cty/cty/gocty" 9 "golang.org/x/crypto/bcrypt" 10) 11 12// BcryptFunc is a function that computes a hash of the given string using the 13// Blowfish cipher. 14var BcryptFunc = function.New(&function.Spec{ 15 Params: []function.Parameter{ 16 { 17 Name: "str", 18 Type: cty.String, 19 }, 20 }, 21 VarParam: &function.Parameter{ 22 Name: "cost", 23 Type: cty.Number, 24 }, 25 Type: function.StaticReturnType(cty.String), 26 Impl: func(args []cty.Value, retType cty.Type) (ret cty.Value, err error) { 27 defaultCost := 10 28 29 if len(args) > 1 { 30 var val int 31 if err := gocty.FromCtyValue(args[1], &val); err != nil { 32 return cty.UnknownVal(cty.String), err 33 } 34 defaultCost = val 35 } 36 37 if len(args) > 2 { 38 return cty.UnknownVal(cty.String), fmt.Errorf("bcrypt() takes no more than two arguments") 39 } 40 41 input := args[0].AsString() 42 out, err := bcrypt.GenerateFromPassword([]byte(input), defaultCost) 43 if err != nil { 44 return cty.UnknownVal(cty.String), fmt.Errorf("error occured generating password %s", err.Error()) 45 } 46 47 return cty.StringVal(string(out)), nil 48 }, 49}) 50 51// Bcrypt computes a hash of the given string using the Blowfish cipher, 52// returning a string in the Modular Crypt Format usually expected in the 53// shadow password file on many Unix systems. 54func Bcrypt(str cty.Value, cost ...cty.Value) (cty.Value, error) { 55 args := make([]cty.Value, len(cost)+1) 56 args[0] = str 57 copy(args[1:], cost) 58 return BcryptFunc.Call(args) 59} 60