diff options
Diffstat (limited to 'vendor/github.com/hashicorp/terraform/lang/funcs/crypto.go')
-rw-r--r-- | vendor/github.com/hashicorp/terraform/lang/funcs/crypto.go | 285 |
1 files changed, 285 insertions, 0 deletions
diff --git a/vendor/github.com/hashicorp/terraform/lang/funcs/crypto.go b/vendor/github.com/hashicorp/terraform/lang/funcs/crypto.go new file mode 100644 index 0000000..5cb4bc5 --- /dev/null +++ b/vendor/github.com/hashicorp/terraform/lang/funcs/crypto.go | |||
@@ -0,0 +1,285 @@ | |||
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 | } | ||