PyKMIP library version 0.0.1
This implementation supports version 1.1 of the KMIP spec. The
library supports the following operations for SymmetricKey objects:
create
register
get
destroy
Peter Hamilton
9 years ago
0 | /* FIXME Insert a license here */ | |
0 | Apache License | |
1 | Version 2.0, January 2004 | |
2 | http://www.apache.org/licenses/ | |
3 | ||
4 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION | |
5 | ||
6 | 1. Definitions. | |
7 | ||
8 | "License" shall mean the terms and conditions for use, reproduction, | |
9 | and distribution as defined by Sections 1 through 9 of this document. | |
10 | ||
11 | "Licensor" shall mean the copyright owner or entity authorized by | |
12 | the copyright owner that is granting the License. | |
13 | ||
14 | "Legal Entity" shall mean the union of the acting entity and all | |
15 | other entities that control, are controlled by, or are under common | |
16 | control with that entity. For the purposes of this definition, | |
17 | "control" means (i) the power, direct or indirect, to cause the | |
18 | direction or management of such entity, whether by contract or | |
19 | otherwise, or (ii) ownership of fifty percent (50%) or more of the | |
20 | outstanding shares, or (iii) beneficial ownership of such entity. | |
21 | ||
22 | "You" (or "Your") shall mean an individual or Legal Entity | |
23 | exercising permissions granted by this License. | |
24 | ||
25 | "Source" form shall mean the preferred form for making modifications, | |
26 | including but not limited to software source code, documentation | |
27 | source, and configuration files. | |
28 | ||
29 | "Object" form shall mean any form resulting from mechanical | |
30 | transformation or translation of a Source form, including but | |
31 | not limited to compiled object code, generated documentation, | |
32 | and conversions to other media types. | |
33 | ||
34 | "Work" shall mean the work of authorship, whether in Source or | |
35 | Object form, made available under the License, as indicated by a | |
36 | copyright notice that is included in or attached to the work | |
37 | (an example is provided in the Appendix below). | |
38 | ||
39 | "Derivative Works" shall mean any work, whether in Source or Object | |
40 | form, that is based on (or derived from) the Work and for which the | |
41 | editorial revisions, annotations, elaborations, or other modifications | |
42 | represent, as a whole, an original work of authorship. For the purposes | |
43 | of this License, Derivative Works shall not include works that remain | |
44 | separable from, or merely link (or bind by name) to the interfaces of, | |
45 | the Work and Derivative Works thereof. | |
46 | ||
47 | "Contribution" shall mean any work of authorship, including | |
48 | the original version of the Work and any modifications or additions | |
49 | to that Work or Derivative Works thereof, that is intentionally | |
50 | submitted to Licensor for inclusion in the Work by the copyright owner | |
51 | or by an individual or Legal Entity authorized to submit on behalf of | |
52 | the copyright owner. For the purposes of this definition, "submitted" | |
53 | means any form of electronic, verbal, or written communication sent | |
54 | to the Licensor or its representatives, including but not limited to | |
55 | communication on electronic mailing lists, source code control systems, | |
56 | and issue tracking systems that are managed by, or on behalf of, the | |
57 | Licensor for the purpose of discussing and improving the Work, but | |
58 | excluding communication that is conspicuously marked or otherwise | |
59 | designated in writing by the copyright owner as "Not a Contribution." | |
60 | ||
61 | "Contributor" shall mean Licensor and any individual or Legal Entity | |
62 | on behalf of whom a Contribution has been received by Licensor and | |
63 | subsequently incorporated within the Work. | |
64 | ||
65 | 2. Grant of Copyright License. Subject to the terms and conditions of | |
66 | this License, each Contributor hereby grants to You a perpetual, | |
67 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable | |
68 | copyright license to reproduce, prepare Derivative Works of, | |
69 | publicly display, publicly perform, sublicense, and distribute the | |
70 | Work and such Derivative Works in Source or Object form. | |
71 | ||
72 | 3. Grant of Patent License. Subject to the terms and conditions of | |
73 | this License, each Contributor hereby grants to You a perpetual, | |
74 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable | |
75 | (except as stated in this section) patent license to make, have made, | |
76 | use, offer to sell, sell, import, and otherwise transfer the Work, | |
77 | where such license applies only to those patent claims licensable | |
78 | by such Contributor that are necessarily infringed by their | |
79 | Contribution(s) alone or by combination of their Contribution(s) | |
80 | with the Work to which such Contribution(s) was submitted. If You | |
81 | institute patent litigation against any entity (including a | |
82 | cross-claim or counterclaim in a lawsuit) alleging that the Work | |
83 | or a Contribution incorporated within the Work constitutes direct | |
84 | or contributory patent infringement, then any patent licenses | |
85 | granted to You under this License for that Work shall terminate | |
86 | as of the date such litigation is filed. | |
87 | ||
88 | 4. Redistribution. You may reproduce and distribute copies of the | |
89 | Work or Derivative Works thereof in any medium, with or without | |
90 | modifications, and in Source or Object form, provided that You | |
91 | meet the following conditions: | |
92 | ||
93 | (a) You must give any other recipients of the Work or | |
94 | Derivative Works a copy of this License; and | |
95 | ||
96 | (b) You must cause any modified files to carry prominent notices | |
97 | stating that You changed the files; and | |
98 | ||
99 | (c) You must retain, in the Source form of any Derivative Works | |
100 | that You distribute, all copyright, patent, trademark, and | |
101 | attribution notices from the Source form of the Work, | |
102 | excluding those notices that do not pertain to any part of | |
103 | the Derivative Works; and | |
104 | ||
105 | (d) If the Work includes a "NOTICE" text file as part of its | |
106 | distribution, then any Derivative Works that You distribute must | |
107 | include a readable copy of the attribution notices contained | |
108 | within such NOTICE file, excluding those notices that do not | |
109 | pertain to any part of the Derivative Works, in at least one | |
110 | of the following places: within a NOTICE text file distributed | |
111 | as part of the Derivative Works; within the Source form or | |
112 | documentation, if provided along with the Derivative Works; or, | |
113 | within a display generated by the Derivative Works, if and | |
114 | wherever such third-party notices normally appear. The contents | |
115 | of the NOTICE file are for informational purposes only and | |
116 | do not modify the License. You may add Your own attribution | |
117 | notices within Derivative Works that You distribute, alongside | |
118 | or as an addendum to the NOTICE text from the Work, provided | |
119 | that such additional attribution notices cannot be construed | |
120 | as modifying the License. | |
121 | ||
122 | You may add Your own copyright statement to Your modifications and | |
123 | may provide additional or different license terms and conditions | |
124 | for use, reproduction, or distribution of Your modifications, or | |
125 | for any such Derivative Works as a whole, provided Your use, | |
126 | reproduction, and distribution of the Work otherwise complies with | |
127 | the conditions stated in this License. | |
128 | ||
129 | 5. Submission of Contributions. Unless You explicitly state otherwise, | |
130 | any Contribution intentionally submitted for inclusion in the Work | |
131 | by You to the Licensor shall be under the terms and conditions of | |
132 | this License, without any additional terms or conditions. | |
133 | Notwithstanding the above, nothing herein shall supersede or modify | |
134 | the terms of any separate license agreement you may have executed | |
135 | with Licensor regarding such Contributions. | |
136 | ||
137 | 6. Trademarks. This License does not grant permission to use the trade | |
138 | names, trademarks, service marks, or product names of the Licensor, | |
139 | except as required for reasonable and customary use in describing the | |
140 | origin of the Work and reproducing the content of the NOTICE file. | |
141 | ||
142 | 7. Disclaimer of Warranty. Unless required by applicable law or | |
143 | agreed to in writing, Licensor provides the Work (and each | |
144 | Contributor provides its Contributions) on an "AS IS" BASIS, | |
145 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or | |
146 | implied, including, without limitation, any warranties or conditions | |
147 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A | |
148 | PARTICULAR PURPOSE. You are solely responsible for determining the | |
149 | appropriateness of using or redistributing the Work and assume any | |
150 | risks associated with Your exercise of permissions under this License. | |
151 | ||
152 | 8. Limitation of Liability. In no event and under no legal theory, | |
153 | whether in tort (including negligence), contract, or otherwise, | |
154 | unless required by applicable law (such as deliberate and grossly | |
155 | negligent acts) or agreed to in writing, shall any Contributor be | |
156 | liable to You for damages, including any direct, indirect, special, | |
157 | incidental, or consequential damages of any character arising as a | |
158 | result of this License or out of the use or inability to use the | |
159 | Work (including but not limited to damages for loss of goodwill, | |
160 | work stoppage, computer failure or malfunction, or any and all | |
161 | other commercial damages or losses), even if such Contributor | |
162 | has been advised of the possibility of such damages. | |
163 | ||
164 | 9. Accepting Warranty or Additional Liability. While redistributing | |
165 | the Work or Derivative Works thereof, You may choose to offer, | |
166 | and charge a fee for, acceptance of support, warranty, indemnity, | |
167 | or other liability obligations and/or rights consistent with this | |
168 | License. However, in accepting such obligations, You may act only | |
169 | on Your own behalf and on Your sole responsibility, not on behalf | |
170 | of any other Contributor, and only if You agree to indemnify, | |
171 | defend, and hold each Contributor harmless for any liability | |
172 | incurred by, or claims asserted against, such Contributor by reason | |
173 | of your accepting any such warranty or additional liability. | |
174 | ||
175 | END OF TERMS AND CONDITIONS | |
176 | ||
177 | APPENDIX: How to apply the Apache License to your work. | |
178 | ||
179 | To apply the Apache License to your work, attach the following | |
180 | boilerplate notice, with the fields enclosed by brackets "[]" | |
181 | replaced with your own identifying information. (Don't include | |
182 | the brackets!) The text should be enclosed in the appropriate | |
183 | comment syntax for the file format. We also recommend that a | |
184 | file or class name and description of purpose be included on the | |
185 | same "printed page" as the copyright notice for easier | |
186 | identification within third-party archives. | |
187 | ||
188 | Copyright 2013, Rackspace (http://www.rackspace.com) | |
189 | ||
190 | Licensed under the Apache License, Version 2.0 (the "License"); | |
191 | you may not use this file except in compliance with the License. | |
192 | You may obtain a copy of the License at | |
193 | ||
194 | http://www.apache.org/licenses/LICENSE-2.0 | |
195 | ||
196 | Unless required by applicable law or agreed to in writing, software | |
197 | distributed under the License is distributed on an "AS IS" BASIS, | |
198 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |
199 | See the License for the specific language governing permissions and | |
200 | limitations under the License. |
0 | # Copyright (c) 2014 The Johns Hopkins University/Applied Physics Laboratory | |
1 | # All Rights Reserved. | |
2 | # | |
3 | # Licensed under the Apache License, Version 2.0 (the "License"); you may | |
4 | # not use this file except in compliance with the License. You may obtain | |
5 | # a copy of the License at | |
6 | # | |
7 | # http://www.apache.org/licenses/LICENSE-2.0 | |
8 | # | |
9 | # Unless required by applicable law or agreed to in writing, software | |
10 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT | |
11 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the | |
12 | # License for the specific language governing permissions and limitations | |
13 | # under the License. | |
14 | ||
15 | import logging | |
16 | import optparse | |
17 | import sys | |
18 | ||
19 | from thrift.server import TServer | |
20 | from thrift.transport import TSocket | |
21 | from thrift.transport import TTransport | |
22 | ||
23 | from kmip.core.server import KMIPImpl | |
24 | ||
25 | from kmip.services.kmip_protocol import KMIPProtocolFactory | |
26 | from kmip.services.kmip_server import Processor | |
27 | ||
28 | ||
29 | def run_server(host='127.0.0.1', port=5696): | |
30 | logger = logging.getLogger(__name__) | |
31 | ||
32 | handler = KMIPImpl() | |
33 | processor = Processor(handler) | |
34 | transport = TSocket.TServerSocket(host, port) | |
35 | tfactory = TTransport.TBufferedTransportFactory() | |
36 | pfactory = KMIPProtocolFactory() | |
37 | server = TServer.TSimpleServer(processor, transport, tfactory, pfactory) | |
38 | ||
39 | logger.info('Starting the KMIP server') | |
40 | ||
41 | try: | |
42 | server.serve() | |
43 | except KeyboardInterrupt: | |
44 | logger.info('KeyboardInterrupt received while serving') | |
45 | except Exception, e: | |
46 | logger.info('Exception received while serving: {0}'.format(e)) | |
47 | finally: | |
48 | transport.close() | |
49 | ||
50 | logger.info('Shutting down KMIP server') | |
51 | ||
52 | ||
53 | def build_cli_parser(): | |
54 | parser = optparse.OptionParser(usage="%prog [options]", | |
55 | description="Run KMIP Server") | |
56 | parser.add_option("-n", "--hostname", action="store", default='127.0.0.1', | |
57 | dest="hostname", | |
58 | help="Hostname/IP address of platform running the KMIP " | |
59 | "server (e.g., localhost, 127.0.0.1)") | |
60 | parser.add_option("-p", "--port", action="store", default=5696, | |
61 | dest="port", help="Port number for KMIP services") | |
62 | return parser | |
63 | ||
64 | if __name__ == '__main__': | |
65 | parser = build_cli_parser() | |
66 | ||
67 | opts, args = parser.parse_args(sys.argv[1:]) | |
68 | ||
69 | run_server(opts.hostname, opts.port) |
0 | PyKMIP documentation goes here.⏎ |
0 | # Copyright (c) 2014 The Johns Hopkins University/Applied Physics Laboratory | |
1 | # All Rights Reserved. | |
2 | # | |
3 | # Licensed under the Apache License, Version 2.0 (the "License"); you may | |
4 | # not use this file except in compliance with the License. You may obtain | |
5 | # a copy of the License at | |
6 | # | |
7 | # http://www.apache.org/licenses/LICENSE-2.0 | |
8 | # | |
9 | # Unless required by applicable law or agreed to in writing, software | |
10 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT | |
11 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the | |
12 | # License for the specific language governing permissions and limitations | |
13 | # under the License. | |
14 | ||
15 | import logging.config | |
16 | import os | |
17 | import sys | |
18 | ||
19 | path = os.path.join(os.path.dirname(__file__), 'logconfig.ini') | |
20 | ||
21 | if os.path.exists(path): | |
22 | logging.config.fileConfig(path) | |
23 | else: | |
24 | minor_version = sys.version_info[1] | |
25 | ||
26 | if minor_version == 7: | |
27 | config = { | |
28 | 'version': 1, | |
29 | 'disable_existing_loggers': False, | |
30 | 'formatters': { | |
31 | 'simpleFormatter': { | |
32 | 'format': | |
33 | '%(asctime)s - %(name)s - %(levelname)s - %(message)s' | |
34 | } | |
35 | }, | |
36 | 'handlers': { | |
37 | 'consoleHandler': { | |
38 | 'level': 'DEBUG', | |
39 | 'class': 'logging.StreamHandler', | |
40 | 'formatter': 'simpleFormatter', | |
41 | 'stream': sys.stdout | |
42 | } | |
43 | }, | |
44 | 'loggers': { | |
45 | 'root': { | |
46 | 'level': 'DEBUG', | |
47 | 'handlers': ['consoleHandler'] | |
48 | } | |
49 | } | |
50 | } | |
51 | ||
52 | logging.config.dictConfig(config) | |
53 | else: | |
54 | logging.basicConfig() | |
55 | ||
56 | __all__ = ['test', 'transport'] |
0 | # Copyright (c) 2014 The Johns Hopkins University/Applied Physics Laboratory | |
1 | # All Rights Reserved. | |
2 | # | |
3 | # Licensed under the Apache License, Version 2.0 (the "License"); you may | |
4 | # not use this file except in compliance with the License. You may obtain | |
5 | # a copy of the License at | |
6 | # | |
7 | # http://www.apache.org/licenses/LICENSE-2.0 | |
8 | # | |
9 | # Unless required by applicable law or agreed to in writing, software | |
10 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT | |
11 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the | |
12 | # License for the specific language governing permissions and limitations | |
13 | # under the License. | |
14 | ||
15 | __all__ = ['attributes', 'enums', 'errors', 'messages', 'objects', | |
16 | 'primitives', 'protocol', 'utils'] |
0 | # Copyright (c) 2014 The Johns Hopkins University/Applied Physics Laboratory | |
1 | # All Rights Reserved. | |
2 | # | |
3 | # Licensed under the Apache License, Version 2.0 (the "License"); you may | |
4 | # not use this file except in compliance with the License. You may obtain | |
5 | # a copy of the License at | |
6 | # | |
7 | # http://www.apache.org/licenses/LICENSE-2.0 | |
8 | # | |
9 | # Unless required by applicable law or agreed to in writing, software | |
10 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT | |
11 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the | |
12 | # License for the specific language governing permissions and limitations | |
13 | # under the License. | |
14 | ||
15 | import enums | |
16 | ||
17 | from kmip.core.enums import Tags | |
18 | ||
19 | from kmip.core.errors import ErrorStrings | |
20 | ||
21 | from kmip.core.primitives import Struct | |
22 | from kmip.core.primitives import Integer | |
23 | from kmip.core.primitives import Enumeration | |
24 | from kmip.core.primitives import TextString | |
25 | ||
26 | from utils import BytearrayStream | |
27 | ||
28 | ||
29 | # 3.1 | |
30 | class UniqueIdentifier(TextString): | |
31 | ||
32 | def __init__(self, value=None): | |
33 | super(self.__class__, self).__init__(value, | |
34 | Tags.UNIQUE_IDENTIFIER) | |
35 | ||
36 | ||
37 | # 3.2 | |
38 | class Name(Struct): | |
39 | ||
40 | class NameValue(TextString): | |
41 | ||
42 | def __init__(self, value=None): | |
43 | super(self.__class__, self).__init__(value, Tags.NAME_VALUE) | |
44 | ||
45 | class NameType(Enumeration): | |
46 | ||
47 | ENUM_TYPE = enums.NameType | |
48 | ||
49 | def __init__(self, value=None): | |
50 | super(self.__class__, self).__init__(value, Tags.NAME_TYPE) | |
51 | ||
52 | def __init__(self, name_value=None, name_type=None): | |
53 | super(self.__class__, self).__init__(tag=Tags.NAME) | |
54 | self.name_value = name_value | |
55 | self.name_type = name_type | |
56 | ||
57 | def read(self, istream): | |
58 | super(self.__class__, self).read(istream) | |
59 | tstream = BytearrayStream(istream.read(self.length)) | |
60 | ||
61 | # Read the value and type of the name | |
62 | self.name_value = Name.NameValue() | |
63 | self.name_type = Name.NameType() | |
64 | self.name_value.read(tstream) | |
65 | self.name_type.read(tstream) | |
66 | ||
67 | self.is_oversized(tstream) | |
68 | ||
69 | def write(self, ostream): | |
70 | tstream = BytearrayStream() | |
71 | ||
72 | # Write the value and type of the name | |
73 | self.name_value.write(tstream) | |
74 | self.name_type.write(tstream) | |
75 | ||
76 | # Write the length and value of the template attribute | |
77 | self.length = tstream.length() | |
78 | super(self.__class__, self).write(ostream) | |
79 | ostream.write(tstream.buffer) | |
80 | ||
81 | def validate(self): | |
82 | self.__validate() | |
83 | ||
84 | def __validate(self): | |
85 | # TODO (peter-hamilton) Finish implementation. | |
86 | pass | |
87 | ||
88 | @classmethod | |
89 | def create(cls, name_value, name_type): | |
90 | value = cls.NameValue(name_value) | |
91 | n_type = cls.NameType(name_type) | |
92 | return Name(name_value=value, | |
93 | name_type=n_type) | |
94 | ||
95 | ||
96 | # 3.3 | |
97 | class ObjectType(Enumeration): | |
98 | ||
99 | ENUM_TYPE = enums.ObjectType | |
100 | ||
101 | def __init__(self, value=None): | |
102 | super(self.__class__, self).__init__(value, Tags.OBJECT_TYPE) | |
103 | ||
104 | ||
105 | # 3.4 | |
106 | class CryptographicAlgorithm(Enumeration): | |
107 | ||
108 | ENUM_TYPE = enums.CryptographicAlgorithm | |
109 | ||
110 | def __init__(self, value=None): | |
111 | super(self.__class__, self).__init__(value, | |
112 | Tags.CRYPTOGRAPHIC_ALGORITHM) | |
113 | ||
114 | ||
115 | # 3.5 | |
116 | class CryptographicLength(Integer): | |
117 | ||
118 | def __init__(self, value=None): | |
119 | super(self.__class__, self).__init__(value, | |
120 | Tags.CRYPTOGRAPHIC_LENGTH) | |
121 | ||
122 | ||
123 | # 3.6 | |
124 | class CryptographicParameters(Struct): | |
125 | ||
126 | class BlockCipherMode(Enumeration): | |
127 | ENUM_TYPE = enums.BlockCipherMode | |
128 | ||
129 | def __init__(self, value=None): | |
130 | super(self.__class__, self).__init__(value, | |
131 | Tags.BLOCK_CIPHER_MODE) | |
132 | ||
133 | class PaddingMethod(Enumeration): | |
134 | ENUM_TYPE = enums.PaddingMethod | |
135 | ||
136 | def __init__(self, value=None): | |
137 | super(self.__class__, self).__init__(value, | |
138 | Tags.PADDING_METHOD) | |
139 | ||
140 | class HashingAlgorithm(Enumeration): | |
141 | ENUM_TYPE = enums.HashingAlgorithm | |
142 | ||
143 | def __init__(self, value=None): | |
144 | super(self.__class__, self).__init__(value, | |
145 | Tags.HASHING_ALGORITHM) | |
146 | ||
147 | class KeyRoleType(Enumeration): | |
148 | ENUM_TYPE = enums.KeyRoleType | |
149 | ||
150 | def __init__(self, value=None): | |
151 | super(self.__class__, self).__init__(value, | |
152 | Tags.KEY_ROLE_TYPE) | |
153 | ||
154 | def __init__(self, | |
155 | block_cipher_mode=None, | |
156 | padding_method=None, | |
157 | hashing_algorithm=None, | |
158 | key_role_type=None): | |
159 | super(self.__class__, self).__init__(tag=Tags.CRYPTOGRAPHIC_PARAMETERS) | |
160 | self.block_cipher_mode = block_cipher_mode | |
161 | self.padding_method = padding_method | |
162 | self.hashing_algorithm = hashing_algorithm | |
163 | self.key_role_type = key_role_type | |
164 | ||
165 | def read(self, istream): | |
166 | super(self.__class__, self).read(istream) | |
167 | tstream = BytearrayStream(istream.read(self.length)) | |
168 | ||
169 | if self.is_tag_next(Tags.BLOCK_CIPHER_MODE, tstream): | |
170 | self.block_cipher_mode = CryptographicParameters.BlockCipherMode() | |
171 | self.block_cipher_mode.read(tstream) | |
172 | ||
173 | if self.is_tag_next(Tags.PADDING_METHOD, tstream): | |
174 | self.padding_method = CryptographicParameters.PaddingMethod() | |
175 | self.padding_method.read(tstream) | |
176 | ||
177 | if self.is_tag_next(Tags.HASHING_ALGORITHM, tstream): | |
178 | self.hashing_algorithm = CryptographicParameters.HashingAlgorithm() | |
179 | self.hashing_algorithm.read(tstream) | |
180 | ||
181 | if self.is_tag_next(Tags.KEY_ROLE_TYPE, tstream): | |
182 | self.key_role_type = CryptographicParameters.KeyRoleType() | |
183 | self.key_role_type.read(tstream) | |
184 | ||
185 | self.is_oversized(tstream) | |
186 | self.validate() | |
187 | ||
188 | def write(self, ostream): | |
189 | tstream = BytearrayStream() | |
190 | ||
191 | # Write the contents of the request payload | |
192 | if self.block_cipher_mode is not None: | |
193 | self.block_cipher_mode.write(tstream) | |
194 | if self.padding_method is not None: | |
195 | self.padding_method.write(tstream) | |
196 | if self.hashing_algorithm is not None: | |
197 | self.hashing_algorithm.write(tstream) | |
198 | if self.key_role_type is not None: | |
199 | self.key_role_type.write(tstream) | |
200 | ||
201 | # Write the length and value of the request payload | |
202 | self.length = tstream.length() | |
203 | super(self.__class__, self).write(ostream) | |
204 | ostream.write(tstream.buffer) | |
205 | ||
206 | def validate(self): | |
207 | self.__validate() | |
208 | ||
209 | def __validate(self): | |
210 | # TODO (peter-hamilton) Finish implementation. | |
211 | pass | |
212 | ||
213 | ||
214 | # 3.8 | |
215 | class CertificateType(Enumeration): | |
216 | ENUM_TYPE = enums.CertificateType | |
217 | ||
218 | def __init__(self, value=None): | |
219 | super(self.__class__, self).__init__(value, | |
220 | Tags.CERTIFICATE_TYPE) | |
221 | ||
222 | ||
223 | # 3.19 | |
224 | class CryptographicUsageMask(Integer): | |
225 | ||
226 | ENUM_TYPE = enums.CryptographicUsageMask | |
227 | ||
228 | def __init__(self, value=None): | |
229 | super(self.__class__, self).__init__(value, | |
230 | Tags.CRYPTOGRAPHIC_USAGE_MASK) | |
231 | ||
232 | ||
233 | # 3.33 | |
234 | class ObjectGroup(TextString): | |
235 | ||
236 | def __init__(self, value=None): | |
237 | super(self.__class__, | |
238 | self).__init__(value, Tags.OBJECT_GROUP) | |
239 | ||
240 | ||
241 | # 3.36 | |
242 | class ApplicationSpecificInformation(Struct): | |
243 | ||
244 | class ApplicationNamespace(TextString): | |
245 | ||
246 | def __init__(self, value=None): | |
247 | super(self.__class__, | |
248 | self).__init__(value, Tags.APPLICATION_NAMESPACE) | |
249 | ||
250 | class ApplicationData(TextString): | |
251 | ||
252 | def __init__(self, value=None): | |
253 | super(self.__class__, | |
254 | self).__init__(value, Tags.APPLICATION_DATA) | |
255 | ||
256 | def __init__(self, application_namespace=None, | |
257 | application_data=None): | |
258 | super(self.__class__, | |
259 | self).__init__(Tags.APPLICATION_SPECIFIC_INFORMATION) | |
260 | ||
261 | self.application_namespace = application_namespace | |
262 | self.application_data = application_data | |
263 | ||
264 | self.validate() | |
265 | ||
266 | def read(self, istream): | |
267 | super(self.__class__, self).read(istream) | |
268 | tstream = BytearrayStream(istream.read(self.length)) | |
269 | ||
270 | self.application_namespace = self.ApplicationNamespace() | |
271 | self.application_data = self.ApplicationData() | |
272 | ||
273 | self.application_namespace.read(tstream) | |
274 | self.application_data.read(tstream) | |
275 | ||
276 | self.is_oversized(tstream) | |
277 | self.validate() | |
278 | ||
279 | def write(self, ostream): | |
280 | tstream = BytearrayStream() | |
281 | ||
282 | self.application_namespace.write(tstream) | |
283 | self.application_data.write(tstream) | |
284 | ||
285 | # Write the length and value of the request payload | |
286 | self.length = tstream.length() | |
287 | super(self.__class__, self).write(ostream) | |
288 | ostream.write(tstream.buffer) | |
289 | ||
290 | def validate(self): | |
291 | self.__validate() | |
292 | ||
293 | def __validate(self): | |
294 | name = self.__class__.__name__ | |
295 | msg = ErrorStrings.BAD_EXP_RECV | |
296 | ||
297 | if self.application_namespace is not None: | |
298 | if self.application_data is None: | |
299 | member = 'application_data' | |
300 | raise ValueError(msg.format('{}.{}'.format(name, member), | |
301 | 'value', 'not None', 'None')) | |
302 | else: | |
303 | member = 'application_namespace' | |
304 | exp_type = self.ApplicationNamespace | |
305 | if not isinstance(self.application_namespace, exp_type): | |
306 | rcv_type = type(self.application_namespace) | |
307 | raise TypeError(msg.format('{}.{}'.format(name, member), | |
308 | 'type', exp_type, rcv_type)) | |
309 | ||
310 | if self.application_data is not None: | |
311 | if self.application_namespace is None: | |
312 | member = 'application_namespace' | |
313 | raise ValueError(msg.format('{}.{}'.format(name, member), | |
314 | 'value', 'not None', 'None')) | |
315 | else: | |
316 | member = 'application_data' | |
317 | exp_type = self.ApplicationData | |
318 | if not isinstance(self.application_data, exp_type): | |
319 | rcv_type = type(self.application_data) | |
320 | raise TypeError(msg.format('{}.{}'.format(name, member), | |
321 | 'type', exp_type, rcv_type)) | |
322 | ||
323 | @classmethod | |
324 | def create(cls, application_namespace, application_data): | |
325 | namespace = ApplicationSpecificInformation.\ | |
326 | ApplicationNamespace(application_namespace) | |
327 | data = ApplicationSpecificInformation.\ | |
328 | ApplicationData(application_data) | |
329 | return ApplicationSpecificInformation(application_namespace=namespace, | |
330 | application_data=data) | |
331 | ||
332 | ||
333 | # 3.37 | |
334 | class ContactInformation(TextString): | |
335 | ||
336 | def __init__(self, value=None): | |
337 | super(self.__class__, | |
338 | self).__init__(value, Tags.CONTACT_INFORMATION) | |
339 | ||
340 | ||
341 | # 3.39 | |
342 | # TODO (peter-hamilton) A CustomAttribute TextString is not sufficient to | |
343 | # TODO (peter-hamilton) cover all potential custom attributes. This is a | |
344 | # TODO (peter-hamilton) temporary stopgap. | |
345 | class CustomAttribute(TextString): | |
346 | ||
347 | def __init__(self, value=None): | |
348 | super(self.__class__, | |
349 | self).__init__(value, Tags.ATTRIBUTE_VALUE) |
0 | # Copyright (c) 2014 The Johns Hopkins University/Applied Physics Laboratory | |
1 | # All Rights Reserved. | |
2 | # | |
3 | # Licensed under the Apache License, Version 2.0 (the "License"); you may | |
4 | # not use this file except in compliance with the License. You may obtain | |
5 | # a copy of the License at | |
6 | # | |
7 | # http://www.apache.org/licenses/LICENSE-2.0 | |
8 | # | |
9 | # Unless required by applicable law or agreed to in writing, software | |
10 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT | |
11 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the | |
12 | # License for the specific language governing permissions and limitations | |
13 | # under the License. | |
14 | ||
15 | # In case of new content, remove the following line to enable flake8 tests | |
16 | # flake8: noqa | |
17 | ||
18 | from enum import Enum | |
19 | ||
20 | ||
21 | class AttributeType(Enum): | |
22 | UNIQUE_IDENTIFIER = 'Unique Identifier' | |
23 | NAME = 'Name' | |
24 | OBJECT_TYPE = 'Object Type' | |
25 | CRYPTOGRAPHIC_ALGORITHM = 'Cryptographic Algorithm' | |
26 | CRYPTOGRAPHIC_LENGTH = 'Cryptographic Length' | |
27 | CRYPTOGRAPHIC_PARAMETERS = 'Cryptographic Parameters' | |
28 | CRYPTOGRAPHIC_DOMAIN_PARAMETERS = 'Cryptographic Domain Parameters' | |
29 | CERTIFICATE_TYPE = 'Certificate Type' | |
30 | CERTIFICATE_LENGTH = 'Certificate Length' | |
31 | X_509_CERTIFICATE_IDENTIFIER = 'X.509 Certificate Identifier' | |
32 | X_509_CERTIFICATE_SUBJECT = 'X.509 Certificate Subject' | |
33 | X_509_CERTIFICATE_ISSUER = 'X.509 Certificate Issuer' | |
34 | CERTIFICATE_IDENTIFIER = 'Certificate Identifier' | |
35 | CERTIFICATE_SUBJECT = 'Certificate Subject' | |
36 | CERTIFICATE_ISSUER = 'Certificate Issuer' | |
37 | DIGITAL_SIGNATURE_ALGORITHM = 'Digital Signature Algorithm' | |
38 | DIGEST = 'Digest' | |
39 | OPERATION_POLICY_NAME = 'Operation Policy Name' | |
40 | CRYPTOGRAPHIC_USAGE_MASK = 'Cryptographic Usage Mask' | |
41 | LEASE_TIME = 'Lease Time' | |
42 | USAGE_LIMITS = 'Usage Limits' | |
43 | STATE = 'State' | |
44 | INITIAL_DATE = 'Initial Date' | |
45 | ACTIVATION_DATE = 'Activation Date' | |
46 | PROCESS_START_DATE = 'Process Start Date' | |
47 | PROTECT_STOP_DATE = 'Protect Stop Date' | |
48 | DEACTIVATION_DATE = 'Deactivation Date' | |
49 | DESTROY_DATE = 'Destroy Date' | |
50 | COMPROMISE_OCCURRENCE_DATE = 'Compromise Occurrence Date' | |
51 | COMPROMISE_DATE = 'Compromise Date' | |
52 | REVOCATION_REASON = 'Revocation Reason' | |
53 | ARCHIVE_DATE = 'Archive Date' | |
54 | OBJECT_GROUP = 'Object Group' | |
55 | FRESH = 'Fresh' | |
56 | LINK = 'Link' | |
57 | APPLICATION_SPECIFIC_INFORMATION = 'Application Specific Information' | |
58 | CONTACT_INFORMATION = 'Contact Information' | |
59 | LAST_CHANGE_DATE = 'Last Change Date' | |
60 | CUSTOM_ATTRIBUTE = 'Custom Attribute' | |
61 | ||
62 | ||
63 | # 9.1.1.2 | |
64 | class Types(Enum): | |
65 | DEFAULT = 0x00 | |
66 | STRUCTURE = 0x01 | |
67 | INTEGER = 0x02 | |
68 | LONG_INTEGER = 0x03 | |
69 | BIG_INTEGER = 0x04 | |
70 | ENUMERATION = 0x05 | |
71 | BOOLEAN = 0x06 | |
72 | TEXT_STRING = 0x07 | |
73 | BYTE_STRING = 0x08 | |
74 | DATE_TIME = 0x09 | |
75 | INTERVAL = 0x0A | |
76 | ||
77 | ||
78 | # 9.1.3.1 | |
79 | class Tags(Enum): | |
80 | DEFAULT = 0x420000 | |
81 | ACTIVATION_DATE = 0x420001 | |
82 | APPLICATION_DATA = 0x420002 | |
83 | APPLICATION_NAMESPACE = 0x420003 | |
84 | APPLICATION_SPECIFIC_INFORMATION = 0x420004 | |
85 | ARCHIVE_DATE = 0x420005 | |
86 | ASYNCHRONOUS_CORRELATION_VALUE = 0x420006 | |
87 | ASYNCHRONOUS_INDICATOR = 0x420007 | |
88 | ATTRIBUTE = 0x420008 | |
89 | ATTRIBUTE_INDEX = 0x420009 | |
90 | ATTRIBUTE_NAME = 0x42000A | |
91 | ATTRIBUTE_VALUE = 0x42000B | |
92 | AUTHENTICATION = 0x42000C | |
93 | BATCH_COUNT = 0x42000D | |
94 | BATCH_ERROR_CONTINUATION_OPTION = 0x42000E | |
95 | BATCH_ITEM = 0x42000F | |
96 | BATCH_ORDER_OPTION = 0x420010 | |
97 | BLOCK_CIPHER_MODE = 0x420011 | |
98 | CANCELLATION_RESULT = 0x420012 | |
99 | CERTIFICATE = 0x420013 | |
100 | CERTIFICATE_IDENTIFIER = 0x420014 # DEPRECATED | |
101 | CERTIFICATE_ISSUER = 0x420015 # DEPRECATED | |
102 | CERTIFICATE_ISSUER_ALTERNATIVE_NAME = 0x420016 # DEPRECATED | |
103 | CERTIFICATE_ISSUER_DISTINGUISHED_NAME = 0x420017 # DEPRECATED | |
104 | CERTIFICATE_REQUEST = 0x420018 | |
105 | CERTIFICATE_REQUEST_TYPE = 0x420019 | |
106 | CERTIFICATE_SUBJECT = 0x42001A # DEPRECATED | |
107 | CERTIFICATE_SUBJECT_ALTERNATIVE_NAME = 0x42001B # DEPRECATED | |
108 | CERTIFICATE_SUBJECT_DISTINGUISHED_NAME = 0x42001C # DEPRECATED | |
109 | CERTIFICATE_TYPE = 0x42001D | |
110 | CERTIFICATE_VALUE = 0x42001E | |
111 | COMMON_TEMPLATE_ATTRIBUTE = 0x42001F | |
112 | COMPROMISE_DATE = 0x420020 | |
113 | COMPROMISE_OCCURRENCE_DATE = 0x420021 | |
114 | CONTACT_INFORMATION = 0x420022 | |
115 | CREDENTIAL = 0x420023 | |
116 | CREDENTIAL_TYPE = 0x420024 | |
117 | CREDENTIAL_VALUE = 0x420025 | |
118 | CRITICALITY_INDICATOR = 0x420026 | |
119 | CRT_COEFFICIENT = 0x420027 | |
120 | CRYPTOGRAPHIC_ALGORITHM = 0x420028 | |
121 | CRYPTOGRAPHIC_DOMAIN_PARAMETERS = 0x420029 | |
122 | CRYPTOGRAPHIC_LENGTH = 0x42002A | |
123 | CRYPTOGRAPHIC_PARAMETERS = 0x42002B | |
124 | CRYPTOGRAPHIC_USAGE_MASK = 0x42002C | |
125 | CUSTOM_ATTRIBUTE = 0x42002D | |
126 | D = 0x42002E | |
127 | DEACTIVATION_DATE = 0x42002F | |
128 | DERIVATION_DATA = 0x420030 | |
129 | DERIVATION_METHOD = 0x420031 | |
130 | DERIVATION_PARAMETERS = 0x420032 | |
131 | DESTROY_DATE = 0x420033 | |
132 | DIGEST = 0x420034 | |
133 | DIGEST_VALUE = 0x420035 | |
134 | ENCRYPTION_KEY_INFORMATION = 0x420036 | |
135 | G = 0x420037 | |
136 | HASHING_ALGORITHM = 0x420038 | |
137 | INITIAL_DATE = 0x420039 | |
138 | INITIALIZATION_VECTOR = 0x42003A | |
139 | ISSUER = 0x42003B # DEPRECATED | |
140 | ITERATION_COUNT = 0x42003C | |
141 | IV_COUNTER_NONCE = 0x42003D | |
142 | J = 0x42003E | |
143 | KEY = 0x42003F | |
144 | KEY_BLOCK = 0x420040 | |
145 | KEY_COMPRESSION_TYPE = 0x420041 | |
146 | KEY_FORMAT_TYPE = 0x420042 | |
147 | KEY_MATERIAL = 0x420043 | |
148 | KEY_PART_IDENTIFIER = 0x420044 | |
149 | KEY_VALUE = 0x420045 | |
150 | KEY_WRAPPING_DATA = 0x420046 | |
151 | KEY_WRAPPING_SPECIFICATION = 0x420047 | |
152 | LAST_CHANGE_DATE = 0x420048 | |
153 | LEASE_TIME = 0x420049 | |
154 | LINK = 0x42004A | |
155 | LINK_TYPE = 0x42004B | |
156 | LINKED_OBJECT_IDENTIFIER = 0x42004C | |
157 | MAC_SIGNATURE = 0x42004D | |
158 | MAC_SIGNATURE_KEY_INFORMATION = 0x42004E | |
159 | MAXIMUM_ITEMS = 0x42004F | |
160 | MAXIMUM_RESPONSE_SIZE = 0x420050 | |
161 | MESSAGE_EXTENSION = 0x420051 | |
162 | MODULUS = 0x420052 | |
163 | NAME = 0x420053 | |
164 | NAME_TYPE = 0x420054 | |
165 | NAME_VALUE = 0x420055 | |
166 | OBJECT_GROUP = 0x420056 | |
167 | OBJECT_TYPE = 0x420057 | |
168 | OFFSET = 0x420058 | |
169 | OPAQUE_DATA_TYPE = 0x420059 | |
170 | OPAQUE_DATA_VALUE = 0x42005A | |
171 | OPAQUE_OBJECT = 0x42005B | |
172 | OPERATION = 0x42005C | |
173 | OPERATION_POLICY_NAME = 0x42005D | |
174 | P = 0x42005E | |
175 | PADDING_METHOD = 0x42005F | |
176 | PRIME_EXPONENT_P = 0x420060 | |
177 | PRIME_EXPONENT_Q = 0x420061 | |
178 | PRIME_FIELD_SIZE = 0x420062 | |
179 | PRIVATE_EXPONENT = 0x420063 | |
180 | PRIVATE_KEY = 0x420064 | |
181 | PRIVATE_KEY_TEMPLATE_ATTRIBUTE = 0x420065 | |
182 | PRIVATE_KEY_UNIQUE_IDENTIFIER = 0x420066 | |
183 | PROCESS_START_DATE = 0x420067 | |
184 | PROTECT_STOP_DATE = 0x420068 | |
185 | PROTOCOL_VERSION = 0x420069 | |
186 | PROTOCOL_VERSION_MAJOR = 0x42006A | |
187 | PROTOCOL_VERSION_MINOR = 0x42006B | |
188 | PUBLIC_EXPONENT = 0x42006C | |
189 | PUBLIC_KEY = 0x42006D | |
190 | PUBLIC_KEY_TEMPLATE_ATTRIBUTE = 0x42006E | |
191 | PUBLIC_KEY_UNIQUE_IDENTIFIER = 0x42006F | |
192 | PUT_FUNCTION = 0x420070 | |
193 | Q = 0x420071 | |
194 | Q_STRING = 0x420072 | |
195 | QLENGTH = 0x420073 | |
196 | QUERY_FUNCTION = 0x420074 | |
197 | RECOMMENDED_CURVE = 0x420075 | |
198 | REPLACED_UNIQUE_IDENTIFIER = 0x420076 | |
199 | REQUEST_BATCH_ITEM = 0x42000F | |
200 | REQUEST_HEADER = 0x420077 | |
201 | REQUEST_MESSAGE = 0x420078 | |
202 | REQUEST_PAYLOAD = 0x420079 | |
203 | RESPONSE_BATCH_ITEM = 0x42000F | |
204 | RESPONSE_HEADER = 0x42007A | |
205 | RESPONSE_MESSAGE = 0x42007B | |
206 | RESPONSE_PAYLOAD = 0x42007C | |
207 | RESULT_MESSAGE = 0x42007D | |
208 | RESULT_REASON = 0x42007E | |
209 | RESULT_STATUS = 0x42007F | |
210 | REVOCATION_MESSAGE = 0x420080 | |
211 | REVOCATION_REASON = 0x420081 | |
212 | REVOCATION_REASON_CODE = 0x420082 | |
213 | KEY_ROLE_TYPE = 0x420083 | |
214 | SALT = 0x420084 | |
215 | SECRET_DATA = 0x420085 | |
216 | SECRET_DATA_TYPE = 0x420086 | |
217 | SERIAL_NUMBER = 0x420087 # DEPRECATED | |
218 | SERVER_INFORMATION = 0x420088 | |
219 | SPLIT_KEY = 0x420089 | |
220 | SPLIT_KEY_METHOD = 0x42008A | |
221 | SPLIT_KEY_PARTS = 0x42008B | |
222 | SPLIT_KEY_THRESHOLD = 0x42008C | |
223 | STATE = 0x42008D | |
224 | STORAGE_STATUS_MASK = 0x42008E | |
225 | SYMMETRIC_KEY = 0x42008F | |
226 | TEMPLATE = 0x420090 | |
227 | TEMPLATE_ATTRIBUTE = 0x420091 | |
228 | TIME_STAMP = 0x420092 | |
229 | UNIQUE_BATCH_ITEM_ID = 0x420093 | |
230 | UNIQUE_IDENTIFIER = 0x420094 | |
231 | USAGE_LIMITS = 0x420095 | |
232 | USAGE_LIMITS_COUNT = 0x420096 | |
233 | USAGE_LIMITS_TOTAL = 0x420097 | |
234 | USAGE_LIMITS_UNIT = 0x420098 | |
235 | USERNAME = 0x420099 | |
236 | VALIDITY_DATE = 0x42009A | |
237 | VALIDITY_INDICATOR = 0x42009B | |
238 | VENDOR_EXTENSION = 0x42009C | |
239 | VENDOR_IDENTIFICATION = 0x42009D | |
240 | WRAPPING_METHOD = 0x42009E | |
241 | X = 0x42009F | |
242 | Y = 0x4200A0 | |
243 | PASSWORD = 0x4200A1 | |
244 | DEVICE_IDENTIFIER = 0x4200A2 | |
245 | ENCODING_OPTION = 0x4200A3 | |
246 | EXTENSION_INFORMATION = 0x4200A4 | |
247 | EXTENSION_NAME = 0x4200A5 | |
248 | EXTENSION_TAG = 0x4200A6 | |
249 | EXTENSION_TYPE = 0x4200A7 | |
250 | FRESH = 0x4200A8 | |
251 | MACHINE_IDENTIFIER = 0x4200A9 | |
252 | MEDIA_IDENTIFIER = 0x4200AA | |
253 | NETWORK_IDENTIFIER = 0x4200AB | |
254 | OBJECT_GROUP_MEMBER = 0x4200AC | |
255 | CERTIFICATE_LENGTH = 0x4200AD | |
256 | DIGITAL_SIGNATURE_ALGORITHM = 0x4200AE | |
257 | CERTIFICATE_SERIAL_NUMBER = 0x4200AF | |
258 | DEVICE_SERIAL_NUMBER = 0x4200B0 | |
259 | ISSUER_ALTERNATIVE_NAME = 0x4200B1 | |
260 | ISSUER_DISTINGUISHED_NAME = 0x4200B2 | |
261 | SUBJECT_ALTERNATIVE_NAME = 0x4200B3 | |
262 | SUBJECT_DISTINGUISHED_NAME = 0x4200B4 | |
263 | X_509_CERTIFICATE_IDENTIFER = 0x4200B5 | |
264 | X_509_CERTIFICATE_ISSUER = 0x4200B6 | |
265 | X_509_CERTIFICATE_SUBJECT = 0x4200B7 | |
266 | ||
267 | ||
268 | # 9.1.3.2.1 | |
269 | class CredentialType(Enum): | |
270 | USERNAME_AND_PASSWORD = 0x00000001 | |
271 | DEVICE = 0x00000002 | |
272 | ||
273 | ||
274 | # 9.1.3.2.2 | |
275 | class KeyCompressionType(Enum): | |
276 | EC_PUBLIC_KEY_TYPE_UNCOMPRESSED = 0x00000001 | |
277 | EC_PUBLIC_KEY_TYPE_X9_62_COMPRESSED_PRIME = 0x00000002 | |
278 | EC_PUBLIC_KEY_TYPE_X9_62_COMPRESSED_CHAR2 = 0x00000003 | |
279 | EC_PUBLIC_KEY_TYPE_X9_62_HYBRID = 0x00000004 | |
280 | ||
281 | ||
282 | # 9.1.3.2.3 | |
283 | class KeyFormatType(Enum): | |
284 | RAW = 0x00000001 | |
285 | OPAQUE = 0x00000002 | |
286 | PKCS_1 = 0x00000003 | |
287 | PKCS_8 = 0x00000004 | |
288 | X_509 = 0x00000005 | |
289 | EC_PRIVATE_KEY = 0x00000006 | |
290 | TRANSPARENT_SYMMETRIC_KEY = 0x00000007 | |
291 | TRANSPARENT_DSA_PRIVATE_KEY = 0x00000008 | |
292 | TRANSPARENT_DSA_PUBLIC_KEY = 0x00000009 | |
293 | TRANSPARENT_RSA_PRIVATE_KEY = 0x0000000A | |
294 | TRANSPARENT_RSA_PUBLIC_KEY = 0x0000000B | |
295 | TRANSPARENT_DH_PRIVATE_KEY = 0x0000000C | |
296 | TRANSPARENT_DH_PUBLIC_KEY = 0x0000000D | |
297 | TRANSPARENT_ECDSA_PRIVATE_KEY = 0x0000000E | |
298 | TRANSPARENT_ECDSA_PUBLIC_KEY = 0x0000000F | |
299 | TRANSPARENT_ECDH_PRIVATE_KEY = 0x00000010 | |
300 | TRANSPARENT_ECDH_PUBLIC_KEY = 0x00000011 | |
301 | TRANSPARENT_ECMQV_PRIVATE_KEY = 0x00000012 | |
302 | TRANSPARENT_ECMQV_PUBLIC_KEY = 0x00000013 | |
303 | ||
304 | ||
305 | # 9.1.3.2.4 | |
306 | class WrappingMethod(Enum): | |
307 | ENCRYPT = 0x00000001 | |
308 | MAC_SIGN = 0x00000002 | |
309 | ENCRYPT_THEN_MAC_SIGN = 0x00000003 | |
310 | MAC_SIGN_THEN_ENCRYPT = 0x00000004 | |
311 | TR_31 = 0x00000005 | |
312 | ||
313 | ||
314 | # 9.1.3.2.6 | |
315 | class CertificateType(Enum): | |
316 | X_509 = 0x00000001 | |
317 | PGP = 0x00000002 | |
318 | ||
319 | ||
320 | # 9.1.3.2.8 | |
321 | class SplitKeyMethod(Enum): | |
322 | XOR = 0x00000001 | |
323 | POLYNOMIAL_SHARING_GF = 0x00000002 | |
324 | POLYNOMIAL_SHARING_PRIME_FIELD = 0x00000003 | |
325 | ||
326 | ||
327 | # 9.1.3.2.9 | |
328 | class SecretDataType(Enum): | |
329 | PASSWORD = 0x00000001 | |
330 | SEED = 0x00000002 | |
331 | ||
332 | ||
333 | # 9.1.3.2.10 | |
334 | class OpaqueDataType(Enum): | |
335 | pass | |
336 | ||
337 | ||
338 | # 9.1.3.2.11 | |
339 | class NameType(Enum): | |
340 | UNINTERPRETED_TEXT_STRING = 0x00000001 | |
341 | URI = 0x00000002 | |
342 | ||
343 | ||
344 | # 9.1.3.2.12 | |
345 | class ObjectType(Enum): | |
346 | CERTIFICATE = 0x00000001 | |
347 | SYMMETRIC_KEY = 0x00000002 | |
348 | PUBLIC_KEY = 0x00000003 | |
349 | PRIVATE_KEY = 0x00000004 | |
350 | SPLIT_KEY = 0x00000005 | |
351 | TEMPLATE = 0x00000006 | |
352 | SECRET_DATA = 0x00000007 | |
353 | OPAQUE_DATA = 0x00000008 | |
354 | ||
355 | ||
356 | # 9.1.3.2.13 | |
357 | class CryptographicAlgorithm(Enum): | |
358 | DES = 0x00000001 | |
359 | TRIPLE_DES = 0x00000002 # '3DES' is invalid syntax | |
360 | AES = 0x00000003 | |
361 | RSA = 0x00000004 | |
362 | DSA = 0x00000005 | |
363 | ECDSA = 0x00000006 | |
364 | HMAC_SHA1 = 0x00000007 | |
365 | HMAC_SHA224 = 0x00000008 | |
366 | HMAC_SHA256 = 0x00000009 | |
367 | HMAC_SHA384 = 0x0000000A | |
368 | HMAC_SHA512 = 0x0000000B | |
369 | HMAC_MD5 = 0x0000000C | |
370 | DH = 0x0000000D | |
371 | ECDH = 0x0000000E | |
372 | ECMQV = 0x0000000F | |
373 | BLOWFISH = 0x00000010 | |
374 | CAMELLIA = 0x00000011 | |
375 | CAST5 = 0x00000012 | |
376 | IDEA = 0x00000013 | |
377 | MARS = 0x00000014 | |
378 | RC2 = 0x00000015 | |
379 | RC4 = 0x00000016 | |
380 | RC5 = 0x00000017 | |
381 | SKIPJACK = 0x00000018 | |
382 | TWOFISH = 0x00000019 | |
383 | ||
384 | ||
385 | # 9.1.3.2.14 | |
386 | class BlockCipherMode(Enum): | |
387 | CBC = 0x00000001 | |
388 | ECB = 0x00000002 | |
389 | PCBC = 0x00000003 | |
390 | CFB = 0x00000004 | |
391 | OFB = 0x00000005 | |
392 | CTR = 0x00000006 | |
393 | CMAC = 0x00000007 | |
394 | CCM = 0x00000008 | |
395 | GCM = 0x00000009 | |
396 | CBC_MAC = 0x0000000A | |
397 | XTS = 0x0000000B | |
398 | AES_KEY_WRAP_PADDING = 0x0000000C | |
399 | NIST_KEY_WRAP = 0x0000000D | |
400 | X9_102_AESKW = 0x0000000E | |
401 | X9_102_TDKW = 0x0000000F | |
402 | X9_102_AKW1 = 0x00000010 | |
403 | X9_102_AKW2 = 0x00000011 | |
404 | ||
405 | ||
406 | # 9.1.3.2.15 | |
407 | class PaddingMethod(Enum): | |
408 | NONE = 0x00000001 | |
409 | OAEP = 0x00000002 | |
410 | PKCS5 = 0x00000003 | |
411 | SSL3 = 0x00000004 | |
412 | ZEROS = 0x00000005 | |
413 | ANSI_X9_23 = 0x00000006 | |
414 | ISO_10126 = 0x00000007 | |
415 | PKCS1_V_1_5 = 0x00000008 | |
416 | X9_31 = 0x00000009 | |
417 | PSS = 0x0000000A | |
418 | ||
419 | ||
420 | # 9.1.3.2.16 | |
421 | class HashingAlgorithm(Enum): | |
422 | MD2 = 0x00000001 | |
423 | MD4 = 0x00000002 | |
424 | MD5 = 0x00000003 | |
425 | SHA_1 = 0x00000004 | |
426 | SHA_224 = 0x00000005 | |
427 | SHA_256 = 0x00000006 | |
428 | SHA_384 = 0x00000007 | |
429 | SHA_512 = 0x00000008 | |
430 | RIPEMD_160 = 0x00000009 | |
431 | TIGER = 0x0000000A | |
432 | WHIRLPOOL = 0x0000000B | |
433 | ||
434 | ||
435 | # 9.1.3.2.17 | |
436 | class KeyRoleType(Enum): | |
437 | BDK = 0x00000001 | |
438 | CVK = 0x00000002 | |
439 | DEK = 0x00000003 | |
440 | MKAC = 0x00000004 | |
441 | MKSMC = 0x00000005 | |
442 | MKSMI = 0x00000006 | |
443 | MKDAC = 0x00000007 | |
444 | MKDN = 0x00000008 | |
445 | MKCP = 0x00000009 | |
446 | MKOTH = 0x0000000A | |
447 | KEK = 0x0000000B | |
448 | MAC_16609 = 0x0000000C | |
449 | MAC_97971 = 0x0000000D | |
450 | MAC_97972 = 0x0000000E | |
451 | MAC_97973 = 0x0000000F | |
452 | MAC_97974 = 0x00000010 | |
453 | MAC_97975 = 0x00000011 | |
454 | ZPK = 0x00000012 | |
455 | PVKIBM = 0x00000013 | |
456 | PVKPVV = 0x00000014 | |
457 | PVKOTH = 0x00000015 | |
458 | ||
459 | ||
460 | # 9.1.3.2.27 | |
461 | class Operation(Enum): | |
462 | CREATE = 0x00000001 | |
463 | CREATE_KEY_PAIR = 0x00000002 | |
464 | REGISTER = 0x00000003 | |
465 | REKEY = 0x00000004 | |
466 | DERIVE_KEY = 0x00000005 | |
467 | CERTIFY = 0x00000006 | |
468 | RECERTIFY = 0x00000007 | |
469 | LOCATE = 0x00000008 | |
470 | CHECK = 0x00000009 | |
471 | GET = 0x0000000A | |
472 | GET_ATTRIBUTES = 0x0000000B | |
473 | GET_ATTRIBUTE_LIST = 0x0000000C | |
474 | ADD_ATTRIBUTE = 0x0000000D | |
475 | MODIFY_ATTRIBUTE = 0x0000000E | |
476 | DELETE_ATTRIBUTE = 0x0000000F | |
477 | OBTAIN_LEASE = 0x00000010 | |
478 | GET_USAGE_ALLOCATION = 0x00000011 | |
479 | ACTIVATE = 0x00000012 | |
480 | REVOKE = 0x00000013 | |
481 | DESTROY = 0x00000014 | |
482 | ARCHIVE = 0x00000015 | |
483 | RECOVER = 0x00000016 | |
484 | VALIDATE = 0x00000017 | |
485 | QUERY = 0x00000018 | |
486 | CANCEL = 0x00000019 | |
487 | POLL = 0x0000001A | |
488 | NOTIFY = 0x0000001B | |
489 | PUT = 0x0000001C | |
490 | REKEY_KEY_PAIR = 0x0000001D | |
491 | DISCOVER_VERSIONS = 0x0000001E | |
492 | ||
493 | ||
494 | # 9.1.3.2.28 | |
495 | class ResultStatus(Enum): | |
496 | SUCCESS = 0x00000000 | |
497 | OPERATION_FAILED = 0x00000001 | |
498 | OPERATION_PENDING = 0x00000002 | |
499 | OPERATION_UNDONE = 0x00000003 | |
500 | ||
501 | ||
502 | # 9.1.3.2.29 | |
503 | class ResultReason(Enum): | |
504 | ITEM_NOT_FOUND = 0x00000001 | |
505 | RESPONSE_TOO_LARGE = 0x00000002 | |
506 | AUTHENTICATION_NOT_SUCCESSFUL = 0x00000003 | |
507 | INVALID_MESSAGE = 0x00000004 | |
508 | OPERATION_NOT_SUPPORTED = 0x00000005 | |
509 | MISSING_DATA = 0x00000006 | |
510 | INVALID_FIELD = 0x00000007 | |
511 | FEATURE_NOT_SUPPORTED = 0x00000008 | |
512 | OPERATION_CANCELED_BY_REQUESTER = 0x00000009 | |
513 | CRYPTOGRAPHIC_FAILURE = 0x0000000A | |
514 | ILLEGAL_OPERATION = 0x0000000B | |
515 | PERMISSION_DENIED = 0x0000000C | |
516 | OBJECT_ARCHIVED = 0x0000000D | |
517 | INDEX_OUT_OF_BOUNDS = 0x0000000E | |
518 | APPLICATION_NAMESPACE_NOT_SUPPORTED = 0x0000000F | |
519 | KEY_FORMAT_TYPE_NOT_SUPPORTED = 0x00000010 | |
520 | KEY_COMPRESSION_TYPE_NOT_SUPPORTED = 0x00000011 | |
521 | ENCODING_OPTION_ERROR = 0x00000012 | |
522 | GENERAL_FAILURE = 0x00000100 | |
523 | ||
524 | ||
525 | # 9.1.3.2.30 | |
526 | class BatchErrorContinuationOption(Enum): | |
527 | CONTINUE = 0x00000001 | |
528 | STOP = 0x00000002 | |
529 | UNDO = 0x00000003 | |
530 | ||
531 | ||
532 | # 9.1.3.2.32 | |
533 | class EncodingOption(Enum): | |
534 | NO_ENCODING = 0x00000001 | |
535 | TTLV_ENCODING = 0x00000002 | |
536 | ||
537 | ||
538 | # 9.1.3.3 | |
539 | # 9.1.3.3.1 | |
540 | class CryptographicUsageMask(Enum): | |
541 | SIGN = 0x00000001 | |
542 | VERIFY = 0x00000002 | |
543 | ENCRYPT = 0x00000004 | |
544 | DECRYPT = 0x00000008 | |
545 | WRAP_KEY = 0x00000010 | |
546 | UNWRAP_KEY = 0x00000020 | |
547 | EXPORT = 0x00000040 | |
548 | MAC_GENERATE = 0x00000080 | |
549 | MAC_VERIFY = 0x00000100 | |
550 | DERIVE_KEY = 0x00000200 | |
551 | CONTENT_COMMITMENT = 0x00000400 | |
552 | KEY_AGREEMENT = 0x00000800 | |
553 | CERTIFICATE_SIGN = 0x00001000 | |
554 | CRL_SIGN = 0x00002000 | |
555 | GENERATE_CRYPTOGRAM = 0x00004000 | |
556 | VALIDATE_CRYPTOGRAM = 0x00008000 | |
557 | TRANSLATE_ENCRYPT = 0x00010000 | |
558 | TRANSLATE_DECRYPT = 0x00020000 | |
559 | TRANSLATE_WRAP = 0x00040000 | |
560 | TRANSLATE_UNWRAP = 0x00080000 |
0 | # Copyright (c) 2014 The Johns Hopkins University/Applied Physics Laboratory | |
1 | # All Rights Reserved. | |
2 | # | |
3 | # Licensed under the Apache License, Version 2.0 (the "License"); you may | |
4 | # not use this file except in compliance with the License. You may obtain | |
5 | # a copy of the License at | |
6 | # | |
7 | # http://www.apache.org/licenses/LICENSE-2.0 | |
8 | # | |
9 | # Unless required by applicable law or agreed to in writing, software | |
10 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT | |
11 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the | |
12 | # License for the specific language governing permissions and limitations | |
13 | # under the License. | |
14 | ||
15 | ||
16 | class ErrorStrings: | |
17 | BAD_EXP_RECV = "Bad {0} {1}: expected {2}, received {3}" | |
18 | BAD_ENCODING = "Bad {0} {1}: encoding mismatch" | |
19 | ||
20 | ||
21 | class BaseError(Exception): | |
22 | """Base class for exceptions defined in this module.""" | |
23 | ||
24 | def __init__(self, args): | |
25 | [setattr(self, k, v) for k, v in args.iteritems() if k is not 'self'] | |
26 | ||
27 | ||
28 | class KMIPServerError(BaseError): | |
29 | """Base Exception for KMIP server errors.""" | |
30 | def __init__(self, args): | |
31 | super(KMIPServerError, self).__init__(args) | |
32 | ||
33 | ||
34 | class KMIPServerZombieError(KMIPServerError): | |
35 | """KMIP server error for hung and persistent live KMIP servers.""" | |
36 | def __init__(self, pid): | |
37 | message = 'KMIP server alive after termination: PID {0}'.format(pid) | |
38 | super(KMIPServerZombieError, self).__init__({'message': message}) | |
39 | ||
40 | def __str__(self): | |
41 | return self.message | |
42 | ||
43 | ||
44 | class KMIPServerSuicideError(KMIPServerError): | |
45 | """KMIP server error for prematurely dead KMIP servers.""" | |
46 | def __init__(self, pid): | |
47 | message = 'KMIP server dead prematurely: PID {0}'.format(pid) | |
48 | super(KMIPServerSuicideError, self).__init__({'message': message}) | |
49 | ||
50 | def __str__(self): | |
51 | return self.message | |
52 | ||
53 | ||
54 | class InitError(BaseError): | |
55 | """Exception thrown for bad initializations.""" | |
56 | def __init__(self, cls, exp, recv): | |
57 | super(InitError, self).__init__(locals()) | |
58 | ||
59 | def __str__(self): | |
60 | msg = "Tried to initialize {0} instance with bad type: " | |
61 | msg += "expected {1}, received {2}" | |
62 | return msg.format(self.cls, self.exp, self.recv) | |
63 | ||
64 | ||
65 | class WriteValueError(BaseError): | |
66 | def __init__(self, cls, attr, value): | |
67 | super(WriteValueError, self).__init__(locals()) | |
68 | ||
69 | def __str__(self): | |
70 | msg = "Tried to write {0}.{1} with invalid value: {2}" | |
71 | return msg.format(self.cls, self.attr, self.value) | |
72 | ||
73 | ||
74 | class WriteTypeError(BaseError): | |
75 | def __init__(self, cls, attr, value): | |
76 | super(WriteTypeError, self).__init__(locals()) | |
77 | ||
78 | def __str__(self): | |
79 | msg = "Tried to write {0}.{1} with invalid type: {2}" | |
80 | return msg.format(self.cls, self.attr, self.value) | |
81 | ||
82 | ||
83 | class WriteOverflowError(BaseError): | |
84 | def __init__(self, cls, attr, exp, recv): | |
85 | super(WriteOverflowError, self).__init__(locals()) | |
86 | ||
87 | def __str__(self): | |
88 | msg = "Tried to write {0}.{1} with too many bytes: " | |
89 | msg += "expected {2}, received {3}" | |
90 | return msg.format(self.cls, self.attr, self.exp, self.recv) | |
91 | ||
92 | ||
93 | class ReadValueError(BaseError): | |
94 | def __init__(self, cls, attr, exp, recv): | |
95 | super(ReadValueError, self).__init__(locals()) | |
96 | ||
97 | def __str__(self): | |
98 | msg = "Tried to read {0}.{1}: expected {2}, received {3}" | |
99 | return msg.format(self.cls, self.attr, self.exp, self.recv) | |
100 | ||
101 | ||
102 | class InvalidLengthError(ValueError): | |
103 | def __init__(self, cls, exp, recv): | |
104 | msg = "Invalid length read for {0}: expected {1}, received {2}" | |
105 | super(InvalidLengthError, self).__init__(msg.format(cls, exp, recv)) | |
106 | ||
107 | ||
108 | class StreamNotEmptyError(BaseError): | |
109 | def __init__(self, cls, extra): | |
110 | super(StreamNotEmptyError, self).__init__(locals()) | |
111 | ||
112 | def __str__(self): | |
113 | msg = "Invalid length used to read {0}, bytes remaining: {1}" | |
114 | return msg.format(self.cls, self.extra) | |
115 | ||
116 | ||
117 | class StateTypeError(TypeError): | |
118 | def __init__(self, cls, exp, recv): | |
119 | msg = "Tried to initialize {0} instance with bad type: " | |
120 | msg += "expected {1}, received {2}" | |
121 | super(StateTypeError, self).__init__(msg.format(cls, exp, recv)) | |
122 | ||
123 | ||
124 | class StateOverflowError(ValueError): | |
125 | def __init__(self, cls, attr, exp, recv): | |
126 | msg = "Tried to write {0}.{1} with too many bytes: " | |
127 | msg += "expected {2}, received {3}" | |
128 | super(StateOverflowError, self).__init__(msg.format(cls, attr, exp, | |
129 | recv)) |
0 | # Copyright (c) 2014 The Johns Hopkins University/Applied Physics Laboratory | |
1 | # All Rights Reserved. | |
2 | # | |
3 | # Licensed under the Apache License, Version 2.0 (the "License"); you may | |
4 | # not use this file except in compliance with the License. You may obtain | |
5 | # a copy of the License at | |
6 | # | |
7 | # http://www.apache.org/licenses/LICENSE-2.0 | |
8 | # | |
9 | # Unless required by applicable law or agreed to in writing, software | |
10 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT | |
11 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the | |
12 | # License for the specific language governing permissions and limitations | |
13 | # under the License. |
0 | # Copyright (c) 2014 The Johns Hopkins University/Applied Physics Laboratory | |
1 | # All Rights Reserved. | |
2 | # | |
3 | # Licensed under the Apache License, Version 2.0 (the "License"); you may | |
4 | # not use this file except in compliance with the License. You may obtain | |
5 | # a copy of the License at | |
6 | # | |
7 | # http://www.apache.org/licenses/LICENSE-2.0 | |
8 | # | |
9 | # Unless required by applicable law or agreed to in writing, software | |
10 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT | |
11 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the | |
12 | # License for the specific language governing permissions and limitations | |
13 | # under the License. | |
14 | ||
15 | from kmip.core.enums import AttributeType | |
16 | ||
17 | from kmip.core.attributes import ApplicationSpecificInformation | |
18 | from kmip.core.attributes import ContactInformation | |
19 | from kmip.core.attributes import CryptographicAlgorithm | |
20 | from kmip.core.attributes import CryptographicLength | |
21 | from kmip.core.attributes import CryptographicUsageMask | |
22 | from kmip.core.attributes import CustomAttribute | |
23 | from kmip.core.attributes import Name | |
24 | from kmip.core.attributes import ObjectGroup | |
25 | from kmip.core.attributes import UniqueIdentifier | |
26 | ||
27 | from kmip.core import utils | |
28 | ||
29 | ||
30 | class AttributeValueFactory(object): | |
31 | ||
32 | def create_attribute_value(self, name, value): | |
33 | # Switch on the name of the attribute | |
34 | if name is AttributeType.UNIQUE_IDENTIFIER: | |
35 | value = self._create_unique_identifier(value) | |
36 | elif name is AttributeType.NAME: | |
37 | value = self._create_name(value) | |
38 | elif name is AttributeType.OBJECT_TYPE: | |
39 | value = self._create_object_type(value) | |
40 | elif name is AttributeType.CRYPTOGRAPHIC_ALGORITHM: | |
41 | value = self._create_cryptographic_algorithm(value) | |
42 | elif name is AttributeType.CRYPTOGRAPHIC_LENGTH: | |
43 | value = self._create_cryptographic_length(value) | |
44 | elif name is AttributeType.CRYPTOGRAPHIC_PARAMETERS: | |
45 | value = self._create_cryptographic_parameters(value) | |
46 | elif name is AttributeType.CRYPTOGRAPHIC_DOMAIN_PARAMETERS: | |
47 | value = self._create_cryptographic_domain_parameters(value) | |
48 | elif name is AttributeType.CERTIFICATE_TYPE: | |
49 | value = self._create_certificate_type(value) | |
50 | elif name is AttributeType.CERTIFICATE_LENGTH: | |
51 | value = self._create_certificate_length(value) | |
52 | elif name is AttributeType.X_509_CERTIFICATE_IDENTIFIER: | |
53 | value = self._create_x_509_certificate_identifier(value) | |
54 | elif name is AttributeType.X_509_CERTIFICATE_SUBJECT: | |
55 | value = self._create_x_509_certificate_subject(value) | |
56 | elif name is AttributeType.X_509_CERTIFICATE_ISSUER: | |
57 | value = self._create_x_509_certificate_issuer(value) | |
58 | elif name is AttributeType.CERTIFICATE_IDENTIFIER: | |
59 | value = self._create_certificate_identifier(value) | |
60 | elif name is AttributeType.CERTIFICATE_SUBJECT: | |
61 | value = self._create_certificate_subject(value) | |
62 | elif name is AttributeType.CERTIFICATE_ISSUER: | |
63 | value = self._create_certificate_issuer(value) | |
64 | elif name is AttributeType.DIGITAL_SIGNATURE_ALGORITHM: | |
65 | value = self._create_digital_signature_algorithm(value) | |
66 | elif name is AttributeType.DIGEST: | |
67 | value = self._create_digest(value) | |
68 | elif name is AttributeType.OPERATION_POLICY_NAME: | |
69 | value = self._create_operation_policy_name(value) | |
70 | elif name is AttributeType.CRYPTOGRAPHIC_USAGE_MASK: | |
71 | value = self._create_cryptographic_usage_mask(value) | |
72 | elif name is AttributeType.LEASE_TIME: | |
73 | value = self._create_lease_time(value) | |
74 | elif name is AttributeType.USAGE_LIMITS: | |
75 | value = self._create_usage_limits(value) | |
76 | elif name is AttributeType.STATE: | |
77 | value = self._create_state(value) | |
78 | elif name is AttributeType.INITIAL_DATE: | |
79 | value = self._create_initial_date(value) | |
80 | elif name is AttributeType.ACTIVATION_DATE: | |
81 | value = self._create_activation_date(value) | |
82 | elif name is AttributeType.PROCESS_START_DATE: | |
83 | value = self._create_process_start_date(value) | |
84 | elif name is AttributeType.PROTECT_STOP_DATE: | |
85 | value = self._create_protect_stop_date(value) | |
86 | elif name is AttributeType.DEACTIVATION_DATE: | |
87 | value = self._create_deactivation_date(value) | |
88 | elif name is AttributeType.DESTROY_DATE: | |
89 | value = self._create_destroy_date(value) | |
90 | elif name is AttributeType.COMPROMISE_OCCURRENCE_DATE: | |
91 | value = self._create_compromise_occurrence_date(value) | |
92 | elif name is AttributeType.COMPROMISE_DATE: | |
93 | value = self._create_compromise_date(value) | |
94 | elif name is AttributeType.REVOCATION_REASON: | |
95 | value = self._create_revocation_reason(value) | |
96 | elif name is AttributeType.ARCHIVE_DATE: | |
97 | value = self._create_archive_date(value) | |
98 | elif name is AttributeType.OBJECT_GROUP: | |
99 | value = self._create_object_group(value) | |
100 | elif name is AttributeType.FRESH: | |
101 | value = self._create_fresh(value) | |
102 | elif name is AttributeType.LINK: | |
103 | value = self._create_link(value) | |
104 | elif name is AttributeType.APPLICATION_SPECIFIC_INFORMATION: | |
105 | value = self._create_application_specific_information(value) | |
106 | elif name is AttributeType.CONTACT_INFORMATION: | |
107 | value = self._create_contact_information(value) | |
108 | elif name is AttributeType.LAST_CHANGE_DATE: | |
109 | value = self._create_last_change_date(value) | |
110 | elif name is AttributeType.CUSTOM_ATTRIBUTE: | |
111 | value = self._create_custom_attribute(value) | |
112 | else: | |
113 | if not isinstance(name, str): | |
114 | raise ValueError('Unrecognized attribute type: ' | |
115 | '{}'.format(name)) | |
116 | elif name.startswith('x-'): | |
117 | # Custom attribute indicated | |
118 | value = self._create_custom_attribute(value) | |
119 | ||
120 | return value | |
121 | ||
122 | def _create_unique_identifier(self, uuid): | |
123 | return UniqueIdentifier(uuid) | |
124 | ||
125 | def _create_name(self, name): | |
126 | if name is not None: | |
127 | name_value = name.get('name_value') | |
128 | name_type = name.get('name_type') | |
129 | ||
130 | return Name.create(name_value, name_type) | |
131 | else: | |
132 | return Name() | |
133 | ||
134 | def _create_object_type(self, obj): | |
135 | raise NotImplementedError() | |
136 | ||
137 | def _create_cryptographic_algorithm(self, alg): | |
138 | return CryptographicAlgorithm(alg) | |
139 | ||
140 | def _create_cryptographic_length(self, length): | |
141 | if length is not None and not isinstance(length, int): | |
142 | msg = utils.build_er_error(CryptographicLength, | |
143 | 'constructor argument type', int, | |
144 | type(length)) | |
145 | raise TypeError(msg) | |
146 | ||
147 | return CryptographicLength(length) | |
148 | ||
149 | def _create_cryptographic_parameters(self, params): | |
150 | raise NotImplementedError() | |
151 | ||
152 | def _create_cryptographic_domain_parameters(self, params): | |
153 | raise NotImplementedError() | |
154 | ||
155 | def _create_certificate_type(self, cert): | |
156 | raise NotImplementedError() | |
157 | ||
158 | def _create_certificate_length(self, length): | |
159 | raise NotImplementedError() | |
160 | ||
161 | def _create_x_509_certificate_identifier(self, ident): | |
162 | raise NotImplementedError() | |
163 | ||
164 | def _create_x_509_certificate_subject(self, subject): | |
165 | raise NotImplementedError() | |
166 | ||
167 | def _create_x_509_certificate_issuer(self, issuer): | |
168 | raise NotImplementedError() | |
169 | ||
170 | def _create_certificate_identifier(self, ident): | |
171 | raise NotImplementedError() | |
172 | ||
173 | def _create_certificate_subject(self, subject): | |
174 | raise NotImplementedError() | |
175 | ||
176 | def _create_certificate_issuer(self, issuer): | |
177 | raise NotImplementedError() | |
178 | ||
179 | def _create_digital_signature_algorithm(self, alg): | |
180 | raise NotImplementedError() | |
181 | ||
182 | def _create_digest(self, digest): | |
183 | raise NotImplementedError() | |
184 | ||
185 | def _create_operation_policy_name(self, name): | |
186 | raise NotImplementedError() | |
187 | ||
188 | def _create_cryptographic_usage_mask(self, flags): | |
189 | mask = None | |
190 | if flags is not None: | |
191 | mask = 0 | |
192 | for flag in flags: | |
193 | mask |= flag.value | |
194 | ||
195 | return CryptographicUsageMask(mask) | |
196 | ||
197 | def _create_lease_time(self, lease): | |
198 | raise NotImplementedError() | |
199 | ||
200 | def _create_usage_limits(self, limits): | |
201 | raise NotImplementedError() | |
202 | ||
203 | def _create_state(self, state): | |
204 | raise NotImplementedError() | |
205 | ||
206 | def _create_initial_date(self, date): | |
207 | raise NotImplementedError() | |
208 | ||
209 | def _create_activation_date(self, date): | |
210 | raise NotImplementedError() | |
211 | ||
212 | def _create_process_start_date(self, date): | |
213 | raise NotImplementedError() | |
214 | ||
215 | def _create_protect_stop_date(self, date): | |
216 | raise NotImplementedError() | |
217 | ||
218 | def _create_deactivation_date(self, date): | |
219 | raise NotImplementedError() | |
220 | ||
221 | def _create_destroy_date(self, date): | |
222 | raise NotImplementedError() | |
223 | ||
224 | def _create_compromise_occurrence_date(self, date): | |
225 | raise NotImplementedError() | |
226 | ||
227 | def _create_compromise_date(self, date): | |
228 | raise NotImplementedError() | |
229 | ||
230 | def _create_revocation_reason(self, reason): | |
231 | raise NotImplementedError() | |
232 | ||
233 | def _create_archive_date(self, date): | |
234 | raise NotImplementedError() | |
235 | ||
236 | def _create_object_group(self, group): | |
237 | if group is not None and not isinstance(group, str): | |
238 | msg = utils.build_er_error(ObjectGroup, | |
239 | 'constructor argument type', str, | |
240 | type(group)) | |
241 | raise TypeError(msg) | |
242 | ||
243 | return ObjectGroup(group) | |
244 | ||
245 | def _create_fresh(self, fresh): | |
246 | raise NotImplementedError() | |
247 | ||
248 | def _create_link(self, link): | |
249 | raise NotImplementedError() | |
250 | ||
251 | def _create_application_specific_information(self, info): | |
252 | if info is None: | |
253 | return ApplicationSpecificInformation() | |
254 | else: | |
255 | application_namespace = info.get('application_namespace') | |
256 | application_data = info.get('application_data') | |
257 | ||
258 | if not isinstance(application_namespace, str): | |
259 | msg = utils.build_er_error(ApplicationSpecificInformation, | |
260 | 'constructor argument type', | |
261 | str, type(application_namespace)) | |
262 | raise TypeError(msg) | |
263 | ||
264 | if not isinstance(application_data, str): | |
265 | msg = utils.build_er_error(ApplicationSpecificInformation, | |
266 | 'constructor argument type', | |
267 | str, type(application_data)) | |
268 | raise TypeError(msg) | |
269 | ||
270 | return ApplicationSpecificInformation.create(application_namespace, | |
271 | application_data) | |
272 | ||
273 | def _create_contact_information(self, info): | |
274 | if info is None: | |
275 | return ContactInformation() | |
276 | else: | |
277 | if not isinstance(info, str): | |
278 | msg = utils.build_er_error(ContactInformation, | |
279 | 'constructor argument type', str, | |
280 | type(info)) | |
281 | raise TypeError(msg) | |
282 | ||
283 | return ContactInformation(info) | |
284 | ||
285 | def _create_last_change_date(self, date): | |
286 | raise NotImplementedError() | |
287 | ||
288 | def _create_custom_attribute(self, data): | |
289 | return CustomAttribute(data) |
0 | # Copyright (c) 2014 The Johns Hopkins University/Applied Physics Laboratory | |
1 | # All Rights Reserved. | |
2 | # | |
3 | # Licensed under the Apache License, Version 2.0 (the "License"); you may | |
4 | # not use this file except in compliance with the License. You may obtain | |
5 | # a copy of the License at | |
6 | # | |
7 | # http://www.apache.org/licenses/LICENSE-2.0 | |
8 | # | |
9 | # Unless required by applicable law or agreed to in writing, software | |
10 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT | |
11 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the | |
12 | # License for the specific language governing permissions and limitations | |
13 | # under the License. | |
14 | ||
15 | from enum import Enum | |
16 | ||
17 | from kmip.core.factories.attribute_values import AttributeValueFactory | |
18 | ||
19 | from kmip.core.objects import Attribute | |
20 | ||
21 | from kmip.core import utils | |
22 | ||
23 | ||
24 | class AttributeFactory(object): | |
25 | ||
26 | def __init__(self): | |
27 | self.value_factory = AttributeValueFactory() | |
28 | ||
29 | def _create_attribute(self, name, value, index): | |
30 | attribute_name = Attribute.AttributeName(name) | |
31 | ||
32 | if index is None: | |
33 | return Attribute(attribute_name=attribute_name, | |
34 | attribute_value=value) | |
35 | else: | |
36 | attribute_index = Attribute.AttributeIndex(index) | |
37 | return Attribute(attribute_name=attribute_name, | |
38 | attribute_index=attribute_index, | |
39 | attribute_value=value) | |
40 | ||
41 | def create_attribute(self, name, value, index=None): | |
42 | value = self.value_factory.create_attribute_value(name, value) | |
43 | ||
44 | if isinstance(name, Enum): | |
45 | name = name.value | |
46 | elif isinstance(name, str): | |
47 | # Name is already a string, pass | |
48 | pass | |
49 | else: | |
50 | msg = utils.build_er_error(Attribute, 'name', | |
51 | '{} or {}'.format('Enum', 'str'), | |
52 | type(name)) | |
53 | raise TypeError(msg) | |
54 | ||
55 | return self._create_attribute(name, value, index) |
0 | # Copyright (c) 2014 The Johns Hopkins University/Applied Physics Laboratory | |
1 | # All Rights Reserved. | |
2 | # | |
3 | # Licensed under the Apache License, Version 2.0 (the "License"); you may | |
4 | # not use this file except in compliance with the License. You may obtain | |
5 | # a copy of the License at | |
6 | # | |
7 | # http://www.apache.org/licenses/LICENSE-2.0 | |
8 | # | |
9 | # Unless required by applicable law or agreed to in writing, software | |
10 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT | |
11 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the | |
12 | # License for the specific language governing permissions and limitations | |
13 | # under the License. | |
14 | ||
15 | from kmip.core.enums import CredentialType | |
16 | ||
17 | from kmip.core.objects import Credential | |
18 | ||
19 | ||
20 | class CredentialFactory(object): | |
21 | def __init__(self): | |
22 | pass | |
23 | ||
24 | def _create_credential(self, credential_type, credential_value): | |
25 | credential_type = Credential.CredentialType(credential_type) | |
26 | return Credential(credential_type=credential_type, | |
27 | credential_value=credential_value) | |
28 | ||
29 | def create_credential(self, cred_type, value): | |
30 | # Switch on the type of the credential | |
31 | if cred_type is CredentialType.USERNAME_AND_PASSWORD: | |
32 | value = self._create_username_password_credential(value) | |
33 | elif cred_type is CredentialType.DEVICE: | |
34 | value = self._create_device_credential(value) | |
35 | else: | |
36 | msg = 'Unrecognized credential type: {}' | |
37 | raise ValueError(msg.format(cred_type)) | |
38 | ||
39 | return self._create_credential(cred_type, value) | |
40 | ||
41 | def _create_username_password_credential(self, value): | |
42 | username = value.get('Username') | |
43 | password = value.get('Password') | |
44 | ||
45 | username = Credential.UsernamePasswordCredential.Username(username) | |
46 | password = Credential.UsernamePasswordCredential.Password(password) | |
47 | ||
48 | return Credential.UsernamePasswordCredential(username=username, | |
49 | password=password) | |
50 | ||
51 | def _create_device_credential(self, value): | |
52 | dsn = value.get('Device Serial Number') | |
53 | password = value.get('Password') | |
54 | dev_id = value.get('Device Identifier') | |
55 | net_id = value.get('Network Identifier') | |
56 | mach_id = value.get('Machine Identifier') | |
57 | med_id = value.get('Media Identifier') | |
58 | ||
59 | dsn = Credential.DeviceCredential.DeviceSerialNumber(dsn) | |
60 | password = Credential.DeviceCredential.Password(password) | |
61 | dev_id = Credential.DeviceCredential.DeviceIdentifier(dev_id) | |
62 | net_id = Credential.DeviceCredential.NetworkIdentifier(net_id) | |
63 | mach_id = Credential.DeviceCredential.MachineIdentifier(mach_id) | |
64 | med_id = Credential.DeviceCredential.MediaIdentifier(med_id) | |
65 | ||
66 | return Credential.DeviceCredential(device_serial_number=dsn, | |
67 | password=password, | |
68 | device_identifier=dev_id, | |
69 | network_identifier=net_id, | |
70 | machine_identifier=mach_id, | |
71 | media_identifier=med_id) |
0 | # Copyright (c) 2014 The Johns Hopkins University/Applied Physics Laboratory | |
1 | # All Rights Reserved. | |
2 | # | |
3 | # Licensed under the Apache License, Version 2.0 (the "License"); you may | |
4 | # not use this file except in compliance with the License. You may obtain | |
5 | # a copy of the License at | |
6 | # | |
7 | # http://www.apache.org/licenses/LICENSE-2.0 | |
8 | # | |
9 | # Unless required by applicable law or agreed to in writing, software | |
10 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT | |
11 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the | |
12 | # License for the specific language governing permissions and limitations | |
13 | # under the License. | |
14 | ||
15 | from kmip.core.enums import KeyFormatType | |
16 | ||
17 | from kmip.core.keys import RawKey | |
18 | ||
19 | ||
20 | class KeyFactory(object): | |
21 | ||
22 | def create_key(self, key_format, value=None): | |
23 | if value is None: | |
24 | value = {} | |
25 | ||
26 | # Switch on the format type of the key | |
27 | if key_format is KeyFormatType.RAW: | |
28 | return self._create_raw_key(value) | |
29 | elif key_format is KeyFormatType.OPAQUE: | |
30 | return self._create_opaque_key(value) | |
31 | elif key_format is KeyFormatType.PKCS_1: | |
32 | return self._create_pkcs_1_key(value) | |
33 | elif key_format is KeyFormatType.PKCS_8: | |
34 | return self._create_pkcs_8_key(value) | |
35 | elif key_format is KeyFormatType.X_509: | |
36 | return self._create_x_509_key(value) | |
37 | elif key_format is KeyFormatType.EC_PRIVATE_KEY: | |
38 | return self._create_ec_private_key(value) | |
39 | elif key_format is KeyFormatType.TRANSPARENT_SYMMETRIC_KEY: | |
40 | return self._create_transparent_symmetric_key(value) | |
41 | elif key_format is KeyFormatType.TRANSPARENT_DSA_PRIVATE_KEY: | |
42 | return self._create_transparent_dsa_private_key(value) | |
43 | elif key_format is KeyFormatType.TRANSPARENT_DSA_PUBLIC_KEY: | |
44 | return self._create_transparent_dsa_public_key(value) | |
45 | elif key_format is KeyFormatType.TRANSPARENT_RSA_PRIVATE_KEY: | |
46 | return self._create_transparent_rsa_private_key(value) | |
47 | elif key_format is KeyFormatType.TRANSPARENT_RSA_PUBLIC_KEY: | |
48 | return self._create_transparent_rsa_public_key(value) | |
49 | elif key_format is KeyFormatType.TRANSPARENT_DH_PRIVATE_KEY: | |
50 | return self._create_transparent_dh_private_key(value) | |
51 | elif key_format is KeyFormatType.TRANSPARENT_DH_PUBLIC_KEY: | |
52 | return self._create_transparent_dh_public_key(value) | |
53 | elif key_format is KeyFormatType.TRANSPARENT_ECDSA_PRIVATE_KEY: | |
54 | return self._create_transparent_ecdsa_private_key(value) | |
55 | elif key_format is KeyFormatType.TRANSPARENT_ECDSA_PUBLIC_KEY: | |
56 | return self._create_transparent_ecdsa_public_key(value) | |
57 | elif key_format is KeyFormatType.TRANSPARENT_ECDH_PRIVATE_KEY: | |
58 | return self._create_transparent_ecdh_private_key(value) | |
59 | elif key_format is KeyFormatType.TRANSPARENT_ECDH_PUBLIC_KEY: | |
60 | return self._create_transparent_ecdh_public_key(value) | |
61 | elif key_format is KeyFormatType.TRANSPARENT_ECMQV_PRIVATE_KEY: | |
62 | return self._create_transparent_ecmqv_private_key(value) | |
63 | elif key_format is KeyFormatType.TRANSPARENT_ECMQV_PUBLIC_KEY: | |
64 | return self._create_transparent_ecmqv_public_key(value) | |
65 | else: | |
66 | msg = 'Unrecognized key format type: {}' | |
67 | raise ValueError(msg.format(key_format)) | |
68 | ||
69 | def _create_raw_key(self, value): | |
70 | data = value.get('bytes') | |
71 | return RawKey(data) | |
72 | ||
73 | def _create_opaque_key(self, value): | |
74 | raise NotImplementedError() | |
75 | ||
76 | def _create_pkcs_1_key(self, value): | |
77 | raise NotImplementedError() | |
78 | ||
79 | def _create_pkcs_8_key(self, value): | |
80 | raise NotImplementedError() | |
81 | ||
82 | def _create_x_509_key(self, value): | |
83 | raise NotImplementedError() | |
84 | ||
85 | def _create_ec_private_key(self, value): | |
86 | raise NotImplementedError() | |
87 | ||
88 | def _create_transparent_symmetric_key(self, value): | |
89 | raise NotImplementedError() | |
90 | ||
91 | def _create_transparent_dsa_private_key(self, value): | |
92 | raise NotImplementedError() | |
93 | ||
94 | def _create_transparent_dsa_public_key(self, value): | |
95 | raise NotImplementedError() | |
96 | ||
97 | def _create_transparent_rsa_private_key(self, value): | |
98 | raise NotImplementedError() | |
99 | ||
100 | def _create_transparent_rsa_public_key(self, value): | |
101 | raise NotImplementedError() | |
102 | ||
103 | def _create_transparent_dh_private_key(self, value): | |
104 | raise NotImplementedError() | |
105 | ||
106 | def _create_transparent_dh_public_key(self, value): | |
107 | raise NotImplementedError() | |
108 | ||
109 | def _create_transparent_ecdsa_private_key(self, value): | |
110 | raise NotImplementedError() | |
111 | ||
112 | def _create_transparent_ecdsa_public_key(self, value): | |
113 | raise NotImplementedError() | |
114 | ||
115 | def _create_transparent_ecdh_private_key(self, value): | |
116 | raise NotImplementedError() | |
117 | ||
118 | def _create_transparent_ecdh_public_key(self, value): | |
119 | raise NotImplementedError() | |
120 | ||
121 | def _create_transparent_ecmqv_private_key(self, value): | |
122 | raise NotImplementedError() | |
123 | ||
124 | def _create_transparent_ecmqv_public_key(self, value): | |
125 | raise NotImplementedError() |
0 | # Copyright (c) 2014 The Johns Hopkins University/Applied Physics Laboratory | |
1 | # All Rights Reserved. | |
2 | # | |
3 | # Licensed under the Apache License, Version 2.0 (the "License"); you may | |
4 | # not use this file except in compliance with the License. You may obtain | |
5 | # a copy of the License at | |
6 | # | |
7 | # http://www.apache.org/licenses/LICENSE-2.0 | |
8 | # | |
9 | # Unless required by applicable law or agreed to in writing, software | |
10 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT | |
11 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the | |
12 | # License for the specific language governing permissions and limitations | |
13 | # under the License. | |
14 | ||
15 | from kmip.core.factories.keys import KeyFactory | |
16 | ||
17 | from kmip.core.attributes import CryptographicAlgorithm | |
18 | from kmip.core.attributes import CryptographicLength | |
19 | ||
20 | from kmip.core.enums import ObjectType | |
21 | ||
22 | from kmip.core.errors import ErrorStrings | |
23 | ||
24 | from kmip.core.objects import Attribute | |
25 | from kmip.core.objects import KeyBlock | |
26 | from kmip.core.objects import KeyWrappingData | |
27 | from kmip.core.objects import KeyValueStruct | |
28 | from kmip.core.objects import KeyValue | |
29 | ||
30 | from kmip.core.secrets import SymmetricKey | |
31 | from kmip.core.secrets import Template | |
32 | ||
33 | from kmip.core import utils | |
34 | ||
35 | ||
36 | class SecretFactory(object): | |
37 | ||
38 | def __init__(self): | |
39 | self.key_factory = KeyFactory() | |
40 | ||
41 | self.base_error = ErrorStrings.BAD_EXP_RECV | |
42 | self.template_input = self.base_error.format('Template', '{0}', '{1}', | |
43 | '{2}') | |
44 | ||
45 | def create_secret(self, secret_type, value=None): | |
46 | if secret_type is ObjectType.CERTIFICATE: | |
47 | return self._create_certificate(value) | |
48 | elif secret_type is ObjectType.SYMMETRIC_KEY: | |
49 | return self._create_symmetric_key(value) | |
50 | elif secret_type is ObjectType.PUBLIC_KEY: | |
51 | return self._create_public_key(value) | |
52 | elif secret_type is ObjectType.PRIVATE_KEY: | |
53 | return self._create_private_key(value) | |
54 | elif secret_type is ObjectType.SPLIT_KEY: | |
55 | return self._create_split_key(value) | |
56 | elif secret_type is ObjectType.TEMPLATE: | |
57 | return self._create_template(value) | |
58 | elif secret_type is ObjectType.SECRET_DATA: | |
59 | return self._create_secret_data(value) | |
60 | elif secret_type is ObjectType.OPAQUE_DATA: | |
61 | return self._create_opaque_data(value) | |
62 | ||
63 | def _create_certificate(self, value): | |
64 | raise NotImplementedError() | |
65 | ||
66 | def _create_symmetric_key(self, value): | |
67 | if value is None: | |
68 | return SymmetricKey() | |
69 | else: | |
70 | key_type = value.get('key_format_type') | |
71 | key_compression_type = value.get('key_compression_type') | |
72 | key_value = value.get('key_value') | |
73 | cryptographic_algorithm = value.get('cryptographic_algorithm') | |
74 | cryptographic_length = value.get('cryptographic_length') | |
75 | key_wrapping_data = value.get('key_wrapping_data') | |
76 | ||
77 | key_format_type = KeyBlock.KeyFormatType(key_type) | |
78 | ||
79 | key_comp_type = None | |
80 | if key_compression_type is not None: | |
81 | key_comp_type = KeyBlock.KeyCompressionType( | |
82 | key_compression_type) | |
83 | ||
84 | key_material = self.key_factory.create_key(key_type, | |
85 | key_value) | |
86 | key_val_struc = KeyValueStruct(key_format_type=key_format_type, | |
87 | key_material=key_material) | |
88 | key_value = KeyValue(key_value=key_val_struc, | |
89 | key_format_type=key_format_type) | |
90 | crypto_algorithm = CryptographicAlgorithm(cryptographic_algorithm) | |
91 | crypto_length = CryptographicLength(cryptographic_length) | |
92 | ||
93 | key_wrap_data = None | |
94 | if key_wrapping_data is not None: | |
95 | # TODO (peter-hamilton) This currently isn't used in the tests | |
96 | # TODO (peter-hamilton) but needs to be updated to properly | |
97 | # TODO (peter-hamilton) create a KeyWrappingData object. | |
98 | key_wrap_data = KeyWrappingData(key_wrapping_data) | |
99 | ||
100 | key_block = KeyBlock(key_format_type, | |
101 | key_comp_type, | |
102 | key_value, | |
103 | crypto_algorithm, | |
104 | crypto_length, | |
105 | key_wrap_data) | |
106 | return SymmetricKey(key_block) | |
107 | ||
108 | def _create_public_key(self, value): | |
109 | raise NotImplementedError() | |
110 | ||
111 | def _create_private_key(self, value): | |
112 | raise NotImplementedError() | |
113 | ||
114 | def _create_split_key(self, value): | |
115 | raise NotImplementedError() | |
116 | ||
117 | def _create_template(self, value): | |
118 | if value is None: | |
119 | return Template() | |
120 | else: | |
121 | if not isinstance(value, list): | |
122 | msg = utils.build_er_error(Template, | |
123 | 'constructor argument type', list, | |
124 | type(value)) | |
125 | raise TypeError(msg) | |
126 | else: | |
127 | for val in value: | |
128 | if not isinstance(val, Attribute): | |
129 | msg = utils.build_er_error(Template, | |
130 | 'constructor argument type', | |
131 | Attribute, type(val)) | |
132 | raise TypeError(msg) | |
133 | return Template(value) | |
134 | ||
135 | def _create_secret_data(self, value): | |
136 | raise NotImplementedError() | |
137 | ||
138 | def _create_opaque_data(self, value): | |
139 | raise NotImplementedError() |
0 | # Copyright (c) 2014 The Johns Hopkins University/Applied Physics Laboratory | |
1 | # All Rights Reserved. | |
2 | # | |
3 | # Licensed under the Apache License, Version 2.0 (the "License"); you may | |
4 | # not use this file except in compliance with the License. You may obtain | |
5 | # a copy of the License at | |
6 | # | |
7 | # http://www.apache.org/licenses/LICENSE-2.0 | |
8 | # | |
9 | # Unless required by applicable law or agreed to in writing, software | |
10 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT | |
11 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the | |
12 | # License for the specific language governing permissions and limitations | |
13 | # under the License. | |
14 | ||
15 | # This module defines classes representing all of the different key types | |
16 | # used by KMIP, including the more detailed structures of the Transparent | |
17 | # Keys defined in Section 2.1.7. | |
18 | ||
19 | from kmip.core.enums import Tags | |
20 | ||
21 | from kmip.core.primitives import Struct | |
22 | from kmip.core.primitives import ByteString | |
23 | ||
24 | from kmip.core.utils import BytearrayStream | |
25 | ||
26 | ||
27 | class RawKey(ByteString): | |
28 | ||
29 | def __init__(self, value=None): | |
30 | super(self.__class__, self).__init__(value, Tags.KEY_MATERIAL) | |
31 | ||
32 | ||
33 | class OpaqueKey(ByteString): | |
34 | ||
35 | def __init__(self, value=None): | |
36 | super(self.__class__, self).__init__(value, Tags.KEY_MATERIAL) | |
37 | ||
38 | ||
39 | class PKCS1Key(ByteString): | |
40 | ||
41 | def __init__(self, value=None): | |
42 | super(self.__class__, self).__init__(value, Tags.KEY_MATERIAL) | |
43 | ||
44 | ||
45 | class PKCS8Key(ByteString): | |
46 | ||
47 | def __init__(self, value=None): | |
48 | super(self.__class__, self).__init__(value, Tags.KEY_MATERIAL) | |
49 | ||
50 | ||
51 | class X509Key(ByteString): | |
52 | ||
53 | def __init__(self, value=None): | |
54 | super(self.__class__, self).__init__(value, Tags.KEY_MATERIAL) | |
55 | ||
56 | ||
57 | class ECPrivateKey(ByteString): | |
58 | ||
59 | def __init__(self, value=None): | |
60 | super(self.__class__, self).__init__(value, Tags.KEY_MATERIAL) | |
61 | ||
62 | ||
63 | # 2.1.7.1 | |
64 | class TransparentSymmetricKey(Struct): | |
65 | ||
66 | class Key(ByteString): | |
67 | ||
68 | def __init__(self, value=None): | |
69 | super(self.__class__, self).__init__(value, Tags.KEY) | |
70 | ||
71 | def __init__(self, key=None): | |
72 | super(self.__class__, self).__init__(Tags.KEY_MATERIAL) | |
73 | self.key = key | |
74 | self.validate() | |
75 | ||
76 | def read(self, istream): | |
77 | super(self.__class__, self).read(istream) | |
78 | tstream = BytearrayStream(istream.read(self.length)) | |
79 | ||
80 | self.key = TransparentSymmetricKey.Key() | |
81 | self.key.read(tstream) | |
82 | ||
83 | self.is_oversized(tstream) | |
84 | self.validate() | |
85 | ||
86 | def write(self, ostream): | |
87 | tstream = BytearrayStream() | |
88 | ||
89 | self.key.write(tstream) | |
90 | ||
91 | # Write the length and value of the key wrapping data | |
92 | self.length = tstream.length() | |
93 | super(self.__class__, self).write(ostream) | |
94 | ostream.write(tstream.buffer) | |
95 | ||
96 | def validate(self): | |
97 | self.__validate() | |
98 | ||
99 | def __validate(self): | |
100 | # TODO (peter-hamilton) Finish implementation. | |
101 | pass |
0 | # Copyright (c) 2014 The Johns Hopkins University/Applied Physics Laboratory | |
1 | # All Rights Reserved. | |
2 | # | |
3 | # Licensed under the Apache License, Version 2.0 (the "License"); you may | |
4 | # not use this file except in compliance with the License. You may obtain | |
5 | # a copy of the License at | |
6 | # | |
7 | # http://www.apache.org/licenses/LICENSE-2.0 | |
8 | # | |
9 | # Unless required by applicable law or agreed to in writing, software | |
10 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT | |
11 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the | |
12 | # License for the specific language governing permissions and limitations | |
13 | # under the License. | |
14 | ||
15 | __all__ = ['contents', 'messages', 'operations'] |
0 | # Copyright (c) 2014 The Johns Hopkins University/Applied Physics Laboratory | |
1 | # All Rights Reserved. | |
2 | # | |
3 | # Licensed under the Apache License, Version 2.0 (the "License"); you may | |
4 | # not use this file except in compliance with the License. You may obtain | |
5 | # a copy of the License at | |
6 | # | |
7 | # http://www.apache.org/licenses/LICENSE-2.0 | |
8 | # | |
9 | # Unless required by applicable law or agreed to in writing, software | |
10 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT | |
11 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the | |
12 | # License for the specific language governing permissions and limitations | |
13 | # under the License. | |
14 | ||
15 | from kmip.core import enums | |
16 | from kmip.core import objects | |
17 | from kmip.core import utils | |
18 | ||
19 | from kmip.core.primitives import Struct | |
20 | from kmip.core.primitives import Integer | |
21 | from kmip.core.primitives import Enumeration | |
22 | from kmip.core.primitives import Boolean | |
23 | from kmip.core.primitives import TextString | |
24 | from kmip.core.primitives import ByteString | |
25 | from kmip.core.primitives import DateTime | |
26 | ||
27 | ||
28 | # 6.1 | |
29 | class ProtocolVersion(Struct): | |
30 | ||
31 | class ProtocolVersionMajor(Integer): | |
32 | def __init__(self, value=None): | |
33 | super(self.__class__, self).\ | |
34 | __init__(value, enums.Tags.PROTOCOL_VERSION_MAJOR) | |
35 | ||
36 | class ProtocolVersionMinor(Integer): | |
37 | def __init__(self, value=None): | |
38 | super(self.__class__, self).\ | |
39 | __init__(value, enums.Tags.PROTOCOL_VERSION_MINOR) | |
40 | ||
41 | def __init__(self, | |
42 | protocol_version_major=None, | |
43 | protocol_version_minor=None): | |
44 | super(self.__class__, self).__init__(tag=enums.Tags.PROTOCOL_VERSION) | |
45 | self.protocol_version_major = protocol_version_major | |
46 | self.protocol_version_minor = protocol_version_minor | |
47 | ||
48 | def read(self, istream): | |
49 | super(self.__class__, self).read(istream) | |
50 | tstream = utils.BytearrayStream(istream.read(self.length)) | |
51 | ||
52 | # Read the major and minor portions of the version number | |
53 | self.protocol_version_major = ProtocolVersion.ProtocolVersionMajor() | |
54 | self.protocol_version_minor = ProtocolVersion.ProtocolVersionMinor() | |
55 | self.protocol_version_major.read(tstream) | |
56 | self.protocol_version_minor.read(tstream) | |
57 | ||
58 | self.is_oversized(tstream) | |
59 | ||
60 | def write(self, ostream): | |
61 | tstream = utils.BytearrayStream() | |
62 | ||
63 | # Write the major and minor portions of the protocol version | |
64 | self.protocol_version_major.write(tstream) | |
65 | self.protocol_version_minor.write(tstream) | |
66 | ||
67 | # Write the length and value of the protocol version | |
68 | self.length = tstream.length() | |
69 | super(self.__class__, self).write(ostream) | |
70 | ostream.write(tstream.buffer) | |
71 | ||
72 | def validate(self): | |
73 | # TODO (peter-hamilton) Finish implementation. | |
74 | pass | |
75 | ||
76 | @classmethod | |
77 | def create(cls, major, minor): | |
78 | major_version = cls.ProtocolVersionMajor(major) | |
79 | minor_version = cls.ProtocolVersionMinor(minor) | |
80 | return ProtocolVersion(major_version, minor_version) | |
81 | ||
82 | ||
83 | # 6.2 | |
84 | class Operation(Enumeration): | |
85 | ENUM_TYPE = enums.Operation | |
86 | ||
87 | def __init__(self, value=None): | |
88 | super(self.__class__, self).__init__(value, enums.Tags.OPERATION) | |
89 | ||
90 | ||
91 | # 6.3 | |
92 | class MaximumResponseSize(Integer): | |
93 | def __init__(self, value=None): | |
94 | super(self.__class__, self).\ | |
95 | __init__(value, enums.Tags.MAXIMUM_RESPONSE_SIZE) | |
96 | ||
97 | ||
98 | # 6.4 | |
99 | class UniqueBatchItemID(ByteString): | |
100 | def __init__(self, value=None): | |
101 | super(self.__class__, self)\ | |
102 | .__init__(value, enums.Tags.UNIQUE_BATCH_ITEM_ID) | |
103 | ||
104 | ||
105 | # 6.5 | |
106 | class TimeStamp(DateTime): | |
107 | def __init__(self, value=None): | |
108 | super(self.__class__, self).__init__(value, enums.Tags.TIME_STAMP) | |
109 | ||
110 | ||
111 | # 6.6 | |
112 | class Authentication(Struct): | |
113 | ||
114 | def __init__(self, credential=None): | |
115 | super(self.__class__, self).__init__(tag=enums.Tags.AUTHENTICATION) | |
116 | self.credential = credential | |
117 | ||
118 | def read(self, istream): | |
119 | super(self.__class__, self).read(istream) | |
120 | tstream = utils.BytearrayStream(istream.read(self.length)) | |
121 | ||
122 | # Read the credential | |
123 | self.credential = objects.Credential() | |
124 | self.credential.read(tstream) | |
125 | ||
126 | self.is_oversized(tstream) | |
127 | ||
128 | def write(self, ostream): | |
129 | tstream = utils.BytearrayStream() | |
130 | ||
131 | # Write the credential | |
132 | self.credential.write(tstream) | |
133 | ||
134 | # Write the length and value of the protocol version | |
135 | self.length = tstream.length() | |
136 | super(self.__class__, self).write(ostream) | |
137 | ostream.write(tstream.buffer) | |
138 | ||
139 | def validate(self): | |
140 | # TODO (peter-hamilton) Finish implementation. | |
141 | pass | |
142 | ||
143 | ||
144 | # 6.7 | |
145 | class AsynchronousIndicator(Boolean): | |
146 | def __init__(self, value=None): | |
147 | super(self.__class__, self).\ | |
148 | __init__(value, enums.Tags.ASYNCHRONOUS_INDICATOR) | |
149 | ||
150 | ||
151 | # 6.8 | |
152 | class AsynchronousCorrelationValue(ByteString): | |
153 | def __init__(self, value=None): | |
154 | super(self.__class__, self).\ | |
155 | __init__(value, enums.Tags.ASYNCHRONOUS_CORRELATION_VALUE) | |
156 | ||
157 | ||
158 | # 6.9 | |
159 | class ResultStatus(Enumeration): | |
160 | ENUM_TYPE = enums.ResultStatus | |
161 | ||
162 | def __init__(self, value=None): | |
163 | super(self.__class__, self).__init__(value, enums.Tags.RESULT_STATUS) | |
164 | ||
165 | ||
166 | # 6.10 | |
167 | class ResultReason(Enumeration): | |
168 | ENUM_TYPE = enums.ResultReason | |
169 | ||
170 | def __init__(self, value=None): | |
171 | super(self.__class__, self).__init__(value, enums.Tags.RESULT_REASON) | |
172 | ||
173 | ||
174 | # 6.11 | |
175 | class ResultMessage(TextString): | |
176 | def __init__(self, value=None): | |
177 | super(self.__class__, self).__init__(value, enums.Tags.RESULT_MESSAGE) | |
178 | ||
179 | ||
180 | # 6.12 | |
181 | class BatchOrderOption(Boolean): | |
182 | def __init__(self, value=None): | |
183 | super(self.__class__, self).\ | |
184 | __init__(value, enums.Tags.BATCH_ORDER_OPTION) | |
185 | ||
186 | ||
187 | # 6.13 | |
188 | class BatchErrorContinuationOption(Enumeration): | |
189 | ENUM_TYPE = enums.BatchErrorContinuationOption | |
190 | ||
191 | def __init__(self, value=None): | |
192 | super(self.__class__, self).\ | |
193 | __init__(value, enums.Tags.BATCH_ERROR_CONTINUATION_OPTION) | |
194 | ||
195 | ||
196 | # 6.14 | |
197 | class BatchCount(Integer): | |
198 | def __init__(self, value=None): | |
199 | super(self.__class__, self).__init__(value, enums.Tags.BATCH_COUNT) | |
200 | ||
201 | ||
202 | # 6.16 | |
203 | class MessageExtension(Struct): | |
204 | def __init__(self): | |
205 | super(self.__class__, self).__init__(tag=enums.Tags.MESSAGE_EXTENSION) | |
206 | ||
207 | ||
208 | # 9.1.3.2.2 | |
209 | class KeyCompressionType(Enumeration): | |
210 | ENUM_TYPE = enums.KeyCompressionType | |
211 | ||
212 | def __init__(self, value=None): | |
213 | super(self.__class__, self).\ | |
214 | __init__(value, enums.Tags.KEY_COMPRESSION_TYPE) | |
215 | ||
216 | ||
217 | # 9.1.3.2.3 | |
218 | class KeyFormatType(Enumeration): | |
219 | ENUM_TYPE = enums.KeyFormatType | |
220 | ||
221 | def __init__(self, value=None): | |
222 | super(self.__class__, self).\ | |
223 | __init__(value, enums.Tags.KEY_FORMAT_TYPE) |
0 | # Copyright (c) 2014 The Johns Hopkins University/Applied Physics Laboratory | |
1 | # All Rights Reserved. | |
2 | # | |
3 | # Licensed under the Apache License, Version 2.0 (the "License"); you may | |
4 | # not use this file except in compliance with the License. You may obtain | |
5 | # a copy of the License at | |
6 | # | |
7 | # http://www.apache.org/licenses/LICENSE-2.0 | |
8 | # | |
9 | # Unless required by applicable law or agreed to in writing, software | |
10 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT | |
11 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the | |
12 | # License for the specific language governing permissions and limitations | |
13 | # under the License. | |
14 | ||
15 | from kmip.core.enums import Tags | |
16 | ||
17 | from kmip.core.messages import contents | |
18 | from kmip.core.messages.contents import AsynchronousCorrelationValue | |
19 | from kmip.core.messages.contents import BatchErrorContinuationOption | |
20 | ||
21 | from kmip.core.messages import operations | |
22 | ||
23 | from kmip.core.primitives import Struct | |
24 | ||
25 | from kmip.core.utils import BytearrayStream | |
26 | ||
27 | ||
28 | class RequestHeader(Struct): | |
29 | ||
30 | def __init__(self, | |
31 | protocol_version=None, | |
32 | maximum_response_size=None, | |
33 | asynchronous_indicator=None, | |
34 | authentication=None, | |
35 | batch_error_cont_option=None, | |
36 | batch_order_option=None, | |
37 | time_stamp=None, | |
38 | batch_count=None): | |
39 | super(self.__class__, self).__init__(tag=Tags.REQUEST_HEADER) | |
40 | self.protocol_version = protocol_version | |
41 | self.maximum_response_size = maximum_response_size | |
42 | self.asynchronous_indicator = asynchronous_indicator | |
43 | self.authentication = authentication | |
44 | self.batch_error_cont_option = batch_error_cont_option | |
45 | self.batch_order_option = batch_order_option | |
46 | self.time_stamp = time_stamp | |
47 | self.batch_count = batch_count | |
48 | ||
49 | def read(self, istream): | |
50 | super(self.__class__, self).read(istream) | |
51 | tstream = BytearrayStream(istream.read(self.length)) | |
52 | ||
53 | self.protocol_version = contents.ProtocolVersion() | |
54 | self.protocol_version.read(tstream) | |
55 | ||
56 | # Read the maximum response size if it is present | |
57 | if self.is_tag_next(Tags.MAXIMUM_RESPONSE_SIZE, tstream): | |
58 | self.maximum_response_size = contents.MaximumResponseSize() | |
59 | self.maximum_response_size.read(tstream) | |
60 | ||
61 | # Read the asynchronous indicator if it is present | |
62 | if self.is_tag_next(Tags.ASYNCHRONOUS_INDICATOR, tstream): | |
63 | self.asynchronous_indicator = contents.AsynchronousIndicator() | |
64 | self.asynchronous_indicator.read(tstream) | |
65 | ||
66 | # Read the authentication if it is present | |
67 | if self.is_tag_next(Tags.AUTHENTICATION, tstream): | |
68 | self.authentication = contents.Authentication() | |
69 | self.authentication.read(tstream) | |
70 | ||
71 | # Read the batch error continuation option if it is present | |
72 | if self.is_tag_next(Tags.BATCH_ERROR_CONTINUATION_OPTION, tstream): | |
73 | self.batch_error_cont_option = BatchErrorContinuationOption() | |
74 | self.batch_error_cont_option.read(tstream) | |
75 | ||
76 | # Read the batch order option if it is present | |
77 | if self.is_tag_next(Tags.BATCH_ORDER_OPTION, tstream): | |
78 | self.batch_order_option = contents.BatchOrderOption() | |
79 | self.batch_order_option.read(tstream) | |
80 | ||
81 | # Read the time stamp if it is present | |
82 | if self.is_tag_next(Tags.TIME_STAMP, tstream): | |
83 | self.time_stamp = contents.TimeStamp() | |
84 | self.time_stamp.read(tstream) | |
85 | ||
86 | self.batch_count = contents.BatchCount() | |
87 | self.batch_count.read(tstream) | |
88 | ||
89 | self.is_oversized(tstream) | |
90 | ||
91 | def write(self, ostream): | |
92 | tstream = BytearrayStream() | |
93 | ||
94 | # Write the contents of a request header to the stream | |
95 | self.protocol_version.write(tstream) | |
96 | if self.maximum_response_size is not None: | |
97 | self.maximum_response_size.write(tstream) | |
98 | if self.asynchronous_indicator is not None: | |
99 | self.asynchronous_indicator.write(tstream) | |
100 | if self.authentication is not None: | |
101 | self.authentication.write(tstream) | |
102 | if self.batch_error_cont_option is not None: | |
103 | self.batch_error_cont_option.write(tstream) | |
104 | if self.batch_order_option is not None: | |
105 | self.batch_order_option.write(tstream) | |
106 | if self.time_stamp is not None: | |
107 | self.time_stamp.write(tstream) | |
108 | self.batch_count.write(tstream) | |
109 | ||
110 | # Write the length and value of the request header | |
111 | self.length = tstream.length() | |
112 | super(self.__class__, self).write(ostream) | |
113 | ostream.write(tstream.buffer) | |
114 | ||
115 | ||
116 | class ResponseHeader(Struct): | |
117 | ||
118 | def __init__(self, | |
119 | protocol_version=None, | |
120 | time_stamp=None, | |
121 | batch_count=None): | |
122 | super(self.__class__, self).__init__(tag=Tags.RESPONSE_HEADER) | |
123 | self.protocol_version = protocol_version | |
124 | self.time_stamp = time_stamp | |
125 | self.batch_count = batch_count | |
126 | self.validate() | |
127 | ||
128 | def read(self, istream): | |
129 | super(self.__class__, self).read(istream) | |
130 | tstream = BytearrayStream(istream.read(self.length)) | |
131 | ||
132 | self.protocol_version = contents.ProtocolVersion() | |
133 | self.protocol_version.read(tstream) | |
134 | ||
135 | self.time_stamp = contents.TimeStamp() | |
136 | self.time_stamp.read(tstream) | |
137 | ||
138 | self.batch_count = contents.BatchCount() | |
139 | self.batch_count.read(tstream) | |
140 | ||
141 | self.is_oversized(tstream) | |
142 | self.validate() | |
143 | ||
144 | def write(self, ostream): | |
145 | tstream = BytearrayStream() | |
146 | ||
147 | # Write the contents of a response header to the stream | |
148 | self.protocol_version.write(tstream) | |
149 | self.time_stamp.write(tstream) | |
150 | self.batch_count.write(tstream) | |
151 | ||
152 | # Write the length and value of the request header | |
153 | self.length = tstream.length() | |
154 | super(self.__class__, self).write(ostream) | |
155 | ostream.write(tstream.buffer) | |
156 | ||
157 | def validate(self): | |
158 | if self.protocol_version is not None: | |
159 | # TODO (peter-hamilton) conduct type check | |
160 | self.protocol_version.validate() | |
161 | if self.time_stamp is not None: | |
162 | # TODO (peter-hamilton) conduct type check | |
163 | self.time_stamp.validate() | |
164 | if self.batch_count is not None: | |
165 | # TODO (peter-hamilton) conduct type check | |
166 | self.batch_count.validate() | |
167 | ||
168 | ||
169 | class RequestBatchItem(Struct): | |
170 | ||
171 | def __init__(self, | |
172 | operation=None, | |
173 | unique_batch_item_id=None, | |
174 | request_payload=None, | |
175 | message_extension=None): | |
176 | super(self.__class__, self).__init__(tag=Tags.REQUEST_BATCH_ITEM) | |
177 | self.operation = operation | |
178 | self.unique_batch_item_id = unique_batch_item_id | |
179 | self.request_payload = request_payload | |
180 | self.message_extension = message_extension | |
181 | ||
182 | def read(self, istream): | |
183 | super(self.__class__, self).read(istream) | |
184 | tstream = BytearrayStream(istream.read(self.length)) | |
185 | ||
186 | # Read the batch item operation | |
187 | self.operation = contents.Operation() | |
188 | self.operation.read(tstream) | |
189 | ||
190 | # Read the unique batch item ID if it is present | |
191 | if self.is_tag_next(Tags.UNIQUE_BATCH_ITEM_ID, tstream): | |
192 | self.unique_batch_item_id = contents.UniqueBatchItemID() | |
193 | self.unique_batch_item_id.read(tstream) | |
194 | ||
195 | # Lookup the response payload class that belongs to the operation | |
196 | cls = operations.REQUEST_MAP.get(self.operation.enum) | |
197 | self.request_payload = cls() | |
198 | self.request_payload.read(tstream) | |
199 | ||
200 | # Read the message extension if it is present | |
201 | if self.is_tag_next(Tags.MESSAGE_EXTENSION, tstream): | |
202 | self.message_extension = contents.MessageExtension() | |
203 | self.message_extension.read(tstream) | |
204 | ||
205 | self.is_oversized(tstream) | |
206 | ||
207 | def write(self, ostream): | |
208 | tstream = BytearrayStream() | |
209 | ||
210 | # Write the contents of the batch item to the stream | |
211 | self.operation.write(tstream) | |
212 | ||
213 | if self.unique_batch_item_id is not None: | |
214 | self.unique_batch_item_id.write(tstream) | |
215 | ||
216 | self.request_payload.write(tstream) | |
217 | ||
218 | if self.message_extension is not None: | |
219 | self.message_extension.write(tstream) | |
220 | ||
221 | # Write the length and value of the batch item | |
222 | self.length = tstream.length() | |
223 | super(self.__class__, self).write(ostream) | |
224 | ostream.write(tstream.buffer) | |
225 | ||
226 | ||
227 | class ResponseBatchItem(Struct): | |
228 | ||
229 | def __init__(self, | |
230 | operation=None, | |
231 | unique_batch_item_id=None, | |
232 | result_status=None, | |
233 | result_reason=None, | |
234 | result_message=None, | |
235 | async_correlation_value=None, | |
236 | response_payload=None, | |
237 | message_extension=None): | |
238 | super(self.__class__, self).__init__(tag=Tags.RESPONSE_BATCH_ITEM) | |
239 | self.operation = operation | |
240 | self.unique_batch_item_id = unique_batch_item_id | |
241 | self.result_status = result_status | |
242 | self.result_reason = result_reason | |
243 | self.result_message = result_message | |
244 | self.async_correlation_value = async_correlation_value | |
245 | self.response_payload = response_payload | |
246 | self.message_extension = message_extension | |
247 | self.validate() | |
248 | ||
249 | def read(self, istream): | |
250 | super(self.__class__, self).read(istream) | |
251 | tstream = BytearrayStream(istream.read(self.length)) | |
252 | ||
253 | # Read the batch item operation if it is present | |
254 | if self.is_tag_next(Tags.OPERATION, tstream): | |
255 | self.operation = contents.Operation() | |
256 | self.operation.read(tstream) | |
257 | ||
258 | # Read the unique batch item ID if it is present | |
259 | if self.is_tag_next(Tags.UNIQUE_BATCH_ITEM_ID, tstream): | |
260 | self.unique_batch_item_id = contents.UniqueBatchItemID() | |
261 | self.unique_batch_item_id.read(tstream) | |
262 | ||
263 | # Read the batch item result status | |
264 | self.result_status = contents.ResultStatus() | |
265 | self.result_status.read(tstream) | |
266 | ||
267 | # Read the batch item result reason if it is present | |
268 | if self.is_tag_next(Tags.RESULT_REASON, tstream): | |
269 | self.result_reason = contents.ResultReason() | |
270 | self.result_reason.read(tstream) | |
271 | ||
272 | # Read the batch item result message if it is present | |
273 | if self.is_tag_next(Tags.RESULT_MESSAGE, tstream): | |
274 | self.result_message = contents.ResultMessage() | |
275 | self.result_message.read(tstream) | |
276 | ||
277 | # Read the batch item asynchronous correlation value if it is present | |
278 | if self.is_tag_next(Tags.ASYNCHRONOUS_CORRELATION_VALUE, tstream): | |
279 | self.async_correlation_value = AsynchronousCorrelationValue() | |
280 | self.async_correlation_value.read(tstream) | |
281 | ||
282 | # Lookup the response payload class that belongs to the operation | |
283 | cls = operations.RESPONSE_MAP.get(self.operation.enum) | |
284 | expected = cls() | |
285 | if self.is_tag_next(expected.tag, tstream): | |
286 | self.response_payload = cls() | |
287 | self.response_payload.read(tstream) | |
288 | ||
289 | # Read the message extension if it is present | |
290 | if self.is_tag_next(Tags.MESSAGE_EXTENSION, tstream): | |
291 | self.message_extension = contents.MessageExtension() | |
292 | self.message_extension.read(tstream) | |
293 | ||
294 | self.is_oversized(tstream) | |
295 | self.validate() | |
296 | ||
297 | def write(self, ostream): | |
298 | tstream = BytearrayStream() | |
299 | ||
300 | # Write the contents of the batch item to the stream | |
301 | if self.operation is not None: | |
302 | self.operation.write(tstream) | |
303 | if self.unique_batch_item_id is not None: | |
304 | self.unique_batch_item_id.write(tstream) | |
305 | ||
306 | self.result_status.write(tstream) | |
307 | ||
308 | if self.result_reason is not None: | |
309 | self.result_reason.write(tstream) | |
310 | if self.result_message is not None: | |
311 | self.result_message.write(tstream) | |
312 | if self.async_correlation_value is not None: | |
313 | self.async_correlation_value.write(tstream) | |
314 | if self.response_payload is not None: | |
315 | self.response_payload.write(tstream) | |
316 | if self.message_extension is not None: | |
317 | self.message_extension.write(tstream) | |
318 | ||
319 | # Write the length and value of the batch item | |
320 | self.length = tstream.length() | |
321 | super(self.__class__, self).write(ostream) | |
322 | ostream.write(tstream.buffer) | |
323 | ||
324 | def validate(self): | |
325 | pass | |
326 | ||
327 | ||
328 | class RequestMessage(Struct): | |
329 | ||
330 | def __init__(self, request_header=None, batch_items=None,): | |
331 | super(self.__class__, self).__init__(tag=Tags.REQUEST_MESSAGE) | |
332 | self.request_header = request_header | |
333 | self.batch_items = batch_items | |
334 | ||
335 | def read(self, istream): | |
336 | super(self.__class__, self).read(istream) | |
337 | ||
338 | self.request_header = RequestHeader() | |
339 | self.request_header.read(istream) | |
340 | ||
341 | self.batch_items = [] | |
342 | for _ in xrange(self.request_header.batch_count.value): | |
343 | batch_item = RequestBatchItem() | |
344 | batch_item.read(istream) | |
345 | self.batch_items.append(batch_item) | |
346 | ||
347 | def write(self, ostream): | |
348 | tstream = BytearrayStream() | |
349 | ||
350 | # Write the request header and all batch items | |
351 | self.request_header.write(tstream) | |
352 | for batch_item in self.batch_items: | |
353 | batch_item.write(tstream) | |
354 | ||
355 | # Write the TTLV encoding of the request message | |
356 | self.length = tstream.length() | |
357 | super(self.__class__, self).write(ostream) | |
358 | ostream.write(tstream.buffer) | |
359 | ||
360 | ||
361 | class ResponseMessage(Struct): | |
362 | ||
363 | def __init__(self, response_header=None, batch_items=None,): | |
364 | super(self.__class__, self).__init__(tag=Tags.RESPONSE_MESSAGE) | |
365 | self.response_header = response_header | |
366 | self.batch_items = batch_items | |
367 | self.validate() | |
368 | ||
369 | def read(self, istream): | |
370 | super(self.__class__, self).read(istream) | |
371 | ||
372 | self.response_header = ResponseHeader() | |
373 | self.response_header.read(istream) | |
374 | ||
375 | self.batch_items = [] | |
376 | for _ in xrange(self.response_header.batch_count.value): | |
377 | batch_item = ResponseBatchItem() | |
378 | batch_item.read(istream) | |
379 | self.batch_items.append(batch_item) | |
380 | self.validate() | |
381 | ||
382 | def write(self, ostream): | |
383 | tstream = BytearrayStream() | |
384 | ||
385 | # Write the request header and all batch items | |
386 | self.response_header.write(tstream) | |
387 | for batch_item in self.batch_items: | |
388 | batch_item.write(tstream) | |
389 | ||
390 | # Write the TTLV encoding of the request message | |
391 | self.length = tstream.length() | |
392 | super(self.__class__, self).write(ostream) | |
393 | ostream.write(tstream.buffer) | |
394 | ||
395 | def validate(self): | |
396 | pass |
0 | # Copyright (c) 2014 The Johns Hopkins University/Applied Physics Laboratory | |
1 | # All Rights Reserved. | |
2 | # | |
3 | # Licensed under the Apache License, Version 2.0 (the "License"); you may | |
4 | # not use this file except in compliance with the License. You may obtain | |
5 | # a copy of the License at | |
6 | # | |
7 | # http://www.apache.org/licenses/LICENSE-2.0 | |
8 | # | |
9 | # Unless required by applicable law or agreed to in writing, software | |
10 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT | |
11 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the | |
12 | # License for the specific language governing permissions and limitations | |
13 | # under the License. | |
14 | ||
15 | from kmip.core.factories.secrets import SecretFactory | |
16 | ||
17 | from kmip.core import attributes | |
18 | from kmip.core import enums | |
19 | from kmip.core.enums import Tags | |
20 | ||
21 | from kmip.core.objects import KeyWrappingSpecification | |
22 | from kmip.core.objects import TemplateAttribute | |
23 | ||
24 | from kmip.core.primitives import Struct | |
25 | from kmip.core.primitives import Enumeration | |
26 | ||
27 | from kmip.core.utils import BytearrayStream | |
28 | ||
29 | ||
30 | # 4.1 | |
31 | class CreateRequestPayload(Struct): | |
32 | ||
33 | def __init__(self, | |
34 | object_type=None, | |
35 | template_attribute=None): | |
36 | super(self.__class__, self).__init__(tag=enums.Tags.REQUEST_PAYLOAD) | |
37 | self.object_type = object_type | |
38 | self.template_attribute = template_attribute | |
39 | self.validate() | |
40 | ||
41 | def read(self, istream): | |
42 | super(self.__class__, self).read(istream) | |
43 | tstream = BytearrayStream(istream.read(self.length)) | |
44 | ||
45 | self.object_type = attributes.ObjectType() | |
46 | self.template_attribute = TemplateAttribute() | |
47 | ||
48 | self.object_type.read(tstream) | |
49 | self.template_attribute.read(tstream) | |
50 | ||
51 | self.is_oversized(tstream) | |
52 | self.validate() | |
53 | ||
54 | def write(self, ostream): | |
55 | tstream = BytearrayStream() | |
56 | ||
57 | # Write the object type and template attribute of the request payload | |
58 | self.object_type.write(tstream) | |
59 | self.template_attribute.write(tstream) | |
60 | ||
61 | # Write the length and value of the request payload | |
62 | self.length = tstream.length() | |
63 | super(self.__class__, self).write(ostream) | |
64 | ostream.write(tstream.buffer) | |
65 | ||
66 | def validate(self): | |
67 | # TODO (peter-hamilton) Finish implementation. | |
68 | pass | |
69 | ||
70 | ||
71 | class CreateResponsePayload(Struct): | |
72 | ||
73 | def __init__(self, | |
74 | object_type=None, | |
75 | unique_identifier=None, | |
76 | template_attribute=None): | |
77 | super(self.__class__, self).__init__(tag=enums.Tags.RESPONSE_PAYLOAD) | |
78 | self.object_type = object_type | |
79 | self.unique_identifier = unique_identifier | |
80 | self.template_attribute = template_attribute | |
81 | self.validate() | |
82 | ||
83 | def read(self, istream): | |
84 | super(self.__class__, self).read(istream) | |
85 | tstream = BytearrayStream(istream.read(self.length)) | |
86 | ||
87 | self.object_type = attributes.ObjectType() | |
88 | self.unique_identifier = attributes.UniqueIdentifier() | |
89 | ||
90 | self.object_type.read(tstream) | |
91 | self.unique_identifier.read(tstream) | |
92 | ||
93 | if self.is_tag_next(Tags.TEMPLATE_ATTRIBUTE, tstream): | |
94 | self.template_attribute = TemplateAttribute() | |
95 | self.template_attribute.read(tstream) | |
96 | ||
97 | self.is_oversized(tstream) | |
98 | self.validate() | |
99 | ||
100 | def write(self, ostream): | |
101 | tstream = BytearrayStream() | |
102 | ||
103 | # Write the contents of the request payload | |
104 | self.object_type.write(tstream) | |
105 | self.unique_identifier.write(tstream) | |
106 | ||
107 | if self.template_attribute is not None: | |
108 | self.template_attribute.write(tstream) | |
109 | ||
110 | # Write the length and value of the request payload | |
111 | self.length = tstream.length() | |
112 | super(self.__class__, self).write(ostream) | |
113 | ostream.write(tstream.buffer) | |
114 | ||
115 | def validate(self): | |
116 | # TODO (peter-hamilton) Finish implementation. | |
117 | pass | |
118 | ||
119 | ||
120 | # 4.3 | |
121 | class RegisterRequestPayload(Struct): | |
122 | ||
123 | def __init__(self, | |
124 | object_type=None, | |
125 | template_attribute=None, | |
126 | secret=None): | |
127 | super(self.__class__, self).__init__(Tags.REQUEST_PAYLOAD) | |
128 | ||
129 | self.secret_factory = SecretFactory() | |
130 | self.object_type = object_type | |
131 | self.template_attribute = template_attribute | |
132 | self.secret = secret | |
133 | ||
134 | self.validate() | |
135 | ||
136 | def read(self, istream): | |
137 | super(self.__class__, self).read(istream) | |
138 | tstream = BytearrayStream(istream.read(self.length)) | |
139 | ||
140 | self.object_type = attributes.ObjectType() | |
141 | self.template_attribute = TemplateAttribute() | |
142 | ||
143 | self.object_type.read(tstream) | |
144 | self.template_attribute.read(tstream) | |
145 | ||
146 | secret_type = self.object_type.enum | |
147 | secret = self.secret_factory.create_secret(secret_type) | |
148 | ||
149 | if self.is_tag_next(secret.tag, tstream): | |
150 | self.secret = secret | |
151 | self.secret.read(tstream) | |
152 | ||
153 | self.is_oversized(tstream) | |
154 | self.validate() | |
155 | ||
156 | def write(self, ostream): | |
157 | tstream = BytearrayStream() | |
158 | ||
159 | # Write the contents of the request payload | |
160 | self.object_type.write(tstream) | |
161 | self.template_attribute.write(tstream) | |
162 | ||
163 | if self.secret is not None: | |
164 | self.secret.write(tstream) | |
165 | ||
166 | # Write the length and value of the request payload | |
167 | self.length = tstream.length() | |
168 | super(self.__class__, self).write(ostream) | |
169 | ostream.write(tstream.buffer) | |
170 | ||
171 | def validate(self): | |
172 | self.__validate() | |
173 | ||
174 | def __validate(self): | |
175 | # TODO (peter-hamilton) Finish implementation. | |
176 | pass | |
177 | ||
178 | ||
179 | class RegisterResponsePayload(Struct): | |
180 | ||
181 | def __init__(self, | |
182 | unique_identifier=None, | |
183 | template_attribute=None): | |
184 | super(self.__class__, self).__init__(Tags.RESPONSE_PAYLOAD) | |
185 | ||
186 | self.unique_identifier = unique_identifier | |
187 | self.template_attribute = template_attribute | |
188 | ||
189 | self.validate() | |
190 | ||
191 | def read(self, istream): | |
192 | super(self.__class__, self).read(istream) | |
193 | tstream = BytearrayStream(istream.read(self.length)) | |
194 | ||
195 | self.unique_identifier = attributes.UniqueIdentifier() | |
196 | self.unique_identifier.read(tstream) | |
197 | ||
198 | if self.is_tag_next(Tags.TEMPLATE_ATTRIBUTE, tstream): | |
199 | self.template_attribute = TemplateAttribute() | |
200 | self.template_attribute.read(tstream) | |
201 | ||
202 | self.is_oversized(tstream) | |
203 | self.validate() | |
204 | ||
205 | def write(self, ostream): | |
206 | tstream = BytearrayStream() | |
207 | ||
208 | # Write the contents of the request payload | |
209 | self.unique_identifier.write(tstream) | |
210 | ||
211 | if self.template_attribute is not None: | |
212 | self.template_attribute.write(tstream) | |
213 | ||
214 | # Write the length and value of the request payload | |
215 | self.length = tstream.length() | |
216 | super(self.__class__, self).write(ostream) | |
217 | ostream.write(tstream.buffer) | |
218 | ||
219 | def validate(self): | |
220 | self.__validate() | |
221 | ||
222 | def __validate(self): | |
223 | # TODO (peter-hamilton) Finish implementation. | |
224 | pass | |
225 | ||
226 | ||
227 | # 4.11 | |
228 | class GetRequestPayload(Struct): | |
229 | ||
230 | # 9.1.3.2.2 | |
231 | class KeyCompressionType(Enumeration): | |
232 | ENUM_TYPE = enums.KeyCompressionType | |
233 | ||
234 | def __init__(self, value=None): | |
235 | super(self.__class__, self).__init__(value, | |
236 | Tags.KEY_COMPRESSION_TYPE) | |
237 | ||
238 | # 9.1.3.2.3 | |
239 | class KeyFormatType(Enumeration): | |
240 | ENUM_TYPE = enums.KeyFormatType | |
241 | ||
242 | def __init__(self, value=None): | |
243 | super(self.__class__, self).__init__(value, Tags.KEY_FORMAT_TYPE) | |
244 | ||
245 | def __init__(self, | |
246 | unique_identifier=None, | |
247 | key_format_type=None, | |
248 | key_compression_type=None, | |
249 | key_wrapping_specification=None): | |
250 | super(self.__class__, self).__init__(tag=enums.Tags.REQUEST_PAYLOAD) | |
251 | self.unique_identifier = unique_identifier | |
252 | self.key_format_type = key_format_type | |
253 | self.key_compression_type = key_compression_type | |
254 | self.key_wrapping_specification = key_wrapping_specification | |
255 | self.validate() | |
256 | ||
257 | def read(self, istream): | |
258 | super(self.__class__, self).read(istream) | |
259 | tstream = BytearrayStream(istream.read(self.length)) | |
260 | ||
261 | if self.is_tag_next(Tags.UNIQUE_IDENTIFIER, tstream): | |
262 | self.unique_identifier = attributes.UniqueIdentifier() | |
263 | self.unique_identifier.read(tstream) | |
264 | ||
265 | if self.is_tag_next(Tags.KEY_FORMAT_TYPE, tstream): | |
266 | self.key_format_type = GetRequestPayload.KeyFormatType() | |
267 | self.key_format_type.read(tstream) | |
268 | ||
269 | if self.is_tag_next(Tags.KEY_COMPRESSION_TYPE, tstream): | |
270 | self.key_compression_type = GetRequestPayload.KeyCompressionType() | |
271 | self.key_compression_type.read(tstream) | |
272 | ||
273 | if self.is_tag_next(Tags.KEY_WRAPPING_SPECIFICATION, tstream): | |
274 | self.key_wrapping_specification = KeyWrappingSpecification() | |
275 | self.key_wrapping_specification.read(tstream) | |
276 | ||
277 | self.is_oversized(tstream) | |
278 | self.validate() | |
279 | ||
280 | def write(self, ostream): | |
281 | tstream = BytearrayStream() | |
282 | ||
283 | # Write the contents of the request payload | |
284 | if self.unique_identifier is not None: | |
285 | self.unique_identifier.write(tstream) | |
286 | if self.key_format_type is not None: | |
287 | self.key_format_type.write(tstream) | |
288 | if self.key_compression_type is not None: | |
289 | self.key_compression_type.write(tstream) | |
290 | if self.key_wrapping_specification is not None: | |
291 | self.key_wrapping_specification.write(tstream) | |
292 | ||
293 | # Write the length and value of the request payload | |
294 | self.length = tstream.length() | |
295 | super(self.__class__, self).write(ostream) | |
296 | ostream.write(tstream.buffer) | |
297 | ||
298 | def validate(self): | |
299 | self.__validate() | |
300 | ||
301 | def __validate(self): | |
302 | # TODO (peter-hamilton) Finish implementation | |
303 | pass | |
304 | ||
305 | ||
306 | class GetResponsePayload(Struct): | |
307 | ||
308 | def __init__(self, | |
309 | object_type=None, | |
310 | unique_identifier=None, | |
311 | secret=None): | |
312 | super(self.__class__, self).__init__(tag=Tags.RESPONSE_PAYLOAD) | |
313 | self.object_type = object_type | |
314 | self.unique_identifier = unique_identifier | |
315 | self.secret = secret | |
316 | self.secret_factory = SecretFactory() | |
317 | self.validate() | |
318 | ||
319 | def read(self, istream): | |
320 | super(self.__class__, self).read(istream) | |
321 | tstream = BytearrayStream(istream.read(self.length)) | |
322 | ||
323 | self.object_type = attributes.ObjectType() | |
324 | self.unique_identifier = attributes.UniqueIdentifier() | |
325 | ||
326 | self.object_type.read(tstream) | |
327 | self.unique_identifier.read(tstream) | |
328 | ||
329 | secret_type = self.object_type.enum | |
330 | self.secret = self.secret_factory.create_secret(secret_type) | |
331 | self.secret.read(tstream) | |
332 | ||
333 | self.is_oversized(tstream) | |
334 | self.validate() | |
335 | ||
336 | def write(self, ostream): | |
337 | tstream = BytearrayStream() | |
338 | ||
339 | self.object_type.write(tstream) | |
340 | self.unique_identifier.write(tstream) | |
341 | self.secret.write(tstream) | |
342 | ||
343 | # Write the length and value of the request payload | |
344 | self.length = tstream.length() | |
345 | super(self.__class__, self).write(ostream) | |
346 | ostream.write(tstream.buffer) | |
347 | ||
348 | def validate(self): | |
349 | self.__validate() | |
350 | ||
351 | def __validate(self): | |
352 | # TODO (peter-hamilton) Finish implementation. | |
353 | pass | |
354 | ||
355 | ||
356 | # 4.21 | |
357 | class DestroyRequestPayload(Struct): | |
358 | ||
359 | def __init__(self, | |
360 | unique_identifier=None): | |
361 | super(self.__class__, self).__init__(enums.Tags.REQUEST_PAYLOAD) | |
362 | self.unique_identifier = unique_identifier | |
363 | self.validate() | |
364 | ||
365 | def read(self, istream): | |
366 | super(self.__class__, self).read(istream) | |
367 | tstream = BytearrayStream(istream.read(self.length)) | |
368 | ||
369 | if self.is_tag_next(Tags.UNIQUE_IDENTIFIER, tstream): | |
370 | self.unique_identifier = attributes.UniqueIdentifier() | |
371 | self.unique_identifier.read(tstream) | |
372 | ||
373 | self.is_oversized(tstream) | |
374 | self.validate() | |
375 | ||
376 | def write(self, ostream): | |
377 | tstream = BytearrayStream() | |
378 | ||
379 | if self.unique_identifier is not None: | |
380 | self.unique_identifier.write(tstream) | |
381 | ||
382 | # Write the length and value of the request payload | |
383 | self.length = tstream.length() | |
384 | super(self.__class__, self).write(ostream) | |
385 | ostream.write(tstream.buffer) | |
386 | ||
387 | def validate(self): | |
388 | self.__validate() | |
389 | ||
390 | def __validate(self): | |
391 | # TODO (peter-hamilton) Finish implementation. | |
392 | pass | |
393 | ||
394 | ||
395 | class DestroyResponsePayload(Struct): | |
396 | ||
397 | def __init__(self, | |
398 | unique_identifier=None): | |
399 | super(self.__class__, self).__init__(enums.Tags.RESPONSE_PAYLOAD) | |
400 | self.unique_identifier = unique_identifier | |
401 | self.validate() | |
402 | ||
403 | def read(self, istream): | |
404 | super(self.__class__, self).read(istream) | |
405 | tstream = BytearrayStream(istream.read(self.length)) | |
406 | ||
407 | self.unique_identifier = attributes.UniqueIdentifier() | |
408 | self.unique_identifier.read(tstream) | |
409 | ||
410 | self.is_oversized(tstream) | |
411 | self.validate() | |
412 | ||
413 | def write(self, ostream): | |
414 | tstream = BytearrayStream() | |
415 | ||
416 | self.unique_identifier.write(tstream) | |
417 | ||
418 | # Write the length and value of the request payload | |
419 | self.length = tstream.length() | |
420 | super(self.__class__, self).write(ostream) | |
421 | ostream.write(tstream.buffer) | |
422 | ||
423 | def validate(self): | |
424 | self.__validate() | |
425 | ||
426 | def __validate(self): | |
427 | # TODO (peter-hamilton) Finish implementation. | |
428 | pass | |
429 | ||
430 | ||
431 | REQUEST_MAP = {enums.Operation.CREATE: CreateRequestPayload, | |
432 | enums.Operation.GET: GetRequestPayload, | |
433 | enums.Operation.DESTROY: DestroyRequestPayload, | |
434 | enums.Operation.REGISTER: RegisterRequestPayload} | |
435 | RESPONSE_MAP = {enums.Operation.CREATE: CreateResponsePayload, | |
436 | enums.Operation.GET: GetResponsePayload, | |
437 | enums.Operation.DESTROY: DestroyResponsePayload, | |
438 | enums.Operation.REGISTER: RegisterResponsePayload} |
0 | # Copyright (c) 2014 The Johns Hopkins University/Applied Physics Laboratory | |
1 | # All Rights Reserved. | |
2 | # | |
3 | # Licensed under the Apache License, Version 2.0 (the "License"); you may | |
4 | # not use this file except in compliance with the License. You may obtain | |
5 | # a copy of the License at | |
6 | # | |
7 | # http://www.apache.org/licenses/LICENSE-2.0 | |
8 | # | |
9 | # Unless required by applicable law or agreed to in writing, software | |
10 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT | |
11 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the | |
12 | # License for the specific language governing permissions and limitations | |
13 | # under the License. | |
14 | ||
15 | import attributes | |
16 | from kmip.core.attributes import CryptographicParameters | |
17 | ||
18 | from kmip.core.factories.attribute_values import AttributeValueFactory | |
19 | from kmip.core.factories.keys import KeyFactory | |
20 | ||
21 | from kmip.core import enums | |
22 | from kmip.core.enums import AttributeType | |
23 | from kmip.core.enums import Tags | |
24 | from kmip.core.enums import Types | |
25 | from kmip.core.enums import CredentialType | |
26 | ||
27 | from kmip.core.errors import ErrorStrings | |
28 | ||
29 | from kmip.core.primitives import Struct | |
30 | from kmip.core.primitives import TextString | |
31 | from kmip.core.primitives import ByteString | |
32 | from kmip.core.primitives import Integer | |
33 | from kmip.core.primitives import Enumeration | |
34 | ||
35 | from utils import BytearrayStream | |
36 | ||
37 | ||
38 | # 2.1 | |
39 | # 2.1.1 | |
40 | class Attribute(Struct): | |
41 | ||
42 | class AttributeName(TextString): | |
43 | ||
44 | def __init__(self, value=None): | |
45 | super(self.__class__, self).__init__(value, Tags.ATTRIBUTE_NAME) | |
46 | ||
47 | class AttributeIndex(Integer): | |
48 | ||
49 | def __init__(self, value=None): | |
50 | super(self.__class__, self).__init__(value, Tags.ATTRIBUTE_INDEX) | |
51 | ||
52 | def __init__(self, | |
53 | attribute_name=None, | |
54 | attribute_index=None, | |
55 | attribute_value=None): | |
56 | super(self.__class__, self).__init__(tag=Tags.ATTRIBUTE) | |
57 | ||
58 | self.value_factory = AttributeValueFactory() | |
59 | ||
60 | self.attribute_name = attribute_name | |
61 | self.attribute_index = attribute_index | |
62 | self.attribute_value = attribute_value | |
63 | ||
64 | if attribute_value is not None: | |
65 | attribute_value.tag = Tags.ATTRIBUTE_VALUE | |
66 | ||
67 | def read(self, istream): | |
68 | super(self.__class__, self).read(istream) | |
69 | tstream = BytearrayStream(istream.read(self.length)) | |
70 | ||
71 | # Read the name of the attribute | |
72 | self.attribute_name = Attribute.AttributeName() | |
73 | self.attribute_name.read(tstream) | |
74 | ||
75 | # Read the attribute index if it is next | |
76 | if self.is_tag_next(Tags.ATTRIBUTE_INDEX, tstream): | |
77 | self.attribute_index = Attribute.AttributeIndex() | |
78 | self.attribute_index.read(tstream) | |
79 | ||
80 | # Lookup the attribute class that belongs to the attribute name | |
81 | name = self.attribute_name.value | |
82 | enum_name = name.replace('.', '_').replace(' ', '_').upper() | |
83 | enum_type = None | |
84 | ||
85 | try: | |
86 | enum_type = AttributeType[enum_name] | |
87 | except KeyError: | |
88 | # Likely custom attribute, pass raw name string as attribute type | |
89 | enum_type = name | |
90 | ||
91 | value = self.value_factory.create_attribute_value(enum_type, None) | |
92 | self.attribute_value = value | |
93 | self.attribute_value.tag = Tags.ATTRIBUTE_VALUE | |
94 | self.attribute_value.read(tstream) | |
95 | ||
96 | self.is_oversized(tstream) | |
97 | ||
98 | def write(self, ostream): | |
99 | tstream = BytearrayStream() | |
100 | ||
101 | self.attribute_name.write(tstream) | |
102 | if self.attribute_index is not None: | |
103 | self.attribute_index.write(tstream) | |
104 | self.attribute_value.write(tstream) | |
105 | ||
106 | # Write the length and value of the attribute | |
107 | self.length = tstream.length() | |
108 | super(self.__class__, self).write(ostream) | |
109 | ostream.write(tstream.buffer) | |
110 | ||
111 | ||
112 | # 2.1.2 | |
113 | class Credential(Struct): | |
114 | ||
115 | class CredentialType(Enumeration): | |
116 | ||
117 | ENUM_TYPE = CredentialType | |
118 | ||
119 | def __init__(self, value=None): | |
120 | super(self.__class__, self).__init__(value, Tags.CREDENTIAL_TYPE) | |
121 | ||
122 | class UsernamePasswordCredential(Struct): | |
123 | ||
124 | class Username(TextString): | |
125 | def __init__(self, value=None): | |
126 | super(self.__class__, self).__init__(value, Tags.USERNAME) | |
127 | ||
128 | class Password(TextString): | |
129 | def __init__(self, value=None): | |
130 | super(self.__class__, self).__init__(value, Tags.PASSWORD) | |
131 | ||
132 | def __init__(self, username=None, password=None): | |
133 | super(self.__class__, self).__init__(tag=Tags.CREDENTIAL_VALUE) | |
134 | self.username = username | |
135 | self.password = password | |
136 | self.validate() | |
137 | ||
138 | def read(self, istream): | |
139 | super(self.__class__, self).read(istream) | |
140 | tstream = BytearrayStream(istream.read(self.length)) | |
141 | ||
142 | # Read the username of the credential | |
143 | self.username = self.Username() | |
144 | self.username.read(tstream) | |
145 | ||
146 | # Read the password if it is next | |
147 | if self.is_tag_next(Tags.PASSWORD, tstream): | |
148 | self.password = self.Password() | |
149 | self.password.read(tstream) | |
150 | ||
151 | self.is_oversized(tstream) | |
152 | self.validate() | |
153 | ||
154 | def write(self, ostream): | |
155 | tstream = BytearrayStream() | |
156 | ||
157 | self.username.write(tstream) | |
158 | if self.password is not None: | |
159 | self.password.write(tstream) | |
160 | ||
161 | # Write the length and value of the credential | |
162 | self.length = tstream.length() | |
163 | super(self.__class__, self).write(ostream) | |
164 | ostream.write(tstream.buffer) | |
165 | ||
166 | def validate(self): | |
167 | pass | |
168 | ||
169 | class DeviceCredential(Struct): | |
170 | ||
171 | class DeviceSerialNumber(TextString): | |
172 | ||
173 | def __init__(self, value=None): | |
174 | super(Credential.DeviceCredential.DeviceSerialNumber, self).\ | |
175 | __init__(value, Tags.DEVICE_SERIAL_NUMBER) | |
176 | ||
177 | class Password(TextString): | |
178 | ||
179 | def __init__(self, value=None): | |
180 | super(Credential.DeviceCredential.Password, self).\ | |
181 | __init__(value, Tags.PASSWORD) | |
182 | ||
183 | class DeviceIdentifier(TextString): | |
184 | ||
185 | def __init__(self, value=None): | |
186 | super(Credential.DeviceCredential.DeviceIdentifier, self).\ | |
187 | __init__(value, Tags.DEVICE_IDENTIFIER) | |
188 | ||
189 | class NetworkIdentifier(TextString): | |
190 | ||
191 | def __init__(self, value=None): | |
192 | super(Credential.DeviceCredential.NetworkIdetifier, self).\ | |
193 | __init__(value, Tags.NETWORK_IDENTIFIER) | |
194 | ||
195 | class MachineIdentifier(TextString): | |
196 | ||
197 | def __init__(self, value=None): | |
198 | super(Credential.DeviceCredential.MachineIdentifier, self).\ | |
199 | __init__(value, Tags.MACHINE_IDENTIFIER) | |
200 | ||
201 | class MediaIdentifier(TextString): | |
202 | ||
203 | def __init__(self, value=None): | |
204 | super(Credential.DeviceCredential.MediaIdentifier, self).\ | |
205 | __init__(value, Tags.MEDIA_IDENTIFIER) | |
206 | ||
207 | def __init__(self, | |
208 | device_serial_number=None, | |
209 | password=None, | |
210 | device_identifier=None, | |
211 | network_identifier=None, | |
212 | machine_identifier=None, | |
213 | media_identifier=None): | |
214 | super(self.__class__, self).__init__(tag=Tags.CREDENTIAL_VALUE) | |
215 | super.device_serial_number = device_serial_number | |
216 | super.password = password | |
217 | super.device_identifier = device_identifier | |
218 | super.network_identifier = network_identifier | |
219 | super.machine_identifier = machine_identifier | |
220 | super.media_identifier = media_identifier | |
221 | ||
222 | def read(self, istream): | |
223 | super(self.__class__, self).read(istream) | |
224 | tstream = BytearrayStream(istream.read(self.length)) | |
225 | ||
226 | # Read the password if it is next | |
227 | if self.is_tag_next(Tags.DEVICE_SERIAL_NUMBER, tstream): | |
228 | self.device_serial_number = self.DeviceSerialNumber() | |
229 | self.device_serial_number.read(tstream) | |
230 | ||
231 | # Read the password if it is next | |
232 | if self.is_tag_next(Tags.PASSWORD, tstream): | |
233 | self.password = self.Password() | |
234 | self.password.read(tstream) | |
235 | ||
236 | # Read the password if it is next | |
237 | if self.is_tag_next(Tags.DEVICE_IDENTIFIER, tstream): | |
238 | self.device_identifier = self.DeviceIdentifier() | |
239 | self.device_identifier.read(tstream) | |
240 | ||
241 | # Read the password if it is next | |
242 | if self.is_tag_next(Tags.NETWORK_IDENTIFIER, tstream): | |
243 | self.network_identifier = self.NetworkIdentifier() | |
244 | self.network_identifier.read(tstream) | |
245 | ||
246 | # Read the password if it is next | |
247 | if self.is_tag_next(Tags.MACHINE_IDENTIFIER, tstream): | |
248 | self.machine_identifier = self.MachineIdentifier() | |
249 | self.machine_identifier.read(tstream) | |
250 | ||
251 | # Read the password if it is next | |
252 | if self.is_tag_next(Tags.MEDIA_IDENTIFIER, tstream): | |
253 | self.media_identifier = self.MediaIdentifier() | |
254 | self.media_identifier.read(tstream) | |
255 | ||
256 | self.is_oversized(tstream) | |
257 | self.validate() | |
258 | ||
259 | def write(self, ostream): | |
260 | tstream = BytearrayStream() | |
261 | ||
262 | if self.device_serial_number is not None: | |
263 | self.device_serial_number.write(tstream) | |
264 | if self.password is not None: | |
265 | self.password.write(tstream) | |
266 | if self.device_identifier is not None: | |
267 | self.device_identifier.write(tstream) | |
268 | if self.network_identifier is not None: | |
269 | self.network_identifier.write(tstream) | |
270 | if self.machine_identifier is not None: | |
271 | self.machine_identifier.write(tstream) | |
272 | if self.media_identifier is not None: | |
273 | self.media_identifier.write(tstream) | |
274 | ||
275 | # Write the length and value of the credential | |
276 | self.length = tstream.length() | |
277 | super(self.__class__, self).write(ostream) | |
278 | ostream.write(tstream.buffer) | |
279 | ||
280 | def validate(self): | |
281 | pass | |
282 | ||
283 | def __init__(self, credential_type=None, credential_value=None): | |
284 | super(self.__class__, self).__init__(tag=Tags.CREDENTIAL) | |
285 | self.credential_type = credential_type | |
286 | self.credential_value = credential_value | |
287 | ||
288 | def read(self, istream): | |
289 | super(self.__class__, self).read(istream) | |
290 | tstream = BytearrayStream(istream.read(self.length)) | |
291 | ||
292 | # Read the type of the credential | |
293 | self.credential_type = self.CredentialType() | |
294 | self.credential_type.read(tstream) | |
295 | ||
296 | # Use the type to determine what credential value to read | |
297 | if self.credential_type.enum is CredentialType.USERNAME_AND_PASSWORD: | |
298 | self.credential_value = self.UsernamePasswordCredential() | |
299 | elif self.credential_type.enum is CredentialType.DEVICE: | |
300 | self.credential_value = self.DeviceCredential() | |
301 | else: | |
302 | # TODO (peter-hamilton) Use more descriptive error here | |
303 | raise NotImplementedError() | |
304 | self.credential_value.read(tstream) | |
305 | ||
306 | self.is_oversized(tstream) | |
307 | self.validate() | |
308 | ||
309 | def write(self, ostream): | |
310 | tstream = BytearrayStream() | |
311 | ||
312 | self.credential_type.write(tstream) | |
313 | self.credential_value.write(tstream) | |
314 | ||
315 | # Write the length and value of the credential | |
316 | self.length = tstream.length() | |
317 | super(self.__class__, self).write(ostream) | |
318 | ostream.write(tstream.buffer) | |
319 | ||
320 | def validate(self): | |
321 | pass | |
322 | ||
323 | ||
324 | # 2.1.3 | |
325 | class KeyBlock(Struct): | |
326 | ||
327 | class KeyFormatType(Enumeration): | |
328 | ENUM_TYPE = enums.KeyFormatType | |
329 | ||
330 | def __init__(self, value=None): | |
331 | super(self.__class__, self).__init__(value, Tags.KEY_FORMAT_TYPE) | |
332 | ||
333 | class KeyCompressionType(Enumeration): | |
334 | ENUM_TYPE = enums.KeyCompressionType | |
335 | ||
336 | def __init__(self, value=None): | |
337 | super(self.__class__, self).__init__(value, | |
338 | Tags.KEY_COMPRESSION_TYPE) | |
339 | ||
340 | def __init__(self, | |
341 | key_format_type=None, | |
342 | key_compression_type=None, | |
343 | key_value=None, | |
344 | cryptographic_algorithm=None, | |
345 | cryptographic_length=None, | |
346 | key_wrapping_data=None): | |
347 | super(self.__class__, self).__init__(Tags.KEY_BLOCK) | |
348 | self.key_format_type = key_format_type | |
349 | self.key_compression_type = key_compression_type | |
350 | self.key_value = key_value | |
351 | self.cryptographic_algorithm = cryptographic_algorithm | |
352 | self.cryptographic_length = cryptographic_length | |
353 | self.key_wrapping_data = key_wrapping_data | |
354 | self.validate() | |
355 | ||
356 | def read(self, istream): | |
357 | super(self.__class__, self).read(istream) | |
358 | tstream = BytearrayStream(istream.read(self.length)) | |
359 | ||
360 | self.key_format_type = KeyBlock.KeyFormatType() | |
361 | self.key_format_type.read(tstream) | |
362 | key_format_type = self.key_format_type.enum | |
363 | ||
364 | if self.is_tag_next(Tags.KEY_COMPRESSION_TYPE, tstream): | |
365 | self.key_compression_type = KeyBlock.KeyCompressionType() | |
366 | self.key_compression_type.read(tstream) | |
367 | ||
368 | self.key_value = KeyValue(key_format_type=key_format_type) | |
369 | self.key_value.read(tstream) | |
370 | ||
371 | if self.is_tag_next(Tags.CRYPTOGRAPHIC_ALGORITHM, tstream): | |
372 | self.cryptographic_algorithm = attributes.CryptographicAlgorithm() | |
373 | self.cryptographic_algorithm.read(tstream) | |
374 | ||
375 | if self.is_tag_next(Tags.CRYPTOGRAPHIC_LENGTH, tstream): | |
376 | self.cryptographic_length = attributes.CryptographicLength() | |
377 | self.cryptographic_length.read(tstream) | |
378 | ||
379 | if self.is_tag_next(Tags.KEY_WRAPPING_DATA, tstream): | |
380 | self.key_wrapping_data = KeyWrappingData() | |
381 | self.key_wrapping_data.read(tstream) | |
382 | ||
383 | self.is_oversized(tstream) | |
384 | self.validate() | |
385 | ||
386 | def write(self, ostream): | |
387 | tstream = BytearrayStream() | |
388 | ||
389 | self.key_format_type.write(tstream) | |
390 | ||
391 | if self.key_compression_type is not None: | |
392 | self.key_compression_type.write(tstream) | |
393 | ||
394 | self.key_value.write(tstream) | |
395 | ||
396 | if self.cryptographic_algorithm is not None: | |
397 | self.cryptographic_algorithm.write(tstream) | |
398 | if self.cryptographic_length is not None: | |
399 | self.cryptographic_length.write(tstream) | |
400 | if self.key_wrapping_data is not None: | |
401 | self.key_wrapping_data.write(tstream) | |
402 | ||
403 | # Write the length and value of the credential | |
404 | self.length = tstream.length() | |
405 | super(self.__class__, self).write(ostream) | |
406 | ostream.write(tstream.buffer) | |
407 | ||
408 | def validate(self): | |
409 | self.__validate() | |
410 | ||
411 | def __validate(self): | |
412 | if self.key_format_type is not None: | |
413 | if type(self.key_format_type) is not KeyBlock.KeyFormatType: | |
414 | member = 'KeyBlock.key_format_type' | |
415 | exp_type = KeyBlock.KeyFormatType | |
416 | rcv_type = type(self.key_format_type) | |
417 | msg = ErrorStrings.BAD_EXP_RECV.format(member, 'type', | |
418 | exp_type, rcv_type) | |
419 | raise TypeError(msg) | |
420 | ||
421 | ||
422 | # 2.1.4 | |
423 | class KeyValueString(ByteString): | |
424 | ||
425 | def __init__(self, value=None): | |
426 | super(self.__class__, self).__init__(value, Tags.KEY_VALUE) | |
427 | ||
428 | ||
429 | class KeyValueStruct(Struct): | |
430 | ||
431 | def __init__(self, | |
432 | key_format_type=None, | |
433 | key_material=None, | |
434 | attributes=None): | |
435 | super(self.__class__, self).__init__(Tags.KEY_VALUE) | |
436 | self.key_format_type = key_format_type | |
437 | self.key_material = key_material | |
438 | self.attributes = attributes | |
439 | self.key_factory = KeyFactory() | |
440 | self.validate() | |
441 | ||
442 | def read(self, istream): | |
443 | super(self.__class__, self).read(istream) | |
444 | tstream = BytearrayStream(istream.read(self.length)) | |
445 | ||
446 | self.key_material = self.key_factory.create_key(self.key_format_type) | |
447 | self.key_material.read(tstream) | |
448 | ||
449 | self.attributes = list() | |
450 | ||
451 | # Read the attributes, 0 or more | |
452 | while self.is_tag_next(Tags.ATTRIBUTE, tstream): | |
453 | attribute = Attribute() | |
454 | attribute.read(tstream) | |
455 | self.attributes.append(attribute) | |
456 | ||
457 | self.is_oversized(tstream) | |
458 | self.validate() | |
459 | ||
460 | def write(self, ostream): | |
461 | tstream = BytearrayStream() | |
462 | ||
463 | self.key_material.write(tstream) | |
464 | ||
465 | if self.attributes is not None: | |
466 | for attribute in self.attributes: | |
467 | attribute.write(tstream) | |
468 | ||
469 | # Write the length and value of the credential | |
470 | self.length = tstream.length() | |
471 | super(self.__class__, self).write(ostream) | |
472 | ostream.write(tstream.buffer) | |
473 | ||
474 | def validate(self): | |
475 | self.__validate() | |
476 | ||
477 | def __validate(self): | |
478 | # TODO (peter-hamilton) Finish implementation. | |
479 | pass | |
480 | ||
481 | ||
482 | class KeyValue(Struct): | |
483 | ''' | |
484 | KeyValue can be either a ByteString or a Struct. Therefore, this class | |
485 | acts as a wrapper for two different KeyValue objects, KeyValueString, | |
486 | which represents the ByteString format, and KeyValueStruct, which | |
487 | represents the Struct format, both of which are defined above. This | |
488 | KeyValue object does not read or write itself; instead, it reads and | |
489 | writes its internal key_value attribute, which is either a KeyValueString | |
490 | or a KeyValueStruct. | |
491 | ||
492 | When reading, the class determines what the format of its internal | |
493 | structure should be by looking at the type of the object it will read | |
494 | using KeyValue.is_type_next(). This is one of the only places in the | |
495 | code where this approach is used. | |
496 | ''' | |
497 | ||
498 | def __init__(self, | |
499 | key_value=None, | |
500 | key_format_type=None): | |
501 | super(self.__class__, self).__init__(Tags.KEY_VALUE) | |
502 | self.key_value = key_value | |
503 | self.key_format_type = key_format_type | |
504 | if self.key_value is not None: | |
505 | self.type = key_value.type | |
506 | self.validate() | |
507 | ||
508 | def read(self, istream): | |
509 | if self.is_type_next(Types.BYTE_STRING, istream): | |
510 | self.key_value = KeyValueString() | |
511 | self.key_value.read(istream) | |
512 | elif self.is_type_next(Types.STRUCTURE, istream): | |
513 | kft = self.key_format_type | |
514 | self.key_value = KeyValueStruct(key_format_type=kft) | |
515 | self.key_value.read(istream) | |
516 | ||
517 | def write(self, ostream): | |
518 | tstream = BytearrayStream() | |
519 | self.key_value.write(tstream) | |
520 | ostream.write(tstream.buffer) | |
521 | ||
522 | def validate(self): | |
523 | self.__validate() | |
524 | ||
525 | def __validate(self): | |
526 | # TODO (peter-hamilton) Finish implementation. | |
527 | pass | |
528 | ||
529 | ||
530 | # 2.1.5 | |
531 | class WrappingMethod(Enumeration): | |
532 | ENUM_TYPE = enums.WrappingMethod | |
533 | ||
534 | def __init__(self, value=None): | |
535 | super(WrappingMethod, self).__init__(value, Tags.WRAPPING_METHOD) | |
536 | ||
537 | ||
538 | class EncodingOption(Enumeration): | |
539 | ENUM_TYPE = enums.EncodingOption | |
540 | ||
541 | def __init__(self, value=None): | |
542 | super(WrappingMethod, self).__init__(value, Tags.ENCODING_OPTION) | |
543 | ||
544 | ||
545 | class KeyInformation(Struct): | |
546 | ||
547 | def __init__(self, | |
548 | unique_identifier=None, | |
549 | cryptographic_parameters=None, | |
550 | tag=Tags.ENCRYPTION_KEY_INFORMATION): | |
551 | super(self.__class__, self).\ | |
552 | __init__(tag=Tags.ENCRYPTION_KEY_INFORMATION) | |
553 | self.unique_identifier = unique_identifier | |
554 | self.cryptographic_parameters = cryptographic_parameters | |
555 | self.validate() | |
556 | ||
557 | def read(self, istream): | |
558 | super(self.__class__, self).read(istream) | |
559 | tstream = BytearrayStream(istream.read(self.length)) | |
560 | ||
561 | self.unique_identifier = attributes.UniqueIdentifier() | |
562 | self.unique_identifier.read(tstream) | |
563 | ||
564 | if self.is_tag_next(Tags.CRYPTOGRAPHIC_PARAMETERS, tstream): | |
565 | self.cryptographic_parameters = CryptographicParameters() | |
566 | self.cryptographic_parameters.read(tstream) | |
567 | ||
568 | self.is_oversized(tstream) | |
569 | self.validate() | |
570 | ||
571 | def write(self, ostream): | |
572 | tstream = BytearrayStream() | |
573 | ||
574 | self.unique_identifier.write(tstream) | |
575 | ||
576 | if self.cryptographic_parameters is not None: | |
577 | self.cryptographic_parameters.write(tstream) | |
578 | ||
579 | # Write the length and value of the template attribute | |
580 | self.length = tstream.length() | |
581 | super(self.__class__, self).write(ostream) | |
582 | ostream.write(tstream.buffer) | |
583 | ||
584 | def validate(self): | |
585 | self.__validate() | |
586 | ||
587 | def __validate(self): | |
588 | # TODO (peter-hamilton) Finish implementation. | |
589 | pass | |
590 | ||
591 | ||
592 | class EncryptionKeyInformation(KeyInformation): | |
593 | ||
594 | def __init__(self, | |
595 | unique_identifier=None, | |
596 | cryptographic_parameters=None, | |
597 | tag=Tags.ENCRYPTION_KEY_INFORMATION): | |
598 | super(self.__class__, self).\ | |
599 | __init__(unique_identifier, cryptographic_parameters, tag) | |
600 | ||
601 | def validate(self): | |
602 | self.__validate() | |
603 | ||
604 | def __validate(self): | |
605 | # TODO (peter-hamilton) Finish implementation. | |
606 | pass | |
607 | ||
608 | ||
609 | class MACSignatureKeyInformation(KeyInformation): | |
610 | ||
611 | def __init__(self, | |
612 | unique_identifier=None, | |
613 | cryptographic_parameters=None, | |
614 | tag=Tags.MAC_SIGNATURE_KEY_INFORMATION): | |
615 | super(self.__class__, self).\ | |
616 | __init__(unique_identifier, cryptographic_parameters, tag) | |
617 | ||
618 | def validate(self): | |
619 | self.__validate() | |
620 | ||
621 | def __validate(self): | |
622 | # TODO (peter-hamilton) Finish implementation. | |
623 | pass | |
624 | ||
625 | ||
626 | class KeyWrappingData(Struct): | |
627 | ||
628 | class MACSignature(ByteString): | |
629 | ||
630 | def __init__(self, value=None): | |
631 | super(self.__class__, self).__init__(value, Tags.MAC_SIGNATURE) | |
632 | ||
633 | class IVCounterNonce(ByteString): | |
634 | ||
635 | def __init__(self, value=None): | |
636 | super(self.__class__, self).__init__(value, Tags.IV_COUNTER_NONCE) | |
637 | ||
638 | def __init__(self, | |
639 | wrapping_method=None, | |
640 | encryption_key_information=None, | |
641 | mac_signature_key_information=None, | |
642 | mac_signature=None, | |
643 | iv_counter_nonce=None, | |
644 | encoding_option=None): | |
645 | super(self.__class__, self).__init__(Tags.KEY_WRAPPING_DATA) | |
646 | self.wrapping_method = wrapping_method | |
647 | self.encryption_key_information = encryption_key_information | |
648 | self.mac_signature_key_information = mac_signature_key_information | |
649 | self.mac_signature = mac_signature | |
650 | self.iv_counter_nonce = iv_counter_nonce | |
651 | self.encoding_option = encoding_option | |
652 | self.validate() | |
653 | ||
654 | def read(self, istream): | |
655 | super(self.__class__, self).read(istream) | |
656 | tstream = BytearrayStream(istream.read(self.length)) | |
657 | ||
658 | self.wrapping_method = WrappingMethod() | |
659 | self.wrapping_method.read(tstream) | |
660 | ||
661 | if self.is_tag_next(Tags.ENCRYPTION_KEY_INFORMATION, tstream): | |
662 | self.encryption_key_information = EncryptionKeyInformation() | |
663 | self.encryption_key_information.read(tstream) | |
664 | ||
665 | if self.is_tag_next(Tags.MAC_SIGNATURE_KEY_INFORMATION, tstream): | |
666 | self.mac_signature_key_information = MACSignatureKeyInformation() | |
667 | self.mac_signature_key_information.read(tstream) | |
668 | ||
669 | if self.is_tag_next(Tags.MAC_SIGNATURE, tstream): | |
670 | self.mac_signature = KeyWrappingData.MACSignature() | |
671 | self.mac_signature.read(tstream) | |
672 | ||
673 | if self.is_tag_next(Tags.IV_COUNTER_NONCE, tstream): | |
674 | self.iv_counter_nonce = KeyWrappingData.IVCounterNonce() | |
675 | self.iv_counter_nonce.read(tstream) | |
676 | ||
677 | if self.is_tag_next(Tags.ENCODING_OPTION, tstream): | |
678 | self.encoding_option = EncodingOption() | |
679 | self.encoding_option.read(tstream) | |
680 | ||
681 | self.is_oversized(tstream) | |
682 | self.validate() | |
683 | ||
684 | def write(self, ostream): | |
685 | tstream = BytearrayStream() | |
686 | ||
687 | # Write the contents of the key wrapping data | |
688 | self.wrapping_method.write(tstream) | |
689 | ||
690 | if self.encryption_key_information is not None: | |
691 | self.encryption_key_information.write(tstream) | |
692 | if self.mac_signature_key_information is not None: | |
693 | self.mac_signature_key_information.write(tstream) | |
694 | if self.mac_signature is not None: | |
695 | self.mac_signature.write(tstream) | |
696 | if self.iv_counter_nonce is not None: | |
697 | self.iv_counter_nonce.write(tstream) | |
698 | if self.encoding_option is not None: | |
699 | self.encoding_option.write(tstream) | |
700 | ||
701 | # Write the length and value of the key wrapping data | |
702 | self.length = tstream.length() | |
703 | super(self.__class__, self).write(ostream) | |
704 | ostream.write(tstream.buffer) | |
705 | ||
706 | def validate(self): | |
707 | self.__validate() | |
708 | ||
709 | def __validate(self): | |
710 | # TODO (peter-hamilton) Finish implementation | |
711 | pass | |
712 | ||
713 | ||
714 | # 2.1.6 | |
715 | class KeyWrappingSpecification(Struct): | |
716 | ||
717 | class AttributeName(TextString): | |
718 | ||
719 | def __init__(self, value=None): | |
720 | super(self.__class__, self).__init__(value, Tags.ATTRIBUTE_NAME) | |
721 | ||
722 | def __init__(self, | |
723 | wrapping_method=None, | |
724 | encryption_key_information=None, | |
725 | mac_signature_key_information=None, | |
726 | attribute_name=None, | |
727 | encoding_option=None): | |
728 | super(self.__class__, self).\ | |
729 | __init__(tag=Tags.KEY_WRAPPING_SPECIFICATION) | |
730 | self.wrapping_method = wrapping_method | |
731 | self.encryption_key_information = encryption_key_information | |
732 | self.mac_signature_key_information = mac_signature_key_information | |
733 | self.attribute_name = attribute_name | |
734 | self.encoding_option = encoding_option | |
735 | ||
736 | def read(self, istream): | |
737 | super(self.__class__, self).read(istream) | |
738 | tstream = BytearrayStream(istream.read(self.length)) | |
739 | ||
740 | self.wrapping_method = WrappingMethod() | |
741 | self.wrapping_method.read(tstream) | |
742 | ||
743 | if self.is_tag_next(Tags.ENCRYPTION_KEY_INFORMATION, tstream): | |
744 | self.encryption_key_information = EncryptionKeyInformation() | |
745 | self.encryption_key_information.read(tstream) | |
746 | ||
747 | if self.is_tag_next(Tags.MAC_SIGNATURE_KEY_INFORMATION, tstream): | |
748 | self.mac_signature_key_information = MACSignatureKeyInformation() | |
749 | self.mac_signature_key_information.read(tstream) | |
750 | ||
751 | if self.is_tag_next(Tags.ATTRIBUTE_NAME, tstream): | |
752 | self.attribute_name = KeyWrappingSpecification.AttributeName() | |
753 | self.attribute_name.read(tstream) | |
754 | ||
755 | if self.is_tag_next(Tags.ENCODING_OPTION, tstream): | |
756 | self.encoding_option = EncodingOption() | |
757 | self.encoding_option.read(tstream) | |
758 | ||
759 | self.is_oversized(tstream) | |
760 | self.validate() | |
761 | ||
762 | def write(self, ostream): | |
763 | tstream = BytearrayStream() | |
764 | ||
765 | # Write the contents of the key wrapping data | |
766 | self.wrapping_method.write(tstream) | |
767 | ||
768 | if self.encryption_key_information is not None: | |
769 | self.encryption_key_information.write(tstream) | |
770 | if self.mac_signature_key_information is not None: | |
771 | self.mac_signature_key_information.write(tstream) | |
772 | if self.attribute_name is not None: | |
773 | self.attribute_name.write(tstream) | |
774 | if self.encoding_option is not None: | |
775 | self.encoding_option.write(tstream) | |
776 | ||
777 | # Write the length and value of the key wrapping data | |
778 | self.length = tstream.length() | |
779 | super(self.__class__, self).write(ostream) | |
780 | ostream.write(tstream.buffer) | |
781 | ||
782 | def validate(self): | |
783 | self.__validate() | |
784 | ||
785 | def __validate(self): | |
786 | # TODO (peter-hamilton) Finish implementation. | |
787 | pass | |
788 | ||
789 | ||
790 | # 2.1.8 | |
791 | class TemplateAttribute(Struct): | |
792 | ||
793 | def __init__(self, | |
794 | names=None, | |
795 | attributes=None): | |
796 | super(self.__class__, self).__init__(tag=Tags.TEMPLATE_ATTRIBUTE) | |
797 | self.names = names | |
798 | self.attributes = attributes | |
799 | self.validate() | |
800 | ||
801 | def read(self, istream): | |
802 | super(self.__class__, self).read(istream) | |
803 | tstream = BytearrayStream(istream.read(self.length)) | |
804 | ||
805 | self.names = list() | |
806 | self.attributes = list() | |
807 | ||
808 | # Read the names of the template attribute, 0 or more | |
809 | while self.is_tag_next(Tags.NAME, tstream): | |
810 | name = attributes.Name() | |
811 | name.read(tstream) | |
812 | self.names.append(name) | |
813 | ||
814 | # Read the attributes of the template attribute, 0 or more | |
815 | while self.is_tag_next(Tags.ATTRIBUTE, tstream): | |
816 | attribute = Attribute() | |
817 | attribute.read(tstream) | |
818 | self.attributes.append(attribute) | |
819 | ||
820 | self.is_oversized(tstream) | |
821 | self.validate() | |
822 | ||
823 | def write(self, ostream): | |
824 | tstream = BytearrayStream() | |
825 | ||
826 | # Write the names and attributes of the template attribute | |
827 | if self.names is not None: | |
828 | for name in self.names: | |
829 | name.write(tstream) | |
830 | if self.attributes is not None: | |
831 | for attribute in self.attributes: | |
832 | attribute.write(tstream) | |
833 | ||
834 | # Write the length and value of the template attribute | |
835 | self.length = tstream.length() | |
836 | super(self.__class__, self).write(ostream) | |
837 | ostream.write(tstream.buffer) | |
838 | ||
839 | def validate(self): | |
840 | self.__validate() | |
841 | ||
842 | def __validate(self): | |
843 | # TODO (peter-hamilton) Finish implementation. | |
844 | pass |
0 | # Copyright (c) 2014 The Johns Hopkins University/Applied Physics Laboratory | |
1 | # All Rights Reserved. | |
2 | # | |
3 | # Licensed under the Apache License, Version 2.0 (the "License"); you may | |
4 | # not use this file except in compliance with the License. You may obtain | |
5 | # a copy of the License at | |
6 | # | |
7 | # http://www.apache.org/licenses/LICENSE-2.0 | |
8 | # | |
9 | # Unless required by applicable law or agreed to in writing, software | |
10 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT | |
11 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the | |
12 | # License for the specific language governing permissions and limitations | |
13 | # under the License. | |
14 | ||
15 | from struct import pack, unpack | |
16 | from enum import Enum | |
17 | ||
18 | from kmip.core.enums import Types | |
19 | from kmip.core.enums import Tags | |
20 | ||
21 | from kmip.core.errors import ErrorStrings | |
22 | ||
23 | import errors | |
24 | import utils | |
25 | ||
26 | ||
27 | class Base(object): | |
28 | TAG_SIZE = 3 | |
29 | TYPE_SIZE = 1 | |
30 | LENGTH_SIZE = 4 | |
31 | ||
32 | def __init__(self, tag=Tags.DEFAULT, type=Types.DEFAULT): | |
33 | self.tag = tag | |
34 | self.type = type | |
35 | self.length = None | |
36 | ||
37 | # TODO (peter-hamilton) Convert this into a classmethod, class name can be | |
38 | # obtained from cls parameter that replaces self | |
39 | def is_oversized(self, stream): | |
40 | extra = len(stream.peek()) | |
41 | if extra > 0: | |
42 | raise errors.StreamNotEmptyError(Base.__name__, extra) | |
43 | ||
44 | def read_tag(self, istream): | |
45 | # Read in the bytes for the tag | |
46 | tts = istream.read(self.TAG_SIZE) | |
47 | tag = unpack('!I', '\x00' + tts[0:self.TAG_SIZE])[0] | |
48 | ||
49 | enum_tag = Tags(tag) | |
50 | ||
51 | # Verify that the tag matches for the current object | |
52 | if enum_tag is not self.tag: | |
53 | raise errors.ReadValueError(Base.__name__, 'tag', | |
54 | hex(self.tag.value), hex(tag)) | |
55 | ||
56 | def read_type(self, istream): | |
57 | # Read in the bytes for the type | |
58 | tts = istream.read(self.TYPE_SIZE) | |
59 | num_bytes = len(tts) | |
60 | if num_bytes != self.TYPE_SIZE: | |
61 | min_bytes = 'a minimum of {0} bytes'.format(self.TYPE_SIZE) | |
62 | raise errors.ReadValueError(Base.__name__, 'type', min_bytes, | |
63 | '{0} bytes'.format(num_bytes)) | |
64 | typ = unpack('!B', tts)[0] | |
65 | ||
66 | enum_typ = Types(typ) | |
67 | ||
68 | if enum_typ is not self.type: | |
69 | raise errors.ReadValueError(Base.__name__, 'type', | |
70 | self.type.value, typ) | |
71 | ||
72 | def read_length(self, istream): | |
73 | # Read in the bytes for the length | |
74 | lst = istream.read(self.LENGTH_SIZE) | |
75 | num_bytes = len(lst) | |
76 | if num_bytes != self.LENGTH_SIZE: | |
77 | min_bytes = 'a minimum of {0} bytes'.format(self.LENGTH_SIZE) | |
78 | raise errors.ReadValueError(Base.__name__, 'length', min_bytes, | |
79 | '{0} bytes'.format(num_bytes)) | |
80 | length = unpack('!I', lst)[0] | |
81 | ||
82 | # Verify that the length matches the expected length, if one exists | |
83 | if self.length is not None: | |
84 | if length is not self.length: | |
85 | raise errors.ReadValueError(Base.__name__, 'length', | |
86 | self.length, length) | |
87 | else: | |
88 | self.length = length | |
89 | ||
90 | def read_value(self, istream): | |
91 | raise NotImplementedError() | |
92 | ||
93 | def read(self, istream): | |
94 | self.read_tag(istream) | |
95 | self.read_type(istream) | |
96 | self.read_length(istream) | |
97 | ||
98 | def write_tag(self, ostream): | |
99 | # Write the tag to the output stream | |
100 | ostream.write(pack('!I', self.tag.value)[1:]) | |
101 | ||
102 | def write_type(self, ostream): | |
103 | if type(self.type) is not Types: | |
104 | msg = ErrorStrings.BAD_EXP_RECV | |
105 | raise TypeError(msg.format(Base.__name__, 'type', | |
106 | Types, type(self.type))) | |
107 | ostream.write(pack('!B', self.type.value)) | |
108 | ||
109 | def write_length(self, ostream): | |
110 | if type(self.length) is not int: | |
111 | msg = ErrorStrings.BAD_EXP_RECV | |
112 | raise TypeError(msg.format(Base.__name__, 'length', | |
113 | int, type(self.length))) | |
114 | num_bytes = utils.count_bytes(self.length) | |
115 | if num_bytes > self.LENGTH_SIZE: | |
116 | raise errors.WriteOverflowError(Base.__name__, 'length', | |
117 | self.LENGTH_SIZE, num_bytes) | |
118 | ostream.write(pack('!I', self.length)) | |
119 | ||
120 | def write_value(self, ostream): | |
121 | raise NotImplementedError() | |
122 | ||
123 | def write(self, ostream): | |
124 | self.write_tag(ostream) | |
125 | self.write_type(ostream) | |
126 | self.write_length(ostream) | |
127 | ||
128 | def validate(self): | |
129 | raise NotImplementedError() | |
130 | ||
131 | @staticmethod | |
132 | def is_tag_next(tag, stream): | |
133 | next_tag = stream.peek(Base.TAG_SIZE) | |
134 | if len(next_tag) != Base.TAG_SIZE: | |
135 | return False | |
136 | next_tag = unpack('!I', '\x00' + next_tag)[0] | |
137 | if next_tag == tag.value: | |
138 | return True | |
139 | else: | |
140 | return False | |
141 | ||
142 | @staticmethod | |
143 | def is_type_next(kmip_type, stream): | |
144 | tag_type_size = Base.TAG_SIZE + Base.TYPE_SIZE | |
145 | tt = stream.peek(tag_type_size) | |
146 | ||
147 | if len(tt) != tag_type_size: | |
148 | return False | |
149 | ||
150 | typ = unpack('!B', tt[Base.TAG_SIZE:])[0] | |
151 | ||
152 | if typ == kmip_type.value: | |
153 | return True | |
154 | else: | |
155 | return False | |
156 | ||
157 | ||
158 | class Struct(Base): | |
159 | ||
160 | def __init__(self, tag=Tags.DEFAULT): | |
161 | super(Struct, self).__init__(tag, type=Types.STRUCTURE) | |
162 | ||
163 | def __repr__(self): | |
164 | return '<Struct>' | |
165 | ||
166 | ||
167 | class Integer(Base): | |
168 | LENGTH = 4 | |
169 | ||
170 | def __init__(self, value=None, tag=Tags.DEFAULT): | |
171 | super(Integer, self).__init__(tag, type=Types.INTEGER) | |
172 | ||
173 | self.value = value | |
174 | self.length = self.LENGTH | |
175 | self.padding_length = self.LENGTH | |
176 | ||
177 | self.validate() | |
178 | ||
179 | def read_value(self, istream): | |
180 | if self.length is not self.LENGTH: | |
181 | raise errors.ReadValueError(Integer.__name__, 'length', | |
182 | self.LENGTH, self.length) | |
183 | ||
184 | self.value = unpack('!i', str(istream.read(self.length)))[0] | |
185 | pad = unpack('!i', str(istream.read(self.padding_length)))[0] | |
186 | ||
187 | if pad is not 0: | |
188 | raise errors.ReadValueError(Integer.__name__, 'pad', 0, | |
189 | pad) | |
190 | self.validate() | |
191 | ||
192 | def read(self, istream): | |
193 | super(Integer, self).read(istream) | |
194 | self.read_value(istream) | |
195 | ||
196 | def write_value(self, ostream): | |
197 | ostream.write(pack('!i', self.value)) | |
198 | ostream.write(pack('!i', 0)) | |
199 | ||
200 | def write(self, ostream): | |
201 | super(Integer, self).write(ostream) | |
202 | self.write_value(ostream) | |
203 | ||
204 | def validate(self): | |
205 | self.__validate() | |
206 | ||
207 | def __validate(self): | |
208 | if self.value is not None: | |
209 | data_type = type(self.value) | |
210 | if data_type is not int: | |
211 | raise errors.StateTypeError(Integer.__name__, int, | |
212 | data_type) | |
213 | num_bytes = utils.count_bytes(self.value) | |
214 | if num_bytes > self.length: | |
215 | raise errors.StateOverflowError(Integer.__name__, | |
216 | 'value', self.length, | |
217 | num_bytes) | |
218 | ||
219 | def __repr__(self): | |
220 | return '<Integer, %d>' % (self.value) | |
221 | ||
222 | ||
223 | class LongInteger(Base): | |
224 | LENGTH = 8 | |
225 | ||
226 | def __init__(self, value=None, tag=Tags.DEFAULT): | |
227 | super(LongInteger, self).__init__(tag, type=Types.LONG_INTEGER) | |
228 | self.value = value | |
229 | self.length = self.LENGTH | |
230 | ||
231 | self.validate() | |
232 | ||
233 | def read_value(self, istream): | |
234 | if self.length is not self.LENGTH: | |
235 | raise errors.ReadValueError(LongInteger.__name__, 'length', | |
236 | self.LENGTH, self.length) | |
237 | ||
238 | self.value = unpack('!q', str(istream.read(self.length)))[0] | |
239 | self.validate() | |
240 | ||
241 | def read(self, istream): | |
242 | super(LongInteger, self).read(istream) | |
243 | self.read_value(istream) | |
244 | ||
245 | def write_value(self, ostream): | |
246 | ostream.write(pack('!q', self.value)) | |
247 | ||
248 | def write(self, ostream): | |
249 | super(LongInteger, self).write(ostream) | |
250 | self.write_value(ostream) | |
251 | ||
252 | def validate(self): | |
253 | self.__validate() | |
254 | ||
255 | def __validate(self): | |
256 | if self.value is not None: | |
257 | data_type = type(self.value) | |
258 | if data_type not in (int, long): | |
259 | raise errors.StateTypeError(LongInteger.__name__, | |
260 | '{0} or {1}'.format(int, long), | |
261 | data_type) | |
262 | num_bytes = utils.count_bytes(self.value) | |
263 | if num_bytes > self.length: | |
264 | raise errors.StateOverflowError(LongInteger.__name__, | |
265 | 'value', self.length, | |
266 | num_bytes) | |
267 | ||
268 | def __repr__(self): | |
269 | return '<Long Integer, %d>' % (self.value) | |
270 | ||
271 | ||
272 | class BigInteger(Base): | |
273 | BLOCK_SIZE = 8 | |
274 | SHIFT_SIZE = 64 | |
275 | ||
276 | def __init__(self, value=None, tag=Tags.DEFAULT): | |
277 | super(BigInteger, self).__init__(tag, type=Types.BIG_INTEGER) | |
278 | self.value = value | |
279 | ||
280 | if self.value is not None: | |
281 | self.real_length = utils.count_bytes(self.value) | |
282 | self.padding_length = self.BLOCK_SIZE - (self.length % | |
283 | self.BLOCK_SIZE) | |
284 | if self.padding_length == self.BLOCK_SIZE: | |
285 | self.padding_length = 0 | |
286 | else: | |
287 | self.length = None | |
288 | self.padding_length = None | |
289 | ||
290 | self.validate() | |
291 | ||
292 | def read_value(self, istream): | |
293 | if (self.length < self.BLOCK_SIZE) or (self.length % self.BLOCK_SIZE): | |
294 | raise errors.InvalidLengthError(BigInteger.__name__, | |
295 | ('multiple' | |
296 | 'of {0}'.format(self.BLOCK_SIZE)), | |
297 | self.length) | |
298 | self.value = 0 | |
299 | num_blocks = self.length / self.BLOCK_SIZE | |
300 | ||
301 | # Read first block as signed data | |
302 | self.value = unpack('!q', str(istream.read(self.BLOCK_SIZE)))[0] | |
303 | ||
304 | # Shift current value and add on next unsigned block | |
305 | for _ in xrange(num_blocks - 1): | |
306 | self.value = self.value << self.SHIFT_SIZE | |
307 | stream_data = istream.read(self.BLOCK_SIZE) | |
308 | self.value += unpack('!Q', stream_data)[0] | |
309 | ||
310 | self.validate() | |
311 | ||
312 | def read(self, istream): | |
313 | super(BigInteger, self).read(istream) | |
314 | self.read_value(istream) | |
315 | ||
316 | def write_value(self, ostream): | |
317 | # 1. Determine the sign of the value (+/-); save it. | |
318 | # 2. Extend hex of value with 0s until encoding is right size (8x). | |
319 | # 3. Write out each block of the encoding as signed, 2s complement: | |
320 | # pack('!q', sign * block) | |
321 | ||
322 | # Determine sign for padding | |
323 | pad_byte = 0x00 | |
324 | pad_nybl = 0x0 | |
325 | ||
326 | if self.value < 0: | |
327 | pad_byte = 0xff | |
328 | pad_nybl = 0xf | |
329 | ||
330 | # Compose padding bytes | |
331 | pad = '' | |
332 | for _ in xrange(self.padding_length): | |
333 | pad += hex(pad_byte)[2:] | |
334 | ||
335 | str_rep = hex(self.value).rstrip("Ll")[2:] | |
336 | if len(str_rep) % 2: | |
337 | pad += hex(pad_nybl)[2] | |
338 | ||
339 | # Compose value for block-based write | |
340 | str_rep = pad + str_rep | |
341 | num_blocks = len(str_rep) / self.BLOCK_SIZE | |
342 | ||
343 | # Write first block as signed data | |
344 | block = int(str_rep[0:self.BLOCK_SIZE], 16) | |
345 | ostream.write(pack('!q', block)) | |
346 | ||
347 | # Write remaining blocks as unsigned data | |
348 | for i in xrange(1, num_blocks): | |
349 | block = str_rep[(self.BLOCK_SIZE * i):(self.BLOCK_SIZE * (i + 1))] | |
350 | block = int(block, 16) | |
351 | ostream.write(pack('!Q', block)) | |
352 | ||
353 | def write(self, ostream): | |
354 | super(BigInteger, self).write(ostream) | |
355 | self.write_value(ostream) | |
356 | ||
357 | def validate(self): | |
358 | self.__validate() | |
359 | ||
360 | def __validate(self): | |
361 | if self.value is not None: | |
362 | data_type = type(self.value) | |
363 | if data_type not in (int, long): | |
364 | raise errors.StateTypeError(BigInteger.__name__, | |
365 | '{0} or {1}'.format(int, long), | |
366 | data_type) | |
367 | num_bytes = utils.count_bytes(self.length) | |
368 | if num_bytes > self.LENGTH_SIZE: | |
369 | raise errors.StateOverflowError(BigInteger.__name__, | |
370 | 'length', self.LENGTH_SIZE, | |
371 | num_bytes) | |
372 | ||
373 | ||
374 | class Enumeration(Integer): | |
375 | ENUM_TYPE = None | |
376 | ||
377 | def __init__(self, value=None, tag=Tags.DEFAULT): | |
378 | self.enum = value | |
379 | self.validate() | |
380 | ||
381 | if self.enum is None: | |
382 | super(Enumeration, self).__init__(None, tag) | |
383 | else: | |
384 | super(Enumeration, self).__init__(self.enum.value, tag) | |
385 | self.type = Types.ENUMERATION | |
386 | ||
387 | def read(self, istream): | |
388 | super(Enumeration, self).read(istream) | |
389 | self.enum = self.ENUM_TYPE(self.value) | |
390 | self.validate() | |
391 | ||
392 | def write(self, ostream): | |
393 | super(Enumeration, self).write(ostream) | |
394 | ||
395 | def validate(self): | |
396 | self.__validate() | |
397 | ||
398 | def __validate(self): | |
399 | if self.enum is not None: | |
400 | if type(self.enum) is not self.ENUM_TYPE: | |
401 | msg = ErrorStrings.BAD_EXP_RECV | |
402 | raise TypeError(msg.format(Enumeration.__name__, 'value', | |
403 | Enum, type(self.enum))) | |
404 | ||
405 | def __repr__(self): | |
406 | return '<Enumeration, %s, %d>' % (self.enum.name, self.enum.value) | |
407 | ||
408 | ||
409 | class Boolean(Base): | |
410 | ||
411 | def __init__(self, value=None, tag=Tags.DEFAULT): | |
412 | super(Boolean, self).__init__(tag, type=Types.BOOLEAN) | |
413 | self.value = value | |
414 | self.length = 8 | |
415 | ||
416 | def read_value(self, istream): | |
417 | value = unpack('!Q', str(istream[0:self.length]))[0] | |
418 | ||
419 | if value == 1: | |
420 | self.value = True | |
421 | elif value == 0: | |
422 | self.value = False | |
423 | else: | |
424 | raise errors.ReadValueError(Boolean.__name__, 'value', | |
425 | value) | |
426 | ||
427 | for _ in xrange(self.length): | |
428 | istream.pop(0) | |
429 | ||
430 | def read(self, istream): | |
431 | super(Boolean, self).read(istream) | |
432 | self.read_value(istream) | |
433 | ||
434 | def write_value(self, ostream): | |
435 | if self.value is None: | |
436 | raise errors.WriteValueError(Boolean.__name__, 'value', | |
437 | self.value) | |
438 | ||
439 | data_buffer = bytearray() | |
440 | ||
441 | if isinstance(self.value, type(True)): | |
442 | if self.value: | |
443 | data_buffer.extend(pack('!Q', 1)) | |
444 | else: | |
445 | data_buffer.extend(pack('!Q', 0)) | |
446 | else: | |
447 | raise errors.WriteTypeError(Boolean.__name__, 'value', | |
448 | type(self.value)) | |
449 | ||
450 | ostream.extend(data_buffer) | |
451 | ||
452 | def write(self, ostream): | |
453 | super(Boolean, self).write(ostream) | |
454 | self.write_value(ostream) | |
455 | ||
456 | def validate(self): | |
457 | self.__validate() | |
458 | ||
459 | def __validate(self): | |
460 | pass | |
461 | ||
462 | def __repr__(self): | |
463 | return '<Boolean, %s>' % (self.value) | |
464 | ||
465 | ||
466 | class TextString(Base): | |
467 | PADDING_SIZE = 8 | |
468 | BYTE_FORMAT = '!c' | |
469 | ||
470 | def __init__(self, value=None, tag=Tags.DEFAULT): | |
471 | super(TextString, self).__init__(tag, type=Types.TEXT_STRING) | |
472 | self.value = value | |
473 | ||
474 | self.validate() | |
475 | ||
476 | if self.value is not None: | |
477 | self.length = len(self.value) | |
478 | self.padding_length = self.PADDING_SIZE - (self.length % | |
479 | self.PADDING_SIZE) | |
480 | if self.padding_length == self.PADDING_SIZE: | |
481 | self.padding_length = 0 | |
482 | else: | |
483 | self.length = None | |
484 | self.padding_length = None | |
485 | ||
486 | def read_value(self, istream): | |
487 | # Read string text | |
488 | self.value = '' | |
489 | for _ in xrange(self.length): | |
490 | self.value += unpack(self.BYTE_FORMAT, str(istream.read(1)))[0] | |
491 | ||
492 | # Read padding and check content | |
493 | self.padding_length = self.PADDING_SIZE - (self.length % | |
494 | self.PADDING_SIZE) | |
495 | if self.padding_length < self.PADDING_SIZE: | |
496 | for _ in xrange(self.padding_length): | |
497 | pad = unpack('!B', str(istream.read(1)))[0] | |
498 | if pad is not 0: | |
499 | raise errors.ReadValueError(TextString.__name__, 'pad', 0, | |
500 | pad) | |
501 | ||
502 | def read(self, istream): | |
503 | super(TextString, self).read(istream) | |
504 | self.read_value(istream) | |
505 | self.validate() | |
506 | ||
507 | def write_value(self, ostream): | |
508 | # Write string to stream | |
509 | for char in self.value: | |
510 | ostream.write(pack(self.BYTE_FORMAT, char)) | |
511 | ||
512 | # Write padding to stream | |
513 | for _ in xrange(self.padding_length): | |
514 | ostream.write(pack('!B', 0)) | |
515 | ||
516 | def write(self, ostream): | |
517 | super(TextString, self).write(ostream) | |
518 | self.write_value(ostream) | |
519 | ||
520 | def validate(self): | |
521 | self.__validate() | |
522 | ||
523 | def __validate(self): | |
524 | if self.value is not None: | |
525 | data_type = type(self.value) | |
526 | if data_type is not str: | |
527 | msg = ErrorStrings.BAD_EXP_RECV | |
528 | raise TypeError(msg.format('TextString', 'value', str, | |
529 | data_type)) | |
530 | ||
531 | def __repr__(self): | |
532 | return '<TextString, %s>' % (self.value) | |
533 | ||
534 | ||
535 | class ByteString(Base): | |
536 | PADDING_SIZE = 8 | |
537 | BYTE_FORMAT = '!B' | |
538 | ||
539 | def __init__(self, value=None, tag=Tags.DEFAULT): | |
540 | super(ByteString, self).__init__(tag, type=Types.BYTE_STRING) | |
541 | self.value = value | |
542 | ||
543 | self.validate() | |
544 | ||
545 | if self.value is not None: | |
546 | self.length = len(self.value) | |
547 | self.padding_length = self.PADDING_SIZE - (self.length % | |
548 | self.PADDING_SIZE) | |
549 | if self.padding_length == self.PADDING_SIZE: | |
550 | self.padding_length = 0 | |
551 | else: | |
552 | self.length = None | |
553 | self.padding_length = None | |
554 | ||
555 | def read_value(self, istream): | |
556 | # Read bytes into bytearray | |
557 | self.value = bytearray() | |
558 | for _ in xrange(self.length): | |
559 | self.value.append(istream.read(1)) | |
560 | ||
561 | # Read padding and check content | |
562 | self.padding_length = self.PADDING_SIZE - (self.length % | |
563 | self.PADDING_SIZE) | |
564 | if self.padding_length == self.PADDING_SIZE: | |
565 | self.padding_length = 0 | |
566 | ||
567 | if self.padding_length < self.PADDING_SIZE: | |
568 | for _ in xrange(self.padding_length): | |
569 | pad = unpack('!B', str(istream.read(1)))[0] | |
570 | if pad is not 0: | |
571 | raise errors.ReadValueError(TextString.__name__, 'pad', 0, | |
572 | pad) | |
573 | ||
574 | def read(self, istream): | |
575 | super(ByteString, self).read(istream) | |
576 | self.read_value(istream) | |
577 | ||
578 | def write_value(self, ostream): | |
579 | # Write bytes to stream | |
580 | for byte in self.value: | |
581 | ostream.write(pack(self.BYTE_FORMAT, byte)) | |
582 | ||
583 | # Write padding to stream | |
584 | for _ in xrange(self.padding_length): | |
585 | ostream.write(pack('!B', 0)) | |
586 | ||
587 | def write(self, ostream): | |
588 | super(ByteString, self).write(ostream) | |
589 | self.write_value(ostream) | |
590 | ||
591 | def validate(self): | |
592 | self.__validate() | |
593 | ||
594 | def __validate(self): | |
595 | if self.value is not None: | |
596 | data_type = type(self.value) | |
597 | if data_type is not bytearray: | |
598 | msg = ErrorStrings.BAD_EXP_RECV | |
599 | raise TypeError(msg.format('ByteString', 'value', bytearray, | |
600 | data_type)) | |
601 | ||
602 | def __repr__(self): | |
603 | return '<Integer, %s>' % (self.value) | |
604 | ||
605 | ||
606 | class DateTime(LongInteger): | |
607 | ||
608 | def __init__(self, value=None, tag=Tags.DEFAULT): | |
609 | super(DateTime, self).__init__(value, tag) | |
610 | self.type = Types.DATE_TIME | |
611 | ||
612 | ||
613 | class Interval(Integer): | |
614 | ||
615 | def __init__(self, value=None, tag=Tags.DEFAULT): | |
616 | super(Interval, self).__init__(value, tag) | |
617 | self.type = Types.INTERVAL |
0 | # Copyright (c) 2014 The Johns Hopkins University/Applied Physics Laboratory | |
1 | # All Rights Reserved. | |
2 | # | |
3 | # Licensed under the Apache License, Version 2.0 (the "License"); you may | |
4 | # not use this file except in compliance with the License. You may obtain | |
5 | # a copy of the License at | |
6 | # | |
7 | # http://www.apache.org/licenses/LICENSE-2.0 | |
8 | # | |
9 | # Unless required by applicable law or agreed to in writing, software | |
10 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT | |
11 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the | |
12 | # License for the specific language governing permissions and limitations | |
13 | # under the License. |
0 | # Copyright (c) 2014 The Johns Hopkins University/Applied Physics Laboratory | |
1 | # All Rights Reserved. | |
2 | # | |
3 | # Licensed under the Apache License, Version 2.0 (the "License"); you may | |
4 | # not use this file except in compliance with the License. You may obtain | |
5 | # a copy of the License at | |
6 | # | |
7 | # http://www.apache.org/licenses/LICENSE-2.0 | |
8 | # | |
9 | # Unless required by applicable law or agreed to in writing, software | |
10 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT | |
11 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the | |
12 | # License for the specific language governing permissions and limitations | |
13 | # under the License. | |
14 | ||
15 | from kmip.core.repo.repo import ManagedObjectRepo | |
16 | ||
17 | ||
18 | class MemRepo(ManagedObjectRepo): | |
19 | ||
20 | def __init__(self): | |
21 | self.repo = {} | |
22 | self.uuid = 1 | |
23 | ||
24 | def save(self, managed_object, attributes): | |
25 | # TODO (nate) verify the parameters | |
26 | uuid = "{0}".format(self.uuid) | |
27 | self.repo[uuid] = (managed_object, attributes) | |
28 | self.uuid += 1 | |
29 | return uuid | |
30 | ||
31 | def get(self, uuid): | |
32 | if uuid is None or uuid not in self.repo: | |
33 | return (None, None) | |
34 | return self.repo[uuid] | |
35 | ||
36 | def update(self, uuid, managed_object, attributes): | |
37 | if uuid is None: | |
38 | return False | |
39 | self.repo[uuid] = (managed_object, attributes) | |
40 | return True | |
41 | ||
42 | def delete(self, uuid): | |
43 | if uuid is None or uuid not in self.repo: | |
44 | return False | |
45 | del self.repo[uuid] | |
46 | return True |
0 | # Copyright (c) 2014 The Johns Hopkins University/Applied Physics Laboratory | |
1 | # All Rights Reserved. | |
2 | # | |
3 | # Licensed under the Apache License, Version 2.0 (the "License"); you may | |
4 | # not use this file except in compliance with the License. You may obtain | |
5 | # a copy of the License at | |
6 | # | |
7 | # http://www.apache.org/licenses/LICENSE-2.0 | |
8 | # | |
9 | # Unless required by applicable law or agreed to in writing, software | |
10 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT | |
11 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the | |
12 | # License for the specific language governing permissions and limitations | |
13 | # under the License. | |
14 | ||
15 | ||
16 | class ManagedObjectRepo(object): | |
17 | """Stores and manages KMIP managed objects. | |
18 | ||
19 | The KMIP specification details the managed objects that are stored by a | |
20 | KMIP server. This repository abstraction is an interface for KMIP servers | |
21 | to store managed objects. | |
22 | """ | |
23 | ||
24 | def __init__(self): | |
25 | pass | |
26 | ||
27 | def save(self, managed_object, attributes): | |
28 | """Save a managed object | |
29 | ||
30 | This saves a managed object into the repository and returns a UUID | |
31 | string that can be used to reference the object in the repository. | |
32 | :param managed_object: managed object to save from secrets.py | |
33 | :param attributes: attributes to store with the managed object | |
34 | :returns: a UUID string that can be used to retrieve the object later | |
35 | """ | |
36 | raise NotImplementedError | |
37 | ||
38 | def get(self, uuid): | |
39 | """Retrieve a managed object | |
40 | ||
41 | Retrieve a managed object from the repository. The UUID is used to | |
42 | identify the managed object to return. The UUID is returned from the | |
43 | save call. | |
44 | ||
45 | A tuple is returned that contains the managed object and all of its | |
46 | attributes. | |
47 | :param uuid: UUID of the managed object | |
48 | :returns: (managed_object, attributes) if object exists, otherwise | |
49 | (None, None) | |
50 | """ | |
51 | raise NotImplementedError | |
52 | ||
53 | def update(self, uuid, managed_object, attributes): | |
54 | """Updates a managed object | |
55 | ||
56 | Updates the values for a managed_object. | |
57 | :param uuid: UUID of the managed object | |
58 | :param managed_object: managed object | |
59 | :param attributes: attributes to store with the managed object | |
60 | :returns: True if object existed and successfully updated, otherwise | |
61 | False | |
62 | """ | |
63 | raise NotImplementedError | |
64 | ||
65 | def delete(self, uuid): | |
66 | """Delete a managed object from the repository | |
67 | ||
68 | Delete a managed object from the repository. | |
69 | :param uuid: UUID of the managed object | |
70 | :returns: True if successfully deleted, False if not found | |
71 | """ | |
72 | raise NotImplementedError |
0 | # Copyright (c) 2014 The Johns Hopkins University/Applied Physics Laboratory | |
1 | # All Rights Reserved. | |
2 | # | |
3 | # Licensed under the Apache License, Version 2.0 (the "License"); you may | |
4 | # not use this file except in compliance with the License. You may obtain | |
5 | # a copy of the License at | |
6 | # | |
7 | # http://www.apache.org/licenses/LICENSE-2.0 | |
8 | # | |
9 | # Unless required by applicable law or agreed to in writing, software | |
10 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT | |
11 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the | |
12 | # License for the specific language governing permissions and limitations | |
13 | # under the License. | |
14 | ||
15 | from kmip.core.attributes import CertificateType | |
16 | ||
17 | from kmip.core import enums | |
18 | from kmip.core.enums import Tags | |
19 | ||
20 | from kmip.core.objects import Attribute | |
21 | from kmip.core.objects import KeyBlock | |
22 | ||
23 | from kmip.core.primitives import Struct | |
24 | from kmip.core.primitives import Integer | |
25 | from kmip.core.primitives import Enumeration | |
26 | from kmip.core.primitives import BigInteger | |
27 | from kmip.core.primitives import ByteString | |
28 | ||
29 | from kmip.core.utils import BytearrayStream | |
30 | ||
31 | ||
32 | # 2.2 | |
33 | # 2.2.1 | |
34 | class Certificate(Struct): | |
35 | ||
36 | class CertificateValue(ByteString): | |
37 | ||
38 | def __init__(self, value=None): | |
39 | super(self.__class__, self).__init__(value, | |
40 | Tags.CERTIFICATE_VALUE) | |
41 | ||
42 | def __init__(self, | |
43 | certificate_type=None, | |
44 | certificate_value=None): | |
45 | super(self.__class__, self).__init__(Tags.CERTIFICATE) | |
46 | self.certificate_type = certificate_type | |
47 | self.certificate_value = certificate_value | |
48 | self.validate() | |
49 | ||
50 | def read(self, istream): | |
51 | super(self.__class__, self).read(istream) | |
52 | tstream = BytearrayStream(istream.read(self.length)) | |
53 | ||
54 | self.certificate_type = CertificateType() | |
55 | self.certificate_value = Certificate.CertificateValue() | |
56 | ||
57 | self.certificate_type.read(tstream) | |
58 | self.certificate_value.read(tstream) | |
59 | ||
60 | self.is_oversized(tstream) | |
61 | self.validate() | |
62 | ||
63 | def write(self, ostream): | |
64 | tstream = BytearrayStream() | |
65 | ||
66 | # Write the details of the certificate | |
67 | self.certificate_type.write(tstream) | |
68 | self.certificate_value.write(tstream) | |
69 | ||
70 | # Write the length and value of the template attribute | |
71 | self.length = tstream.length() | |
72 | super(self.__class__, self).write(ostream) | |
73 | ostream.write(tstream.buffer) | |
74 | ||
75 | def validate(self): | |
76 | self.__validate() | |
77 | ||
78 | def __validate(self): | |
79 | # TODO (peter-hamilton) Finish implementation. | |
80 | pass | |
81 | ||
82 | ||
83 | # 2.2.2 | |
84 | class KeyBlockKey(Struct): | |
85 | ||
86 | def __init__(self, key_block=None, tag=Tags.DEFAULT): | |
87 | super(KeyBlockKey, self).__init__(tag) | |
88 | self.key_block = key_block | |
89 | self.validate() | |
90 | ||
91 | def read(self, istream): | |
92 | super(KeyBlockKey, self).read(istream) | |
93 | tstream = BytearrayStream(istream.read(self.length)) | |
94 | ||
95 | self.key_block = KeyBlock() | |
96 | self.key_block.read(tstream) | |
97 | ||
98 | self.is_oversized(tstream) | |
99 | self.validate() | |
100 | ||
101 | def write(self, ostream): | |
102 | tstream = BytearrayStream() | |
103 | ||
104 | self.key_block.write(tstream) | |
105 | ||
106 | # Write the length and value of the template attribute | |
107 | self.length = tstream.length() | |
108 | super(KeyBlockKey, self).write(ostream) | |
109 | ostream.write(tstream.buffer) | |
110 | ||
111 | def validate(self): | |
112 | self.__validate() | |
113 | ||
114 | def __validate(self): | |
115 | # TODO (peter-hamilton) Finish implementation. | |
116 | pass | |
117 | ||
118 | ||
119 | class SymmetricKey(KeyBlockKey): | |
120 | ||
121 | def __init__(self, key_block=None): | |
122 | super(self.__class__, self).__init__(key_block, Tags.SYMMETRIC_KEY) | |
123 | self.validate() | |
124 | ||
125 | def validate(self): | |
126 | self.__validate() | |
127 | ||
128 | def __validate(self): | |
129 | # TODO (peter-hamilton) Finish implementation. | |
130 | pass | |
131 | ||
132 | ||
133 | # 2.2.3 | |
134 | class PublicKey(KeyBlockKey): | |
135 | ||
136 | def __init__(self, key_block=None): | |
137 | super(self.__class__, self).__init__(key_block, Tags.PUBLIC_KEY) | |
138 | self.validate() | |
139 | ||
140 | def validate(self): | |
141 | self.__validate() | |
142 | ||
143 | def __validate(self): | |
144 | # TODO (peter-hamilton) Finish implementation. | |
145 | pass | |
146 | ||
147 | ||
148 | # 2.2.4 | |
149 | class PrivateKey(KeyBlockKey): | |
150 | ||
151 | def __init__(self, key_block=None): | |
152 | super(self.__class__, self).__init__(key_block, Tags.PRIVATE_KEY) | |
153 | self.validate() | |
154 | ||
155 | def validate(self): | |
156 | self.__validate() | |
157 | ||
158 | def __validate(self): | |
159 | # TODO (peter-hamilton) Finish implementation. | |
160 | pass | |
161 | ||
162 | ||
163 | # 2.2.5 | |
164 | class SplitKey(Struct): | |
165 | ||
166 | class SplitKeyParts(Integer): | |
167 | ||
168 | def __init__(self, value=None): | |
169 | super(self.__class__, self).__init__(value, | |
170 | Tags.SPLIT_KEY_PARTS) | |
171 | ||
172 | class KeyPartIdentifier(Integer): | |
173 | ||
174 | def __init__(self, value=None): | |
175 | super(self.__class__, self).__init__(value, | |
176 | Tags.KEY_PART_IDENTIFIER) | |
177 | ||
178 | class SplitKeyThreshold(Integer): | |
179 | ||
180 | def __init__(self, value=None): | |
181 | super(self.__class__, self).__init__(value, | |
182 | Tags.SPLIT_KEY_THRESHOLD) | |
183 | ||
184 | class SplitKeyMethod(Enumeration): | |
185 | ENUM_TYPE = enums.SplitKeyMethod | |
186 | ||
187 | def __init__(self, value=None): | |
188 | super(self.__class__, self).__init__(value, | |
189 | Tags.SPLIT_KEY_METHOD) | |
190 | ||
191 | class PrimeFieldSize(BigInteger): | |
192 | ||
193 | def __init__(self, value=None): | |
194 | super(self.__class__, self).__init__(value, | |
195 | Tags.PRIME_FIELD_SIZE) | |
196 | ||
197 | def __init__(self, | |
198 | split_key_parts=None, | |
199 | key_part_identifier=None, | |
200 | split_key_threshold=None, | |
201 | split_key_method=None, | |
202 | prime_field_size=None, | |
203 | key_block=None): | |
204 | super(self.__class__, self).__init__(Tags.SPLIT_KEY) | |
205 | self.split_key_parts = split_key_parts | |
206 | self.key_part_identifier = key_part_identifier | |
207 | self.split_key_threshold = split_key_threshold | |
208 | self.split_key_method = split_key_method | |
209 | self.prime_field_size = prime_field_size | |
210 | self.key_block = key_block | |
211 | self.validate() | |
212 | ||
213 | def read(self, istream): | |
214 | super(self.__class__, self).read(istream) | |
215 | tstream = BytearrayStream(istream.read(self.length)) | |
216 | ||
217 | self.split_key_parts = SplitKey.SplitKeyParts() | |
218 | self.split_key_parts.read(tstream) | |
219 | ||
220 | self.key_part_identifier = SplitKey.KeyPartIdentifier() | |
221 | self.key_part_identifier.read(tstream) | |
222 | ||
223 | self.split_key_threshold = SplitKey.SplitKeyThreshold() | |
224 | self.split_key_threshold.read(tstream) | |
225 | ||
226 | if self.is_tag_next(Tags.PRIME_FIELD_SIZE, tstream): | |
227 | self.prime_field_size = SplitKey.PrimeFieldSize() | |
228 | self.prime_field_size.read(tstream) | |
229 | ||
230 | self.key_block = KeyBlock() | |
231 | self.key_block.read(tstream) | |
232 | ||
233 | self.is_oversized(tstream) | |
234 | self.validate() | |
235 | ||
236 | def write(self, ostream): | |
237 | tstream = BytearrayStream() | |
238 | ||
239 | self.split_key_parts.write(tstream) | |
240 | self.key_part_identifier.write(tstream) | |
241 | self.split_key_threshold.write(tstream) | |
242 | self.split_key_method.write(tstream) | |
243 | ||
244 | if self.prime_field_size is not None: | |
245 | self.prime_field_size.write(tstream) | |
246 | ||
247 | self.key_block.write(tstream) | |
248 | ||
249 | # Write the length and value of the template attribute | |
250 | self.length = tstream.length() | |
251 | super(self.__class__, self).write(ostream) | |
252 | ostream.write(tstream.buffer) | |
253 | ||
254 | def validate(self): | |
255 | self.__validate() | |
256 | ||
257 | def __validate(self): | |
258 | # TODO (peter-hamilton) Finish implementation. | |
259 | pass | |
260 | ||
261 | ||
262 | # 2.2.6 | |
263 | class Template(Struct): | |
264 | ||
265 | def __init__(self, attributes=None): | |
266 | super(self.__class__, self).__init__(Tags.TEMPLATE) | |
267 | self.attributes = attributes | |
268 | self.validate() | |
269 | ||
270 | def read(self, istream): | |
271 | super(self.__class__, self).read(istream) | |
272 | tstream = BytearrayStream(istream.read(self.length)) | |
273 | ||
274 | self.attributes = list() | |
275 | ||
276 | attribute = Attribute() | |
277 | attribute.read(tstream) | |
278 | self.attributes.append(attribute) | |
279 | ||
280 | while self.is_tag_next(Tags.ATTRIBUTE, tstream): | |
281 | attribute = Attribute() | |
282 | attribute.read(tstream) | |
283 | self.attributes.append(attribute) | |
284 | ||
285 | self.is_oversized(tstream) | |
286 | self.validate() | |
287 | ||
288 | def write(self, ostream): | |
289 | tstream = BytearrayStream() | |
290 | ||
291 | for attribute in self.attributes: | |
292 | attribute.write(tstream) | |
293 | ||
294 | # Write the length and value of the template attribute | |
295 | self.length = tstream.length() | |
296 | super(self.__class__, self).write(ostream) | |
297 | ostream.write(tstream.buffer) | |
298 | ||
299 | def validate(self): | |
300 | self.__validate() | |
301 | ||
302 | def __validate(self): | |
303 | # TODO (peter-hamilton) Finish implementation. | |
304 | pass | |
305 | ||
306 | ||
307 | # 2.2.7 | |
308 | class SecretData(Struct): | |
309 | ||
310 | class SecretDataType(Enumeration): | |
311 | ENUM_TYPE = enums.SecretDataType | |
312 | ||
313 | def __init__(self, value=None): | |
314 | super(self.__class__, self).__init__(value, Tags.SECRET_DATA_TYPE) | |
315 | ||
316 | def __init__(self, | |
317 | secret_data_type=None, | |
318 | key_block=None): | |
319 | super(self.__class__, self).__init__(Tags.SECRET_DATA) | |
320 | self.secret_data_type = secret_data_type | |
321 | self.key_block = key_block | |
322 | self.validate() | |
323 | ||
324 | def read(self, istream): | |
325 | super(self.__class__, self).read(istream) | |
326 | tstream = BytearrayStream(istream.read(self.length)) | |
327 | ||
328 | self.secret_data_type = SecretData.SecretDataType() | |
329 | self.key_block = KeyBlock() | |
330 | ||
331 | self.secret_data_type.read(tstream) | |
332 | self.key_block.read(tstream) | |
333 | ||
334 | self.is_oversized(tstream) | |
335 | self.validate() | |
336 | ||
337 | def write(self, ostream): | |
338 | tstream = BytearrayStream() | |
339 | ||
340 | self.secret_data_type.write(tstream) | |
341 | self.key_block.write(tstream) | |
342 | ||
343 | # Write the length and value of the template attribute | |
344 | self.length = tstream.length() | |
345 | super(self.__class__, self).write(ostream) | |
346 | ostream.write(tstream.buffer) | |
347 | ||
348 | def validate(self): | |
349 | self.__validate() | |
350 | ||
351 | def __validate(self): | |
352 | # TODO (peter-hamilton) Finish implementation. | |
353 | pass | |
354 | ||
355 | ||
356 | # 2.2.8 | |
357 | class OpaqueObject(Struct): | |
358 | ||
359 | class OpaqueDataType(Enumeration): | |
360 | ENUM_TYPE = enums.OpaqueDataType | |
361 | ||
362 | def __init__(self, value=None): | |
363 | super(self.__class__, self).__init__(value, Tags.OPAQUE_DATA_TYPE) | |
364 | ||
365 | class OpaqueDataValue(ByteString): | |
366 | ||
367 | def __init__(self, value=None): | |
368 | super(self.__class__, self).__init__(value, Tags.OPAQUE_DATA_VALUE) | |
369 | ||
370 | def __init__(self, | |
371 | opaque_data_type=None, | |
372 | opaque_data_value=None): | |
373 | super(self.__class__, self).__init__(Tags.OPAQUE_OBJECT) | |
374 | self.opaque_data_type = opaque_data_type | |
375 | self.opaque_data_value = opaque_data_value | |
376 | self.validate() | |
377 | ||
378 | def read(self, istream): | |
379 | super(self.__class__, self).read(istream) | |
380 | tstream = BytearrayStream(istream.read(self.length)) | |
381 | ||
382 | self.opaque_data_type = OpaqueObject.OpaqueDataType() | |
383 | self.opaque_data_value = OpaqueObject.OpaqueDataValue() | |
384 | ||
385 | self.opaque_data_type.read(tstream) | |
386 | self.opaque_data_value.read(tstream) | |
387 | ||
388 | self.is_oversized(tstream) | |
389 | self.validate() | |
390 | ||
391 | def write(self, ostream): | |
392 | tstream = BytearrayStream() | |
393 | ||
394 | self.opaque_data_type.write(tstream) | |
395 | self.opaque_data_value.write(tstream) | |
396 | ||
397 | # Write the length and value of the template attribute | |
398 | self.length = tstream.length() | |
399 | super(self.__class__, self).write(ostream) | |
400 | ostream.write(tstream.buffer) | |
401 | ||
402 | def validate(self): | |
403 | self.__validate() | |
404 | ||
405 | def __validate(self): | |
406 | # TODO (peter-hamilton) Finish implementation. | |
407 | pass |
0 | # Copyright (c) 2014 The Johns Hopkins University/Applied Physics Laboratory | |
1 | # All Rights Reserved. | |
2 | # | |
3 | # Licensed under the Apache License, Version 2.0 (the "License"); you may | |
4 | # not use this file except in compliance with the License. You may obtain | |
5 | # a copy of the License at | |
6 | # | |
7 | # http://www.apache.org/licenses/LICENSE-2.0 | |
8 | # | |
9 | # Unless required by applicable law or agreed to in writing, software | |
10 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT | |
11 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the | |
12 | # License for the specific language governing permissions and limitations | |
13 | # under the License. | |
14 | ||
15 | import logging | |
16 | import os | |
17 | ||
18 | from kmip.core.attributes import CryptographicLength | |
19 | from kmip.core.attributes import CryptographicAlgorithm | |
20 | from kmip.core.attributes import ObjectType | |
21 | from kmip.core.attributes import UniqueIdentifier | |
22 | from kmip.core.enums import AttributeType as AT | |
23 | from kmip.core.enums import CryptographicAlgorithm as CA | |
24 | from kmip.core.enums import KeyFormatType as KeyFormatTypeEnum | |
25 | from kmip.core.enums import ObjectType as OT | |
26 | from kmip.core.enums import ResultReason as ResultReasonEnum | |
27 | from kmip.core.enums import ResultStatus as RS | |
28 | from kmip.core.factories.attributes import AttributeFactory | |
29 | from kmip.core.factories.keys import KeyFactory | |
30 | from kmip.core.factories.secrets import SecretFactory | |
31 | from kmip.core.keys import RawKey | |
32 | ||
33 | from kmip.core.messages.contents import KeyFormatType | |
34 | from kmip.core.messages.contents import ResultStatus | |
35 | from kmip.core.messages.contents import ResultReason | |
36 | from kmip.core.messages.contents import ResultMessage | |
37 | ||
38 | from kmip.core.objects import KeyBlock | |
39 | from kmip.core.objects import KeyValue | |
40 | from kmip.core.objects import KeyValueStruct | |
41 | from kmip.core.objects import TemplateAttribute | |
42 | from kmip.core.repo.mem_repo import MemRepo | |
43 | from kmip.core.secrets import SymmetricKey | |
44 | from kmip.services.results import CreateResult | |
45 | from kmip.services.results import DestroyResult | |
46 | from kmip.services.results import GetResult | |
47 | from kmip.services.results import OperationResult | |
48 | from kmip.services.results import RegisterResult | |
49 | ||
50 | ||
51 | class KMIP(object): | |
52 | ||
53 | def __init__(self): | |
54 | pass | |
55 | ||
56 | def create(self, object_type, template_attribute, credential=None): | |
57 | raise NotImplementedError | |
58 | ||
59 | def register(self, object_type, template_attribute, secret, | |
60 | credential=None): | |
61 | raise NotImplementedError | |
62 | ||
63 | def get(self, uuid=None, key_format_type=None, key_compression_type=None, | |
64 | key_wrapping_specification=None, credential=None): | |
65 | raise NotImplementedError | |
66 | ||
67 | def destroy(self, uuid, credential=None): | |
68 | raise NotImplementedError | |
69 | ||
70 | ||
71 | class KMIPImpl(KMIP): | |
72 | ||
73 | def __init__(self): | |
74 | super(self.__class__, self).__init__() | |
75 | self.logger = logging.getLogger(__name__) | |
76 | self.key_factory = KeyFactory() | |
77 | self.secret_factory = SecretFactory() | |
78 | self.attribute_factory = AttributeFactory() | |
79 | self.repo = MemRepo() | |
80 | ||
81 | def create(self, object_type, template_attribute, credential=None): | |
82 | self.logger.debug('create() called') | |
83 | self.logger.debug('object type = %s' % object_type) | |
84 | bit_length = 256 | |
85 | attributes = template_attribute.attributes | |
86 | ret_attributes = [] | |
87 | if object_type.enum != OT.SYMMETRIC_KEY: | |
88 | self.logger.debug('invalid object type') | |
89 | return self._get_invalid_field_result('invalid object type') | |
90 | try: | |
91 | alg_attr =\ | |
92 | self._validate_req_field(attributes, | |
93 | AT.CRYPTOGRAPHIC_ALGORITHM.value, | |
94 | (CA.AES.value,), | |
95 | 'unsupported algorithm') | |
96 | len_attr = self._validate_req_field(attributes, | |
97 | AT.CRYPTOGRAPHIC_LENGTH.value, | |
98 | (128, 256, 512), | |
99 | 'unsupported key length', | |
100 | False) | |
101 | self._validate_req_field(attributes, | |
102 | AT.CRYPTOGRAPHIC_USAGE_MASK.value, | |
103 | (), | |
104 | '') | |
105 | except InvalidFieldException as e: | |
106 | self.logger.debug('InvalidFieldException raised') | |
107 | return e.result | |
108 | ||
109 | crypto_alg = CryptographicAlgorithm(CA(alg_attr.attribute_value.value)) | |
110 | ||
111 | if len_attr is None: | |
112 | self.logger.debug('cryptographic length not supplied') | |
113 | attribute_type = AT.CRYPTOGRAPHIC_LENGTH | |
114 | length_attribute = self.attribute_factory.\ | |
115 | create_attribute(attribute_type, bit_length) | |
116 | attributes.append(length_attribute) | |
117 | ret_attributes.append(length_attribute) | |
118 | else: | |
119 | bit_length = len_attr.attribute_value.value | |
120 | ||
121 | key = self._gen_symmetric_key(bit_length, crypto_alg) | |
122 | s_uuid, uuid_attribute = self._save(key, attributes) | |
123 | ret_attributes.append(uuid_attribute) | |
124 | template_attribute = TemplateAttribute(attributes=ret_attributes) | |
125 | return CreateResult(ResultStatus(RS.SUCCESS), | |
126 | object_type=object_type, | |
127 | uuid=UniqueIdentifier(s_uuid), | |
128 | template_attribute=template_attribute) | |
129 | ||
130 | def register(self, object_type, template_attribute, secret, | |
131 | credential=None): | |
132 | self.logger.debug('register() called') | |
133 | self.logger.debug('object type = %s' % object_type) | |
134 | attributes = template_attribute.attributes | |
135 | ret_attributes = [] | |
136 | if object_type is None: | |
137 | self.logger.debug('invalid object type') | |
138 | return self._get_missing_field_result('object type') | |
139 | if object_type.enum != OT.SYMMETRIC_KEY: | |
140 | self.logger.debug('invalid object type') | |
141 | return self._get_invalid_field_result('invalid object type') | |
142 | if secret is None or not isinstance(secret, SymmetricKey): | |
143 | msg = 'object type does not match that of secret' | |
144 | self.logger.debug(msg) | |
145 | return self._get_invalid_field_result(msg) | |
146 | ||
147 | self.logger.debug('Collecting all attributes') | |
148 | if attributes is None: | |
149 | attributes = [] | |
150 | attributes.extend(self._get_key_block_attributes(secret.key_block)) | |
151 | ||
152 | self.logger.debug('Verifying all attributes are valid and set') | |
153 | try: | |
154 | self._validate_req_field(attributes, | |
155 | AT.CRYPTOGRAPHIC_ALGORITHM.value, | |
156 | (CA.AES.value,), | |
157 | 'unsupported algorithm') | |
158 | self._validate_req_field(attributes, | |
159 | AT.CRYPTOGRAPHIC_LENGTH.value, | |
160 | (128, 256, 512), | |
161 | 'unsupported key length') | |
162 | self._validate_req_field(attributes, | |
163 | AT.CRYPTOGRAPHIC_USAGE_MASK.value, | |
164 | (), | |
165 | '') | |
166 | except InvalidFieldException as e: | |
167 | self.logger.debug('InvalidFieldException raised') | |
168 | return RegisterResult(e.result.result_status, | |
169 | e.result.result_reason, | |
170 | e.result.result_message) | |
171 | ||
172 | s_uuid, uuid_attribute = self._save(secret, attributes) | |
173 | ret_attributes.append(uuid_attribute) | |
174 | template_attribute = TemplateAttribute(attributes=ret_attributes) | |
175 | return RegisterResult(ResultStatus(RS.SUCCESS), | |
176 | uuid=UniqueIdentifier(s_uuid), | |
177 | template_attribute=template_attribute) | |
178 | ||
179 | def get(self, | |
180 | uuid=None, | |
181 | key_format_type=None, | |
182 | key_compression_type=None, | |
183 | key_wrapping_specification=None, | |
184 | credential=None): | |
185 | self.logger.debug('get() called') | |
186 | ret_value = RS.OPERATION_FAILED | |
187 | if uuid is None or not hasattr(uuid, 'value'): | |
188 | self.logger.debug('no uuid provided') | |
189 | reason = ResultReason(ResultReasonEnum.ITEM_NOT_FOUND) | |
190 | message = ResultMessage('') | |
191 | return GetResult(ResultStatus(ret_value), reason, message) | |
192 | if key_format_type is None: | |
193 | self.logger.debug('key format type is None, setting to raw') | |
194 | key_format_type = KeyFormatType(KeyFormatTypeEnum.RAW) | |
195 | if key_format_type.enum != KeyFormatTypeEnum.RAW: | |
196 | self.logger.debug('key format type is not raw') | |
197 | reason = ResultReason(ResultReasonEnum. | |
198 | KEY_FORMAT_TYPE_NOT_SUPPORTED) | |
199 | message = ResultMessage('') | |
200 | return GetResult(ResultStatus(ret_value), reason, message) | |
201 | if key_compression_type is not None: | |
202 | self.logger.debug('key compression type is not None') | |
203 | reason = ResultReason(ResultReasonEnum. | |
204 | KEY_COMPRESSION_TYPE_NOT_SUPPORTED) | |
205 | message = ResultMessage('') | |
206 | return GetResult(ResultStatus(ret_value), reason, message) | |
207 | if key_wrapping_specification is not None: | |
208 | self.logger.debug('key wrapping specification is not None') | |
209 | reason = ResultReason(ResultReasonEnum.FEATURE_NOT_SUPPORTED) | |
210 | message = ResultMessage('key wrapping is not currently supported') | |
211 | return GetResult(ResultStatus(ret_value), reason, message) | |
212 | ||
213 | self.logger.debug('retrieving object from repo') | |
214 | managed_object, _ = self.repo.get(uuid.value) | |
215 | ||
216 | if managed_object is None: | |
217 | self.logger.debug('object not found in repo') | |
218 | reason = ResultReason(ResultReasonEnum.ITEM_NOT_FOUND) | |
219 | message = ResultMessage('') | |
220 | return GetResult(ResultStatus(ret_value), reason, message) | |
221 | ||
222 | # currently only symmetric keys are supported, fix this in future | |
223 | object_type = ObjectType(OT.SYMMETRIC_KEY) | |
224 | ret_value = RS.SUCCESS | |
225 | return GetResult(ResultStatus(ret_value), | |
226 | object_type=object_type, | |
227 | uuid=uuid, | |
228 | secret=managed_object) | |
229 | ||
230 | def destroy(self, uuid): | |
231 | self.logger.debug('destroy() called') | |
232 | ret_value = RS.OPERATION_FAILED | |
233 | if uuid is None or not hasattr(uuid, 'value'): | |
234 | self.logger.debug('no uuid provided') | |
235 | reason = ResultReason(ResultReasonEnum.ITEM_NOT_FOUND) | |
236 | message = ResultMessage('') | |
237 | return DestroyResult(ResultStatus(ret_value), reason, message) | |
238 | ||
239 | msg = 'deleting object from repo: {0}'.format(uuid) | |
240 | self.logger.debug(msg) | |
241 | if not self.repo.delete(uuid.value): | |
242 | self.logger.debug('repo did not find and delete managed object') | |
243 | reason = ResultReason(ResultReasonEnum.ITEM_NOT_FOUND) | |
244 | message = ResultMessage('') | |
245 | return DestroyResult(ResultStatus(ret_value), reason, message) | |
246 | ||
247 | ret_value = RS.SUCCESS | |
248 | return DestroyResult(ResultStatus(ret_value), uuid=uuid) | |
249 | ||
250 | def _validate_req_field(self, attrs, name, expected, msg, required=True): | |
251 | self.logger.debug('Validating attribute %s' % name) | |
252 | seen = False | |
253 | found_attr = None | |
254 | for attr in attrs: | |
255 | if self._validate_field(attr, name, expected, msg): | |
256 | if seen: | |
257 | # TODO check what spec says to do on this | |
258 | msg = 'duplicate attribute: %s' % name | |
259 | self.logger.debug(msg) | |
260 | result = self._get_duplicate_attribute_result(name) | |
261 | raise InvalidFieldException(result) | |
262 | seen = True | |
263 | found_attr = attr | |
264 | if required and not seen: | |
265 | result = self._get_missing_field_result(name) | |
266 | raise InvalidFieldException(result) | |
267 | return found_attr | |
268 | ||
269 | def _validate_field(self, attr, name, expected, msg): | |
270 | if attr.attribute_name.value == name: | |
271 | self.logger.debug('validating attribute %s' % name) | |
272 | if not expected or attr.attribute_value.value in expected: | |
273 | self.logger.debug('attribute validated') | |
274 | return True | |
275 | else: | |
276 | self.logger.debug('attribute not validated') | |
277 | result = self._get_invalid_field_result(msg) | |
278 | raise InvalidFieldException(result) | |
279 | else: | |
280 | return False | |
281 | ||
282 | def _get_invalid_field_result(self, msg): | |
283 | status = ResultStatus(RS.OPERATION_FAILED) | |
284 | reason = ResultReason(ResultReasonEnum.INVALID_FIELD) | |
285 | message = ResultMessage(msg) | |
286 | return OperationResult(status, reason, message) | |
287 | ||
288 | def _get_missing_field_result(self, name): | |
289 | msg = '%s not supplied' % name | |
290 | self.logger.debug(msg) | |
291 | status = ResultStatus(RS.OPERATION_FAILED) | |
292 | reason = ResultReason(ResultReasonEnum.ITEM_NOT_FOUND) | |
293 | message = ResultMessage(msg) | |
294 | return OperationResult(status, reason, message) | |
295 | ||
296 | def _get_duplicate_attribute_result(self, name): | |
297 | msg = '%s supplied multiple times' % name | |
298 | self.logger.debug(msg) | |
299 | status = ResultStatus(RS.OPERATION_FAILED) | |
300 | reason = ResultReason(ResultReasonEnum.INDEX_OUT_OF_BOUNDS) | |
301 | message = ResultMessage(msg) | |
302 | return OperationResult(status, reason, message) | |
303 | ||
304 | def _gen_symmetric_key(self, bit_length, crypto_alg): | |
305 | key_format_type = KeyBlock.KeyFormatType(KeyFormatTypeEnum.RAW) | |
306 | key_material = RawKey(bytearray(os.urandom(bit_length/8))) | |
307 | key_value = KeyValueStruct(key_format_type, key_material) | |
308 | crypto_length = CryptographicLength(bit_length) | |
309 | key_block = KeyBlock(key_format_type, None, key_value, crypto_alg, | |
310 | crypto_length, None) | |
311 | return SymmetricKey(key_block) | |
312 | ||
313 | def _save(self, key, attributes): | |
314 | s_uuid = self.repo.save(key, attributes) | |
315 | self.logger.debug('creating object with uuid = %s' % s_uuid) | |
316 | attribute_type = AT.UNIQUE_IDENTIFIER | |
317 | attribute = self.attribute_factory.create_attribute(attribute_type, | |
318 | s_uuid) | |
319 | attributes.append(attribute) | |
320 | # Calling update to also store the UUID | |
321 | self.repo.update(s_uuid, key, attributes) | |
322 | return s_uuid, attribute | |
323 | ||
324 | def _get_key_block_attributes(self, key_block): | |
325 | self.logger.debug('getting all key attributes from key block') | |
326 | attributes = [] | |
327 | if key_block.cryptographic_algorithm is not None: | |
328 | self.logger.debug('crypto_alg set on key block') | |
329 | self.logger.debug('adding crypto algorithm attribute') | |
330 | at = AT.CRYPTOGRAPHIC_ALGORITHM | |
331 | alg = key_block.cryptographic_algorithm.enum | |
332 | attributes.append(self.attribute_factory.create_attribute(at, alg)) | |
333 | if key_block.cryptographic_length is not None: | |
334 | self.logger.debug('crypto_length set on key block') | |
335 | self.logger.debug('adding crypto length attribute') | |
336 | at = AT.CRYPTOGRAPHIC_LENGTH | |
337 | len = key_block.cryptographic_length.value | |
338 | attributes.append(self.attribute_factory.create_attribute(at, len)) | |
339 | self.logger.debug('getting key value attributes') | |
340 | if key_block.key_wrapping_data is not None: | |
341 | self.logger.debug('no wrapping data so key value is struct') | |
342 | kv = key_block.key_value | |
343 | if isinstance(kv, KeyValue): | |
344 | kv = key_block.key_value | |
345 | if isinstance(kv, KeyValueStruct): | |
346 | if kv.attributes is not None: | |
347 | self.logger.debug('adding the key value struct attributes') | |
348 | attributes.extend(kv.attributes) | |
349 | return attributes | |
350 | ||
351 | ||
352 | class InvalidFieldException(Exception): | |
353 | ||
354 | def __init__(self, result): | |
355 | super(self.__class__, self).__init__() | |
356 | self.result = result |
0 | # Copyright (c) 2014 The Johns Hopkins University/Applied Physics Laboratory | |
1 | # All Rights Reserved. | |
2 | # | |
3 | # Licensed under the Apache License, Version 2.0 (the "License"); you may | |
4 | # not use this file except in compliance with the License. You may obtain | |
5 | # a copy of the License at | |
6 | # | |
7 | # http://www.apache.org/licenses/LICENSE-2.0 | |
8 | # | |
9 | # Unless required by applicable law or agreed to in writing, software | |
10 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT | |
11 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the | |
12 | # License for the specific language governing permissions and limitations | |
13 | # under the License. | |
14 | ||
15 | from binascii import hexlify | |
16 | ||
17 | from kmip.core.errors import ErrorStrings | |
18 | ||
19 | ||
20 | def bit_length(num): | |
21 | s = bin(num) | |
22 | s = s.lstrip('0b') | |
23 | return len(s) | |
24 | ||
25 | ||
26 | def count_bytes(num): | |
27 | bits = bit_length(num) | |
28 | num_bytes = bits / 8 | |
29 | if bits == 0 or bits % 8: | |
30 | num_bytes += 1 | |
31 | return num_bytes | |
32 | ||
33 | ||
34 | def print_bytearray(array): | |
35 | sbuffer = hexlify_bytearray(array) | |
36 | print 'buffer: {0}'.format(sbuffer) | |
37 | ||
38 | ||
39 | def hexlify_bytearray(array): | |
40 | sbuffer = bytes(array[0:]) | |
41 | return hexlify(sbuffer) | |
42 | ||
43 | ||
44 | def is_stream_empty(stream): | |
45 | if len(stream.peek(1)) > 0: | |
46 | return False | |
47 | else: | |
48 | return True | |
49 | ||
50 | ||
51 | def build_er_error(class_object, descriptor, expected, received, | |
52 | attribute=None): | |
53 | msg = ErrorStrings.BAD_EXP_RECV | |
54 | ||
55 | class_string = '' | |
56 | if attribute is None: | |
57 | class_string = '{0}'.format(class_object.__name__) | |
58 | else: | |
59 | class_string = '{0}.{1}'.format(class_object.__name__, attribute) | |
60 | ||
61 | return msg.format(class_string, descriptor, expected, received) | |
62 | ||
63 | ||
64 | class BytearrayStream(object): | |
65 | def __init__(self, data=None): | |
66 | if data is None: | |
67 | self.buffer = bytearray() | |
68 | else: | |
69 | self.buffer = bytearray(data) | |
70 | ||
71 | def read(self, n=None): | |
72 | if n is None: | |
73 | return str(self.buffer[0:]) | |
74 | ||
75 | length = len(self.buffer) | |
76 | if n > length: | |
77 | n = length | |
78 | ||
79 | data = self.buffer[0:n] | |
80 | for _ in xrange(n): | |
81 | self.buffer.pop(0) | |
82 | return str(data) | |
83 | ||
84 | def peek(self, n=None): | |
85 | length = len(self.buffer) | |
86 | if n is None or n > length: | |
87 | n = length | |
88 | return str(self.buffer[0:n]) | |
89 | ||
90 | def write(self, b): | |
91 | prev_bytes = len(self.buffer) | |
92 | self.buffer.extend(b) | |
93 | return len(self.buffer) - prev_bytes | |
94 | ||
95 | def length(self): | |
96 | return len(self.buffer) |
0 | # Copyright (c) 2014 The Johns Hopkins University/Applied Physics Laboratory | |
1 | # All Rights Reserved. | |
2 | # | |
3 | # Licensed under the Apache License, Version 2.0 (the "License"); you may | |
4 | # not use this file except in compliance with the License. You may obtain | |
5 | # a copy of the License at | |
6 | # | |
7 | # http://www.apache.org/licenses/LICENSE-2.0 | |
8 | # | |
9 | # Unless required by applicable law or agreed to in writing, software | |
10 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT | |
11 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the | |
12 | # License for the specific language governing permissions and limitations | |
13 | # under the License. |
0 | # Copyright (c) 2014 The Johns Hopkins University/Applied Physics Laboratory | |
1 | # All Rights Reserved. | |
2 | # | |
3 | # Licensed under the Apache License, Version 2.0 (the "License"); you may | |
4 | # not use this file except in compliance with the License. You may obtain | |
5 | # a copy of the License at | |
6 | # | |
7 | # http://www.apache.org/licenses/LICENSE-2.0 | |
8 | # | |
9 | # Unless required by applicable law or agreed to in writing, software | |
10 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT | |
11 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the | |
12 | # License for the specific language governing permissions and limitations | |
13 | # under the License. | |
14 | ||
15 | from kmip.core.enums import AttributeType | |
16 | from kmip.core.enums import CredentialType | |
17 | from kmip.core.enums import ObjectType | |
18 | from kmip.core.enums import CryptographicAlgorithm | |
19 | from kmip.core.enums import CryptographicUsageMask | |
20 | ||
21 | from kmip.core.factories.attributes import AttributeFactory | |
22 | from kmip.core.factories.credentials import CredentialFactory | |
23 | ||
24 | from kmip.core.objects import TemplateAttribute | |
25 | ||
26 | from kmip.services.kmip_client import KMIPProxy | |
27 | ||
28 | import logging | |
29 | import os | |
30 | ||
31 | if __name__ == '__main__': | |
32 | f_log = os.path.join(os.path.dirname(__file__), '..', 'logconfig.ini') | |
33 | logging.config.fileConfig(f_log) | |
34 | logger = logging.getLogger(__name__) | |
35 | ||
36 | attribute_factory = AttributeFactory() | |
37 | credential_factory = CredentialFactory() | |
38 | ||
39 | credential_type = CredentialType.USERNAME_AND_PASSWORD | |
40 | credential_value = {'Username': 'Peter', 'Password': 'abc123'} | |
41 | credential = credential_factory.create_credential(credential_type, | |
42 | credential_value) | |
43 | ||
44 | client = KMIPProxy() | |
45 | client.open() | |
46 | ||
47 | object_type = ObjectType.SYMMETRIC_KEY | |
48 | attribute_type = AttributeType.CRYPTOGRAPHIC_ALGORITHM | |
49 | algorithm = attribute_factory.create_attribute(attribute_type, | |
50 | CryptographicAlgorithm.AES) | |
51 | mask_flags = [CryptographicUsageMask.ENCRYPT, | |
52 | CryptographicUsageMask.DECRYPT] | |
53 | attribute_type = AttributeType.CRYPTOGRAPHIC_USAGE_MASK | |
54 | usage_mask = attribute_factory.create_attribute(attribute_type, | |
55 | mask_flags) | |
56 | attributes = [algorithm, usage_mask] | |
57 | template_attribute = TemplateAttribute(attributes=attributes) | |
58 | ||
59 | result = client.create(object_type, template_attribute, | |
60 | credential) | |
61 | client.close() | |
62 | ||
63 | logger.debug('create() result status: {}'.format( | |
64 | result.result_status.enum)) | |
65 | logger.debug('created object type: {}'.format(result.object_type.enum)) | |
66 | logger.debug('created UUID: {}'.format(result.uuid.value)) | |
67 | logger.debug('created template attribute: {}'. | |
68 | format(result.template_attribute)) |
0 | # Copyright (c) 2014 The Johns Hopkins University/Applied Physics Laboratory | |
1 | # All Rights Reserved. | |
2 | # | |
3 | # Licensed under the Apache License, Version 2.0 (the "License"); you may | |
4 | # not use this file except in compliance with the License. You may obtain | |
5 | # a copy of the License at | |
6 | # | |
7 | # http://www.apache.org/licenses/LICENSE-2.0 | |
8 | # | |
9 | # Unless required by applicable law or agreed to in writing, software | |
10 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT | |
11 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the | |
12 | # License for the specific language governing permissions and limitations | |
13 | # under the License. | |
14 | ||
15 | from kmip.core.enums import AttributeType | |
16 | from kmip.core.enums import CredentialType | |
17 | from kmip.core.enums import ObjectType | |
18 | from kmip.core.enums import CryptographicAlgorithm | |
19 | from kmip.core.enums import CryptographicUsageMask | |
20 | ||
21 | from kmip.core.factories.attributes import AttributeFactory | |
22 | from kmip.core.factories.credentials import CredentialFactory | |
23 | ||
24 | from kmip.core.objects import TemplateAttribute | |
25 | ||
26 | from kmip.services.kmip_client import KMIPProxy | |
27 | ||
28 | import logging | |
29 | import os | |
30 | ||
31 | if __name__ == '__main__': | |
32 | f_log = os.path.join(os.path.dirname(__file__), '..', 'logconfig.ini') | |
33 | logging.config.fileConfig(f_log) | |
34 | logger = logging.getLogger(__name__) | |
35 | ||
36 | attribute_factory = AttributeFactory() | |
37 | credential_factory = CredentialFactory() | |
38 | ||
39 | credential_type = CredentialType.USERNAME_AND_PASSWORD | |
40 | credential_value = {'Username': 'Peter', 'Password': 'abc123'} | |
41 | credential = credential_factory.create_credential(credential_type, | |
42 | credential_value) | |
43 | client = KMIPProxy() | |
44 | client.open() | |
45 | ||
46 | # Create a SYMMETRIC_KEY object | |
47 | object_type = ObjectType.SYMMETRIC_KEY | |
48 | attribute_type = AttributeType.CRYPTOGRAPHIC_ALGORITHM | |
49 | algorithm = attribute_factory.create_attribute(attribute_type, | |
50 | CryptographicAlgorithm.AES) | |
51 | mask_flags = [CryptographicUsageMask.ENCRYPT, | |
52 | CryptographicUsageMask.DECRYPT] | |
53 | attribute_type = AttributeType.CRYPTOGRAPHIC_USAGE_MASK | |
54 | usage_mask = attribute_factory.create_attribute(attribute_type, | |
55 | mask_flags) | |
56 | attributes = [algorithm, usage_mask] | |
57 | template_attribute = TemplateAttribute(attributes=attributes) | |
58 | ||
59 | result = client.create(object_type, template_attribute, | |
60 | credential) | |
61 | uuid = result.uuid.value | |
62 | ||
63 | # Destroy the SYMMETRIC_KEY object | |
64 | result = client.destroy(uuid, credential) | |
65 | client.close() | |
66 | ||
67 | logger.debug('destroy() result status: {}'.format( | |
68 | result.result_status.enum)) | |
69 | logger.debug('destroyed UUID: {}'.format(result.uuid.value)) |
0 | # Copyright (c) 2014 The Johns Hopkins University/Applied Physics Laboratory | |
1 | # All Rights Reserved. | |
2 | # | |
3 | # Licensed under the Apache License, Version 2.0 (the "License"); you may | |
4 | # not use this file except in compliance with the License. You may obtain | |
5 | # a copy of the License at | |
6 | # | |
7 | # http://www.apache.org/licenses/LICENSE-2.0 | |
8 | # | |
9 | # Unless required by applicable law or agreed to in writing, software | |
10 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT | |
11 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the | |
12 | # License for the specific language governing permissions and limitations | |
13 | # under the License. | |
14 | ||
15 | from kmip.core.enums import AttributeType | |
16 | from kmip.core.enums import CredentialType | |
17 | from kmip.core.enums import ObjectType | |
18 | from kmip.core.enums import CryptographicAlgorithm | |
19 | from kmip.core.enums import CryptographicUsageMask | |
20 | ||
21 | from kmip.core.factories.attributes import AttributeFactory | |
22 | from kmip.core.factories.credentials import CredentialFactory | |
23 | ||
24 | from kmip.core.objects import TemplateAttribute | |
25 | ||
26 | from kmip.services.kmip_client import KMIPProxy | |
27 | ||
28 | import logging | |
29 | import os | |
30 | ||
31 | if __name__ == '__main__': | |
32 | f_log = os.path.join(os.path.dirname(__file__), '..', 'logconfig.ini') | |
33 | logging.config.fileConfig(f_log) | |
34 | logger = logging.getLogger(__name__) | |
35 | ||
36 | attribute_factory = AttributeFactory() | |
37 | credential_factory = CredentialFactory() | |
38 | ||
39 | credential_type = CredentialType.USERNAME_AND_PASSWORD | |
40 | credential_value = {'Username': 'Peter', 'Password': 'abc123'} | |
41 | credential = credential_factory.create_credential(credential_type, | |
42 | credential_value) | |
43 | client = KMIPProxy() | |
44 | client.open() | |
45 | ||
46 | object_type = ObjectType.SYMMETRIC_KEY | |
47 | attribute_type = AttributeType.CRYPTOGRAPHIC_ALGORITHM | |
48 | algorithm = attribute_factory.create_attribute(attribute_type, | |
49 | CryptographicAlgorithm.AES) | |
50 | mask_flags = [CryptographicUsageMask.ENCRYPT, | |
51 | CryptographicUsageMask.DECRYPT] | |
52 | attribute_type = AttributeType.CRYPTOGRAPHIC_USAGE_MASK | |
53 | usage_mask = attribute_factory.create_attribute(attribute_type, | |
54 | mask_flags) | |
55 | attributes = [algorithm, usage_mask] | |
56 | template_attribute = TemplateAttribute(attributes=attributes) | |
57 | ||
58 | result = client.create(object_type, template_attribute, | |
59 | credential) | |
60 | uuid = result.uuid.value | |
61 | ||
62 | result = client.get(uuid, credential) | |
63 | client.close() | |
64 | ||
65 | logger.debug('get() result status: {}'.format(result.result_status.enum)) | |
66 | logger.debug('retrieved object type: {}'.format(result.object_type.enum)) | |
67 | logger.debug('retrieved UUID: {}'.format(result.uuid.value)) | |
68 | logger.debug('retrieved secret: {}'.format(result.secret)) |
0 | # Copyright (c) 2014 The Johns Hopkins University/Applied Physics Laboratory | |
1 | # All Rights Reserved. | |
2 | # | |
3 | # Licensed under the Apache License, Version 2.0 (the "License"); you may | |
4 | # not use this file except in compliance with the License. You may obtain | |
5 | # a copy of the License at | |
6 | # | |
7 | # http://www.apache.org/licenses/LICENSE-2.0 | |
8 | # | |
9 | # Unless required by applicable law or agreed to in writing, software | |
10 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT | |
11 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the | |
12 | # License for the specific language governing permissions and limitations | |
13 | # under the License. | |
14 | ||
15 | from kmip.core.enums import AttributeType | |
16 | from kmip.core.enums import CredentialType | |
17 | from kmip.core.enums import CryptographicAlgorithm | |
18 | from kmip.core.enums import CryptographicUsageMask | |
19 | from kmip.core.enums import KeyFormatType | |
20 | from kmip.core.enums import ObjectType | |
21 | ||
22 | from kmip.core.factories.attributes import AttributeFactory | |
23 | from kmip.core.factories.credentials import CredentialFactory | |
24 | from kmip.core.factories.secrets import SecretFactory | |
25 | ||
26 | from kmip.core.objects import TemplateAttribute | |
27 | ||
28 | from kmip.services.kmip_client import KMIPProxy | |
29 | ||
30 | import logging | |
31 | import os | |
32 | ||
33 | if __name__ == '__main__': | |
34 | f_log = os.path.join(os.path.dirname(__file__), '..', 'logconfig.ini') | |
35 | logging.config.fileConfig(f_log) | |
36 | logger = logging.getLogger(__name__) | |
37 | ||
38 | attribute_factory = AttributeFactory() | |
39 | credential_factory = CredentialFactory() | |
40 | secret_factory = SecretFactory() | |
41 | ||
42 | credential_type = CredentialType.USERNAME_AND_PASSWORD | |
43 | credential_value = {'Username': 'Peter', 'Password': 'abc123'} | |
44 | credential = credential_factory.create_credential(credential_type, | |
45 | credential_value) | |
46 | client = KMIPProxy() | |
47 | client.open() | |
48 | ||
49 | object_type = ObjectType.SYMMETRIC_KEY | |
50 | algorithm_value = CryptographicAlgorithm.AES | |
51 | ||
52 | mask_flags = [CryptographicUsageMask.ENCRYPT, | |
53 | CryptographicUsageMask.DECRYPT] | |
54 | attribute_type = AttributeType.CRYPTOGRAPHIC_USAGE_MASK | |
55 | usage_mask = attribute_factory.create_attribute(attribute_type, | |
56 | mask_flags) | |
57 | attributes = [usage_mask] | |
58 | template_attribute = TemplateAttribute(attributes=attributes) | |
59 | ||
60 | secret_features = {} | |
61 | ||
62 | key_format_type = KeyFormatType.RAW | |
63 | secret_features.update([('key_format_type', key_format_type)]) | |
64 | ||
65 | # TODO (peter-hamilton) Replace with calls to crypto libraries | |
66 | key_data = {'bytes': bytearray('\x00\x00\x00\x00\x00\x00\x00\x00' | |
67 | '\x00\x00\x00\x00\x00\x00\x00\x00')} | |
68 | ||
69 | secret_features.update([('key_value', key_data)]) | |
70 | secret_features.update([('cryptographic_algorithm', algorithm_value)]) | |
71 | secret_features.update([('cryptographic_length', 128)]) | |
72 | ||
73 | secret = secret_factory.create_secret(object_type, secret_features) | |
74 | ||
75 | result = client.register(object_type, template_attribute, secret, | |
76 | credential) | |
77 | client.close() | |
78 | ||
79 | logger.debug('register() result status: {}'.format( | |
80 | result.result_status.enum)) | |
81 | logger.debug('registered UUID: {}'.format(result.uuid.value)) | |
82 | logger.debug('registered template attribute: {}'. | |
83 | format(result.template_attribute)) |
0 | #!/usr/bin/env python | |
1 | ||
2 | # TODO insert license here | |
3 | ||
4 | from transport.kmip import KMIP | |
5 | from transport.kmip.ttypes import * | |
6 | ||
7 | from thrift import Thrift | |
8 | from thrift.transport import TSocket | |
9 | from thrift.transport import TTransport | |
10 | from thrift.protocol import TBinaryProtocol | |
11 | ||
12 | try: | |
13 | ||
14 | transport = TSocket.TSocket('localhost', 9090) | |
15 | transport = TTransport.TBufferedTransport(transport) | |
16 | protocol = TBinaryProtocol.TBinaryProtocol(transport) | |
17 | client = KMIP.Client(protocol) | |
18 | transport.open() | |
19 | ||
20 | print 'ping-client()' | |
21 | client.create() | |
22 | print 'register_mo-client()' | |
23 | client.register_mo() | |
24 | ||
25 | transport.close() | |
26 | ||
27 | except Thrift.TException, tx: | |
28 | print '%s' % (tx.message) |
0 | #!/usr/bin/env python | |
1 | ||
2 | # TODO insert license here | |
3 | ||
4 | from transport.kmip import KMIP | |
5 | from transport.kmip.ttypes import * | |
6 | ||
7 | from thrift.transport import TSocket | |
8 | from thrift.transport import TTransport | |
9 | from thrift.protocol import TBinaryProtocol | |
10 | from thrift.server import TServer | |
11 | ||
12 | class KMIPHandler: | |
13 | def __init__(self): | |
14 | pass | |
15 | ||
16 | def create(self): | |
17 | print 'create()' | |
18 | ||
19 | def register_mo(self): | |
20 | print 'register_mo()' | |
21 | ||
22 | handler = KMIPHandler() | |
23 | processor = KMIP.Processor(handler) | |
24 | transport = TSocket.TServerSocket(port=9090) | |
25 | tfactory = TTransport.TBufferedTransportFactory() | |
26 | pfactory = TBinaryProtocol.TBinaryProtocolFactory() | |
27 | server = TServer.TSimpleServer(processor, transport, tfactory, pfactory) | |
28 | ||
29 | print 'Starting the KMIP server...' | |
30 | server.serve() | |
31 | print 'done.' |
0 | [loggers] | |
1 | keys=root | |
2 | ||
3 | [handlers] | |
4 | keys=consoleHandler | |
5 | ||
6 | [formatters] | |
7 | keys=simpleFormatter | |
8 | ||
9 | [logger_root] | |
10 | level=DEBUG | |
11 | handlers=consoleHandler | |
12 | ||
13 | [handler_consoleHandler] | |
14 | class=StreamHandler | |
15 | level=DEBUG | |
16 | formatter=simpleFormatter | |
17 | args=(sys.stdout,) | |
18 | ||
19 | [formatter_simpleFormatter] | |
20 | format=%(asctime)s - %(name)s - %(levelname)s - %(message)s⏎ |
0 | # Copyright (c) 2014 The Johns Hopkins University/Applied Physics Laboratory | |
1 | # All Rights Reserved. | |
2 | # | |
3 | # Licensed under the Apache License, Version 2.0 (the "License"); you may | |
4 | # not use this file except in compliance with the License. You may obtain | |
5 | # a copy of the License at | |
6 | # | |
7 | # http://www.apache.org/licenses/LICENSE-2.0 | |
8 | # | |
9 | # Unless required by applicable law or agreed to in writing, software | |
10 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT | |
11 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the | |
12 | # License for the specific language governing permissions and limitations | |
13 | # under the License. |
0 | # Copyright (c) 2014 The Johns Hopkins University/Applied Physics Laboratory | |
1 | # All Rights Reserved. | |
2 | # | |
3 | # Licensed under the Apache License, Version 2.0 (the "License"); you may | |
4 | # not use this file except in compliance with the License. You may obtain | |
5 | # a copy of the License at | |
6 | # | |
7 | # http://www.apache.org/licenses/LICENSE-2.0 | |
8 | # | |
9 | # Unless required by applicable law or agreed to in writing, software | |
10 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT | |
11 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the | |
12 | # License for the specific language governing permissions and limitations | |
13 | # under the License. | |
14 | ||
15 | from kmip.services.results import CreateResult | |
16 | from kmip.services.results import GetResult | |
17 | from kmip.services.results import DestroyResult | |
18 | from kmip.services.results import RegisterResult | |
19 | ||
20 | from kmip.core import attributes as attr | |
21 | ||
22 | from kmip.core.enums import Operation as OperationEnum | |
23 | ||
24 | from kmip.core import objects | |
25 | from kmip.core.server import KMIP | |
26 | ||
27 | from kmip.core.messages.contents import Authentication | |
28 | from kmip.core.messages.contents import BatchCount | |
29 | from kmip.core.messages.contents import ProtocolVersion | |
30 | from kmip.core.messages.contents import Operation | |
31 | ||
32 | from kmip.core.messages import messages | |
33 | from kmip.core.messages import operations | |
34 | ||
35 | from kmip.services.kmip_protocol import KMIPProtocol | |
36 | ||
37 | from kmip.core.utils import BytearrayStream | |
38 | ||
39 | from thrift.transport import TSocket | |
40 | from thrift.transport import TTransport | |
41 | ||
42 | import logging | |
43 | import logging.config | |
44 | ||
45 | ||
46 | class KMIPProxy(KMIP): | |
47 | ||
48 | # TODO (peter-hamilton) Move these defaults into config | |
49 | def __init__(self, hostname='127.0.0.1', port=5696): | |
50 | super(self.__class__, self).__init__() | |
51 | self.logger = logging.getLogger(__name__) | |
52 | self.socket = TSocket.TSocket(hostname, port) | |
53 | self.transport = TTransport.TBufferedTransport(self.socket) | |
54 | self.protocol = KMIPProtocol(self.transport) | |
55 | ||
56 | def open(self): | |
57 | self.transport.open() | |
58 | ||
59 | def close(self): | |
60 | self.transport.close() | |
61 | ||
62 | def create(self, object_type, template_attribute, credential=None): | |
63 | object_type = attr.ObjectType(object_type) | |
64 | return self._create(object_type=object_type, | |
65 | template_attribute=template_attribute, | |
66 | credential=credential) | |
67 | ||
68 | def get(self, uuid=None, key_format_type=None, key_compression_type=None, | |
69 | key_wrapping_specification=None, credential=None): | |
70 | return self._get(unique_identifier=uuid, credential=credential) | |
71 | ||
72 | def destroy(self, uuid, credential=None): | |
73 | return self._destroy(unique_identifier=uuid, | |
74 | credential=credential) | |
75 | ||
76 | def register(self, object_type, template_attribute, secret, | |
77 | credential=None): | |
78 | object_type = attr.ObjectType(object_type) | |
79 | return self._register(object_type=object_type, | |
80 | template_attribute=template_attribute, | |
81 | secret=secret, | |
82 | credential=credential) | |
83 | ||
84 | def _create(self, | |
85 | object_type=None, | |
86 | template_attribute=None, | |
87 | credential=None): | |
88 | operation = Operation(OperationEnum.CREATE) | |
89 | ||
90 | if object_type is None: | |
91 | raise ValueError('object_type cannot be None') | |
92 | ||
93 | req_pl = operations.CreateRequestPayload( | |
94 | object_type=object_type, | |
95 | template_attribute=template_attribute) | |
96 | batch_item = messages.RequestBatchItem(operation=operation, | |
97 | request_payload=req_pl) | |
98 | ||
99 | message = self._build_request_message(credential, [batch_item]) | |
100 | self._send_message(message) | |
101 | message = messages.ResponseMessage() | |
102 | data = self._receive_message() | |
103 | message.read(data) | |
104 | batch_items = message.batch_items | |
105 | batch_item = batch_items[0] | |
106 | payload = batch_item.response_payload | |
107 | ||
108 | if payload is None: | |
109 | payload_unique_identifier = None | |
110 | payload_template_attribute = None | |
111 | payload_object_type = None | |
112 | else: | |
113 | payload_unique_identifier = payload.unique_identifier | |
114 | payload_template_attribute = payload.template_attribute | |
115 | payload_object_type = payload.object_type | |
116 | ||
117 | result = CreateResult(batch_item.result_status, | |
118 | batch_item.result_reason, | |
119 | batch_item.result_message, | |
120 | payload_object_type, | |
121 | payload_unique_identifier, | |
122 | payload_template_attribute) | |
123 | return result | |
124 | ||
125 | def _get(self, | |
126 | unique_identifier=None, | |
127 | key_format_type=None, | |
128 | key_compression_type=None, | |
129 | key_wrapping_specification=None, | |
130 | credential=None): | |
131 | operation = Operation(OperationEnum.GET) | |
132 | ||
133 | uuid = None | |
134 | kft = None | |
135 | kct = None | |
136 | kws = None | |
137 | ||
138 | if unique_identifier is not None: | |
139 | uuid = attr.UniqueIdentifier(unique_identifier) | |
140 | if key_format_type is not None: | |
141 | kft = operations.GetRequestPayload.KeyFormatType(key_format_type) | |
142 | if key_compression_type is not None: | |
143 | kct = key_compression_type | |
144 | kct = operations.GetRequestPayload.KeyCompressionType(kct) | |
145 | if key_wrapping_specification is not None: | |
146 | kws = objects.KeyWrappingSpecification(key_wrapping_specification) | |
147 | ||
148 | req_pl = operations.GetRequestPayload(unique_identifier=uuid, | |
149 | key_format_type=kft, | |
150 | key_compression_type=kct, | |
151 | key_wrapping_specification=kws) | |
152 | ||
153 | batch_item = messages.RequestBatchItem(operation=operation, | |
154 | request_payload=req_pl) | |
155 | message = self._build_request_message(credential, [batch_item]) | |
156 | self._send_message(message) | |
157 | message = messages.ResponseMessage() | |
158 | data = self._receive_message() | |
159 | message.read(data) | |
160 | batch_items = message.batch_items | |
161 | batch_item = batch_items[0] | |
162 | payload = batch_item.response_payload | |
163 | ||
164 | if payload is None: | |
165 | payload_unique_identifier = None | |
166 | payload_object_type = None | |
167 | payload_secret = None | |
168 | else: | |
169 | payload_unique_identifier = payload.unique_identifier | |
170 | payload_object_type = payload.object_type | |
171 | payload_secret = payload.secret | |
172 | ||
173 | result = GetResult(batch_item.result_status, | |
174 | batch_item.result_reason, | |
175 | batch_item.result_message, | |
176 | payload_object_type, | |
177 | payload_unique_identifier, | |
178 | payload_secret) | |
179 | return result | |
180 | ||
181 | def _destroy(self, | |
182 | unique_identifier=None, | |
183 | credential=None): | |
184 | operation = Operation(OperationEnum.DESTROY) | |
185 | ||
186 | uuid = None | |
187 | if unique_identifier is not None: | |
188 | uuid = attr.UniqueIdentifier(unique_identifier) | |
189 | ||
190 | payload = operations.DestroyRequestPayload(unique_identifier=uuid) | |
191 | ||
192 | batch_item = messages.RequestBatchItem(operation=operation, | |
193 | request_payload=payload) | |
194 | message = self._build_request_message(credential, [batch_item]) | |
195 | self._send_message(message) | |
196 | message = messages.ResponseMessage() | |
197 | data = self._receive_message() | |
198 | message.read(data) | |
199 | batch_items = message.batch_items | |
200 | batch_item = batch_items[0] | |
201 | payload = batch_item.response_payload | |
202 | ||
203 | if payload is None: | |
204 | payload_unique_identifier = None | |
205 | else: | |
206 | payload_unique_identifier = payload.unique_identifier | |
207 | ||
208 | result = DestroyResult(batch_item.result_status, | |
209 | batch_item.result_reason, | |
210 | batch_item.result_message, | |
211 | payload_unique_identifier) | |
212 | return result | |
213 | ||
214 | def _register(self, | |
215 | object_type=None, | |
216 | template_attribute=None, | |
217 | secret=None, | |
218 | credential=None): | |
219 | operation = Operation(OperationEnum.REGISTER) | |
220 | ||
221 | if object_type is None: | |
222 | raise ValueError('object_type cannot be None') | |
223 | ||
224 | req_pl = operations.RegisterRequestPayload( | |
225 | object_type=object_type, | |
226 | template_attribute=template_attribute, | |
227 | secret=secret) | |
228 | batch_item = messages.RequestBatchItem(operation=operation, | |
229 | request_payload=req_pl) | |
230 | ||
231 | message = self._build_request_message(credential, [batch_item]) | |
232 | self._send_message(message) | |
233 | message = messages.ResponseMessage() | |
234 | data = self._receive_message() | |
235 | message.read(data) | |
236 | batch_items = message.batch_items | |
237 | batch_item = batch_items[0] | |
238 | payload = batch_item.response_payload | |
239 | ||
240 | if payload is None: | |
241 | payload_unique_identifier = None | |
242 | payload_template_attribute = None | |
243 | else: | |
244 | payload_unique_identifier = payload.unique_identifier | |
245 | payload_template_attribute = payload.template_attribute | |
246 | ||
247 | result = RegisterResult(batch_item.result_status, | |
248 | batch_item.result_reason, | |
249 | batch_item.result_message, | |
250 | payload_unique_identifier, | |
251 | payload_template_attribute) | |
252 | return result | |
253 | ||
254 | def _build_request_message(self, credential, batch_items): | |
255 | protocol_version = ProtocolVersion.create(1, 1) | |
256 | ||
257 | authentication = None | |
258 | if credential is not None: | |
259 | authentication = Authentication(credential) | |
260 | ||
261 | batch_count = BatchCount(len(batch_items)) | |
262 | req_header = messages.RequestHeader(protocol_version=protocol_version, | |
263 | authentication=authentication, | |
264 | batch_count=batch_count) | |
265 | ||
266 | return messages.RequestMessage(request_header=req_header, | |
267 | batch_items=batch_items) | |
268 | ||
269 | def _send_message(self, message): | |
270 | stream = BytearrayStream() | |
271 | message.write(stream) | |
272 | self.protocol.write(stream.buffer) | |
273 | ||
274 | def _receive_message(self): | |
275 | return self.protocol.read() |
0 | # Copyright (c) 2014 The Johns Hopkins University/Applied Physics Laboratory | |
1 | # All Rights Reserved. | |
2 | # | |
3 | # Licensed under the Apache License, Version 2.0 (the "License"); you may | |
4 | # not use this file except in compliance with the License. You may obtain | |
5 | # a copy of the License at | |
6 | # | |
7 | # http://www.apache.org/licenses/LICENSE-2.0 | |
8 | # | |
9 | # Unless required by applicable law or agreed to in writing, software | |
10 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT | |
11 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the | |
12 | # License for the specific language governing permissions and limitations | |
13 | # under the License. | |
14 | ||
15 | from struct import unpack | |
16 | ||
17 | from thrift.protocol.TProtocol import TProtocolBase | |
18 | ||
19 | import binascii | |
20 | import logging | |
21 | ||
22 | from kmip.core.utils import BytearrayStream | |
23 | ||
24 | ||
25 | class KMIPProtocol(TProtocolBase): | |
26 | HEADER_SIZE = 8 | |
27 | ||
28 | def __init__(self, trans, buffer_size=1024): | |
29 | TProtocolBase.__init__(self, trans) | |
30 | self.logger = logging.getLogger(__name__) | |
31 | ||
32 | def write(self, data): | |
33 | if len(data) > 0: | |
34 | sbuffer = bytes(data) | |
35 | self.logger.debug('buffer: {0}'.format(binascii.hexlify(sbuffer))) | |
36 | self.trans.write(sbuffer) | |
37 | self.trans.flush() | |
38 | ||
39 | def read(self): | |
40 | header = self.trans.readAll(self.HEADER_SIZE) | |
41 | msg_size = unpack('!I', header[4:])[0] | |
42 | payload = self.trans.readAll(msg_size) | |
43 | return BytearrayStream(header + payload) | |
44 | ||
45 | ||
46 | class KMIPProtocolFactory(object): | |
47 | ||
48 | def getProtocol(self, trans): | |
49 | return KMIPProtocol(trans) |
0 | # Copyright (c) 2014 The Johns Hopkins University/Applied Physics Laboratory | |
1 | # All Rights Reserved. | |
2 | # | |
3 | # Licensed under the Apache License, Version 2.0 (the "License"); you may | |
4 | # not use this file except in compliance with the License. You may obtain | |
5 | # a copy of the License at | |
6 | # | |
7 | # http://www.apache.org/licenses/LICENSE-2.0 | |
8 | # | |
9 | # Unless required by applicable law or agreed to in writing, software | |
10 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT | |
11 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the | |
12 | # License for the specific language governing permissions and limitations | |
13 | # under the License. | |
14 | ||
15 | import time | |
16 | ||
17 | from thrift.Thrift import TProcessor | |
18 | ||
19 | from kmip.core.messages.messages import RequestMessage | |
20 | from kmip.core.messages.messages import ResponseMessage | |
21 | from kmip.core.messages.messages import ResponseBatchItem | |
22 | from kmip.core.messages.messages import ResponseHeader | |
23 | ||
24 | from kmip.core.messages.contents import AsynchronousIndicator | |
25 | from kmip.core.messages.contents import BatchErrorContinuationOption | |
26 | from kmip.core.messages.contents import BatchCount | |
27 | from kmip.core.messages.contents import TimeStamp | |
28 | ||
29 | from kmip.core.primitives import Base | |
30 | ||
31 | from kmip.core.messages.operations import CreateResponsePayload | |
32 | from kmip.core.messages.operations import GetResponsePayload | |
33 | from kmip.core.messages.operations import DestroyResponsePayload | |
34 | from kmip.core.messages.operations import RegisterResponsePayload | |
35 | ||
36 | from kmip.core.enums import Operation | |
37 | from kmip.core.enums import ResultStatus as RS | |
38 | from kmip.core.enums import Tags | |
39 | from kmip.core.enums import BatchErrorContinuationOption as BECO | |
40 | ||
41 | from kmip.core.utils import BytearrayStream | |
42 | ||
43 | ||
44 | class Processor(TProcessor): | |
45 | def __init__(self, handler): | |
46 | self._handler = handler | |
47 | ||
48 | def process(self, istream, ostream): | |
49 | stream = istream.read() | |
50 | ||
51 | if Base.is_tag_next(Tags.REQUEST_MESSAGE, stream): | |
52 | message = RequestMessage() | |
53 | message.read(stream) | |
54 | result = self._process_request(message) | |
55 | tstream = BytearrayStream() | |
56 | result.write(tstream) | |
57 | ostream.write(tstream.buffer) | |
58 | elif Base.is_tag_next(Tags.RESPONSE_MESSAGE, stream): | |
59 | message = ResponseMessage() | |
60 | message.read(stream) | |
61 | self._process_response(message) | |
62 | else: | |
63 | raise ValueError('Processing error: stream contains unknown' | |
64 | 'message type') | |
65 | ||
66 | def _process_request(self, message): | |
67 | header = message.request_header | |
68 | ||
69 | protocol_version = header.protocol_version | |
70 | # maximum_response_size = header.maximum_response_size | |
71 | asynchronous_indicator = header.asynchronous_indicator | |
72 | # authentication = header.authentication | |
73 | batch_error_cont_option = header.batch_error_cont_option | |
74 | # batch_order_option = header.batch_order_option | |
75 | # time_stamp = header.time_stamp | |
76 | request_batch_count = header.batch_count.value | |
77 | ||
78 | # TODO (peter-hamilton) Log receipt of message with time stamp | |
79 | ||
80 | if asynchronous_indicator is None: | |
81 | asynchronous_indicator = AsynchronousIndicator(False) | |
82 | ||
83 | if batch_error_cont_option is None: | |
84 | batch_error_cont_option = BatchErrorContinuationOption(BECO.STOP) | |
85 | ||
86 | request_batch_items = message.batch_items | |
87 | response_batch_items = [] | |
88 | ||
89 | for i in xrange(request_batch_count): | |
90 | request_batch_item = request_batch_items[i] | |
91 | failure_occurred = False | |
92 | ||
93 | operation = request_batch_item.operation | |
94 | ubi_id = request_batch_item.unique_batch_item_id | |
95 | payload = request_batch_item.request_payload | |
96 | message_extension = request_batch_item.message_extension | |
97 | ||
98 | result = self._process_operation(operation, payload) | |
99 | ||
100 | result_status = result[0] | |
101 | result_reason = result[1] | |
102 | result_message = result[2] | |
103 | asyn_cv = None | |
104 | response_payload = None | |
105 | message_extension = None | |
106 | ||
107 | if result_status.enum is RS.SUCCESS: | |
108 | response_payload = result[3] | |
109 | elif result_status.enum is RS.OPERATION_FAILED: | |
110 | failure_occurred = True | |
111 | result_reason = result[1] | |
112 | elif result_status.enum is RS.OPERATION_PENDING: | |
113 | # TODO (peter-hamilton) Need to add a way to track async | |
114 | # TODO (peter-hamilton) operations. | |
115 | asyn_cv = '\x00' | |
116 | elif result_status.enum is RS.OPERATION_UNDONE: | |
117 | result_reason = result[1] | |
118 | else: | |
119 | msg = 'Unrecognized operation result status: {}' | |
120 | raise RuntimeError(msg.format(result_status)) | |
121 | ||
122 | resp_bi = ResponseBatchItem(operation=operation, | |
123 | unique_batch_item_id=ubi_id, | |
124 | result_status=result_status, | |
125 | result_reason=result_reason, | |
126 | result_message=result_message, | |
127 | async_correlation_value=asyn_cv, | |
128 | response_payload=response_payload, | |
129 | message_extension=message_extension) | |
130 | response_batch_items.append(resp_bi) | |
131 | ||
132 | if failure_occurred: | |
133 | if batch_error_cont_option.enum is BECO.STOP: | |
134 | break | |
135 | elif batch_error_cont_option.enum is BECO.UNDO: | |
136 | # TODO (peter-hamilton) Tell client to undo operations. | |
137 | # TODO (peter-hamilton) Unclear what response should be. | |
138 | break | |
139 | elif batch_error_cont_option.enum is BECO.CONTINUE: | |
140 | continue | |
141 | else: | |
142 | msg = 'Unrecognized batch error continuation option: {}' | |
143 | raise RuntimeError(msg.format(batch_error_cont_option)) | |
144 | ||
145 | response_batch_count = BatchCount(len(response_batch_items)) | |
146 | response_time_stamp = TimeStamp(int(time.time())) | |
147 | response_header = ResponseHeader(protocol_version=protocol_version, | |
148 | time_stamp=response_time_stamp, | |
149 | batch_count=response_batch_count) | |
150 | ||
151 | response_message = ResponseMessage(response_header=response_header, | |
152 | batch_items=response_batch_items) | |
153 | return response_message | |
154 | ||
155 | def _process_response(self, message): | |
156 | raise NotImplementedError() | |
157 | ||
158 | def _process_operation(self, operation, payload): | |
159 | op = operation.enum | |
160 | ||
161 | if op is Operation.CREATE: | |
162 | return self._process_create_request(payload) | |
163 | elif op is Operation.GET: | |
164 | return self._process_get_request(payload) | |
165 | elif op is Operation.DESTROY: | |
166 | return self._process_destroy_request(payload) | |
167 | elif op is Operation.REGISTER: | |
168 | return self._process_register_request(payload) | |
169 | else: | |
170 | raise NotImplementedError() | |
171 | ||
172 | def _process_create_request(self, payload): | |
173 | object_type = payload.object_type | |
174 | template_attribute = payload.template_attribute | |
175 | result = self._handler.create(object_type, template_attribute) | |
176 | ||
177 | result_status = result.result_status | |
178 | result_reason = result.result_reason | |
179 | result_message = result.result_message | |
180 | created_type = result.object_type | |
181 | uuid = result.uuid | |
182 | template_attribute = result.template_attribute | |
183 | ||
184 | resp_pl = CreateResponsePayload(object_type=created_type, | |
185 | unique_identifier=uuid, | |
186 | template_attribute=template_attribute) | |
187 | ||
188 | return (result_status, result_reason, result_message, resp_pl) | |
189 | ||
190 | def _process_get_request(self, payload): | |
191 | uuid = None | |
192 | kft = None | |
193 | kct = None | |
194 | ||
195 | unique_identifier = payload.unique_identifier | |
196 | key_format_type = payload.key_format_type | |
197 | key_compression_type = payload.key_compression_type | |
198 | key_wrapping_specification = payload.key_wrapping_specification | |
199 | ||
200 | if unique_identifier is not None: | |
201 | uuid = unique_identifier | |
202 | if key_format_type is not None: | |
203 | kft = key_format_type | |
204 | if key_compression_type is not None: | |
205 | kct = key_compression_type | |
206 | ||
207 | result = self._handler.get(uuid, kft, kct, | |
208 | key_wrapping_specification) | |
209 | ||
210 | result_status = result.result_status | |
211 | result_reason = result.result_reason | |
212 | result_message = result.result_message | |
213 | retrieved_type = result.object_type | |
214 | uuid = result.uuid | |
215 | secret = result.secret | |
216 | ||
217 | resp_pl = GetResponsePayload(object_type=retrieved_type, | |
218 | unique_identifier=uuid, | |
219 | secret=secret) | |
220 | ||
221 | return (result_status, result_reason, result_message, resp_pl) | |
222 | ||
223 | def _process_destroy_request(self, payload): | |
224 | uuid = payload.unique_identifier | |
225 | result = self._handler.destroy(uuid) | |
226 | ||
227 | result_status = result.result_status | |
228 | result_reason = result.result_reason | |
229 | result_message = result.result_message | |
230 | uuid = result.uuid | |
231 | ||
232 | payload = DestroyResponsePayload(unique_identifier=uuid) | |
233 | ||
234 | return (result_status, result_reason, result_message, payload) | |
235 | ||
236 | def _process_register_request(self, payload): | |
237 | object_type = payload.object_type | |
238 | template_attribute = payload.template_attribute | |
239 | secret = payload.secret | |
240 | result = self._handler.register(object_type, template_attribute, | |
241 | secret) | |
242 | ||
243 | result_status = result.result_status | |
244 | result_reason = result.result_reason | |
245 | result_message = result.result_message | |
246 | uuid = result.uuid | |
247 | template_attr = result.template_attribute | |
248 | ||
249 | resp_pl = RegisterResponsePayload(unique_identifier=uuid, | |
250 | template_attribute=template_attr) | |
251 | ||
252 | return (result_status, result_reason, result_message, resp_pl) |
0 | # Copyright (c) 2014 The Johns Hopkins University/Applied Physics Laboratory | |
1 | # All Rights Reserved. | |
2 | # | |
3 | # Licensed under the Apache License, Version 2.0 (the "License"); you may | |
4 | # not use this file except in compliance with the License. You may obtain | |
5 | # a copy of the License at | |
6 | # | |
7 | # http://www.apache.org/licenses/LICENSE-2.0 | |
8 | # | |
9 | # Unless required by applicable law or agreed to in writing, software | |
10 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT | |
11 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the | |
12 | # License for the specific language governing permissions and limitations | |
13 | # under the License. | |
14 | ||
15 | ||
16 | class OperationResult(object): | |
17 | ||
18 | def __init__(self, | |
19 | result_status, | |
20 | result_reason=None, | |
21 | result_message=None): | |
22 | self.result_status = result_status | |
23 | ||
24 | if result_reason is not None: | |
25 | self.result_reason = result_reason | |
26 | else: | |
27 | self.result_reason = None | |
28 | ||
29 | if result_message is not None: | |
30 | self.result_message = result_message | |
31 | else: | |
32 | self.result_message = None | |
33 | ||
34 | ||
35 | class CreateResult(OperationResult): | |
36 | ||
37 | def __init__(self, | |
38 | result_status, | |
39 | result_reason=None, | |
40 | result_message=None, | |
41 | object_type=None, | |
42 | uuid=None, | |
43 | template_attribute=None): | |
44 | super(self.__class__, self).__init__(result_status, | |
45 | result_reason, | |
46 | result_message) | |
47 | if object_type is not None: | |
48 | self.object_type = object_type | |
49 | else: | |
50 | self.object_type = None | |
51 | ||
52 | if uuid is not None: | |
53 | self.uuid = uuid | |
54 | else: | |
55 | self.uuid = None | |
56 | ||
57 | if template_attribute is not None: | |
58 | self.template_attribute = template_attribute | |
59 | else: | |
60 | self.template_attribute = None | |
61 | ||
62 | ||
63 | class RegisterResult(OperationResult): | |
64 | ||
65 | def __init__(self, | |
66 | result_status, | |
67 | result_reason=None, | |
68 | result_message=None, | |
69 | uuid=None, | |
70 | template_attribute=None): | |
71 | super(self.__class__, self).__init__(result_status, | |
72 | result_reason, | |
73 | result_message) | |
74 | if uuid is not None: | |
75 | self.uuid = uuid | |
76 | else: | |
77 | self.uuid = None | |
78 | ||
79 | if template_attribute is not None: | |
80 | self.template_attribute = template_attribute | |
81 | else: | |
82 | self.template_attribute = None | |
83 | ||
84 | ||
85 | class GetResult(OperationResult): | |
86 | ||
87 | def __init__(self, | |
88 | result_status, | |
89 | result_reason=None, | |
90 | result_message=None, | |
91 | object_type=None, | |
92 | uuid=None, | |
93 | secret=None): | |
94 | super(self.__class__, self).__init__(result_status, | |
95 | result_reason, | |
96 | result_message) | |
97 | if object_type is not None: | |
98 | self.object_type = object_type | |
99 | else: | |
100 | self.object_type = None | |
101 | ||
102 | if uuid is not None: | |
103 | self.uuid = uuid | |
104 | else: | |
105 | self.uuid = None | |
106 | ||
107 | if secret is not None: | |
108 | self.secret = secret | |
109 | else: | |
110 | self.secret = None | |
111 | ||
112 | ||
113 | class DestroyResult(OperationResult): | |
114 | ||
115 | def __init__(self, | |
116 | result_status, | |
117 | result_reason=None, | |
118 | result_message=None, | |
119 | uuid=None): | |
120 | super(self.__class__, self).__init__(result_status, | |
121 | result_reason, | |
122 | result_message) | |
123 | if uuid is not None: | |
124 | self.uuid = uuid | |
125 | else: | |
126 | self.uuid = None |
0 | # Copyright (c) 2014 The Johns Hopkins University/Applied Physics Laboratory | |
1 | # All Rights Reserved. | |
2 | # | |
3 | # Licensed under the Apache License, Version 2.0 (the "License"); you may | |
4 | # not use this file except in compliance with the License. You may obtain | |
5 | # a copy of the License at | |
6 | # | |
7 | # http://www.apache.org/licenses/LICENSE-2.0 | |
8 | # | |
9 | # Unless required by applicable law or agreed to in writing, software | |
10 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT | |
11 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the | |
12 | # License for the specific language governing permissions and limitations | |
13 | # under the License. |
0 | # Copyright (c) 2014 The Johns Hopkins University/Applied Physics Laboratory | |
1 | # All Rights Reserved. | |
2 | # | |
3 | # Licensed under the Apache License, Version 2.0 (the "License"); you may | |
4 | # not use this file except in compliance with the License. You may obtain | |
5 | # a copy of the License at | |
6 | # | |
7 | # http://www.apache.org/licenses/LICENSE-2.0 | |
8 | # | |
9 | # Unless required by applicable law or agreed to in writing, software | |
10 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT | |
11 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the | |
12 | # License for the specific language governing permissions and limitations | |
13 | # under the License. |
0 | # Copyright (c) 2014 The Johns Hopkins University/Applied Physics Laboratory | |
1 | # All Rights Reserved. | |
2 | # | |
3 | # Licensed under the Apache License, Version 2.0 (the "License"); you may | |
4 | # not use this file except in compliance with the License. You may obtain | |
5 | # a copy of the License at | |
6 | # | |
7 | # http://www.apache.org/licenses/LICENSE-2.0 | |
8 | # | |
9 | # Unless required by applicable law or agreed to in writing, software | |
10 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT | |
11 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the | |
12 | # License for the specific language governing permissions and limitations | |
13 | # under the License. |
0 | # Copyright (c) 2014 The Johns Hopkins University/Applied Physics Laboratory | |
1 | # All Rights Reserved. | |
2 | # | |
3 | # Licensed under the Apache License, Version 2.0 (the "License"); you may | |
4 | # not use this file except in compliance with the License. You may obtain | |
5 | # a copy of the License at | |
6 | # | |
7 | # http://www.apache.org/licenses/LICENSE-2.0 | |
8 | # | |
9 | # Unless required by applicable law or agreed to in writing, software | |
10 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT | |
11 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the | |
12 | # License for the specific language governing permissions and limitations | |
13 | # under the License. |
0 | # Copyright (c) 2014 The Johns Hopkins University/Applied Physics Laboratory | |
1 | # All Rights Reserved. | |
2 | # | |
3 | # Licensed under the Apache License, Version 2.0 (the "License"); you may | |
4 | # not use this file except in compliance with the License. You may obtain | |
5 | # a copy of the License at | |
6 | # | |
7 | # http://www.apache.org/licenses/LICENSE-2.0 | |
8 | # | |
9 | # Unless required by applicable law or agreed to in writing, software | |
10 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT | |
11 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the | |
12 | # License for the specific language governing permissions and limitations | |
13 | # under the License. | |
14 | ||
15 | from testtools import TestCase | |
16 | ||
17 | from kmip.core.factories.keys import KeyFactory | |
18 | from kmip.core.factories.secrets import SecretFactory | |
19 | from kmip.core.factories.attributes import AttributeFactory | |
20 | ||
21 | from kmip.core import attributes as attr | |
22 | from kmip.core.attributes import ApplicationSpecificInformation | |
23 | from kmip.core.attributes import ContactInformation | |
24 | from kmip.core.attributes import Name | |
25 | from kmip.core.attributes import ObjectGroup | |
26 | ||
27 | from kmip.core import enums | |
28 | from kmip.core.enums import AttributeType | |
29 | from kmip.core.enums import CryptographicAlgorithm | |
30 | from kmip.core.enums import CryptographicUsageMask | |
31 | from kmip.core.enums import NameType | |
32 | from kmip.core.enums import ObjectType | |
33 | ||
34 | from kmip.core import errors | |
35 | from kmip.core.errors import ErrorStrings | |
36 | ||
37 | from kmip.core import objects | |
38 | ||
39 | from kmip.core.keys import RawKey | |
40 | ||
41 | from kmip.core.messages import contents | |
42 | from kmip.core.messages import messages | |
43 | from kmip.core.messages import operations | |
44 | ||
45 | from kmip.core.messages.operations import DestroyRequestPayload | |
46 | from kmip.core.messages.operations import RegisterRequestPayload | |
47 | from kmip.core.messages.operations import DestroyResponsePayload | |
48 | from kmip.core.messages.operations import RegisterResponsePayload | |
49 | ||
50 | from kmip.core.primitives import TextString | |
51 | ||
52 | from kmip.core.secrets import SymmetricKey | |
53 | from kmip.core.secrets import Template | |
54 | ||
55 | from kmip.core import utils | |
56 | from kmip.core.utils import BytearrayStream | |
57 | ||
58 | ||
59 | class TestRequestMessage(TestCase): | |
60 | ||
61 | def setUp(self): | |
62 | super(TestRequestMessage, self).setUp() | |
63 | self.stream = BytearrayStream() | |
64 | self.attribute_factory = AttributeFactory() | |
65 | self.msg = errors.ErrorStrings.BAD_EXP_RECV | |
66 | self.create = ( | |
67 | '\x42\x00\x78\x01\x00\x00\x01\x20\x42\x00\x77\x01\x00\x00\x00\x38' | |
68 | '\x42\x00\x69\x01\x00\x00\x00\x20\x42\x00\x6A\x02\x00\x00\x00\x04' | |
69 | '\x00\x00\x00\x01\x00\x00\x00\x00\x42\x00\x6B\x02\x00\x00\x00\x04' | |
70 | '\x00\x00\x00\x01\x00\x00\x00\x00\x42\x00\x0D\x02\x00\x00\x00\x04' | |
71 | '\x00\x00\x00\x01\x00\x00\x00\x00\x42\x00\x0F\x01\x00\x00\x00\xD8' | |
72 | '\x42\x00\x5C\x05\x00\x00\x00\x04\x00\x00\x00\x01\x00\x00\x00\x00' | |
73 | '\x42\x00\x79\x01\x00\x00\x00\xC0\x42\x00\x57\x05\x00\x00\x00\x04' | |
74 | '\x00\x00\x00\x02\x00\x00\x00\x00\x42\x00\x91\x01\x00\x00\x00\xA8' | |
75 | '\x42\x00\x08\x01\x00\x00\x00\x30\x42\x00\x0A\x07\x00\x00\x00\x17' | |
76 | '\x43\x72\x79\x70\x74\x6F\x67\x72\x61\x70\x68\x69\x63\x20\x41\x6C' | |
77 | '\x67\x6F\x72\x69\x74\x68\x6D\x00\x42\x00\x0B\x05\x00\x00\x00\x04' | |
78 | '\x00\x00\x00\x03\x00\x00\x00\x00\x42\x00\x08\x01\x00\x00\x00\x30' | |
79 | '\x42\x00\x0A\x07\x00\x00\x00\x14\x43\x72\x79\x70\x74\x6F\x67\x72' | |
80 | '\x61\x70\x68\x69\x63\x20\x4C\x65\x6E\x67\x74\x68\x00\x00\x00\x00' | |
81 | '\x42\x00\x0B\x02\x00\x00\x00\x04\x00\x00\x00\x80\x00\x00\x00\x00' | |
82 | '\x42\x00\x08\x01\x00\x00\x00\x30\x42\x00\x0A\x07\x00\x00\x00\x18' | |
83 | '\x43\x72\x79\x70\x74\x6F\x67\x72\x61\x70\x68\x69\x63\x20\x55\x73' | |
84 | '\x61\x67\x65\x20\x4D\x61\x73\x6B\x42\x00\x0B\x02\x00\x00\x00\x04' | |
85 | '\x00\x00\x00\x0C\x00\x00\x00\x00') | |
86 | self.register = ( | |
87 | '\x42\x00\x78\x01\x00\x00\x01\xC8\x42\x00\x77\x01\x00\x00\x00\x38' | |
88 | '\x42\x00\x69\x01\x00\x00\x00\x20\x42\x00\x6A\x02\x00\x00\x00\x04' | |
89 | '\x00\x00\x00\x01\x00\x00\x00\x00\x42\x00\x6B\x02\x00\x00\x00\x04' | |
90 | '\x00\x00\x00\x01\x00\x00\x00\x00\x42\x00\x0D\x02\x00\x00\x00\x04' | |
91 | '\x00\x00\x00\x01\x00\x00\x00\x00\x42\x00\x0F\x01\x00\x00\x01\x80' | |
92 | '\x42\x00\x5C\x05\x00\x00\x00\x04\x00\x00\x00\x03\x00\x00\x00\x00' | |
93 | '\x42\x00\x79\x01\x00\x00\x01\x68\x42\x00\x57\x05\x00\x00\x00\x04' | |
94 | '\x00\x00\x00\x06\x00\x00\x00\x00\x42\x00\x91\x01\x00\x00\x00\x00' | |
95 | '\x42\x00\x90\x01\x00\x00\x01\x48\x42\x00\x08\x01\x00\x00\x00\x28' | |
96 | '\x42\x00\x0A\x07\x00\x00\x00\x0C\x4F\x62\x6A\x65\x63\x74\x20\x47' | |
97 | '\x72\x6F\x75\x70\x00\x00\x00\x00\x42\x00\x0B\x07\x00\x00\x00\x06' | |
98 | '\x47\x72\x6F\x75\x70\x31\x00\x00\x42\x00\x08\x01\x00\x00\x00\x58' | |
99 | '\x42\x00\x0A\x07\x00\x00\x00\x20\x41\x70\x70\x6C\x69\x63\x61\x74' | |
100 | '\x69\x6F\x6E\x20\x53\x70\x65\x63\x69\x66\x69\x63\x20\x49\x6E\x66' | |
101 | '\x6F\x72\x6D\x61\x74\x69\x6F\x6E\x42\x00\x0B\x01\x00\x00\x00\x28' | |
102 | '\x42\x00\x03\x07\x00\x00\x00\x03\x73\x73\x6C\x00\x00\x00\x00\x00' | |
103 | '\x42\x00\x02\x07\x00\x00\x00\x0F\x77\x77\x77\x2E\x65\x78\x61\x6D' | |
104 | '\x70\x6C\x65\x2E\x63\x6F\x6D\x00\x42\x00\x08\x01\x00\x00\x00\x30' | |
105 | '\x42\x00\x0A\x07\x00\x00\x00\x13\x43\x6F\x6E\x74\x61\x63\x74\x20' | |
106 | '\x49\x6E\x66\x6F\x72\x6D\x61\x74\x69\x6F\x6E\x00\x00\x00\x00\x00' | |
107 | '\x42\x00\x0B\x07\x00\x00\x00\x03\x4A\x6F\x65\x00\x00\x00\x00\x00' | |
108 | '\x42\x00\x08\x01\x00\x00\x00\x30\x42\x00\x0A\x07\x00\x00\x00\x09' | |
109 | '\x78\x2D\x50\x75\x72\x70\x6F\x73\x65\x00\x00\x00\x00\x00\x00\x00' | |
110 | '\x42\x00\x0B\x07\x00\x00\x00\x0D\x64\x65\x6D\x6F\x6E\x73\x74\x72' | |
111 | '\x61\x74\x69\x6F\x6E\x00\x00\x00\x42\x00\x08\x01\x00\x00\x00\x40' | |
112 | '\x42\x00\x0A\x07\x00\x00\x00\x04\x4E\x61\x6D\x65\x00\x00\x00\x00' | |
113 | '\x42\x00\x0B\x01\x00\x00\x00\x28\x42\x00\x55\x07\x00\x00\x00\x09' | |
114 | '\x54\x65\x6D\x70\x6C\x61\x74\x65\x31\x00\x00\x00\x00\x00\x00\x00' | |
115 | '\x42\x00\x54\x05\x00\x00\x00\x04\x00\x00\x00\x01\x00\x00\x00\x00') | |
116 | self.get = ( | |
117 | '\x42\x00\x78\x01\x00\x00\x00\x90\x42\x00\x77\x01\x00\x00\x00\x38' | |
118 | '\x42\x00\x69\x01\x00\x00\x00\x20\x42\x00\x6A\x02\x00\x00\x00\x04' | |
119 | '\x00\x00\x00\x01\x00\x00\x00\x00\x42\x00\x6B\x02\x00\x00\x00\x04' | |
120 | '\x00\x00\x00\x01\x00\x00\x00\x00\x42\x00\x0D\x02\x00\x00\x00\x04' | |
121 | '\x00\x00\x00\x01\x00\x00\x00\x00\x42\x00\x0F\x01\x00\x00\x00\x48' | |
122 | '\x42\x00\x5C\x05\x00\x00\x00\x04\x00\x00\x00\x0A\x00\x00\x00\x00' | |
123 | '\x42\x00\x79\x01\x00\x00\x00\x30\x42\x00\x94\x07\x00\x00\x00\x24' | |
124 | '\x34\x39\x61\x31\x63\x61\x38\x38\x2D\x36\x62\x65\x61\x2D\x34\x66' | |
125 | '\x62\x32\x2D\x62\x34\x35\x30\x2D\x37\x65\x35\x38\x38\x30\x32\x63' | |
126 | '\x33\x30\x33\x38\x00\x00\x00\x00') | |
127 | self.destroy = ( | |
128 | '\x42\x00\x78\x01\x00\x00\x00\x90\x42\x00\x77\x01\x00\x00\x00\x38' | |
129 | '\x42\x00\x69\x01\x00\x00\x00\x20\x42\x00\x6A\x02\x00\x00\x00\x04' | |
130 | '\x00\x00\x00\x01\x00\x00\x00\x00\x42\x00\x6B\x02\x00\x00\x00\x04' | |
131 | '\x00\x00\x00\x01\x00\x00\x00\x00\x42\x00\x0D\x02\x00\x00\x00\x04' | |
132 | '\x00\x00\x00\x01\x00\x00\x00\x00\x42\x00\x0F\x01\x00\x00\x00\x48' | |
133 | '\x42\x00\x5C\x05\x00\x00\x00\x04\x00\x00\x00\x14\x00\x00\x00\x00' | |
134 | '\x42\x00\x79\x01\x00\x00\x00\x30\x42\x00\x94\x07\x00\x00\x00\x24' | |
135 | '\x66\x62\x34\x62\x35\x62\x39\x63\x2D\x36\x31\x38\x38\x2D\x34\x63' | |
136 | '\x36\x33\x2D\x38\x31\x34\x32\x2D\x66\x65\x39\x63\x33\x32\x38\x31' | |
137 | '\x32\x39\x66\x63\x00\x00\x00\x00') | |
138 | ||
139 | def tearDown(self): | |
140 | super(TestRequestMessage, self).tearDown() | |
141 | ||
142 | def test_create_request_read(self): | |
143 | self.stream = BytearrayStream(self.create) | |
144 | ||
145 | request_message = messages.RequestMessage() | |
146 | request_message.read(self.stream) | |
147 | ||
148 | request_header = request_message.request_header | |
149 | msg = "Bad request header type: expected {0}, received{1}" | |
150 | self.assertIsInstance(request_header, messages.RequestHeader, | |
151 | msg.format(messages.RequestHeader, | |
152 | type(request_header))) | |
153 | ||
154 | protocol_version = request_header.protocol_version | |
155 | msg = "Bad protocol version type: expected {0}, received {1}" | |
156 | self.assertIsInstance(protocol_version, contents.ProtocolVersion, | |
157 | msg.format(contents.ProtocolVersion, | |
158 | type(protocol_version))) | |
159 | ||
160 | protocol_version_major = protocol_version.protocol_version_major | |
161 | msg = "Bad protocol version major type: expected {0}, received {1}" | |
162 | exp_type = contents.ProtocolVersion.ProtocolVersionMajor | |
163 | rcv_type = type(protocol_version_major) | |
164 | self.assertIsInstance(protocol_version_major, exp_type, | |
165 | msg.format(exp_type, rcv_type)) | |
166 | msg = "Bad protocol version major value: expected {0}, received {1}" | |
167 | self.assertEqual(1, protocol_version_major.value, | |
168 | msg.format(1, protocol_version_major.value)) | |
169 | ||
170 | protocol_version_minor = protocol_version.protocol_version_minor | |
171 | msg = "Bad protocol version minor type: expected {0}, received {1}" | |
172 | exp_type = contents.ProtocolVersion.ProtocolVersionMinor | |
173 | rcv_type = type(protocol_version_minor) | |
174 | self.assertIsInstance(protocol_version_minor, exp_type, | |
175 | msg.format(exp_type, rcv_type)) | |
176 | msg = "Bad protocol version minor value: expected {0}, received {1}" | |
177 | self.assertEqual(1, protocol_version_minor.value, | |
178 | msg.format(1, protocol_version_minor.value)) | |
179 | ||
180 | batch_count = request_header.batch_count | |
181 | msg = "Bad batch count type: expected {0}, received {1}" | |
182 | self.assertIsInstance(batch_count, contents.BatchCount, | |
183 | msg.format(contents.BatchCount, | |
184 | type(batch_count))) | |
185 | msg = "Bad batch count value: expected {0}, received {1}" | |
186 | self.assertEqual(1, batch_count.value, | |
187 | msg.format(1, batch_count.value)) | |
188 | ||
189 | batch_items = request_message.batch_items | |
190 | msg = "Bad batch items type: expected {0}, received {1}" | |
191 | self.assertIsInstance(batch_items, list, | |
192 | msg.format(list, type(batch_items))) | |
193 | self.assertEquals(1, len(batch_items), | |
194 | self.msg.format('batch items', 'length', | |
195 | 1, len(batch_items))) | |
196 | ||
197 | batch_item = batch_items[0] | |
198 | msg = "Bad batch item type: expected {0}, received {1}" | |
199 | self.assertIsInstance(batch_item, messages.RequestBatchItem, | |
200 | msg.format(messages.RequestBatchItem, | |
201 | type(batch_item))) | |
202 | ||
203 | operation = batch_item.operation | |
204 | msg = "Bad operation type: expected {0}, received {1}" | |
205 | self.assertIsInstance(operation, contents.Operation, | |
206 | msg.format(contents.Operation, | |
207 | type(operation))) | |
208 | msg = "Bad operation value: expected {0}, received {1}" | |
209 | self.assertEqual(enums.Operation.CREATE, operation.enum, | |
210 | msg.format(enums.Operation.CREATE, | |
211 | operation.enum)) | |
212 | ||
213 | request_payload = batch_item.request_payload | |
214 | msg = "Bad request payload type: expected {0}, received {1}" | |
215 | self.assertIsInstance(request_payload, | |
216 | operations.CreateRequestPayload, | |
217 | msg.format(operations.CreateRequestPayload, | |
218 | type(request_payload))) | |
219 | ||
220 | object_type = request_payload.object_type | |
221 | msg = "Bad object type type: expected {0}, received {1}" | |
222 | self.assertIsInstance(object_type, attr.ObjectType, | |
223 | msg.format(attr.ObjectType, | |
224 | type(object_type))) | |
225 | msg = "Bad object type value: expected {0}, received {1}" | |
226 | self.assertEqual(enums.ObjectType.SYMMETRIC_KEY, object_type.enum, | |
227 | msg.format(enums.ObjectType.SYMMETRIC_KEY, | |
228 | object_type.enum)) | |
229 | ||
230 | template_attribute = request_payload.template_attribute | |
231 | msg = "Bad template attribute type: expected {0}, received {1}" | |
232 | self.assertIsInstance(template_attribute, | |
233 | objects.TemplateAttribute, | |
234 | msg.format(objects.TemplateAttribute, | |
235 | type(template_attribute))) | |
236 | ||
237 | attributes = template_attribute.attributes | |
238 | self.assertIsInstance(attributes, list, | |
239 | self.msg.format('attributes', 'type', | |
240 | list, type(attributes))) | |
241 | self.assertEquals(3, len(attributes), | |
242 | self.msg.format('attributes', 'length', | |
243 | 3, len(attributes))) | |
244 | ||
245 | attribute_a = attributes[0] | |
246 | self.assertIsInstance(attribute_a, objects.Attribute, | |
247 | self.msg.format('attribute', 'type', | |
248 | objects.Attribute, | |
249 | type(attribute_a))) | |
250 | ||
251 | attribute_name = attribute_a.attribute_name | |
252 | self.assertIsInstance(attribute_name, objects.Attribute.AttributeName, | |
253 | self.msg.format('attribute name', 'type', | |
254 | objects.Attribute.AttributeName, | |
255 | type(attribute_name))) | |
256 | self.assertEquals('Cryptographic Algorithm', attribute_name.value, | |
257 | self.msg.format('attribute name', 'value', | |
258 | 'Cryptographic Algorithm', | |
259 | attribute_name.value)) | |
260 | ||
261 | attribute_value = attribute_a.attribute_value | |
262 | exp_type = attr.CryptographicAlgorithm | |
263 | rcv_type = type(attribute_value) | |
264 | self.assertIsInstance(attribute_value, exp_type, | |
265 | self.msg.format('attribute value', 'type', | |
266 | exp_type, rcv_type)) | |
267 | self.assertEquals(attribute_value.enum, | |
268 | enums.CryptographicAlgorithm.AES, | |
269 | self.msg.format('cryptographic algorithm', 'value', | |
270 | enums.CryptographicAlgorithm.AES, | |
271 | attribute_value.enum)) | |
272 | ||
273 | attribute_b = attributes[1] | |
274 | self.assertIsInstance(attribute_b, objects.Attribute, | |
275 | self.msg.format('attribute', 'type', | |
276 | objects.Attribute, | |
277 | type(attribute_b))) | |
278 | ||
279 | attribute_name = attribute_b.attribute_name | |
280 | self.assertIsInstance(attribute_name, objects.Attribute.AttributeName, | |
281 | self.msg.format('attribute name', 'type', | |
282 | objects.Attribute.AttributeName, | |
283 | type(attribute_name))) | |
284 | self.assertEquals('Cryptographic Length', attribute_name.value, | |
285 | self.msg.format('attribute name', 'value', | |
286 | 'Cryptographic Length', | |
287 | attribute_name.value)) | |
288 | ||
289 | attribute_value = attribute_b.attribute_value | |
290 | exp_type = attr.CryptographicLength | |
291 | rcv_type = type(attribute_value) | |
292 | self.assertIsInstance(attribute_value, exp_type, | |
293 | self.msg.format('attribute value', 'type', | |
294 | exp_type, rcv_type)) | |
295 | self.assertEquals(attribute_value.value, 128, | |
296 | self.msg.format('cryptographic length', 'value', | |
297 | 128, attribute_value.value)) | |
298 | ||
299 | attribute_c = attributes[2] | |
300 | self.assertIsInstance(attribute_c, objects.Attribute, | |
301 | self.msg.format('attribute', 'type', | |
302 | objects.Attribute, | |
303 | type(attribute_b))) | |
304 | ||
305 | attribute_name = attribute_c.attribute_name | |
306 | self.assertIsInstance(attribute_name, objects.Attribute.AttributeName, | |
307 | self.msg.format('attribute name', 'type', | |
308 | objects.Attribute.AttributeName, | |
309 | type(attribute_name))) | |
310 | self.assertEquals('Cryptographic Usage Mask', attribute_name.value, | |
311 | self.msg.format('attribute name', 'value', | |
312 | 'Cryptographic Usage Mask', | |
313 | attribute_name.value)) | |
314 | ||
315 | attribute_value = attribute_c.attribute_value | |
316 | exp_type = attr.CryptographicUsageMask | |
317 | rcv_type = type(attribute_value) | |
318 | self.assertIsInstance(attribute_value, exp_type, | |
319 | self.msg.format('attribute value', 'type', | |
320 | exp_type, rcv_type)) | |
321 | flag_encrypt = CryptographicUsageMask.ENCRYPT | |
322 | flag_decrypt = CryptographicUsageMask.DECRYPT | |
323 | exp_value = flag_encrypt.value | flag_decrypt.value | |
324 | self.assertEquals(attribute_value.value, exp_value, | |
325 | self.msg.format('cryptographic usage mask', 'value', | |
326 | exp_value, attribute_value.value)) | |
327 | ||
328 | def test_create_request_write(self): | |
329 | prot_ver = contents.ProtocolVersion.create(1, 1) | |
330 | ||
331 | batch_count = contents.BatchCount(1) | |
332 | request_header = messages.RequestHeader(protocol_version=prot_ver, | |
333 | batch_count=batch_count) | |
334 | ||
335 | operation = contents.Operation(enums.Operation.CREATE) | |
336 | object_type = attr.ObjectType(enums.ObjectType.SYMMETRIC_KEY) | |
337 | ||
338 | name = AttributeType.CRYPTOGRAPHIC_ALGORITHM | |
339 | value = CryptographicAlgorithm.AES | |
340 | attr_a = self.attribute_factory.create_attribute(name, value) | |
341 | ||
342 | name = AttributeType.CRYPTOGRAPHIC_LENGTH | |
343 | value = 128 | |
344 | attr_b = self.attribute_factory.create_attribute(name, value) | |
345 | ||
346 | name = AttributeType.CRYPTOGRAPHIC_USAGE_MASK | |
347 | value = [CryptographicUsageMask.ENCRYPT, | |
348 | CryptographicUsageMask.DECRYPT] | |
349 | attr_c = self.attribute_factory.create_attribute(name, value) | |
350 | ||
351 | temp_attr = objects.TemplateAttribute(attributes=[attr_a, attr_b, | |
352 | attr_c]) | |
353 | req_pl = operations.CreateRequestPayload(object_type=object_type, | |
354 | template_attribute=temp_attr) | |
355 | batch_item = messages.RequestBatchItem(operation=operation, | |
356 | request_payload=req_pl) | |
357 | req_message = messages.RequestMessage(request_header=request_header, | |
358 | batch_items=[batch_item]) | |
359 | req_message.write(self.stream) | |
360 | ||
361 | result = self.stream.read() | |
362 | len_exp = len(self.create) | |
363 | len_rcv = len(result) | |
364 | self.assertEqual(len_exp, len_rcv, | |
365 | self.msg.format('request message', 'write', | |
366 | len_exp, len_rcv)) | |
367 | ||
368 | msg = "Bad request message write: encoding mismatch" | |
369 | self.assertEqual(self.create, result, msg) | |
370 | ||
371 | def test_get_request_read(self): | |
372 | self.stream = BytearrayStream(self.get) | |
373 | ||
374 | request_message = messages.RequestMessage() | |
375 | request_message.read(self.stream) | |
376 | ||
377 | request_header = request_message.request_header | |
378 | msg = "Bad request header type: expected {0}, received{0}" | |
379 | self.assertIsInstance(request_header, messages.RequestHeader, | |
380 | msg.format(messages.RequestHeader, | |
381 | type(request_header))) | |
382 | ||
383 | protocol_version = request_header.protocol_version | |
384 | msg = "Bad protocol version type: expected {0}, received {1}" | |
385 | self.assertIsInstance(protocol_version, contents.ProtocolVersion, | |
386 | msg.format(contents.ProtocolVersion, | |
387 | type(protocol_version))) | |
388 | ||
389 | protocol_version_major = protocol_version.protocol_version_major | |
390 | msg = "Bad protocol version major type: expected {0}, received {1}" | |
391 | exp_type = contents.ProtocolVersion.ProtocolVersionMajor | |
392 | rcv_type = type(protocol_version_major) | |
393 | self.assertIsInstance(protocol_version_major, exp_type, | |
394 | msg.format(exp_type, rcv_type)) | |
395 | msg = "Bad protocol version major value: expected {0}, received {1}" | |
396 | self.assertEqual(1, protocol_version_major.value, | |
397 | msg.format(1, protocol_version_major.value)) | |
398 | ||
399 | protocol_version_minor = protocol_version.protocol_version_minor | |
400 | msg = "Bad protocol version minor type: expected {0}, received {1}" | |
401 | exp_type = contents.ProtocolVersion.ProtocolVersionMinor | |
402 | rcv_type = type(protocol_version_minor) | |
403 | self.assertIsInstance(protocol_version_minor, exp_type, | |
404 | msg.format(exp_type, rcv_type)) | |
405 | msg = "Bad protocol version minor value: expected {0}, received {1}" | |
406 | self.assertEqual(1, protocol_version_minor.value, | |
407 | msg.format(1, protocol_version_minor.value)) | |
408 | ||
409 | batch_count = request_header.batch_count | |
410 | msg = "Bad batch count type: expected {0}, received {1}" | |
411 | self.assertIsInstance(batch_count, contents.BatchCount, | |
412 | msg.format(contents.BatchCount, | |
413 | type(batch_count))) | |
414 | msg = "Bad batch count value: expected {0}, received {1}" | |
415 | self.assertEqual(1, batch_count.value, | |
416 | msg.format(1, batch_count.value)) | |
417 | ||
418 | batch_items = request_message.batch_items | |
419 | msg = "Bad batch items type: expected {0}, received {1}" | |
420 | self.assertIsInstance(batch_items, list, | |
421 | msg.format(list, type(batch_items))) | |
422 | self.assertEquals(1, len(batch_items), | |
423 | self.msg.format('batch items', 'length', | |
424 | 1, len(batch_items))) | |
425 | ||
426 | batch_item = batch_items[0] | |
427 | msg = "Bad batch item type: expected {0}, received {1}" | |
428 | self.assertIsInstance(batch_item, messages.RequestBatchItem, | |
429 | msg.format(messages.RequestBatchItem, | |
430 | type(batch_item))) | |
431 | ||
432 | operation = batch_item.operation | |
433 | msg = "Bad operation type: expected {0}, received {1}" | |
434 | self.assertIsInstance(operation, contents.Operation, | |
435 | msg.format(contents.Operation, | |
436 | type(operation))) | |
437 | msg = "Bad operation value: expected {0}, received {1}" | |
438 | self.assertEqual(enums.Operation.GET, operation.enum, | |
439 | msg.format(enums.Operation.GET, | |
440 | operation.enum)) | |
441 | ||
442 | request_payload = batch_item.request_payload | |
443 | msg = "Bad request payload type: expected {0}, received {1}" | |
444 | self.assertIsInstance(request_payload, | |
445 | operations.GetRequestPayload, | |
446 | msg.format(operations.GetRequestPayload, | |
447 | type(request_payload))) | |
448 | ||
449 | unique_identifier = request_payload.unique_identifier | |
450 | msg = "Bad unique identifier type: expected {0}, received {1}" | |
451 | self.assertIsInstance(unique_identifier, attr.UniqueIdentifier, | |
452 | msg.format(attr.UniqueIdentifier, | |
453 | type(unique_identifier))) | |
454 | msg = "Bad unique identifier value: expected {0}, received {1}" | |
455 | self.assertEqual('49a1ca88-6bea-4fb2-b450-7e58802c3038', | |
456 | unique_identifier.value, | |
457 | msg.format('49a1ca88-6bea-4fb2-b450-7e58802c3038', | |
458 | unique_identifier.value)) | |
459 | ||
460 | def test_get_request_write(self): | |
461 | prot_ver = contents.ProtocolVersion.create(1, 1) | |
462 | ||
463 | batch_count = contents.BatchCount(1) | |
464 | req_header = messages.RequestHeader(protocol_version=prot_ver, | |
465 | batch_count=batch_count) | |
466 | ||
467 | operation = contents.Operation(enums.Operation.GET) | |
468 | ||
469 | uuid = attr.UniqueIdentifier('49a1ca88-6bea-4fb2-b450-7e58802c3038') | |
470 | request_payload = operations.GetRequestPayload(unique_identifier=uuid) | |
471 | batch_item = messages.RequestBatchItem(operation=operation, | |
472 | request_payload=request_payload) | |
473 | request_message = messages.RequestMessage(request_header=req_header, | |
474 | batch_items=[batch_item]) | |
475 | request_message.write(self.stream) | |
476 | ||
477 | result = self.stream.read() | |
478 | len_exp = len(self.get) | |
479 | len_rcv = len(result) | |
480 | self.assertEqual(len_exp, len_rcv, | |
481 | self.msg.format('request message', 'write', | |
482 | len_exp, len_rcv)) | |
483 | ||
484 | msg = "Bad request message write: encoding mismatch" | |
485 | self.assertEqual(self.get, result, msg) | |
486 | ||
487 | def test_destroy_request_read(self): | |
488 | self.stream = BytearrayStream(self.destroy) | |
489 | ||
490 | request_message = messages.RequestMessage() | |
491 | request_message.read(self.stream) | |
492 | ||
493 | request_header = request_message.request_header | |
494 | msg = "Bad request header type: expected {0}, received{0}" | |
495 | self.assertIsInstance(request_header, messages.RequestHeader, | |
496 | msg.format(messages.RequestHeader, | |
497 | type(request_header))) | |
498 | ||
499 | protocol_version = request_header.protocol_version | |
500 | msg = "Bad protocol version type: expected {0}, received {1}" | |
501 | self.assertIsInstance(protocol_version, contents.ProtocolVersion, | |
502 | msg.format(contents.ProtocolVersion, | |
503 | type(protocol_version))) | |
504 | ||
505 | protocol_version_major = protocol_version.protocol_version_major | |
506 | msg = "Bad protocol version major type: expected {0}, received {1}" | |
507 | exp_type = contents.ProtocolVersion.ProtocolVersionMajor | |
508 | rcv_type = type(protocol_version_major) | |
509 | self.assertIsInstance(protocol_version_major, exp_type, | |
510 | msg.format(exp_type, rcv_type)) | |
511 | msg = "Bad protocol version major value: expected {0}, received {1}" | |
512 | self.assertEqual(1, protocol_version_major.value, | |
513 | msg.format(1, protocol_version_major.value)) | |
514 | ||
515 | protocol_version_minor = protocol_version.protocol_version_minor | |
516 | msg = "Bad protocol version minor type: expected {0}, received {1}" | |
517 | exp_type = contents.ProtocolVersion.ProtocolVersionMinor | |
518 | rcv_type = type(protocol_version_minor) | |
519 | self.assertIsInstance(protocol_version_minor, exp_type, | |
520 | msg.format(exp_type, rcv_type)) | |
521 | msg = "Bad protocol version minor value: expected {0}, received {1}" | |
522 | self.assertEqual(1, protocol_version_minor.value, | |
523 | msg.format(1, protocol_version_minor.value)) | |
524 | ||
525 | batch_count = request_header.batch_count | |
526 | msg = "Bad batch count type: expected {0}, received {1}" | |
527 | self.assertIsInstance(batch_count, contents.BatchCount, | |
528 | msg.format(contents.BatchCount, | |
529 | type(batch_count))) | |
530 | msg = "Bad batch count value: expected {0}, received {1}" | |
531 | self.assertEqual(1, batch_count.value, | |
532 | msg.format(1, batch_count.value)) | |
533 | ||
534 | batch_items = request_message.batch_items | |
535 | msg = "Bad batch items type: expected {0}, received {1}" | |
536 | self.assertIsInstance(batch_items, list, | |
537 | msg.format(list, type(batch_items))) | |
538 | self.assertEquals(1, len(batch_items), | |
539 | self.msg.format('batch items', 'length', | |
540 | 1, len(batch_items))) | |
541 | ||
542 | batch_item = batch_items[0] | |
543 | msg = "Bad batch item type: expected {0}, received {1}" | |
544 | self.assertIsInstance(batch_item, messages.RequestBatchItem, | |
545 | msg.format(messages.RequestBatchItem, | |
546 | type(batch_item))) | |
547 | ||
548 | operation = batch_item.operation | |
549 | msg = "Bad operation type: expected {0}, received {1}" | |
550 | self.assertIsInstance(operation, contents.Operation, | |
551 | msg.format(contents.Operation, | |
552 | type(operation))) | |
553 | msg = "Bad operation value: expected {0}, received {1}" | |
554 | exp_value = enums.Operation.DESTROY | |
555 | rcv_value = operation.enum | |
556 | self.assertEqual(exp_value, rcv_value, | |
557 | msg.format(exp_value, rcv_value)) | |
558 | ||
559 | request_payload = batch_item.request_payload | |
560 | msg = "Bad request payload type: expected {0}, received {1}" | |
561 | exp_type = operations.DestroyRequestPayload | |
562 | rcv_type = type(request_payload) | |
563 | self.assertIsInstance(request_payload, exp_type, | |
564 | msg.format(exp_type, rcv_type)) | |
565 | ||
566 | unique_identifier = request_payload.unique_identifier | |
567 | msg = "Bad unique identifier type: expected {0}, received {1}" | |
568 | self.assertIsInstance(unique_identifier, attr.UniqueIdentifier, | |
569 | msg.format(attr.UniqueIdentifier, | |
570 | type(unique_identifier))) | |
571 | msg = "Bad unique identifier value: expected {0}, received {1}" | |
572 | exp_value = 'fb4b5b9c-6188-4c63-8142-fe9c328129fc' | |
573 | rcv_value = unique_identifier.value | |
574 | self.assertEqual(exp_value, rcv_value, | |
575 | msg.format(exp_value, rcv_value)) | |
576 | ||
577 | def test_destroy_request_write(self): | |
578 | prot_ver = contents.ProtocolVersion.create(1, 1) | |
579 | ||
580 | batch_count = contents.BatchCount(1) | |
581 | req_header = messages.RequestHeader(protocol_version=prot_ver, | |
582 | batch_count=batch_count) | |
583 | ||
584 | operation = contents.Operation(enums.Operation.DESTROY) | |
585 | ||
586 | uuid = attr.UniqueIdentifier('fb4b5b9c-6188-4c63-8142-fe9c328129fc') | |
587 | request_payload = DestroyRequestPayload(unique_identifier=uuid) | |
588 | batch_item = messages.RequestBatchItem(operation=operation, | |
589 | request_payload=request_payload) | |
590 | request_message = messages.RequestMessage(request_header=req_header, | |
591 | batch_items=[batch_item]) | |
592 | request_message.write(self.stream) | |
593 | ||
594 | result = self.stream.read() | |
595 | len_exp = len(self.destroy) | |
596 | len_rcv = len(result) | |
597 | self.assertEqual(len_exp, len_rcv, | |
598 | self.msg.format('request message', 'write', | |
599 | len_exp, len_rcv)) | |
600 | ||
601 | msg = "Bad request message write: encoding mismatch" | |
602 | self.assertEqual(self.destroy, result, msg) | |
603 | ||
604 | def test_register_request_read(self): | |
605 | self.stream = BytearrayStream(self.register) | |
606 | ||
607 | request_message = messages.RequestMessage() | |
608 | request_message.read(self.stream) | |
609 | ||
610 | request_header = request_message.request_header | |
611 | msg = "Bad request header type: expected {0}, received{0}" | |
612 | self.assertIsInstance(request_header, messages.RequestHeader, | |
613 | msg.format(messages.RequestHeader, | |
614 | type(request_header))) | |
615 | ||
616 | protocol_version = request_header.protocol_version | |
617 | msg = "Bad protocol version type: expected {0}, received {1}" | |
618 | self.assertIsInstance(protocol_version, contents.ProtocolVersion, | |
619 | msg.format(contents.ProtocolVersion, | |
620 | type(protocol_version))) | |
621 | ||
622 | protocol_version_major = protocol_version.protocol_version_major | |
623 | msg = "Bad protocol version major type: expected {0}, received {1}" | |
624 | exp_type = contents.ProtocolVersion.ProtocolVersionMajor | |
625 | rcv_type = type(protocol_version_major) | |
626 | self.assertIsInstance(protocol_version_major, exp_type, | |
627 | msg.format(exp_type, rcv_type)) | |
628 | msg = "Bad protocol version major value: expected {0}, received {1}" | |
629 | self.assertEqual(1, protocol_version_major.value, | |
630 | msg.format(1, protocol_version_major.value)) | |
631 | ||
632 | protocol_version_minor = protocol_version.protocol_version_minor | |
633 | msg = "Bad protocol version minor type: expected {0}, received {1}" | |
634 | exp_type = contents.ProtocolVersion.ProtocolVersionMinor | |
635 | rcv_type = type(protocol_version_minor) | |
636 | self.assertIsInstance(protocol_version_minor, exp_type, | |
637 | msg.format(exp_type, rcv_type)) | |
638 | msg = "Bad protocol version minor value: expected {0}, received {1}" | |
639 | self.assertEqual(1, protocol_version_minor.value, | |
640 | msg.format(1, protocol_version_minor.value)) | |
641 | ||
642 | batch_count = request_header.batch_count | |
643 | msg = "Bad batch count type: expected {0}, received {1}" | |
644 | self.assertIsInstance(batch_count, contents.BatchCount, | |
645 | msg.format(contents.BatchCount, | |
646 | type(batch_count))) | |
647 | msg = "Bad batch count value: expected {0}, received {1}" | |
648 | self.assertEqual(1, batch_count.value, | |
649 | msg.format(1, batch_count.value)) | |
650 | ||
651 | batch_items = request_message.batch_items | |
652 | msg = "Bad batch items type: expected {0}, received {1}" | |
653 | self.assertIsInstance(batch_items, list, | |
654 | msg.format(list, type(batch_items))) | |
655 | self.assertEquals(1, len(batch_items), | |
656 | self.msg.format('batch items', 'length', | |
657 | 1, len(batch_items))) | |
658 | ||
659 | for batch_item in batch_items: | |
660 | msg = "Bad batch item type: expected {0}, received {1}" | |
661 | self.assertIsInstance(batch_item, messages.RequestBatchItem, | |
662 | msg.format(messages.RequestBatchItem, | |
663 | type(batch_item))) | |
664 | ||
665 | operation = batch_item.operation | |
666 | msg = "Bad operation type: expected {0}, received {1}" | |
667 | self.assertIsInstance(operation, contents.Operation, | |
668 | msg.format(contents.Operation, | |
669 | type(operation))) | |
670 | msg = "Bad operation value: expected {0}, received {1}" | |
671 | exp_value = enums.Operation.REGISTER | |
672 | rcv_value = operation.enum | |
673 | self.assertEqual(exp_value, rcv_value, | |
674 | msg.format(exp_value, rcv_value)) | |
675 | ||
676 | request_payload = batch_item.request_payload | |
677 | msg = "Bad request payload type: expected {0}, received {1}" | |
678 | exp_type = operations.RegisterRequestPayload | |
679 | rcv_type = type(request_payload) | |
680 | self.assertIsInstance(request_payload, exp_type, | |
681 | msg.format(exp_type, rcv_type)) | |
682 | ||
683 | object_type = request_payload.object_type | |
684 | msg = "Bad object type type: expected {0}, received {1}" | |
685 | self.assertIsInstance(object_type, attr.ObjectType, | |
686 | msg.format(attr.ObjectType, | |
687 | type(object_type))) | |
688 | msg = "Bad object type value: expected {0}, received {1}" | |
689 | exp_value = enums.ObjectType.TEMPLATE | |
690 | rcv_value = object_type.enum | |
691 | self.assertEqual(exp_value, rcv_value, | |
692 | msg.format(exp_value, rcv_value)) | |
693 | ||
694 | template_attribute = request_payload.template_attribute | |
695 | msg = "Bad template attribute type: expected {0}, received {1}" | |
696 | exp_type = objects.TemplateAttribute | |
697 | rcv_type = type(template_attribute) | |
698 | self.assertIsInstance(template_attribute, exp_type, | |
699 | msg.format(exp_type, rcv_type)) | |
700 | ||
701 | names = template_attribute.names | |
702 | exp_type = list | |
703 | rcv_type = type(names) | |
704 | msg = ErrorStrings.BAD_EXP_RECV.format('TemplateAttribute.names', | |
705 | 'type', '{0}', '{0}') | |
706 | self.assertIsInstance(names, exp_type, | |
707 | msg.format(exp_type, rcv_type)) | |
708 | exp_length = 0 | |
709 | rcv_length = len(names) | |
710 | msg = ErrorStrings.BAD_EXP_RECV.format('TemplateAttribute.names', | |
711 | 'length', '{0}', '{0}') | |
712 | self.assertEqual(exp_length, rcv_length, | |
713 | msg.format(exp_length, rcv_length)) | |
714 | ||
715 | attributes = template_attribute.attributes | |
716 | exp_type = list | |
717 | rcv_type = type(attributes) | |
718 | msg = ErrorStrings.BAD_EXP_RECV.format( | |
719 | 'TemplateAttribute.attributes', 'type', '{0}', '{1}') | |
720 | self.assertIsInstance(names, exp_type, | |
721 | msg.format(exp_type, rcv_type)) | |
722 | exp_length = 0 | |
723 | rcv_length = len(attributes) | |
724 | msg = ErrorStrings.BAD_EXP_RECV.format( | |
725 | 'TemplateAttribute.attributes', 'length', '{0}', '{1}') | |
726 | self.assertEqual(exp_length, rcv_length, | |
727 | msg.format(exp_length, rcv_length)) | |
728 | ||
729 | def test_register_request_write(self): | |
730 | prot_ver = contents.ProtocolVersion.create(1, 1) | |
731 | ||
732 | batch_count = contents.BatchCount(1) | |
733 | req_header = messages.RequestHeader(protocol_version=prot_ver, | |
734 | batch_count=batch_count) | |
735 | ||
736 | operation = contents.Operation(enums.Operation.REGISTER) | |
737 | ||
738 | object_type = attr.ObjectType(enums.ObjectType.TEMPLATE) | |
739 | tmpl_attr = objects.TemplateAttribute() | |
740 | ||
741 | attributes = [] | |
742 | ||
743 | name = objects.Attribute.AttributeName('Object Group') | |
744 | value = ObjectGroup('Group1') | |
745 | attribute = objects.Attribute(attribute_name=name, | |
746 | attribute_value=value) | |
747 | attributes.append(attribute) | |
748 | ||
749 | name = objects.Attribute.AttributeName('Application Specific ' | |
750 | 'Information') | |
751 | ap_n_name = 'ssl' | |
752 | ap_n_value = 'www.example.com' | |
753 | ap_n = ApplicationSpecificInformation.ApplicationNamespace(ap_n_name) | |
754 | ap_d = ApplicationSpecificInformation.ApplicationData(ap_n_value) | |
755 | value = ApplicationSpecificInformation(application_namespace=ap_n, | |
756 | application_data=ap_d) | |
757 | attribute = objects.Attribute(attribute_name=name, | |
758 | attribute_value=value) | |
759 | attributes.append(attribute) | |
760 | ||
761 | name = objects.Attribute.AttributeName('Contact Information') | |
762 | value = ContactInformation('Joe') | |
763 | attribute = objects.Attribute(attribute_name=name, | |
764 | attribute_value=value) | |
765 | attributes.append(attribute) | |
766 | ||
767 | name = objects.Attribute.AttributeName('x-Purpose') | |
768 | value = TextString('demonstration') | |
769 | attribute = objects.Attribute(attribute_name=name, | |
770 | attribute_value=value) | |
771 | attributes.append(attribute) | |
772 | ||
773 | name = objects.Attribute.AttributeName('Name') | |
774 | name_value = Name.NameValue('Template1') | |
775 | name_type = Name.NameType(NameType.UNINTERPRETED_TEXT_STRING) | |
776 | value = Name(name_value=name_value, | |
777 | name_type=name_type) | |
778 | attribute = objects.Attribute(attribute_name=name, | |
779 | attribute_value=value) | |
780 | attributes.append(attribute) | |
781 | ||
782 | template = Template(attributes=attributes) | |
783 | ||
784 | request_payload = RegisterRequestPayload(object_type=object_type, | |
785 | template_attribute=tmpl_attr, | |
786 | secret=template) | |
787 | batch_item = messages.RequestBatchItem(operation=operation, | |
788 | request_payload=request_payload) | |
789 | request_message = messages.RequestMessage(request_header=req_header, | |
790 | batch_items=[batch_item]) | |
791 | request_message.write(self.stream) | |
792 | ||
793 | result = self.stream.read() | |
794 | len_exp = len(self.register) | |
795 | len_rcv = len(result) | |
796 | self.assertEqual(len_exp, len_rcv, | |
797 | self.msg.format('request message', 'write', | |
798 | len_exp, len_rcv)) | |
799 | ||
800 | msg = "Bad request message write: encoding mismatch" | |
801 | self.assertEqual(self.register, result, msg) | |
802 | ||
803 | ||
804 | class TestResponseMessage(TestCase): | |
805 | ||
806 | def setUp(self): | |
807 | super(TestResponseMessage, self).setUp() | |
808 | self.stream = BytearrayStream() | |
809 | self.key_factory = KeyFactory() | |
810 | self.secret_factory = SecretFactory() | |
811 | self.msg = errors.ErrorStrings.BAD_EXP_RECV | |
812 | self.create = ( | |
813 | '\x42\x00\x7B\x01\x00\x00\x00\xC0\x42\x00\x7A\x01\x00\x00\x00\x48' | |
814 | '\x42\x00\x69\x01\x00\x00\x00\x20\x42\x00\x6A\x02\x00\x00\x00\x04' | |
815 | '\x00\x00\x00\x01\x00\x00\x00\x00\x42\x00\x6B\x02\x00\x00\x00\x04' | |
816 | '\x00\x00\x00\x01\x00\x00\x00\x00\x42\x00\x92\x09\x00\x00\x00\x08' | |
817 | '\x00\x00\x00\x00\x4F\x9A\x54\xE5\x42\x00\x0D\x02\x00\x00\x00\x04' | |
818 | '\x00\x00\x00\x01\x00\x00\x00\x00\x42\x00\x0F\x01\x00\x00\x00\x68' | |
819 | '\x42\x00\x5C\x05\x00\x00\x00\x04\x00\x00\x00\x01\x00\x00\x00\x00' | |
820 | '\x42\x00\x7F\x05\x00\x00\x00\x04\x00\x00\x00\x00\x00\x00\x00\x00' | |
821 | '\x42\x00\x7C\x01\x00\x00\x00\x40\x42\x00\x57\x05\x00\x00\x00\x04' | |
822 | '\x00\x00\x00\x02\x00\x00\x00\x00\x42\x00\x94\x07\x00\x00\x00\x24' | |
823 | '\x66\x62\x34\x62\x35\x62\x39\x63\x2D\x36\x31\x38\x38\x2D\x34\x63' | |
824 | '\x36\x33\x2D\x38\x31\x34\x32\x2D\x66\x65\x39\x63\x33\x32\x38\x31' | |
825 | '\x32\x39\x66\x63\x00\x00\x00\x00') | |
826 | self.register = ( | |
827 | '\x42\x00\x7B\x01\x00\x00\x00\xB0\x42\x00\x7A\x01\x00\x00\x00\x48' | |
828 | '\x42\x00\x69\x01\x00\x00\x00\x20\x42\x00\x6A\x02\x00\x00\x00\x04' | |
829 | '\x00\x00\x00\x01\x00\x00\x00\x00\x42\x00\x6B\x02\x00\x00\x00\x04' | |
830 | '\x00\x00\x00\x01\x00\x00\x00\x00\x42\x00\x92\x09\x00\x00\x00\x08' | |
831 | '\x00\x00\x00\x00\x4F\x9A\x54\xE5\x42\x00\x0D\x02\x00\x00\x00\x04' | |
832 | '\x00\x00\x00\x01\x00\x00\x00\x00\x42\x00\x0F\x01\x00\x00\x00\x58' | |
833 | '\x42\x00\x5C\x05\x00\x00\x00\x04\x00\x00\x00\x03\x00\x00\x00\x00' | |
834 | '\x42\x00\x7F\x05\x00\x00\x00\x04\x00\x00\x00\x00\x00\x00\x00\x00' | |
835 | '\x42\x00\x7C\x01\x00\x00\x00\x30\x42\x00\x94\x07\x00\x00\x00\x24' | |
836 | '\x35\x63\x39\x62\x38\x31\x65\x66\x2D\x34\x65\x65\x35\x2D\x34\x32' | |
837 | '\x63\x64\x2D\x62\x61\x32\x64\x2D\x63\x30\x30\x32\x66\x64\x64\x30' | |
838 | '\x63\x37\x62\x33\x00\x00\x00\x00') | |
839 | self.get = ( | |
840 | '\x42\x00\x7B\x01\x00\x00\x01\x28\x42\x00\x7A\x01\x00\x00\x00\x48' | |
841 | '\x42\x00\x69\x01\x00\x00\x00\x20\x42\x00\x6A\x02\x00\x00\x00\x04' | |
842 | '\x00\x00\x00\x01\x00\x00\x00\x00\x42\x00\x6B\x02\x00\x00\x00\x04' | |
843 | '\x00\x00\x00\x01\x00\x00\x00\x00\x42\x00\x92\x09\x00\x00\x00\x08' | |
844 | '\x00\x00\x00\x00\x4F\x9A\x54\xE7\x42\x00\x0D\x02\x00\x00\x00\x04' | |
845 | '\x00\x00\x00\x01\x00\x00\x00\x00\x42\x00\x0F\x01\x00\x00\x00\xD0' | |
846 | '\x42\x00\x5C\x05\x00\x00\x00\x04\x00\x00\x00\x0A\x00\x00\x00\x00' | |
847 | '\x42\x00\x7F\x05\x00\x00\x00\x04\x00\x00\x00\x00\x00\x00\x00\x00' | |
848 | '\x42\x00\x7C\x01\x00\x00\x00\xA8\x42\x00\x57\x05\x00\x00\x00\x04' | |
849 | '\x00\x00\x00\x02\x00\x00\x00\x00\x42\x00\x94\x07\x00\x00\x00\x24' | |
850 | '\x34\x39\x61\x31\x63\x61\x38\x38\x2D\x36\x62\x65\x61\x2D\x34\x66' | |
851 | '\x62\x32\x2D\x62\x34\x35\x30\x2D\x37\x65\x35\x38\x38\x30\x32\x63' | |
852 | '\x33\x30\x33\x38\x00\x00\x00\x00\x42\x00\x8F\x01\x00\x00\x00\x60' | |
853 | '\x42\x00\x40\x01\x00\x00\x00\x58\x42\x00\x42\x05\x00\x00\x00\x04' | |
854 | '\x00\x00\x00\x01\x00\x00\x00\x00\x42\x00\x45\x01\x00\x00\x00\x20' | |
855 | '\x42\x00\x43\x08\x00\x00\x00\x18\x73\x67\x57\x80\x51\x01\x2A\x6D' | |
856 | '\x13\x4A\x85\x5E\x25\xC8\xCD\x5E\x4C\xA1\x31\x45\x57\x29\xD3\xC8' | |
857 | '\x42\x00\x28\x05\x00\x00\x00\x04\x00\x00\x00\x02\x00\x00\x00\x00' | |
858 | '\x42\x00\x2A\x02\x00\x00\x00\x04\x00\x00\x00\xA8\x00\x00\x00\x00') | |
859 | self.destroy = ( | |
860 | '\x42\x00\x7B\x01\x00\x00\x00\xB0\x42\x00\x7A\x01\x00\x00\x00\x48' | |
861 | '\x42\x00\x69\x01\x00\x00\x00\x20\x42\x00\x6A\x02\x00\x00\x00\x04' | |
862 | '\x00\x00\x00\x01\x00\x00\x00\x00\x42\x00\x6B\x02\x00\x00\x00\x04' | |
863 | '\x00\x00\x00\x01\x00\x00\x00\x00\x42\x00\x92\x09\x00\x00\x00\x08' | |
864 | '\x00\x00\x00\x00\x4F\x9A\x54\xE5\x42\x00\x0D\x02\x00\x00\x00\x04' | |
865 | '\x00\x00\x00\x01\x00\x00\x00\x00\x42\x00\x0F\x01\x00\x00\x00\x58' | |
866 | '\x42\x00\x5C\x05\x00\x00\x00\x04\x00\x00\x00\x14\x00\x00\x00\x00' | |
867 | '\x42\x00\x7F\x05\x00\x00\x00\x04\x00\x00\x00\x00\x00\x00\x00\x00' | |
868 | '\x42\x00\x7C\x01\x00\x00\x00\x30\x42\x00\x94\x07\x00\x00\x00\x24' | |
869 | '\x66\x62\x34\x62\x35\x62\x39\x63\x2D\x36\x31\x38\x38\x2D\x34\x63' | |
870 | '\x36\x33\x2D\x38\x31\x34\x32\x2D\x66\x65\x39\x63\x33\x32\x38\x31' | |
871 | '\x32\x39\x66\x63\x00\x00\x00\x00') | |
872 | ||
873 | def tearDown(self): | |
874 | super(TestResponseMessage, self).tearDown() | |
875 | ||
876 | def test_create_response_read(self): | |
877 | self.stream = BytearrayStream(str(self.create)) | |
878 | ||
879 | response_message = messages.ResponseMessage() | |
880 | response_message.read(self.stream) | |
881 | ||
882 | response_header = response_message.response_header | |
883 | self.assertIsInstance(response_header, messages.ResponseHeader, | |
884 | self.msg.format('response header', 'type', | |
885 | messages.ResponseHeader, | |
886 | type(response_header))) | |
887 | protocol_version = response_header.protocol_version | |
888 | self.assertIsInstance(protocol_version, contents.ProtocolVersion, | |
889 | self.msg.format('response header', 'value', | |
890 | contents.ProtocolVersion, | |
891 | type(protocol_version))) | |
892 | ||
893 | protocol_version_major = protocol_version.protocol_version_major | |
894 | exp_type = contents.ProtocolVersion.ProtocolVersionMajor | |
895 | rcv_type = type(protocol_version_major) | |
896 | self.assertIsInstance(protocol_version_major, exp_type, | |
897 | self.msg.format('protocol version major', | |
898 | 'type', exp_type, rcv_type)) | |
899 | self.assertEqual(1, protocol_version_major.value, | |
900 | self.msg.format('protocol version major', 'value', | |
901 | 1, protocol_version_major.value)) | |
902 | ||
903 | protocol_version_minor = protocol_version.protocol_version_minor | |
904 | exp_type = contents.ProtocolVersion.ProtocolVersionMinor | |
905 | rcv_type = type(protocol_version_minor) | |
906 | self.assertIsInstance(protocol_version_minor, | |
907 | contents.ProtocolVersion.ProtocolVersionMinor, | |
908 | self.msg.format('protocol version minor', | |
909 | 'type', exp_type, rcv_type)) | |
910 | self.assertEqual(1, protocol_version_minor.value, | |
911 | self.msg.format('protocol version minor', 'value', | |
912 | 1, protocol_version_minor.value)) | |
913 | ||
914 | time_stamp = response_header.time_stamp | |
915 | value = 0x4f9a54e5 # Fri Apr 27 10:12:21 CEST 2012 | |
916 | self.assertIsInstance(time_stamp, contents.TimeStamp, | |
917 | self.msg.format('time stamp', 'value', | |
918 | contents.TimeStamp, | |
919 | type(time_stamp))) | |
920 | self.assertEqual(time_stamp.value, value, | |
921 | self.msg.format('time stamp', 'value', | |
922 | time_stamp.value, value)) | |
923 | ||
924 | batch_count = response_header.batch_count | |
925 | self.assertIsInstance(batch_count, contents.BatchCount, | |
926 | self.msg.format('batch count', 'type', | |
927 | contents.BatchCount, | |
928 | type(batch_count))) | |
929 | self.assertEqual(1, batch_count.value, | |
930 | self.msg.format('batch count', 'value', 1, | |
931 | batch_count.value)) | |
932 | ||
933 | batch_items = response_message.batch_items | |
934 | self.assertIsInstance(batch_items, list, | |
935 | self.msg.format('batch items', 'type', | |
936 | list, type(batch_items))) | |
937 | ||
938 | for batch_item in batch_items: | |
939 | self.assertIsInstance(batch_item, messages.ResponseBatchItem, | |
940 | self.msg.format('batch item', 'type', | |
941 | messages.ResponseBatchItem, | |
942 | type(batch_item))) | |
943 | ||
944 | operation = batch_item.operation | |
945 | self.assertIsInstance(operation, contents.Operation, | |
946 | self.msg.format('operation', 'type', | |
947 | contents.Operation, | |
948 | type(operation))) | |
949 | self.assertEqual(enums.Operation.CREATE, operation.enum, | |
950 | self.msg.format('operation', 'value', | |
951 | enums.Operation.CREATE, | |
952 | operation.enum)) | |
953 | ||
954 | result_status = batch_item.result_status | |
955 | self.assertIsInstance(result_status, contents.ResultStatus, | |
956 | self.msg.format('result status', 'type', | |
957 | contents.ResultStatus, | |
958 | type(result_status))) | |
959 | self.assertEqual(enums.ResultStatus.SUCCESS, result_status.enum, | |
960 | self.msg.format('result status', 'value', | |
961 | enums.ResultStatus.SUCCESS, | |
962 | result_status.enum)) | |
963 | ||
964 | response_payload = batch_item.response_payload | |
965 | exp_type = operations.CreateResponsePayload | |
966 | rcv_type = type(response_payload) | |
967 | self.assertIsInstance(response_payload, exp_type, | |
968 | self.msg.format('response payload', 'type', | |
969 | exp_type, rcv_type)) | |
970 | ||
971 | object_type = response_payload.object_type | |
972 | self.assertIsInstance(object_type, attr.ObjectType, | |
973 | self.msg.format('object type', 'type', | |
974 | attr.ObjectType, | |
975 | type(object_type))) | |
976 | self.assertEqual(enums.ObjectType.SYMMETRIC_KEY, object_type.enum, | |
977 | self.msg.format('object type', 'value', | |
978 | enums.ObjectType.SYMMETRIC_KEY, | |
979 | object_type.enum)) | |
980 | ||
981 | unique_identifier = response_payload.unique_identifier | |
982 | value = 'fb4b5b9c-6188-4c63-8142-fe9c328129fc' | |
983 | self.assertIsInstance(unique_identifier, attr.UniqueIdentifier, | |
984 | self.msg.format('unique identifier', 'type', | |
985 | attr.UniqueIdentifier, | |
986 | type(unique_identifier))) | |
987 | self.assertEqual(value, unique_identifier.value, | |
988 | self.msg.format('unique identifier', 'value', | |
989 | unique_identifier.value, value)) | |
990 | ||
991 | def test_create_response_write(self): | |
992 | prot_ver = contents.ProtocolVersion.create(1, 1) | |
993 | ||
994 | # Fri Apr 27 10:12:21 CEST 2012 | |
995 | time_stamp = contents.TimeStamp(0x4f9a54e5) | |
996 | ||
997 | batch_count = contents.BatchCount(1) | |
998 | response_header = messages.ResponseHeader(protocol_version=prot_ver, | |
999 | time_stamp=time_stamp, | |
1000 | batch_count=batch_count) | |
1001 | operation = contents.Operation(enums.Operation.CREATE) | |
1002 | result_status = contents.ResultStatus(enums.ResultStatus.SUCCESS) | |
1003 | object_type = attr.ObjectType(enums.ObjectType.SYMMETRIC_KEY) | |
1004 | ||
1005 | uuid = 'fb4b5b9c-6188-4c63-8142-fe9c328129fc' | |
1006 | uniq_id = attr.UniqueIdentifier(uuid) | |
1007 | resp_pl = operations.CreateResponsePayload(object_type=object_type, | |
1008 | unique_identifier=uniq_id) | |
1009 | batch_item = messages.ResponseBatchItem(operation=operation, | |
1010 | result_status=result_status, | |
1011 | response_payload=resp_pl) | |
1012 | rm = messages.ResponseMessage(response_header=response_header, | |
1013 | batch_items=[batch_item]) | |
1014 | rm.write(self.stream) | |
1015 | ||
1016 | result = self.stream.read() | |
1017 | len_exp = len(self.create) | |
1018 | len_rcv = len(result) | |
1019 | self.assertEqual(len_exp, len_rcv, | |
1020 | self.msg.format('response message', 'write', len_exp, | |
1021 | len_rcv)) | |
1022 | ||
1023 | msg = "Bad response message write: encoding mismatch" | |
1024 | self.assertEqual(self.create, result, msg) | |
1025 | ||
1026 | def test_get_response_read(self): | |
1027 | self.stream = BytearrayStream(str(self.get)) | |
1028 | ||
1029 | response_message = messages.ResponseMessage() | |
1030 | response_message.read(self.stream) | |
1031 | ||
1032 | response_header = response_message.response_header | |
1033 | self.assertIsInstance(response_header, messages.ResponseHeader, | |
1034 | self.msg.format('response header', 'type', | |
1035 | messages.ResponseHeader, | |
1036 | type(response_header))) | |
1037 | protocol_version = response_header.protocol_version | |
1038 | self.assertIsInstance(protocol_version, contents.ProtocolVersion, | |
1039 | self.msg.format('response header', 'value', | |
1040 | contents.ProtocolVersion, | |
1041 | type(protocol_version))) | |
1042 | ||
1043 | protocol_version_major = protocol_version.protocol_version_major | |
1044 | exp_type = contents.ProtocolVersion.ProtocolVersionMajor | |
1045 | rcv_type = type(protocol_version_major) | |
1046 | self.assertIsInstance(protocol_version_major, exp_type, | |
1047 | self.msg.format('protocol version major', 'type', | |
1048 | exp_type, rcv_type)) | |
1049 | self.assertEqual(1, protocol_version_major.value, | |
1050 | self.msg.format('protocol version major', 'value', | |
1051 | 1, protocol_version_major.value)) | |
1052 | ||
1053 | protocol_version_minor = protocol_version.protocol_version_minor | |
1054 | exp_type = contents.ProtocolVersion.ProtocolVersionMinor | |
1055 | rcv_type = type(protocol_version_minor) | |
1056 | self.assertIsInstance(protocol_version_minor, exp_type, | |
1057 | self.msg.format('protocol version minor', 'type', | |
1058 | exp_type, rcv_type)) | |
1059 | self.assertEqual(1, protocol_version_minor.value, | |
1060 | self.msg.format('protocol version minor', 'value', | |
1061 | 1, protocol_version_minor.value)) | |
1062 | ||
1063 | time_stamp = response_header.time_stamp | |
1064 | value = 0x4f9a54e7 # Fri Apr 27 10:12:23 CEST 2012 | |
1065 | self.assertIsInstance(time_stamp, contents.TimeStamp, | |
1066 | self.msg.format('time stamp', 'value', | |
1067 | contents.TimeStamp, | |
1068 | type(time_stamp))) | |
1069 | self.assertEqual(time_stamp.value, value, | |
1070 | self.msg.format('time stamp', 'value', | |
1071 | time_stamp.value, value)) | |
1072 | ||
1073 | batch_count = response_header.batch_count | |
1074 | self.assertIsInstance(batch_count, contents.BatchCount, | |
1075 | self.msg.format('batch count', 'type', | |
1076 | contents.BatchCount, | |
1077 | type(batch_count))) | |
1078 | self.assertEqual(1, batch_count.value, | |
1079 | self.msg.format('batch count', 'value', 1, | |
1080 | batch_count.value)) | |
1081 | ||
1082 | batch_items = response_message.batch_items | |
1083 | self.assertIsInstance(batch_items, list, | |
1084 | self.msg.format('batch items', 'type', | |
1085 | list, type(batch_items))) | |
1086 | ||
1087 | for batch_item in batch_items: | |
1088 | self.assertIsInstance(batch_item, messages.ResponseBatchItem, | |
1089 | self.msg.format('batch item', 'type', | |
1090 | messages.ResponseBatchItem, | |
1091 | type(batch_item))) | |
1092 | ||
1093 | operation = batch_item.operation | |
1094 | self.assertIsInstance(operation, contents.Operation, | |
1095 | self.msg.format('operation', 'type', | |
1096 | contents.Operation, | |
1097 | type(operation))) | |
1098 | self.assertEqual(enums.Operation.GET, operation.enum, | |
1099 | self.msg.format('operation', 'value', | |
1100 | enums.Operation.GET, | |
1101 | operation.enum)) | |
1102 | ||
1103 | result_status = batch_item.result_status | |
1104 | self.assertIsInstance(result_status, contents.ResultStatus, | |
1105 | self.msg.format('result status', 'type', | |
1106 | contents.ResultStatus, | |
1107 | type(result_status))) | |
1108 | self.assertEqual(enums.ResultStatus.SUCCESS, result_status.enum, | |
1109 | self.msg.format('result status', 'value', | |
1110 | enums.ResultStatus.SUCCESS, | |
1111 | result_status.enum)) | |
1112 | ||
1113 | response_payload = batch_item.response_payload | |
1114 | exp_type = operations.GetResponsePayload | |
1115 | rcv_type = type(response_payload) | |
1116 | self.assertIsInstance(response_payload, exp_type, | |
1117 | self.msg.format('response payload', 'type', | |
1118 | exp_type, rcv_type)) | |
1119 | ||
1120 | object_type = response_payload.object_type | |
1121 | self.assertIsInstance(object_type, attr.ObjectType, | |
1122 | self.msg.format('object type', 'type', | |
1123 | attr.ObjectType, | |
1124 | type(object_type))) | |
1125 | self.assertEqual(enums.ObjectType.SYMMETRIC_KEY, object_type.enum, | |
1126 | self.msg.format('object type', 'value', | |
1127 | enums.ObjectType.SYMMETRIC_KEY, | |
1128 | object_type.enum)) | |
1129 | ||
1130 | unique_identifier = response_payload.unique_identifier | |
1131 | value = '49a1ca88-6bea-4fb2-b450-7e58802c3038' | |
1132 | self.assertIsInstance(unique_identifier, attr.UniqueIdentifier, | |
1133 | self.msg.format('unique identifier', 'type', | |
1134 | attr.UniqueIdentifier, | |
1135 | type(unique_identifier))) | |
1136 | self.assertEqual(value, unique_identifier.value, | |
1137 | self.msg.format('unique identifier', 'value', | |
1138 | unique_identifier.value, value)) | |
1139 | ||
1140 | secret = response_payload.secret | |
1141 | self.assertIsInstance(secret, SymmetricKey, | |
1142 | self.msg.format('secret', 'type', | |
1143 | SymmetricKey, type(secret))) | |
1144 | ||
1145 | key_block = secret.key_block | |
1146 | self.assertIsInstance(key_block, objects.KeyBlock, | |
1147 | self.msg.format('key_block', 'type', | |
1148 | objects.KeyBlock, | |
1149 | type(key_block))) | |
1150 | ||
1151 | key_format_type = key_block.key_format_type | |
1152 | exp_type = objects.KeyBlock.KeyFormatType | |
1153 | rcv_type = type(key_format_type) | |
1154 | self.assertIsInstance(key_format_type, exp_type, | |
1155 | self.msg.format('key_format_type', 'type', | |
1156 | exp_type, rcv_type)) | |
1157 | ||
1158 | key_value = key_block.key_value | |
1159 | self.assertIsInstance(key_value, objects.KeyValue, | |
1160 | self.msg.format('key_value', 'type', | |
1161 | objects.KeyValue, | |
1162 | type(key_value))) | |
1163 | ||
1164 | key_material = key_value.key_value.key_material | |
1165 | value = bytearray('\x73\x67\x57\x80\x51\x01\x2A\x6D\x13\x4A\x85' | |
1166 | '\x5E\x25\xC8\xCD\x5E\x4C\xA1\x31\x45\x57\x29' | |
1167 | '\xD3\xC8') | |
1168 | self.assertIsInstance(key_material, RawKey, | |
1169 | self.msg.format('key_material', 'type', | |
1170 | RawKey, | |
1171 | type(key_material))) | |
1172 | exp = utils.hexlify_bytearray(value) | |
1173 | obs = utils.hexlify_bytearray(key_material.value) | |
1174 | self.assertEqual(exp, obs, self.msg.format('key_material', 'value', | |
1175 | exp, obs)) | |
1176 | ||
1177 | cryptographic_algorithm = key_block.cryptographic_algorithm | |
1178 | exp_type = attr.CryptographicAlgorithm | |
1179 | rcv_type = type(cryptographic_algorithm) | |
1180 | self.assertIsInstance(cryptographic_algorithm, exp_type, | |
1181 | self.msg.format('cryptographic_algorithm', | |
1182 | 'type', exp_type, rcv_type)) | |
1183 | exp = enums.CryptographicAlgorithm.TRIPLE_DES | |
1184 | obs = cryptographic_algorithm.enum | |
1185 | self.assertEqual(exp, obs, | |
1186 | self.msg.format('cryptographic_algorithm', | |
1187 | 'value', exp, obs)) | |
1188 | ||
1189 | cryptographic_length = key_block.cryptographic_length | |
1190 | self.assertIsInstance(cryptographic_length, | |
1191 | attr.CryptographicLength, | |
1192 | self.msg.format('cryptographic_length', | |
1193 | 'type', | |
1194 | attr.CryptographicLength, | |
1195 | type(cryptographic_length))) | |
1196 | exp = 168 | |
1197 | obs = cryptographic_length.value | |
1198 | self.assertEqual(exp, obs, self.msg.format('cryptographic_length', | |
1199 | 'value', exp, obs)) | |
1200 | ||
1201 | def test_get_response_write(self): | |
1202 | prot_ver = contents.ProtocolVersion.create(1, 1) | |
1203 | ||
1204 | # Fri Apr 27 10:12:23 CEST 2012 | |
1205 | time_stamp = contents.TimeStamp(0x4f9a54e7) | |
1206 | ||
1207 | batch_count = contents.BatchCount(1) | |
1208 | response_header = messages.ResponseHeader(protocol_version=prot_ver, | |
1209 | time_stamp=time_stamp, | |
1210 | batch_count=batch_count) | |
1211 | operation = contents.Operation(enums.Operation.GET) | |
1212 | result_status = contents.ResultStatus(enums.ResultStatus.SUCCESS) | |
1213 | object_type = attr.ObjectType(enums.ObjectType.SYMMETRIC_KEY) | |
1214 | ||
1215 | uuid = '49a1ca88-6bea-4fb2-b450-7e58802c3038' | |
1216 | uniq_id = attr.UniqueIdentifier(uuid) | |
1217 | ||
1218 | key_type = enums.KeyFormatType.RAW | |
1219 | key = bytearray('\x73\x67\x57\x80\x51\x01\x2A\x6D\x13\x4A\x85\x5E\x25' | |
1220 | '\xC8\xCD\x5E\x4C\xA1\x31\x45\x57\x29\xD3\xC8') | |
1221 | ||
1222 | crypto_algorithm = enums.CryptographicAlgorithm.TRIPLE_DES | |
1223 | cryptographic_length = 168 | |
1224 | value = {'key_format_type': key_type, | |
1225 | 'key_value': {'bytes': key}, | |
1226 | 'cryptographic_algorithm': crypto_algorithm, | |
1227 | 'cryptographic_length': cryptographic_length} | |
1228 | secret = self.secret_factory.create_secret(ObjectType.SYMMETRIC_KEY, | |
1229 | value) | |
1230 | resp_pl = operations.GetResponsePayload(object_type=object_type, | |
1231 | unique_identifier=uniq_id, | |
1232 | secret=secret) | |
1233 | batch_item = messages.ResponseBatchItem(operation=operation, | |
1234 | result_status=result_status, | |
1235 | response_payload=resp_pl) | |
1236 | rm = messages.ResponseMessage(response_header=response_header, | |
1237 | batch_items=[batch_item]) | |
1238 | rm.write(self.stream) | |
1239 | ||
1240 | result = self.stream.read() | |
1241 | len_exp = len(self.get) | |
1242 | len_rcv = len(result) | |
1243 | self.assertEqual(len_exp, len_rcv, | |
1244 | self.msg.format('get response message', 'write', | |
1245 | len_exp, len_rcv)) | |
1246 | ||
1247 | msg = "Bad get response message write: encoding mismatch" | |
1248 | print self.get | |
1249 | print result | |
1250 | self.assertEqual(self.get, result, msg) | |
1251 | ||
1252 | def test_destroy_response_read(self): | |
1253 | self.stream = BytearrayStream(self.destroy) | |
1254 | ||
1255 | response_message = messages.ResponseMessage() | |
1256 | response_message.read(self.stream) | |
1257 | ||
1258 | response_header = response_message.response_header | |
1259 | msg = "Bad response header type: expected {0}, received{1}" | |
1260 | self.assertIsInstance(response_header, messages.ResponseHeader, | |
1261 | msg.format(messages.ResponseHeader, | |
1262 | type(response_header))) | |
1263 | ||
1264 | protocol_version = response_header.protocol_version | |
1265 | msg = "Bad protocol version type: expected {0}, received {1}" | |
1266 | self.assertIsInstance(protocol_version, contents.ProtocolVersion, | |
1267 | msg.format(contents.ProtocolVersion, | |
1268 | type(protocol_version))) | |
1269 | ||
1270 | protocol_version_major = protocol_version.protocol_version_major | |
1271 | msg = "Bad protocol version major type: expected {0}, received {1}" | |
1272 | exp_type = contents.ProtocolVersion.ProtocolVersionMajor | |
1273 | rcv_type = type(protocol_version_major) | |
1274 | self.assertIsInstance(protocol_version_major, exp_type, | |
1275 | msg.format(exp_type, rcv_type)) | |
1276 | msg = "Bad protocol version major value: expected {0}, received {1}" | |
1277 | self.assertEqual(1, protocol_version_major.value, | |
1278 | msg.format(1, protocol_version_major.value)) | |
1279 | ||
1280 | protocol_version_minor = protocol_version.protocol_version_minor | |
1281 | msg = "Bad protocol version minor type: expected {0}, received {1}" | |
1282 | exp_type = contents.ProtocolVersion.ProtocolVersionMinor | |
1283 | rcv_type = type(protocol_version_minor) | |
1284 | self.assertIsInstance(protocol_version_minor, exp_type, | |
1285 | msg.format(exp_type, rcv_type)) | |
1286 | msg = "Bad protocol version minor value: expected {0}, received {1}" | |
1287 | self.assertEqual(1, protocol_version_minor.value, | |
1288 | msg.format(1, protocol_version_minor.value)) | |
1289 | ||
1290 | time_stamp = response_header.time_stamp | |
1291 | value = 0x4f9a54e5 # Fri Apr 27 10:12:21 CEST 2012 | |
1292 | self.assertIsInstance(time_stamp, contents.TimeStamp, | |
1293 | self.msg.format('time stamp', 'value', | |
1294 | contents.TimeStamp, | |
1295 | type(time_stamp))) | |
1296 | self.assertEqual(time_stamp.value, value, | |
1297 | self.msg.format('time stamp', 'value', | |
1298 | time_stamp.value, value)) | |
1299 | ||
1300 | batch_count = response_header.batch_count | |
1301 | msg = "Bad batch count type: expected {0}, received {1}" | |
1302 | self.assertIsInstance(batch_count, contents.BatchCount, | |
1303 | msg.format(contents.BatchCount, | |
1304 | type(batch_count))) | |
1305 | msg = "Bad batch count value: expected {0}, received {1}" | |
1306 | self.assertEqual(1, batch_count.value, | |
1307 | msg.format(1, batch_count.value)) | |
1308 | ||
1309 | batch_items = response_message.batch_items | |
1310 | msg = "Bad batch items type: expected {0}, received {1}" | |
1311 | self.assertIsInstance(batch_items, list, | |
1312 | msg.format(list, type(batch_items))) | |
1313 | self.assertEquals(1, len(batch_items), | |
1314 | self.msg.format('batch items', 'length', | |
1315 | 1, len(batch_items))) | |
1316 | ||
1317 | for batch_item in batch_items: | |
1318 | msg = "Bad batch item type: expected {0}, received {1}" | |
1319 | self.assertIsInstance(batch_item, messages.ResponseBatchItem, | |
1320 | msg.format(messages.ResponseBatchItem, | |
1321 | type(batch_item))) | |
1322 | ||
1323 | operation = batch_item.operation | |
1324 | msg = "Bad operation type: expected {0}, received {1}" | |
1325 | self.assertIsInstance(operation, contents.Operation, | |
1326 | msg.format(contents.Operation, | |
1327 | type(operation))) | |
1328 | msg = "Bad operation value: expected {0}, received {1}" | |
1329 | exp_value = enums.Operation.DESTROY | |
1330 | rcv_value = operation.enum | |
1331 | self.assertEqual(exp_value, rcv_value, | |
1332 | msg.format(exp_value, rcv_value)) | |
1333 | ||
1334 | result_status = batch_item.result_status | |
1335 | self.assertIsInstance(result_status, contents.ResultStatus, | |
1336 | self.msg.format('result status', 'type', | |
1337 | contents.ResultStatus, | |
1338 | type(result_status))) | |
1339 | self.assertEqual(enums.ResultStatus.SUCCESS, result_status.enum, | |
1340 | self.msg.format('result status', 'value', | |
1341 | enums.ResultStatus.SUCCESS, | |
1342 | result_status.enum)) | |
1343 | ||
1344 | response_payload = batch_item.response_payload | |
1345 | msg = "Bad response payload type: expected {0}, received {1}" | |
1346 | exp_type = operations.DestroyResponsePayload | |
1347 | rcv_type = type(response_payload) | |
1348 | self.assertIsInstance(response_payload, exp_type, | |
1349 | msg.format(exp_type, rcv_type)) | |
1350 | ||
1351 | unique_identifier = response_payload.unique_identifier | |
1352 | msg = "Bad unique identifier type: expected {0}, received {1}" | |
1353 | self.assertIsInstance(unique_identifier, attr.UniqueIdentifier, | |
1354 | msg.format(attr.UniqueIdentifier, | |
1355 | type(unique_identifier))) | |
1356 | msg = "Bad unique identifier value: expected {0}, received {1}" | |
1357 | exp_value = 'fb4b5b9c-6188-4c63-8142-fe9c328129fc' | |
1358 | rcv_value = unique_identifier.value | |
1359 | self.assertEqual(exp_value, rcv_value, | |
1360 | msg.format(exp_value, rcv_value)) | |
1361 | ||
1362 | def test_destroy_response_write(self): | |
1363 | prot_ver = contents.ProtocolVersion.create(1, 1) | |
1364 | ||
1365 | # Fri Apr 27 10:12:21 CEST 2012 | |
1366 | time_stamp = contents.TimeStamp(0x4f9a54e5) | |
1367 | ||
1368 | batch_count = contents.BatchCount(1) | |
1369 | resp_hdr = messages.ResponseHeader(protocol_version=prot_ver, | |
1370 | time_stamp=time_stamp, | |
1371 | batch_count=batch_count) | |
1372 | ||
1373 | operation = contents.Operation(enums.Operation.DESTROY) | |
1374 | result_status = contents.ResultStatus(enums.ResultStatus.SUCCESS) | |
1375 | ||
1376 | uuid = attr.UniqueIdentifier('fb4b5b9c-6188-4c63-8142-fe9c328129fc') | |
1377 | resp_pl = DestroyResponsePayload(unique_identifier=uuid) | |
1378 | batch_item = messages.ResponseBatchItem(operation=operation, | |
1379 | result_status=result_status, | |
1380 | response_payload=resp_pl) | |
1381 | response_message = messages.ResponseMessage(response_header=resp_hdr, | |
1382 | batch_items=[batch_item]) | |
1383 | response_message.write(self.stream) | |
1384 | ||
1385 | result = self.stream.read() | |
1386 | len_exp = len(self.destroy) | |
1387 | len_rcv = len(result) | |
1388 | self.assertEqual(len_exp, len_rcv, | |
1389 | self.msg.format('response message', 'write', | |
1390 | len_exp, len_rcv)) | |
1391 | ||
1392 | msg = "Bad response message write: encoding mismatch" | |
1393 | self.assertEqual(self.destroy, result, msg) | |
1394 | ||
1395 | def test_register_response_read(self): | |
1396 | self.stream = BytearrayStream(self.register) | |
1397 | ||
1398 | response_message = messages.ResponseMessage() | |
1399 | response_message.read(self.stream) | |
1400 | ||
1401 | response_header = response_message.response_header | |
1402 | msg = "Bad response header type: expected {0}, received{1}" | |
1403 | self.assertIsInstance(response_header, messages.ResponseHeader, | |
1404 | msg.format(messages.ResponseHeader, | |
1405 | type(response_header))) | |
1406 | ||
1407 | protocol_version = response_header.protocol_version | |
1408 | msg = "Bad protocol version type: expected {0}, received {1}" | |
1409 | self.assertIsInstance(protocol_version, contents.ProtocolVersion, | |
1410 | msg.format(contents.ProtocolVersion, | |
1411 | type(protocol_version))) | |
1412 | ||
1413 | protocol_version_major = protocol_version.protocol_version_major | |
1414 | msg = "Bad protocol version major type: expected {0}, received {1}" | |
1415 | exp_type = contents.ProtocolVersion.ProtocolVersionMajor | |
1416 | rcv_type = type(protocol_version_major) | |
1417 | self.assertIsInstance(protocol_version_major, exp_type, | |
1418 | msg.format(exp_type, rcv_type)) | |
1419 | msg = "Bad protocol version major value: expected {0}, received {1}" | |
1420 | self.assertEqual(1, protocol_version_major.value, | |
1421 | msg.format(1, protocol_version_major.value)) | |
1422 | ||
1423 | protocol_version_minor = protocol_version.protocol_version_minor | |
1424 | msg = "Bad protocol version minor type: expected {0}, received {1}" | |
1425 | exp_type = contents.ProtocolVersion.ProtocolVersionMinor | |
1426 | rcv_type = type(protocol_version_minor) | |
1427 | self.assertIsInstance(protocol_version_minor, exp_type, | |
1428 | msg.format(exp_type, rcv_type)) | |
1429 | msg = "Bad protocol version minor value: expected {0}, received {1}" | |
1430 | self.assertEqual(1, protocol_version_minor.value, | |
1431 | msg.format(1, protocol_version_minor.value)) | |
1432 | ||
1433 | time_stamp = response_header.time_stamp | |
1434 | value = 0x4f9a54e5 # Fri Apr 27 10:12:21 CEST 2012 | |
1435 | self.assertIsInstance(time_stamp, contents.TimeStamp, | |
1436 | self.msg.format('time stamp', 'value', | |
1437 | contents.TimeStamp, | |
1438 | type(time_stamp))) | |
1439 | self.assertEqual(time_stamp.value, value, | |
1440 | self.msg.format('time stamp', 'value', | |
1441 | time_stamp.value, value)) | |
1442 | ||
1443 | batch_count = response_header.batch_count | |
1444 | msg = "Bad batch count type: expected {0}, received {1}" | |
1445 | self.assertIsInstance(batch_count, contents.BatchCount, | |
1446 | msg.format(contents.BatchCount, | |
1447 | type(batch_count))) | |
1448 | msg = "Bad batch count value: expected {0}, received {1}" | |
1449 | self.assertEqual(1, batch_count.value, | |
1450 | msg.format(1, batch_count.value)) | |
1451 | ||
1452 | batch_items = response_message.batch_items | |
1453 | msg = "Bad batch items type: expected {0}, received {1}" | |
1454 | self.assertIsInstance(batch_items, list, | |
1455 | msg.format(list, type(batch_items))) | |
1456 | self.assertEquals(1, len(batch_items), | |
1457 | self.msg.format('batch items', 'length', | |
1458 | 1, len(batch_items))) | |
1459 | ||
1460 | for batch_item in batch_items: | |
1461 | msg = "Bad batch item type: expected {0}, received {1}" | |
1462 | self.assertIsInstance(batch_item, messages.ResponseBatchItem, | |
1463 | msg.format(messages.ResponseBatchItem, | |
1464 | type(batch_item))) | |
1465 | ||
1466 | operation = batch_item.operation | |
1467 | msg = "Bad operation type: expected {0}, received {1}" | |
1468 | self.assertIsInstance(operation, contents.Operation, | |
1469 | msg.format(contents.Operation, | |
1470 | type(operation))) | |
1471 | msg = "Bad operation value: expected {0}, received {1}" | |
1472 | exp_value = enums.Operation.REGISTER | |
1473 | rcv_value = operation.enum | |
1474 | self.assertEqual(exp_value, rcv_value, | |
1475 | msg.format(exp_value, rcv_value)) | |
1476 | ||
1477 | result_status = batch_item.result_status | |
1478 | self.assertIsInstance(result_status, contents.ResultStatus, | |
1479 | self.msg.format('result status', 'type', | |
1480 | contents.ResultStatus, | |
1481 | type(result_status))) | |
1482 | self.assertEqual(enums.ResultStatus.SUCCESS, result_status.enum, | |
1483 | self.msg.format('result status', 'value', | |
1484 | enums.ResultStatus.SUCCESS, | |
1485 | result_status.enum)) | |
1486 | ||
1487 | response_payload = batch_item.response_payload | |
1488 | msg = "Bad response payload type: expected {0}, received {1}" | |
1489 | exp_type = operations.RegisterResponsePayload | |
1490 | rcv_type = type(response_payload) | |
1491 | self.assertIsInstance(response_payload, exp_type, | |
1492 | msg.format(exp_type, rcv_type)) | |
1493 | ||
1494 | unique_identifier = response_payload.unique_identifier | |
1495 | msg = "Bad unique identifier type: expected {0}, received {1}" | |
1496 | self.assertIsInstance(unique_identifier, attr.UniqueIdentifier, | |
1497 | msg.format(attr.UniqueIdentifier, | |
1498 | type(unique_identifier))) | |
1499 | msg = "Bad unique identifier value: expected {0}, received {1}" | |
1500 | exp_value = '5c9b81ef-4ee5-42cd-ba2d-c002fdd0c7b3' | |
1501 | rcv_value = unique_identifier.value | |
1502 | self.assertEqual(exp_value, rcv_value, | |
1503 | msg.format(exp_value, rcv_value)) | |
1504 | ||
1505 | def test_register_response_write(self): | |
1506 | prot_ver = contents.ProtocolVersion.create(1, 1) | |
1507 | ||
1508 | # Fri Apr 27 10:12:21 CEST 2012 | |
1509 | time_stamp = contents.TimeStamp(0x4f9a54e5) | |
1510 | ||
1511 | batch_count = contents.BatchCount(1) | |
1512 | resp_hdr = messages.ResponseHeader(protocol_version=prot_ver, | |
1513 | time_stamp=time_stamp, | |
1514 | batch_count=batch_count) | |
1515 | ||
1516 | operation = contents.Operation(enums.Operation.REGISTER) | |
1517 | result_status = contents.ResultStatus(enums.ResultStatus.SUCCESS) | |
1518 | ||
1519 | uuid = attr.UniqueIdentifier('5c9b81ef-4ee5-42cd-ba2d-c002fdd0c7b3') | |
1520 | resp_pl = RegisterResponsePayload(unique_identifier=uuid) | |
1521 | batch_item = messages.ResponseBatchItem(operation=operation, | |
1522 | result_status=result_status, | |
1523 | response_payload=resp_pl) | |
1524 | response_message = messages.ResponseMessage(response_header=resp_hdr, | |
1525 | batch_items=[batch_item]) | |
1526 | response_message.write(self.stream) | |
1527 | ||
1528 | result = self.stream.read() | |
1529 | len_exp = len(self.register) | |
1530 | len_rcv = len(result) | |
1531 | self.assertEqual(len_exp, len_rcv, | |
1532 | self.msg.format('response message', 'write', | |
1533 | len_exp, len_rcv)) | |
1534 | ||
1535 | msg = "Bad response message write: encoding mismatch" | |
1536 | self.assertEqual(self.register, result, msg) |
0 | # Copyright (c) 2014 The Johns Hopkins University/Applied Physics Laboratory | |
1 | # All Rights Reserved. | |
2 | # | |
3 | # Licensed under the Apache License, Version 2.0 (the "License"); you may | |
4 | # not use this file except in compliance with the License. You may obtain | |
5 | # a copy of the License at | |
6 | # | |
7 | # http://www.apache.org/licenses/LICENSE-2.0 | |
8 | # | |
9 | # Unless required by applicable law or agreed to in writing, software | |
10 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT | |
11 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the | |
12 | # License for the specific language governing permissions and limitations | |
13 | # under the License. |
0 | # Copyright (c) 2014 The Johns Hopkins University/Applied Physics Laboratory | |
1 | # All Rights Reserved. | |
2 | # | |
3 | # Licensed under the Apache License, Version 2.0 (the "License"); you may | |
4 | # not use this file except in compliance with the License. You may obtain | |
5 | # a copy of the License at | |
6 | # | |
7 | # http://www.apache.org/licenses/LICENSE-2.0 | |
8 | # | |
9 | # Unless required by applicable law or agreed to in writing, software | |
10 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT | |
11 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the | |
12 | # License for the specific language governing permissions and limitations | |
13 | # under the License. | |
14 | ||
15 | from testtools import TestCase | |
16 | ||
17 | from kmip.core.utils import BytearrayStream | |
18 | ||
19 | ||
20 | class TestNameValue(TestCase): | |
21 | ||
22 | def setUp(self): | |
23 | super(TestNameValue, self).setUp() | |
24 | self.stream = BytearrayStream() | |
25 | ||
26 | def tearDown(self): | |
27 | super(TestNameValue, self).tearDown() | |
28 | ||
29 | def test_write_no_padding(self): | |
30 | pass | |
31 | ||
32 | def test_write_with_padding(self): | |
33 | pass | |
34 | ||
35 | def test_read_no_padding(self): | |
36 | pass | |
37 | ||
38 | def test_read_with_padding(self): | |
39 | pass | |
40 | ||
41 | ||
42 | class TestName(TestCase): | |
43 | ||
44 | def setUp(self): | |
45 | super(TestName, self).setUp() | |
46 | self.stream = BytearrayStream() | |
47 | ||
48 | def tearDown(self): | |
49 | super(TestName, self).tearDown() | |
50 | ||
51 | def test_minimum_write(self): | |
52 | pass | |
53 | ||
54 | def test_maximum_write(self): | |
55 | pass | |
56 | ||
57 | def test_minimum_read(self): | |
58 | pass | |
59 | ||
60 | def test_maximum_read(self): | |
61 | pass |
0 | # Copyright (c) 2014 The Johns Hopkins University/Applied Physics Laboratory | |
1 | # All Rights Reserved. | |
2 | # | |
3 | # Licensed under the Apache License, Version 2.0 (the "License"); you may | |
4 | # not use this file except in compliance with the License. You may obtain | |
5 | # a copy of the License at | |
6 | # | |
7 | # http://www.apache.org/licenses/LICENSE-2.0 | |
8 | # | |
9 | # Unless required by applicable law or agreed to in writing, software | |
10 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT | |
11 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the | |
12 | # License for the specific language governing permissions and limitations | |
13 | # under the License. | |
14 | ||
15 | from testtools import TestCase | |
16 | ||
17 | from kmip.core.enums import Tags | |
18 | from kmip.core.enums import Types | |
19 | ||
20 | from kmip.core.utils import BytearrayStream | |
21 | ||
22 | import kmip.core.errors as errors | |
23 | from kmip.core.errors import ErrorStrings | |
24 | ||
25 | from kmip.core.primitives import Base | |
26 | from kmip.core.primitives import Integer | |
27 | from kmip.core.primitives import LongInteger | |
28 | from kmip.core.primitives import BigInteger | |
29 | from kmip.core.primitives import Enumeration | |
30 | from kmip.core.primitives import TextString | |
31 | from kmip.core.primitives import ByteString | |
32 | ||
33 | ||
34 | class TestBase(TestCase): | |
35 | ||
36 | def setUp(self): | |
37 | super(self.__class__, self).setUp() | |
38 | self.stream = BytearrayStream() | |
39 | self.bad_init = 'Bad Base initialization: attribute {0} missing' | |
40 | self.bad_write = ErrorStrings.BAD_EXP_RECV.format('Base.{0}', 'write', | |
41 | '{1}', '{2}') | |
42 | self.bad_encoding = ErrorStrings.BAD_ENCODING.format('Base.{0}', | |
43 | 'write') | |
44 | self.bad_match = ErrorStrings.BAD_EXP_RECV.format('Base.{0}', | |
45 | 'comparison', '{1}', | |
46 | '{2}') | |
47 | ||
48 | def tearDown(self): | |
49 | super(self.__class__, self).tearDown() | |
50 | ||
51 | def test_is_oversized(self): | |
52 | base = Base() | |
53 | ||
54 | # Check no exception thrown | |
55 | base.is_oversized(self.stream) | |
56 | ||
57 | def test_is_oversized_error(self): | |
58 | self.stream.write('\x00') | |
59 | base = Base() | |
60 | ||
61 | self.assertRaises(errors.StreamNotEmptyError, base.is_oversized, | |
62 | self.stream) | |
63 | ||
64 | def test_read_tag(self): | |
65 | encoding = ('\x42\x00\x00') | |
66 | base = Base() | |
67 | self.stream = BytearrayStream(str(encoding)) | |
68 | ||
69 | # Check no exception thrown | |
70 | base.read_tag(self.stream) | |
71 | ||
72 | def test_read_tag_invalid(self): | |
73 | encoding = ('\x42\x00\x01') | |
74 | base = Base() | |
75 | self.stream = BytearrayStream(str(encoding)) | |
76 | ||
77 | self.assertRaises(errors.ReadValueError, base.read_tag, self.stream) | |
78 | ||
79 | def test_read_type(self): | |
80 | self.stream.write('\x00') | |
81 | base = Base() | |
82 | ||
83 | # Check no exception thrown | |
84 | base.read_type(self.stream) | |
85 | ||
86 | def test_read_type_error(self): | |
87 | self.stream.write('\x01') | |
88 | base = Base() | |
89 | ||
90 | self.assertRaises(errors.ReadValueError, base.read_type, self.stream) | |
91 | ||
92 | def test_read_type_underflow(self): | |
93 | base = Base() | |
94 | ||
95 | self.assertRaises(errors.ReadValueError, base.read_type, | |
96 | self.stream) | |
97 | ||
98 | def test_read_type_overflow(self): | |
99 | self.stream.write('\x00\x00') | |
100 | base = Base() | |
101 | ||
102 | # Check no exception thrown | |
103 | base.read_type(self.stream) | |
104 | ||
105 | def test_read_length(self): | |
106 | self.stream.write('\x00\x00\x00\x04') | |
107 | base = Base() | |
108 | base.length = 4 | |
109 | ||
110 | # Check no exception thrown | |
111 | base.read_length(self.stream) | |
112 | ||
113 | def test_read_length_error(self): | |
114 | self.stream.write('\x00\x00\x00\x00') | |
115 | base = Base() | |
116 | base.length = 4 | |
117 | ||
118 | self.assertRaises(errors.ReadValueError, base.read_length, | |
119 | self.stream) | |
120 | ||
121 | def test_read_length_underflow(self): | |
122 | self.stream.write('\x00') | |
123 | base = Base() | |
124 | base.length = 4 | |
125 | ||
126 | self.assertRaises(errors.ReadValueError, base.read_length, | |
127 | self.stream) | |
128 | ||
129 | def test_read_length_overflow(self): | |
130 | self.stream.write('\x00\x00\x00\x04\x00') | |
131 | base = Base() | |
132 | base.length = 4 | |
133 | ||
134 | # Check no exception thrown | |
135 | base.read_length(self.stream) | |
136 | ||
137 | def test_read_value(self): | |
138 | base = Base() | |
139 | ||
140 | self.assertRaises(NotImplementedError, base.read_value, self.stream) | |
141 | ||
142 | def test_read(self): | |
143 | self.stream.write('\x42\x00\x00\x00\x00\x00\x00\x04') | |
144 | base = Base() | |
145 | base.length = 4 | |
146 | ||
147 | # Check no exception thrown | |
148 | base.read(self.stream) | |
149 | ||
150 | def test_write_tag(self): | |
151 | encoding = ('\x42\x00\x00') | |
152 | base = Base() | |
153 | base.write_tag(self.stream) | |
154 | ||
155 | result = self.stream.read() | |
156 | len_exp = len(encoding) | |
157 | len_rcv = len(result) | |
158 | ||
159 | self.assertEqual(len_exp, len_rcv, | |
160 | self.bad_write.format('tag', | |
161 | '{0} bytes'.format(len_exp), | |
162 | '{0} bytes'.format(len_rcv))) | |
163 | self.assertEqual(encoding, result, self.bad_encoding.format('tag')) | |
164 | ||
165 | def test_write_type(self): | |
166 | encoding = '\x00' | |
167 | base = Base() | |
168 | base.write_type(self.stream) | |
169 | ||
170 | result = self.stream.read() | |
171 | len_exp = len(encoding) | |
172 | len_rcv = len(result) | |
173 | ||
174 | self.assertEqual(len_exp, len_rcv, | |
175 | self.bad_write.format('type', | |
176 | '{0} bytes'.format(len_exp), | |
177 | '{0} bytes'.format(len_rcv))) | |
178 | self.assertEqual(encoding, result, self.bad_encoding.format('type')) | |
179 | ||
180 | def test_write_type_invalid(self): | |
181 | base = Base() | |
182 | base.type = '' | |
183 | ||
184 | self.assertRaises(TypeError, base.write_type, self.stream) | |
185 | ||
186 | def test_write_length(self): | |
187 | encoding = '\x00\x00\x00\x04' | |
188 | base = Base() | |
189 | base.length = 4 | |
190 | base.write_length(self.stream) | |
191 | ||
192 | result = self.stream.read() | |
193 | len_exp = len(encoding) | |
194 | len_rcv = len(result) | |
195 | ||
196 | self.assertEqual(len_exp, len_rcv, | |
197 | self.bad_write.format('length', | |
198 | '{0} bytes'.format(len_exp), | |
199 | '{0} bytes'.format(len_rcv))) | |
200 | self.assertEqual(encoding, result, self.bad_encoding.format('length')) | |
201 | ||
202 | def test_write_length_invalid(self): | |
203 | base = Base() | |
204 | base.length = '' | |
205 | ||
206 | self.assertRaises(TypeError, base.write_length, self.stream) | |
207 | ||
208 | def test_write_length_overflow(self): | |
209 | self.skip('No easy way to test with a number requiring more than ' | |
210 | '2 ** 0xffffffff bytes for representation. Test preserved ' | |
211 | 'for completeness.') | |
212 | ||
213 | def test_write_value(self): | |
214 | base = Base() | |
215 | ||
216 | self.assertRaises(NotImplementedError, base.write_value, self.stream) | |
217 | ||
218 | def test_write(self): | |
219 | encoding = '\x42\x00\x00\x00\x00\x00\x00\x04' | |
220 | base = Base() | |
221 | base.length = 4 | |
222 | base.write(self.stream) | |
223 | ||
224 | result = self.stream.read() | |
225 | len_exp = len(encoding) | |
226 | len_rcv = len(result) | |
227 | ||
228 | self.assertEqual(len_exp, len_rcv, | |
229 | self.bad_write.format('type/length', | |
230 | '{0} bytes'.format(len_exp), | |
231 | '{0} bytes'.format(len_rcv))) | |
232 | self.assertEqual(encoding, result, | |
233 | self.bad_encoding.format('type/length')) | |
234 | ||
235 | def test_is_tag_next(self): | |
236 | encoding = ('\x42\x00\x00') | |
237 | base = Base() | |
238 | self.stream = BytearrayStream(str(encoding)) | |
239 | ||
240 | self.assertTrue(Base.is_tag_next(base.tag, self.stream), | |
241 | self.bad_match.format('tag', 'match', 'mismatch')) | |
242 | ||
243 | def test_is_tag_next_invalid(self): | |
244 | encoding = ('\x42\x00\x01') | |
245 | base = Base() | |
246 | self.stream = BytearrayStream(str(encoding)) | |
247 | ||
248 | self.assertFalse(Base.is_tag_next(base.tag, self.stream), | |
249 | self.bad_match.format('tag', 'mismatch', 'match')) | |
250 | ||
251 | ||
252 | class TestInteger(TestCase): | |
253 | ||
254 | def setUp(self): | |
255 | super(self.__class__, self).setUp() | |
256 | self.stream = BytearrayStream() | |
257 | self.max_byte_int = 4294967295 | |
258 | self.max_int = 2147483647 | |
259 | self.bad_value = ('Bad Integer.{0} after init: expected {1}, ' | |
260 | 'received {2}') | |
261 | self.bad_write = ('Bad Integer write: expected {0} bytes, ' | |
262 | 'received {1} bytes') | |
263 | self.bad_encoding = 'Bad Integer write: encoding mismatch' | |
264 | self.bad_read = ('Bad Integer.value read: expected {0}, received {1}') | |
265 | ||
266 | def tearDown(self): | |
267 | super(self.__class__, self).tearDown() | |
268 | ||
269 | def test_init(self): | |
270 | i = Integer(0) | |
271 | ||
272 | self.assertEqual(0, i.value, | |
273 | self.bad_value.format('value', 0, i.value)) | |
274 | self.assertEqual(i.LENGTH, i.length, | |
275 | self.bad_value.format('length', i.LENGTH, i.length)) | |
276 | self.assertEqual(i.LENGTH, i.padding_length, | |
277 | self.bad_value.format('padding_length', i.LENGTH, | |
278 | i.padding_length)) | |
279 | ||
280 | def test_init_unset(self): | |
281 | i = Integer() | |
282 | ||
283 | self.assertEqual(None, i.value, | |
284 | self.bad_value.format('value', None, i.value)) | |
285 | self.assertEqual(i.LENGTH, i.length, | |
286 | self.bad_value.format('length', i.LENGTH, i.length)) | |
287 | self.assertEqual(i.LENGTH, i.padding_length, | |
288 | self.bad_value.format('padding_length', i.LENGTH, | |
289 | i.padding_length)) | |
290 | ||
291 | def test_validate_on_valid(self): | |
292 | i = Integer() | |
293 | i.value = 0 | |
294 | ||
295 | # Check no exception thrown | |
296 | i.validate() | |
297 | ||
298 | def test_validate_on_valid_unset(self): | |
299 | i = Integer() | |
300 | ||
301 | # Check no exception thrown | |
302 | i.validate() | |
303 | ||
304 | def test_validate_on_invalid_type(self): | |
305 | i = Integer() | |
306 | i.value = 'test' | |
307 | ||
308 | self.assertRaises(errors.StateTypeError, i.validate) | |
309 | ||
310 | def test_validate_on_invalid_value(self): | |
311 | self.assertRaises(errors.StateOverflowError, Integer, | |
312 | self.max_byte_int + 1) | |
313 | ||
314 | def test_read_value(self): | |
315 | encoding = ('\x00\x00\x00\x01\x00\x00\x00\x00') | |
316 | self.stream = BytearrayStream(str(encoding)) | |
317 | i = Integer() | |
318 | i.read_value(self.stream) | |
319 | ||
320 | self.assertEqual(1, i.value, self.bad_read.format(1, i.value)) | |
321 | ||
322 | def test_read_value_zero(self): | |
323 | encoding = ('\x00\x00\x00\x00\x00\x00\x00\x00') | |
324 | self.stream = BytearrayStream(str(encoding)) | |
325 | i = Integer() | |
326 | i.read_value(self.stream) | |
327 | ||
328 | self.assertEqual(0, i.value, self.bad_read.format(0, i.value)) | |
329 | ||
330 | def test_read_value_max_positive(self): | |
331 | encoding = ('\x7f\xff\xff\xff\x00\x00\x00\x00') | |
332 | self.stream = BytearrayStream(str(encoding)) | |
333 | i = Integer() | |
334 | i.read_value(self.stream) | |
335 | ||
336 | self.assertEqual(self.max_int, i.value, | |
337 | self.bad_read.format(1, i.value)) | |
338 | ||
339 | def test_read_value_min_negative(self): | |
340 | encoding = ('\xff\xff\xff\xff\x00\x00\x00\x00') | |
341 | self.stream = BytearrayStream(str(encoding)) | |
342 | i = Integer() | |
343 | i.read_value(self.stream) | |
344 | ||
345 | self.assertEqual(-1, i.value, | |
346 | self.bad_read.format(1, i.value)) | |
347 | ||
348 | def test_read(self): | |
349 | encoding = ('\x42\x00\x00\x02\x00\x00\x00\x04\x00\x00\x00\x01\x00\x00' | |
350 | '\x00\x00') | |
351 | self.stream = BytearrayStream(str(encoding)) | |
352 | i = Integer() | |
353 | i.read(self.stream) | |
354 | ||
355 | self.assertEqual(1, i.value, self.bad_read.format(1, i.value)) | |
356 | ||
357 | def test_read_on_invalid_length(self): | |
358 | encoding = ('\x42\x00\x00\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' | |
359 | '\x00\x00') | |
360 | self.stream = BytearrayStream(str(encoding)) | |
361 | i = Integer() | |
362 | ||
363 | self.assertRaises(errors.ReadValueError, i.read, self.stream) | |
364 | ||
365 | def test_read_on_invalid_padding(self): | |
366 | encoding = ('\x42\x00\x00\x02\x00\x00\x00\x04\x00\x00\x00\x00\xff\xff' | |
367 | '\xff\xff') | |
368 | self.stream = BytearrayStream(str(encoding)) | |
369 | i = Integer() | |
370 | ||
371 | self.assertRaises(errors.ReadValueError, i.read, self.stream) | |
372 | ||
373 | def test_write_value(self): | |
374 | encoding = ('\x00\x00\x00\x01\x00\x00\x00\x00') | |
375 | i = Integer(1) | |
376 | i.write_value(self.stream) | |
377 | ||
378 | result = self.stream.read() | |
379 | len_exp = len(encoding) | |
380 | len_rcv = len(result) | |
381 | ||
382 | self.assertEqual(len_exp, len_rcv, self.bad_write.format(len_exp, | |
383 | len_rcv)) | |
384 | self.assertEqual(encoding, result, self.bad_encoding) | |
385 | ||
386 | def test_write_value_zero(self): | |
387 | encoding = ('\x00\x00\x00\x00\x00\x00\x00\x00') | |
388 | i = Integer(0) | |
389 | i.write_value(self.stream) | |
390 | ||
391 | result = self.stream.read() | |
392 | len_exp = len(encoding) | |
393 | len_rcv = len(result) | |
394 | ||
395 | self.assertEqual(len_exp, len_rcv, self.bad_write.format(len_exp, | |
396 | len_rcv)) | |
397 | self.assertEqual(encoding, result, self.bad_encoding) | |
398 | ||
399 | def test_write_value_max_positive(self): | |
400 | encoding = ('\x7f\xff\xff\xff\x00\x00\x00\x00') | |
401 | i = Integer(self.max_int) | |
402 | i.write_value(self.stream) | |
403 | ||
404 | result = self.stream.read() | |
405 | len_exp = len(encoding) | |
406 | len_rcv = len(result) | |
407 | ||
408 | self.assertEqual(len_exp, len_rcv, self.bad_write.format(len_exp, | |
409 | len_rcv)) | |
410 | self.assertEqual(encoding, result, self.bad_encoding) | |
411 | ||
412 | def test_write_value_min_negative(self): | |
413 | encoding = ('\xff\xff\xff\xff\x00\x00\x00\x00') | |
414 | i = Integer(-1) | |
415 | i.write_value(self.stream) | |
416 | ||
417 | result = self.stream.read() | |
418 | len_exp = len(encoding) | |
419 | len_rcv = len(result) | |
420 | ||
421 | self.assertEqual(len_exp, len_rcv, self.bad_write.format(len_exp, | |
422 | len_rcv)) | |
423 | self.assertEqual(encoding, result, self.bad_encoding) | |
424 | ||
425 | def test_write(self): | |
426 | encoding = ('\x42\x00\x00\x02\x00\x00\x00\x04\x00\x00\x00\x01\x00\x00' | |
427 | '\x00\x00') | |
428 | i = Integer(1) | |
429 | i.write(self.stream) | |
430 | ||
431 | result = self.stream.read() | |
432 | len_exp = len(encoding) | |
433 | len_rcv = len(result) | |
434 | ||
435 | self.assertEqual(len_exp, len_rcv, self.bad_write.format(len_exp, | |
436 | len_rcv)) | |
437 | self.assertEqual(encoding, result, self.bad_encoding) | |
438 | ||
439 | ||
440 | class TestLongInteger(TestCase): | |
441 | ||
442 | def setUp(self): | |
443 | super(self.__class__, self).setUp() | |
444 | self.stream = BytearrayStream() | |
445 | self.max_byte_long = 18446744073709551615 | |
446 | self.max_long = 9223372036854775807 | |
447 | self.bad_value = ('Bad LongInteger.{0} after init: expected {1}, ' | |
448 | 'received {2}') | |
449 | self.bad_write = ('Bad LongInteger write: expected {0} bytes, ' | |
450 | 'received {1} bytes') | |
451 | self.bad_encoding = 'Bad LongInteger write: encoding mismatch' | |
452 | self.bad_read = ('Bad LongInteger.value read: expected {0}, received ' | |
453 | '{1}') | |
454 | ||
455 | def tearDown(self): | |
456 | super(self.__class__, self).tearDown() | |
457 | ||
458 | def test_init(self): | |
459 | i = LongInteger(0) | |
460 | ||
461 | self.assertEqual(0, i.value, | |
462 | self.bad_value.format('value', 0, i.value)) | |
463 | self.assertEqual(i.LENGTH, i.length, | |
464 | self.bad_value.format('length', i.LENGTH, i.length)) | |
465 | ||
466 | def test_init_unset(self): | |
467 | i = LongInteger() | |
468 | ||
469 | self.assertEqual(None, i.value, | |
470 | self.bad_value.format('value', None, i.value)) | |
471 | self.assertEqual(i.LENGTH, i.length, | |
472 | self.bad_value.format('length', i.LENGTH, i.length)) | |
473 | ||
474 | def test_validate_on_valid(self): | |
475 | i = LongInteger() | |
476 | i.value = 0 | |
477 | ||
478 | # Check no exception thrown | |
479 | i.validate() | |
480 | ||
481 | def test_validate_on_valid_long(self): | |
482 | i = LongInteger() | |
483 | i.value = self.max_long + 1 | |
484 | ||
485 | # Check no exception thrown | |
486 | i.validate() | |
487 | ||
488 | def test_validate_on_valid_unset(self): | |
489 | i = LongInteger() | |
490 | ||
491 | # Check no exception thrown | |
492 | i.validate() | |
493 | ||
494 | def test_validate_on_invalid_type(self): | |
495 | i = LongInteger() | |
496 | i.value = 'test' | |
497 | ||
498 | self.assertRaises(errors.StateTypeError, i.validate) | |
499 | ||
500 | def test_validate_on_invalid_value(self): | |
501 | self.assertRaises(errors.StateOverflowError, LongInteger, | |
502 | self.max_byte_long + 1) | |
503 | ||
504 | def test_read_value(self): | |
505 | encoding = ('\x00\x00\x00\x00\x00\x00\x00\x01') | |
506 | self.stream = BytearrayStream(str(encoding)) | |
507 | i = LongInteger() | |
508 | i.read_value(self.stream) | |
509 | ||
510 | self.assertEqual(1, i.value, self.bad_read.format(1, i.value)) | |
511 | ||
512 | def test_read_value_zero(self): | |
513 | encoding = ('\x00\x00\x00\x00\x00\x00\x00\x00') | |
514 | self.stream = BytearrayStream(str(encoding)) | |
515 | i = LongInteger() | |
516 | i.read_value(self.stream) | |
517 | ||
518 | self.assertEqual(0, i.value, self.bad_read.format(0, i.value)) | |
519 | ||
520 | def test_read_value_max_positive(self): | |
521 | encoding = ('\x7f\xff\xff\xff\xff\xff\xff\xff') | |
522 | self.stream = BytearrayStream(str(encoding)) | |
523 | i = LongInteger() | |
524 | i.read_value(self.stream) | |
525 | ||
526 | self.assertEqual(self.max_long, i.value, | |
527 | self.bad_read.format(1, i.value)) | |
528 | ||
529 | def test_read_value_min_negative(self): | |
530 | encoding = ('\xff\xff\xff\xff\xff\xff\xff\xff') | |
531 | self.stream = BytearrayStream(str(encoding)) | |
532 | i = LongInteger() | |
533 | i.read_value(self.stream) | |
534 | ||
535 | self.assertEqual(-1, i.value, | |
536 | self.bad_read.format(1, i.value)) | |
537 | ||
538 | def test_read(self): | |
539 | encoding = ('\x42\x00\x00\x03\x00\x00\x00\x08\x00\x00\x00\x00\x00\x00' | |
540 | '\x00\x01') | |
541 | self.stream = BytearrayStream(str(encoding)) | |
542 | i = LongInteger() | |
543 | i.read(self.stream) | |
544 | ||
545 | self.assertEqual(1, i.value, self.bad_read.format(1, i.value)) | |
546 | ||
547 | def test_read_on_invalid_length(self): | |
548 | encoding = ('\x42\x00\x00\x03\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' | |
549 | '\x00\x00') | |
550 | self.stream = BytearrayStream(str(encoding)) | |
551 | i = LongInteger() | |
552 | ||
553 | self.assertRaises(errors.ReadValueError, i.read, self.stream) | |
554 | ||
555 | def test_write_value(self): | |
556 | encoding = ('\x00\x00\x00\x00\x00\x00\x00\x01') | |
557 | i = LongInteger(1) | |
558 | i.write_value(self.stream) | |
559 | ||
560 | result = self.stream.read() | |
561 | len_exp = len(encoding) | |
562 | len_rcv = len(result) | |
563 | ||
564 | self.assertEqual(len_exp, len_rcv, self.bad_write.format(len_exp, | |
565 | len_rcv)) | |
566 | self.assertEqual(encoding, result, self.bad_encoding) | |
567 | ||
568 | def test_write_value_zero(self): | |
569 | encoding = ('\x00\x00\x00\x00\x00\x00\x00\x00') | |
570 | i = LongInteger(0) | |
571 | i.write_value(self.stream) | |
572 | ||
573 | result = self.stream.read() | |
574 | len_exp = len(encoding) | |
575 | len_rcv = len(result) | |
576 | ||
577 | self.assertEqual(len_exp, len_rcv, self.bad_write.format(len_exp, | |
578 | len_rcv)) | |
579 | self.assertEqual(encoding, result, self.bad_encoding) | |
580 | ||
581 | def test_write_value_max_positive(self): | |
582 | encoding = ('\x7f\xff\xff\xff\xff\xff\xff\xff') | |
583 | i = LongInteger(self.max_long) | |
584 | i.write_value(self.stream) | |
585 | ||
586 | result = self.stream.read() | |
587 | len_exp = len(encoding) | |
588 | len_rcv = len(result) | |
589 | ||
590 | self.assertEqual(len_exp, len_rcv, self.bad_write.format(len_exp, | |
591 | len_rcv)) | |
592 | self.assertEqual(encoding, result, self.bad_encoding) | |
593 | ||
594 | def test_write_value_min_negative(self): | |
595 | encoding = ('\xff\xff\xff\xff\xff\xff\xff\xff') | |
596 | i = LongInteger(-1) | |
597 | i.write_value(self.stream) | |
598 | ||
599 | result = self.stream.read() | |
600 | len_exp = len(encoding) | |
601 | len_rcv = len(result) | |
602 | ||
603 | self.assertEqual(len_exp, len_rcv, self.bad_write.format(len_exp, | |
604 | len_rcv)) | |
605 | self.assertEqual(encoding, result, self.bad_encoding) | |
606 | ||
607 | def test_write(self): | |
608 | encoding = ('\x42\x00\x00\x03\x00\x00\x00\x08\x00\x00\x00\x00\x00\x00' | |
609 | '\x00\x01') | |
610 | i = LongInteger(1) | |
611 | i.write(self.stream) | |
612 | ||
613 | result = self.stream.read() | |
614 | len_exp = len(encoding) | |
615 | len_rcv = len(result) | |
616 | ||
617 | self.assertEqual(len_exp, len_rcv, self.bad_write.format(len_exp, | |
618 | len_rcv)) | |
619 | self.assertEqual(encoding, result, self.bad_encoding) | |
620 | ||
621 | ||
622 | class TestBigInteger(TestCase): | |
623 | ||
624 | def setUp(self): | |
625 | super(self.__class__, self).setUp() | |
626 | self.stream = BytearrayStream() | |
627 | self.max_byte_long = 18446744073709551615 | |
628 | self.max_long = 9223372036854775807 | |
629 | self.bad_value = ('Bad BigInteger.{0} after init: expected {1}, ' | |
630 | 'received {2}') | |
631 | self.bad_write = ('Bad BigInteger write: expected {0} bytes, ' | |
632 | 'received {1} bytes') | |
633 | self.bad_encoding = 'Bad BigInteger write: encoding mismatch' | |
634 | self.bad_read = ('Bad BigInteger.value read: expected {0}, ' | |
635 | 'received {1}') | |
636 | ||
637 | def tearDown(self): | |
638 | super(self.__class__, self).tearDown() | |
639 | ||
640 | def test_big_integer(self): | |
641 | self.skip('BigInteger implementation incomplete') | |
642 | i = BigInteger(0) | |
643 | ||
644 | self.assertEqual(0, i.value, | |
645 | self.bad_value.format('value', 0, i.value)) | |
646 | self.assertEqual(1, i.length, | |
647 | self.bad_value.format('length', 1, i.length)) | |
648 | self.assertEqual(i.BLOCK_SIZE - 1, i.padding_length, | |
649 | self.bad_value.format('padding_length', | |
650 | i.BLOCK_SIZE - 1, | |
651 | i.padding_length)) | |
652 | ||
653 | def test_big_integer_unset(self): | |
654 | self.skip('BigInteger implementation incomplete') | |
655 | i = BigInteger() | |
656 | ||
657 | self.assertEqual(None, i.value, | |
658 | self.bad_value.format('value', None, i.value)) | |
659 | self.assertEqual(None, i.length, | |
660 | self.bad_value.format('length', None, i.length)) | |
661 | self.assertEqual(None, i.padding_length, | |
662 | self.bad_value.format('padding_length', None, | |
663 | i.padding_length)) | |
664 | ||
665 | def test_validate_on_valid(self): | |
666 | self.skip('BigInteger implementation incomplete') | |
667 | i = BigInteger() | |
668 | i.value = 0 | |
669 | i.length = i.BLOCK_SIZE | |
670 | i.padding_length = 0 | |
671 | ||
672 | # Check no exception thrown | |
673 | i.validate() | |
674 | ||
675 | def test_validate_on_valid_long(self): | |
676 | self.skip('BigInteger implementation incomplete') | |
677 | i = BigInteger() | |
678 | i.value = self.max_long + 1 | |
679 | i.length = i.BLOCK_SIZE | |
680 | i.padding_length = 0 | |
681 | ||
682 | # Check no exception thrown | |
683 | i.validate() | |
684 | ||
685 | def test_validate_on_valid_unset(self): | |
686 | self.skip('BigInteger implementation incomplete') | |
687 | i = BigInteger() | |
688 | ||
689 | # Check no exception thrown | |
690 | i.validate() | |
691 | ||
692 | def test_validate_on_invalid_type(self): | |
693 | self.skip('BigInteger implementation incomplete') | |
694 | i = BigInteger() | |
695 | i.value = 'test' | |
696 | ||
697 | self.assertRaises(errors.StateTypeError, i.validate) | |
698 | ||
699 | def test_write(self): | |
700 | self.skip('BigInteger implementation incomplete') | |
701 | encoding = ('\x42\x00\x01\x04\x00\x00\x00\x08\x00\x00\x00\x00\x00\x00' | |
702 | '\x00\x01') | |
703 | i = BigInteger(1) | |
704 | i.TAG = Tags.ACTIVATION_DATE | |
705 | i.write(self.stream) | |
706 | ||
707 | result = self.stream.read() | |
708 | len_exp = len(encoding) | |
709 | len_rcv = len(result) | |
710 | ||
711 | self.assertEqual(len_exp, len_rcv, self.bad_write.format(len_exp, | |
712 | len_rcv)) | |
713 | self.assertEqual(encoding, result, self.bad_encoding) | |
714 | ||
715 | def test_write_zero(self): | |
716 | self.skip('BigInteger implementation incomplete') | |
717 | encoding = ('\x42\x00\x01\x04\x00\x00\x00\x08\x00\x00\x00\x00\x00\x00' | |
718 | '\x00\x00') | |
719 | i = BigInteger(0) | |
720 | i.TAG = Tags.ACTIVATION_DATE | |
721 | i.write(self.stream) | |
722 | ||
723 | result = self.stream.read() | |
724 | len_exp = len(encoding) | |
725 | len_rcv = len(result) | |
726 | ||
727 | self.assertEqual(len_exp, len_rcv, self.bad_write.format(len_exp, | |
728 | len_rcv)) | |
729 | self.assertEqual(encoding, result, self.bad_encoding) | |
730 | ||
731 | def test_write_max_positive_value(self): | |
732 | self.skip('BigInteger implementation incomplete') | |
733 | encoding = ('\x42\x00\x01\x04\x00\x00\x00\x08\x7f\xff\xff\xff\xff\xff' | |
734 | '\xff\xff') | |
735 | i = BigInteger(self.max_long) | |
736 | i.TAG = Tags.ACTIVATION_DATE | |
737 | i.write(self.stream) | |
738 | ||
739 | result = self.stream.read() | |
740 | len_exp = len(encoding) | |
741 | len_rcv = len(result) | |
742 | ||
743 | self.assertEqual(len_exp, len_rcv, self.bad_write.format(len_exp, | |
744 | len_rcv)) | |
745 | self.assertEqual(encoding, result, self.bad_encoding) | |
746 | ||
747 | def test_write_min_negative_value(self): | |
748 | self.skip('BigInteger implementation incomplete') | |
749 | encoding = ('\x42\x00\x01\x04\x00\x00\x00\x08\xff\xff\xff\xff\xff\xff' | |
750 | '\xff\xff') | |
751 | i = BigInteger(-1) | |
752 | i.TAG = Tags.ACTIVATION_DATE | |
753 | i.write(self.stream) | |
754 | ||
755 | result = self.stream.read() | |
756 | len_exp = len(encoding) | |
757 | len_rcv = len(result) | |
758 | ||
759 | self.assertEqual(len_exp, len_rcv, self.bad_write.format(len_exp, | |
760 | len_rcv)) | |
761 | self.assertEqual(encoding, result, self.bad_encoding) | |
762 | ||
763 | def test_read(self): | |
764 | self.skip('BigInteger implementation incomplete') | |
765 | encoding = ('\x42\x00\x01\x04\x00\x00\x00\x08\x00\x00\x00\x00\x00\x00' | |
766 | '\x00\x01') | |
767 | self.stream = BytearrayStream(str(encoding)) | |
768 | i = BigInteger() | |
769 | i.TAG = Tags.ACTIVATION_DATE | |
770 | i.read(self.stream) | |
771 | ||
772 | self.assertEqual(1, i.value, self.bad_read.format(1, i.value)) | |
773 | ||
774 | def test_read_zero(self): | |
775 | self.skip('BigInteger implementation incomplete') | |
776 | encoding = ('\x42\x00\x01\x04\x00\x00\x00\x08\x00\x00\x00\x00\x00\x00' | |
777 | '\x00\x00') | |
778 | self.stream = BytearrayStream(str(encoding)) | |
779 | i = BigInteger() | |
780 | i.TAG = Tags.ACTIVATION_DATE | |
781 | i.read(self.stream) | |
782 | ||
783 | self.assertEqual(0, i.value, self.bad_read.format(0, i.value)) | |
784 | ||
785 | def test_read_max_positive_value(self): | |
786 | self.skip('BigInteger implementation incomplete') | |
787 | encoding = ('\x42\x00\x01\x04\x00\x00\x00\x08\x7f\xff\xff\xff\xff\xff' | |
788 | '\xff\xff') | |
789 | self.stream = BytearrayStream(str(encoding)) | |
790 | i = BigInteger() | |
791 | i.TAG = Tags.ACTIVATION_DATE | |
792 | i.read(self.stream) | |
793 | ||
794 | self.assertEqual(self.max_long, i.value, | |
795 | self.bad_read.format(1, i.value)) | |
796 | ||
797 | def test_read_min_negative_value(self): | |
798 | self.skip('BigInteger implementation incomplete') | |
799 | encoding = ('\x42\x00\x01\x04\x00\x00\x00\x08\xff\xff\xff\xff\xff\xff' | |
800 | '\xff\xff') | |
801 | self.stream = BytearrayStream(str(encoding)) | |
802 | i = BigInteger() | |
803 | i.TAG = Tags.ACTIVATION_DATE | |
804 | i.read(self.stream) | |
805 | ||
806 | self.assertEqual(-1, i.value, | |
807 | self.bad_read.format(1, i.value)) | |
808 | ||
809 | def test_read_on_invalid_length(self): | |
810 | self.skip('BigInteger implementation incomplete') | |
811 | encoding = ('\x42\x00\x01\x04\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00' | |
812 | '\x00\x00') | |
813 | self.stream = BytearrayStream(str(encoding)) | |
814 | i = BigInteger() | |
815 | i.TAG = Tags.ACTIVATION_DATE | |
816 | ||
817 | self.assertRaises(errors.InvalidLengthError, i.read, self.stream) | |
818 | ||
819 | ||
820 | class TestEnumeration(TestCase): | |
821 | ||
822 | def setUp(self): | |
823 | super(self.__class__, self).setUp() | |
824 | self.stream = BytearrayStream() | |
825 | Enumeration.ENUM_TYPE = Types | |
826 | self.bad_type = ErrorStrings.BAD_EXP_RECV.format('Enumeration.{0}', | |
827 | 'type', '{1}', '{2}') | |
828 | self.bad_value = ErrorStrings.BAD_EXP_RECV.format('Enumeration.{0}', | |
829 | 'value', '{1}', | |
830 | '{2}') | |
831 | self.bad_write = ErrorStrings.BAD_EXP_RECV.format('Enumeration', | |
832 | 'write', | |
833 | '{0} bytes', | |
834 | '{1} bytes') | |
835 | self.bad_encoding = ErrorStrings.BAD_ENCODING.format('Enumeration', | |
836 | 'write') | |
837 | ||
838 | def tearDown(self): | |
839 | super(self.__class__, self).tearDown() | |
840 | ||
841 | def test_init(self): | |
842 | e = Enumeration(Types.DEFAULT) | |
843 | ||
844 | self.assertIsInstance(e.enum, Types, | |
845 | self.bad_type.format('enum', Types, | |
846 | type(e.enum))) | |
847 | self.assertEqual(Types.DEFAULT, e.enum, | |
848 | self.bad_value.format('enum', Types.DEFAULT, e.enum)) | |
849 | ||
850 | default = Types.DEFAULT | |
851 | self.assertEqual(default.value, e.value, | |
852 | self.bad_value.format('value', default.value, | |
853 | e.value)) | |
854 | ||
855 | def test_init_unset(self): | |
856 | e = Enumeration() | |
857 | ||
858 | self.assertEqual(None, e.enum, | |
859 | self.bad_value.format('enum', None, e.enum)) | |
860 | self.assertEqual(None, e.value, | |
861 | self.bad_value.format('value', None, e.value)) | |
862 | ||
863 | def test_validate_on_valid(self): | |
864 | e = Enumeration() | |
865 | e.enum = Types.DEFAULT | |
866 | ||
867 | # Check no exception thrown | |
868 | e.validate() | |
869 | ||
870 | def test_validate_on_valid_unset(self): | |
871 | e = Enumeration() | |
872 | ||
873 | # Check no exception thrown | |
874 | e.validate() | |
875 | ||
876 | def test_validate_on_invalid_type(self): | |
877 | e = Enumeration() | |
878 | e.enum = 0 | |
879 | ||
880 | self.assertRaises(TypeError, e.validate) | |
881 | ||
882 | def test_read(self): | |
883 | encoding = ('\x42\x00\x00\x05\x00\x00\x00\x04\x00\x00\x00\x00\x00\x00' | |
884 | '\x00\x00') | |
885 | self.stream = BytearrayStream(str(encoding)) | |
886 | e = Enumeration() | |
887 | e.read(self.stream) | |
888 | ||
889 | self.assertIsInstance(e.enum, Types, | |
890 | self.bad_type.format('enum', Types, | |
891 | type(e.enum))) | |
892 | self.assertEqual(Types.DEFAULT, e.enum, | |
893 | self.bad_value.format('enum', Types.DEFAULT, | |
894 | type(e.enum))) | |
895 | default = Types.DEFAULT | |
896 | self.assertEqual(default.value, e.value, | |
897 | self.bad_value.format('value', default.value, | |
898 | e.value)) | |
899 | ||
900 | def test_write(self): | |
901 | encoding = ('\x42\x00\x00\x05\x00\x00\x00\x04\x00\x00\x00\x00\x00\x00' | |
902 | '\x00\x00') | |
903 | e = Enumeration(Types.DEFAULT) | |
904 | e.write(self.stream) | |
905 | ||
906 | result = self.stream.read() | |
907 | len_exp = len(encoding) | |
908 | len_rcv = len(result) | |
909 | ||
910 | self.assertEqual(len_exp, len_rcv, self.bad_write.format(len_exp, | |
911 | len_rcv)) | |
912 | self.assertEqual(encoding, result, self.bad_encoding) | |
913 | ||
914 | ||
915 | class TestBoolean(TestCase): | |
916 | ||
917 | def setUp(self): | |
918 | super(self.__class__, self).setUp() | |
919 | self.stream = BytearrayStream() | |
920 | ||
921 | def tearDown(self): | |
922 | super(self.__class__, self).tearDown() | |
923 | ||
924 | def test_init(self): | |
925 | self.skip('') | |
926 | ||
927 | def test_init_unset(self): | |
928 | self.skip('') | |
929 | ||
930 | def test_validate_on_valid(self): | |
931 | self.skip('') | |
932 | ||
933 | def test_validate_on_valid_unset(self): | |
934 | self.skip('') | |
935 | ||
936 | def test_validate_on_invalid_type(self): | |
937 | self.skip('') | |
938 | ||
939 | def test_read_value(self): | |
940 | self.skip('') | |
941 | ||
942 | def test_read(self): | |
943 | self.skip('') | |
944 | ||
945 | def test_write_value(self): | |
946 | self.skip('') | |
947 | ||
948 | def test_write(self): | |
949 | self.skip('') | |
950 | ||
951 | ||
952 | class TestTextString(TestCase): | |
953 | ||
954 | def setUp(self): | |
955 | super(self.__class__, self).setUp() | |
956 | self.stream = BytearrayStream() | |
957 | self.bad_type = ErrorStrings.BAD_EXP_RECV.format('TextString.{0}', | |
958 | 'type', '{1}', '{2}') | |
959 | self.bad_value = ErrorStrings.BAD_EXP_RECV.format('TextString.{0}', | |
960 | 'value', '{1}', | |
961 | '{2}') | |
962 | self.bad_read = ErrorStrings.BAD_EXP_RECV.format('TextString.{0}', | |
963 | '', '{1}', '{2}') | |
964 | self.bad_write = ErrorStrings.BAD_EXP_RECV.format('TextString.{0}', | |
965 | 'write', '{1}', | |
966 | '{2}') | |
967 | self.bad_encoding = ErrorStrings.BAD_ENCODING.format('TextString', '') | |
968 | self.bad_length = ErrorStrings.BAD_EXP_RECV.format('TextString', | |
969 | 'length', | |
970 | '{0} bytes', | |
971 | '{1} bytes') | |
972 | ||
973 | def tearDown(self): | |
974 | super(self.__class__, self).tearDown() | |
975 | ||
976 | def test_init(self): | |
977 | value = 'Hello World' | |
978 | ts = TextString(value) | |
979 | ||
980 | self.assertIsInstance(ts.value, str, | |
981 | self.bad_type.format('value', str, | |
982 | type(ts.value))) | |
983 | self.assertEqual(value, ts.value, | |
984 | self.bad_value.format('value', value, ts.value)) | |
985 | ||
986 | def test_init_unset(self): | |
987 | ts = TextString() | |
988 | ||
989 | self.assertIsInstance(ts.value, type(None), | |
990 | self.bad_type.format('value', type(None), | |
991 | type(ts.value))) | |
992 | self.assertEqual(None, ts.value, | |
993 | self.bad_value.format('value', None, ts.value)) | |
994 | ||
995 | def test_validate_on_valid(self): | |
996 | ts = TextString() | |
997 | ts.value = 'Hello World' | |
998 | ||
999 | # Check no exception thrown. | |
1000 | ts.validate() | |
1001 | ||
1002 | def test_validate_on_valid_unset(self): | |
1003 | ts = TextString() | |
1004 | ||
1005 | # Check no exception thrown. | |
1006 | ts.validate() | |
1007 | ||
1008 | def test_validate_on_invalid_type(self): | |
1009 | ts = TextString() | |
1010 | ts.value = 0 | |
1011 | ||
1012 | self.assertRaises(TypeError, ts.validate) | |
1013 | ||
1014 | def test_read_value(self): | |
1015 | encoding = ('\x48\x65\x6C\x6C\x6F\x20\x57\x6F\x72\x6C\x64\x00\x00\x00' | |
1016 | '\x00\x00') | |
1017 | self.stream = BytearrayStream(str(encoding)) | |
1018 | ts = TextString() | |
1019 | ts.length = 0x0B | |
1020 | ts.read_value(self.stream) | |
1021 | ||
1022 | expected = 'Hello World' | |
1023 | self.assertEqual(expected, ts.value, | |
1024 | self.bad_read.format('value', expected, ts.value)) | |
1025 | ||
1026 | def test_read_value_no_padding(self): | |
1027 | encoding = ('\x48\x65\x6C\x6C\x6F\x20\x57\x6F') | |
1028 | self.stream = BytearrayStream(str(encoding)) | |
1029 | ts = TextString() | |
1030 | ts.length = 0x08 | |
1031 | ts.read_value(self.stream) | |
1032 | ||
1033 | expected = 'Hello Wo' | |
1034 | self.assertEqual(expected, ts.value, | |
1035 | self.bad_read.format('value', expected, ts.value)) | |
1036 | ||
1037 | def test_read_value_max_padding(self): | |
1038 | encoding = ('\x48\x00\x00\x00\x00\x00\x00\x00') | |
1039 | self.stream = BytearrayStream(str(encoding)) | |
1040 | ts = TextString() | |
1041 | ts.length = 0x01 | |
1042 | ts.read_value(self.stream) | |
1043 | ||
1044 | expected = 'H' | |
1045 | self.assertEqual(expected, ts.value, | |
1046 | self.bad_read.format('value', expected, ts.value)) | |
1047 | ||
1048 | def test_read(self): | |
1049 | encoding = ('\x42\x00\x00\x07\x00\x00\x00\x0B\x48\x65\x6C\x6C\x6F\x20' | |
1050 | '\x57\x6F\x72\x6C\x64\x00\x00\x00\x00\x00') | |
1051 | self.stream = BytearrayStream(str(encoding)) | |
1052 | ts = TextString() | |
1053 | ts.read(self.stream) | |
1054 | ||
1055 | expected = 'Hello World' | |
1056 | self.assertEqual(expected, ts.value, | |
1057 | self.bad_read.format('value', expected, ts.value)) | |
1058 | ||
1059 | def test_read_on_invalid_padding(self): | |
1060 | encoding = ('\x42\x00\x00\x07\x00\x00\x00\x0B\x48\x65\x6C\x6C\x6F\x20' | |
1061 | '\x57\x6F\x72\x6C\x64\xff\xff\xff\xff\xff') | |
1062 | self.stream = BytearrayStream(str(encoding)) | |
1063 | ts = TextString() | |
1064 | ||
1065 | self.assertRaises(errors.ReadValueError, ts.read, self.stream) | |
1066 | ||
1067 | def test_write_value(self): | |
1068 | encoding = ('\x48\x65\x6C\x6C\x6F\x20\x57\x6F\x72\x6C\x64\x00\x00\x00' | |
1069 | '\x00\x00') | |
1070 | self.stream = BytearrayStream() | |
1071 | value = 'Hello World' | |
1072 | ts = TextString(value) | |
1073 | ts.write_value(self.stream) | |
1074 | ||
1075 | result = self.stream.read() | |
1076 | len_exp = len(encoding) | |
1077 | len_rcv = len(result) | |
1078 | ||
1079 | self.assertEqual(len_exp, len_rcv, | |
1080 | self.bad_length.format(len_exp, len_rcv)) | |
1081 | self.assertEqual(encoding, result, self.bad_encoding) | |
1082 | ||
1083 | def test_write_value_no_padding(self): | |
1084 | encoding = ('\x48\x65\x6C\x6C\x6F\x20\x57\x6F') | |
1085 | self.stream = BytearrayStream() | |
1086 | value = 'Hello Wo' | |
1087 | ts = TextString(value) | |
1088 | ts.write_value(self.stream) | |
1089 | ||
1090 | result = self.stream.read() | |
1091 | len_exp = len(encoding) | |
1092 | len_rcv = len(result) | |
1093 | ||
1094 | self.assertEqual(len_exp, len_rcv, | |
1095 | self.bad_length.format(len_exp, len_rcv)) | |
1096 | self.assertEqual(encoding, result, self.bad_encoding) | |
1097 | ||
1098 | def test_write_value_max_padding(self): | |
1099 | encoding = ('\x48\x00\x00\x00\x00\x00\x00\x00') | |
1100 | self.stream = BytearrayStream() | |
1101 | value = 'H' | |
1102 | ts = TextString(value) | |
1103 | ts.write_value(self.stream) | |
1104 | ||
1105 | result = self.stream.read() | |
1106 | len_exp = len(encoding) | |
1107 | len_rcv = len(result) | |
1108 | ||
1109 | self.assertEqual(len_exp, len_rcv, | |
1110 | self.bad_length.format(len_exp, len_rcv)) | |
1111 | self.assertEqual(encoding, result, self.bad_encoding) | |
1112 | ||
1113 | def test_write(self): | |
1114 | encoding = ('\x42\x00\x00\x07\x00\x00\x00\x0B\x48\x65\x6C\x6C\x6F\x20' | |
1115 | '\x57\x6F\x72\x6C\x64\x00\x00\x00\x00\x00') | |
1116 | self.stream = BytearrayStream() | |
1117 | value = 'Hello World' | |
1118 | ts = TextString(value) | |
1119 | ts.write(self.stream) | |
1120 | ||
1121 | result = self.stream.read() | |
1122 | len_exp = len(encoding) | |
1123 | len_rcv = len(result) | |
1124 | ||
1125 | self.assertEqual(len_exp, len_rcv, | |
1126 | self.bad_length.format(len_exp, len_rcv)) | |
1127 | self.assertEqual(encoding, result, self.bad_encoding) | |
1128 | ||
1129 | ||
1130 | class TestByteString(TestCase): | |
1131 | ||
1132 | def setUp(self): | |
1133 | super(self.__class__, self).setUp() | |
1134 | self.stream = BytearrayStream() | |
1135 | self.bad_type = ErrorStrings.BAD_EXP_RECV.format('ByteString.{0}', | |
1136 | 'type', '{1}', '{2}') | |
1137 | self.bad_value = ErrorStrings.BAD_EXP_RECV.format('ByteString.{0}', | |
1138 | 'value', '{1}', | |
1139 | '{2}') | |
1140 | self.bad_read = ErrorStrings.BAD_EXP_RECV.format('ByteString.{0}', | |
1141 | '', '{1}', '{2}') | |
1142 | self.bad_write = ErrorStrings.BAD_EXP_RECV.format('ByteString.{0}', | |
1143 | 'write', '{1}', | |
1144 | '{2}') | |
1145 | self.bad_encoding = ErrorStrings.BAD_ENCODING.format('ByteString', '') | |
1146 | self.bad_length = ErrorStrings.BAD_EXP_RECV.format('ByteString', | |
1147 | 'length', | |
1148 | '{0} bytes', | |
1149 | '{1} bytes') | |
1150 | ||
1151 | def tearDown(self): | |
1152 | super(self.__class__, self).tearDown() | |
1153 | ||
1154 | def test_init(self): | |
1155 | value = bytearray('\x01\x02\x03') | |
1156 | bs = ByteString(value) | |
1157 | ||
1158 | self.assertIsInstance(bs.value, bytearray, | |
1159 | self.bad_type.format('value', bytearray, | |
1160 | type(bs.value))) | |
1161 | self.assertEqual(value, bs.value, | |
1162 | self.bad_value.format('value', value, bs.value)) | |
1163 | ||
1164 | def test_init_unset(self): | |
1165 | bs = ByteString() | |
1166 | ||
1167 | self.assertIsInstance(bs.value, type(None), | |
1168 | self.bad_type.format('value', type(None), | |
1169 | type(bs.value))) | |
1170 | self.assertEqual(None, bs.value, | |
1171 | self.bad_value.format('value', None, bs.value)) | |
1172 | ||
1173 | def test_validate_on_valid(self): | |
1174 | bs = ByteString() | |
1175 | bs.value = bytearray('\x00') | |
1176 | ||
1177 | # Check no exception thrown. | |
1178 | bs.validate() | |
1179 | ||
1180 | def test_validate_on_valid_unset(self): | |
1181 | bs = ByteString() | |
1182 | ||
1183 | # Check no exception thrown. | |
1184 | bs.validate() | |
1185 | ||
1186 | def test_validate_on_invalid_type(self): | |
1187 | bs = ByteString() | |
1188 | bs.value = 0 | |
1189 | ||
1190 | self.assertRaises(TypeError, bs.validate) | |
1191 | ||
1192 | def test_read_value(self): | |
1193 | encoding = ('\x01\x02\x03\x00\x00\x00\x00\x00') | |
1194 | self.stream = BytearrayStream(str(encoding)) | |
1195 | bs = ByteString() | |
1196 | bs.length = 0x03 | |
1197 | bs.read_value(self.stream) | |
1198 | ||
1199 | expected = bytearray('\x01\x02\x03') | |
1200 | self.assertEqual(expected, bs.value, | |
1201 | self.bad_read.format('value', expected, bs.value)) | |
1202 | ||
1203 | def test_read_value_no_padding(self): | |
1204 | encoding = ('\x01\x02\x03\x04\x05\x06\x07\x08') | |
1205 | self.stream = BytearrayStream(str(encoding)) | |
1206 | bs = ByteString() | |
1207 | bs.length = 0x08 | |
1208 | bs.read_value(self.stream) | |
1209 | ||
1210 | expected = bytearray('\x01\x02\x03\x04\x05\x06\x07\x08') | |
1211 | self.assertEqual(expected, bs.value, | |
1212 | self.bad_read.format('value', expected, bs.value)) | |
1213 | ||
1214 | def test_read_value_max_padding(self): | |
1215 | encoding = ('\x01\x00\x00\x00\x00\x00\x00\x00') | |
1216 | self.stream = BytearrayStream(str(encoding)) | |
1217 | bs = ByteString() | |
1218 | bs.length = 0x01 | |
1219 | bs.read_value(self.stream) | |
1220 | ||
1221 | expected = bytearray('\x01') | |
1222 | self.assertEqual(expected, bs.value, | |
1223 | self.bad_read.format('value', expected, bs.value)) | |
1224 | ||
1225 | def test_read_value_zero(self): | |
1226 | encoding = ('\x00\x00\x00\x00\x00\x00\x00\x00') | |
1227 | self.stream = BytearrayStream(str(encoding)) | |
1228 | bs = ByteString() | |
1229 | bs.length = 0x01 | |
1230 | bs.read_value(self.stream) | |
1231 | ||
1232 | expected = bytearray('\x00') | |
1233 | self.assertEqual(expected, bs.value, | |
1234 | self.bad_read.format('value', expected, bs.value)) | |
1235 | ||
1236 | def test_read(self): | |
1237 | encoding = ('\x42\x00\x00\x08\x00\x00\x00\x03\x01\x02\x03\x00\x00\x00' | |
1238 | '\x00\x00') | |
1239 | self.stream = BytearrayStream(str(encoding)) | |
1240 | bs = ByteString() | |
1241 | bs.read(self.stream) | |
1242 | ||
1243 | expected = bytearray('\x01\x02\x03') | |
1244 | self.assertEqual(expected, bs.value, | |
1245 | self.bad_read.format('value', expected, bs.value)) | |
1246 | ||
1247 | def test_read_on_invalid_padding(self): | |
1248 | encoding = ('\x42\x00\x00\x08\x00\x00\x00\x03\x01\x02\x03\xff\xff\xff' | |
1249 | '\xff\xff') | |
1250 | self.stream = BytearrayStream(str(encoding)) | |
1251 | bs = ByteString() | |
1252 | ||
1253 | self.assertRaises(errors.ReadValueError, bs.read, self.stream) | |
1254 | ||
1255 | def test_write_value(self): | |
1256 | encoding = ('\x01\x02\x03\x00\x00\x00\x00\x00') | |
1257 | self.stream = BytearrayStream() | |
1258 | value = bytearray('\x01\x02\x03') | |
1259 | bs = ByteString(value) | |
1260 | bs.write_value(self.stream) | |
1261 | ||
1262 | result = self.stream.read() | |
1263 | len_exp = len(encoding) | |
1264 | len_rcv = len(result) | |
1265 | ||
1266 | self.assertEqual(len_exp, len_rcv, | |
1267 | self.bad_length.format(len_exp, len_rcv)) | |
1268 | self.assertEqual(encoding, result, self.bad_encoding) | |
1269 | ||
1270 | def test_write_value_no_padding(self): | |
1271 | encoding = ('\x01\x02\x03\x04\x05\x06\x07\x08') | |
1272 | self.stream = BytearrayStream() | |
1273 | value = bytearray('\x01\x02\x03\x04\x05\x06\x07\x08') | |
1274 | bs = ByteString(value) | |
1275 | bs.write_value(self.stream) | |
1276 | ||
1277 | result = self.stream.read() | |
1278 | len_exp = len(encoding) | |
1279 | len_rcv = len(result) | |
1280 | ||
1281 | self.assertEqual(len_exp, len_rcv, | |
1282 | self.bad_length.format(len_exp, len_rcv)) | |
1283 | self.assertEqual(encoding, result, self.bad_encoding) | |
1284 | ||
1285 | def test_write_value_max_padding(self): | |
1286 | encoding = ('\x01\x00\x00\x00\x00\x00\x00\x00') | |
1287 | self.stream = BytearrayStream() | |
1288 | value = bytearray('\x01') | |
1289 | bs = ByteString(value) | |
1290 | bs.write_value(self.stream) | |
1291 | ||
1292 | result = self.stream.read() | |
1293 | len_exp = len(encoding) | |
1294 | len_rcv = len(result) | |
1295 | ||
1296 | self.assertEqual(len_exp, len_rcv, | |
1297 | self.bad_length.format(len_exp, len_rcv)) | |
1298 | self.assertEqual(encoding, result, self.bad_encoding) | |
1299 | ||
1300 | def test_write_value_zero(self): | |
1301 | encoding = ('\x00\x00\x00\x00\x00\x00\x00\x00') | |
1302 | self.stream = BytearrayStream() | |
1303 | value = bytearray('\x00') | |
1304 | bs = ByteString(value) | |
1305 | bs.write_value(self.stream) | |
1306 | ||
1307 | result = self.stream.read() | |
1308 | len_exp = len(encoding) | |
1309 | len_rcv = len(result) | |
1310 | ||
1311 | self.assertEqual(len_exp, len_rcv, | |
1312 | self.bad_length.format(len_exp, len_rcv)) | |
1313 | self.assertEqual(encoding, result, self.bad_encoding) | |
1314 | ||
1315 | def test_write(self): | |
1316 | encoding = ('\x42\x00\x00\x08\x00\x00\x00\x03\x01\x02\x03\x00\x00\x00' | |
1317 | '\x00\x00') | |
1318 | self.stream = BytearrayStream() | |
1319 | value = bytearray('\x01\x02\x03') | |
1320 | bs = ByteString(value) | |
1321 | bs.write(self.stream) | |
1322 | ||
1323 | result = self.stream.read() | |
1324 | len_exp = len(encoding) | |
1325 | len_rcv = len(result) | |
1326 | ||
1327 | self.assertEqual(len_exp, len_rcv, | |
1328 | self.bad_length.format(len_exp, len_rcv)) | |
1329 | self.assertEqual(encoding, result, self.bad_encoding) | |
1330 | ||
1331 | ||
1332 | class TestDateTime(TestCase): | |
1333 | ||
1334 | def setUp(self): | |
1335 | super(self.__class__, self).setUp() | |
1336 | self.stream = BytearrayStream() | |
1337 | ||
1338 | def tearDown(self): | |
1339 | super(self.__class__, self).tearDown() | |
1340 | ||
1341 | def test_init(self): | |
1342 | self.skip('') | |
1343 | ||
1344 | def test_init_unset(self): | |
1345 | self.skip('') | |
1346 | ||
1347 | def test_validate_on_valid(self): | |
1348 | self.skip('') | |
1349 | ||
1350 | def test_validate_on_valid_unset(self): | |
1351 | self.skip('') | |
1352 | ||
1353 | def test_validate_on_invalid_type(self): | |
1354 | self.skip('') | |
1355 | ||
1356 | def test_read(self): | |
1357 | self.skip('') | |
1358 | ||
1359 | def test_write(self): | |
1360 | self.skip('') | |
1361 | ||
1362 | ||
1363 | class TestInterval(TestCase): | |
1364 | ||
1365 | def setUp(self): | |
1366 | super(self.__class__, self).setUp() | |
1367 | self.stream = BytearrayStream() | |
1368 | ||
1369 | def tearDown(self): | |
1370 | super(self.__class__, self).tearDown() | |
1371 | ||
1372 | def test_init(self): | |
1373 | self.skip('') | |
1374 | ||
1375 | def test_init_unset(self): | |
1376 | self.skip('') | |
1377 | ||
1378 | def test_validate_on_valid(self): | |
1379 | self.skip('') | |
1380 | ||
1381 | def test_validate_on_valid_unset(self): | |
1382 | self.skip('') | |
1383 | ||
1384 | def test_validate_on_invalid_type(self): | |
1385 | self.skip('') | |
1386 | ||
1387 | def test_read(self): | |
1388 | self.skip('') | |
1389 | ||
1390 | def test_write(self): | |
1391 | self.skip('') |
0 | # Copyright (c) 2014 The Johns Hopkins University/Applied Physics Laboratory | |
1 | # All Rights Reserved. | |
2 | # | |
3 | # Licensed under the Apache License, Version 2.0 (the "License"); you may | |
4 | # not use this file except in compliance with the License. You may obtain | |
5 | # a copy of the License at | |
6 | # | |
7 | # http://www.apache.org/licenses/LICENSE-2.0 | |
8 | # | |
9 | # Unless required by applicable law or agreed to in writing, software | |
10 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT | |
11 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the | |
12 | # License for the specific language governing permissions and limitations | |
13 | # under the License. | |
14 | ||
15 | from testtools import TestCase | |
16 | ||
17 | from kmip.core.attributes import CryptographicAlgorithm | |
18 | from kmip.core.attributes import CryptographicLength | |
19 | from kmip.core.attributes import CryptographicUsageMask | |
20 | from kmip.core.attributes import UniqueIdentifier | |
21 | from kmip.core.attributes import ObjectType | |
22 | from kmip.core.enums import AttributeType | |
23 | from kmip.core.enums import CryptographicAlgorithm as CryptoAlgorithmEnum | |
24 | from kmip.core.enums import CryptographicUsageMask as CryptoUsageMaskEnum | |
25 | from kmip.core.enums import KeyCompressionType as KeyCompressionTypeEnum | |
26 | from kmip.core.enums import KeyFormatType as KeyFormatTypeEnum | |
27 | from kmip.core.enums import ObjectType as ObjectTypeEnum | |
28 | from kmip.core.enums import ResultReason | |
29 | from kmip.core.enums import ResultStatus | |
30 | from kmip.core.factories.attributes import AttributeFactory | |
31 | from kmip.core.keys import RawKey | |
32 | from kmip.core.messages.contents import KeyCompressionType | |
33 | from kmip.core.messages.contents import KeyFormatType | |
34 | from kmip.core.objects import KeyBlock | |
35 | from kmip.core.objects import KeyValueStruct | |
36 | from kmip.core.objects import TemplateAttribute | |
37 | from kmip.core.secrets import SymmetricKey | |
38 | from kmip.core.server import KMIPImpl | |
39 | ||
40 | ||
41 | class TestKMIPServer(TestCase): | |
42 | ||
43 | def setUp(self): | |
44 | super(TestKMIPServer, self).setUp() | |
45 | self.kmip = KMIPImpl() | |
46 | self.algorithm_name = CryptoAlgorithmEnum.AES | |
47 | self.key_length = 256 | |
48 | self.key = bytearray(range(0, 32)) | |
49 | self.usage_mask = CryptoUsageMaskEnum.ENCRYPT.value |\ | |
50 | CryptoUsageMaskEnum.DECRYPT.value | |
51 | ||
52 | def tearDown(self): | |
53 | super(TestKMIPServer, self).tearDown() | |
54 | ||
55 | def test_create(self): | |
56 | obj_type = ObjectType(ObjectTypeEnum.SYMMETRIC_KEY) | |
57 | attributes = self._get_attrs() | |
58 | template_attribute = TemplateAttribute(attributes=attributes) | |
59 | res = self.kmip.create(obj_type, template_attribute) | |
60 | self.assertNotEqual(None, res, 'result is None') | |
61 | self.assertEqual(ResultStatus.SUCCESS, res.result_status.enum, | |
62 | 'result status did not return success') | |
63 | ||
64 | def test_create_no_length(self): | |
65 | obj_type = ObjectType(ObjectTypeEnum.SYMMETRIC_KEY) | |
66 | attributes = self._get_attrs()[0:2] | |
67 | template_attribute = TemplateAttribute(attributes=attributes) | |
68 | res = self.kmip.create(obj_type, template_attribute) | |
69 | self.assertNotEqual(None, res, 'result is None') | |
70 | attrs = res.template_attribute.attributes | |
71 | self.assertEqual(ResultStatus.SUCCESS, res.result_status.enum, | |
72 | 'result status did not return success') | |
73 | self.assertTrue(self._check_attr_exists(attributes[2], attrs), | |
74 | 'length attribute not returned') | |
75 | ||
76 | def test_create_no_alg(self): | |
77 | obj_type = ObjectType(ObjectTypeEnum.SYMMETRIC_KEY) | |
78 | attributes = [self._get_attrs()[1]] | |
79 | template_attribute = TemplateAttribute(attributes=attributes) | |
80 | res = self.kmip.create(obj_type, template_attribute) | |
81 | self.assertNotEqual(None, res, 'result is None') | |
82 | self.assertEqual(ResultStatus.OPERATION_FAILED, res.result_status.enum, | |
83 | 'result status did not return failed') | |
84 | ||
85 | def test_create_no_usage_mask(self): | |
86 | obj_type = ObjectType(ObjectTypeEnum.SYMMETRIC_KEY) | |
87 | attributes = [self._get_attrs()[0]] | |
88 | template_attribute = TemplateAttribute(attributes=attributes) | |
89 | res = self.kmip.create(obj_type, template_attribute) | |
90 | self.assertNotEqual(None, res, 'result is None') | |
91 | self.assertEqual(ResultStatus.OPERATION_FAILED, res.result_status.enum, | |
92 | 'result status did not return failed') | |
93 | ||
94 | def test_register(self): | |
95 | obj_type = ObjectType(ObjectTypeEnum.SYMMETRIC_KEY) | |
96 | key = self._get_symmetric_key() | |
97 | attributes = [] | |
98 | template_attribute = TemplateAttribute(attributes=attributes) | |
99 | res = self.kmip.register(obj_type, template_attribute, key) | |
100 | self.assertNotEqual(None, res, 'result is None') | |
101 | self.assertEqual(ResultStatus.SUCCESS, res.result_status.enum, | |
102 | 'result status did not return success') | |
103 | ||
104 | def test_register_attrs_in_key_value(self): | |
105 | obj_type = ObjectType(ObjectTypeEnum.SYMMETRIC_KEY) | |
106 | key = self._get_symmetric_key() | |
107 | key.key_block.cryptographic_algorithm = None | |
108 | key.key_block.cryptographic_length = None | |
109 | key.key_block.key_value.attributes = self._get_attrs() | |
110 | attributes = [] | |
111 | template_attribute = TemplateAttribute(attributes=attributes) | |
112 | res = self.kmip.register(obj_type, template_attribute, key) | |
113 | self.assertNotEqual(None, res, 'result is None') | |
114 | self.assertEqual(ResultStatus.SUCCESS, res.result_status.enum, | |
115 | 'result status did not return success') | |
116 | ||
117 | def test_register_attrs_in_template(self): | |
118 | obj_type = ObjectType(ObjectTypeEnum.SYMMETRIC_KEY) | |
119 | key = self._get_symmetric_key() | |
120 | key.key_block.cryptographic_algorithm = None | |
121 | key.key_block.cryptographic_length = None | |
122 | key.key_block.key_value.attributes = [] | |
123 | attributes = self._get_attrs() | |
124 | template_attribute = TemplateAttribute(attributes=attributes) | |
125 | res = self.kmip.register(obj_type, template_attribute, key) | |
126 | self.assertNotEqual(None, res, 'result is None') | |
127 | self.assertEqual(ResultStatus.SUCCESS, res.result_status.enum, | |
128 | 'result status did not return success') | |
129 | ||
130 | def test_register_no_alg(self): | |
131 | obj_type = ObjectType(ObjectTypeEnum.SYMMETRIC_KEY) | |
132 | key = self._get_symmetric_key() | |
133 | key.key_block.cryptographic_algorithm = None | |
134 | attributes = [] | |
135 | template_attribute = TemplateAttribute(attributes=attributes) | |
136 | res = self.kmip.register(obj_type, template_attribute, key) | |
137 | self.assertEqual(ResultStatus.OPERATION_FAILED, | |
138 | res.result_status.enum, | |
139 | 'result status did not return failed') | |
140 | self.assertEqual(ResultReason.ITEM_NOT_FOUND, | |
141 | res.result_reason.enum, | |
142 | 'result reason did not match') | |
143 | ||
144 | def test_register_alg_in_key_value_and_key_block(self): | |
145 | obj_type = ObjectType(ObjectTypeEnum.SYMMETRIC_KEY) | |
146 | key = self._get_symmetric_key() | |
147 | key.key_block.key_value.attributes = [self._get_alg_attr()] | |
148 | attributes = [] | |
149 | template_attribute = TemplateAttribute(attributes=attributes) | |
150 | res = self.kmip.register(obj_type, template_attribute, key) | |
151 | self.assertEqual(ResultStatus.OPERATION_FAILED, | |
152 | res.result_status.enum, | |
153 | 'result status did not return failed') | |
154 | self.assertEqual(ResultReason.INDEX_OUT_OF_BOUNDS, | |
155 | res.result_reason.enum, | |
156 | 'result reason did not match') | |
157 | ||
158 | def test_register_alg_in_template_and_key_block(self): | |
159 | obj_type = ObjectType(ObjectTypeEnum.SYMMETRIC_KEY) | |
160 | key = self._get_symmetric_key() | |
161 | attributes = [self._get_alg_attr()] | |
162 | template_attribute = TemplateAttribute(attributes=attributes) | |
163 | res = self.kmip.register(obj_type, template_attribute, key) | |
164 | self.assertEqual(ResultStatus.OPERATION_FAILED, | |
165 | res.result_status.enum, | |
166 | 'result status did not return failed') | |
167 | self.assertEqual(ResultReason.INDEX_OUT_OF_BOUNDS, | |
168 | res.result_reason.enum, | |
169 | 'result reason did not match') | |
170 | ||
171 | def test_register_alg_in_template_and_key_value(self): | |
172 | obj_type = ObjectType(ObjectTypeEnum.SYMMETRIC_KEY) | |
173 | key = self._get_symmetric_key() | |
174 | key.key_block.cryptographic_algorithm = None | |
175 | key.key_block.key_value.attributes = [self._get_alg_attr()] | |
176 | attributes = [self._get_alg_attr()] | |
177 | template_attribute = TemplateAttribute(attributes=attributes) | |
178 | res = self.kmip.register(obj_type, template_attribute, key) | |
179 | self.assertEqual(ResultStatus.OPERATION_FAILED, | |
180 | res.result_status.enum, | |
181 | 'result status did not return failed') | |
182 | self.assertEqual(ResultReason.INDEX_OUT_OF_BOUNDS, | |
183 | res.result_reason.enum, | |
184 | 'result reason did not match') | |
185 | ||
186 | def test_register_invalid_alg(self): | |
187 | unsupported_algs = (CryptoAlgorithmEnum.RSA, | |
188 | CryptoAlgorithmEnum.DSA, | |
189 | CryptoAlgorithmEnum.ECDSA, | |
190 | CryptoAlgorithmEnum.HMAC_SHA1, | |
191 | CryptoAlgorithmEnum.HMAC_SHA224, | |
192 | CryptoAlgorithmEnum.HMAC_SHA256, | |
193 | CryptoAlgorithmEnum.HMAC_SHA384, | |
194 | CryptoAlgorithmEnum.HMAC_SHA512, | |
195 | CryptoAlgorithmEnum.HMAC_MD5, | |
196 | CryptoAlgorithmEnum.DH, | |
197 | CryptoAlgorithmEnum.ECDH, | |
198 | CryptoAlgorithmEnum.ECMQV, | |
199 | CryptoAlgorithmEnum.BLOWFISH, | |
200 | CryptoAlgorithmEnum.CAMELLIA, | |
201 | CryptoAlgorithmEnum.CAST5, | |
202 | CryptoAlgorithmEnum.IDEA, | |
203 | CryptoAlgorithmEnum.MARS, | |
204 | CryptoAlgorithmEnum.RC2, | |
205 | CryptoAlgorithmEnum.RC4, | |
206 | CryptoAlgorithmEnum.RC5, | |
207 | CryptoAlgorithmEnum.SKIPJACK, | |
208 | CryptoAlgorithmEnum.TWOFISH) | |
209 | for alg in unsupported_algs: | |
210 | obj_type = ObjectType(ObjectTypeEnum.SYMMETRIC_KEY) | |
211 | key = self._get_symmetric_key() | |
212 | key.key_block.cryptographic_algorithm = CryptographicAlgorithm(alg) | |
213 | attributes = [] | |
214 | template_attribute = TemplateAttribute(attributes=attributes) | |
215 | res = self.kmip.register(obj_type, template_attribute, key) | |
216 | self.assertEqual(ResultStatus.OPERATION_FAILED, | |
217 | res.result_status.enum, | |
218 | 'result status did not return failed') | |
219 | self.assertEqual(ResultReason.INVALID_FIELD, | |
220 | res.result_reason.enum, | |
221 | 'result reason did not match') | |
222 | ||
223 | def test_register_no_length(self): | |
224 | obj_type = ObjectType(ObjectTypeEnum.SYMMETRIC_KEY) | |
225 | key = self._get_symmetric_key() | |
226 | key.key_block.cryptographic_length = None | |
227 | attributes = [] | |
228 | template_attribute = TemplateAttribute(attributes=attributes) | |
229 | res = self.kmip.register(obj_type, template_attribute, key) | |
230 | self.assertEqual(ResultStatus.OPERATION_FAILED, | |
231 | res.result_status.enum, | |
232 | 'result status did not return failed') | |
233 | self.assertEqual(ResultReason.ITEM_NOT_FOUND, | |
234 | res.result_reason.enum, | |
235 | 'result reason did not match') | |
236 | ||
237 | def test_register_length_in_key_value_and_key_block(self): | |
238 | obj_type = ObjectType(ObjectTypeEnum.SYMMETRIC_KEY) | |
239 | key = self._get_symmetric_key() | |
240 | key.key_block.key_value.attributes = [self._get_length_attr()] | |
241 | attributes = [] | |
242 | template_attribute = TemplateAttribute(attributes=attributes) | |
243 | res = self.kmip.register(obj_type, template_attribute, key) | |
244 | self.assertEqual(ResultStatus.OPERATION_FAILED, | |
245 | res.result_status.enum, | |
246 | 'result status did not return failed') | |
247 | self.assertEqual(ResultReason.INDEX_OUT_OF_BOUNDS, | |
248 | res.result_reason.enum, | |
249 | 'result reason did not match') | |
250 | ||
251 | def test_register_length_in_template_and_key_block(self): | |
252 | obj_type = ObjectType(ObjectTypeEnum.SYMMETRIC_KEY) | |
253 | key = self._get_symmetric_key() | |
254 | attributes = [self._get_length_attr()] | |
255 | template_attribute = TemplateAttribute(attributes=attributes) | |
256 | res = self.kmip.register(obj_type, template_attribute, key) | |
257 | self.assertEqual(ResultStatus.OPERATION_FAILED, | |
258 | res.result_status.enum, | |
259 | 'result status did not return failed') | |
260 | self.assertEqual(ResultReason.INDEX_OUT_OF_BOUNDS, | |
261 | res.result_reason.enum, | |
262 | 'result reason did not match') | |
263 | ||
264 | def test_register_length_in_template_and_key_value(self): | |
265 | obj_type = ObjectType(ObjectTypeEnum.SYMMETRIC_KEY) | |
266 | key = self._get_symmetric_key() | |
267 | key.key_block.cryptographic_length = None | |
268 | key.key_block.key_value.attributes = [self._get_length_attr()] | |
269 | attributes = [self._get_length_attr()] | |
270 | template_attribute = TemplateAttribute(attributes=attributes) | |
271 | res = self.kmip.register(obj_type, template_attribute, key) | |
272 | self.assertEqual(ResultStatus.OPERATION_FAILED, | |
273 | res.result_status.enum, | |
274 | 'result status did not return failed') | |
275 | self.assertEqual(ResultReason.INDEX_OUT_OF_BOUNDS, | |
276 | res.result_reason.enum, | |
277 | 'result reason did not match') | |
278 | ||
279 | def test_register_invalid_length(self): | |
280 | unsupported_lens = (-1, 0, 2048, 5, 18) | |
281 | for len in unsupported_lens: | |
282 | obj_type = ObjectType(ObjectTypeEnum.SYMMETRIC_KEY) | |
283 | key = self._get_symmetric_key() | |
284 | key.key_block.cryptographic_length = CryptographicLength(len) | |
285 | attributes = [] | |
286 | template_attribute = TemplateAttribute(attributes=attributes) | |
287 | res = self.kmip.register(obj_type, template_attribute, key) | |
288 | self.assertEqual(ResultStatus.OPERATION_FAILED, | |
289 | res.result_status.enum, | |
290 | 'result status did not return failed') | |
291 | self.assertEqual(ResultReason.INVALID_FIELD, | |
292 | res.result_reason.enum, | |
293 | 'result reason did not match') | |
294 | ||
295 | def test_register_no_usage_mask(self): | |
296 | obj_type = ObjectType(ObjectTypeEnum.SYMMETRIC_KEY) | |
297 | key = self._get_symmetric_key() | |
298 | key.key_block.key_value.attributes = [] | |
299 | attributes = [] | |
300 | template_attribute = TemplateAttribute(attributes=attributes) | |
301 | res = self.kmip.register(obj_type, template_attribute, key) | |
302 | self.assertEqual(ResultStatus.OPERATION_FAILED, | |
303 | res.result_status.enum, | |
304 | 'result status did not return failed') | |
305 | self.assertEqual(ResultReason.ITEM_NOT_FOUND, | |
306 | res.result_reason.enum, | |
307 | 'result reason did not match') | |
308 | ||
309 | def test_register_no_object_type(self): | |
310 | obj_type = None | |
311 | key = self._get_symmetric_key() | |
312 | attributes = [] | |
313 | template_attribute = TemplateAttribute(attributes=attributes) | |
314 | res = self.kmip.register(obj_type, template_attribute, key) | |
315 | self.assertNotEqual(None, res, 'result is None') | |
316 | self.assertEqual(ResultStatus.OPERATION_FAILED, | |
317 | res.result_status.enum, | |
318 | 'result status did not return failed') | |
319 | self.assertEqual(ResultReason.ITEM_NOT_FOUND, | |
320 | res.result_reason.enum, | |
321 | 'result reason did not match') | |
322 | ||
323 | def test_register_unsupported_object_type(self): | |
324 | unsupported_types = (ObjectTypeEnum.CERTIFICATE, | |
325 | ObjectTypeEnum.PUBLIC_KEY, | |
326 | ObjectTypeEnum.PRIVATE_KEY, | |
327 | ObjectTypeEnum.SPLIT_KEY, | |
328 | ObjectTypeEnum.TEMPLATE, | |
329 | ObjectTypeEnum.SECRET_DATA, | |
330 | ObjectTypeEnum.OPAQUE_DATA) | |
331 | for unsupported_type in unsupported_types: | |
332 | obj_type = ObjectType(unsupported_type) | |
333 | key = self._get_symmetric_key() | |
334 | attributes = [] | |
335 | template_attribute = TemplateAttribute(attributes=attributes) | |
336 | res = self.kmip.register(obj_type, template_attribute, key) | |
337 | self.assertNotEqual(None, res, 'result is None') | |
338 | self.assertEqual(ResultStatus.OPERATION_FAILED, | |
339 | res.result_status.enum, | |
340 | 'result status did not return failed') | |
341 | self.assertEqual(ResultReason.INVALID_FIELD, | |
342 | res.result_reason.enum, | |
343 | 'result reason did not match') | |
344 | ||
345 | def test_register_object_type_mismatch(self): | |
346 | unsupported_types = (ObjectTypeEnum.CERTIFICATE, | |
347 | ObjectTypeEnum.PUBLIC_KEY, | |
348 | ObjectTypeEnum.PRIVATE_KEY, | |
349 | ObjectTypeEnum.SPLIT_KEY, | |
350 | ObjectTypeEnum.TEMPLATE, | |
351 | ObjectTypeEnum.SECRET_DATA, | |
352 | ObjectTypeEnum.OPAQUE_DATA) | |
353 | for unsupported_type in unsupported_types: | |
354 | obj_type = ObjectType(unsupported_type) | |
355 | key = self._get_symmetric_key() | |
356 | attributes = [] | |
357 | template_attribute = TemplateAttribute(attributes=attributes) | |
358 | res = self.kmip.register(obj_type, template_attribute, key) | |
359 | self.assertNotEqual(None, res, 'result is None') | |
360 | self.assertEqual(ResultStatus.OPERATION_FAILED, | |
361 | res.result_status.enum, | |
362 | 'result status did not return failed') | |
363 | self.assertEqual(ResultReason.INVALID_FIELD, | |
364 | res.result_reason.enum, | |
365 | 'result reason did not match') | |
366 | ||
367 | def test_get(self): | |
368 | uuid = self._create() | |
369 | key_format_type = KeyFormatType(KeyFormatTypeEnum.RAW) | |
370 | res = self.kmip.get(uuid, key_format_type) | |
371 | self.assertEqual(ResultStatus.SUCCESS, res.result_status.enum, | |
372 | 'result status did not return success') | |
373 | ||
374 | def test_get_no_key_format_type(self): | |
375 | uuid = self._create() | |
376 | res = self.kmip.get(uuid, None) | |
377 | self.assertEqual(ResultStatus.SUCCESS, res.result_status.enum, | |
378 | 'result status did not return success') | |
379 | ||
380 | def test_get_unknown(self): | |
381 | uuids = ('some random string', UniqueIdentifier('no key here')) | |
382 | for uuid in uuids: | |
383 | key_format_type = KeyFormatType(KeyFormatTypeEnum.RAW) | |
384 | res = self.kmip.get(uuid, key_format_type) | |
385 | self.assertEqual(ResultStatus.OPERATION_FAILED, | |
386 | res.result_status.enum, | |
387 | 'result status did not return failed') | |
388 | self.assertEqual(ResultReason.ITEM_NOT_FOUND, | |
389 | res.result_reason.enum, | |
390 | 'result reason did not match') | |
391 | ||
392 | def test_get_no_uuid(self): | |
393 | self._create() | |
394 | key_format_type = KeyFormatType(KeyFormatTypeEnum.RAW) | |
395 | res = self.kmip.get(None, key_format_type) | |
396 | self.assertEqual(ResultStatus.OPERATION_FAILED, res.result_status.enum, | |
397 | 'result status did not return failed') | |
398 | ||
399 | def test_get_with_key_compression(self): | |
400 | uuid = self._create() | |
401 | key_format_type = KeyFormatType(KeyFormatTypeEnum.RAW) | |
402 | key_compression = KeyCompressionType(KeyCompressionTypeEnum. | |
403 | EC_PUBLIC_KEY_TYPE_UNCOMPRESSED) | |
404 | res = self.kmip.get(uuid, key_format_type, key_compression) | |
405 | self.assertEqual(ResultStatus.OPERATION_FAILED, res.result_status.enum, | |
406 | 'result status did not return failed') | |
407 | self.assertEqual(ResultReason.KEY_COMPRESSION_TYPE_NOT_SUPPORTED, | |
408 | res.result_reason.enum, | |
409 | 'result reason did not match') | |
410 | ||
411 | def test_destroy(self): | |
412 | uuid = self._create() | |
413 | key_format_type = KeyFormatType(KeyFormatTypeEnum.RAW) | |
414 | res = self.kmip.get(uuid, key_format_type) | |
415 | self.assertEqual(ResultStatus.SUCCESS, res.result_status.enum, | |
416 | 'result status did not return success') | |
417 | res = self.kmip.destroy(uuid) | |
418 | self.assertEqual(ResultStatus.SUCCESS, res.result_status.enum, | |
419 | 'result status did not return success') | |
420 | res = self.kmip.destroy(uuid) | |
421 | self.assertEqual(ResultStatus.OPERATION_FAILED, | |
422 | res.result_status.enum, | |
423 | 'result status did not return failed') | |
424 | self.assertEqual(ResultReason.ITEM_NOT_FOUND, | |
425 | res.result_reason.enum, | |
426 | 'result reason did not match') | |
427 | ||
428 | def test_destroy_no_uuid(self): | |
429 | res = self.kmip.destroy(None) | |
430 | self.assertEqual(ResultStatus.OPERATION_FAILED, | |
431 | res.result_status.enum, | |
432 | 'result status did not return failed') | |
433 | self.assertEqual(ResultReason.ITEM_NOT_FOUND, | |
434 | res.result_reason.enum, | |
435 | 'result reason did not match') | |
436 | ||
437 | def test_destroy_unknown(self): | |
438 | uuids = ('some random string', UniqueIdentifier('no key here')) | |
439 | for uuid in uuids: | |
440 | key_format_type = KeyFormatType(KeyFormatTypeEnum.RAW) | |
441 | res = self.kmip.get(uuid, key_format_type) | |
442 | self.assertEqual(ResultStatus.OPERATION_FAILED, | |
443 | res.result_status.enum, | |
444 | 'result status did not return failed') | |
445 | res = self.kmip.destroy(uuid) | |
446 | self.assertEqual(ResultStatus.OPERATION_FAILED, | |
447 | res.result_status.enum, | |
448 | 'result status did not return failed') | |
449 | self.assertEqual(ResultReason.ITEM_NOT_FOUND, | |
450 | res.result_reason.enum, | |
451 | 'result reason did not match') | |
452 | ||
453 | def _create(self): | |
454 | obj_type = ObjectType(ObjectTypeEnum.SYMMETRIC_KEY) | |
455 | attributes = self._get_attrs() | |
456 | template_attribute = TemplateAttribute(attributes=attributes) | |
457 | res = self.kmip.create(obj_type, template_attribute) | |
458 | self.assertNotEqual(None, res, 'result is None') | |
459 | self.assertEqual(ResultStatus.SUCCESS, res.result_status.enum, | |
460 | 'result status did not return success') | |
461 | return res.uuid | |
462 | ||
463 | def _get_symmetric_key(self): | |
464 | # only need usage attribute | |
465 | attrs = [self._get_attrs()[1]] | |
466 | key_format_type = KeyBlock.KeyFormatType(KeyFormatTypeEnum.RAW) | |
467 | key_material = RawKey(self.key) | |
468 | key_value = KeyValueStruct(key_format_type, key_material, attrs) | |
469 | crypto_alg = CryptographicAlgorithm(self.algorithm_name) | |
470 | crypto_length = CryptographicLength(self.key_length) | |
471 | usage = CryptographicUsageMask(self.usage_mask) | |
472 | key_block = KeyBlock(key_format_type, None, key_value, crypto_alg, | |
473 | crypto_length, usage) | |
474 | return SymmetricKey(key_block) | |
475 | ||
476 | def _get_attrs(self): | |
477 | attr_factory = AttributeFactory() | |
478 | algorithm = self._get_alg_attr(self.algorithm_name) | |
479 | length = self._get_length_attr(self.key_length) | |
480 | attribute_type = AttributeType.CRYPTOGRAPHIC_USAGE_MASK | |
481 | mask_flags = [CryptoUsageMaskEnum.ENCRYPT, | |
482 | CryptoUsageMaskEnum.DECRYPT] | |
483 | usage_mask = attr_factory.create_attribute(attribute_type, | |
484 | mask_flags) | |
485 | return [algorithm, usage_mask, length] | |
486 | ||
487 | def _get_alg_attr(self, alg=None): | |
488 | if alg is None: | |
489 | alg = self.algorithm_name | |
490 | attr_factory = AttributeFactory() | |
491 | attribute_type = AttributeType.CRYPTOGRAPHIC_ALGORITHM | |
492 | return attr_factory.create_attribute(attribute_type, alg) | |
493 | ||
494 | def _get_length_attr(self, length=None): | |
495 | if length is None: | |
496 | length = self.key_length | |
497 | attr_factory = AttributeFactory() | |
498 | attribute_type = AttributeType.CRYPTOGRAPHIC_LENGTH | |
499 | return attr_factory.create_attribute(attribute_type, length) | |
500 | ||
501 | def _check_attr_exists(self, attr_expected, attributes): | |
502 | for attribute in attributes: | |
503 | if attribute.attribute_name.value ==\ | |
504 | attr_expected.attribute_name.value: | |
505 | return attribute.attribute_value.value ==\ | |
506 | attr_expected.attribute_value.value | |
507 | return False |
0 | # Copyright (c) 2014 The Johns Hopkins University/Applied Physics Laboratory | |
1 | # All Rights Reserved. | |
2 | # | |
3 | # Licensed under the Apache License, Version 2.0 (the "License"); you may | |
4 | # not use this file except in compliance with the License. You may obtain | |
5 | # a copy of the License at | |
6 | # | |
7 | # http://www.apache.org/licenses/LICENSE-2.0 | |
8 | # | |
9 | # Unless required by applicable law or agreed to in writing, software | |
10 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT | |
11 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the | |
12 | # License for the specific language governing permissions and limitations | |
13 | # under the License. | |
14 | ||
15 | from testtools import TestCase | |
16 | ||
17 | from kmip.core.errors import ErrorStrings | |
18 | ||
19 | from kmip.core import utils | |
20 | ||
21 | ||
22 | class TestUtils(TestCase): | |
23 | ||
24 | def setUp(self): | |
25 | super(TestUtils, self).setUp() | |
26 | ||
27 | def tearDown(self): | |
28 | super(TestUtils, self).tearDown() | |
29 | ||
30 | def test_count_bytes(self): | |
31 | num = 65535 | |
32 | bytes_exp = 2 | |
33 | bytes_obs = utils.count_bytes(num) | |
34 | self.assertEqual(bytes_exp, bytes_obs, | |
35 | 'Value {0} requires {1} bytes to encode, ' | |
36 | 'received {2} byte(s)'.format(num, bytes_exp, | |
37 | bytes_obs)) | |
38 | ||
39 | def test_count_bytes_overflow(self): | |
40 | num = 65536 | |
41 | bytes_exp = 3 | |
42 | bytes_obs = utils.count_bytes(num) | |
43 | self.assertEqual(bytes_exp, bytes_obs, | |
44 | 'Value {0} requires {1} bytes to encode, ' | |
45 | 'received {2} bytes'.format(num, bytes_exp, | |
46 | bytes_obs)) | |
47 | ||
48 | def test_count_bytes_zero(self): | |
49 | num = 0 | |
50 | bytes_exp = 1 | |
51 | bytes_obs = utils.count_bytes(num) | |
52 | self.assertEqual(bytes_exp, bytes_obs, | |
53 | 'Value {0} requires {1} bytes to encode, ' | |
54 | 'received {2} byte(s)'.format(num, bytes_exp, | |
55 | bytes_obs)) | |
56 | ||
57 | ||
58 | class TestBytearrayStream(TestCase): | |
59 | ||
60 | def setUp(self): | |
61 | super(TestBytearrayStream, self).setUp() | |
62 | self.stream = utils.BytearrayStream() | |
63 | ||
64 | self.bad_type = ErrorStrings.BAD_EXP_RECV.format('BytearrayStream.{0}', | |
65 | 'type', '{1}', '{2}') | |
66 | self.bad_len = ErrorStrings.BAD_EXP_RECV.format('BytearrayStream.{0}', | |
67 | 'length', '{1}', '{2}') | |
68 | self.bad_val = ErrorStrings.BAD_EXP_RECV.format('BytearrayStream.{0}', | |
69 | 'value', '{1}', '{2}') | |
70 | ||
71 | def tearDown(self): | |
72 | super(TestBytearrayStream, self).tearDown() | |
73 | ||
74 | def test_init(self): | |
75 | value = '\x00' | |
76 | b = utils.BytearrayStream(value) | |
77 | ||
78 | buf_type = type(b.buffer) | |
79 | msg = self.bad_type.format('buffer', bytearray, buf_type) | |
80 | self.assertIsInstance(b.buffer, bytearray, | |
81 | msg.format(bytearray, type(b.buffer))) | |
82 | ||
83 | length = len(b.buffer) | |
84 | msg = self.bad_len.format('buffer', 1, length) | |
85 | self.assertEqual(1, length, msg) | |
86 | ||
87 | content = str(b.buffer) | |
88 | msg = self.bad_val.format('buffer', value, content) | |
89 | self.assertEqual(value, content, msg) | |
90 | ||
91 | def test_init_unset(self): | |
92 | b = utils.BytearrayStream() | |
93 | ||
94 | buf_type = type(b.buffer) | |
95 | msg = self.bad_type.format('buffer', bytearray, buf_type) | |
96 | self.assertIsInstance(b.buffer, bytearray, | |
97 | msg.format(bytearray, type(b.buffer))) | |
98 | ||
99 | length = len(b.buffer) | |
100 | msg = self.bad_len.format('buffer', 0, length) | |
101 | self.assertEqual(0, length, msg) | |
102 | ||
103 | def test_read(self): | |
104 | # TODO (peter-hamilton) Finish implementation. | |
105 | self.skip('') | |
106 | ||
107 | def test_write(self): | |
108 | # TODO (peter-hamilton) Finish implementation. | |
109 | self.skip('') | |
110 | ||
111 | def test_peek(self): | |
112 | # TODO (peter-hamilton) Finish implementation. | |
113 | value = ('\x00\x01\x02\x03') | |
114 | expected = value | |
115 | b = expected | |
116 | expected = b | |
117 | b = utils.BytearrayStream(value) | |
118 | ||
119 | def test_peek_overflow(self): | |
120 | # TODO (peter-hamilton) Finish implementation. | |
121 | self.skip('') | |
122 | ||
123 | def test_peek_empty(self): | |
124 | # TODO (peter-hamilton) Finish implementation. | |
125 | self.skip('') | |
126 | ||
127 | def test_peek_none(self): | |
128 | # TODO (peter-hamilton) Finish implementation. | |
129 | self.skip('') | |
130 | ||
131 | def test_length(self): | |
132 | # TODO (peter-hamilton) Finish implementation. | |
133 | self.skip('') |
0 | # Copyright (c) 2014 The Johns Hopkins University/Applied Physics Laboratory | |
1 | # All Rights Reserved. | |
2 | # | |
3 | # Licensed under the Apache License, Version 2.0 (the "License"); you may | |
4 | # not use this file except in compliance with the License. You may obtain | |
5 | # a copy of the License at | |
6 | # | |
7 | # http://www.apache.org/licenses/LICENSE-2.0 | |
8 | # | |
9 | # Unless required by applicable law or agreed to in writing, software | |
10 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT | |
11 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the | |
12 | # License for the specific language governing permissions and limitations | |
13 | # under the License. |
0 | # Copyright (c) 2014 The Johns Hopkins University/Applied Physics Laboratory | |
1 | # All Rights Reserved. | |
2 | # | |
3 | # Licensed under the Apache License, Version 2.0 (the "License"); you may | |
4 | # not use this file except in compliance with the License. You may obtain | |
5 | # a copy of the License at | |
6 | # | |
7 | # http://www.apache.org/licenses/LICENSE-2.0 | |
8 | # | |
9 | # Unless required by applicable law or agreed to in writing, software | |
10 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT | |
11 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the | |
12 | # License for the specific language governing permissions and limitations | |
13 | # under the License. | |
14 | ||
15 | from testtools import TestCase | |
16 | ||
17 | from subprocess import Popen | |
18 | ||
19 | import os | |
20 | import sys | |
21 | import time | |
22 | ||
23 | from kmip.core.enums import AttributeType | |
24 | from kmip.core.enums import CredentialType | |
25 | from kmip.core.enums import CryptographicAlgorithm | |
26 | from kmip.core.enums import CryptographicUsageMask | |
27 | from kmip.core.enums import ObjectType | |
28 | from kmip.core.enums import KeyFormatType | |
29 | from kmip.core.enums import ResultStatus | |
30 | from kmip.core.enums import ResultReason | |
31 | ||
32 | from kmip.core.errors import KMIPServerSuicideError | |
33 | from kmip.core.errors import KMIPServerZombieError | |
34 | ||
35 | from kmip.core.factories.attributes import AttributeFactory | |
36 | from kmip.core.factories.credentials import CredentialFactory | |
37 | from kmip.core.factories.secrets import SecretFactory | |
38 | ||
39 | from kmip.core.objects import Attribute | |
40 | from kmip.core.objects import TemplateAttribute | |
41 | ||
42 | from kmip.core.secrets import SymmetricKey | |
43 | ||
44 | from kmip.services.kmip_client import KMIPProxy | |
45 | ||
46 | import kmip.core.utils as utils | |
47 | ||
48 | ||
49 | class TestKMIPClient(TestCase): | |
50 | STARTUP_TIME = 1.0 | |
51 | SHUTDOWN_TIME = 0.1 | |
52 | KMIP_PORT = 9090 | |
53 | ||
54 | def setUp(self): | |
55 | super(TestKMIPClient, self).setUp() | |
56 | ||
57 | self.attr_factory = AttributeFactory() | |
58 | self.cred_factory = CredentialFactory() | |
59 | self.secret_factory = SecretFactory() | |
60 | ||
61 | # Set up the KMIP server process | |
62 | path = os.path.join(os.path.dirname(__file__), os.path.pardir, | |
63 | os.path.pardir, os.path.pardir, 'bin', | |
64 | 'run_server.py') | |
65 | self.server = Popen(['python', '{0}'.format(path), '-p', | |
66 | '{0}'.format(self.KMIP_PORT)], stderr=sys.stdout) | |
67 | ||
68 | time.sleep(self.STARTUP_TIME) | |
69 | ||
70 | if self.server.poll() is not None: | |
71 | raise KMIPServerSuicideError(self.server.pid) | |
72 | ||
73 | # Set up and open the client proxy; shutdown the server if open fails | |
74 | try: | |
75 | self.client = KMIPProxy(port=self.KMIP_PORT) | |
76 | self.client.open() | |
77 | except Exception, e: | |
78 | self._shutdown_server() | |
79 | raise e | |
80 | ||
81 | def tearDown(self): | |
82 | super(TestKMIPClient, self).tearDown() | |
83 | ||
84 | # Close the client proxy and shutdown the server | |
85 | self.client.close() | |
86 | self._shutdown_server() | |
87 | ||
88 | def test_create(self): | |
89 | result = self._create_symmetric_key() | |
90 | ||
91 | self._check_result_status(result.result_status.enum, ResultStatus, | |
92 | ResultStatus.SUCCESS) | |
93 | self._check_object_type(result.object_type.enum, ObjectType, | |
94 | ObjectType.SYMMETRIC_KEY) | |
95 | self._check_uuid(result.uuid.value, str) | |
96 | ||
97 | # Check the template attribute type | |
98 | self._check_template_attribute(result.template_attribute, | |
99 | TemplateAttribute, 2, | |
100 | [[str, 'Cryptographic Length', int, | |
101 | 256], | |
102 | [str, 'Unique Identifier', str, | |
103 | None]]) | |
104 | ||
105 | def test_get(self): | |
106 | credential_type = CredentialType.USERNAME_AND_PASSWORD | |
107 | credential_value = {'Username': 'Peter', 'Password': 'abc123'} | |
108 | credential = self.cred_factory.create_credential(credential_type, | |
109 | credential_value) | |
110 | result = self._create_symmetric_key() | |
111 | uuid = result.uuid.value | |
112 | ||
113 | result = self.client.get(uuid, credential) | |
114 | ||
115 | self._check_result_status(result.result_status.enum, ResultStatus, | |
116 | ResultStatus.SUCCESS) | |
117 | self._check_object_type(result.object_type.enum, ObjectType, | |
118 | ObjectType.SYMMETRIC_KEY) | |
119 | self._check_uuid(result.uuid.value, str) | |
120 | ||
121 | # Check the secret type | |
122 | secret = result.secret | |
123 | ||
124 | expected = SymmetricKey | |
125 | message = utils.build_er_error(result.__class__, 'type', expected, | |
126 | secret, 'secret') | |
127 | self.assertIsInstance(secret, expected, message) | |
128 | ||
129 | def test_destroy(self): | |
130 | credential_type = CredentialType.USERNAME_AND_PASSWORD | |
131 | credential_value = {'Username': 'Peter', 'Password': 'abc123'} | |
132 | credential = self.cred_factory.create_credential(credential_type, | |
133 | credential_value) | |
134 | result = self._create_symmetric_key() | |
135 | uuid = result.uuid.value | |
136 | ||
137 | # Verify the secret was created | |
138 | result = self.client.get(uuid, credential) | |
139 | ||
140 | self._check_result_status(result.result_status.enum, ResultStatus, | |
141 | ResultStatus.SUCCESS) | |
142 | self._check_object_type(result.object_type.enum, ObjectType, | |
143 | ObjectType.SYMMETRIC_KEY) | |
144 | self._check_uuid(result.uuid.value, str) | |
145 | ||
146 | secret = result.secret | |
147 | ||
148 | expected = SymmetricKey | |
149 | message = utils.build_er_error(result.__class__, 'type', expected, | |
150 | secret, 'secret') | |
151 | self.assertIsInstance(secret, expected, message) | |
152 | ||
153 | # Destroy the SYMMETRIC_KEY object | |
154 | result = self.client.destroy(uuid, credential) | |
155 | self._check_result_status(result.result_status.enum, ResultStatus, | |
156 | ResultStatus.SUCCESS) | |
157 | self._check_uuid(result.uuid.value, str) | |
158 | ||
159 | # Verify the secret was destroyed | |
160 | result = self.client.get(uuid, credential) | |
161 | ||
162 | self._check_result_status(result.result_status.enum, ResultStatus, | |
163 | ResultStatus.OPERATION_FAILED) | |
164 | ||
165 | expected = ResultReason | |
166 | observed = type(result.result_reason.enum) | |
167 | message = utils.build_er_error(result.result_reason.__class__, 'type', | |
168 | expected, observed) | |
169 | self.assertEqual(expected, observed, message) | |
170 | ||
171 | expected = ResultReason.ITEM_NOT_FOUND | |
172 | observed = result.result_reason.enum | |
173 | message = utils.build_er_error(result.result_reason.__class__, | |
174 | 'value', expected, observed) | |
175 | self.assertEqual(expected, observed, message) | |
176 | ||
177 | def test_register(self): | |
178 | credential_type = CredentialType.USERNAME_AND_PASSWORD | |
179 | credential_value = {'Username': 'Peter', 'Password': 'abc123'} | |
180 | credential = self.cred_factory.create_credential(credential_type, | |
181 | credential_value) | |
182 | ||
183 | object_type = ObjectType.SYMMETRIC_KEY | |
184 | algorithm_value = CryptographicAlgorithm.AES | |
185 | mask_flags = [CryptographicUsageMask.ENCRYPT, | |
186 | CryptographicUsageMask.DECRYPT] | |
187 | attribute_type = AttributeType.CRYPTOGRAPHIC_USAGE_MASK | |
188 | usage_mask = self.attr_factory.create_attribute(attribute_type, | |
189 | mask_flags) | |
190 | attributes = [usage_mask] | |
191 | template_attribute = TemplateAttribute(attributes=attributes) | |
192 | ||
193 | secret_features = {} | |
194 | ||
195 | key_format_type = KeyFormatType.RAW | |
196 | secret_features.update([('key_format_type', key_format_type)]) | |
197 | ||
198 | key_data = {'bytes': bytearray('\x00\x00\x00\x00\x00\x00\x00\x00' | |
199 | '\x00\x00\x00\x00\x00\x00\x00\x00')} | |
200 | ||
201 | secret_features.update([('key_value', key_data)]) | |
202 | secret_features.update([('cryptographic_algorithm', algorithm_value)]) | |
203 | secret_features.update([('cryptographic_length', 128)]) | |
204 | ||
205 | secret = self.secret_factory.create_secret(object_type, | |
206 | secret_features) | |
207 | ||
208 | result = self.client.register(object_type, template_attribute, secret, | |
209 | credential) | |
210 | ||
211 | self._check_result_status(result.result_status.enum, ResultStatus, | |
212 | ResultStatus.SUCCESS) | |
213 | self._check_uuid(result.uuid.value, str) | |
214 | ||
215 | # Check the template attribute type | |
216 | self._check_template_attribute(result.template_attribute, | |
217 | TemplateAttribute, 1, | |
218 | [[str, 'Unique Identifier', str, | |
219 | None]]) | |
220 | # Check that the returned key bytes match what was provided | |
221 | uuid = result.uuid.value | |
222 | result = self.client.get(uuid, credential) | |
223 | ||
224 | self._check_result_status(result.result_status.enum, ResultStatus, | |
225 | ResultStatus.SUCCESS) | |
226 | self._check_object_type(result.object_type.enum, ObjectType, | |
227 | ObjectType.SYMMETRIC_KEY) | |
228 | self._check_uuid(result.uuid.value, str) | |
229 | ||
230 | # Check the secret type | |
231 | secret = result.secret | |
232 | ||
233 | expected = SymmetricKey | |
234 | message = utils.build_er_error(result.__class__, 'type', expected, | |
235 | secret, 'secret') | |
236 | self.assertIsInstance(secret, expected, message) | |
237 | ||
238 | key_block = result.secret.key_block | |
239 | key_value = key_block.key_value | |
240 | key_material = key_value.key_value.key_material | |
241 | ||
242 | expected = key_data.get('bytes') | |
243 | observed = key_material.value | |
244 | message = utils.build_er_error(key_material.__class__, 'value', | |
245 | expected, observed, 'value') | |
246 | self.assertEqual(expected, observed, message) | |
247 | ||
248 | def _shutdown_server(self): | |
249 | if self.server.poll() is not None: | |
250 | return | |
251 | else: | |
252 | # Terminate the server process. If it resists, kill it. | |
253 | pid = self.server.pid | |
254 | self.server.terminate() | |
255 | time.sleep(self.SHUTDOWN_TIME) | |
256 | ||
257 | if self.server.poll() is None: | |
258 | raise KMIPServerZombieError(pid) | |
259 | ||
260 | def _create_symmetric_key(self): | |
261 | credential_type = CredentialType.USERNAME_AND_PASSWORD | |
262 | credential_value = {'Username': 'Peter', 'Password': 'abc123'} | |
263 | credential = self.cred_factory.create_credential(credential_type, | |
264 | credential_value) | |
265 | ||
266 | object_type = ObjectType.SYMMETRIC_KEY | |
267 | attribute_type = AttributeType.CRYPTOGRAPHIC_ALGORITHM | |
268 | algorithm = self.attr_factory.create_attribute( | |
269 | attribute_type, | |
270 | CryptographicAlgorithm.AES) | |
271 | ||
272 | mask_flags = [CryptographicUsageMask.ENCRYPT, | |
273 | CryptographicUsageMask.DECRYPT] | |
274 | attribute_type = AttributeType.CRYPTOGRAPHIC_USAGE_MASK | |
275 | usage_mask = self.attr_factory.create_attribute(attribute_type, | |
276 | mask_flags) | |
277 | attributes = [algorithm, usage_mask] | |
278 | template_attribute = TemplateAttribute(attributes=attributes) | |
279 | ||
280 | return self.client.create(object_type, template_attribute, | |
281 | credential) | |
282 | ||
283 | def _check_result_status(self, result_status, result_status_type, | |
284 | result_status_value): | |
285 | # Error check the result status type and value | |
286 | expected = result_status_type | |
287 | message = utils.build_er_error(result_status_type, 'type', expected, | |
288 | result_status) | |
289 | self.assertIsInstance(result_status, expected, message) | |
290 | ||
291 | expected = result_status_value | |
292 | message = utils.build_er_error(result_status_type, 'value', expected, | |
293 | result_status) | |
294 | self.assertEqual(expected, result_status, message) | |
295 | ||
296 | def _check_uuid(self, uuid, uuid_type): | |
297 | # Error check the UUID type and value | |
298 | not_expected = None | |
299 | message = utils.build_er_error(uuid_type, 'type', | |
300 | 'not {0}'.format(not_expected), uuid) | |
301 | self.assertNotEqual(not_expected, uuid, message) | |
302 | ||
303 | expected = uuid_type | |
304 | message = utils.build_er_error(uuid_type, 'type', expected, uuid) | |
305 | self.assertEqual(expected, type(uuid), message) | |
306 | ||
307 | def _check_object_type(self, object_type, object_type_type, | |
308 | object_type_value): | |
309 | # Error check the object type type and value | |
310 | expected = object_type_type | |
311 | message = utils.build_er_error(object_type_type, 'type', expected, | |
312 | object_type) | |
313 | self.assertIsInstance(object_type, expected, message) | |
314 | ||
315 | expected = object_type_value | |
316 | message = utils.build_er_error(object_type_type, 'value', expected, | |
317 | object_type) | |
318 | self.assertEqual(expected, object_type, message) | |
319 | ||
320 | def _check_template_attribute(self, template_attribute, | |
321 | template_attribute_type, num_attributes, | |
322 | attribute_features): | |
323 | # Error check the template attribute type | |
324 | expected = template_attribute_type | |
325 | message = utils.build_er_error(template_attribute.__class__, 'type', | |
326 | expected, template_attribute) | |
327 | self.assertIsInstance(template_attribute, expected, message) | |
328 | ||
329 | attributes = template_attribute.attributes | |
330 | ||
331 | expected = num_attributes | |
332 | observed = len(attributes) | |
333 | message = utils.build_er_error(TemplateAttribute.__class__, 'number', | |
334 | expected, observed, 'attributes') | |
335 | ||
336 | for i in xrange(num_attributes): | |
337 | features = attribute_features[i] | |
338 | self._check_attribute(attributes[i], features[0], features[1], | |
339 | features[2], features[3]) | |
340 | ||
341 | def _check_attribute(self, attribute, attribute_name_type, | |
342 | attribute_name_value, attribute_value_type, | |
343 | attribute_value_value): | |
344 | # Error check the attribute name and value type and value | |
345 | attribute_name = attribute.attribute_name | |
346 | attribute_value = attribute.attribute_value | |
347 | ||
348 | self._check_attribute_name(attribute_name, attribute_name_type, | |
349 | attribute_name_value) | |
350 | ||
351 | if attribute_name_value == 'Unique Identifier': | |
352 | self._check_uuid(attribute_value.value, attribute_value_type) | |
353 | else: | |
354 | self._check_attribute_value(attribute_value, attribute_value_type, | |
355 | attribute_value_value) | |
356 | ||
357 | def _check_attribute_name(self, attribute_name, attribute_name_type, | |
358 | attribute_name_value): | |
359 | # Error check the attribute name type and value | |
360 | expected = attribute_name_type | |
361 | observed = type(attribute_name.value) | |
362 | message = utils.build_er_error(attribute_name_type, 'type', expected, | |
363 | observed) | |
364 | self.assertEqual(expected, observed, message) | |
365 | ||
366 | expected = attribute_name_value | |
367 | observed = attribute_name.value | |
368 | message = utils.build_er_error(attribute_name_type, 'value', expected, | |
369 | observed) | |
370 | self.assertEqual(expected, observed, message) | |
371 | ||
372 | def _check_attribute_value(self, attribute_value, attribute_value_type, | |
373 | attribute_value_value): | |
374 | expected = attribute_value_type | |
375 | observed = type(attribute_value.value) | |
376 | message = utils.build_er_error(Attribute, 'type', expected, observed, | |
377 | 'attribute_value') | |
378 | self.assertEqual(expected, observed, message) | |
379 | ||
380 | expected = attribute_value_value | |
381 | observed = attribute_value.value | |
382 | message = utils.build_er_error(Attribute, 'value', expected, observed, | |
383 | 'attribute_value') | |
384 | self.assertEqual(expected, observed, message) |
0 | #!/usr/bin/env python | |
1 | # | |
2 | # Autogenerated by Thrift Compiler (0.9.1) | |
3 | # | |
4 | # DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING | |
5 | # | |
6 | # options string: py | |
7 | # | |
8 | ||
9 | import sys | |
10 | import pprint | |
11 | from urlparse import urlparse | |
12 | from thrift.transport import TTransport | |
13 | from thrift.transport import TSocket | |
14 | from thrift.transport import THttpClient | |
15 | from thrift.protocol import TBinaryProtocol | |
16 | ||
17 | from kmip import KMIP | |
18 | from kmip.ttypes import * | |
19 | ||
20 | if len(sys.argv) <= 1 or sys.argv[1] == '--help': | |
21 | print '' | |
22 | print 'Usage: ' + sys.argv[0] + ' [-h host[:port]] [-u url] [-f[ramed]] function [arg1 [arg2...]]' | |
23 | print '' | |
24 | print 'Functions:' | |
25 | print ' void create()' | |
26 | print ' void register_mo()' | |
27 | print '' | |
28 | sys.exit(0) | |
29 | ||
30 | pp = pprint.PrettyPrinter(indent = 2) | |
31 | host = 'localhost' | |
32 | port = 9090 | |
33 | uri = '' | |
34 | framed = False | |
35 | http = False | |
36 | argi = 1 | |
37 | ||
38 | if sys.argv[argi] == '-h': | |
39 | parts = sys.argv[argi+1].split(':') | |
40 | host = parts[0] | |
41 | if len(parts) > 1: | |
42 | port = int(parts[1]) | |
43 | argi += 2 | |
44 | ||
45 | if sys.argv[argi] == '-u': | |
46 | url = urlparse(sys.argv[argi+1]) | |
47 | parts = url[1].split(':') | |
48 | host = parts[0] | |
49 | if len(parts) > 1: | |
50 | port = int(parts[1]) | |
51 | else: | |
52 | port = 80 | |
53 | uri = url[2] | |
54 | if url[4]: | |
55 | uri += '?%s' % url[4] | |
56 | http = True | |
57 | argi += 2 | |
58 | ||
59 | if sys.argv[argi] == '-f' or sys.argv[argi] == '-framed': | |
60 | framed = True | |
61 | argi += 1 | |
62 | ||
63 | cmd = sys.argv[argi] | |
64 | args = sys.argv[argi+1:] | |
65 | ||
66 | if http: | |
67 | transport = THttpClient.THttpClient(host, port, uri) | |
68 | else: | |
69 | socket = TSocket.TSocket(host, port) | |
70 | if framed: | |
71 | transport = TTransport.TFramedTransport(socket) | |
72 | else: | |
73 | transport = TTransport.TBufferedTransport(socket) | |
74 | protocol = TBinaryProtocol.TBinaryProtocol(transport) | |
75 | client = KMIP.Client(protocol) | |
76 | transport.open() | |
77 | ||
78 | if cmd == 'create': | |
79 | if len(args) != 0: | |
80 | print 'create requires 0 args' | |
81 | sys.exit(1) | |
82 | pp.pprint(client.create()) | |
83 | ||
84 | elif cmd == 'register_mo': | |
85 | if len(args) != 0: | |
86 | print 'register_mo requires 0 args' | |
87 | sys.exit(1) | |
88 | pp.pprint(client.register_mo()) | |
89 | ||
90 | else: | |
91 | print 'Unrecognized method %s' % cmd | |
92 | sys.exit(1) | |
93 | ||
94 | transport.close() |
0 | # | |
1 | # Autogenerated by Thrift Compiler (0.9.1) | |
2 | # | |
3 | # DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING | |
4 | # | |
5 | # options string: py | |
6 | # | |
7 | ||
8 | from thrift.Thrift import TType, TMessageType, TException, TApplicationException | |
9 | from ttypes import * | |
10 | from thrift.Thrift import TProcessor | |
11 | from thrift.transport import TTransport | |
12 | from thrift.protocol import TBinaryProtocol, TProtocol | |
13 | try: | |
14 | from thrift.protocol import fastbinary | |
15 | except: | |
16 | fastbinary = None | |
17 | ||
18 | ||
19 | class Iface: | |
20 | def create(self): | |
21 | pass | |
22 | ||
23 | def register_mo(self): | |
24 | pass | |
25 | ||
26 | ||
27 | class Client(Iface): | |
28 | def __init__(self, iprot, oprot=None): | |
29 | self._iprot = self._oprot = iprot | |
30 | if oprot is not None: | |
31 | self._oprot = oprot | |
32 | self._seqid = 0 | |
33 | ||
34 | def create(self): | |
35 | self.send_create() | |
36 | self.recv_create() | |
37 | ||
38 | def send_create(self): | |
39 | self._oprot.writeMessageBegin('create', TMessageType.CALL, self._seqid) | |
40 | args = create_args() | |
41 | args.write(self._oprot) | |
42 | self._oprot.writeMessageEnd() | |
43 | self._oprot.trans.flush() | |
44 | ||
45 | def recv_create(self): | |
46 | (fname, mtype, rseqid) = self._iprot.readMessageBegin() | |
47 | if mtype == TMessageType.EXCEPTION: | |
48 | x = TApplicationException() | |
49 | x.read(self._iprot) | |
50 | self._iprot.readMessageEnd() | |
51 | raise x | |
52 | result = create_result() | |
53 | result.read(self._iprot) | |
54 | self._iprot.readMessageEnd() | |
55 | return | |
56 | ||
57 | def register_mo(self): | |
58 | self.send_register_mo() | |
59 | self.recv_register_mo() | |
60 | ||
61 | def send_register_mo(self): | |
62 | self._oprot.writeMessageBegin('register_mo', TMessageType.CALL, self._seqid) | |
63 | args = register_mo_args() | |
64 | args.write(self._oprot) | |
65 | self._oprot.writeMessageEnd() | |
66 | self._oprot.trans.flush() | |
67 | ||
68 | def recv_register_mo(self): | |
69 | (fname, mtype, rseqid) = self._iprot.readMessageBegin() | |
70 | if mtype == TMessageType.EXCEPTION: | |
71 | x = TApplicationException() | |
72 | x.read(self._iprot) | |
73 | self._iprot.readMessageEnd() | |
74 | raise x | |
75 | result = register_mo_result() | |
76 | result.read(self._iprot) | |
77 | self._iprot.readMessageEnd() | |
78 | return | |
79 | ||
80 | ||
81 | class Processor(Iface, TProcessor): | |
82 | def __init__(self, handler): | |
83 | self._handler = handler | |
84 | self._processMap = {} | |
85 | self._processMap["create"] = Processor.process_create | |
86 | self._processMap["register_mo"] = Processor.process_register_mo | |
87 | ||
88 | def process(self, iprot, oprot): | |
89 | (name, type, seqid) = iprot.readMessageBegin() | |
90 | if name not in self._processMap: | |
91 | iprot.skip(TType.STRUCT) | |
92 | iprot.readMessageEnd() | |
93 | x = TApplicationException(TApplicationException.UNKNOWN_METHOD, 'Unknown function %s' % (name)) | |
94 | oprot.writeMessageBegin(name, TMessageType.EXCEPTION, seqid) | |
95 | x.write(oprot) | |
96 | oprot.writeMessageEnd() | |
97 | oprot.trans.flush() | |
98 | return | |
99 | else: | |
100 | self._processMap[name](self, seqid, iprot, oprot) | |
101 | return True | |
102 | ||
103 | def process_create(self, seqid, iprot, oprot): | |
104 | args = create_args() | |
105 | args.read(iprot) | |
106 | iprot.readMessageEnd() | |
107 | result = create_result() | |
108 | self._handler.create() | |
109 | oprot.writeMessageBegin("create", TMessageType.REPLY, seqid) | |
110 | result.write(oprot) | |
111 | oprot.writeMessageEnd() | |
112 | oprot.trans.flush() | |
113 | ||
114 | def process_register_mo(self, seqid, iprot, oprot): | |
115 | args = register_mo_args() | |
116 | args.read(iprot) | |
117 | iprot.readMessageEnd() | |
118 | result = register_mo_result() | |
119 | self._handler.register_mo() | |
120 | oprot.writeMessageBegin("register_mo", TMessageType.REPLY, seqid) | |
121 | result.write(oprot) | |
122 | oprot.writeMessageEnd() | |
123 | oprot.trans.flush() | |
124 | ||
125 | ||
126 | # HELPER FUNCTIONS AND STRUCTURES | |
127 | ||
128 | class create_args: | |
129 | ||
130 | thrift_spec = ( | |
131 | ) | |
132 | ||
133 | def read(self, iprot): | |
134 | if iprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None and fastbinary is not None: | |
135 | fastbinary.decode_binary(self, iprot.trans, (self.__class__, self.thrift_spec)) | |
136 | return | |
137 | iprot.readStructBegin() | |
138 | while True: | |
139 | (fname, ftype, fid) = iprot.readFieldBegin() | |
140 | if ftype == TType.STOP: | |
141 | break | |
142 | else: | |
143 | iprot.skip(ftype) | |
144 | iprot.readFieldEnd() | |
145 | iprot.readStructEnd() | |
146 | ||
147 | def write(self, oprot): | |
148 | if oprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and self.thrift_spec is not None and fastbinary is not None: | |
149 | oprot.trans.write(fastbinary.encode_binary(self, (self.__class__, self.thrift_spec))) | |
150 | return | |
151 | oprot.writeStructBegin('create_args') | |
152 | oprot.writeFieldStop() | |
153 | oprot.writeStructEnd() | |
154 | ||
155 | def validate(self): | |
156 | return | |
157 | ||
158 | ||
159 | def __repr__(self): | |
160 | L = ['%s=%r' % (key, value) | |
161 | for key, value in self.__dict__.iteritems()] | |
162 | return '%s(%s)' % (self.__class__.__name__, ', '.join(L)) | |
163 | ||
164 | def __eq__(self, other): | |
165 | return isinstance(other, self.__class__) and self.__dict__ == other.__dict__ | |
166 | ||
167 | def __ne__(self, other): | |
168 | return not (self == other) | |
169 | ||
170 | class create_result: | |
171 | ||
172 | thrift_spec = ( | |
173 | ) | |
174 | ||
175 | def read(self, iprot): | |
176 | if iprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None and fastbinary is not None: | |
177 | fastbinary.decode_binary(self, iprot.trans, (self.__class__, self.thrift_spec)) | |
178 | return | |
179 | iprot.readStructBegin() | |
180 | while True: | |
181 | (fname, ftype, fid) = iprot.readFieldBegin() | |
182 | if ftype == TType.STOP: | |
183 | break | |
184 | else: | |
185 | iprot.skip(ftype) | |
186 | iprot.readFieldEnd() | |
187 | iprot.readStructEnd() | |
188 | ||
189 | def write(self, oprot): | |
190 | if oprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and self.thrift_spec is not None and fastbinary is not None: | |
191 | oprot.trans.write(fastbinary.encode_binary(self, (self.__class__, self.thrift_spec))) | |
192 | return | |
193 | oprot.writeStructBegin('create_result') | |
194 | oprot.writeFieldStop() | |
195 | oprot.writeStructEnd() | |
196 | ||
197 | def validate(self): | |
198 | return | |
199 | ||
200 | ||
201 | def __repr__(self): | |
202 | L = ['%s=%r' % (key, value) | |
203 | for key, value in self.__dict__.iteritems()] | |
204 | return '%s(%s)' % (self.__class__.__name__, ', '.join(L)) | |
205 | ||
206 | def __eq__(self, other): | |
207 | return isinstance(other, self.__class__) and self.__dict__ == other.__dict__ | |
208 | ||
209 | def __ne__(self, other): | |
210 | return not (self == other) | |
211 | ||
212 | class register_mo_args: | |
213 | ||
214 | thrift_spec = ( | |
215 | ) | |
216 | ||
217 | def read(self, iprot): | |
218 | if iprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None and fastbinary is not None: | |
219 | fastbinary.decode_binary(self, iprot.trans, (self.__class__, self.thrift_spec)) | |
220 | return | |
221 | iprot.readStructBegin() | |
222 | while True: | |
223 | (fname, ftype, fid) = iprot.readFieldBegin() | |
224 | if ftype == TType.STOP: | |
225 | break | |
226 | else: | |
227 | iprot.skip(ftype) | |
228 | iprot.readFieldEnd() | |
229 | iprot.readStructEnd() | |
230 | ||
231 | def write(self, oprot): | |
232 | if oprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and self.thrift_spec is not None and fastbinary is not None: | |
233 | oprot.trans.write(fastbinary.encode_binary(self, (self.__class__, self.thrift_spec))) | |
234 | return | |
235 | oprot.writeStructBegin('register_mo_args') | |
236 | oprot.writeFieldStop() | |
237 | oprot.writeStructEnd() | |
238 | ||
239 | def validate(self): | |
240 | return | |
241 | ||
242 | ||
243 | def __repr__(self): | |
244 | L = ['%s=%r' % (key, value) | |
245 | for key, value in self.__dict__.iteritems()] | |
246 | return '%s(%s)' % (self.__class__.__name__, ', '.join(L)) | |
247 | ||
248 | def __eq__(self, other): | |
249 | return isinstance(other, self.__class__) and self.__dict__ == other.__dict__ | |
250 | ||
251 | def __ne__(self, other): | |
252 | return not (self == other) | |
253 | ||
254 | class register_mo_result: | |
255 | ||
256 | thrift_spec = ( | |
257 | ) | |
258 | ||
259 | def read(self, iprot): | |
260 | if iprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and isinstance(iprot.trans, TTransport.CReadableTransport) and self.thrift_spec is not None and fastbinary is not None: | |
261 | fastbinary.decode_binary(self, iprot.trans, (self.__class__, self.thrift_spec)) | |
262 | return | |
263 | iprot.readStructBegin() | |
264 | while True: | |
265 | (fname, ftype, fid) = iprot.readFieldBegin() | |
266 | if ftype == TType.STOP: | |
267 | break | |
268 | else: | |
269 | iprot.skip(ftype) | |
270 | iprot.readFieldEnd() | |
271 | iprot.readStructEnd() | |
272 | ||
273 | def write(self, oprot): | |
274 | if oprot.__class__ == TBinaryProtocol.TBinaryProtocolAccelerated and self.thrift_spec is not None and fastbinary is not None: | |
275 | oprot.trans.write(fastbinary.encode_binary(self, (self.__class__, self.thrift_spec))) | |
276 | return | |
277 | oprot.writeStructBegin('register_mo_result') | |
278 | oprot.writeFieldStop() | |
279 | oprot.writeStructEnd() | |
280 | ||
281 | def validate(self): | |
282 | return | |
283 | ||
284 | ||
285 | def __repr__(self): | |
286 | L = ['%s=%r' % (key, value) | |
287 | for key, value in self.__dict__.iteritems()] | |
288 | return '%s(%s)' % (self.__class__.__name__, ', '.join(L)) | |
289 | ||
290 | def __eq__(self, other): | |
291 | return isinstance(other, self.__class__) and self.__dict__ == other.__dict__ | |
292 | ||
293 | def __ne__(self, other): | |
294 | return not (self == other) |
0 | # | |
1 | # Autogenerated by Thrift Compiler (0.9.1) | |
2 | # | |
3 | # DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING | |
4 | # | |
5 | # options string: py | |
6 | # | |
7 | ||
8 | from thrift.Thrift import TType, TMessageType, TException, TApplicationException | |
9 | from ttypes import * | |
10 |
0 | # | |
1 | # Autogenerated by Thrift Compiler (0.9.1) | |
2 | # | |
3 | # DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING | |
4 | # | |
5 | # options string: py | |
6 | # | |
7 | ||
8 | from thrift.Thrift import TType, TMessageType, TException, TApplicationException | |
9 | ||
10 | from thrift.transport import TTransport | |
11 | from thrift.protocol import TBinaryProtocol, TProtocol | |
12 | try: | |
13 | from thrift.protocol import fastbinary | |
14 | except: | |
15 | fastbinary = None | |
16 | ||
17 |
0 | #!/usr/bin/env python | |
1 | # | |
2 | # Licensed under the Apache License, Version 2.0 (the "License"); | |
3 | # you may not use this file except in compliance with the License. | |
4 | # You may obtain a copy of the License at | |
5 | # | |
6 | # http://www.apache.org/licenses/LICENSE-2.0 | |
7 | # | |
8 | # Unless required by applicable law or agreed to in writing, software | |
9 | # distributed under the License is distributed on an "AS IS" BASIS, | |
10 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or | |
11 | # implied. | |
12 | # See the License for the specific language governing permissions and | |
13 | # limitations under the License. | |
14 | ||
15 | import setuptools | |
16 | ||
17 | setuptools.setup( | |
18 | name='PyKMIP', | |
19 | version='0.0.1', | |
20 | description='KMIP v1.1 library', | |
21 | keywords='KMIP', | |
22 | author='Peter Hamilton', | |
23 | author_email='peter.hamilton@jhuapl.edu', | |
24 | url='http://www.jhuapl.edu', | |
25 | license='Apache License, Version 2.0', | |
26 | packages=setuptools.find_packages(exclude=["kmip.tests", "kmip.tests.*"]), | |
27 | classifiers=[ | |
28 | "Intended Audience :: Developers", | |
29 | "License :: OSI Approved :: Apache Software License", | |
30 | "Natural Language :: English", | |
31 | "Operating System :: MacOS :: MacOS X", | |
32 | "Operating System :: POSIX", | |
33 | "Operating System :: POSIX :: BSD", | |
34 | "Operating System :: POSIX :: Linux", | |
35 | "Operating System :: Microsoft :: Windows", | |
36 | "Programming Language :: Python", | |
37 | "Programming Language :: Python :: 2", | |
38 | "Programming Language :: Python :: 2.6", | |
39 | "Programming Language :: Python :: 2.7", | |
40 | ], | |
41 | ) |
0 | 0 | # TODO: add any test requirements here |
1 | coverage | |
2 | pytest | |
3 | flake8 | |
4 | testtools | |
5 | fixtures | |
6 | testresources | |
7 | mock | |
8 | testscenarios | |
9 | testrepository | |
10 | sphinx |
0 | /** | |
1 | * This is the thrift definition file. It defines all of the methods and objects | |
2 | * for the KMIP server. This file is used by thrift to generate the plumbing for | |
3 | * a KMIP client and server. | |
4 | * | |
5 | * This file generated the files under kmip/thrift. | |
6 | * | |
7 | * If this file is updated then run the following command to update the | |
8 | * kmip/thrift directory. | |
9 | * | |
10 | * thrift -o kmip -r --gen py thrift/tutorial.thrift | |
11 | */ | |
12 | ||
13 | /** | |
14 | * The first thing to know about are types. The available types in Thrift are: | |
15 | * | |
16 | * bool Boolean, one byte | |
17 | * byte Signed byte | |
18 | * i16 Signed 16-bit integer | |
19 | * i32 Signed 32-bit integer | |
20 | * i64 Signed 64-bit integer | |
21 | * double 64-bit floating point value | |
22 | * string String | |
23 | * binary Blob (byte array) | |
24 | * map<t1,t2> Map from one type to another | |
25 | * list<t1> Ordered list of one type | |
26 | * set<t1> Set of unique elements of one type | |
27 | * | |
28 | */ | |
29 | ||
30 | namespace cpp thrift | |
31 | namespace d thrift | |
32 | namespace java thrift | |
33 | namespace php thrift | |
34 | namespace perl thrift | |
35 | ||
36 | service KMIP { | |
37 | ||
38 | void create(), | |
39 | /* Did not use register because it is a reserved word */ | |
40 | void register_mo() | |
41 | ||
42 | }⏎ |
0 | [tox] | |
1 | envlist = pep8,py27,py26 | |
2 | ||
3 | [testenv] | |
4 | deps = -r{toxinidir}/requirements.txt | |
5 | -r{toxinidir}/test-requirements.txt | |
6 | ||
7 | commands = | |
8 | coverage run --source=kmip/ -m pytest --strict {posargs} | |
9 | coverage report | |
10 | ||
11 | [testenv:pep8] | |
12 | commands = flake8 {posargs} | |
13 | ||
14 | [flake8] | |
15 | exclude = .git,.tox,dist,rpmbuild,*.egg-info |