]> git.immae.eu Git - github/fretlink/terraform-provider-statuscake.git/blob - vendor/github.com/hashicorp/terraform/lang/funcs/crypto.go
Upgrade to 0.12
[github/fretlink/terraform-provider-statuscake.git] / vendor / github.com / hashicorp / terraform / lang / funcs / crypto.go
1 package funcs
2
3 import (
4 "crypto/md5"
5 "crypto/rsa"
6 "crypto/sha1"
7 "crypto/sha256"
8 "crypto/sha512"
9 "crypto/x509"
10 "encoding/base64"
11 "encoding/hex"
12 "encoding/pem"
13 "fmt"
14 "hash"
15
16 uuid "github.com/hashicorp/go-uuid"
17 "github.com/zclconf/go-cty/cty"
18 "github.com/zclconf/go-cty/cty/function"
19 "github.com/zclconf/go-cty/cty/gocty"
20 "golang.org/x/crypto/bcrypt"
21 )
22
23 var UUIDFunc = function.New(&function.Spec{
24 Params: []function.Parameter{},
25 Type: function.StaticReturnType(cty.String),
26 Impl: func(args []cty.Value, retType cty.Type) (ret cty.Value, err error) {
27 result, err := uuid.GenerateUUID()
28 if err != nil {
29 return cty.UnknownVal(cty.String), err
30 }
31 return cty.StringVal(result), nil
32 },
33 })
34
35 // Base64Sha256Func constructs a function that computes the SHA256 hash of a given string
36 // and encodes it with Base64.
37 var Base64Sha256Func = makeStringHashFunction(sha256.New, base64.StdEncoding.EncodeToString)
38
39 // MakeFileBase64Sha256Func constructs a function that is like Base64Sha256Func but reads the
40 // contents of a file rather than hashing a given literal string.
41 func MakeFileBase64Sha256Func(baseDir string) function.Function {
42 return makeFileHashFunction(baseDir, sha256.New, base64.StdEncoding.EncodeToString)
43 }
44
45 // Base64Sha512Func constructs a function that computes the SHA256 hash of a given string
46 // and encodes it with Base64.
47 var Base64Sha512Func = makeStringHashFunction(sha512.New, base64.StdEncoding.EncodeToString)
48
49 // MakeFileBase64Sha512Func constructs a function that is like Base64Sha512Func but reads the
50 // contents of a file rather than hashing a given literal string.
51 func MakeFileBase64Sha512Func(baseDir string) function.Function {
52 return makeFileHashFunction(baseDir, sha512.New, base64.StdEncoding.EncodeToString)
53 }
54
55 // BcryptFunc constructs a function that computes a hash of the given string using the Blowfish cipher.
56 var BcryptFunc = function.New(&function.Spec{
57 Params: []function.Parameter{
58 {
59 Name: "str",
60 Type: cty.String,
61 },
62 },
63 VarParam: &function.Parameter{
64 Name: "cost",
65 Type: cty.Number,
66 },
67 Type: function.StaticReturnType(cty.String),
68 Impl: func(args []cty.Value, retType cty.Type) (ret cty.Value, err error) {
69 defaultCost := 10
70
71 if len(args) > 1 {
72 var val int
73 if err := gocty.FromCtyValue(args[1], &val); err != nil {
74 return cty.UnknownVal(cty.String), err
75 }
76 defaultCost = val
77 }
78
79 if len(args) > 2 {
80 return cty.UnknownVal(cty.String), fmt.Errorf("bcrypt() takes no more than two arguments")
81 }
82
83 input := args[0].AsString()
84 out, err := bcrypt.GenerateFromPassword([]byte(input), defaultCost)
85 if err != nil {
86 return cty.UnknownVal(cty.String), fmt.Errorf("error occured generating password %s", err.Error())
87 }
88
89 return cty.StringVal(string(out)), nil
90 },
91 })
92
93 // Md5Func constructs a function that computes the MD5 hash of a given string and encodes it with hexadecimal digits.
94 var Md5Func = makeStringHashFunction(md5.New, hex.EncodeToString)
95
96 // MakeFileMd5Func constructs a function that is like Md5Func but reads the
97 // contents of a file rather than hashing a given literal string.
98 func MakeFileMd5Func(baseDir string) function.Function {
99 return makeFileHashFunction(baseDir, md5.New, hex.EncodeToString)
100 }
101
102 // RsaDecryptFunc constructs a function that decrypts an RSA-encrypted ciphertext.
103 var RsaDecryptFunc = function.New(&function.Spec{
104 Params: []function.Parameter{
105 {
106 Name: "ciphertext",
107 Type: cty.String,
108 },
109 {
110 Name: "privatekey",
111 Type: cty.String,
112 },
113 },
114 Type: function.StaticReturnType(cty.String),
115 Impl: func(args []cty.Value, retType cty.Type) (ret cty.Value, err error) {
116 s := args[0].AsString()
117 key := args[1].AsString()
118
119 b, err := base64.StdEncoding.DecodeString(s)
120 if err != nil {
121 return cty.UnknownVal(cty.String), fmt.Errorf("failed to decode input %q: cipher text must be base64-encoded", s)
122 }
123
124 block, _ := pem.Decode([]byte(key))
125 if block == nil {
126 return cty.UnknownVal(cty.String), fmt.Errorf("failed to parse key: no key found")
127 }
128 if block.Headers["Proc-Type"] == "4,ENCRYPTED" {
129 return cty.UnknownVal(cty.String), fmt.Errorf(
130 "failed to parse key: password protected keys are not supported. Please decrypt the key prior to use",
131 )
132 }
133
134 x509Key, err := x509.ParsePKCS1PrivateKey(block.Bytes)
135 if err != nil {
136 return cty.UnknownVal(cty.String), err
137 }
138
139 out, err := rsa.DecryptPKCS1v15(nil, x509Key, b)
140 if err != nil {
141 return cty.UnknownVal(cty.String), err
142 }
143
144 return cty.StringVal(string(out)), nil
145 },
146 })
147
148 // Sha1Func contructs a function that computes the SHA1 hash of a given string
149 // and encodes it with hexadecimal digits.
150 var Sha1Func = makeStringHashFunction(sha1.New, hex.EncodeToString)
151
152 // MakeFileSha1Func constructs a function that is like Sha1Func but reads the
153 // contents of a file rather than hashing a given literal string.
154 func MakeFileSha1Func(baseDir string) function.Function {
155 return makeFileHashFunction(baseDir, sha1.New, hex.EncodeToString)
156 }
157
158 // Sha256Func contructs a function that computes the SHA256 hash of a given string
159 // and encodes it with hexadecimal digits.
160 var Sha256Func = makeStringHashFunction(sha256.New, hex.EncodeToString)
161
162 // MakeFileSha256Func constructs a function that is like Sha256Func but reads the
163 // contents of a file rather than hashing a given literal string.
164 func MakeFileSha256Func(baseDir string) function.Function {
165 return makeFileHashFunction(baseDir, sha256.New, hex.EncodeToString)
166 }
167
168 // Sha512Func contructs a function that computes the SHA512 hash of a given string
169 // and encodes it with hexadecimal digits.
170 var Sha512Func = makeStringHashFunction(sha512.New, hex.EncodeToString)
171
172 // MakeFileSha512Func constructs a function that is like Sha512Func but reads the
173 // contents of a file rather than hashing a given literal string.
174 func MakeFileSha512Func(baseDir string) function.Function {
175 return makeFileHashFunction(baseDir, sha512.New, hex.EncodeToString)
176 }
177
178 func makeStringHashFunction(hf func() hash.Hash, enc func([]byte) string) function.Function {
179 return function.New(&function.Spec{
180 Params: []function.Parameter{
181 {
182 Name: "str",
183 Type: cty.String,
184 },
185 },
186 Type: function.StaticReturnType(cty.String),
187 Impl: func(args []cty.Value, retType cty.Type) (ret cty.Value, err error) {
188 s := args[0].AsString()
189 h := hf()
190 h.Write([]byte(s))
191 rv := enc(h.Sum(nil))
192 return cty.StringVal(rv), nil
193 },
194 })
195 }
196
197 func makeFileHashFunction(baseDir string, hf func() hash.Hash, enc func([]byte) string) function.Function {
198 return function.New(&function.Spec{
199 Params: []function.Parameter{
200 {
201 Name: "path",
202 Type: cty.String,
203 },
204 },
205 Type: function.StaticReturnType(cty.String),
206 Impl: func(args []cty.Value, retType cty.Type) (ret cty.Value, err error) {
207 path := args[0].AsString()
208 src, err := readFileBytes(baseDir, path)
209 if err != nil {
210 return cty.UnknownVal(cty.String), err
211 }
212
213 h := hf()
214 h.Write(src)
215 rv := enc(h.Sum(nil))
216 return cty.StringVal(rv), nil
217 },
218 })
219 }
220
221 // UUID generates and returns a Type-4 UUID in the standard hexadecimal string
222 // format.
223 //
224 // This is not a pure function: it will generate a different result for each
225 // call. It must therefore be registered as an impure function in the function
226 // table in the "lang" package.
227 func UUID() (cty.Value, error) {
228 return UUIDFunc.Call(nil)
229 }
230
231 // Base64Sha256 computes the SHA256 hash of a given string and encodes it with
232 // Base64.
233 //
234 // The given string is first encoded as UTF-8 and then the SHA256 algorithm is applied
235 // as defined in RFC 4634. The raw hash is then encoded with Base64 before returning.
236 // Terraform uses the "standard" Base64 alphabet as defined in RFC 4648 section 4.
237 func Base64Sha256(str cty.Value) (cty.Value, error) {
238 return Base64Sha256Func.Call([]cty.Value{str})
239 }
240
241 // Base64Sha512 computes the SHA512 hash of a given string and encodes it with
242 // Base64.
243 //
244 // The given string is first encoded as UTF-8 and then the SHA256 algorithm is applied
245 // as defined in RFC 4634. The raw hash is then encoded with Base64 before returning.
246 // Terraform uses the "standard" Base64 alphabet as defined in RFC 4648 section 4
247 func Base64Sha512(str cty.Value) (cty.Value, error) {
248 return Base64Sha512Func.Call([]cty.Value{str})
249 }
250
251 // Bcrypt computes a hash of the given string using the Blowfish cipher,
252 // returning a string in the Modular Crypt Format
253 // usually expected in the shadow password file on many Unix systems.
254 func Bcrypt(str cty.Value, cost ...cty.Value) (cty.Value, error) {
255 args := make([]cty.Value, len(cost)+1)
256 args[0] = str
257 copy(args[1:], cost)
258 return BcryptFunc.Call(args)
259 }
260
261 // Md5 computes the MD5 hash of a given string and encodes it with hexadecimal digits.
262 func Md5(str cty.Value) (cty.Value, error) {
263 return Md5Func.Call([]cty.Value{str})
264 }
265
266 // RsaDecrypt decrypts an RSA-encrypted ciphertext, returning the corresponding
267 // cleartext.
268 func RsaDecrypt(ciphertext, privatekey cty.Value) (cty.Value, error) {
269 return RsaDecryptFunc.Call([]cty.Value{ciphertext, privatekey})
270 }
271
272 // Sha1 computes the SHA1 hash of a given string and encodes it with hexadecimal digits.
273 func Sha1(str cty.Value) (cty.Value, error) {
274 return Sha1Func.Call([]cty.Value{str})
275 }
276
277 // Sha256 computes the SHA256 hash of a given string and encodes it with hexadecimal digits.
278 func Sha256(str cty.Value) (cty.Value, error) {
279 return Sha256Func.Call([]cty.Value{str})
280 }
281
282 // Sha512 computes the SHA512 hash of a given string and encodes it with hexadecimal digits.
283 func Sha512(str cty.Value) (cty.Value, error) {
284 return Sha512Func.Call([]cty.Value{str})
285 }