├── .github └── workflows │ ├── codeql-analysis.yml │ └── tox.yml ├── .gitignore ├── .travis.yml ├── .travis ├── functional │ ├── pykmip │ │ ├── certs │ │ │ └── dummy.txt │ │ ├── client.conf │ │ ├── policies │ │ │ └── policy.json │ │ └── server.conf │ └── slugs │ │ ├── slugs.conf │ │ └── user_group_mapping.csv ├── policy.json ├── pykmip.conf ├── run.sh └── server.conf ├── CHANGELOG.rst ├── LICENSE.txt ├── MANIFEST.in ├── README.rst ├── bin ├── create_certificates.py ├── run_server.py └── run_tests.sh ├── doc-requirements.txt ├── docs ├── Makefile ├── make.bat └── source │ ├── _static │ └── .keep │ ├── changelog.rst │ ├── client.rst │ ├── community.rst │ ├── conf.py │ ├── development.rst │ ├── faq.rst │ ├── glossary.rst │ ├── index.rst │ ├── installation.rst │ ├── security.rst │ └── server.rst ├── examples ├── legacy_policy.json ├── policy.json ├── pykmip.conf └── server.conf ├── kmip ├── __init__.py ├── core │ ├── __init__.py │ ├── attributes.py │ ├── config_helper.py │ ├── enums.py │ ├── exceptions.py │ ├── factories │ │ ├── __init__.py │ │ ├── attribute_values.py │ │ ├── attributes.py │ │ ├── credentials.py │ │ ├── payloads │ │ │ ├── __init__.py │ │ │ ├── request.py │ │ │ └── response.py │ │ └── secrets.py │ ├── messages │ │ ├── .gitignore │ │ ├── __init__.py │ │ ├── contents.py │ │ ├── messages.py │ │ └── payloads │ │ │ ├── __init__.py │ │ │ ├── activate.py │ │ │ ├── archive.py │ │ │ ├── base.py │ │ │ ├── cancel.py │ │ │ ├── check.py │ │ │ ├── create.py │ │ │ ├── create_key_pair.py │ │ │ ├── decrypt.py │ │ │ ├── delete_attribute.py │ │ │ ├── derive_key.py │ │ │ ├── destroy.py │ │ │ ├── discover_versions.py │ │ │ ├── encrypt.py │ │ │ ├── get.py │ │ │ ├── get_attribute_list.py │ │ │ ├── get_attributes.py │ │ │ ├── get_usage_allocation.py │ │ │ ├── locate.py │ │ │ ├── mac.py │ │ │ ├── modify_attribute.py │ │ │ ├── obtain_lease.py │ │ │ ├── poll.py │ │ │ ├── query.py │ │ │ ├── recover.py │ │ │ ├── register.py │ │ │ ├── rekey.py │ │ │ ├── rekey_key_pair.py │ │ │ ├── revoke.py │ │ │ ├── set_attribute.py │ │ │ ├── sign.py │ │ │ └── signature_verify.py │ ├── misc.py │ ├── objects.py │ ├── policy.py │ ├── primitives.py │ ├── secrets.py │ └── utils.py ├── demos │ ├── __init__.py │ ├── certs │ │ ├── server.crt │ │ └── server.key │ ├── pie │ │ ├── __init__.py │ │ ├── create.py │ │ ├── create_key_pair.py │ │ ├── decrypt.py │ │ ├── delete_attribute.py │ │ ├── derive_key.py │ │ ├── destroy.py │ │ ├── encrypt.py │ │ ├── get.py │ │ ├── get_attribute_list.py │ │ ├── get_attributes.py │ │ ├── locate.py │ │ ├── mac.py │ │ ├── modify_attribute.py │ │ ├── register_certificate.py │ │ ├── register_opaque_object.py │ │ ├── register_private_key.py │ │ ├── register_public_key.py │ │ ├── register_secret_data.py │ │ ├── register_split_key.py │ │ ├── register_symmetric_key.py │ │ ├── revoke.py │ │ ├── set_attribute.py │ │ ├── sign.py │ │ └── signature_verify.py │ ├── units │ │ ├── __init__.py │ │ ├── activate.py │ │ ├── create.py │ │ ├── create_key_pair.py │ │ ├── destroy.py │ │ ├── discover_versions.py │ │ ├── get.py │ │ ├── locate.py │ │ ├── query.py │ │ ├── register.py │ │ └── revoke.py │ └── utils.py ├── pie │ ├── __init__.py │ ├── client.py │ ├── exceptions.py │ ├── factory.py │ ├── objects.py │ └── sqltypes.py ├── services │ ├── __init__.py │ ├── auth.py │ ├── kmip_client.py │ ├── kmip_protocol.py │ ├── results.py │ └── server │ │ ├── __init__.py │ │ ├── auth │ │ ├── __init__.py │ │ ├── api.py │ │ ├── slugs.py │ │ └── utils.py │ │ ├── config.py │ │ ├── crypto │ │ ├── __init__.py │ │ ├── api.py │ │ └── engine.py │ │ ├── engine.py │ │ ├── monitor.py │ │ ├── policy.py │ │ ├── server.py │ │ └── session.py ├── tests │ ├── __init__.py │ ├── functional │ │ ├── __init__.py │ │ ├── conftest.py │ │ └── services │ │ │ ├── __init__.py │ │ │ └── test_authentication.py │ ├── integration │ │ ├── __init__.py │ │ ├── conftest.py │ │ └── services │ │ │ ├── __init__.py │ │ │ ├── test_integration.py │ │ │ ├── test_kmip_client.py │ │ │ └── test_proxykmipclient.py │ └── unit │ │ ├── __init__.py │ │ ├── core │ │ ├── __init__.py │ │ ├── attributes │ │ │ ├── __init__.py │ │ │ ├── test_application_specific_information.py │ │ │ ├── test_attributes.py │ │ │ └── test_digest.py │ │ ├── factories │ │ │ ├── __init__.py │ │ │ ├── payloads │ │ │ │ ├── __init__.py │ │ │ │ ├── test_payload.py │ │ │ │ ├── test_request.py │ │ │ │ └── test_response.py │ │ │ ├── test_attribute.py │ │ │ └── test_attribute_values.py │ │ ├── messages │ │ │ ├── __init__.py │ │ │ ├── contents │ │ │ │ ├── __init__.py │ │ │ │ ├── test_authentication.py │ │ │ │ └── test_protocol_version.py │ │ │ ├── payloads │ │ │ │ ├── __init__.py │ │ │ │ ├── test_activate.py │ │ │ │ ├── test_archive.py │ │ │ │ ├── test_cancel.py │ │ │ │ ├── test_check.py │ │ │ │ ├── test_create.py │ │ │ │ ├── test_create_key_pair.py │ │ │ │ ├── test_decrypt.py │ │ │ │ ├── test_delete_attribute.py │ │ │ │ ├── test_derive_key.py │ │ │ │ ├── test_destroy.py │ │ │ │ ├── test_discover_versions.py │ │ │ │ ├── test_encrypt.py │ │ │ │ ├── test_get.py │ │ │ │ ├── test_get_attribute_list.py │ │ │ │ ├── test_get_attributes.py │ │ │ │ ├── test_get_usage_allocation.py │ │ │ │ ├── test_locate.py │ │ │ │ ├── test_mac.py │ │ │ │ ├── test_modify_attribute.py │ │ │ │ ├── test_obtain_lease.py │ │ │ │ ├── test_poll.py │ │ │ │ ├── test_query.py │ │ │ │ ├── test_recover.py │ │ │ │ ├── test_register.py │ │ │ │ ├── test_rekey.py │ │ │ │ ├── test_rekey_key_pair.py │ │ │ │ ├── test_revoke.py │ │ │ │ ├── test_set_attribute.py │ │ │ │ ├── test_sign.py │ │ │ │ └── test_signature_verify.py │ │ │ ├── test_messages.py │ │ │ └── test_operations.py │ │ ├── misc │ │ │ ├── __init__.py │ │ │ ├── test_misc.py │ │ │ └── test_server_information.py │ │ ├── objects │ │ │ ├── __init__.py │ │ │ ├── test_attribute.py │ │ │ ├── test_credentials.py │ │ │ ├── test_current_attribute.py │ │ │ ├── test_extension_information.py │ │ │ ├── test_new_attribute.py │ │ │ └── test_objects.py │ │ ├── primitives │ │ │ ├── __init__.py │ │ │ ├── test_base.py │ │ │ ├── test_big_integer.py │ │ │ ├── test_boolean.py │ │ │ ├── test_byte_string.py │ │ │ ├── test_date_time.py │ │ │ ├── test_enumeration.py │ │ │ ├── test_integer.py │ │ │ ├── test_interval.py │ │ │ ├── test_long_integer.py │ │ │ └── test_text_string.py │ │ ├── secrets │ │ │ ├── __init__.py │ │ │ ├── test_certificate.py │ │ │ └── test_split_key.py │ │ ├── test_config_helper.py │ │ ├── test_enums.py │ │ ├── test_policy.py │ │ └── test_utils.py │ │ ├── pie │ │ ├── __init__.py │ │ ├── objects │ │ │ ├── __init__.py │ │ │ ├── test_application_specific_information.py │ │ │ ├── test_certificate.py │ │ │ ├── test_cryptographic_object.py │ │ │ ├── test_key.py │ │ │ ├── test_managed_object.py │ │ │ ├── test_object_group.py │ │ │ ├── test_opaque_object.py │ │ │ ├── test_private_key.py │ │ │ ├── test_public_key.py │ │ │ ├── test_secret_data.py │ │ │ ├── test_split_key.py │ │ │ ├── test_sqltypes.py │ │ │ ├── test_symmetric_key.py │ │ │ └── test_x509_certificate.py │ │ ├── test_client.py │ │ ├── test_exceptions.py │ │ └── test_factory.py │ │ ├── services │ │ ├── __init__.py │ │ ├── server │ │ │ ├── __init__.py │ │ │ ├── auth │ │ │ │ ├── __init__.py │ │ │ │ ├── test_slugs.py │ │ │ │ └── test_utils.py │ │ │ ├── crypto │ │ │ │ ├── __init__.py │ │ │ │ └── test_engine.py │ │ │ ├── test_config.py │ │ │ ├── test_engine.py │ │ │ ├── test_monitor.py │ │ │ ├── test_policy.py │ │ │ ├── test_server.py │ │ │ └── test_session.py │ │ ├── test_auth.py │ │ ├── test_kmip_client.py │ │ └── test_kmip_protocol.py │ │ └── test_kmip.py └── version.py ├── pytest.ini ├── requirements.txt ├── setup.py ├── test-requirements.txt └── tox.ini /.github/workflows/codeql-analysis.yml: -------------------------------------------------------------------------------- 1 | # For most projects, this workflow file will not need changing; you simply need 2 | # to commit it to your repository. 3 | # 4 | # You may wish to alter this file to override the set of languages analyzed, 5 | # or to provide custom queries or build logic. 6 | # 7 | # ******** NOTE ******** 8 | # We have attempted to detect the languages in your repository. Please check 9 | # the `language` matrix defined below to confirm you have the correct set of 10 | # supported CodeQL languages. 11 | # 12 | name: "CodeQL" 13 | 14 | on: 15 | push: 16 | branches: [ master ] 17 | pull_request: 18 | # The branches below must be a subset of the branches above 19 | branches: [ master ] 20 | schedule: 21 | - cron: '35 0 * * 6' 22 | 23 | jobs: 24 | analyze: 25 | name: Analyze 26 | runs-on: ubuntu-latest 27 | 28 | strategy: 29 | fail-fast: false 30 | matrix: 31 | language: [ 'python' ] 32 | # CodeQL supports [ 'cpp', 'csharp', 'go', 'java', 'javascript', 'python' ] 33 | # Learn more: 34 | # https://docs.github.com/en/free-pro-team@latest/github/finding-security-vulnerabilities-and-errors-in-your-code/configuring-code-scanning#changing-the-languages-that-are-analyzed 35 | 36 | steps: 37 | - name: Checkout repository 38 | uses: actions/checkout@v2 39 | 40 | # Initializes the CodeQL tools for scanning. 41 | - name: Initialize CodeQL 42 | uses: github/codeql-action/init@v2 43 | with: 44 | languages: ${{ matrix.language }} 45 | # If you wish to specify custom queries, you can do so here or in a config file. 46 | # By default, queries listed here will override any specified in a config file. 47 | # Prefix the list here with "+" to use these queries and those in the config file. 48 | # queries: ./path/to/local/query, your-org/your-repo/queries@main 49 | 50 | # Autobuild attempts to build any compiled languages (C/C++, C#, or Java). 51 | # If this step fails, then you should remove it and run the build manually (see below) 52 | - name: Autobuild 53 | uses: github/codeql-action/autobuild@v2 54 | 55 | # ℹ️ Command-line programs to run using the OS shell. 56 | # 📚 https://git.io/JvXDl 57 | 58 | # ✏️ If the Autobuild fails above, remove it and uncomment the following three lines 59 | # and modify them (or add more) to build your code if your project 60 | # uses a compiled language 61 | 62 | #- run: | 63 | # make bootstrap 64 | # make release 65 | 66 | - name: Perform CodeQL Analysis 67 | uses: github/codeql-action/analyze@v2 68 | -------------------------------------------------------------------------------- /.github/workflows/tox.yml: -------------------------------------------------------------------------------- 1 | name: tox 2 | 3 | on: 4 | push: 5 | branches: [ master ] 6 | pull_request: 7 | 8 | jobs: 9 | tox-test: 10 | strategy: 11 | matrix: 12 | os: [ubuntu-latest] 13 | python: 14 | - {version: '3.8', env: py38} 15 | - {version: '3.9', env: py39} 16 | - {version: '3.10', env: py310} 17 | - {version: '3.11', env: py311} 18 | test_mode: [0, 1] 19 | runs-on: ${{ matrix.os }} 20 | env: 21 | TOXENV: ${{ matrix.python.env }} 22 | RUN_INTEGRATION_TESTS: ${{ matrix.test_mode }} 23 | steps: 24 | - uses: actions/checkout@v3 25 | - uses: actions/setup-python@v4 26 | with: 27 | python-version: ${{ matrix.python.version }} 28 | - run: pip install tox 29 | - run: pip install codecov 30 | - run: pip install slugs 31 | - run: python3 setup.py install 32 | - run: ./.travis/run.sh 33 | - run: codecov 34 | tox-other: 35 | strategy: 36 | matrix: 37 | os: [ubuntu-latest] 38 | python: ['3.8', '3.9', '3.10', '3.11'] 39 | test: [pep8, bandit, docs] 40 | runs-on: ${{ matrix.os }} 41 | env: 42 | TOXENV: ${{ matrix.test }} 43 | steps: 44 | - uses: actions/checkout@v3 45 | - uses: actions/setup-python@v4 46 | with: 47 | python-version: ${{ matrix.python }} 48 | - run: pip install tox 49 | - run: pip install bandit 50 | if: ${{ matrix.test == 'bandit' }} 51 | - run: tox 52 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .cache 2 | .coverage 3 | .idea 4 | .project 5 | .pydevproject 6 | .pytest_cache 7 | .tox 8 | 9 | *.egg-info 10 | *.pyc 11 | 12 | build 13 | dist 14 | htmlcov 15 | -------------------------------------------------------------------------------- /.travis/functional/pykmip/certs/dummy.txt: -------------------------------------------------------------------------------- 1 | Dummy file to ensure ./certs gets copied with the ./pykmip directory. 2 | -------------------------------------------------------------------------------- /.travis/functional/pykmip/client.conf: -------------------------------------------------------------------------------- 1 | [john_doe] 2 | host=127.0.0.1 3 | port=5696 4 | certfile=/tmp/pykmip/certs/client_certificate_john_doe.pem 5 | keyfile=/tmp/pykmip/certs/client_key_john_doe.pem 6 | ca_certs=/tmp/pykmip/certs/root_certificate.pem 7 | cert_reqs=CERT_REQUIRED 8 | ssl_version=PROTOCOL_SSLv23 9 | do_handshake_on_connect=True 10 | suppress_ragged_eofs=True 11 | username=John Doe 12 | password=secret1 13 | 14 | [jane_doe] 15 | host=127.0.0.1 16 | port=5696 17 | certfile=/tmp/pykmip/certs/client_certificate_jane_doe.pem 18 | keyfile=/tmp/pykmip/certs/client_key_jane_doe.pem 19 | ca_certs=/tmp/pykmip/certs/root_certificate.pem 20 | cert_reqs=CERT_REQUIRED 21 | ssl_version=PROTOCOL_SSLv23 22 | do_handshake_on_connect=True 23 | suppress_ragged_eofs=True 24 | username=Jane Doe 25 | password=secret2 26 | 27 | [john_smith] 28 | host=127.0.0.1 29 | port=5696 30 | certfile=/tmp/pykmip/certs/client_certificate_john_smith.pem 31 | keyfile=/tmp/pykmip/certs/client_key_john_smith.pem 32 | ca_certs=/tmp/pykmip/certs/root_certificate.pem 33 | cert_reqs=CERT_REQUIRED 34 | ssl_version=PROTOCOL_SSLv23 35 | do_handshake_on_connect=True 36 | suppress_ragged_eofs=True 37 | username=John Smith 38 | password=secret3 39 | 40 | [jane_smith] 41 | host=127.0.0.1 42 | port=5696 43 | certfile=/tmp/pykmip/certs/client_certificate_jane_smith.pem 44 | keyfile=/tmp/pykmip/certs/client_key_jane_smith.pem 45 | ca_certs=/tmp/pykmip/certs/root_certificate.pem 46 | cert_reqs=CERT_REQUIRED 47 | ssl_version=PROTOCOL_SSLv23 48 | do_handshake_on_connect=True 49 | suppress_ragged_eofs=True 50 | username=Jane Smith 51 | password=secret4 52 | -------------------------------------------------------------------------------- /.travis/functional/pykmip/policies/policy.json: -------------------------------------------------------------------------------- 1 | { 2 | "policy_1": { 3 | "groups": { 4 | "Group A": { 5 | "SYMMETRIC_KEY": { 6 | "GET": "ALLOW_ALL", 7 | "DESTROY": "ALLOW_ALL" 8 | } 9 | }, 10 | "Group B": { 11 | "SYMMETRIC_KEY": { 12 | "GET": "ALLOW_ALL", 13 | "DESTROY": "DISALLOW_ALL" 14 | } 15 | } 16 | }, 17 | "preset": { 18 | "SYMMETRIC_KEY": { 19 | "GET": "DISALLOW_ALL", 20 | "DESTROY": "DISALLOW_ALL" 21 | } 22 | } 23 | } 24 | } -------------------------------------------------------------------------------- /.travis/functional/pykmip/server.conf: -------------------------------------------------------------------------------- 1 | [server] 2 | hostname=127.0.0.1 3 | port=5696 4 | certificate_path=/tmp/pykmip/certs/server_certificate.pem 5 | key_path=/tmp/pykmip/certs/server_key.pem 6 | ca_path=/tmp/pykmip/certs/root_certificate.pem 7 | auth_suite=Basic 8 | policy_path=/tmp/pykmip/policies 9 | enable_tls_client_auth=True 10 | tls_cipher_suites= 11 | TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256 12 | AES128-SHA256 13 | TLS_RSA_WITH_AES_256_CBC_SHA256 14 | AES256-SHA256 15 | logging_level=DEBUG 16 | 17 | [auth:slugs] 18 | enabled=True 19 | url=http://127.0.0.1:8080/slugs/ 20 | -------------------------------------------------------------------------------- /.travis/functional/slugs/slugs.conf: -------------------------------------------------------------------------------- 1 | [global] 2 | environment = 'production' 3 | server.socket_host = '127.0.0.1' 4 | server.socket_port = 8080 5 | log.access_file = '/tmp/slugs/access.log' 6 | log.error_file = '/tmp/slugs/error.log' 7 | 8 | [data] 9 | user_group_mapping = '/tmp/slugs/user_group_mapping.csv' 10 | 11 | [/slugs] 12 | tools.trailing_slash.on = True 13 | -------------------------------------------------------------------------------- /.travis/functional/slugs/user_group_mapping.csv: -------------------------------------------------------------------------------- 1 | John Doe,Group A 2 | Jane Doe,Group A 3 | Jane Doe,Group B 4 | John Smith,Group B 5 | -------------------------------------------------------------------------------- /.travis/pykmip.conf: -------------------------------------------------------------------------------- 1 | [client] 2 | host=127.0.0.1 3 | port=5696 4 | keyfile=/etc/pykmip/certs/key.pem 5 | certfile=/etc/pykmip/certs/cert.pem 6 | cert_reqs=CERT_REQUIRED 7 | ssl_version=PROTOCOL_SSLv23 8 | ca_certs=/etc/pykmip/certs/cert.pem 9 | do_handshake_on_connect=True 10 | suppress_ragged_eofs=True 11 | username= 12 | password= 13 | -------------------------------------------------------------------------------- /.travis/run.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | set -e 4 | set -x 5 | 6 | pkill -f run_server.py || true 7 | sleep 1 8 | 9 | if [[ "${RUN_INTEGRATION_TESTS}" == "1" ]]; then 10 | sudo mkdir -p /etc/pykmip/certs 11 | sudo mkdir -p /etc/pykmip/policies 12 | cd /etc/pykmip/certs 13 | sudo openssl req -x509 -subj "/CN=test" -newkey rsa:4096 -keyout key.pem -out cert.pem -days 365 -nodes 14 | cd - 15 | sudo cp ./.travis/pykmip.conf /etc/pykmip/pykmip.conf 16 | sudo cp ./.travis/server.conf /etc/pykmip/server.conf 17 | sudo cp ./.travis/policy.json /etc/pykmip/policies/policy.json 18 | sudo mkdir -p /var/log/pykmip 19 | sudo chmod 777 /var/log/pykmip 20 | sudo chmod -R 777 /etc/pykmip/ 21 | python3 ./bin/run_server.py & 22 | tox -e integration -- --config client 23 | elif [[ "${RUN_INTEGRATION_TESTS}" == "2" ]]; then 24 | # Set up the SLUGS instance 25 | cp -r ./.travis/functional/slugs /tmp/ 26 | slugs -c /tmp/slugs/slugs.conf & 27 | 28 | # Set up the PyKMIP server 29 | cp -r ./.travis/functional/pykmip /tmp/ 30 | python3 ./bin/create_certificates.py 31 | mv *.pem /tmp/pykmip/certs/ 32 | sudo mkdir -p /var/log/pykmip 33 | sudo chmod 777 /var/log/pykmip 34 | pykmip-server -f /tmp/pykmip/server.conf -l /tmp/pykmip/server.log & 35 | 36 | # Run the functional tests 37 | tox -e functional -- --config-file /tmp/pykmip/client.conf 38 | else 39 | tox 40 | fi 41 | -------------------------------------------------------------------------------- /.travis/server.conf: -------------------------------------------------------------------------------- 1 | [server] 2 | hostname=127.0.0.1 3 | port=5696 4 | certificate_path=/etc/pykmip/certs/cert.pem 5 | key_path=/etc/pykmip/certs/key.pem 6 | ca_path=/etc/pykmip/certs/cert.pem 7 | auth_suite=TLS1.2 8 | enable_tls_client_auth=False 9 | policy_path=/etc/pykmip/policies/ 10 | -------------------------------------------------------------------------------- /MANIFEST.in: -------------------------------------------------------------------------------- 1 | include AUTHORS.txt CHANGES.txt LICENSE.txt README.rst 2 | global-include logconfig.ini 3 | recursive-include bin run_server.sh 4 | recursive-include kmip *.py 5 | include kmip/demos/certs/server.* 6 | -------------------------------------------------------------------------------- /README.rst: -------------------------------------------------------------------------------- 1 | ------ 2 | PyKMIP 3 | ------ 4 | |pypi-version| 5 | |travis-status| 6 | |codecov-status| 7 | |python-versions| 8 | 9 | PyKMIP is a Python implementation of the Key Management Interoperability 10 | Protocol (KMIP), an `OASIS`_ communication standard for the management of 11 | objects stored and maintained by key management systems. KMIP defines how key 12 | management operations and operation data should be encoded and communicated 13 | between client and server applications. Supported operations include the full 14 | `CRUD`_ key management lifecycle, including operations for managing object 15 | metadata and for conducting cryptographic operations. Supported object types 16 | include: 17 | 18 | * symmetric/asymmetric encryption keys 19 | * passwords/passphrases 20 | * certificates 21 | * opaque data blobs, and more 22 | 23 | For more information on KMIP, check out the `OASIS KMIP Technical Committee`_ 24 | and the `OASIS KMIP Documentation`_. 25 | 26 | For more information on PyKMIP, check out the project `Documentation`_. 27 | 28 | Installation 29 | ------------ 30 | You can install PyKMIP via ``pip``: 31 | 32 | .. code-block:: console 33 | 34 | $ pip install pykmip 35 | 36 | See `Installation`_ for more information. 37 | 38 | Community 39 | --------- 40 | The PyKMIP community has various forums and resources you can use: 41 | 42 | * `Source code`_ 43 | * `Issue tracker`_ 44 | * IRC: ``#pykmip`` on ``irc.freenode.net`` 45 | * Twitter: ``@pykmip`` 46 | 47 | 48 | .. _`CRUD`: https://en.wikipedia.org/wiki/Create,_read,_update_and_delete 49 | .. _`OASIS`: https://www.oasis-open.org 50 | .. _`OASIS KMIP Technical Committee`: https://www.oasis-open.org/committees/tc_home.php?wg_abbrev=kmip 51 | .. _`OASIS KMIP Documentation`: https://docs.oasis-open.org/kmip/spec/ 52 | .. _`Documentation`: https://pykmip.readthedocs.io/en/latest/index.html 53 | .. _`Installation`: https://pykmip.readthedocs.io/en/latest/installation.html 54 | .. _`Source code`: https://github.com/openkmip/pykmip 55 | .. _`Issue tracker`: https://github.com/openkmip/pykmip/issues 56 | 57 | .. |pypi-version| image:: https://img.shields.io/pypi/v/pykmip.svg 58 | :target: https://pypi.python.org/pypi/pykmip 59 | :alt: Latest Version 60 | .. |travis-status| image:: https://travis-ci.org/OpenKMIP/PyKMIP.svg?branch=master 61 | :target: https://travis-ci.org/OpenKMIP/PyKMIP 62 | .. |codecov-status| image:: https://codecov.io/github/OpenKMIP/PyKMIP/coverage.svg?branch=master 63 | :target: https://codecov.io/github/OpenKMIP/PyKMIP?branch=master 64 | .. |python-versions| image:: https://img.shields.io/pypi/pyversions/PyKMIP.svg 65 | :target: https://github.com/OpenKMIP/PyKMIP 66 | -------------------------------------------------------------------------------- /bin/run_server.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | # Copyright (c) 2016 The Johns Hopkins University/Applied Physics Laboratory 4 | # All Rights Reserved. 5 | # 6 | # Licensed under the Apache License, Version 2.0 (the "License"); you may 7 | # not use this file except in compliance with the License. You may obtain 8 | # a copy of the License at 9 | # 10 | # http://www.apache.org/licenses/LICENSE-2.0 11 | # 12 | # Unless required by applicable law or agreed to in writing, software 13 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 14 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 15 | # License for the specific language governing permissions and limitations 16 | # under the License. 17 | 18 | from kmip.services.server import server 19 | 20 | 21 | if __name__ == '__main__': 22 | server.main() 23 | -------------------------------------------------------------------------------- /bin/run_tests.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | set -eu 4 | 5 | tox 6 | 7 | -------------------------------------------------------------------------------- /doc-requirements.txt: -------------------------------------------------------------------------------- 1 | sphinx>=1.6.4 2 | sphinx_rtd_theme>=0.2.4 3 | 4 | -------------------------------------------------------------------------------- /docs/Makefile: -------------------------------------------------------------------------------- 1 | # Minimal makefile for Sphinx documentation 2 | # 3 | 4 | # You can set these variables from the command line. 5 | SPHINXOPTS = 6 | SPHINXBUILD = python -msphinx 7 | SPHINXPROJ = PyKMIP 8 | SOURCEDIR = source 9 | BUILDDIR = build 10 | 11 | # Put it first so that "make" without argument is like "make help". 12 | help: 13 | @$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) 14 | 15 | .PHONY: help Makefile 16 | 17 | # Catch-all target: route all unknown targets to Sphinx using the new 18 | # "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS). 19 | %: Makefile 20 | @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) -------------------------------------------------------------------------------- /docs/make.bat: -------------------------------------------------------------------------------- 1 | @ECHO OFF 2 | 3 | pushd %~dp0 4 | 5 | REM Command file for Sphinx documentation 6 | 7 | if "%SPHINXBUILD%" == "" ( 8 | set SPHINXBUILD=python -msphinx 9 | ) 10 | set SOURCEDIR=source 11 | set BUILDDIR=build 12 | set SPHINXPROJ=PyKMIP 13 | 14 | if "%1" == "" goto help 15 | 16 | %SPHINXBUILD% >NUL 2>NUL 17 | if errorlevel 9009 ( 18 | echo. 19 | echo.The Sphinx module was not found. Make sure you have Sphinx installed, 20 | echo.then set the SPHINXBUILD environment variable to point to the full 21 | echo.path of the 'sphinx-build' executable. Alternatively you may add the 22 | echo.Sphinx directory to PATH. 23 | echo. 24 | echo.If you don't have Sphinx installed, grab it from 25 | echo.http://sphinx-doc.org/ 26 | exit /b 1 27 | ) 28 | 29 | %SPHINXBUILD% -M %1 %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% 30 | goto end 31 | 32 | :help 33 | %SPHINXBUILD% -M help %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% 34 | 35 | :end 36 | popd 37 | -------------------------------------------------------------------------------- /docs/source/_static/.keep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OpenKMIP/PyKMIP/6cd44b572b0ca55adf01a8a12078b2284602e64c/docs/source/_static/.keep -------------------------------------------------------------------------------- /docs/source/changelog.rst: -------------------------------------------------------------------------------- 1 | .. include:: ../../CHANGELOG.rst 2 | -------------------------------------------------------------------------------- /docs/source/community.rst: -------------------------------------------------------------------------------- 1 | Community 2 | ========= 3 | The PyKMIP community has various forums and resources you can use: 4 | 5 | * `Source code`_ 6 | * `Issue tracker`_ 7 | 8 | .. _`Source code`: https://github.com/openkmip/pykmip 9 | .. _`Issue tracker`: https://github.com/openkmip/pykmip/issues 10 | -------------------------------------------------------------------------------- /docs/source/faq.rst: -------------------------------------------------------------------------------- 1 | Frequently Asked Questions 2 | ========================== 3 | 4 | .. contents:: Table of Contents 5 | 6 | What algorithms are available for creating symmetric encryption keys? For asymmetric encryption keys (i.e., key pairs)? 7 | ----------------------------------------------------------------------------------------------------------------------- 8 | The KMIP specification supports a wide variety of symmetric and asymmetric 9 | key algorithms. Support for these algorithms, including corresponding key 10 | lengths, will vary across different KMIP-compliant devices, so check with 11 | your KMIP vendor or with your appliance documentation to determine which 12 | ones are available. 13 | 14 | For a full list of the cryptographic algorithms supported by the KMIP 15 | specification, see :term:`cryptographic_algorithm`. The following algorithms 16 | are supported by the PyKMIP server. 17 | 18 | Symmetric Key Algorithms 19 | ~~~~~~~~~~~~~~~~~~~~~~~~ 20 | * `3DES`_ 21 | * `AES`_ 22 | * `Blowfish`_ 23 | * `Camellia`_ 24 | * `CAST5`_ 25 | * `IDEA`_ 26 | * `RC4`_ 27 | 28 | Asymmetric Key Algorithms 29 | ~~~~~~~~~~~~~~~~~~~~~~~~~ 30 | * `RSA`_ 31 | 32 | How does the PyKMIP server handle client identity and authentication? 33 | --------------------------------------------------------------------- 34 | See :ref:`authentication`. 35 | 36 | How does the PyKMIP server manage access control for the keys and objects it stores? 37 | ------------------------------------------------------------------------------------ 38 | See :ref:`access-control`. 39 | 40 | What built-in operation policies does the PyKMIP server support? 41 | ---------------------------------------------------------------- 42 | See :ref:`reserved-policies`. 43 | 44 | 45 | .. |check| unicode:: U+2713 46 | .. _`3DES`: https://en.wikipedia.org/wiki/Triple_DES 47 | .. _`AES`: https://en.wikipedia.org/wiki/Advanced_Encryption_Standard 48 | .. _`Blowfish`: https://en.wikipedia.org/wiki/Blowfish_%28cipher%29 49 | .. _`Camellia`: https://en.wikipedia.org/wiki/Camellia_%28cipher%29 50 | .. _`CAST5`: https://en.wikipedia.org/wiki/CAST-128 51 | .. _`IDEA`: https://en.wikipedia.org/wiki/International_Data_Encryption_Algorithm 52 | .. _`RC4`: https://en.wikipedia.org/wiki/RC4 53 | .. _`RSA`: https://en.wikipedia.org/wiki/RSA_%28cryptosystem%29 54 | .. _`RFC 5280`: https://www.ietf.org/rfc/rfc5280.txt -------------------------------------------------------------------------------- /docs/source/index.rst: -------------------------------------------------------------------------------- 1 | Welcome to PyKMIP 2 | ================= 3 | PyKMIP is a Python implementation of the Key Management Interoperability 4 | Protocol (KMIP), an `OASIS`_ communication standard for the management of 5 | objects stored and maintained by key management systems. KMIP defines how key 6 | management operations and operation data should be encoded and communicated 7 | between client and server applications. Supported operations include the full 8 | `CRUD`_ key management lifecycle, including operations for managing object 9 | metadata and for conducting cryptographic operations. Supported object types 10 | include: 11 | 12 | * symmetric/asymmetric encryption keys 13 | * passwords/passphrases 14 | * certificates 15 | * opaque data blobs, and more 16 | 17 | For more information on KMIP, check out the `OASIS KMIP Technical Committee`_ 18 | and the `OASIS KMIP Documentation`_. 19 | 20 | Installation 21 | ------------ 22 | You can install PyKMIP via ``pip``: 23 | 24 | .. code-block:: console 25 | 26 | $ pip install pykmip 27 | 28 | See :doc:`Installation ` for more information. 29 | 30 | Layout 31 | ------ 32 | PyKMIP provides both client and server functionality, allowing developers 33 | to incorporate the full key management lifecycle into their projects. For 34 | more information, check out the various articles below. 35 | 36 | .. toctree:: 37 | :maxdepth: 2 38 | 39 | installation 40 | changelog 41 | faq 42 | development 43 | security 44 | client 45 | server 46 | community 47 | glossary 48 | 49 | .. _`CRUD`: https://en.wikipedia.org/wiki/Create,_read,_update_and_delete 50 | .. _`OASIS`: https://www.oasis-open.org 51 | .. _`OASIS KMIP Technical Committee`: https://www.oasis-open.org/committees/tc_home.php?wg_abbrev=kmip 52 | .. _`OASIS KMIP Documentation`: https://docs.oasis-open.org/kmip/spec/ 53 | -------------------------------------------------------------------------------- /docs/source/installation.rst: -------------------------------------------------------------------------------- 1 | Installation 2 | ============ 3 | You can install PyKMIP via ``pip``: 4 | 5 | .. code-block:: console 6 | 7 | $ pip install pykmip 8 | 9 | Supported platforms 10 | ------------------- 11 | PyKMIP is tested on Python 2.7, 3.4, 3.5, 3.6, and 3.7 on the following 12 | operating systems: 13 | 14 | * Ubuntu 12.04, 14.04, and 16.04 15 | 16 | PyKMIP also works on Windows and MacOSX however these platforms are not 17 | officially supported or tested. 18 | 19 | Building PyKMIP on Linux 20 | ------------------------ 21 | You can install PyKMIP from source via ``git``: 22 | 23 | .. code-block:: console 24 | 25 | $ git clone https://github.com/openkmip/pykmip.git 26 | $ python pykmip/setup.py install 27 | 28 | If you are on a fresh Linux build, you may also need several additional system 29 | dependencies, including headers for Python, OpenSSL, ``libffi``, and 30 | ``libsqlite3``. 31 | 32 | Ubuntu 33 | ~~~~~~ 34 | Replace ``python-dev`` with ``python3-dev`` if you are using Python 3.0+. 35 | 36 | .. code-block:: console 37 | 38 | $ sudo apt-get install python-dev libffi-dev libssl-dev libsqlite3-dev 39 | -------------------------------------------------------------------------------- /docs/source/security.rst: -------------------------------------------------------------------------------- 1 | Security 2 | ======== 3 | The PyKMIP development team takes security seriously and will respond promptly 4 | to any reported security issue. Use the information provided here to inform 5 | your security posture. 6 | 7 | Reporting a Security Issue 8 | -------------------------- 9 | If you discover a new PyKMIP security issue, please follow responsible 10 | disclosure best practices and contact the project maintainers in private over 11 | email to discuss the issue before filing a public GitHub issue. When reporting 12 | a security issue, please include as much detail as possible. This includes: 13 | 14 | * a high-level description of the issue 15 | * information on how to cause or reproduce the issue 16 | * any details on specific portions of the project code base related to the issue 17 | 18 | Once you have provided this information, you should receive an acknowledgement. 19 | Depending upon the severity of the issue, the project maintainers will respond 20 | to collect additional information and work with you to address the security 21 | issue. If applicable, a new library subrelease will be produced across all 22 | actively supported releases to address and fix the issue. 23 | 24 | If the developerment team decides the issue does not warrant the sensitivity 25 | of a security issue, you may file a public GitHub issue on the project 26 | `issue tracker`_. 27 | 28 | Known Vulnerabilities 29 | --------------------- 30 | 31 | The following are known vulnerabilities for older, unsupported versions of PyKMIP. 32 | 33 | +---------------------+--------------------------+-------------------+--------------------------+ 34 | | CVE | Brief Description | PyKMIP Version(s) | Mitigation | 35 | +=====================+==========================+===================+==========================+ 36 | | `CVE-2018-1000872`_ | Server Denial-of-Service | <=0.7.0 | Upgrade to PyKMIP 0.8.0+ | 37 | +---------------------+--------------------------+-------------------+--------------------------+ 38 | 39 | .. _`issue tracker`: https://github.com/OpenKMIP/PyKMIP/issues 40 | .. _`CVE-2018-1000872`: https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2018-1000872 -------------------------------------------------------------------------------- /examples/pykmip.conf: -------------------------------------------------------------------------------- 1 | [client] 2 | host=127.0.0.1 3 | port=5696 4 | keyfile=/etc/pykmip/certs/client_private_key.pem 5 | certfile=/etc/pykmip/certs/client_cert.pem 6 | cert_reqs=CERT_REQUIRED 7 | ssl_version=PROTOCOL_SSLv23 8 | ca_certs=/etc/pykmip/certs/server_ca_cert.pem 9 | do_handshake_on_connect=True 10 | suppress_ragged_eofs=True 11 | username=example_username 12 | password=example_password 13 | -------------------------------------------------------------------------------- /examples/server.conf: -------------------------------------------------------------------------------- 1 | [server] 2 | hostname=127.0.0.1 3 | port=5696 4 | certificate_path=/etc/pykmip/certs/server_cert.pem 5 | key_path=/etc/pykmip/certs/server_private_key.pem 6 | ca_path=/etc/pykmip/certs/server_ca_cert.pem 7 | auth_suite=Basic 8 | policy_path=/etc/pykmip/policies 9 | enable_tls_client_auth=True 10 | tls_cipher_suites= 11 | EXAMPLE_CIPHER_SUITE_1 12 | EXAMPLE_CIPHER_SUITE_2 13 | EXAMPLE_CIPHER_SUITE_3 14 | logging_level=INFO 15 | -------------------------------------------------------------------------------- /kmip/__init__.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2014 The Johns Hopkins University/Applied Physics Laboratory 2 | # All Rights Reserved. 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); you may 5 | # not use this file except in compliance with the License. You may obtain 6 | # a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | # License for the specific language governing permissions and limitations 14 | # under the License. 15 | 16 | import os 17 | import re 18 | 19 | from kmip.core import enums 20 | from kmip.pie import client 21 | from kmip.pie import objects 22 | from kmip.pie.client import ProxyKmipClient as KmipClient 23 | 24 | # Dynamically set __version__ 25 | version_path = os.path.join( 26 | os.path.dirname(os.path.realpath(__file__)), 27 | "version.py" 28 | ) 29 | with open(version_path, 'r') as f: 30 | m = re.search( 31 | r"^__version__ = \"(\d+\.\d+\..*)\"$", 32 | f.read(), 33 | re.MULTILINE 34 | ) 35 | __version__ = m.group(1) 36 | 37 | 38 | __all__ = [ 39 | 'client', 40 | 'core', 41 | 'demos', 42 | 'enums', 43 | 'KmipClient', 44 | 'objects', 45 | 'services' 46 | ] 47 | -------------------------------------------------------------------------------- /kmip/core/__init__.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2014 The Johns Hopkins University/Applied Physics Laboratory 2 | # All Rights Reserved. 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); you may 5 | # not use this file except in compliance with the License. You may obtain 6 | # a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | # License for the specific language governing permissions and limitations 14 | # under the License. 15 | 16 | __all__ = ['factories', 'messages', 'repo'] 17 | -------------------------------------------------------------------------------- /kmip/core/config_helper.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2014 The Johns Hopkins University/Applied Physics Laboratory 2 | # All Rights Reserved. 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); you may 5 | # not use this file except in compliance with the License. You may obtain 6 | # a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | # License for the specific language governing permissions and limitations 14 | # under the License. 15 | 16 | import logging 17 | import os 18 | 19 | from six.moves.configparser import ConfigParser 20 | 21 | FILE_PATH = os.path.dirname(os.path.abspath(__file__)) 22 | 23 | # TODO (peter-hamilton): Remove support for kmipconfig.ini on future release. 24 | CONFIG_FILE = [ 25 | os.path.join(os.path.expanduser('~'), '.pykmip', 'pykmip.conf'), 26 | os.path.join(os.sep, 'etc', 'pykmip', 'pykmip.conf'), 27 | os.path.normpath(os.path.join(FILE_PATH, '../pykmip.conf')), 28 | os.path.normpath(os.path.join(FILE_PATH, '../kmipconfig.ini'))] 29 | 30 | 31 | class ConfigHelper(object): 32 | NONE_VALUE = 'None' 33 | DEFAULT_HOST = "127.0.0.1" 34 | DEFAULT_PORT = 5696 35 | DEFAULT_CERTFILE = os.path.normpath(os.path.join( 36 | FILE_PATH, '../demos/certs/server.crt')) 37 | DEFAULT_KEYFILE = os.path.normpath(os.path.join( 38 | FILE_PATH, '../demos/certs/server.key')) 39 | DEFAULT_CA_CERTS = os.path.normpath(os.path.join( 40 | FILE_PATH, '../demos/certs/server.crt')) 41 | DEFAULT_SSL_VERSION = 'PROTOCOL_SSLv23' 42 | DEFAULT_USERNAME = None 43 | DEFAULT_PASSWORD = None 44 | 45 | # Timeout measured in seconds 46 | DEFAULT_TIMEOUT = 30 47 | 48 | def __init__(self, path=None): 49 | self.logger = logging.getLogger(__name__) 50 | # DEBUG logging here may expose passwords, so log at INFO by default. 51 | # However, if consumers know the risks, let them go ahead and override. 52 | if self.logger.level == logging.NOTSET: 53 | self.logger.setLevel(logging.INFO) 54 | 55 | self.conf = ConfigParser() 56 | 57 | filenames = path 58 | if not path: 59 | filenames = CONFIG_FILE 60 | 61 | if self.conf.read(filenames): 62 | self.logger.debug("Using config file at {0}".format(filenames)) 63 | else: 64 | self.logger.warning( 65 | "Config file {0} not found".format(filenames)) 66 | 67 | def get_valid_value(self, direct_value, config_section, 68 | config_option_name, default_value): 69 | """Returns a value that can be used as a parameter in client or 70 | server. If a direct_value is given, that value will be returned 71 | instead of the value from the config file. If the appropriate config 72 | file option is not found, the default_value is returned. 73 | 74 | :param direct_value: represents a direct value that should be used. 75 | supercedes values from config files 76 | :param config_section: which section of the config file to use 77 | :param config_option_name: name of config option value 78 | :param default_value: default value to be used if other options not 79 | found 80 | :returns: a value that can be used as a parameter 81 | """ 82 | ARG_MSG = "Using given value '{0}' for {1}" 83 | CONF_MSG = "Using value '{0}' from configuration file {1} for {2}" 84 | DEFAULT_MSG = "Using default value '{0}' for {1}" 85 | if direct_value: 86 | return_value = direct_value 87 | self.logger.debug(ARG_MSG.format(direct_value, config_option_name)) 88 | else: 89 | try: 90 | return_value = self.conf.get(config_section, 91 | config_option_name) 92 | self.logger.debug(CONF_MSG.format(return_value, 93 | CONFIG_FILE, 94 | config_option_name)) 95 | except Exception: 96 | return_value = default_value 97 | self.logger.debug(DEFAULT_MSG.format(default_value, 98 | config_option_name)) 99 | # TODO (peter-hamilton): Think about adding better value validation 100 | if return_value == self.NONE_VALUE: 101 | return None 102 | else: 103 | return return_value 104 | -------------------------------------------------------------------------------- /kmip/core/factories/__init__.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2014 The Johns Hopkins University/Applied Physics Laboratory 2 | # All Rights Reserved. 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); you may 5 | # not use this file except in compliance with the License. You may obtain 6 | # a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | # License for the specific language governing permissions and limitations 14 | # under the License. 15 | -------------------------------------------------------------------------------- /kmip/core/factories/attributes.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2014 The Johns Hopkins University/Applied Physics Laboratory 2 | # All Rights Reserved. 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); you may 5 | # not use this file except in compliance with the License. You may obtain 6 | # a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | # License for the specific language governing permissions and limitations 14 | # under the License. 15 | 16 | from enum import Enum 17 | 18 | from kmip.core.factories.attribute_values import AttributeValueFactory 19 | 20 | from kmip.core.objects import Attribute 21 | 22 | from kmip.core import utils 23 | 24 | 25 | class AttributeFactory(object): 26 | 27 | def __init__(self): 28 | self.value_factory = AttributeValueFactory() 29 | 30 | def _create_attribute(self, name, value, index): 31 | attribute_name = Attribute.AttributeName(name) 32 | 33 | if index is None: 34 | return Attribute(attribute_name=attribute_name, 35 | attribute_value=value) 36 | else: 37 | attribute_index = Attribute.AttributeIndex(index) 38 | return Attribute(attribute_name=attribute_name, 39 | attribute_index=attribute_index, 40 | attribute_value=value) 41 | 42 | def create_attribute(self, name, value, index=None): 43 | value = self.value_factory.create_attribute_value(name, value) 44 | 45 | if isinstance(name, Enum): 46 | name = name.value 47 | elif isinstance(name, str): 48 | # Name is already a string, pass 49 | pass 50 | else: 51 | msg = utils.build_er_error(Attribute, 'name', 52 | '{0} or {1}'.format('Enum', 'str'), 53 | type(name)) 54 | raise TypeError(msg) 55 | 56 | return self._create_attribute(name, value, index) 57 | -------------------------------------------------------------------------------- /kmip/core/factories/credentials.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2014 The Johns Hopkins University/Applied Physics Laboratory 2 | # All Rights Reserved. 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); you may 5 | # not use this file except in compliance with the License. You may obtain 6 | # a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | # License for the specific language governing permissions and limitations 14 | # under the License. 15 | 16 | from kmip.core import enums 17 | from kmip.core import objects 18 | 19 | 20 | class CredentialFactory(object): 21 | 22 | def create_credential(self, credential_type, credential_value): 23 | # Switch on the type of the credential 24 | if credential_type is enums.CredentialType.USERNAME_AND_PASSWORD: 25 | credential_value = self.create_username_password_credential( 26 | credential_value 27 | ) 28 | elif credential_type is enums.CredentialType.DEVICE: 29 | credential_value = self.create_device_credential(credential_value) 30 | else: 31 | msg = 'Unrecognized credential type: {0}' 32 | raise ValueError(msg.format(credential_type)) 33 | 34 | return objects.Credential( 35 | credential_type=credential_type, 36 | credential_value=credential_value 37 | ) 38 | 39 | @staticmethod 40 | def create_username_password_credential(value): 41 | username = value.get('Username') 42 | password = value.get('Password') 43 | 44 | return objects.UsernamePasswordCredential( 45 | username=username, 46 | password=password 47 | ) 48 | 49 | @staticmethod 50 | def create_device_credential(value): 51 | dsn = value.get('Device Serial Number') 52 | password = value.get('Password') 53 | dev_id = value.get('Device Identifier') 54 | net_id = value.get('Network Identifier') 55 | mach_id = value.get('Machine Identifier') 56 | med_id = value.get('Media Identifier') 57 | 58 | return objects.DeviceCredential( 59 | device_serial_number=dsn, 60 | password=password, 61 | device_identifier=dev_id, 62 | network_identifier=net_id, 63 | machine_identifier=mach_id, 64 | media_identifier=med_id 65 | ) 66 | -------------------------------------------------------------------------------- /kmip/core/factories/payloads/request.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2014 The Johns Hopkins University/Applied Physics Laboratory 2 | # All Rights Reserved. 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); you may 5 | # not use this file except in compliance with the License. You may obtain 6 | # a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | # License for the specific language governing permissions and limitations 14 | # under the License. 15 | 16 | from kmip.core.factories.payloads import PayloadFactory 17 | from kmip.core.messages import payloads 18 | 19 | 20 | class RequestPayloadFactory(PayloadFactory): 21 | 22 | # TODO (peterhamilton) Alphabetize these 23 | def _create_create_payload(self): 24 | return payloads.CreateRequestPayload() 25 | 26 | def _create_create_key_pair_payload(self): 27 | return payloads.CreateKeyPairRequestPayload() 28 | 29 | def _create_register_payload(self): 30 | return payloads.RegisterRequestPayload() 31 | 32 | def _create_derive_key_payload(self): 33 | return payloads.DeriveKeyRequestPayload() 34 | 35 | def _create_rekey_payload(self): 36 | return payloads.RekeyRequestPayload() 37 | 38 | def _create_rekey_key_pair_payload(self): 39 | return payloads.RekeyKeyPairRequestPayload() 40 | 41 | def _create_locate_payload(self): 42 | return payloads.LocateRequestPayload() 43 | 44 | def _create_check_payload(self): 45 | return payloads.CheckRequestPayload() 46 | 47 | def _create_get_payload(self): 48 | return payloads.GetRequestPayload() 49 | 50 | def _create_get_attribute_list_payload(self): 51 | return payloads.GetAttributeListRequestPayload() 52 | 53 | def _create_get_attributes_payload(self): 54 | return payloads.GetAttributesRequestPayload() 55 | 56 | def _create_delete_attribute_payload(self): 57 | return payloads.DeleteAttributeRequestPayload() 58 | 59 | def _create_set_attribute_payload(self): 60 | return payloads.SetAttributeRequestPayload() 61 | 62 | def _create_modify_attribute_payload(self): 63 | return payloads.ModifyAttributeRequestPayload() 64 | 65 | def _create_destroy_payload(self): 66 | return payloads.DestroyRequestPayload() 67 | 68 | def _create_query_payload(self): 69 | return payloads.QueryRequestPayload() 70 | 71 | def _create_discover_versions_payload(self): 72 | return payloads.DiscoverVersionsRequestPayload() 73 | 74 | def _create_activate_payload(self): 75 | return payloads.ActivateRequestPayload() 76 | 77 | def _create_revoke_payload(self): 78 | return payloads.RevokeRequestPayload() 79 | 80 | def _create_mac_payload(self): 81 | return payloads.MACRequestPayload() 82 | 83 | def _create_encrypt_payload(self): 84 | return payloads.EncryptRequestPayload() 85 | 86 | def _create_decrypt_payload(self): 87 | return payloads.DecryptRequestPayload() 88 | 89 | def _create_sign_payload(self): 90 | return payloads.SignRequestPayload() 91 | 92 | def _create_signature_verify_payload(self): 93 | return payloads.SignatureVerifyRequestPayload() 94 | -------------------------------------------------------------------------------- /kmip/core/factories/payloads/response.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2014 The Johns Hopkins University/Applied Physics Laboratory 2 | # All Rights Reserved. 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); you may 5 | # not use this file except in compliance with the License. You may obtain 6 | # a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | # License for the specific language governing permissions and limitations 14 | # under the License. 15 | 16 | from kmip.core.factories.payloads import PayloadFactory 17 | from kmip.core.messages import payloads 18 | 19 | 20 | class ResponsePayloadFactory(PayloadFactory): 21 | 22 | # TODO (peterhamilton) Alphabetize these 23 | def _create_create_payload(self): 24 | return payloads.CreateResponsePayload() 25 | 26 | def _create_create_key_pair_payload(self): 27 | return payloads.CreateKeyPairResponsePayload() 28 | 29 | def _create_register_payload(self): 30 | return payloads.RegisterResponsePayload() 31 | 32 | def _create_derive_key_payload(self): 33 | return payloads.DeriveKeyResponsePayload() 34 | 35 | def _create_rekey_payload(self): 36 | return payloads.RekeyResponsePayload() 37 | 38 | def _create_rekey_key_pair_payload(self): 39 | return payloads.RekeyKeyPairResponsePayload() 40 | 41 | def _create_locate_payload(self): 42 | return payloads.LocateResponsePayload() 43 | 44 | def _create_check_payload(self): 45 | return payloads.CheckResponsePayload() 46 | 47 | def _create_get_payload(self): 48 | return payloads.GetResponsePayload() 49 | 50 | def _create_get_attribute_list_payload(self): 51 | return payloads.GetAttributeListResponsePayload() 52 | 53 | def _create_get_attributes_payload(self): 54 | return payloads.GetAttributesResponsePayload() 55 | 56 | def _create_delete_attribute_payload(self): 57 | return payloads.DeleteAttributeResponsePayload() 58 | 59 | def _create_set_attribute_payload(self): 60 | return payloads.SetAttributeResponsePayload() 61 | 62 | def _create_modify_attribute_payload(self): 63 | return payloads.ModifyAttributeResponsePayload() 64 | 65 | def _create_destroy_payload(self): 66 | return payloads.DestroyResponsePayload() 67 | 68 | def _create_query_payload(self): 69 | return payloads.QueryResponsePayload() 70 | 71 | def _create_discover_versions_payload(self): 72 | return payloads.DiscoverVersionsResponsePayload() 73 | 74 | def _create_activate_payload(self): 75 | return payloads.ActivateResponsePayload() 76 | 77 | def _create_revoke_payload(self): 78 | return payloads.RevokeResponsePayload() 79 | 80 | def _create_mac_payload(self): 81 | return payloads.MACResponsePayload() 82 | 83 | def _create_encrypt_payload(self): 84 | return payloads.EncryptResponsePayload() 85 | 86 | def _create_decrypt_payload(self): 87 | return payloads.DecryptResponsePayload() 88 | 89 | def _create_sign_payload(self): 90 | return payloads.SignResponsePayload() 91 | 92 | def _create_signature_verify_payload(self): 93 | return payloads.SignatureVerifyResponsePayload() 94 | -------------------------------------------------------------------------------- /kmip/core/messages/.gitignore: -------------------------------------------------------------------------------- 1 | /test_in.txt 2 | /test_out.txt 3 | -------------------------------------------------------------------------------- /kmip/core/messages/__init__.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2014 The Johns Hopkins University/Applied Physics Laboratory 2 | # All Rights Reserved. 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); you may 5 | # not use this file except in compliance with the License. You may obtain 6 | # a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | # License for the specific language governing permissions and limitations 14 | # under the License. 15 | 16 | __all__ = ['contents', 'messages', 'payloads'] 17 | -------------------------------------------------------------------------------- /kmip/core/messages/payloads/base.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2019 The Johns Hopkins University/Applied Physics Laboratory 2 | # All Rights Reserved. 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); you may 5 | # not use this file except in compliance with the License. You may obtain 6 | # a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | # License for the specific language governing permissions and limitations 14 | # under the License. 15 | 16 | from kmip.core import enums 17 | from kmip.core import primitives 18 | 19 | 20 | class RequestPayload(primitives.Struct): 21 | """ 22 | An abstract base class for KMIP request payloads. 23 | """ 24 | def __init__(self): 25 | super(RequestPayload, self).__init__(enums.Tags.REQUEST_PAYLOAD) 26 | 27 | 28 | class ResponsePayload(primitives.Struct): 29 | """ 30 | An abstract base class for KMIP response payloads. 31 | """ 32 | 33 | def __init__(self): 34 | super(ResponsePayload, self).__init__(enums.Tags.RESPONSE_PAYLOAD) 35 | -------------------------------------------------------------------------------- /kmip/core/messages/payloads/destroy.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2014 The Johns Hopkins University/Applied Physics Laboratory 2 | # All Rights Reserved. 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); you may 5 | # not use this file except in compliance with the License. You may obtain 6 | # a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | # License for the specific language governing permissions and limitations 14 | # under the License. 15 | 16 | from kmip.core import attributes 17 | from kmip.core import enums 18 | from kmip.core.enums import Tags 19 | from kmip.core.messages.payloads import base 20 | from kmip.core.utils import BytearrayStream 21 | 22 | 23 | # 4.21 24 | class DestroyRequestPayload(base.RequestPayload): 25 | 26 | def __init__(self, 27 | unique_identifier=None): 28 | super(DestroyRequestPayload, self).__init__() 29 | self.unique_identifier = unique_identifier 30 | self.validate() 31 | 32 | def read(self, istream, kmip_version=enums.KMIPVersion.KMIP_1_0): 33 | super(DestroyRequestPayload, self).read( 34 | istream, 35 | kmip_version=kmip_version 36 | ) 37 | tstream = BytearrayStream(istream.read(self.length)) 38 | 39 | if self.is_tag_next(Tags.UNIQUE_IDENTIFIER, tstream): 40 | self.unique_identifier = attributes.UniqueIdentifier() 41 | self.unique_identifier.read(tstream, kmip_version=kmip_version) 42 | 43 | self.is_oversized(tstream) 44 | self.validate() 45 | 46 | def write(self, ostream, kmip_version=enums.KMIPVersion.KMIP_1_0): 47 | tstream = BytearrayStream() 48 | 49 | if self.unique_identifier is not None: 50 | self.unique_identifier.write(tstream, kmip_version=kmip_version) 51 | 52 | # Write the length and value of the request payload 53 | self.length = tstream.length() 54 | super(DestroyRequestPayload, self).write( 55 | ostream, 56 | kmip_version=kmip_version 57 | ) 58 | ostream.write(tstream.buffer) 59 | 60 | def validate(self): 61 | self.__validate() 62 | 63 | def __validate(self): 64 | # TODO (peter-hamilton) Finish implementation. 65 | pass 66 | 67 | 68 | class DestroyResponsePayload(base.ResponsePayload): 69 | 70 | def __init__(self, 71 | unique_identifier=None): 72 | super(DestroyResponsePayload, self).__init__() 73 | self.unique_identifier = unique_identifier 74 | self.validate() 75 | 76 | def read(self, istream, kmip_version=enums.KMIPVersion.KMIP_1_0): 77 | super(DestroyResponsePayload, self).read( 78 | istream, 79 | kmip_version=kmip_version 80 | ) 81 | tstream = BytearrayStream(istream.read(self.length)) 82 | 83 | self.unique_identifier = attributes.UniqueIdentifier() 84 | self.unique_identifier.read(tstream, kmip_version=kmip_version) 85 | 86 | self.is_oversized(tstream) 87 | self.validate() 88 | 89 | def write(self, ostream, kmip_version=enums.KMIPVersion.KMIP_1_0): 90 | tstream = BytearrayStream() 91 | 92 | self.unique_identifier.write(tstream, kmip_version=kmip_version) 93 | 94 | # Write the length and value of the request payload 95 | self.length = tstream.length() 96 | super(DestroyResponsePayload, self).write( 97 | ostream, 98 | kmip_version=kmip_version 99 | ) 100 | ostream.write(tstream.buffer) 101 | 102 | def validate(self): 103 | self.__validate() 104 | 105 | def __validate(self): 106 | # TODO (peter-hamilton) Finish implementation. 107 | pass 108 | -------------------------------------------------------------------------------- /kmip/core/messages/payloads/discover_versions.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2015 The Johns Hopkins University/Applied Physics Laboratory 2 | # All Rights Reserved. 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); you may 5 | # not use this file except in compliance with the License. You may obtain 6 | # a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | # License for the specific language governing permissions and limitations 14 | # under the License. 15 | 16 | from six.moves import xrange 17 | 18 | from kmip.core import enums 19 | from kmip.core.messages.contents import ProtocolVersion 20 | from kmip.core.messages.payloads import base 21 | from kmip.core.utils import BytearrayStream 22 | 23 | 24 | class DiscoverVersionsRequestPayload(base.RequestPayload): 25 | 26 | def __init__(self, protocol_versions=None): 27 | super(DiscoverVersionsRequestPayload, self).__init__() 28 | 29 | if protocol_versions is None: 30 | self.protocol_versions = list() 31 | else: 32 | self.protocol_versions = protocol_versions 33 | 34 | self.validate() 35 | 36 | def read(self, istream, kmip_version=enums.KMIPVersion.KMIP_1_0): 37 | super(DiscoverVersionsRequestPayload, self).read( 38 | istream, 39 | kmip_version=kmip_version 40 | ) 41 | tstream = BytearrayStream(istream.read(self.length)) 42 | 43 | while (self.is_tag_next(enums.Tags.PROTOCOL_VERSION, tstream)): 44 | protocol_version = ProtocolVersion() 45 | protocol_version.read(tstream, kmip_version=kmip_version) 46 | self.protocol_versions.append(protocol_version) 47 | 48 | self.is_oversized(tstream) 49 | self.validate() 50 | 51 | def write(self, ostream, kmip_version=enums.KMIPVersion.KMIP_1_0): 52 | tstream = BytearrayStream() 53 | 54 | for protocol_version in self.protocol_versions: 55 | protocol_version.write(tstream, kmip_version=kmip_version) 56 | 57 | self.length = tstream.length() 58 | super(DiscoverVersionsRequestPayload, self).write( 59 | ostream, 60 | kmip_version=kmip_version 61 | ) 62 | ostream.write(tstream.buffer) 63 | 64 | def validate(self): 65 | self.__validate() 66 | 67 | def __validate(self): 68 | if isinstance(self.protocol_versions, list): 69 | for i in xrange(len(self.protocol_versions)): 70 | protocol_version = self.protocol_versions[i] 71 | if not isinstance(protocol_version, ProtocolVersion): 72 | msg = "invalid protocol version ({0} in list)".format(i) 73 | msg += "; expected {0}, received {1}".format( 74 | ProtocolVersion, protocol_version) 75 | raise TypeError(msg) 76 | else: 77 | msg = "invalid protocol versions list" 78 | msg += "; expected {0}, received {1}".format( 79 | list, self.protocol_versions) 80 | raise TypeError(msg) 81 | 82 | 83 | class DiscoverVersionsResponsePayload(base.ResponsePayload): 84 | 85 | def __init__(self, protocol_versions=None): 86 | super(DiscoverVersionsResponsePayload, self).__init__() 87 | 88 | if protocol_versions is None: 89 | self.protocol_versions = list() 90 | else: 91 | self.protocol_versions = protocol_versions 92 | 93 | self.validate() 94 | 95 | def read(self, istream, kmip_version=enums.KMIPVersion.KMIP_1_0): 96 | super(DiscoverVersionsResponsePayload, self).read( 97 | istream, 98 | kmip_version=kmip_version 99 | ) 100 | tstream = BytearrayStream(istream.read(self.length)) 101 | 102 | while (self.is_tag_next(enums.Tags.PROTOCOL_VERSION, tstream)): 103 | protocol_version = ProtocolVersion() 104 | protocol_version.read(tstream, kmip_version=kmip_version) 105 | self.protocol_versions.append(protocol_version) 106 | 107 | self.is_oversized(tstream) 108 | self.validate() 109 | 110 | def write(self, ostream, kmip_version=enums.KMIPVersion.KMIP_1_0): 111 | tstream = BytearrayStream() 112 | 113 | for protocol_version in self.protocol_versions: 114 | protocol_version.write(tstream, kmip_version=kmip_version) 115 | 116 | self.length = tstream.length() 117 | super(DiscoverVersionsResponsePayload, self).write( 118 | ostream, 119 | kmip_version=kmip_version 120 | ) 121 | ostream.write(tstream.buffer) 122 | 123 | def validate(self): 124 | self.__validate() 125 | 126 | def __validate(self): 127 | if isinstance(self.protocol_versions, list): 128 | for i in xrange(len(self.protocol_versions)): 129 | protocol_version = self.protocol_versions[i] 130 | if not isinstance(protocol_version, ProtocolVersion): 131 | msg = "invalid protocol version ({0} in list)".format(i) 132 | msg += "; expected {0}, received {1}".format( 133 | ProtocolVersion, protocol_version) 134 | raise TypeError(msg) 135 | else: 136 | msg = "invalid protocol versions list" 137 | msg += "; expected {0}, received {1}".format( 138 | list, self.protocol_versions) 139 | raise TypeError(msg) 140 | -------------------------------------------------------------------------------- /kmip/core/utils.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2014 The Johns Hopkins University/Applied Physics Laboratory 2 | # All Rights Reserved. 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); you may 5 | # not use this file except in compliance with the License. You may obtain 6 | # a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | # License for the specific language governing permissions and limitations 14 | # under the License. 15 | 16 | from binascii import hexlify 17 | import io 18 | 19 | from kmip.core import exceptions 20 | 21 | 22 | def bit_length(num): 23 | s = bin(num) 24 | s = s.lstrip('0b') 25 | return len(s) 26 | 27 | 28 | def count_bytes(num): 29 | bits = bit_length(num) 30 | num_bytes = int(bits / 8) 31 | if bits == 0 or bits % 8: 32 | num_bytes += 1 33 | return num_bytes 34 | 35 | 36 | def print_bytearray(array): 37 | sbuffer = hexlify_bytearray(array) 38 | print('buffer: {0}'.format(sbuffer)) 39 | 40 | 41 | def hexlify_bytearray(array): 42 | sbuffer = bytes(array[0:]) 43 | return hexlify(sbuffer) 44 | 45 | 46 | def is_stream_empty(stream): 47 | if len(stream.peek(1)) > 0: 48 | return False 49 | else: 50 | return True 51 | 52 | 53 | def build_er_error(class_object, descriptor, expected, received, 54 | attribute=None): 55 | msg = exceptions.ErrorStrings.BAD_EXP_RECV 56 | 57 | if attribute is None: 58 | class_string = '{0}'.format(class_object.__name__) 59 | else: 60 | class_string = '{0}.{1}'.format(class_object.__name__, attribute) 61 | 62 | return msg.format(class_string, descriptor, expected, received) 63 | 64 | 65 | class BytearrayStream(io.RawIOBase): 66 | def __init__(self, data=None): 67 | if data is None: 68 | self.buffer = bytes() 69 | else: 70 | self.buffer = bytes(data) 71 | 72 | def read(self, n=None): 73 | if n is None or n == -1: 74 | return self.readall() 75 | length = len(self.buffer) 76 | if n > length: 77 | n = length 78 | data = self.buffer[0:n] 79 | self.buffer = self.buffer[n:] 80 | return data 81 | 82 | def readall(self): 83 | data = self.buffer 84 | self.buffer = bytes() 85 | return data 86 | 87 | # TODO (peter-hamilton) Unused, add documentation or cut. 88 | def readinto(self, b): 89 | if len(b) <= len(self.buffer): 90 | num_bytes_to_read = len(b) 91 | else: 92 | num_bytes_to_read = len(self.buffer) 93 | b[:num_bytes_to_read] = self.buffer[:num_bytes_to_read] 94 | self.buffer = self.buffer[num_bytes_to_read:] 95 | return num_bytes_to_read 96 | 97 | def peek(self, n=None): 98 | length = len(self.buffer) 99 | if n is None or n > length: 100 | n = length 101 | return self.buffer[0:n] 102 | 103 | def write(self, b): 104 | prev_bytes = len(self.buffer) 105 | self.buffer += b 106 | return len(self.buffer) - prev_bytes 107 | 108 | def length(self): 109 | return len(self.buffer) 110 | 111 | def __str__(self): 112 | sbuffer = bytes(self.buffer[0:]) 113 | return str(hexlify(sbuffer)) 114 | 115 | def __len__(self): 116 | return len(self.buffer) 117 | 118 | def __eq__(self, other): 119 | if isinstance(other, BytearrayStream): 120 | if len(self.buffer) != len(other.buffer): 121 | return False 122 | elif self.buffer != other.buffer: 123 | return False 124 | else: 125 | return True 126 | else: 127 | return NotImplemented 128 | 129 | def __ne__(self, other): 130 | if isinstance(other, BytearrayStream): 131 | return not (self == other) 132 | else: 133 | return NotImplemented 134 | -------------------------------------------------------------------------------- /kmip/demos/__init__.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2014 The Johns Hopkins University/Applied Physics Laboratory 2 | # All Rights Reserved. 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); you may 5 | # not use this file except in compliance with the License. You may obtain 6 | # a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | # License for the specific language governing permissions and limitations 14 | # under the License. 15 | -------------------------------------------------------------------------------- /kmip/demos/certs/server.crt: -------------------------------------------------------------------------------- 1 | -----BEGIN CERTIFICATE----- 2 | MIIDBjCCAe4CCQDWchiOQEmcDDANBgkqhkiG9w0BAQUFADBFMQswCQYDVQQGEwJB 3 | VTETMBEGA1UECAwKU29tZS1TdGF0ZTEhMB8GA1UECgwYSW50ZXJuZXQgV2lkZ2l0 4 | cyBQdHkgTHRkMB4XDTE0MDgxOTA0MjAzM1oXDTE1MDgxOTA0MjAzM1owRTELMAkG 5 | A1UEBhMCQVUxEzARBgNVBAgMClNvbWUtU3RhdGUxITAfBgNVBAoMGEludGVybmV0 6 | IFdpZGdpdHMgUHR5IEx0ZDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEB 7 | AKcLbcQbhvzQ/5JB/omGt+VHXbnUinWKygYPNdJH5dvt0DVUNRvlvjTjkrNqTTVG 8 | iAdSuhxylW6NB7/aJ5Cen3J22NT01O7g5JNsNrrDwvOUNLnaMYCtIaMaHPrLFqTb 9 | SwlUoCbwY1W9/PWb63IorZOrs4iT0DhBqal6gshUFXYPYqTtseO+lMwTh9ETIcnV 10 | 8wwFCieX4czmQKcBZCBXShkyepSW/JczaYEelxhlfsAvNWKnvLE0SCOM2wp7XaB4 11 | Rjx0wbenQQvg0KqksIBXBa/Xm2YNyzonnPpG59HoAuap3ZP6ZqgdRy9CYNK92j17 12 | ZGzrxG5FWNeGKSCJUi7O7/sCAwEAATANBgkqhkiG9w0BAQUFAAOCAQEAnx2LB4Ma 13 | BKHOszMJQi5vrLni6G1IMWNmbbXERHancFovgGB//YaTnKnJxEPXx+WIrX5S+zLI 14 | 3Du4bQ78HMv7TSp5YV/E988qaGHjrKNp4aZpDM/uDE1p3Ik2mPUCa4uf3/HT2VaI 15 | LzSYZN7/C2CLg/65MuV10Tus0wE3H6UCWmBjNuZpCxIvuEYA2ZD7pHdvZgOe/dYX 16 | PEDRyDzkMAArJ/v4A/yj9JUB2nGkJLf/KHImFfZ+3+6UIiOQPsRvMlw4y7vCV+5d 17 | T5TN4NSj9+l6kGiB4fFszj60erPlRpshuRjcrrzJAxK7XZgZgsl/6UMoPBoUdsNx 18 | /Wc6VFs6KyJvgw== 19 | -----END CERTIFICATE----- 20 | -------------------------------------------------------------------------------- /kmip/demos/certs/server.key: -------------------------------------------------------------------------------- 1 | -----BEGIN RSA PRIVATE KEY----- 2 | MIIEpAIBAAKCAQEApwttxBuG/ND/kkH+iYa35UddudSKdYrKBg810kfl2+3QNVQ1 3 | G+W+NOOSs2pNNUaIB1K6HHKVbo0Hv9onkJ6fcnbY1PTU7uDkk2w2usPC85Q0udox 4 | gK0hoxoc+ssWpNtLCVSgJvBjVb389Zvrciitk6uziJPQOEGpqXqCyFQVdg9ipO2x 5 | 476UzBOH0RMhydXzDAUKJ5fhzOZApwFkIFdKGTJ6lJb8lzNpgR6XGGV+wC81Yqe8 6 | sTRII4zbCntdoHhGPHTBt6dBC+DQqqSwgFcFr9ebZg3LOiec+kbn0egC5qndk/pm 7 | qB1HL0Jg0r3aPXtkbOvEbkVY14YpIIlSLs7v+wIDAQABAoIBAQCiM6nJNAWWdgbE 8 | aUqVFfh5LRwoduZfjn3u9lQHtQLQ1JJJRlQvm51fU98+UilYYv1xRvYq62SIrW7p 9 | 7xZeCni/OAICfx5IOp4ZPInEPpSN2sp78RACZ5ry+kdLi2qYd8vb6o18Yg3C0zHO 10 | +DDeb/tkGeTB6O3VwoTRaYGWrncMZABgOjGI0Iyjn4tJZnl8V+rhoseCKezGwaZl 11 | rAukc0lv4GX6jQoMWB72/qhIu8a9MinP0b3U17j+flnVlcrYS1Y6Atuj4sGCpeVc 12 | fxLfbkUy2p7Ja4YBmYfhlnJb76VBKr2MeKHcHJl2+CzWMbDJsH+/skD0UPfvicjr 13 | wC1m9NQxAoGBANR6a6x3afQG2iLMhmQa9WdH7ufWlL122ssal+u66r68PsqBu0Zs 14 | 264lYyJmjyQvWw6Kbh1Lre14/LpwJMZko2HSqcy0cz7qTKwIAcxI3Qi5ZEhngU/l 15 | lyOLFm6fPdA57vTkb7kgi1EmwWdf8mTDCHrLQpCMIRXc1rQAYKwfGb35AoGBAMlC 16 | o3Ol+Br8pltjKtmlfYLnznFeepqPWBO+lTFqZYA6LvDAsjfEVufsMXCeNKq0Uopi 17 | ocRIkPy0V1DZSe3hfZAV55fH3nk9uo2MfSsEKS/0lrG6PG4VK69Mo9wvkj7N5Oyj 18 | qFc8tjRO43IZaOA1zWh8eFGdHERs6AZHXWEPvCqTAoGAB7nX1nKVILFrFx7WuCce 19 | yz2bW0S7LdR3ijESWxj11i+kHNrww1PL/R4Q57xQ8iDir7mq3VfWIC9pCSJww+H+ 20 | 6tytHetl0WDVnt+/qPzxRJLxKYzR7+TKRRmWnDkgF0U0AiWYRmP/jNja6XZcqvtI 21 | gKaJahYeUdww1mS5HykWV4kCgYEAjz2yf7j8YJi4/goSkV1Le0Polp+buy2Sjlry 22 | bH1BSIYgqpE7Rp2jDOX6OiEfcu9sX7nbUIwlRPZFvvEnwPrgFxDACDLkkH3yrJP0 23 | 8gzAE7WNG2llYSQIN3fgl/HzsGdyK0o/ofc/5vLOxoJ3NjyUuWz9ZXjgiYLJkM5y 24 | E4bTcakCgYBQZuce3iG9DpW/YZwRIasUYfjLgOecwLRP+Bh8iv6NAe3sOJFlY1XQ 25 | 37De7wtSG24SogJDv5vglI9MwY2N1MCqT74HgZhazjtIz3cXwREDf7/vmiWsBPlA 26 | Xghc8kmX70eb471WAI9y1wlj/UtNEeXT/ntfWCLFKdBH+o32P/UsiQ== 27 | -----END RSA PRIVATE KEY----- 28 | -------------------------------------------------------------------------------- /kmip/demos/pie/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OpenKMIP/PyKMIP/6cd44b572b0ca55adf01a8a12078b2284602e64c/kmip/demos/pie/__init__.py -------------------------------------------------------------------------------- /kmip/demos/pie/create.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2015 The Johns Hopkins University/Applied Physics Laboratory 2 | # All Rights Reserved. 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); you may 5 | # not use this file except in compliance with the License. You may obtain 6 | # a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | # License for the specific language governing permissions and limitations 14 | # under the License. 15 | 16 | import logging 17 | import sys 18 | 19 | from kmip.core import enums 20 | from kmip.demos import utils 21 | 22 | from kmip.pie import client 23 | 24 | 25 | if __name__ == '__main__': 26 | logger = utils.build_console_logger(logging.INFO) 27 | 28 | # Build and parse arguments 29 | parser = utils.build_cli_parser(enums.Operation.CREATE) 30 | opts, args = parser.parse_args(sys.argv[1:]) 31 | 32 | config = opts.config 33 | algorithm = opts.algorithm 34 | length = opts.length 35 | 36 | # Exit early if the arguments are not specified 37 | if algorithm is None: 38 | logger.error('No algorithm provided, exiting early from demo') 39 | sys.exit() 40 | if length is None: 41 | logger.error("No key length provided, exiting early from demo") 42 | sys.exit() 43 | 44 | algorithm = getattr(enums.CryptographicAlgorithm, algorithm, None) 45 | 46 | # Build the client and connect to the server 47 | with client.ProxyKmipClient( 48 | config=config, 49 | config_file=opts.config_file 50 | ) as client: 51 | try: 52 | uid = client.create( 53 | algorithm, 54 | length, 55 | operation_policy_name=opts.operation_policy_name 56 | ) 57 | logger.info("Successfully created symmetric key with ID: " 58 | "{0}".format(uid)) 59 | except Exception as e: 60 | logger.error(e) 61 | -------------------------------------------------------------------------------- /kmip/demos/pie/create_key_pair.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2015 The Johns Hopkins University/Applied Physics Laboratory 2 | # All Rights Reserved. 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); you may 5 | # not use this file except in compliance with the License. You may obtain 6 | # a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | # License for the specific language governing permissions and limitations 14 | # under the License. 15 | 16 | import logging 17 | import sys 18 | 19 | from kmip.core import enums 20 | from kmip.demos import utils 21 | from kmip.pie import client 22 | 23 | 24 | if __name__ == '__main__': 25 | logger = utils.build_console_logger(logging.INFO) 26 | 27 | # Build and parse arguments 28 | parser = utils.build_cli_parser(enums.Operation.CREATE_KEY_PAIR) 29 | opts, args = parser.parse_args(sys.argv[1:]) 30 | 31 | config = opts.config 32 | algorithm = opts.algorithm 33 | length = opts.length 34 | 35 | # Exit early if the arguments are not specified 36 | if algorithm is None: 37 | logger.error('No algorithm provided, exiting early from demo') 38 | sys.exit() 39 | if length is None: 40 | logger.error("No key length provided, exiting early from demo") 41 | sys.exit() 42 | 43 | algorithm = getattr(enums.CryptographicAlgorithm, algorithm, None) 44 | 45 | # Build the client and connect to the server 46 | with client.ProxyKmipClient( 47 | config=config, 48 | config_file=opts.config_file 49 | ) as client: 50 | try: 51 | public_uid, private_uid = client.create_key_pair( 52 | algorithm, 53 | length, 54 | operation_policy_name=opts.operation_policy_name, 55 | public_usage_mask=[enums.CryptographicUsageMask.VERIFY], 56 | private_usage_mask=[enums.CryptographicUsageMask.SIGN] 57 | ) 58 | logger.info("Successfully created public key with ID: {0}".format( 59 | public_uid)) 60 | logger.info("Successfully created private key with ID: {0}".format( 61 | private_uid)) 62 | except Exception as e: 63 | logger.error(e) 64 | -------------------------------------------------------------------------------- /kmip/demos/pie/decrypt.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2017 The Johns Hopkins University/Applied Physics Laboratory 2 | # All Rights Reserved. 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); you may 5 | # not use this file except in compliance with the License. You may obtain 6 | # a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | # License for the specific language governing permissions and limitations 14 | # under the License. 15 | 16 | import binascii 17 | import logging 18 | import sys 19 | 20 | from kmip.core import enums 21 | from kmip.demos import utils 22 | from kmip.pie import client 23 | 24 | # Real world example, assuming 'test' is a valid configuration: 25 | # 26 | # $ python kmip/demos/pie/encrypt.py -c test -m "My test message." 27 | # INFO - Successfully created a new encryption key. 28 | # INFO - Secret ID: 470 29 | # INFO - Successfully activated the encryption key. 30 | # INFO - Successfully encrypted the message. 31 | # INFO - Cipher text: b'49cfacbb62659180c20dfbf9f7553488b3ea9ebeecd70ce2e5c4d4 32 | # ece6def0d4' 33 | # INFO - No autogenerated IV expected, since one was provided. 34 | # INFO - Autogenerated IV: None 35 | # $ python kmip/demos/pie/decrypt.py -c test -i 470 -m b'49cfacbb62659180c20df 36 | # bf9f7553488b3ea9ebeecd70ce2e5c4d4ece6def0d4' 37 | # INFO - Successfully decrypted the message. 38 | # INFO - Plain text: 'My test message.' 39 | 40 | 41 | if __name__ == '__main__': 42 | logger = utils.build_console_logger(logging.INFO) 43 | 44 | # Build and parse arguments 45 | parser = utils.build_cli_parser(enums.Operation.DECRYPT) 46 | opts, args = parser.parse_args(sys.argv[1:]) 47 | config = opts.config 48 | uuid = opts.uuid 49 | message = opts.message 50 | 51 | if not message.startswith("b"): 52 | raise ValueError("The message should be a byte string (e.g., b'...').") 53 | else: 54 | message = binascii.unhexlify(message[1:]) 55 | 56 | # Build the client and connect to the server 57 | with client.ProxyKmipClient( 58 | config=config, 59 | config_file=opts.config_file 60 | ) as client: 61 | # Decrypt the cipher text with the encryption key. 62 | try: 63 | plain_text = client.decrypt( 64 | message, 65 | uid=uuid, 66 | cryptographic_parameters={ 67 | 'cryptographic_algorithm': 68 | enums.CryptographicAlgorithm.AES, 69 | 'block_cipher_mode': enums.BlockCipherMode.CBC, 70 | 'padding_method': enums.PaddingMethod.ANSI_X923 71 | }, 72 | iv_counter_nonce=( 73 | b'\x01\x7D\x45\xA0\x88\x08\x11\x11' 74 | b'\xF0\x00\x12\xFF\x7A\x3A\x36\x90' 75 | ) 76 | ) 77 | logger.info("Successfully decrypted the message.") 78 | logger.info("Plain text: '{0}'".format(plain_text.decode('utf-8'))) 79 | except Exception as e: 80 | logger.error(e) 81 | -------------------------------------------------------------------------------- /kmip/demos/pie/delete_attribute.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2019 The Johns Hopkins University/Applied Physics Laboratory 2 | # All Rights Reserved. 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); you may 5 | # not use this file except in compliance with the License. You may obtain 6 | # a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | # License for the specific language governing permissions and limitations 14 | # under the License. 15 | 16 | import logging 17 | import sys 18 | 19 | from kmip.core import enums 20 | from kmip.demos import utils 21 | 22 | from kmip.pie import client 23 | 24 | 25 | # NOTE: This demo script shows how to delete the first Name attribute from 26 | # the user-specified object. The object *must* have at least one Name 27 | # attribute for attribute deletion to work. Otherwise, the client 28 | # call to delete_attribute will fail. 29 | 30 | if __name__ == '__main__': 31 | logger = utils.build_console_logger(logging.INFO) 32 | 33 | parser = utils.build_cli_parser(enums.Operation.DELETE_ATTRIBUTE) 34 | opts, args = parser.parse_args(sys.argv[1:]) 35 | 36 | if opts.uuid is None: 37 | logger.error("No UUID provided, existing early from demo.") 38 | sys.exit() 39 | 40 | with client.ProxyKmipClient( 41 | config=opts.config, 42 | config_file=opts.config_file 43 | ) as c: 44 | try: 45 | object_id, modified_attribute = c.delete_attribute( 46 | unique_identifier=opts.uuid, 47 | attribute_name="Name", 48 | attribute_index=0 49 | ) 50 | logger.info( 51 | "Successfully deleted 'Name' attribute from object: {}".format( 52 | object_id 53 | ) 54 | ) 55 | logger.info("Deleted attribute: {}".format(modified_attribute)) 56 | except Exception as e: 57 | logger.error(e) 58 | -------------------------------------------------------------------------------- /kmip/demos/pie/destroy.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2015 The Johns Hopkins University/Applied Physics Laboratory 2 | # All Rights Reserved. 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); you may 5 | # not use this file except in compliance with the License. You may obtain 6 | # a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | # License for the specific language governing permissions and limitations 14 | # under the License. 15 | 16 | import logging 17 | import sys 18 | 19 | from kmip.core import enums 20 | from kmip.demos import utils 21 | from kmip.pie import client 22 | 23 | 24 | if __name__ == '__main__': 25 | logger = utils.build_console_logger(logging.INFO) 26 | 27 | # Build and parse arguments 28 | parser = utils.build_cli_parser(enums.Operation.DESTROY) 29 | opts, args = parser.parse_args(sys.argv[1:]) 30 | 31 | config = opts.config 32 | uid = opts.uuid 33 | 34 | # Exit early if the UUID is not specified 35 | if uid is None: 36 | logger.error('No UUID provided, exiting early from demo') 37 | sys.exit() 38 | 39 | # Build the client and connect to the server 40 | with client.ProxyKmipClient( 41 | config=config, 42 | config_file=opts.config_file 43 | ) as client: 44 | try: 45 | client.destroy(uid) 46 | logger.info("Successfully destroyed secret with ID: {0}".format( 47 | uid)) 48 | except Exception as e: 49 | logger.error(e) 50 | -------------------------------------------------------------------------------- /kmip/demos/pie/encrypt.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2017 The Johns Hopkins University/Applied Physics Laboratory 2 | # All Rights Reserved. 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); you may 5 | # not use this file except in compliance with the License. You may obtain 6 | # a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | # License for the specific language governing permissions and limitations 14 | # under the License. 15 | 16 | import binascii 17 | import logging 18 | import sys 19 | 20 | from kmip.core import enums 21 | from kmip.demos import utils 22 | from kmip.pie import client 23 | 24 | # Real world example, assuming 'test' is a valid configuration: 25 | # 26 | # $ python kmip/demos/pie/encrypt.py -c test -m "My test message." 27 | # INFO - Successfully created a new encryption key. 28 | # INFO - Secret ID: 470 29 | # INFO - Successfully activated the encryption key. 30 | # INFO - Successfully encrypted the message. 31 | # INFO - Cipher text: b'49cfacbb62659180c20dfbf9f7553488b3ea9ebeecd70ce2e5c4d4 32 | # ece6def0d4' 33 | # INFO - No autogenerated IV expected, since one was provided. 34 | # INFO - Autogenerated IV: None 35 | # $ python kmip/demos/pie/decrypt.py -c test -i 470 -m b'49cfacbb62659180c20df 36 | # bf9f7553488b3ea9ebeecd70ce2e5c4d4ece6def0d4' 37 | # INFO - Successfully decrypted the message. 38 | # INFO - Plain text: 'My test message.' 39 | 40 | 41 | if __name__ == '__main__': 42 | logger = utils.build_console_logger(logging.INFO) 43 | 44 | # Build and parse arguments 45 | parser = utils.build_cli_parser(enums.Operation.ENCRYPT) 46 | opts, args = parser.parse_args(sys.argv[1:]) 47 | config = opts.config 48 | message = opts.message 49 | 50 | message = bytes(message, 'utf-8') 51 | 52 | # Build the client and connect to the server 53 | with client.ProxyKmipClient( 54 | config=config, 55 | config_file=opts.config_file 56 | ) as client: 57 | # Create an encryption key. 58 | try: 59 | key_id = client.create( 60 | enums.CryptographicAlgorithm.AES, 61 | 128, 62 | cryptographic_usage_mask=[ 63 | enums.CryptographicUsageMask.ENCRYPT, 64 | enums.CryptographicUsageMask.DECRYPT 65 | ] 66 | ) 67 | logger.info("Successfully created a new encryption key.") 68 | logger.info("Secret ID: {0}".format(key_id)) 69 | except Exception as e: 70 | logger.error(e) 71 | sys.exit(-1) 72 | 73 | # Activate the encryption key so that it can be used. 74 | try: 75 | client.activate(key_id) 76 | logger.info("Successfully activated the encryption key.") 77 | except Exception as e: 78 | logger.error(e) 79 | sys.exit(-1) 80 | 81 | # Encrypt some data with the encryption key. 82 | try: 83 | cipher_text, autogenerated_iv = client.encrypt( 84 | message, 85 | uid=key_id, 86 | cryptographic_parameters={ 87 | 'cryptographic_algorithm': 88 | enums.CryptographicAlgorithm.AES, 89 | 'block_cipher_mode': enums.BlockCipherMode.CBC, 90 | 'padding_method': enums.PaddingMethod.ANSI_X923 91 | }, 92 | iv_counter_nonce=( 93 | b'\x01\x7D\x45\xA0\x88\x08\x11\x11' 94 | b'\xF0\x00\x12\xFF\x7A\x3A\x36\x90' 95 | ) 96 | ) 97 | logger.info("Successfully encrypted the message.") 98 | logger.info( 99 | "Cipher text: {0}".format(binascii.hexlify(cipher_text)) 100 | ) 101 | logger.info( 102 | "No autogenerated IV expected, since one was provided." 103 | ) 104 | logger.info("Autogenerated IV: {0}".format(autogenerated_iv)) 105 | except Exception as e: 106 | logger.error(e) 107 | -------------------------------------------------------------------------------- /kmip/demos/pie/get.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2015 The Johns Hopkins University/Applied Physics Laboratory 2 | # All Rights Reserved. 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); you may 5 | # not use this file except in compliance with the License. You may obtain 6 | # a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | # License for the specific language governing permissions and limitations 14 | # under the License. 15 | 16 | import logging 17 | import sys 18 | 19 | from kmip.core import enums 20 | from kmip.demos import utils 21 | from kmip.pie import client 22 | 23 | 24 | if __name__ == '__main__': 25 | logger = utils.build_console_logger(logging.INFO) 26 | 27 | # Build and parse arguments 28 | parser = utils.build_cli_parser(enums.Operation.GET) 29 | opts, args = parser.parse_args(sys.argv[1:]) 30 | 31 | config = opts.config 32 | uid = opts.uuid 33 | 34 | # Exit early if the UUID is not specified 35 | if uid is None: 36 | logger.error('No UUID provided, exiting early from demo') 37 | sys.exit() 38 | 39 | # Build the client and connect to the server 40 | with client.ProxyKmipClient( 41 | config=config, 42 | config_file=opts.config_file 43 | ) as client: 44 | try: 45 | secret = client.get(uid) 46 | logger.info("Successfully retrieved secret with ID: {0}".format( 47 | uid)) 48 | logger.info("Secret data: {0}".format(secret)) 49 | except Exception as e: 50 | logger.error(e) 51 | -------------------------------------------------------------------------------- /kmip/demos/pie/get_attribute_list.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2015 The Johns Hopkins University/Applied Physics Laboratory 2 | # All Rights Reserved. 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); you may 5 | # not use this file except in compliance with the License. You may obtain 6 | # a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | # License for the specific language governing permissions and limitations 14 | # under the License. 15 | 16 | import logging 17 | import sys 18 | 19 | from kmip.core import enums 20 | from kmip.demos import utils 21 | from kmip.pie import client 22 | 23 | 24 | if __name__ == '__main__': 25 | logger = utils.build_console_logger(logging.INFO) 26 | 27 | # Build and parse arguments 28 | parser = utils.build_cli_parser(enums.Operation.GET_ATTRIBUTE_LIST) 29 | opts, args = parser.parse_args(sys.argv[1:]) 30 | 31 | config = opts.config 32 | uid = opts.uuid 33 | 34 | # Exit early if the UUID is not specified 35 | if uid is None: 36 | logger.error('No ID provided, exiting early from demo') 37 | sys.exit() 38 | 39 | # Build the client and connect to the server 40 | with client.ProxyKmipClient( 41 | config=config, 42 | config_file=opts.config_file 43 | ) as client: 44 | try: 45 | attribute_names = client.get_attribute_list(uid) 46 | logger.info("Successfully retrieved {0} attribute names:".format( 47 | len(attribute_names))) 48 | for attribute_name in attribute_names: 49 | logger.info("Attribute name: {0}".format(attribute_name)) 50 | except Exception as e: 51 | logger.error(e) 52 | -------------------------------------------------------------------------------- /kmip/demos/pie/get_attributes.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2019 The Johns Hopkins University/Applied Physics Laboratory 2 | # All Rights Reserved. 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); you may 5 | # not use this file except in compliance with the License. You may obtain 6 | # a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | # License for the specific language governing permissions and limitations 14 | # under the License. 15 | 16 | import logging 17 | import sys 18 | 19 | from kmip.core import enums 20 | from kmip.demos import utils 21 | from kmip.pie import client 22 | 23 | 24 | if __name__ == '__main__': 25 | logger = utils.build_console_logger(logging.INFO) 26 | 27 | # Build and parse arguments 28 | parser = utils.build_cli_parser(enums.Operation.GET_ATTRIBUTES) 29 | opts, args = parser.parse_args(sys.argv[1:]) 30 | 31 | config = opts.config 32 | uid = opts.uuid 33 | 34 | # Exit early if the UUID is not specified 35 | if uid is None: 36 | logger.error('No ID provided, exiting early from demo') 37 | sys.exit() 38 | 39 | # Build the client and connect to the server 40 | with client.ProxyKmipClient( 41 | config=config, 42 | config_file=opts.config_file 43 | ) as client: 44 | try: 45 | _, attributes = client.get_attributes( 46 | uid, attribute_names=opts.attribute_names) 47 | logger.info("Successfully retrieved {0} attributes:".format( 48 | len(attributes))) 49 | for attribute in attributes: 50 | logger.info("Attribute {0}: {1}".format( 51 | attribute.attribute_name, attribute.attribute_value)) 52 | except Exception as e: 53 | logger.error(e) 54 | -------------------------------------------------------------------------------- /kmip/demos/pie/mac.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2017 Pure Storage, Inc. 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 sys 17 | import binascii 18 | 19 | from kmip.core import enums 20 | from kmip.demos import utils 21 | 22 | from kmip.pie import client 23 | 24 | 25 | if __name__ == '__main__': 26 | logger = utils.build_console_logger(logging.INFO) 27 | 28 | # Build and parse arguments 29 | parser = utils.build_cli_parser(enums.Operation.MAC) 30 | opts, args = parser.parse_args(sys.argv[1:]) 31 | 32 | config = opts.config 33 | uid = opts.uuid 34 | algorithm = opts.algorithm 35 | 36 | data = ( 37 | b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B\x0C\x0D\x0E' 38 | b'\x0F') 39 | 40 | # Exit early if the arguments are not specified 41 | if uid is None: 42 | logger.error('No UUID provided, exiting early from demo') 43 | sys.exit() 44 | if algorithm is None: 45 | logger.error('No algorithm provided, exiting early from demo') 46 | sys.exit() 47 | 48 | algorithm = getattr(enums.CryptographicAlgorithm, algorithm, None) 49 | 50 | # Build the client and connect to the server 51 | with client.ProxyKmipClient( 52 | config=config, 53 | config_file=opts.config_file 54 | ) as client: 55 | try: 56 | uid, mac_data = client.mac(data, uid, algorithm) 57 | logger.info("Successfully done MAC using key with ID: " 58 | "{0}".format(uid)) 59 | logger.info("MACed data: {0}".format( 60 | str(binascii.hexlify(mac_data)))) 61 | except Exception as e: 62 | logger.error(e) 63 | -------------------------------------------------------------------------------- /kmip/demos/pie/modify_attribute.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2019 The Johns Hopkins University/Applied Physics Laboratory 2 | # All Rights Reserved. 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); you may 5 | # not use this file except in compliance with the License. You may obtain 6 | # a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | # License for the specific language governing permissions and limitations 14 | # under the License. 15 | 16 | import logging 17 | import sys 18 | 19 | from kmip.core.factories import attributes 20 | from kmip.core import enums 21 | from kmip.demos import utils 22 | 23 | from kmip.pie import client 24 | 25 | 26 | # NOTE: This demo script shows how to modify the first Name attribute on 27 | # the user-specified object. The object *must* have at least one Name 28 | # attribute for attribute modification to work. Otherwise, the client 29 | # call to modify_attribute will fail. 30 | 31 | if __name__ == '__main__': 32 | logger = utils.build_console_logger(logging.INFO) 33 | 34 | parser = utils.build_cli_parser(enums.Operation.MODIFY_ATTRIBUTE) 35 | opts, args = parser.parse_args(sys.argv[1:]) 36 | 37 | if opts.uuid is None: 38 | logger.error("No UUID provided, existing early from demo.") 39 | sys.exit() 40 | 41 | factory = attributes.AttributeFactory() 42 | 43 | with client.ProxyKmipClient( 44 | config=opts.config, 45 | config_file=opts.config_file 46 | ) as c: 47 | try: 48 | object_id, modified_attribute = c.modify_attribute( 49 | unique_identifier=opts.uuid, 50 | attribute=factory.create_attribute( 51 | enums.AttributeType.NAME, 52 | "Modified Name", 53 | index=0 54 | ) 55 | ) 56 | logger.info( 57 | "Successfully modified 'Name' attribute on object: {}".format( 58 | object_id 59 | ) 60 | ) 61 | logger.info("Modified attribute: {}".format(modified_attribute)) 62 | except Exception as e: 63 | logger.error(e) 64 | -------------------------------------------------------------------------------- /kmip/demos/pie/register_opaque_object.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2015 The Johns Hopkins University/Applied Physics Laboratory 2 | # All Rights Reserved. 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); you may 5 | # not use this file except in compliance with the License. You may obtain 6 | # a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | # License for the specific language governing permissions and limitations 14 | # under the License. 15 | 16 | import logging 17 | import sys 18 | 19 | from kmip.core import enums 20 | from kmip.demos import utils 21 | 22 | from kmip.pie import client 23 | from kmip.pie import objects 24 | 25 | 26 | if __name__ == '__main__': 27 | logger = utils.build_console_logger(logging.INFO) 28 | 29 | parser = utils.build_cli_parser(enums.Operation.REGISTER) 30 | opts, args = parser.parse_args(sys.argv[1:]) 31 | 32 | config = opts.config 33 | 34 | value = b'\x53\x65\x63\x72\x65\x74\x50\x61\x73\x73\x77\x6F\x72\x64' 35 | opaque_type = enums.OpaqueDataType.NONE 36 | name = 'Demo Opaque Object' 37 | 38 | obj = objects.OpaqueObject(value, opaque_type, name) 39 | obj.operation_policy_name = opts.operation_policy_name 40 | 41 | # Build the client and connect to the server 42 | with client.ProxyKmipClient( 43 | config=config, 44 | config_file=opts.config_file 45 | ) as client: 46 | try: 47 | uid = client.register(obj) 48 | logger.info("Successfully registered opaque object with ID: " 49 | "{0}".format(uid)) 50 | except Exception as e: 51 | logger.error(e) 52 | -------------------------------------------------------------------------------- /kmip/demos/pie/register_public_key.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2015 The Johns Hopkins University/Applied Physics Laboratory 2 | # All Rights Reserved. 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); you may 5 | # not use this file except in compliance with the License. You may obtain 6 | # a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | # License for the specific language governing permissions and limitations 14 | # under the License. 15 | 16 | import logging 17 | import sys 18 | 19 | from kmip.core import enums 20 | from kmip.demos import utils 21 | 22 | from kmip.pie import client 23 | from kmip.pie import objects 24 | 25 | 26 | if __name__ == '__main__': 27 | logger = utils.build_console_logger(logging.INFO) 28 | 29 | parser = utils.build_cli_parser(enums.Operation.REGISTER) 30 | opts, args = parser.parse_args(sys.argv[1:]) 31 | 32 | config = opts.config 33 | 34 | algorithm = enums.CryptographicAlgorithm.RSA 35 | length = 2048 36 | value = ( 37 | b'\x30\x82\x01\x0A\x02\x82\x01\x01\x00\xAB\x7F\x16\x1C\x00\x42\x49' 38 | b'\x6C\xCD\x6C\x6D\x4D\xAD\xB9\x19\x97\x34\x35\x35\x77\x76\x00\x3A' 39 | b'\xCF\x54\xB7\xAF\x1E\x44\x0A\xFB\x80\xB6\x4A\x87\x55\xF8\x00\x2C' 40 | b'\xFE\xBA\x6B\x18\x45\x40\xA2\xD6\x60\x86\xD7\x46\x48\x34\x6D\x75' 41 | b'\xB8\xD7\x18\x12\xB2\x05\x38\x7C\x0F\x65\x83\xBC\x4D\x7D\xC7\xEC' 42 | b'\x11\x4F\x3B\x17\x6B\x79\x57\xC4\x22\xE7\xD0\x3F\xC6\x26\x7F\xA2' 43 | b'\xA6\xF8\x9B\x9B\xEE\x9E\x60\xA1\xD7\xC2\xD8\x33\xE5\xA5\xF4\xBB' 44 | b'\x0B\x14\x34\xF4\xE7\x95\xA4\x11\x00\xF8\xAA\x21\x49\x00\xDF\x8B' 45 | b'\x65\x08\x9F\x98\x13\x5B\x1C\x67\xB7\x01\x67\x5A\xBD\xBC\x7D\x57' 46 | b'\x21\xAA\xC9\xD1\x4A\x7F\x08\x1F\xCE\xC8\x0B\x64\xE8\xA0\xEC\xC8' 47 | b'\x29\x53\x53\xC7\x95\x32\x8A\xBF\x70\xE1\xB4\x2E\x7B\xB8\xB7\xF4' 48 | b'\xE8\xAC\x8C\x81\x0C\xDB\x66\xE3\xD2\x11\x26\xEB\xA8\xDA\x7D\x0C' 49 | b'\xA3\x41\x42\xCB\x76\xF9\x1F\x01\x3D\xA8\x09\xE9\xC1\xB7\xAE\x64' 50 | b'\xC5\x41\x30\xFB\xC2\x1D\x80\xE9\xC2\xCB\x06\xC5\xC8\xD7\xCC\xE8' 51 | b'\x94\x6A\x9A\xC9\x9B\x1C\x28\x15\xC3\x61\x2A\x29\xA8\x2D\x73\xA1' 52 | b'\xF9\x93\x74\xFE\x30\xE5\x49\x51\x66\x2A\x6E\xDA\x29\xC6\xFC\x41' 53 | b'\x13\x35\xD5\xDC\x74\x26\xB0\xF6\x05\x02\x03\x01\x00\x01') 54 | format_type = enums.KeyFormatType.X_509 55 | usage_mask = [enums.CryptographicUsageMask.VERIFY] 56 | name = 'Demo Public Key' 57 | 58 | key = objects.PublicKey( 59 | algorithm, length, value, format_type, usage_mask, name) 60 | key.operation_policy_name = opts.operation_policy_name 61 | 62 | # Build the client and connect to the server 63 | with client.ProxyKmipClient( 64 | config=config, 65 | config_file=opts.config_file 66 | ) as client: 67 | try: 68 | uid = client.register(key) 69 | logger.info("Successfully registered public key with ID: " 70 | "{0}".format(uid)) 71 | except Exception as e: 72 | logger.error(e) 73 | -------------------------------------------------------------------------------- /kmip/demos/pie/register_secret_data.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2015 The Johns Hopkins University/Applied Physics Laboratory 2 | # All Rights Reserved. 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); you may 5 | # not use this file except in compliance with the License. You may obtain 6 | # a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | # License for the specific language governing permissions and limitations 14 | # under the License. 15 | 16 | 17 | import logging 18 | import sys 19 | 20 | from kmip.core import enums 21 | from kmip.demos import utils 22 | 23 | from kmip.pie import client 24 | from kmip.pie import objects 25 | 26 | 27 | if __name__ == '__main__': 28 | logger = utils.build_console_logger(logging.INFO) 29 | 30 | parser = utils.build_cli_parser(enums.Operation.REGISTER) 31 | opts, args = parser.parse_args(sys.argv[1:]) 32 | 33 | config = opts.config 34 | 35 | value = (b'\x53\x65\x63\x72\x65\x74\x50\x61\x73\x73\x77\x6F\x72\x64') 36 | data_type = enums.SecretDataType.PASSWORD 37 | usage_mask = [enums.CryptographicUsageMask.VERIFY] 38 | name = 'Demo Secret Data' 39 | 40 | secret = objects.SecretData(value, data_type, None, usage_mask, name) 41 | secret.operation_policy_name = opts.operation_policy_name 42 | 43 | # Build the client and connect to the server 44 | with client.ProxyKmipClient( 45 | config=config, 46 | config_file=opts.config_file 47 | ) as client: 48 | try: 49 | uid = client.register(secret) 50 | logger.info( 51 | "Successfully registered secret data with ID: {0}".format(uid)) 52 | except Exception as e: 53 | logger.error(e) 54 | -------------------------------------------------------------------------------- /kmip/demos/pie/register_split_key.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2019 The Johns Hopkins University/Applied Physics Laboratory 2 | # All Rights Reserved. 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); you may 5 | # not use this file except in compliance with the License. You may obtain 6 | # a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | # License for the specific language governing permissions and limitations 14 | # under the License. 15 | 16 | import logging 17 | import sys 18 | 19 | from kmip.core import enums 20 | from kmip.demos import utils 21 | 22 | from kmip.pie import client 23 | from kmip.pie import objects 24 | 25 | 26 | if __name__ == '__main__': 27 | logger = utils.build_console_logger(logging.INFO) 28 | 29 | parser = utils.build_cli_parser(enums.Operation.REGISTER) 30 | opts, args = parser.parse_args(sys.argv[1:]) 31 | 32 | config = opts.config 33 | 34 | split_key = objects.SplitKey( 35 | cryptographic_algorithm=enums.CryptographicAlgorithm.AES, 36 | cryptographic_length=128, 37 | key_value=( 38 | b'\x66\xC4\x6A\x77\x54\xF9\x4D\xE4' 39 | b'\x20\xC7\xB1\xA7\xFF\xF5\xEC\x56' 40 | ), 41 | name="Demo Split Key", 42 | cryptographic_usage_masks=[enums.CryptographicUsageMask.EXPORT], 43 | key_format_type=enums.KeyFormatType.RAW, 44 | key_wrapping_data=None, 45 | split_key_parts=4, 46 | key_part_identifier=1, 47 | split_key_threshold=2, 48 | split_key_method=enums.SplitKeyMethod.XOR, 49 | prime_field_size=None 50 | ) 51 | split_key.operation_policy_name = opts.operation_policy_name 52 | 53 | # Build the client and connect to the server 54 | with client.ProxyKmipClient( 55 | config=config, 56 | config_file=opts.config_file 57 | ) as client: 58 | try: 59 | uid = client.register(split_key) 60 | logger.info( 61 | "Successfully registered split key with ID: {0}".format(uid) 62 | ) 63 | except Exception as e: 64 | logger.error(e) 65 | -------------------------------------------------------------------------------- /kmip/demos/pie/register_symmetric_key.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2015 The Johns Hopkins University/Applied Physics Laboratory 2 | # All Rights Reserved. 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); you may 5 | # not use this file except in compliance with the License. You may obtain 6 | # a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | # License for the specific language governing permissions and limitations 14 | # under the License. 15 | 16 | import logging 17 | import sys 18 | 19 | from kmip.core import enums 20 | from kmip.demos import utils 21 | 22 | from kmip.pie import client 23 | from kmip.pie import objects 24 | 25 | 26 | if __name__ == '__main__': 27 | logger = utils.build_console_logger(logging.INFO) 28 | 29 | parser = utils.build_cli_parser(enums.Operation.REGISTER) 30 | opts, args = parser.parse_args(sys.argv[1:]) 31 | 32 | config = opts.config 33 | 34 | algorithm = enums.CryptographicAlgorithm.AES 35 | length = 128 36 | value = ( 37 | b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B\x0C\x0D\x0E' 38 | b'\x0F') 39 | usage_mask = [enums.CryptographicUsageMask.ENCRYPT, 40 | enums.CryptographicUsageMask.DECRYPT] 41 | name = 'Demo Symmetric Key' 42 | 43 | key = objects.SymmetricKey(algorithm, length, value, usage_mask, name) 44 | key.operation_policy_name = opts.operation_policy_name 45 | 46 | # Build the client and connect to the server 47 | with client.ProxyKmipClient( 48 | config=config, 49 | config_file=opts.config_file 50 | ) as client: 51 | try: 52 | uid = client.register(key) 53 | logger.info("Successfully registered symmetric key with ID: " 54 | "{0}".format(uid)) 55 | except Exception as e: 56 | logger.error(e) 57 | -------------------------------------------------------------------------------- /kmip/demos/pie/revoke.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2015 The Johns Hopkins University/Applied Physics Laboratory 2 | # All Rights Reserved. 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); you may 5 | # not use this file except in compliance with the License. You may obtain 6 | # a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | # License for the specific language governing permissions and limitations 14 | # under the License. 15 | 16 | import logging 17 | import sys 18 | import time 19 | 20 | from kmip.core import enums 21 | from kmip.demos import utils 22 | from kmip.pie import client 23 | 24 | 25 | if __name__ == '__main__': 26 | logger = utils.build_console_logger(logging.INFO) 27 | 28 | # Build and parse arguments 29 | parser = utils.build_cli_parser(enums.Operation.REVOKE) 30 | opts, args = parser.parse_args(sys.argv[1:]) 31 | 32 | config = opts.config 33 | uid = opts.uuid 34 | 35 | # Exit early if the UUID is not specified 36 | if uid is None: 37 | logger.error('No UUID provided, exiting early from demo') 38 | sys.exit() 39 | 40 | # Build the client and connect to the server 41 | with client.ProxyKmipClient( 42 | config=config, 43 | config_file=opts.config_file 44 | ) as client: 45 | try: 46 | client.revoke( 47 | enums.RevocationReasonCode.KEY_COMPROMISE, 48 | uid=uid, 49 | revocation_message="I want to revoke this secret.", 50 | compromise_occurrence_date=int(time.time()) 51 | ) 52 | logger.info( 53 | "Successfully revoked secret with ID: {0}".format(uid) 54 | ) 55 | except Exception as e: 56 | logger.error(e) 57 | -------------------------------------------------------------------------------- /kmip/demos/pie/set_attribute.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2019 The Johns Hopkins University/Applied Physics Laboratory 2 | # All Rights Reserved. 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); you may 5 | # not use this file except in compliance with the License. You may obtain 6 | # a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | # License for the specific language governing permissions and limitations 14 | # under the License. 15 | 16 | import logging 17 | import sys 18 | 19 | from kmip.core.factories import attributes 20 | from kmip.core import enums 21 | from kmip.demos import utils 22 | 23 | from kmip.pie import client 24 | 25 | 26 | # NOTE: This demo script shows how to set the Sensitive attribute on 27 | # the user-specified object. The server must support KMIP 2.0, since 28 | # the SetAttribute operation is KMIP 2.0+ only and the Sensitive 29 | # attribute is KMIP 1.4+ only. Otherwise, the client call to 30 | # set_attribute will fail. 31 | 32 | if __name__ == '__main__': 33 | logger = utils.build_console_logger(logging.INFO) 34 | 35 | parser = utils.build_cli_parser(enums.Operation.SET_ATTRIBUTE) 36 | opts, args = parser.parse_args(sys.argv[1:]) 37 | 38 | if opts.uuid is None: 39 | logger.error("No UUID provided, existing early from demo.") 40 | sys.exit() 41 | 42 | factory = attributes.AttributeFactory() 43 | 44 | with client.ProxyKmipClient( 45 | config=opts.config, 46 | config_file=opts.config_file, 47 | kmip_version=enums.KMIPVersion.KMIP_2_0 48 | ) as c: 49 | try: 50 | object_id = c.set_attribute( 51 | unique_identifier=opts.uuid, 52 | attribute_name="Sensitive", 53 | attribute_value=True 54 | ) 55 | logger.info( 56 | "Successfully set the 'Sensitive' attribute on object: " 57 | "{}".format( 58 | object_id 59 | ) 60 | ) 61 | except Exception as e: 62 | logger.error(e) 63 | -------------------------------------------------------------------------------- /kmip/demos/units/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OpenKMIP/PyKMIP/6cd44b572b0ca55adf01a8a12078b2284602e64c/kmip/demos/units/__init__.py -------------------------------------------------------------------------------- /kmip/demos/units/activate.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2015 The Johns Hopkins University/Applied Physics Laboratory 2 | # All Rights Reserved. 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); you may 5 | # not use this file except in compliance with the License. You may obtain 6 | # a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | # License for the specific language governing permissions and limitations 14 | # under the License. 15 | 16 | from kmip.core.enums import Operation 17 | from kmip.core.enums import ResultStatus 18 | 19 | from kmip.demos import utils 20 | 21 | from kmip.services.kmip_client import KMIPProxy 22 | 23 | import logging 24 | import sys 25 | 26 | 27 | if __name__ == '__main__': 28 | logger = utils.build_console_logger(logging.INFO) 29 | 30 | # Build and parse arguments 31 | parser = utils.build_cli_parser(Operation.ACTIVATE) 32 | opts, args = parser.parse_args(sys.argv[1:]) 33 | 34 | config = opts.config 35 | uuid = opts.uuid 36 | 37 | # Exit early if the UUID is not specified 38 | if uuid is None: 39 | logger.error('No UUID provided, exiting early from demo') 40 | sys.exit() 41 | 42 | # Build the client and connect to the server 43 | client = KMIPProxy(config=config, config_file=opts.config_file) 44 | client.open() 45 | 46 | # Activate the object 47 | result = client.activate(uuid) 48 | client.close() 49 | 50 | # Display operation results 51 | logger.info('activate() result status: {0}'.format( 52 | result.result_status.value)) 53 | 54 | if result.result_status.value == ResultStatus.SUCCESS: 55 | logger.info('activated UUID: {0}'.format(result.uuid.value)) 56 | else: 57 | logger.info('activate() result reason: {0}'.format( 58 | result.result_reason.value)) 59 | logger.info('activate() result message: {0}'.format( 60 | result.result_message.value)) 61 | -------------------------------------------------------------------------------- /kmip/demos/units/destroy.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2014 The Johns Hopkins University/Applied Physics Laboratory 2 | # All Rights Reserved. 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); you may 5 | # not use this file except in compliance with the License. You may obtain 6 | # a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | # License for the specific language governing permissions and limitations 14 | # under the License. 15 | 16 | from kmip.core.enums import CredentialType 17 | from kmip.core.enums import Operation 18 | from kmip.core.enums import ResultStatus 19 | 20 | from kmip.core.factories.attributes import AttributeFactory 21 | from kmip.core.factories.credentials import CredentialFactory 22 | 23 | from kmip.demos import utils 24 | 25 | from kmip.services.kmip_client import KMIPProxy 26 | 27 | import logging 28 | import sys 29 | 30 | 31 | if __name__ == '__main__': 32 | logger = utils.build_console_logger(logging.INFO) 33 | 34 | # Build and parse arguments 35 | parser = utils.build_cli_parser(Operation.DESTROY) 36 | opts, args = parser.parse_args(sys.argv[1:]) 37 | 38 | username = opts.username 39 | password = opts.password 40 | config = opts.config 41 | uuid = opts.uuid 42 | 43 | # Exit early if the UUID is not specified 44 | if uuid is None: 45 | logger.error('No UUID provided, exiting early from demo') 46 | sys.exit() 47 | 48 | attribute_factory = AttributeFactory() 49 | credential_factory = CredentialFactory() 50 | 51 | # Build the KMIP server account credentials 52 | # TODO (peter-hamilton) Move up into KMIPProxy 53 | if (username is None) and (password is None): 54 | credential = None 55 | else: 56 | credential_type = CredentialType.USERNAME_AND_PASSWORD 57 | credential_value = {'Username': username, 58 | 'Password': password} 59 | credential = credential_factory.create_credential(credential_type, 60 | credential_value) 61 | # Build the client and connect to the server 62 | client = KMIPProxy(config=config, config_file=opts.config_file) 63 | client.open() 64 | 65 | # Destroy the SYMMETRIC_KEY object 66 | result = client.destroy(uuid, credential) 67 | client.close() 68 | 69 | # Display operation results 70 | logger.info('destroy() result status: {0}'.format( 71 | result.result_status.value)) 72 | 73 | if result.result_status.value == ResultStatus.SUCCESS: 74 | logger.info('destroyed UUID: {0}'.format(result.uuid.value)) 75 | else: 76 | logger.info('destroy() result reason: {0}'.format( 77 | result.result_reason.value)) 78 | logger.info('destroy() result message: {0}'.format( 79 | result.result_message.value)) 80 | -------------------------------------------------------------------------------- /kmip/demos/units/discover_versions.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2015 The Johns Hopkins University/Applied Physics Laboratory 2 | # All Rights Reserved. 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); you may 5 | # not use this file except in compliance with the License. You may obtain 6 | # a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | # License for the specific language governing permissions and limitations 14 | # under the License. 15 | 16 | from kmip.core.enums import Operation 17 | from kmip.core.enums import ResultStatus 18 | 19 | from kmip.core.messages.contents import ProtocolVersion 20 | 21 | from kmip.demos import utils 22 | 23 | from kmip.services.kmip_client import KMIPProxy 24 | 25 | import logging 26 | import sys 27 | import re 28 | 29 | 30 | if __name__ == '__main__': 31 | logger = utils.build_console_logger(logging.INFO) 32 | 33 | # Build and parse arguments 34 | parser = utils.build_cli_parser(Operation.DISCOVER_VERSIONS) 35 | opts, args = parser.parse_args(sys.argv[1:]) 36 | 37 | username = opts.username 38 | password = opts.password 39 | config = opts.config 40 | 41 | protocol_versions = list() 42 | if opts.protocol_versions is not None: 43 | for version in re.split(',| ', opts.protocol_versions): 44 | mm = re.split(r'\.', version) 45 | protocol_versions.append(ProtocolVersion(int(mm[0]), int(mm[1]))) 46 | 47 | # Build the client and connect to the server 48 | client = KMIPProxy(config=config, config_file=opts.config_file) 49 | client.open() 50 | 51 | result = client.discover_versions(protocol_versions=protocol_versions) 52 | client.close() 53 | 54 | # Display operation results 55 | logger.info('discover_versions() result status: {0}'.format( 56 | result.result_status.value)) 57 | 58 | if result.result_status.value == ResultStatus.SUCCESS: 59 | protocol_versions = result.protocol_versions 60 | if isinstance(protocol_versions, list): 61 | logger.info('number of protocol versions returned: {0}'.format( 62 | len(protocol_versions))) 63 | for protocol_version in protocol_versions: 64 | logger.info('protocol version supported: {0}'.format( 65 | protocol_version)) 66 | else: 67 | logger.info('number of protocol versions returned: 0') 68 | else: 69 | logger.info('discover_versions() result reason: {0}'.format( 70 | result.result_reason.value)) 71 | logger.info('discover_versions() result message: {0}'.format( 72 | result.result_message.value)) 73 | -------------------------------------------------------------------------------- /kmip/demos/units/get.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2014 The Johns Hopkins University/Applied Physics Laboratory 2 | # All Rights Reserved. 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); you may 5 | # not use this file except in compliance with the License. You may obtain 6 | # a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | # License for the specific language governing permissions and limitations 14 | # under the License. 15 | 16 | from kmip.core.enums import CredentialType 17 | from kmip.core.enums import KeyFormatType as KeyFormatTypeEnum 18 | from kmip.core.enums import Operation 19 | from kmip.core.enums import ResultStatus 20 | 21 | from kmip.core.factories.attributes import AttributeFactory 22 | from kmip.core.factories.credentials import CredentialFactory 23 | 24 | from kmip.core.misc import KeyFormatType 25 | 26 | from kmip.demos import utils 27 | 28 | from kmip.services.kmip_client import KMIPProxy 29 | 30 | import logging 31 | import sys 32 | 33 | 34 | if __name__ == '__main__': 35 | logger = utils.build_console_logger(logging.INFO) 36 | 37 | # Build and parse arguments 38 | parser = utils.build_cli_parser(Operation.GET) 39 | opts, args = parser.parse_args(sys.argv[1:]) 40 | 41 | username = opts.username 42 | password = opts.password 43 | config = opts.config 44 | uuid = opts.uuid 45 | format_type = opts.format 46 | 47 | # Exit early if the UUID is not specified 48 | if uuid is None: 49 | logger.error('No UUID provided, exiting early from demo') 50 | sys.exit() 51 | 52 | format_type_enum = None 53 | if format_type is not None: 54 | format_type_enum = getattr(KeyFormatTypeEnum, format_type, None) 55 | 56 | if format_type_enum is None: 57 | logger.error( 58 | "Invalid key format type specified; exiting early from demo") 59 | sys.exit() 60 | 61 | attribute_factory = AttributeFactory() 62 | credential_factory = CredentialFactory() 63 | 64 | # Build the KMIP server account credentials 65 | # TODO (peter-hamilton) Move up into KMIPProxy 66 | if (username is None) and (password is None): 67 | credential = None 68 | else: 69 | credential_type = CredentialType.USERNAME_AND_PASSWORD 70 | credential_value = {'Username': username, 71 | 'Password': password} 72 | credential = credential_factory.create_credential(credential_type, 73 | credential_value) 74 | 75 | key_format_type = None 76 | if format_type_enum is not None: 77 | key_format_type = KeyFormatType(format_type_enum) 78 | 79 | # Build the client and connect to the server 80 | client = KMIPProxy(config=config, config_file=opts.config_file) 81 | client.open() 82 | 83 | # Retrieve the SYMMETRIC_KEY object 84 | result = client.get(uuid=uuid, key_format_type=key_format_type, 85 | credential=credential) 86 | client.close() 87 | 88 | # Display operation results 89 | logger.info('get() result status: {0}'.format( 90 | result.result_status.value)) 91 | 92 | if result.result_status.value == ResultStatus.SUCCESS: 93 | logger.info('retrieved object type: {0}'.format( 94 | result.object_type.value)) 95 | logger.info('retrieved UUID: {0}'.format(result.uuid)) 96 | 97 | utils.log_secret(logger, result.object_type, result.secret) 98 | else: 99 | logger.info('get() result reason: {0}'.format( 100 | result.result_reason.value)) 101 | logger.info('get() result message: {0}'.format( 102 | result.result_message.value)) 103 | -------------------------------------------------------------------------------- /kmip/demos/units/query.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2015 The Johns Hopkins University/Applied Physics Laboratory 2 | # All Rights Reserved. 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); you may 5 | # not use this file except in compliance with the License. You may obtain 6 | # a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | # License for the specific language governing permissions and limitations 14 | # under the License. 15 | 16 | import logging 17 | import sys 18 | 19 | from six.moves import xrange 20 | 21 | from kmip.core import enums 22 | 23 | from kmip.demos import utils 24 | 25 | from kmip.services.kmip_client import KMIPProxy 26 | 27 | 28 | if __name__ == '__main__': 29 | logger = utils.build_console_logger(logging.INFO) 30 | 31 | # Build and parse arguments 32 | parser = utils.build_cli_parser(enums.Operation.QUERY) 33 | opts, args = parser.parse_args(sys.argv[1:]) 34 | 35 | username = opts.username 36 | password = opts.password 37 | config = opts.config 38 | 39 | # Build query function list. 40 | query_functions = list() 41 | query_functions.append(enums.QueryFunction.QUERY_OPERATIONS) 42 | query_functions.append(enums.QueryFunction.QUERY_OBJECTS) 43 | query_functions.append(enums.QueryFunction.QUERY_SERVER_INFORMATION) 44 | query_functions.append(enums.QueryFunction.QUERY_APPLICATION_NAMESPACES) 45 | query_functions.append(enums.QueryFunction.QUERY_EXTENSION_LIST) 46 | query_functions.append(enums.QueryFunction.QUERY_EXTENSION_MAP) 47 | 48 | # Build the client and connect to the server 49 | client = KMIPProxy( 50 | config=config, 51 | config_file=opts.config_file 52 | ) 53 | client.open() 54 | 55 | result = client.query(query_functions=query_functions) 56 | client.close() 57 | 58 | # Display operation results 59 | logger.info('query() result status: {0}'.format( 60 | result.result_status.value)) 61 | 62 | if result.result_status.value == enums.ResultStatus.SUCCESS: 63 | operations = result.operations 64 | object_types = result.object_types 65 | vendor_identification = result.vendor_identification 66 | server_information = result.server_information 67 | application_namespaces = result.application_namespaces 68 | extension_information = result.extension_information 69 | 70 | logger.info('number of operations supported: {0}'.format( 71 | len(operations))) 72 | for i in xrange(len(operations)): 73 | logger.info('operation supported: {0}'.format(operations[i])) 74 | 75 | logger.info('number of object types supported: {0}'.format( 76 | len(object_types))) 77 | for i in xrange(len(object_types)): 78 | logger.info('object type supported: {0}'.format(object_types[i])) 79 | 80 | logger.info('vendor identification: {0}'.format(vendor_identification)) 81 | logger.info('server information: {0}'.format(server_information)) 82 | 83 | logger.info('number of application namespaces supported: {0}'.format( 84 | len(application_namespaces))) 85 | for i in xrange(len(application_namespaces)): 86 | logger.info('application namespace supported: {0}'.format( 87 | application_namespaces[i])) 88 | 89 | logger.info('number of extensions supported: {0}'.format( 90 | len(extension_information))) 91 | for i in xrange(len(extension_information)): 92 | logger.info('extension supported: {0}'.format( 93 | extension_information[i])) 94 | 95 | else: 96 | logger.info('query() result reason: {0}'.format( 97 | result.result_reason.value)) 98 | logger.info('query() result message: {0}'.format( 99 | result.result_message.value)) 100 | -------------------------------------------------------------------------------- /kmip/demos/units/register.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2014 The Johns Hopkins University/Applied Physics Laboratory 2 | # All Rights Reserved. 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); you may 5 | # not use this file except in compliance with the License. You may obtain 6 | # a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | # License for the specific language governing permissions and limitations 14 | # under the License. 15 | 16 | from kmip.core import enums 17 | from kmip.core.enums import KeyFormatType 18 | from kmip.core.enums import ObjectType 19 | from kmip.core.enums import Operation 20 | from kmip.core.enums import ResultStatus 21 | 22 | from kmip.core.factories.attributes import AttributeFactory 23 | from kmip.core.objects import TemplateAttribute 24 | 25 | from kmip.demos import utils 26 | 27 | from kmip.services.kmip_client import KMIPProxy 28 | 29 | import logging 30 | import sys 31 | 32 | 33 | if __name__ == '__main__': 34 | logger = utils.build_console_logger(logging.INFO) 35 | 36 | parser = utils.build_cli_parser(Operation.REGISTER) 37 | opts, args = parser.parse_args(sys.argv[1:]) 38 | 39 | username = opts.username 40 | password = opts.password 41 | config = opts.config 42 | object_type = opts.type 43 | format_type = opts.format 44 | 45 | # Exit early if the arguments are not specified 46 | object_type = getattr(ObjectType, object_type, None) 47 | if object_type is None: 48 | logger.error("Invalid object type specified; exiting early from demo") 49 | sys.exit() 50 | 51 | key_format_type = getattr(KeyFormatType, format_type, None) 52 | if key_format_type is None: 53 | logger.error( 54 | "Invalid key format type specified; exiting early from demo") 55 | 56 | attribute_factory = AttributeFactory() 57 | 58 | # Create the template attribute for the secret and then build the secret 59 | usage_mask = utils.build_cryptographic_usage_mask(logger, object_type) 60 | attributes = [usage_mask] 61 | 62 | if opts.operation_policy_name is not None: 63 | opn = attribute_factory.create_attribute( 64 | enums.AttributeType.OPERATION_POLICY_NAME, 65 | opts.operation_policy_name 66 | ) 67 | attributes.append(opn) 68 | 69 | template_attribute = TemplateAttribute(attributes=attributes) 70 | 71 | secret = utils.build_object(logger, object_type, key_format_type) 72 | 73 | # Build the client, connect to the server, register the secret, and 74 | # disconnect from the server 75 | client = KMIPProxy(config=config, config_file=opts.config_file) 76 | 77 | client.open() 78 | result = client.register(object_type, template_attribute, secret) 79 | client.close() 80 | 81 | # Display operation results 82 | logger.info('register() result status: {0}'.format( 83 | result.result_status.value)) 84 | 85 | if result.result_status.value == ResultStatus.SUCCESS: 86 | logger.info('registered UUID: {0}'.format(result.uuid)) 87 | logger.info('registered template attribute: {0}'. 88 | format(result.template_attribute)) 89 | else: 90 | logger.info('register() result reason: {0}'.format( 91 | result.result_reason.value)) 92 | logger.info('register() result message: {0}'.format( 93 | result.result_message.value)) 94 | -------------------------------------------------------------------------------- /kmip/demos/units/revoke.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2015 The Johns Hopkins University/Applied Physics Laboratory 2 | # All Rights Reserved. 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); you may 5 | # not use this file except in compliance with the License. You may obtain 6 | # a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | # License for the specific language governing permissions and limitations 14 | # under the License. 15 | 16 | from kmip.core import enums 17 | from kmip.core.enums import Operation 18 | from kmip.core.enums import ResultStatus 19 | 20 | from kmip.demos import utils 21 | 22 | from kmip.services.kmip_client import KMIPProxy 23 | 24 | import logging 25 | import sys 26 | 27 | 28 | if __name__ == '__main__': 29 | logger = utils.build_console_logger(logging.INFO) 30 | 31 | # Build and parse arguments 32 | parser = utils.build_cli_parser(Operation.REVOKE) 33 | opts, args = parser.parse_args(sys.argv[1:]) 34 | 35 | config = opts.config 36 | uuid = opts.uuid 37 | 38 | # Exit early if the UUID is not specified 39 | if uuid is None: 40 | logger.error('No UUID provided, exiting early from demo') 41 | sys.exit() 42 | 43 | # Build the client and connect to the server 44 | client = KMIPProxy(config=config, config_file=opts.config_file) 45 | client.open() 46 | 47 | # Activate the object 48 | result = client.revoke( 49 | enums.RevocationReasonCode.KEY_COMPROMISE, 50 | uuid, 51 | 'Demo revocation message') 52 | client.close() 53 | 54 | # Display operation results 55 | logger.info('revoke() result status: {0}'.format( 56 | result.result_status.value)) 57 | 58 | if result.result_status.value == ResultStatus.SUCCESS: 59 | logger.info('revoked UUID: {0}'.format(result.unique_identifier.value)) 60 | else: 61 | logger.info('revoke() result reason: {0}'.format( 62 | result.result_reason.value)) 63 | logger.info('revoke() result message: {0}'.format( 64 | result.result_message.value)) 65 | -------------------------------------------------------------------------------- /kmip/pie/__init__.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2015 The Johns Hopkins University/Applied Physics Laboratory 2 | # All Rights Reserved. 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); you may 5 | # not use this file except in compliance with the License. You may obtain 6 | # a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | # License for the specific language governing permissions and limitations 14 | # under the License. 15 | 16 | from kmip.pie.client import ProxyKmipClient 17 | 18 | 19 | __all__ = [ 20 | "ProxyKmipClient" 21 | ] 22 | -------------------------------------------------------------------------------- /kmip/pie/exceptions.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2015 The Johns Hopkins University/Applied Physics Laboratory 2 | # All Rights Reserved. 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); you may 5 | # not use this file except in compliance with the License. You may obtain 6 | # a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | # License for the specific language governing permissions and limitations 14 | # under the License. 15 | 16 | 17 | class ClientConnectionFailure(Exception): 18 | """ 19 | An exception raised for errors with the client socket connection. 20 | """ 21 | pass 22 | 23 | 24 | class ClientConnectionNotOpen(Exception): 25 | """ 26 | An exception raised when operations are issued to a closed connection. 27 | """ 28 | def __init__(self): 29 | """ 30 | Construct the closed client connection error message. 31 | """ 32 | super(ClientConnectionNotOpen, self).__init__( 33 | "client connection not open") 34 | 35 | 36 | class KmipOperationFailure(Exception): 37 | """ 38 | An exception raised upon the failure of a KMIP appliance operation. 39 | """ 40 | def __init__(self, status, reason, message): 41 | """ 42 | Construct the error message and attributes for the KMIP operation 43 | failure. 44 | 45 | Args: 46 | status: a ResultStatus enumeration 47 | reason: a ResultReason enumeration 48 | message: a string providing additional error information 49 | """ 50 | msg = "{0}: {1} - {2}".format(status.name, reason.name, message) 51 | super(KmipOperationFailure, self).__init__(msg) 52 | self.status = status 53 | self.reason = reason 54 | self.message = message 55 | -------------------------------------------------------------------------------- /kmip/services/__init__.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2014 The Johns Hopkins University/Applied Physics Laboratory 2 | # All Rights Reserved. 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); you may 5 | # not use this file except in compliance with the License. You may obtain 6 | # a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | # License for the specific language governing permissions and limitations 14 | # under the License. 15 | -------------------------------------------------------------------------------- /kmip/services/kmip_protocol.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2014 The Johns Hopkins University/Applied Physics Laboratory 2 | # All Rights Reserved. 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); you may 5 | # not use this file except in compliance with the License. You may obtain 6 | # a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | # License for the specific language governing permissions and limitations 14 | # under the License. 15 | 16 | from struct import unpack 17 | 18 | import binascii 19 | import logging 20 | 21 | from kmip.core.utils import BytearrayStream 22 | 23 | 24 | class KMIPProtocol(object): 25 | HEADER_SIZE = 8 26 | 27 | def __init__(self, socket, buffer_size=1024): 28 | self.socket = socket 29 | self.logger = logging.getLogger(__name__) 30 | # DEBUG logging here may expose secrets, so log at INFO by default. 31 | # However, if consumers know the risks, let them go ahead and override. 32 | if self.logger.level == logging.NOTSET: 33 | self.logger.setLevel(logging.INFO) 34 | 35 | def write(self, data): 36 | if len(data) > 0: 37 | sbuffer = bytes(data) 38 | self.logger.debug('KMIPProtocol.write: {0}'.format( 39 | binascii.hexlify(sbuffer))) 40 | self.socket.sendall(sbuffer) 41 | 42 | def read(self): 43 | try: 44 | header = self._recv_all(self.HEADER_SIZE) 45 | except RequestLengthMismatch as e: 46 | if e.received == 0: 47 | raise EOFError("No data read from socket") 48 | else: 49 | raise 50 | msg_size = unpack('!I', header[4:])[0] 51 | 52 | payload = self._recv_all(msg_size) 53 | data = BytearrayStream(header + payload) 54 | self.logger.debug('KMIPProtocol.read: {0}'.format( 55 | binascii.hexlify(bytes(data.buffer)))) 56 | return data 57 | 58 | def _recv_all(self, total_bytes_to_be_read): 59 | bytes_read = 0 60 | total_msg = b'' 61 | while bytes_read < total_bytes_to_be_read: 62 | msg = self.socket.recv(total_bytes_to_be_read - bytes_read) 63 | if not msg: 64 | break 65 | bytes_read += len(msg) 66 | total_msg += msg 67 | if bytes_read != total_bytes_to_be_read: 68 | msg = "expected {0}, received {1} bytes".format( 69 | total_bytes_to_be_read, bytes_read) 70 | raise RequestLengthMismatch(total_bytes_to_be_read, bytes_read) 71 | 72 | return total_msg 73 | 74 | 75 | class KMIPProtocolFactory(object): 76 | 77 | def getProtocol(self, socket): 78 | return KMIPProtocol(socket) 79 | 80 | 81 | class RequestLengthMismatch(Exception): 82 | """ 83 | This exception raised when the request read from stream has unexpected 84 | length. 85 | """ 86 | def __init__(self, expected, received, message="KMIPProtocol read error"): 87 | super(RequestLengthMismatch, self).__init__(message) 88 | self.message = message 89 | self.expected = expected 90 | self.received = received 91 | 92 | def __str__(self): 93 | return "{0}: expected {1}, received {2}".format( 94 | self.message, self.expected, self.received) 95 | 96 | def __repr__(self): 97 | return self.__str__() 98 | -------------------------------------------------------------------------------- /kmip/services/server/__init__.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2015 The Johns Hopkins University/Applied Physics Laboratory 2 | # All Rights Reserved. 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); you may 5 | # not use this file except in compliance with the License. You may obtain 6 | # a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | # License for the specific language governing permissions and limitations 14 | # under the License. 15 | 16 | from kmip.services.server.server import KmipServer 17 | 18 | 19 | __all__ = [ 20 | "KmipServer" 21 | ] 22 | -------------------------------------------------------------------------------- /kmip/services/server/auth/__init__.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2018 The Johns Hopkins University/Applied Physics Laboratory 2 | # All Rights Reserved. 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); you may 5 | # not use this file except in compliance with the License. You may obtain 6 | # a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | # License for the specific language governing permissions and limitations 14 | # under the License. 15 | 16 | from kmip.services.server.auth.api import AuthAPI 17 | from kmip.services.server.auth.slugs import SLUGSConnector 18 | 19 | from kmip.services.server.auth.utils import get_certificate_from_connection 20 | from kmip.services.server.auth.utils import \ 21 | get_client_identity_from_certificate 22 | from kmip.services.server.auth.utils import get_common_names_from_certificate 23 | from kmip.services.server.auth.utils import \ 24 | get_extended_key_usage_from_certificate 25 | 26 | 27 | __all__ = [ 28 | 'AuthAPI', 29 | 'SLUGSConnector', 30 | 'get_certificate_from_connection', 31 | 'get_client_identity_from_certificate', 32 | 'get_common_names_from_certificate', 33 | 'get_extended_key_usage_from_certificate' 34 | ] 35 | -------------------------------------------------------------------------------- /kmip/services/server/auth/api.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2018 The Johns Hopkins University/Applied Physics Laboratory 2 | # All Rights Reserved. 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); you may 5 | # not use this file except in compliance with the License. You may obtain 6 | # a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | # License for the specific language governing permissions and limitations 14 | # under the License. 15 | 16 | import abc 17 | import six 18 | 19 | 20 | @six.add_metaclass(abc.ABCMeta) 21 | class AuthAPI: 22 | """ 23 | The base class for an authentication API connector. 24 | """ 25 | 26 | @abc.abstractmethod 27 | def authenticate(self, 28 | connection_certificate=None, 29 | connection_info=None, 30 | request_credentials=None): 31 | """ 32 | Query the configured authentication service with the given credentials. 33 | 34 | Args: 35 | connection_certificate (cryptography.x509.Certificate): An X.509 36 | certificate object obtained from the connection being 37 | authenticated. Optional, defaults to None. 38 | connection_info (tuple): A tuple of information pertaining to the 39 | connection being authenticated, including the source IP address 40 | and a timestamp (e.g., ('127.0.0.1', 1519759267.467451)). 41 | Optional, defaults to None. 42 | request_credentials (list): A list of KMIP Credential structures 43 | containing credential information to use for authentication. 44 | Optional, defaults to None. 45 | """ 46 | -------------------------------------------------------------------------------- /kmip/services/server/auth/slugs.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2018 The Johns Hopkins University/Applied Physics Laboratory 2 | # All Rights Reserved. 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); you may 5 | # not use this file except in compliance with the License. You may obtain 6 | # a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | # License for the specific language governing permissions and limitations 14 | # under the License. 15 | 16 | import requests 17 | import six 18 | 19 | from kmip.core import exceptions 20 | from kmip.services.server.auth import api 21 | from kmip.services.server.auth import utils 22 | 23 | 24 | class SLUGSConnector(api.AuthAPI): 25 | """ 26 | An authentication API connector for a SLUGS service. 27 | """ 28 | 29 | def __init__(self, url=None): 30 | """ 31 | Construct a SLUGSConnector. 32 | 33 | Args: 34 | url (string): The base URL for the remote SLUGS instance. Optional, 35 | defaults to None. Required for authentication. 36 | """ 37 | self._url = None 38 | self.users_url = None 39 | self.groups_url = None 40 | 41 | self.url = url 42 | 43 | @property 44 | def url(self): 45 | return self._url 46 | 47 | @url.setter 48 | def url(self, value): 49 | if value is None: 50 | self._url = None 51 | self.users_url = None 52 | self.groups_url = None 53 | elif isinstance(value, six.string_types): 54 | self._url = value 55 | if not self._url.endswith("/"): 56 | self._url += "/" 57 | self.users_url = self._url + "users/{}" 58 | self.groups_url = self.users_url + "/groups" 59 | else: 60 | raise TypeError("URL must be a string.") 61 | 62 | def authenticate(self, 63 | connection_certificate=None, 64 | connection_info=None, 65 | request_credentials=None): 66 | """ 67 | Query the configured SLUGS service with the provided credentials. 68 | 69 | Args: 70 | connection_certificate (cryptography.x509.Certificate): An X.509 71 | certificate object obtained from the connection being 72 | authenticated. Required for SLUGS authentication. 73 | connection_info (tuple): A tuple of information pertaining to the 74 | connection being authenticated, including the source IP address 75 | and a timestamp (e.g., ('127.0.0.1', 1519759267.467451)). 76 | Optional, defaults to None. Ignored for SLUGS authentication. 77 | request_credentials (list): A list of KMIP Credential structures 78 | containing credential information to use for authentication. 79 | Optional, defaults to None. Ignored for SLUGS authentication. 80 | """ 81 | if (self.users_url is None) or (self.groups_url is None): 82 | raise exceptions.ConfigurationError( 83 | "The SLUGS URL must be specified." 84 | ) 85 | 86 | user_id = utils.get_client_identity_from_certificate( 87 | connection_certificate 88 | ) 89 | 90 | try: 91 | response = requests.get(self.users_url.format(user_id), timeout=10) 92 | except Exception: 93 | raise exceptions.ConfigurationError( 94 | "A connection could not be established using the SLUGS URL." 95 | ) 96 | if response.status_code == 404: 97 | raise exceptions.PermissionDenied( 98 | "Unrecognized user ID: {}".format(user_id) 99 | ) 100 | 101 | response = requests.get(self.groups_url.format(user_id), timeout=10) 102 | if response.status_code == 404: 103 | raise exceptions.PermissionDenied( 104 | "Group information could not be retrieved for user ID: " 105 | "{}".format(user_id) 106 | ) 107 | 108 | return user_id, response.json().get('groups') 109 | -------------------------------------------------------------------------------- /kmip/services/server/auth/utils.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2018 The Johns Hopkins University/Applied Physics Laboratory 2 | # All Rights Reserved. 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); you may 5 | # not use this file except in compliance with the License. You may obtain 6 | # a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | # License for the specific language governing permissions and limitations 14 | # under the License. 15 | 16 | from cryptography import x509 17 | from cryptography.hazmat import backends 18 | 19 | from kmip.core import exceptions 20 | 21 | 22 | def get_certificate_from_connection(connection): 23 | """ 24 | Extract an X.509 certificate from a socket connection. 25 | """ 26 | certificate = connection.getpeercert(binary_form=True) 27 | if certificate: 28 | return x509.load_der_x509_certificate( 29 | certificate, 30 | backends.default_backend() 31 | ) 32 | return None 33 | 34 | 35 | def get_extended_key_usage_from_certificate(certificate): 36 | """ 37 | Given an X.509 certificate, extract and return the extendedKeyUsage 38 | extension. 39 | """ 40 | try: 41 | return certificate.extensions.get_extension_for_oid( 42 | x509.oid.ExtensionOID.EXTENDED_KEY_USAGE 43 | ).value 44 | except x509.ExtensionNotFound: 45 | return None 46 | 47 | 48 | def get_common_names_from_certificate(certificate): 49 | """ 50 | Given an X.509 certificate, extract and return all common names. 51 | """ 52 | 53 | common_names = certificate.subject.get_attributes_for_oid( 54 | x509.oid.NameOID.COMMON_NAME 55 | ) 56 | return [common_name.value for common_name in common_names] 57 | 58 | 59 | def get_client_identity_from_certificate(certificate): 60 | """ 61 | Given an X.509 certificate, extract and return the client identity. 62 | """ 63 | client_ids = get_common_names_from_certificate(certificate) 64 | 65 | if len(client_ids) > 0: 66 | if len(client_ids) > 1: 67 | raise exceptions.PermissionDenied( 68 | "Multiple client identities found." 69 | ) 70 | return client_ids[0] 71 | else: 72 | raise exceptions.PermissionDenied( 73 | "The certificate does not define any subject common names. " 74 | "Client identity unavailable." 75 | ) 76 | -------------------------------------------------------------------------------- /kmip/services/server/crypto/__init__.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2016 The Johns Hopkins University/Applied Physics Laboratory 2 | # All Rights Reserved. 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); you may 5 | # not use this file except in compliance with the License. You may obtain 6 | # a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | # License for the specific language governing permissions and limitations 14 | # under the License. 15 | 16 | from kmip.services.server.crypto.api import CryptographicEngine 17 | from kmip.services.server.crypto.engine import CryptographyEngine 18 | 19 | __all__ = [ 20 | 'CryptographicEngine', 21 | 'CryptographyEngine', 22 | ] 23 | -------------------------------------------------------------------------------- /kmip/tests/__init__.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2014 The Johns Hopkins University/Applied Physics Laboratory 2 | # All Rights Reserved. 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); you may 5 | # not use this file except in compliance with the License. You may obtain 6 | # a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | # License for the specific language governing permissions and limitations 14 | # under the License. 15 | -------------------------------------------------------------------------------- /kmip/tests/functional/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OpenKMIP/PyKMIP/6cd44b572b0ca55adf01a8a12078b2284602e64c/kmip/tests/functional/__init__.py -------------------------------------------------------------------------------- /kmip/tests/functional/conftest.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2018 The Johns Hopkins University/Applied Physics Laboratory 2 | # All Rights Reserved. 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); you may 5 | # not use this file except in compliance with the License. You may obtain 6 | # a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | # License for the specific language governing permissions and limitations 14 | # under the License. 15 | 16 | import pytest 17 | 18 | 19 | def pytest_addoption(parser): 20 | parser.addoption( 21 | "--config-file", 22 | action="store", 23 | help="Config file path for client configuration settings" 24 | ) 25 | 26 | 27 | @pytest.fixture(scope="class") 28 | def config_file(request): 29 | request.cls.config_file = request.config.getoption("--config-file") 30 | -------------------------------------------------------------------------------- /kmip/tests/functional/services/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OpenKMIP/PyKMIP/6cd44b572b0ca55adf01a8a12078b2284602e64c/kmip/tests/functional/services/__init__.py -------------------------------------------------------------------------------- /kmip/tests/integration/__init__.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2015 The Johns Hopkins University/Applied Physics Laboratory 2 | # All Rights Reserved. 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); you may 5 | # not use this file except in compliance with the License. You may obtain 6 | # a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | # License for the specific language governing permissions and limitations 14 | # under the License. 15 | -------------------------------------------------------------------------------- /kmip/tests/integration/conftest.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2015 The Johns Hopkins University/Applied Physics Laboratory 2 | # All Rights Reserved. 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); you may 5 | # not use this file except in compliance with the License. You may obtain 6 | # a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | # License for the specific language governing permissions and limitations 14 | # under the License. 15 | 16 | import pytest 17 | 18 | from kmip.services import kmip_client 19 | from kmip.pie import client as pclient 20 | 21 | 22 | def pytest_addoption(parser): 23 | parser.addoption( 24 | "--config", 25 | action="store", 26 | default="client", 27 | help="Config file section name for client configuration settings") 28 | 29 | 30 | @pytest.fixture(scope="class") 31 | def client(request): 32 | config = request.config.getoption("--config") 33 | 34 | client = kmip_client.KMIPProxy(config=config) 35 | client.open() 36 | 37 | def finalize(): 38 | client.close() 39 | 40 | request.addfinalizer(finalize) 41 | request.cls.client = client 42 | 43 | 44 | @pytest.fixture(scope="class") 45 | def simple(request): 46 | config = request.config.getoption("--config") 47 | 48 | client = pclient.ProxyKmipClient(config=config) 49 | client.open() 50 | 51 | def finalize(): 52 | client.close() 53 | 54 | request.addfinalizer(finalize) 55 | request.cls.client = client 56 | -------------------------------------------------------------------------------- /kmip/tests/integration/services/__init__.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2015 The Johns Hopkins University/Applied Physics Laboratory 2 | # All Rights Reserved. 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); you may 5 | # not use this file except in compliance with the License. You may obtain 6 | # a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | # License for the specific language governing permissions and limitations 14 | # under the License. 15 | -------------------------------------------------------------------------------- /kmip/tests/unit/__init__.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2015 The Johns Hopkins University/Applied Physics Laboratory 2 | # All Rights Reserved. 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); you may 5 | # not use this file except in compliance with the License. You may obtain 6 | # a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | # License for the specific language governing permissions and limitations 14 | # under the License. 15 | -------------------------------------------------------------------------------- /kmip/tests/unit/core/__init__.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2014 The Johns Hopkins University/Applied Physics Laboratory 2 | # All Rights Reserved. 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); you may 5 | # not use this file except in compliance with the License. You may obtain 6 | # a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | # License for the specific language governing permissions and limitations 14 | # under the License. 15 | -------------------------------------------------------------------------------- /kmip/tests/unit/core/attributes/__init__.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2015 The Johns Hopkins University/Applied Physics Laboratory 2 | # All Rights Reserved. 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); you may 5 | # not use this file except in compliance with the License. You may obtain 6 | # a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | # License for the specific language governing permissions and limitations 14 | # under the License. 15 | -------------------------------------------------------------------------------- /kmip/tests/unit/core/factories/__init__.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2014 The Johns Hopkins University/Applied Physics Laboratory 2 | # All Rights Reserved. 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); you may 5 | # not use this file except in compliance with the License. You may obtain 6 | # a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | # License for the specific language governing permissions and limitations 14 | # under the License. 15 | -------------------------------------------------------------------------------- /kmip/tests/unit/core/factories/payloads/__init__.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2014 The Johns Hopkins University/Applied Physics Laboratory 2 | # All Rights Reserved. 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); you may 5 | # not use this file except in compliance with the License. You may obtain 6 | # a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | # License for the specific language governing permissions and limitations 14 | # under the License. 15 | -------------------------------------------------------------------------------- /kmip/tests/unit/core/factories/test_attribute.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2016 The Johns Hopkins University/Applied Physics Laboratory 2 | # All Rights Reserved. 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); you may 5 | # not use this file except in compliance with the License. You may obtain 6 | # a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | # License for the specific language governing permissions and limitations 14 | # under the License. 15 | 16 | import testtools 17 | 18 | from kmip.core import enums 19 | 20 | from kmip.core.factories import attributes 21 | 22 | 23 | class TestAttributeFactory(testtools.TestCase): 24 | """ 25 | Test suite for Attribute Factory 26 | """ 27 | 28 | def setUp(self): 29 | super(TestAttributeFactory, self).setUp() 30 | self.attribute_factory = attributes.AttributeFactory() 31 | 32 | def tearDown(self): 33 | super(TestAttributeFactory, self).tearDown() 34 | 35 | def test_name_eq(self): 36 | """ 37 | Test that two identical name attributes match 38 | """ 39 | attr_type = enums.AttributeType.NAME 40 | attr_name = "foo" 41 | attr_a = self.attribute_factory.create_attribute(attr_type, attr_name) 42 | attr_b = self.attribute_factory.create_attribute(attr_type, attr_name) 43 | self.assertTrue(attr_a == attr_b) 44 | self.assertFalse(attr_a != attr_b) 45 | -------------------------------------------------------------------------------- /kmip/tests/unit/core/messages/__init__.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2014 The Johns Hopkins University/Applied Physics Laboratory 2 | # All Rights Reserved. 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); you may 5 | # not use this file except in compliance with the License. You may obtain 6 | # a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | # License for the specific language governing permissions and limitations 14 | # under the License. 15 | -------------------------------------------------------------------------------- /kmip/tests/unit/core/messages/contents/__init__.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2015 The Johns Hopkins University/Applied Physics Laboratory 2 | # All Rights Reserved. 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); you may 5 | # not use this file except in compliance with the License. You may obtain 6 | # a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | # License for the specific language governing permissions and limitations 14 | # under the License. 15 | -------------------------------------------------------------------------------- /kmip/tests/unit/core/messages/payloads/__init__.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2014 The Johns Hopkins University/Applied Physics Laboratory 2 | # All Rights Reserved. 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); you may 5 | # not use this file except in compliance with the License. You may obtain 6 | # a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | # License for the specific language governing permissions and limitations 14 | # under the License. 15 | -------------------------------------------------------------------------------- /kmip/tests/unit/core/messages/payloads/test_destroy.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2014 The Johns Hopkins University/Applied Physics Laboratory 2 | # All Rights Reserved. 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); you may 5 | # not use this file except in compliance with the License. You may obtain 6 | # a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | # License for the specific language governing permissions and limitations 14 | # under the License. 15 | -------------------------------------------------------------------------------- /kmip/tests/unit/core/messages/test_operations.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2014 The Johns Hopkins University/Applied Physics Laboratory 2 | # All Rights Reserved. 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); you may 5 | # not use this file except in compliance with the License. You may obtain 6 | # a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | # License for the specific language governing permissions and limitations 14 | # under the License. 15 | -------------------------------------------------------------------------------- /kmip/tests/unit/core/misc/__init__.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2015 The Johns Hopkins University/Applied Physics Laboratory 2 | # All Rights Reserved. 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); you may 5 | # not use this file except in compliance with the License. You may obtain 6 | # a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | # License for the specific language governing permissions and limitations 14 | # under the License. 15 | -------------------------------------------------------------------------------- /kmip/tests/unit/core/objects/__init__.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2015 The Johns Hopkins University/Applied Physics Laboratory 2 | # All Rights Reserved. 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); you may 5 | # not use this file except in compliance with the License. You may obtain 6 | # a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | # License for the specific language governing permissions and limitations 14 | # under the License. 15 | -------------------------------------------------------------------------------- /kmip/tests/unit/core/objects/test_attribute.py: -------------------------------------------------------------------------------- 1 | # Licensed under the Apache License, Version 2.0 (the "License"); you may 2 | # not use this file except in compliance with the License. You may obtain 3 | # a copy of the License at 4 | # 5 | # http://www.apache.org/licenses/LICENSE-2.0 6 | # 7 | # Unless required by applicable law or agreed to in writing, software 8 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 9 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 10 | # License for the specific language governing permissions and limitations 11 | # under the License. 12 | 13 | import testtools 14 | 15 | from kmip.core import attributes 16 | from kmip.core import objects 17 | 18 | 19 | class TestAttribute(testtools.TestCase): 20 | """ 21 | Test suite for the Attribute object. 22 | """ 23 | 24 | def setUp(self): 25 | super(TestAttribute, self).setUp() 26 | 27 | def tearDown(self): 28 | super(TestAttribute, self).tearDown() 29 | 30 | def test_init(self): 31 | """ 32 | Test that an Attribute object can be created. 33 | """ 34 | objects.Attribute() 35 | 36 | def test_init_with_args(self): 37 | self.skipTest('') 38 | 39 | def test_read(self): 40 | self.skipTest('') 41 | 42 | def test_write(self): 43 | self.skipTest('') 44 | 45 | def test_repr(self): 46 | """ 47 | Test that repr can be applied to an Attribute object. 48 | """ 49 | attribute = objects.Attribute( 50 | attribute_name=objects.Attribute.AttributeName('test-name'), 51 | attribute_index=objects.Attribute.AttributeIndex(0), 52 | attribute_value=attributes.CustomAttribute('test-value') 53 | ) 54 | 55 | self.assertEqual( 56 | "Attribute(" 57 | "attribute_name=AttributeName(value='test-name'), " 58 | "attribute_index=AttributeIndex(value=0), " 59 | "attribute_value=CustomAttribute(value='test-value'))", 60 | repr(attribute) 61 | ) 62 | 63 | def test_str(self): 64 | """ 65 | Test that str can be applied to an Attribute object. 66 | """ 67 | attribute = objects.Attribute( 68 | attribute_name=objects.Attribute.AttributeName('test-name'), 69 | attribute_index=objects.Attribute.AttributeIndex(0), 70 | attribute_value=attributes.CustomAttribute('test-value') 71 | ) 72 | 73 | self.assertEqual( 74 | str({ 75 | 'attribute_name': 'test-name', 76 | 'attribute_index': '0', 77 | 'attribute_value': 'test-value' 78 | }), 79 | str(attribute) 80 | ) 81 | 82 | def test_equal_on_equal(self): 83 | self.skipTest('') 84 | 85 | def test_equal_on_not_equal_name(self): 86 | self.skipTest('') 87 | 88 | def test_equal_on_not_equal_index(self): 89 | self.skipTest('') 90 | 91 | def test_equal_on_not_equal_value(self): 92 | self.skipTest('') 93 | 94 | def test_equal_on_type_mismatch(self): 95 | self.skipTest('') 96 | 97 | def test_not_equal_on_equal(self): 98 | self.skipTest('') 99 | 100 | def test_not_equal_on_not_equal_name(self): 101 | self.skipTest('') 102 | 103 | def test_not_equal_on_not_equal_index(self): 104 | self.skipTest('') 105 | 106 | def test_not_equal_on_not_equal_value(self): 107 | self.skipTest('') 108 | 109 | def test_not_equal_on_type_mismatch(self): 110 | self.skipTest('') 111 | -------------------------------------------------------------------------------- /kmip/tests/unit/core/primitives/__init__.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2015 The Johns Hopkins University/Applied Physics Laboratory 2 | # All Rights Reserved. 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); you may 5 | # not use this file except in compliance with the License. You may obtain 6 | # a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | # License for the specific language governing permissions and limitations 14 | # under the License. 15 | -------------------------------------------------------------------------------- /kmip/tests/unit/core/primitives/test_date_time.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2015 The Johns Hopkins University/Applied Physics Laboratory 2 | # All Rights Reserved. 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); you may 5 | # not use this file except in compliance with the License. You may obtain 6 | # a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | # License for the specific language governing permissions and limitations 14 | # under the License. 15 | 16 | import testtools 17 | 18 | from kmip.core import primitives 19 | from kmip.core import utils 20 | 21 | 22 | class TestDateTime(testtools.TestCase): 23 | """ 24 | Test suite for the DateTime primitive. 25 | 26 | Since DateTime is a subclass of LongInteger, the bulk of the functionality 27 | tests are omitted due to redundancy with the LongInteger test suite. 28 | """ 29 | 30 | def setUp(self): 31 | super(TestDateTime, self).setUp() 32 | 33 | self.value = 1335514341 34 | self.encoding = ( 35 | b'\x42\x00\x00\x09\x00\x00\x00\x08\x00\x00\x00\x00\x4F\x9A\x54' 36 | b'\xE5') 37 | 38 | def tearDown(self): 39 | super(TestDateTime, self).tearDown() 40 | 41 | def test_init(self): 42 | """ 43 | Test that a DateTime can be instantiated. 44 | """ 45 | date_time = primitives.DateTime(1) 46 | self.assertEqual(1, date_time.value) 47 | 48 | def test_init_unset(self): 49 | """ 50 | Test that a DateTime can be instantiated with no input. 51 | """ 52 | date_time = primitives.DateTime() 53 | self.assertNotEqual(date_time.value, None) 54 | 55 | def test_read(self): 56 | """ 57 | Test that a DateTime can be read from a byte stream. 58 | """ 59 | stream = utils.BytearrayStream(self.encoding) 60 | date_time = primitives.DateTime() 61 | date_time.read(stream) 62 | self.assertEqual(self.value, date_time.value) 63 | 64 | def test_write(self): 65 | """ 66 | Test that a DateTime can be written to a byte stream. 67 | """ 68 | stream = utils.BytearrayStream() 69 | date_time = primitives.DateTime(self.value) 70 | date_time.write(stream) 71 | 72 | result = stream.read() 73 | self.assertEqual(len(self.encoding), len(result)) 74 | self.assertEqual(self.encoding, result) 75 | 76 | def test_repr(self): 77 | """ 78 | Test that the representation of a DateTime is formatted properly. 79 | """ 80 | date_time = primitives.DateTime(1439299135) 81 | value = "value={0}".format(date_time.value) 82 | tag = "tag={0}".format(date_time.tag) 83 | r = "DateTime({0}, {1})".format(value, tag) 84 | 85 | self.assertEqual(r, repr(date_time)) 86 | 87 | def test_str(self): 88 | """ 89 | Test that the string representation of a DateTime is formatted 90 | properly. 91 | """ 92 | expected = 'Tue Aug 11 13:18:55 2015' 93 | date_time = primitives.DateTime(1439299135) 94 | 95 | self.assertEqual(expected, str(date_time)) 96 | -------------------------------------------------------------------------------- /kmip/tests/unit/core/secrets/__init__.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2015 The Johns Hopkins University/Applied Physics Laboratory 2 | # All Rights Reserved. 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); you may 5 | # not use this file except in compliance with the License. You may obtain 6 | # a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | # License for the specific language governing permissions and limitations 14 | # under the License. 15 | -------------------------------------------------------------------------------- /kmip/tests/unit/core/test_config_helper.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2014 The Johns Hopkins University/Applied Physics Laboratory 2 | # All Rights Reserved. 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); you may 5 | # not use this file except in compliance with the License. You may obtain 6 | # a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | # License for the specific language governing permissions and limitations 14 | # under the License. 15 | 16 | try: 17 | import configparser 18 | except ImportError: 19 | import ConfigParser as configparser 20 | 21 | from testtools import TestCase 22 | from mock import MagicMock 23 | from mock import Mock 24 | 25 | from kmip.core.config_helper import ConfigHelper 26 | 27 | 28 | class TestConfigHelper(TestCase): 29 | 30 | def setUp(self): 31 | def side_effect(arg1, arg2): 32 | if arg1 == 'conf_test_section' and arg2 == 'conf_test_option': 33 | return 'conf_test_value' 34 | elif arg1 == 'conf_test_section' and arg2 == 'conf_null_option': 35 | return ConfigHelper.NONE_VALUE 36 | else: 37 | raise configparser.NoSectionError 38 | super(TestConfigHelper, self).setUp() 39 | self.config_helper = ConfigHelper() 40 | self.config_helper.conf = MagicMock() 41 | self.config_helper.conf.get = Mock(side_effect=side_effect) 42 | 43 | def tearDown(self): 44 | super(TestConfigHelper, self).tearDown() 45 | 46 | def test_get_valid_value_null_input(self): 47 | value = self.config_helper.get_valid_value(None, None, None, None) 48 | self.assertEqual(None, value) 49 | 50 | def test_get_valid_value_direct_value_is_none(self): 51 | value = self.config_helper.get_valid_value(ConfigHelper.NONE_VALUE, 52 | 'conf_test_section', 53 | 'conf_test_option', 54 | 'test_default_option') 55 | self.assertFalse(self.config_helper.conf.get.called) 56 | self.assertEqual(None, value) 57 | 58 | def test_get_valid_value_config_value_is_none(self): 59 | value = self.config_helper.get_valid_value(None, 60 | 'conf_test_section', 61 | 'conf_null_option', 62 | 'test_default_option') 63 | self.assertTrue(self.config_helper.conf.get.called) 64 | self.config_helper.conf.get.assert_called_with('conf_test_section', 65 | 'conf_null_option') 66 | self.assertEqual(None, value) 67 | 68 | def test_get_valid_value_returns_direct(self): 69 | value = self.config_helper.get_valid_value('test_direct_value', 70 | 'conf_test_section', 71 | 'conf_test_option', 72 | 'test_default_value') 73 | self.assertFalse(self.config_helper.conf.get.called) 74 | self.assertEqual('test_direct_value', value) 75 | 76 | def test_get_valid_value_returns_conf_value(self): 77 | value = self.config_helper.get_valid_value(None, 78 | 'conf_test_section', 79 | 'conf_test_option', 80 | 'test_default_value') 81 | self.assertTrue(self.config_helper.conf.get.called) 82 | self.config_helper.conf.get.assert_called_with('conf_test_section', 83 | 'conf_test_option') 84 | self.assertEqual(value, 'conf_test_value') 85 | 86 | def test_get_valid_value_returns_default(self): 87 | value = self.config_helper.get_valid_value(None, 88 | 'invalid_section', 89 | 'invalid_option', 90 | 'test_default_value') 91 | self.assertTrue(self.config_helper.conf.get.called) 92 | self.config_helper.conf.get.assert_called_with('invalid_section', 93 | 'invalid_option') 94 | self.assertEqual(value, 'test_default_value') 95 | -------------------------------------------------------------------------------- /kmip/tests/unit/core/test_utils.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2014 The Johns Hopkins University/Applied Physics Laboratory 2 | # All Rights Reserved. 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); you may 5 | # not use this file except in compliance with the License. You may obtain 6 | # a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | # License for the specific language governing permissions and limitations 14 | # under the License. 15 | 16 | from testtools import TestCase 17 | 18 | from kmip.core import exceptions 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 = exceptions.ErrorStrings.BAD_EXP_RECV.format( 65 | 'BytearrayStream.{0}', 66 | 'type', 67 | '{1}', 68 | '{2}' 69 | ) 70 | self.bad_len = exceptions.ErrorStrings.BAD_EXP_RECV.format( 71 | 'BytearrayStream.{0}', 72 | 'length', 73 | '{1}', 74 | '{2}' 75 | ) 76 | self.bad_val = exceptions.ErrorStrings.BAD_EXP_RECV.format( 77 | 'BytearrayStream.{0}', 78 | 'value', 79 | '{1}', 80 | '{2}' 81 | ) 82 | 83 | def tearDown(self): 84 | super(TestBytearrayStream, self).tearDown() 85 | 86 | def test_init(self): 87 | value = b'\x00' 88 | b = utils.BytearrayStream(value) 89 | 90 | buf_type = type(b.buffer) 91 | msg = self.bad_type.format('buffer', type(b''), buf_type) 92 | self.assertIsInstance(b.buffer, type(b''), 93 | msg.format(type(b''), type(b.buffer))) 94 | 95 | length = len(b.buffer) 96 | msg = self.bad_len.format('buffer', 1, length) 97 | self.assertEqual(1, length, msg) 98 | 99 | content = b.buffer 100 | msg = self.bad_val.format('buffer', value, content) 101 | self.assertEqual(value, content, msg) 102 | 103 | def test_init_unset(self): 104 | b = utils.BytearrayStream() 105 | 106 | buf_type = type(b.buffer) 107 | msg = self.bad_type.format('buffer', type(b''), buf_type) 108 | self.assertIsInstance(b.buffer, type(b''), 109 | msg.format(type(b''), type(b.buffer))) 110 | 111 | length = len(b.buffer) 112 | msg = self.bad_len.format('buffer', 0, length) 113 | self.assertEqual(0, length, msg) 114 | 115 | def test_read(self): 116 | # TODO (peter-hamilton) Finish implementation. 117 | self.skipTest('') 118 | 119 | def test_write(self): 120 | # TODO (peter-hamilton) Finish implementation. 121 | self.skipTest('') 122 | 123 | def test_peek(self): 124 | # TODO (peter-hamilton) Finish implementation. 125 | value = (b'\x00\x01\x02\x03') 126 | expected = value 127 | b = expected 128 | expected = b 129 | b = utils.BytearrayStream(value) 130 | 131 | def test_peek_overflow(self): 132 | # TODO (peter-hamilton) Finish implementation. 133 | self.skipTest('') 134 | 135 | def test_peek_empty(self): 136 | # TODO (peter-hamilton) Finish implementation. 137 | self.skipTest('') 138 | 139 | def test_peek_none(self): 140 | # TODO (peter-hamilton) Finish implementation. 141 | self.skipTest('') 142 | 143 | def test_length(self): 144 | # TODO (peter-hamilton) Finish implementation. 145 | self.skipTest('') 146 | -------------------------------------------------------------------------------- /kmip/tests/unit/pie/__init__.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2015 The Johns Hopkins University/Applied Physics Laboratory 2 | # All Rights Reserved. 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); you may 5 | # not use this file except in compliance with the License. You may obtain 6 | # a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | # License for the specific language governing permissions and limitations 14 | # under the License. 15 | -------------------------------------------------------------------------------- /kmip/tests/unit/pie/objects/__init__.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2015 The Johns Hopkins University/Applied Physics Laboratory 2 | # All Rights Reserved. 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); you may 5 | # not use this file except in compliance with the License. You may obtain 6 | # a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | # License for the specific language governing permissions and limitations 14 | # under the License. 15 | -------------------------------------------------------------------------------- /kmip/tests/unit/pie/objects/test_cryptographic_object.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2015 The Johns Hopkins University/Applied Physics Laboratory 2 | # All Rights Reserved. 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); you may 5 | # not use this file except in compliance with the License. You may obtain 6 | # a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | # License for the specific language governing permissions and limitations 14 | # under the License. 15 | 16 | 17 | from testtools import TestCase 18 | 19 | from kmip.pie.objects import CryptographicObject 20 | 21 | 22 | class DummyCryptographicObject(CryptographicObject): 23 | """ 24 | A dummy CryptographicObject subclass for testing purposes. 25 | """ 26 | 27 | def __init__(self): 28 | """ 29 | Create a DummyCryptographicObject 30 | """ 31 | super(DummyCryptographicObject, self).__init__() 32 | 33 | def validate(self): 34 | return 35 | 36 | def __repr__(self): 37 | return '' 38 | 39 | def __str__(self): 40 | return '' 41 | 42 | def __eq__(self, other): 43 | return True 44 | 45 | def __ne__(self, other): 46 | return False 47 | 48 | 49 | class TestCryptographicObject(TestCase): 50 | """ 51 | Test suite for CryptographicObject. 52 | 53 | Since CryptographicObject is an ABC abstract class, all tests are run 54 | against a dummy subclass defined above, DummyCryptographicObject. 55 | """ 56 | 57 | def setUp(self): 58 | super(TestCryptographicObject, self).setUp() 59 | 60 | def tearDown(self): 61 | super(TestCryptographicObject, self).tearDown() 62 | 63 | def test_init(self): 64 | """ 65 | Test that a complete subclass of CryptographicObject can be 66 | instantiated. 67 | """ 68 | DummyCryptographicObject() 69 | 70 | def test_repr(self): 71 | """ 72 | Test that repr can be applied to a CryptographicObject. 73 | """ 74 | dummy = DummyCryptographicObject() 75 | repr(dummy) 76 | 77 | def test_str(self): 78 | """ 79 | Test that str can be applied to a CryptographicObject. 80 | """ 81 | dummy = DummyCryptographicObject() 82 | str(dummy) 83 | 84 | def test_eq(self): 85 | """ 86 | Test that equality can be applied to a CryptographicObject. 87 | """ 88 | dummy = DummyCryptographicObject() 89 | self.assertTrue(dummy == dummy) 90 | 91 | def test_ne(self): 92 | """ 93 | Test that inequality can be applied to a CryptographicObject. 94 | """ 95 | dummy = DummyCryptographicObject() 96 | self.assertFalse(dummy != dummy) 97 | -------------------------------------------------------------------------------- /kmip/tests/unit/pie/objects/test_key.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2015 The Johns Hopkins University/Applied Physics Laboratory 2 | # All Rights Reserved. 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); you may 5 | # not use this file except in compliance with the License. You may obtain 6 | # a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | # License for the specific language governing permissions and limitations 14 | # under the License. 15 | 16 | 17 | from testtools import TestCase 18 | 19 | from kmip.pie.objects import Key 20 | 21 | 22 | class DummyKey(Key): 23 | """ 24 | A dummy Key subclass for testing purposes. 25 | """ 26 | 27 | def __init__(self): 28 | """ 29 | Create a DummyKey 30 | """ 31 | super(DummyKey, self).__init__() 32 | 33 | def validate(self): 34 | return 35 | 36 | def __repr__(self): 37 | return '' 38 | 39 | def __str__(self): 40 | return '' 41 | 42 | def __eq__(self, other): 43 | return True 44 | 45 | def __ne__(self, other): 46 | return False 47 | 48 | 49 | class TestKey(TestCase): 50 | """ 51 | Test suite for Key. 52 | 53 | Since Key is an ABC abstract class, all tests are run against a dummy 54 | subclass defined above, DummyKey. 55 | """ 56 | 57 | def setUp(self): 58 | super(TestKey, self).setUp() 59 | 60 | def tearDown(self): 61 | super(TestKey, self).tearDown() 62 | 63 | def test_init(self): 64 | """ 65 | Test that a complete subclass of Key can be 66 | instantiated. 67 | """ 68 | DummyKey() 69 | 70 | def test_repr(self): 71 | """ 72 | Test that repr can be applied to a Key. 73 | """ 74 | dummy = DummyKey() 75 | repr(dummy) 76 | 77 | def test_str(self): 78 | """ 79 | Test that str can be applied to a Key. 80 | """ 81 | dummy = DummyKey() 82 | str(dummy) 83 | 84 | def test_eq(self): 85 | """ 86 | Test that equality can be applied to a Key. 87 | """ 88 | dummy = DummyKey() 89 | self.assertTrue(dummy == dummy) 90 | 91 | def test_ne(self): 92 | """ 93 | Test that inequality can be applied to a Key. 94 | """ 95 | dummy = DummyKey() 96 | self.assertFalse(dummy != dummy) 97 | 98 | def test_key_wrapping_data_invalid(self): 99 | """ 100 | Test that the right error is raised when setting the key wrapping 101 | data with an invalid value. 102 | """ 103 | dummy = DummyKey() 104 | args = (dummy, 'key_wrapping_data', 'invalid') 105 | self.assertRaisesRegex( 106 | TypeError, 107 | "Key wrapping data must be a dictionary.", 108 | setattr, 109 | *args 110 | ) 111 | -------------------------------------------------------------------------------- /kmip/tests/unit/pie/objects/test_managed_object.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2015 The Johns Hopkins University/Applied Physics Laboratory 2 | # All Rights Reserved. 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); you may 5 | # not use this file except in compliance with the License. You may obtain 6 | # a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | # License for the specific language governing permissions and limitations 14 | # under the License. 15 | 16 | from testtools import TestCase 17 | 18 | from kmip.pie.objects import ManagedObject 19 | 20 | 21 | class DummyManagedObject(ManagedObject): 22 | """ 23 | A dummy ManagedObject subclass for testing purposes. 24 | """ 25 | 26 | def __init__(self, object_type=None): 27 | """ 28 | Create a DummyManagedObject 29 | 30 | Args: 31 | object_type (any): A value to test the setting of the object_type 32 | attribute. Optional, defaults to None. 33 | """ 34 | super(DummyManagedObject, self).__init__() 35 | 36 | self._object_type = object_type 37 | 38 | def validate(self): 39 | super(DummyManagedObject, self).validate() 40 | return 41 | 42 | def __repr__(self): 43 | super(DummyManagedObject, self).__repr__() 44 | return '' 45 | 46 | def __str__(self): 47 | super(DummyManagedObject, self).__str__() 48 | return '' 49 | 50 | def __eq__(self, other): 51 | super(DummyManagedObject, self).__eq__(other) 52 | return True 53 | 54 | def __ne__(self, other): 55 | super(DummyManagedObject, self).__ne__(other) 56 | return False 57 | 58 | 59 | class TestManagedObject(TestCase): 60 | """ 61 | Test suite for ManagedObject. 62 | 63 | Since ManagedObject is an ABC abstract class, all tests are run against a 64 | dummy subclass defined above, DummyManagedObject. 65 | """ 66 | 67 | def setUp(self): 68 | super(TestManagedObject, self).setUp() 69 | 70 | def tearDown(self): 71 | super(TestManagedObject, self).tearDown() 72 | 73 | def test_init(self): 74 | """ 75 | Test that a complete subclass of ManagedObject can be instantiated. 76 | """ 77 | DummyManagedObject() 78 | 79 | def test_get_object_type(self): 80 | """ 81 | Test that the object type can be retrieved from the ManagedObject. 82 | """ 83 | expected = 'dummy' 84 | dummy = DummyManagedObject(expected) 85 | observed = dummy.object_type 86 | 87 | self.assertEqual(expected, observed) 88 | 89 | def test_set_object_type(self): 90 | """ 91 | Test that an AttributeError is raised when attempting to change the 92 | value of the object type. 93 | """ 94 | dummy = DummyManagedObject() 95 | 96 | def set_object_type(): 97 | dummy.object_type = 'placeholder' 98 | 99 | self.assertRaises(AttributeError, set_object_type) 100 | 101 | def test_validate(self): 102 | """ 103 | Test that validate can be called on a ManagedObject. 104 | """ 105 | dummy = DummyManagedObject() 106 | dummy.validate() 107 | 108 | def test_repr(self): 109 | """ 110 | Test that repr can be applied to a ManagedObject. 111 | """ 112 | dummy = DummyManagedObject() 113 | repr(dummy) 114 | 115 | def test_str(self): 116 | """ 117 | Test that str can be applied to a ManagedObject. 118 | """ 119 | dummy = DummyManagedObject() 120 | str(dummy) 121 | 122 | def test_eq(self): 123 | """ 124 | Test that equality can be applied to a ManagedObject. 125 | """ 126 | dummy = DummyManagedObject() 127 | self.assertTrue(dummy == dummy) 128 | 129 | def test_ne(self): 130 | """ 131 | Test that inequality can be applied to a ManagedObject. 132 | """ 133 | dummy = DummyManagedObject() 134 | self.assertFalse(dummy != dummy) 135 | -------------------------------------------------------------------------------- /kmip/tests/unit/pie/objects/test_sqltypes.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2016 The Johns Hopkins University/Applied Physics Laboratory 2 | # All Rights Reserved. 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); you may 5 | # not use this file except in compliance with the License. You may obtain 6 | # a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | # License for the specific language governing permissions and limitations 14 | # under the License. 15 | 16 | import testtools 17 | 18 | from kmip.core import enums 19 | from kmip.pie.sqltypes import ManagedObjectName 20 | 21 | 22 | class TestSqlTypesManagedObjectName(testtools.TestCase): 23 | """ 24 | Test suite for objects in sqltypes.py. 25 | """ 26 | 27 | def test_equal_on_equal(self): 28 | """ 29 | Test that the equality operator returns True when comparing two 30 | ManagedObjectName objects with the same data. 31 | """ 32 | a = ManagedObjectName('a', 0) 33 | b = ManagedObjectName('a', 0) 34 | self.assertTrue(a == b) 35 | self.assertTrue(b == a) 36 | 37 | def test_equal_on_not_equal_name(self): 38 | """ 39 | Test that the equality operator returns False when comparing two 40 | ManagedObjectName objects with different names. 41 | """ 42 | a = ManagedObjectName('a', 0) 43 | b = ManagedObjectName('b', 0) 44 | self.assertFalse(a == b) 45 | self.assertFalse(b == a) 46 | 47 | def test_equal_on_not_equal_index(self): 48 | """ 49 | Test that the equality operator returns False when comparing two 50 | ManagedObjectName objects with different indices. 51 | """ 52 | a = ManagedObjectName('a', 0) 53 | b = ManagedObjectName('a', 1) 54 | self.assertFalse(a == b) 55 | self.assertFalse(b == a) 56 | 57 | def test_equal_on_not_equal_name_type(self): 58 | """ 59 | Test that the equality operator returns False when comparing two 60 | ManagedObjectName objects with different name types. 61 | """ 62 | a = ManagedObjectName('a', 0, enums.NameType.UNINTERPRETED_TEXT_STRING) 63 | b = ManagedObjectName('a', 0, enums.NameType.URI) 64 | self.assertFalse(a == b) 65 | self.assertFalse(b == a) 66 | 67 | def test_equal_on_not_equal_class_type(self): 68 | """ 69 | Test that the equality operator returns False when comparing a 70 | ManagedObjectName object with a different type of object. 71 | """ 72 | a = ManagedObjectName('a', 0, enums.NameType.UNINTERPRETED_TEXT_STRING) 73 | b = 'foo' 74 | self.assertFalse(a == b) 75 | self.assertFalse(b == a) 76 | 77 | def test_not_equal_on_equal(self): 78 | """ 79 | Test that the not equal operator returns False when comparing two 80 | ManagedObjectName objects with the same data. 81 | """ 82 | a = ManagedObjectName('a', 0) 83 | b = ManagedObjectName('a', 0) 84 | self.assertFalse(a != b) 85 | self.assertFalse(b != a) 86 | 87 | def test_not_equal_on_not_equal_name(self): 88 | """ 89 | Test that the not equal operator returns True when comparing two 90 | ManagedObjectName objects with different names. 91 | """ 92 | a = ManagedObjectName('a', 0) 93 | b = ManagedObjectName('b', 0) 94 | self.assertTrue(a != b) 95 | self.assertTrue(b != a) 96 | 97 | def test_not_equal_on_not_equal_index(self): 98 | """ 99 | Test that the not equal operator returns True when comparing two 100 | ManagedObjectName objects with different indices. 101 | """ 102 | a = ManagedObjectName('a', 0) 103 | b = ManagedObjectName('a', 1) 104 | self.assertTrue(a != b) 105 | self.assertTrue(b != a) 106 | 107 | def test_not_equal_on_not_equal_name_type(self): 108 | """ 109 | Test that the not equal operator returns True when comparing two 110 | ManagedObjectName objects with different name types. 111 | """ 112 | a = ManagedObjectName('a', 0, enums.NameType.UNINTERPRETED_TEXT_STRING) 113 | b = ManagedObjectName('a', 0, enums.NameType.URI) 114 | self.assertTrue(a != b) 115 | self.assertTrue(b != a) 116 | 117 | def test_not_equal_on_not_equal_class_type(self): 118 | """ 119 | Test that the not equal operator returns False when comparing a 120 | ManagedObjectName object with a different type of object. 121 | """ 122 | a = ManagedObjectName('a', 0, enums.NameType.UNINTERPRETED_TEXT_STRING) 123 | b = 'foo' 124 | self.assertTrue(a != b) 125 | self.assertTrue(b != a) 126 | 127 | def test_repr(self): 128 | """ 129 | Test that __repr__ is implemented. 130 | """ 131 | a = ManagedObjectName('a', 0, enums.NameType.UNINTERPRETED_TEXT_STRING) 132 | repr(a) 133 | -------------------------------------------------------------------------------- /kmip/tests/unit/pie/test_exceptions.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2015 The Johns Hopkins University/Applied Physics Laboratory 2 | # All Rights Reserved. 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); you may 5 | # not use this file except in compliance with the License. You may obtain 6 | # a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | # License for the specific language governing permissions and limitations 14 | # under the License. 15 | 16 | from testtools import TestCase 17 | 18 | from kmip.core.enums import ResultStatus 19 | from kmip.core.enums import ResultReason 20 | 21 | from kmip.pie.exceptions import ClientConnectionFailure 22 | from kmip.pie.exceptions import ClientConnectionNotOpen 23 | from kmip.pie.exceptions import KmipOperationFailure 24 | 25 | 26 | class TestClientConnectionFailure(TestCase): 27 | """ 28 | Test suite for ClientConnectionFailure. 29 | """ 30 | 31 | def setUp(self): 32 | super(TestClientConnectionFailure, self).setUp() 33 | 34 | def tearDown(self): 35 | super(TestClientConnectionFailure, self).tearDown() 36 | 37 | def test_init(self): 38 | """ 39 | Test that a ClientConnectionFailure exception can be instantiated. 40 | """ 41 | exc = ClientConnectionFailure() 42 | self.assertIsInstance(exc, Exception) 43 | 44 | def test_message(self): 45 | """ 46 | Test that a ClientConnectionFailure exception message can be set 47 | properly. 48 | """ 49 | exc = ClientConnectionFailure("test message") 50 | self.assertEqual("test message", str(exc)) 51 | 52 | 53 | class TestClientConnectionNotOpen(TestCase): 54 | """ 55 | Test suite for ClientConnectionNotOpen. 56 | """ 57 | 58 | def setUp(self): 59 | super(TestClientConnectionNotOpen, self).setUp() 60 | 61 | def tearDown(self): 62 | super(TestClientConnectionNotOpen, self).tearDown() 63 | 64 | def test_init(self): 65 | """ 66 | Test that a ClientConnectionNotOpen exception can be instantiated. 67 | """ 68 | exc = ClientConnectionNotOpen() 69 | self.assertIsInstance(exc, Exception) 70 | self.assertEqual("client connection not open", str(exc)) 71 | 72 | 73 | class TestKmipOperationFailure(TestCase): 74 | """ 75 | Test suite for KmipOperationFailure. 76 | """ 77 | 78 | def setUp(self): 79 | super(TestKmipOperationFailure, self).setUp() 80 | 81 | def tearDown(self): 82 | super(TestKmipOperationFailure, self).tearDown() 83 | 84 | def test_init(self): 85 | """ 86 | Test that a KmipOperationFailure exception can be instantiated. 87 | """ 88 | exc = KmipOperationFailure( 89 | ResultStatus.OPERATION_FAILED, 90 | ResultReason.GENERAL_FAILURE, 91 | "Test error message.") 92 | self.assertIsInstance(exc, Exception) 93 | 94 | def test_message(self): 95 | """ 96 | Test that a KmipOperationFailure exception message and attributes can 97 | be set properly. 98 | """ 99 | status = ResultStatus.OPERATION_FAILED 100 | reason = ResultReason.GENERAL_FAILURE 101 | exc = KmipOperationFailure(status, reason, "Test error message.") 102 | 103 | msg = "{0}: {1} - {2}".format( 104 | status.name, reason.name, "Test error message.") 105 | 106 | self.assertEqual(msg, str(exc)) 107 | self.assertEqual(status, exc.status) 108 | self.assertEqual(reason, exc.reason) 109 | self.assertEqual("Test error message.", exc.message) 110 | -------------------------------------------------------------------------------- /kmip/tests/unit/services/__init__.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2014 The Johns Hopkins University/Applied Physics Laboratory 2 | # All Rights Reserved. 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); you may 5 | # not use this file except in compliance with the License. You may obtain 6 | # a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | # License for the specific language governing permissions and limitations 14 | # under the License. 15 | -------------------------------------------------------------------------------- /kmip/tests/unit/services/server/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OpenKMIP/PyKMIP/6cd44b572b0ca55adf01a8a12078b2284602e64c/kmip/tests/unit/services/server/__init__.py -------------------------------------------------------------------------------- /kmip/tests/unit/services/server/auth/__init__.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2018 The Johns Hopkins University/Applied Physics Laboratory 2 | # All Rights Reserved. 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); you may 5 | # not use this file except in compliance with the License. You may obtain 6 | # a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | # License for the specific language governing permissions and limitations 14 | # under the License. 15 | -------------------------------------------------------------------------------- /kmip/tests/unit/services/server/crypto/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OpenKMIP/PyKMIP/6cd44b572b0ca55adf01a8a12078b2284602e64c/kmip/tests/unit/services/server/crypto/__init__.py -------------------------------------------------------------------------------- /kmip/tests/unit/services/test_kmip_protocol.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2014 The Johns Hopkins University/Applied Physics Laboratory 2 | # All Rights Reserved. 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); you may 5 | # not use this file except in compliance with the License. You may obtain 6 | # a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | # License for the specific language governing permissions and limitations 14 | # under the License. 15 | 16 | from mock import call, MagicMock 17 | from testtools import TestCase 18 | 19 | import binascii 20 | 21 | from kmip.services.kmip_protocol import KMIPProtocol 22 | from kmip.services.kmip_protocol import RequestLengthMismatch 23 | from kmip.services.kmip_protocol import KMIPProtocolFactory 24 | 25 | 26 | class TestKMIPProtocol(TestCase): 27 | 28 | request = binascii.unhexlify( 29 | '42007801000000b04200770100000088420069010000002042006a02000000040' 30 | '00000010000000042006b0200000004000000010000000042000c010000004842' 31 | '00230100000040420024050000000400000001000000004200250100000028420' 32 | '099070000000a4b6d6970436c69656e740000000000004200a10700000006436f' 33 | '75636f75000042000d0200000004000000010000000042000f010000001842005' 34 | 'c05000000040000001e000000004200790100000000') 35 | response = binascii.unhexlify( 36 | '42007b01000000d042007a0100000048420069010000002042006a02000000040' 37 | '00000010000000042006b02000000040000000100000000420092090000000800' 38 | '00000056bda8eb42000d0200000004000000010000000042000f0100000078420' 39 | '05c05000000040000001e0000000042007f050000000400000000000000004200' 40 | '7c0100000050420069010000002042006a0200000004000000010000000042006' 41 | 'b02000000040000000100000000420069010000002042006a0200000004000000' 42 | '010000000042006b02000000040000000000000000') 43 | 44 | def setUp(self): 45 | super(TestKMIPProtocol, self).setUp() 46 | self.factory = KMIPProtocolFactory() 47 | 48 | def tearDown(self): 49 | super(TestKMIPProtocol, self).tearDown() 50 | 51 | def test_init(self): 52 | """ 53 | Test that a KmipProtocol can be created without errors. 54 | """ 55 | socket = MagicMock() 56 | KMIPProtocol(socket) 57 | 58 | def test_protocol_factory(self): 59 | mock_name = 'test_protocol_factory' 60 | socket = MagicMock(mock_name=mock_name) 61 | protocol = self.factory.getProtocol(socket) 62 | 63 | base = "expected {0}, received {1}" 64 | msg = base.format(KMIPProtocol, protocol) 65 | self.assertIsInstance(protocol, KMIPProtocol, msg) 66 | self.assertEqual(protocol.socket.mock_name, mock_name, msg) 67 | 68 | def test_IO_write(self): 69 | socket = MagicMock() 70 | protocol = self.factory.getProtocol(socket) 71 | protocol.logger = MagicMock() 72 | protocol.write(self.request) 73 | 74 | protocol.logger.debug.assert_any_call( 75 | "KMIPProtocol.write: {0}".format(binascii.hexlify(self.request))) 76 | protocol.socket.sendall.assert_called_once_with(self.request) 77 | 78 | def test_IO_read(self): 79 | socket = MagicMock() 80 | socket.recv = MagicMock( 81 | side_effect=[self.response[:8], self.response[8:]]) 82 | protocol = self.factory.getProtocol(socket) 83 | 84 | received = protocol.read() 85 | 86 | socket.recv.assert_any_call(8) 87 | socket.recv.assert_any_call(len(self.response) - 8) 88 | 89 | self.assertEqual(self.response, received.peek()) 90 | 91 | def test_IO_read_EOF(self): 92 | socket = MagicMock() 93 | socket.recv = MagicMock(side_effect=[[]]) 94 | protocol = self.factory.getProtocol(socket) 95 | 96 | try: 97 | protocol.read() 98 | except Exception as e: 99 | self.assertIsInstance(e, EOFError, "Invalid exception") 100 | else: 101 | self.assertTrue(False, "Unexpected error") 102 | 103 | socket.recv.assert_any_call(8) 104 | 105 | def test_IO_read_request_length_mismatch(self): 106 | socket = MagicMock() 107 | socket.recv = MagicMock( 108 | side_effect=[self.response[:8], self.response[8:16], []]) 109 | protocol = self.factory.getProtocol(socket) 110 | resp_len = len(self.response) 111 | 112 | try: 113 | protocol.read() 114 | except Exception as e: 115 | self.assertIsInstance( 116 | e, RequestLengthMismatch, "Invalid exception") 117 | self.assertEqual(e.expected, resp_len - 8, "Unexpected expected") 118 | self.assertEqual(e.received, 8, "Unexpected received") 119 | self.assertEqual( 120 | "{0}".format(e), 121 | "{0}: expected {1}, received {2}".format( 122 | "KMIPProtocol read error", resp_len - 8, 8), 123 | "Invalid RequestLengthMismatch attributes") 124 | else: 125 | self.assertTrue(False, "Unexpected error") 126 | 127 | calls = [call(8), call(resp_len - 8), call(resp_len - 16)] 128 | socket.recv.assert_has_calls(calls) 129 | -------------------------------------------------------------------------------- /kmip/tests/unit/test_kmip.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2015 The Johns Hopkins University/Applied Physics Laboratory 2 | # All Rights Reserved. 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); you may 5 | # not use this file except in compliance with the License. You may obtain 6 | # a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | # License for the specific language governing permissions and limitations 14 | # under the License. 15 | 16 | from testtools import TestCase 17 | 18 | 19 | class TestKMIP(TestCase): 20 | """ 21 | A test suite for the overall `kmip` module. 22 | """ 23 | 24 | def setUp(self): 25 | super(TestKMIP, self).setUp() 26 | 27 | def tearDown(self): 28 | super(TestKMIP, self).tearDown() 29 | 30 | def test_version(self): 31 | """ 32 | Verify that the kmip module has a __version__ attribute and that it's 33 | value is correct. 34 | """ 35 | kmip = __import__('kmip') 36 | self.assertTrue(hasattr(kmip, '__version__')) 37 | 38 | version = __import__('kmip.version') 39 | self.assertTrue(hasattr(version, '__version__')) 40 | 41 | observed = getattr(kmip, '__version__') 42 | expected = getattr(version, '__version__') 43 | self.assertEqual(expected, observed) 44 | -------------------------------------------------------------------------------- /kmip/version.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2015 The Johns Hopkins University/Applied Physics Laboratory 2 | # All Rights Reserved. 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); you may 5 | # not use this file except in compliance with the License. You may obtain 6 | # a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | # License for the specific language governing permissions and limitations 14 | # under the License. 15 | 16 | __version__ = "0.11.0.dev1" 17 | -------------------------------------------------------------------------------- /pytest.ini: -------------------------------------------------------------------------------- 1 | [pytest] 2 | markers = 3 | ignore: skip the given test object 4 | -------------------------------------------------------------------------------- /requirements.txt: -------------------------------------------------------------------------------- 1 | cryptography>=2.5 2 | enum-compat 3 | requests 4 | six>=1.11.0 5 | sqlalchemy>=1.0 6 | -------------------------------------------------------------------------------- /setup.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain 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, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 12 | # implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | 16 | import os 17 | import re 18 | import setuptools 19 | 20 | # Dynamically set __version__ 21 | this_dir = os.path.dirname(os.path.realpath(__file__)) 22 | version_path = os.path.join(this_dir, "kmip", "version.py") 23 | with open(version_path, 'r') as f: 24 | m = re.search( 25 | r"^__version__ = \"(\d+\.\d+\..*)\"$", 26 | f.read(), 27 | re.MULTILINE 28 | ) 29 | __version__ = m.group(1) 30 | readme_path = os.path.join(this_dir, "README.rst") 31 | with open(readme_path, 'r') as f: 32 | long_description = f.read() 33 | 34 | setuptools.setup( 35 | name='PyKMIP', 36 | version=__version__, 37 | description='KMIP library', 38 | keywords='KMIP', 39 | author='Peter Hamilton', 40 | author_email='peter.hamilton@jhuapl.edu', 41 | url='https://github.com/OpenKMIP/PyKMIP', 42 | license='Apache License, Version 2.0', 43 | long_description=long_description, 44 | long_description_content_type="text/x-rst", 45 | packages=setuptools.find_packages(exclude=["kmip.tests", "kmip.tests.*"]), 46 | package_data={'kmip': ['kmipconfig.ini', 'logconfig.ini'], 47 | 'kmip.demos': ['certs/server.crt', 'certs/server.key']}, 48 | entry_points={ 49 | 'console_scripts':[ 50 | 'pykmip-server = kmip.services.server.server:main' 51 | ] 52 | }, 53 | install_requires=[ 54 | "cryptography", 55 | "enum-compat", 56 | "requests", 57 | "six", 58 | "sqlalchemy" 59 | ], 60 | python_requires=">= 3.8", 61 | classifiers=[ 62 | "Intended Audience :: Developers", 63 | "License :: OSI Approved :: Apache Software License", 64 | "Natural Language :: English", 65 | "Operating System :: POSIX", 66 | "Operating System :: POSIX :: BSD", 67 | "Operating System :: POSIX :: Linux", 68 | "Programming Language :: Python", 69 | "Programming Language :: Python :: 3", 70 | "Programming Language :: Python :: 3 :: Only", 71 | "Programming Language :: Python :: 3.8", 72 | "Programming Language :: Python :: 3.9", 73 | "Programming Language :: Python :: 3.10", 74 | "Programming Language :: Python :: 3.11", 75 | ], 76 | ) 77 | -------------------------------------------------------------------------------- /test-requirements.txt: -------------------------------------------------------------------------------- 1 | coverage 2 | pytest 3 | flake8 4 | testtools 5 | fixtures 6 | mock 7 | slugs 8 | sphinx 9 | PyYAML 10 | bandit 11 | -------------------------------------------------------------------------------- /tox.ini: -------------------------------------------------------------------------------- 1 | [tox] 2 | envlist = pep8,py38,py310,bandit,docs 3 | 4 | [testenv] 5 | passenv = * 6 | 7 | deps = -r{toxinidir}/requirements.txt 8 | -r{toxinidir}/test-requirements.txt 9 | 10 | commands = 11 | coverage run --source=kmip/ --omit=kmip/demos/*,kmip/tests/* -m pytest --strict kmip/tests/unit {posargs} 12 | coverage report -m 13 | coverage html 14 | 15 | [testenv:pep8] 16 | commands = flake8 kmip/ 17 | 18 | [testenv:integration] 19 | # Note: This requires local or remote access to a KMIP appliance or service 20 | deps = {[testenv]deps} 21 | commands = 22 | py.test --strict kmip/tests/integration -m "not ignore" {posargs} 23 | 24 | [testenv:functional] 25 | # Note: This requires local access to instances of the PyKMIP server and SLUGS. 26 | deps = {[testenv]deps} 27 | commands = 28 | py.test --strict kmip/tests/functional -m "not ignore" {posargs} 29 | 30 | [testenv:bandit] 31 | deps = {[testenv]deps} 32 | commands = bandit -r kmip -n5 -x kmip/tests 33 | 34 | [testenv:docs] 35 | changedir = docs 36 | deps = 37 | sphinx 38 | sphinx_rtd_theme 39 | commands = 40 | sphinx-build -j4 -T -W -b html -d {envtmpdir}/doctrees source {envtmpdir}/html 41 | 42 | [testenv:docs-linkcheck] 43 | changedir = docs 44 | extras = 45 | deps = {[testenv:docs]deps} 46 | commands = 47 | sphinx-build -W -b linkcheck source {envtmpdir}/html 48 | 49 | [flake8] 50 | exclude = .git,.tox,dist,rpmbuild,*.egg-info 51 | max-line-length = 88 52 | --------------------------------------------------------------------------------