comparison env/lib/python3.7/site-packages/boto/kms/layer1.py @ 0:26e78fe6e8c4 draft

"planemo upload commit c699937486c35866861690329de38ec1a5d9f783"
author shellac
date Sat, 02 May 2020 07:14:21 -0400
parents
children
comparison
equal deleted inserted replaced
-1:000000000000 0:26e78fe6e8c4
1 # Copyright (c) 2014 Amazon.com, Inc. or its affiliates. All Rights Reserved
2 #
3 # Permission is hereby granted, free of charge, to any person obtaining a
4 # copy of this software and associated documentation files (the
5 # "Software"), to deal in the Software without restriction, including
6 # without limitation the rights to use, copy, modify, merge, publish, dis-
7 # tribute, sublicense, and/or sell copies of the Software, and to permit
8 # persons to whom the Software is furnished to do so, subject to the fol-
9 # lowing conditions:
10 #
11 # The above copyright notice and this permission notice shall be included
12 # in all copies or substantial portions of the Software.
13 #
14 # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
15 # OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABIL-
16 # ITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT
17 # SHALL THE AUTHOR BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
18 # WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19 # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
20 # IN THE SOFTWARE.
21 #
22
23 import boto
24 from boto.compat import json
25 from boto.connection import AWSQueryConnection
26 from boto.regioninfo import RegionInfo
27 from boto.exception import JSONResponseError
28 from boto.kms import exceptions
29 from boto.compat import six
30 import base64
31
32
33 class KMSConnection(AWSQueryConnection):
34 """
35 AWS Key Management Service
36 AWS Key Management Service (KMS) is an encryption and key
37 management web service. This guide describes the KMS actions that
38 you can call programmatically. For general information about KMS,
39 see (need an address here). For the KMS developer guide, see (need
40 address here).
41
42 AWS provides SDKs that consist of libraries and sample code for
43 various programming languages and platforms (Java, Ruby, .Net,
44 iOS, Android, etc.). The SDKs provide a convenient way to create
45 programmatic access to KMS and AWS. For example, the SDKs take
46 care of tasks such as signing requests (see below), managing
47 errors, and retrying requests automatically. For more information
48 about the AWS SDKs, including how to download and install them,
49 see `Tools for Amazon Web Services`_.
50
51 We recommend that you use the AWS SDKs to make programmatic API
52 calls to KMS. However, you can also use the KMS Query API to make
53 to make direct calls to the KMS web service.
54
55 **Signing Requests**
56
57 Requests must be signed by using an access key ID and a secret
58 access key. We strongly recommend that you do not use your AWS
59 account access key ID and secret key for everyday work with KMS.
60 Instead, use the access key ID and secret access key for an IAM
61 user, or you can use the AWS Security Token Service to generate
62 temporary security credentials that you can use to sign requests.
63
64 All KMS operations require `Signature Version 4`_.
65
66 **Recording API Requests**
67
68 KMS supports AWS CloudTrail, a service that records AWS API calls
69 and related events for your AWS account and delivers them to an
70 Amazon S3 bucket that you specify. By using the information
71 collected by CloudTrail, you can determine what requests were made
72 to KMS, who made the request, when it was made, and so on. To
73 learn more about CloudTrail, including how to turn it on and find
74 your log files, see the `AWS CloudTrail User Guide`_
75
76 **Additional Resources**
77
78 For more information about credentials and request signing, see
79 the following:
80
81
82 + `AWS Security Credentials`_. This topic provides general
83 information about the types of credentials used for accessing AWS.
84 + `AWS Security Token Service`_. This guide describes how to
85 create and use temporary security credentials.
86 + `Signing AWS API Requests`_. This set of topics walks you
87 through the process of signing a request using an access key ID
88 and a secret access key.
89 """
90 APIVersion = "2014-11-01"
91 DefaultRegionName = "us-east-1"
92 DefaultRegionEndpoint = "kms.us-east-1.amazonaws.com"
93 ServiceName = "KMS"
94 TargetPrefix = "TrentService"
95 ResponseError = JSONResponseError
96
97 _faults = {
98 "InvalidGrantTokenException": exceptions.InvalidGrantTokenException,
99 "DisabledException": exceptions.DisabledException,
100 "LimitExceededException": exceptions.LimitExceededException,
101 "DependencyTimeoutException": exceptions.DependencyTimeoutException,
102 "InvalidMarkerException": exceptions.InvalidMarkerException,
103 "AlreadyExistsException": exceptions.AlreadyExistsException,
104 "InvalidCiphertextException": exceptions.InvalidCiphertextException,
105 "KeyUnavailableException": exceptions.KeyUnavailableException,
106 "InvalidAliasNameException": exceptions.InvalidAliasNameException,
107 "UnsupportedOperationException": exceptions.UnsupportedOperationException,
108 "InvalidArnException": exceptions.InvalidArnException,
109 "KMSInternalException": exceptions.KMSInternalException,
110 "InvalidKeyUsageException": exceptions.InvalidKeyUsageException,
111 "MalformedPolicyDocumentException": exceptions.MalformedPolicyDocumentException,
112 "NotFoundException": exceptions.NotFoundException,
113 }
114
115
116 def __init__(self, **kwargs):
117 region = kwargs.pop('region', None)
118 if not region:
119 region = RegionInfo(self, self.DefaultRegionName,
120 self.DefaultRegionEndpoint)
121
122 if 'host' not in kwargs or kwargs['host'] is None:
123 kwargs['host'] = region.endpoint
124
125 super(KMSConnection, self).__init__(**kwargs)
126 self.region = region
127
128 def _required_auth_capability(self):
129 return ['hmac-v4']
130
131 def create_alias(self, alias_name, target_key_id):
132 """
133 Creates a display name for a customer master key. An alias can
134 be used to identify a key and should be unique. The console
135 enforces a one-to-one mapping between the alias and a key. An
136 alias name can contain only alphanumeric characters, forward
137 slashes (/), underscores (_), and dashes (-). An alias must
138 start with the word "alias" followed by a forward slash
139 (alias/). An alias that begins with "aws" after the forward
140 slash (alias/aws...) is reserved by Amazon Web Services (AWS).
141
142 :type alias_name: string
143 :param alias_name: String that contains the display name. Aliases that
144 begin with AWS are reserved.
145
146 :type target_key_id: string
147 :param target_key_id: An identifier of the key for which you are
148 creating the alias. This value cannot be another alias.
149
150 """
151 params = {
152 'AliasName': alias_name,
153 'TargetKeyId': target_key_id,
154 }
155 return self.make_request(action='CreateAlias',
156 body=json.dumps(params))
157
158 def create_grant(self, key_id, grantee_principal,
159 retiring_principal=None, operations=None,
160 constraints=None, grant_tokens=None):
161 """
162 Adds a grant to a key to specify who can access the key and
163 under what conditions. Grants are alternate permission
164 mechanisms to key policies. If absent, access to the key is
165 evaluated based on IAM policies attached to the user. By
166 default, grants do not expire. Grants can be listed, retired,
167 or revoked as indicated by the following APIs. Typically, when
168 you are finished using a grant, you retire it. When you want
169 to end a grant immediately, revoke it. For more information
170 about grants, see `Grants`_.
171
172 #. ListGrants
173 #. RetireGrant
174 #. RevokeGrant
175
176 :type key_id: string
177 :param key_id: A unique key identifier for a customer master key. This
178 value can be a globally unique identifier, an ARN, or an alias.
179
180 :type grantee_principal: string
181 :param grantee_principal: Principal given permission by the grant to
182 use the key identified by the `keyId` parameter.
183
184 :type retiring_principal: string
185 :param retiring_principal: Principal given permission to retire the
186 grant. For more information, see RetireGrant.
187
188 :type operations: list
189 :param operations: List of operations permitted by the grant. This can
190 be any combination of one or more of the following values:
191
192 #. Decrypt
193 #. Encrypt
194 #. GenerateDataKey
195 #. GenerateDataKeyWithoutPlaintext
196 #. ReEncryptFrom
197 #. ReEncryptTo
198 #. CreateGrant
199
200 :type constraints: dict
201 :param constraints: Specifies the conditions under which the actions
202 specified by the `Operations` parameter are allowed.
203
204 :type grant_tokens: list
205 :param grant_tokens: List of grant tokens.
206
207 """
208 params = {
209 'KeyId': key_id,
210 'GranteePrincipal': grantee_principal,
211 }
212 if retiring_principal is not None:
213 params['RetiringPrincipal'] = retiring_principal
214 if operations is not None:
215 params['Operations'] = operations
216 if constraints is not None:
217 params['Constraints'] = constraints
218 if grant_tokens is not None:
219 params['GrantTokens'] = grant_tokens
220 return self.make_request(action='CreateGrant',
221 body=json.dumps(params))
222
223 def create_key(self, policy=None, description=None, key_usage=None):
224 """
225 Creates a customer master key. Customer master keys can be
226 used to encrypt small amounts of data (less than 4K) directly,
227 but they are most commonly used to encrypt or envelope data
228 keys that are then used to encrypt customer data. For more
229 information about data keys, see GenerateDataKey and
230 GenerateDataKeyWithoutPlaintext.
231
232 :type policy: string
233 :param policy: Policy to be attached to the key. This is required and
234 delegates back to the account. The key is the root of trust.
235
236 :type description: string
237 :param description: Description of the key. We recommend that you
238 choose a description that helps your customer decide whether the
239 key is appropriate for a task.
240
241 :type key_usage: string
242 :param key_usage: Specifies the intended use of the key. Currently this
243 defaults to ENCRYPT/DECRYPT, and only symmetric encryption and
244 decryption are supported.
245
246 """
247 params = {}
248 if policy is not None:
249 params['Policy'] = policy
250 if description is not None:
251 params['Description'] = description
252 if key_usage is not None:
253 params['KeyUsage'] = key_usage
254 return self.make_request(action='CreateKey',
255 body=json.dumps(params))
256
257 def decrypt(self, ciphertext_blob, encryption_context=None,
258 grant_tokens=None):
259 """
260 Decrypts ciphertext. Ciphertext is plaintext that has been
261 previously encrypted by using the Encrypt function.
262
263 :type ciphertext_blob: blob
264 :param ciphertext_blob: Ciphertext including metadata.
265
266 :type encryption_context: map
267 :param encryption_context: The encryption context. If this was
268 specified in the Encrypt function, it must be specified here or the
269 decryption operation will fail. For more information, see
270 `Encryption Context`_.
271
272 :type grant_tokens: list
273 :param grant_tokens: A list of grant tokens that represent grants which
274 can be used to provide long term permissions to perform decryption.
275
276 """
277 if not isinstance(ciphertext_blob, six.binary_type):
278 raise TypeError(
279 "Value of argument ``ciphertext_blob`` "
280 "must be of type %s." % six.binary_type)
281 ciphertext_blob = base64.b64encode(ciphertext_blob)
282 params = {'CiphertextBlob': ciphertext_blob.decode('utf-8'), }
283 if encryption_context is not None:
284 params['EncryptionContext'] = encryption_context
285 if grant_tokens is not None:
286 params['GrantTokens'] = grant_tokens
287 response = self.make_request(action='Decrypt',
288 body=json.dumps(params))
289 if response.get('Plaintext') is not None:
290 response['Plaintext'] = base64.b64decode(
291 response['Plaintext'].encode('utf-8'))
292 return response
293
294 def delete_alias(self, alias_name):
295 """
296 Deletes the specified alias.
297
298 :type alias_name: string
299 :param alias_name: The alias to be deleted.
300
301 """
302 params = {'AliasName': alias_name, }
303 return self.make_request(action='DeleteAlias',
304 body=json.dumps(params))
305
306 def describe_key(self, key_id):
307 """
308 Provides detailed information about the specified customer
309 master key.
310
311 :type key_id: string
312 :param key_id: Unique identifier of the customer master key to be
313 described. This can be an ARN, an alias, or a globally unique
314 identifier.
315
316 """
317 params = {'KeyId': key_id, }
318 return self.make_request(action='DescribeKey',
319 body=json.dumps(params))
320
321 def disable_key(self, key_id):
322 """
323 Marks a key as disabled, thereby preventing its use.
324
325 :type key_id: string
326 :param key_id: Unique identifier of the customer master key to be
327 disabled. This can be an ARN, an alias, or a globally unique
328 identifier.
329
330 """
331 params = {'KeyId': key_id, }
332 return self.make_request(action='DisableKey',
333 body=json.dumps(params))
334
335 def disable_key_rotation(self, key_id):
336 """
337 Disables rotation of the specified key.
338
339 :type key_id: string
340 :param key_id: Unique identifier of the customer master key for which
341 rotation is to be disabled. This can be an ARN, an alias, or a
342 globally unique identifier.
343
344 """
345 params = {'KeyId': key_id, }
346 return self.make_request(action='DisableKeyRotation',
347 body=json.dumps(params))
348
349 def enable_key(self, key_id):
350 """
351 Marks a key as enabled, thereby permitting its use. You can
352 have up to 25 enabled keys at one time.
353
354 :type key_id: string
355 :param key_id: Unique identifier of the customer master key to be
356 enabled. This can be an ARN, an alias, or a globally unique
357 identifier.
358
359 """
360 params = {'KeyId': key_id, }
361 return self.make_request(action='EnableKey',
362 body=json.dumps(params))
363
364 def enable_key_rotation(self, key_id):
365 """
366 Enables rotation of the specified customer master key.
367
368 :type key_id: string
369 :param key_id: Unique identifier of the customer master key for which
370 rotation is to be enabled. This can be an ARN, an alias, or a
371 globally unique identifier.
372
373 """
374 params = {'KeyId': key_id, }
375 return self.make_request(action='EnableKeyRotation',
376 body=json.dumps(params))
377
378 def encrypt(self, key_id, plaintext, encryption_context=None,
379 grant_tokens=None):
380 """
381 Encrypts plaintext into ciphertext by using a customer master
382 key.
383
384 :type key_id: string
385 :param key_id: Unique identifier of the customer master. This can be an
386 ARN, an alias, or the Key ID.
387
388 :type plaintext: blob
389 :param plaintext: Data to be encrypted.
390
391 :type encryption_context: map
392 :param encryption_context: Name:value pair that specifies the
393 encryption context to be used for authenticated encryption. For
394 more information, see `Authenticated Encryption`_.
395
396 :type grant_tokens: list
397 :param grant_tokens: A list of grant tokens that represent grants which
398 can be used to provide long term permissions to perform encryption.
399
400 """
401 if not isinstance(plaintext, six.binary_type):
402 raise TypeError(
403 "Value of argument ``plaintext`` "
404 "must be of type %s." % six.binary_type)
405 plaintext = base64.b64encode(plaintext)
406 params = {'KeyId': key_id, 'Plaintext': plaintext.decode('utf-8'), }
407 if encryption_context is not None:
408 params['EncryptionContext'] = encryption_context
409 if grant_tokens is not None:
410 params['GrantTokens'] = grant_tokens
411 response = self.make_request(action='Encrypt',
412 body=json.dumps(params))
413 if response.get('CiphertextBlob') is not None:
414 response['CiphertextBlob'] = base64.b64decode(
415 response['CiphertextBlob'].encode('utf-8'))
416 return response
417
418 def generate_data_key(self, key_id, encryption_context=None,
419 number_of_bytes=None, key_spec=None,
420 grant_tokens=None):
421 """
422 Generates a secure data key. Data keys are used to encrypt and
423 decrypt data. They are wrapped by customer master keys.
424
425 :type key_id: string
426 :param key_id: Unique identifier of the key. This can be an ARN, an
427 alias, or a globally unique identifier.
428
429 :type encryption_context: map
430 :param encryption_context: Name/value pair that contains additional
431 data to be authenticated during the encryption and decryption
432 processes that use the key. This value is logged by AWS CloudTrail
433 to provide context around the data encrypted by the key.
434
435 :type number_of_bytes: integer
436 :param number_of_bytes: Integer that contains the number of bytes to
437 generate. Common values are 128, 256, 512, 1024 and so on. 1024 is
438 the current limit.
439
440 :type key_spec: string
441 :param key_spec: Value that identifies the encryption algorithm and key
442 size to generate a data key for. Currently this can be AES_128 or
443 AES_256.
444
445 :type grant_tokens: list
446 :param grant_tokens: A list of grant tokens that represent grants which
447 can be used to provide long term permissions to generate a key.
448
449 """
450 params = {'KeyId': key_id, }
451 if encryption_context is not None:
452 params['EncryptionContext'] = encryption_context
453 if number_of_bytes is not None:
454 params['NumberOfBytes'] = number_of_bytes
455 if key_spec is not None:
456 params['KeySpec'] = key_spec
457 if grant_tokens is not None:
458 params['GrantTokens'] = grant_tokens
459 response = self.make_request(action='GenerateDataKey',
460 body=json.dumps(params))
461 if response.get('CiphertextBlob') is not None:
462 response['CiphertextBlob'] = base64.b64decode(
463 response['CiphertextBlob'].encode('utf-8'))
464 if response.get('Plaintext') is not None:
465 response['Plaintext'] = base64.b64decode(
466 response['Plaintext'].encode('utf-8'))
467 return response
468
469 def generate_data_key_without_plaintext(self, key_id,
470 encryption_context=None,
471 key_spec=None,
472 number_of_bytes=None,
473 grant_tokens=None):
474 """
475 Returns a key wrapped by a customer master key without the
476 plaintext copy of that key. To retrieve the plaintext, see
477 GenerateDataKey.
478
479 :type key_id: string
480 :param key_id: Unique identifier of the key. This can be an ARN, an
481 alias, or a globally unique identifier.
482
483 :type encryption_context: map
484 :param encryption_context: Name:value pair that contains additional
485 data to be authenticated during the encryption and decryption
486 processes.
487
488 :type key_spec: string
489 :param key_spec: Value that identifies the encryption algorithm and key
490 size. Currently this can be AES_128 or AES_256.
491
492 :type number_of_bytes: integer
493 :param number_of_bytes: Integer that contains the number of bytes to
494 generate. Common values are 128, 256, 512, 1024 and so on.
495
496 :type grant_tokens: list
497 :param grant_tokens: A list of grant tokens that represent grants which
498 can be used to provide long term permissions to generate a key.
499
500 """
501 params = {'KeyId': key_id, }
502 if encryption_context is not None:
503 params['EncryptionContext'] = encryption_context
504 if key_spec is not None:
505 params['KeySpec'] = key_spec
506 if number_of_bytes is not None:
507 params['NumberOfBytes'] = number_of_bytes
508 if grant_tokens is not None:
509 params['GrantTokens'] = grant_tokens
510 response = self.make_request(action='GenerateDataKeyWithoutPlaintext',
511 body=json.dumps(params))
512 if response.get('CiphertextBlob') is not None:
513 response['CiphertextBlob'] = base64.b64decode(
514 response['CiphertextBlob'].encode('utf-8'))
515 return response
516
517 def generate_random(self, number_of_bytes=None):
518 """
519 Generates an unpredictable byte string.
520
521 :type number_of_bytes: integer
522 :param number_of_bytes: Integer that contains the number of bytes to
523 generate. Common values are 128, 256, 512, 1024 and so on. The
524 current limit is 1024 bytes.
525
526 """
527 params = {}
528 if number_of_bytes is not None:
529 params['NumberOfBytes'] = number_of_bytes
530 response = self.make_request(action='GenerateRandom',
531 body=json.dumps(params))
532 if response.get('Plaintext') is not None:
533 response['Plaintext'] = base64.b64decode(
534 response['Plaintext'].encode('utf-8'))
535 return response
536
537 def get_key_policy(self, key_id, policy_name):
538 """
539 Retrieves a policy attached to the specified key.
540
541 :type key_id: string
542 :param key_id: Unique identifier of the key. This can be an ARN, an
543 alias, or a globally unique identifier.
544
545 :type policy_name: string
546 :param policy_name: String that contains the name of the policy.
547 Currently, this must be "default". Policy names can be discovered
548 by calling ListKeyPolicies.
549
550 """
551 params = {'KeyId': key_id, 'PolicyName': policy_name, }
552 return self.make_request(action='GetKeyPolicy',
553 body=json.dumps(params))
554
555 def get_key_rotation_status(self, key_id):
556 """
557 Retrieves a Boolean value that indicates whether key rotation
558 is enabled for the specified key.
559
560 :type key_id: string
561 :param key_id: Unique identifier of the key. This can be an ARN, an
562 alias, or a globally unique identifier.
563
564 """
565 params = {'KeyId': key_id, }
566 return self.make_request(action='GetKeyRotationStatus',
567 body=json.dumps(params))
568
569 def list_aliases(self, limit=None, marker=None):
570 """
571 Lists all of the key aliases in the account.
572
573 :type limit: integer
574 :param limit: Specify this parameter when paginating results to
575 indicate the maximum number of aliases you want in each response.
576 If there are additional aliases beyond the maximum you specify, the
577 `Truncated` response element will be set to `true.`
578
579 :type marker: string
580 :param marker: Use this parameter when paginating results, and only in
581 a subsequent request after you've received a response where the
582 results are truncated. Set it to the value of the `NextMarker`
583 element in the response you just received.
584
585 """
586 params = {}
587 if limit is not None:
588 params['Limit'] = limit
589 if marker is not None:
590 params['Marker'] = marker
591 return self.make_request(action='ListAliases',
592 body=json.dumps(params))
593
594 def list_grants(self, key_id, limit=None, marker=None):
595 """
596 List the grants for a specified key.
597
598 :type key_id: string
599 :param key_id: Unique identifier of the key. This can be an ARN, an
600 alias, or a globally unique identifier.
601
602 :type limit: integer
603 :param limit: Specify this parameter only when paginating results to
604 indicate the maximum number of grants you want listed in the
605 response. If there are additional grants beyond the maximum you
606 specify, the `Truncated` response element will be set to `true.`
607
608 :type marker: string
609 :param marker: Use this parameter only when paginating results, and
610 only in a subsequent request after you've received a response where
611 the results are truncated. Set it to the value of the `NextMarker`
612 in the response you just received.
613
614 """
615 params = {'KeyId': key_id, }
616 if limit is not None:
617 params['Limit'] = limit
618 if marker is not None:
619 params['Marker'] = marker
620 return self.make_request(action='ListGrants',
621 body=json.dumps(params))
622
623 def list_key_policies(self, key_id, limit=None, marker=None):
624 """
625 Retrieves a list of policies attached to a key.
626
627 :type key_id: string
628 :param key_id: Unique identifier of the key. This can be an ARN, an
629 alias, or a globally unique identifier.
630
631 :type limit: integer
632 :param limit: Specify this parameter only when paginating results to
633 indicate the maximum number of policies you want listed in the
634 response. If there are additional policies beyond the maximum you
635 specify, the `Truncated` response element will be set to `true.`
636
637 :type marker: string
638 :param marker: Use this parameter only when paginating results, and
639 only in a subsequent request after you've received a response where
640 the results are truncated. Set it to the value of the `NextMarker`
641 in the response you just received.
642
643 """
644 params = {'KeyId': key_id, }
645 if limit is not None:
646 params['Limit'] = limit
647 if marker is not None:
648 params['Marker'] = marker
649 return self.make_request(action='ListKeyPolicies',
650 body=json.dumps(params))
651
652 def list_keys(self, limit=None, marker=None):
653 """
654 Lists the customer master keys.
655
656 :type limit: integer
657 :param limit: Specify this parameter only when paginating results to
658 indicate the maximum number of keys you want listed in the
659 response. If there are additional keys beyond the maximum you
660 specify, the `Truncated` response element will be set to `true.`
661
662 :type marker: string
663 :param marker: Use this parameter only when paginating results, and
664 only in a subsequent request after you've received a response where
665 the results are truncated. Set it to the value of the `NextMarker`
666 in the response you just received.
667
668 """
669 params = {}
670 if limit is not None:
671 params['Limit'] = limit
672 if marker is not None:
673 params['Marker'] = marker
674 return self.make_request(action='ListKeys',
675 body=json.dumps(params))
676
677 def put_key_policy(self, key_id, policy_name, policy):
678 """
679 Attaches a policy to the specified key.
680
681 :type key_id: string
682 :param key_id: Unique identifier of the key. This can be an ARN, an
683 alias, or a globally unique identifier.
684
685 :type policy_name: string
686 :param policy_name: Name of the policy to be attached. Currently, the
687 only supported name is "default".
688
689 :type policy: string
690 :param policy: The policy, in JSON format, to be attached to the key.
691
692 """
693 params = {
694 'KeyId': key_id,
695 'PolicyName': policy_name,
696 'Policy': policy,
697 }
698 return self.make_request(action='PutKeyPolicy',
699 body=json.dumps(params))
700
701 def re_encrypt(self, ciphertext_blob, destination_key_id,
702 source_encryption_context=None,
703 destination_encryption_context=None, grant_tokens=None):
704 """
705 Encrypts data on the server side with a new customer master
706 key without exposing the plaintext of the data on the client
707 side. The data is first decrypted and then encrypted. This
708 operation can also be used to change the encryption context of
709 a ciphertext.
710
711 :type ciphertext_blob: blob
712 :param ciphertext_blob: Ciphertext of the data to re-encrypt.
713
714 :type source_encryption_context: map
715 :param source_encryption_context: Encryption context used to encrypt
716 and decrypt the data specified in the `CiphertextBlob` parameter.
717
718 :type destination_key_id: string
719 :param destination_key_id: Key identifier of the key used to re-encrypt
720 the data.
721
722 :type destination_encryption_context: map
723 :param destination_encryption_context: Encryption context to be used
724 when the data is re-encrypted.
725
726 :type grant_tokens: list
727 :param grant_tokens: Grant tokens that identify the grants that have
728 permissions for the encryption and decryption process.
729
730 """
731 if not isinstance(ciphertext_blob, six.binary_type):
732 raise TypeError(
733 "Value of argument ``ciphertext_blob`` "
734 "must be of type %s." % six.binary_type)
735 ciphertext_blob = base64.b64encode(ciphertext_blob)
736 params = {
737 'CiphertextBlob': ciphertext_blob,
738 'DestinationKeyId': destination_key_id,
739 }
740 if source_encryption_context is not None:
741 params['SourceEncryptionContext'] = source_encryption_context
742 if destination_encryption_context is not None:
743 params['DestinationEncryptionContext'] = destination_encryption_context
744 if grant_tokens is not None:
745 params['GrantTokens'] = grant_tokens
746 response = self.make_request(action='ReEncrypt',
747 body=json.dumps(params))
748 if response.get('CiphertextBlob') is not None:
749 response['CiphertextBlob'] = base64.b64decode(
750 response['CiphertextBlob'].encode('utf-8'))
751 return response
752
753 def retire_grant(self, grant_token):
754 """
755 Retires a grant. You can retire a grant when you're done using
756 it to clean up. You should revoke a grant when you intend to
757 actively deny operations that depend on it.
758
759 :type grant_token: string
760 :param grant_token: Token that identifies the grant to be retired.
761
762 """
763 params = {'GrantToken': grant_token, }
764 return self.make_request(action='RetireGrant',
765 body=json.dumps(params))
766
767 def revoke_grant(self, key_id, grant_id):
768 """
769 Revokes a grant. You can revoke a grant to actively deny
770 operations that depend on it.
771
772 :type key_id: string
773 :param key_id: Unique identifier of the key associated with the grant.
774
775 :type grant_id: string
776 :param grant_id: Identifier of the grant to be revoked.
777
778 """
779 params = {'KeyId': key_id, 'GrantId': grant_id, }
780 return self.make_request(action='RevokeGrant',
781 body=json.dumps(params))
782
783 def update_key_description(self, key_id, description):
784 """
785
786
787 :type key_id: string
788 :param key_id:
789
790 :type description: string
791 :param description:
792
793 """
794 params = {'KeyId': key_id, 'Description': description, }
795 return self.make_request(action='UpdateKeyDescription',
796 body=json.dumps(params))
797
798 def make_request(self, action, body):
799 headers = {
800 'X-Amz-Target': '%s.%s' % (self.TargetPrefix, action),
801 'Host': self.region.endpoint,
802 'Content-Type': 'application/x-amz-json-1.1',
803 'Content-Length': str(len(body)),
804 }
805 http_request = self.build_base_http_request(
806 method='POST', path='/', auth_path='/', params={},
807 headers=headers, data=body)
808 response = self._mexe(http_request, sender=None,
809 override_num_retries=10)
810 response_body = response.read().decode('utf-8')
811 boto.log.debug(response_body)
812 if response.status == 200:
813 if response_body:
814 return json.loads(response_body)
815 else:
816 json_body = json.loads(response_body)
817 fault_name = json_body.get('__type', None)
818 exception_class = self._faults.get(fault_name, self.ResponseError)
819 raise exception_class(response.status, response.reason,
820 body=json_body)
821