From 93aacb43e642449011edcb4c707fa5d84a8d59c4 Mon Sep 17 00:00:00 2001 From: lhinds Date: Tue, 28 Aug 2018 09:33:12 +0100 Subject: [PATCH] Retiring Project http://lists.openstack.org/pipermail/openstack-sigs/2018-August/000481.html Depends-On: 90ca23f2ef5bf2cfdaf63552a7d8d8be325a03e6 Change-Id: I9ebc8cfcbb8906e9c4e1fd9e91205fe364bdc3c9 --- .coveragerc | 7 - .gitignore | 29 - .testr.conf | 7 - CA/.empty | 0 CONTRIBUTING.rst | 17 - Dockerfile | 6 - README.rst | 364 +--- anchor/X509/__init__.py | 0 anchor/X509/certificate.py | 284 ---- anchor/X509/errors.py | 31 - anchor/X509/extension.py | 523 ------ anchor/X509/name.py | 172 -- anchor/X509/signature.py | 175 -- anchor/X509/signing_request.py | 244 --- anchor/X509/utils.py | 180 -- anchor/__init__.py | 0 anchor/app.py | 237 --- anchor/asn1/__init__.py | 0 anchor/asn1/rfc3280.py | 1505 ----------------- anchor/asn1/rfc3281.py | 344 ---- anchor/asn1/rfc3852.py | 663 -------- anchor/asn1/rfc4211.py | 349 ---- anchor/asn1/rfc5280.py | 1502 ---------------- anchor/asn1/rfc5652.py | 666 -------- anchor/asn1/rfc6402.py | 576 ------- anchor/audit/__init__.py | 132 -- anchor/auth/__init__.py | 44 - anchor/auth/keystone.py | 55 - anchor/auth/ldap.py | 75 - anchor/auth/results.py | 32 - anchor/auth/static.py | 69 - anchor/certificate_ops.py | 201 --- anchor/cmc.py | 80 - anchor/config.py | 48 - anchor/controllers/__init__.py | 106 -- anchor/errors.py | 2 - anchor/fixups.py | 44 - anchor/jsonloader.py | 135 -- anchor/signers/__init__.py | 91 - anchor/signers/cryptography_io.py | 74 - anchor/signers/pkcs11.py | 120 -- anchor/util.py | 86 - anchor/validation.py | 84 - anchor/validators/__init__.py | 0 anchor/validators/custom.py | 313 ---- anchor/validators/errors.py | 16 - anchor/validators/internal.py | 42 - anchor/validators/standards.py | 111 -- anchor/validators/utils.py | 137 -- asn/autogenerated.txt | 10 - asn/rfc3280.e.asn | 628 ------- asn/rfc3280.i.asn | 347 ---- asn/rfc3852.e.asn | 51 - asn/rfc3852.i.asn | 333 ---- asn/rfc4211.asn | 284 ---- asn/rfc6402.asn | 425 ----- bin/anchor | 43 - bin/anchor_debug | 6 - bin/container_bootstrap.py | 67 - certs/.empty | 0 config.json | 36 - doc/source/api.rst | 48 - doc/source/audit.rst | 27 - doc/source/conf.py | 258 --- doc/source/configuration.rst | 240 --- doc/source/ephemeralPKI.rst | 129 -- doc/source/extensions.rst | 42 - doc/source/fixups.rst | 19 - doc/source/index.rst | 29 - doc/source/signing_backends.rst | 117 -- doc/source/validators.rst | 184 -- requirements.txt | 17 - run_tests.sh | 161 -- setup.cfg | 67 - setup.py | 29 - test-requirements.txt | 18 - tests/CA/root-ca-unwrapped.key | 15 - tests/CA/root-ca.crt | 58 - tests/X509/__init__.py | 0 tests/X509/test_extension.py | 270 --- tests/X509/test_utils.py | 34 - tests/X509/test_x509_certificate.py | 296 ---- tests/X509/test_x509_csr.py | 199 --- tests/X509/test_x509_name.py | 132 -- tests/__init__.py | 102 -- tests/auth/__init__.py | 0 tests/auth/test_keystone.py | 143 -- tests/auth/test_ldap.py | 117 -- tests/auth/test_static.py | 70 - tests/controllers/__init__.py | 0 tests/controllers/test_app.py | 256 --- tests/fixups/__init__.py | 0 ..._fixup_ensure_alternative_names_present.py | 109 -- tests/fixups/test_fixup_functionality.py | 84 - tests/test_certificate_ops.py | 148 -- tests/test_config.py | 98 -- tests/test_functional.py | 149 -- tests/test_signing_backend.py | 265 --- tests/validators/__init__.py | 0 .../test_base_validation_functions.py | 82 - tests/validators/test_callable_validators.py | 688 -------- tests/validators/test_standards_validator.py | 194 --- tools/apparmor.anchor_debug | 61 - tools/apparmor.anchor_production | 62 - tools/bootstrap_test_ca.sh | 3 - tools/cmc_wrap.vbs | 26 - tools/colorizer.py | 333 ---- tools/install_venv.py | 72 - tools/install_venv_common.py | 172 -- tools/with_venv.sh | 7 - tox.ini | 50 - 111 files changed, 8 insertions(+), 17880 deletions(-) delete mode 100644 .coveragerc delete mode 100644 .gitignore delete mode 100644 .testr.conf delete mode 100644 CA/.empty delete mode 100644 CONTRIBUTING.rst delete mode 100644 Dockerfile delete mode 100644 anchor/X509/__init__.py delete mode 100644 anchor/X509/certificate.py delete mode 100644 anchor/X509/errors.py delete mode 100644 anchor/X509/extension.py delete mode 100644 anchor/X509/name.py delete mode 100644 anchor/X509/signature.py delete mode 100644 anchor/X509/signing_request.py delete mode 100644 anchor/X509/utils.py delete mode 100644 anchor/__init__.py delete mode 100644 anchor/app.py delete mode 100644 anchor/asn1/__init__.py delete mode 100644 anchor/asn1/rfc3280.py delete mode 100644 anchor/asn1/rfc3281.py delete mode 100644 anchor/asn1/rfc3852.py delete mode 100644 anchor/asn1/rfc4211.py delete mode 100644 anchor/asn1/rfc5280.py delete mode 100644 anchor/asn1/rfc5652.py delete mode 100644 anchor/asn1/rfc6402.py delete mode 100644 anchor/audit/__init__.py delete mode 100644 anchor/auth/__init__.py delete mode 100644 anchor/auth/keystone.py delete mode 100644 anchor/auth/ldap.py delete mode 100644 anchor/auth/results.py delete mode 100644 anchor/auth/static.py delete mode 100644 anchor/certificate_ops.py delete mode 100644 anchor/cmc.py delete mode 100644 anchor/config.py delete mode 100644 anchor/controllers/__init__.py delete mode 100644 anchor/errors.py delete mode 100644 anchor/fixups.py delete mode 100644 anchor/jsonloader.py delete mode 100644 anchor/signers/__init__.py delete mode 100644 anchor/signers/cryptography_io.py delete mode 100644 anchor/signers/pkcs11.py delete mode 100644 anchor/util.py delete mode 100644 anchor/validation.py delete mode 100644 anchor/validators/__init__.py delete mode 100644 anchor/validators/custom.py delete mode 100644 anchor/validators/errors.py delete mode 100644 anchor/validators/internal.py delete mode 100644 anchor/validators/standards.py delete mode 100644 anchor/validators/utils.py delete mode 100644 asn/autogenerated.txt delete mode 100644 asn/rfc3280.e.asn delete mode 100644 asn/rfc3280.i.asn delete mode 100644 asn/rfc3852.e.asn delete mode 100644 asn/rfc3852.i.asn delete mode 100644 asn/rfc4211.asn delete mode 100644 asn/rfc6402.asn delete mode 100755 bin/anchor delete mode 100755 bin/anchor_debug delete mode 100644 bin/container_bootstrap.py delete mode 100644 certs/.empty delete mode 100644 config.json delete mode 100644 doc/source/api.rst delete mode 100644 doc/source/audit.rst delete mode 100644 doc/source/conf.py delete mode 100644 doc/source/configuration.rst delete mode 100644 doc/source/ephemeralPKI.rst delete mode 100644 doc/source/extensions.rst delete mode 100644 doc/source/fixups.rst delete mode 100644 doc/source/index.rst delete mode 100644 doc/source/signing_backends.rst delete mode 100644 doc/source/validators.rst delete mode 100644 requirements.txt delete mode 100755 run_tests.sh delete mode 100644 setup.cfg delete mode 100644 setup.py delete mode 100644 test-requirements.txt delete mode 100644 tests/CA/root-ca-unwrapped.key delete mode 100644 tests/CA/root-ca.crt delete mode 100644 tests/X509/__init__.py delete mode 100644 tests/X509/test_extension.py delete mode 100644 tests/X509/test_utils.py delete mode 100644 tests/X509/test_x509_certificate.py delete mode 100644 tests/X509/test_x509_csr.py delete mode 100644 tests/X509/test_x509_name.py delete mode 100644 tests/__init__.py delete mode 100644 tests/auth/__init__.py delete mode 100644 tests/auth/test_keystone.py delete mode 100644 tests/auth/test_ldap.py delete mode 100644 tests/auth/test_static.py delete mode 100644 tests/controllers/__init__.py delete mode 100644 tests/controllers/test_app.py delete mode 100644 tests/fixups/__init__.py delete mode 100644 tests/fixups/test_fixup_ensure_alternative_names_present.py delete mode 100644 tests/fixups/test_fixup_functionality.py delete mode 100644 tests/test_certificate_ops.py delete mode 100644 tests/test_config.py delete mode 100644 tests/test_functional.py delete mode 100644 tests/test_signing_backend.py delete mode 100644 tests/validators/__init__.py delete mode 100644 tests/validators/test_base_validation_functions.py delete mode 100644 tests/validators/test_callable_validators.py delete mode 100644 tests/validators/test_standards_validator.py delete mode 100644 tools/apparmor.anchor_debug delete mode 100644 tools/apparmor.anchor_production delete mode 100755 tools/bootstrap_test_ca.sh delete mode 100755 tools/cmc_wrap.vbs delete mode 100755 tools/colorizer.py delete mode 100644 tools/install_venv.py delete mode 100644 tools/install_venv_common.py delete mode 100755 tools/with_venv.sh delete mode 100644 tox.ini diff --git a/.coveragerc b/.coveragerc deleted file mode 100644 index f2c3d0b..0000000 --- a/.coveragerc +++ /dev/null @@ -1,7 +0,0 @@ -[run] -branch = True - -[report] -exclude_lines = - pragma: no cover - raise NotImplementedError diff --git a/.gitignore b/.gitignore deleted file mode 100644 index d3aa0fb..0000000 --- a/.gitignore +++ /dev/null @@ -1,29 +0,0 @@ -*.pyc -temp-*.crt -config.cfg -.venv -*.sw[op] -certs/*.crt -dist/* -build/* -.tox/* -.DS_Store -*.egg -*.egg-info -.testrepository -build/* -cover/* -.cover -.coverage -doc/build -.eggs/ -pep8.txt -AUTHORS -ChangeLog - -# mentioned in README for test/bootstrap -anchor-test.example.com.key -anchor-test.example.com.csr -CA/serial -CA/*.key -CA/*.crt diff --git a/.testr.conf b/.testr.conf deleted file mode 100644 index 35d9ba4..0000000 --- a/.testr.conf +++ /dev/null @@ -1,7 +0,0 @@ -[DEFAULT] -test_command=OS_STDOUT_CAPTURE=${OS_STDOUT_CAPTURE:-1} \ - OS_STDERR_CAPTURE=${OS_STDERR_CAPTURE:-1} \ - OS_TEST_TIMEOUT=${OS_TEST_TIMEOUT:-60} \ - ${PYTHON:-python} -m subunit.run discover -t ./ ./tests $LISTOPT $IDOPTION -test_id_option=--load-list $IDFILE -test_list_option=--list diff --git a/CA/.empty b/CA/.empty deleted file mode 100644 index e69de29..0000000 diff --git a/CONTRIBUTING.rst b/CONTRIBUTING.rst deleted file mode 100644 index c7e3bce..0000000 --- a/CONTRIBUTING.rst +++ /dev/null @@ -1,17 +0,0 @@ -This project is part of the OpenStack / Stackforge family. If you would like to -contribute to the development, you must follow the steps in this page: - - http://docs.openstack.org/infra/manual/developers.html - -Once those steps have been completed, changes to OpenStack should be submitted -for review via the Gerrit tool, following the workflow documented at: - - http://docs.openstack.org/infra/manual/developers.html#development-workflow - -(in short - install git-review package, then submit changes via `git review`) - -Pull requests submitted through GitHub will be ignored. - -Bugs should be filed on Launchpad, not GitHub: - - https://bugs.launchpad.net/anchor diff --git a/Dockerfile b/Dockerfile deleted file mode 100644 index 96230d9..0000000 --- a/Dockerfile +++ /dev/null @@ -1,6 +0,0 @@ -FROM python:2.7 -RUN pip install pecan -ADD . /code -WORKDIR /code -RUN pip install -e . -ENTRYPOINT ["python","bin/container_bootstrap.py"] diff --git a/README.rst b/README.rst index 3648b61..d98af48 100644 --- a/README.rst +++ b/README.rst @@ -1,358 +1,10 @@ -Anchor -====== +This project is no longer maintained. -.. image:: https://img.shields.io/pypi/v/anchor.svg - :target: https://pypi.python.org/pypi/anchor/ - :alt: Latest Version +The contents of this repository are still available in the Git +source code management system. To see the contents of this +repository before it reached its end of life, please check out the +previous commit with "git checkout HEAD^1". -.. image:: https://img.shields.io/pypi/pyversions/anchor.svg - :target: https://pypi.python.org/pypi/anchor/ - :alt: Python Versions - -.. image:: https://img.shields.io/pypi/format/anchor.svg - :target: https://pypi.python.org/pypi/anchor/ - :alt: Format - -.. image:: https://img.shields.io/badge/license-Apache%202-blue.svg - :target: https://git.openstack.org/cgit/openstack/anchor/plain/LICENSE - :alt: License - -Anchor is an ephemeral PKI service that, based on certain conditions, -automates the verification of CSRs and signs certificates for clients. -The validity period can be set in the config file with hour resolution. - -Ideas behind Anchor -=================== - -A critical capability within PKI is to revoke a certificate - to ensure -that it is no longer trusted by any peer. Unfortunately research has -demonstrated that the two typical methods of revocation (Certificate -Revocation Lists and Online Certificate Status Protocol) both have -failings that make them unreliable, especially when attempting to -leverage PKI outside of web-browser software. - -Through the use of short-lifetime certificates Anchor introduces the -concept of "passive revocation". By issuing certificates with lifetimes -measured in hours, revocation can be achieved by simply not re-issuing -certificates to clients. - -The benefits of using Anchor instead of manual long-term certificates -are: - -* quick certificate revoking / rotation -* always tested certificate update mechanism (used daily) -* easy integration with certmonger for service restarting -* certificates are signed only when validation is passed -* signing certificates follows consistent process - -Installation -============ - -In order to install Anchor from source, the following system -dependencies need to be present: - -* python 2.7 -* python (dev files) -* libffi (dev) -* libssl (dev) - -When everything is in place, Anchor can be installed in one of three -ways: a local development instance in a python virtual environment, a local -production instance or a test instance in a docker container. - -For a development instance with virtualenv, run: - - virtualenv .venv && source .venv/bin/activate && pip install . - -For installing in production, either install a perpared system package, -or install globally in the system: - - python setup.py install - -Running the service -=================== - -In order to run the service, it needs to be started via the `pecan` -application server. The only extra parameter is a config file: - - pecan serve anchor/config.py - -For development, an additional `--reload` parameter may be used. It will -cause the service to reload every time a source file is changed, however -it requires installing an additional `watchdog` python module. - -In the default configuration, Anchor will wait for web requests on port -5016 on local network interface. This can be adjusted in the `config.py` -file. - -Preparing a test environment -============================ - -In order to test Anchor with the default configuration, the following -can be done to create a test CA. The test certificate can be then used -to sign the new certificates. - - openssl req -out CA/root-ca.crt -keyout CA/root-ca-unwrapped.key \ - -newkey rsa:4096 -subj "/CN=Anchor Test CA" -nodes -x509 -days 365 \ - -sha256 - chmod 0400 CA/root-ca-unwrapped.key - -Next, a new certificate request may be generated: - - openssl req -out anchor-test.example.com.csr -nodes \ - -keyout anchor-test.example.com.key -newkey rsa:2048 \ - -subj "/CN=anchor-test.example.com" -sha256 - -That reqest can be submitted using curl (while `pecan serve config.py` -is running): - - curl http://0.0.0.0:5016/v1/sign/default -F user='myusername' \ - -F secret='simplepassword' -F encoding=pem \ - -F 'csr=`_. - -Additionally, using an AppArmor profile for Anchor is a good idea to -prevent exploits relying on one of the native libraries used by Anchor -(for example OpenSSL). This can be done with sample profiles which you -can find in the `tools/apparmor.anchor_*` files. The used file needs to -be reviewed and updated with the right paths depending on the deployment -location. - -Validators -========== - -One of the main features of Anchor are the validators which make sure -that all requests match a given set of rules. They're configured in -`config.json` and the sample configuration includes a few of them. - -Each validator takes a dictionary of options which provide the specific -matching conditions. - -Currently available validators are: - -* `common_name` ensures CN matches one of names in `allowed_domains` or -ranges in `allowed_networks` - -* `alternative_names` ensures alternative names match one of the names -in `allowed_domains` - -* `alternative_names_ip` ensures alternative names match one of the -names in `allowed_domains` or IP ranges in `allowed_networks` - -* `blacklist_names` ensures CN and alternative names do not contain any -of the configured `domains` - -* `server_group` ensures the group the requester is contained within - `group_prefixes` - -* `extensions` ensures only `allowed_extensions` are present in the -request - -* `key_usage` ensures only `allowed_usage` is requested for the -certificate - -* `ca_status` ensures the request does/doesn't require the CA flag - -* `source_cidrs` ensures the request comes from one of the ranges in -`cidrs` - -A configuration entry for a validator might look like one from the -sample config: - - "key_usage": { - "allowed_usage": [ - "Digital Signature", - "Key Encipherment", - "Non Repudiation" - ] - } - -Authentication -============== - -Anchor can use one of the following authentication modules: static, -keystone, ldap. - -Static: Username and password are present in `config.json`. This mode -should be used only for development and testing. - - "auth": { - "static": { - "secret": "simplepassword", - "user": "myusername" - } - } - -Keystone: Username is ignored, but password is a token valid in the -configured keystone location. - - "auth": { - "keystone": { - "url": "https://keystone.example.com" - } - } - -LDAP: Username and password are used to bind to an LDAP user in a -configured domain. User's groups for the `server_group` filter are -retrieved from attribute `memberOf` in search for -`(sAMAccountName=username@domain)`. The search is done in the configured -base. - - "auth": { - "ldap": { - "host": "ldap.example.com", - "base": "ou=Users,dc=example,dc=com", - "domain": "example.com" - "port": 636, - "ssl": true - } - } - -Signing backends -================ - -Anchor allows the use of configurable signing backend. Currently it provides two -implementation: one based on cryptography.io ("anchor"), the other using PKCS#11 -libraries ("pkcs11"). The first one is used in the sample config. Other backends -may have extra dependencies: pkcs11 requires the PyKCS11 module, not required by -anchor by default. - -The resulting certificate is stored locally if the `output_path` is set -to any string. This does not depend on the configured backend. - -Backends can specify their own options - please refer to the backend -documentation for the specific list. The default backend takes the -following options: - -* `cert_path`: path where local CA certificate can be found - -* `key_path`: path to the key for that certificate - -* `signing_hash`: which hash method to use when producing signatures - -* `valid_hours`: number of hours the signed certificates are valid for - -Sample configuration for the default backend: - - "ca": { - "backend": "anchor" - "cert_path": "CA/root-ca.crt", - "key_path": "CA/root-ca-unwrapped.key", - "output_path": "certs", - "signing_hash": "sha256", - "valid_hours": 24 - } - -Other backends may be created too. For more information, please refer to the -documentation. - -Fixups -====== - -Anchor can modify the submitted CSRs in order to enforce some rules, -remove deprecated elements, or just add information. Submitted CSR may -be modified or entirely redone. Fixup are loaded from "anchor.fixups" -namespace and can take parameters just like validators. - -Reporting bugs and contributing -=============================== - -For bug reporting and contributing, please check the CONTRIBUTING.rst -file. +For any further questions, please email +openstack-dev@lists.openstack.org or join #openstack-dev on +Freenode. diff --git a/anchor/X509/__init__.py b/anchor/X509/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/anchor/X509/certificate.py b/anchor/X509/certificate.py deleted file mode 100644 index a4d6e27..0000000 --- a/anchor/X509/certificate.py +++ /dev/null @@ -1,284 +0,0 @@ -# -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - -from __future__ import absolute_import - -import base64 -import binascii -import io - -from cryptography.hazmat import backends as cio_backends -from cryptography.hazmat.primitives import hashes -from pyasn1.codec.ber import encoder as ber_encoder -from pyasn1.codec.der import decoder -from pyasn1.codec.der import encoder -from pyasn1.type import univ as asn1_univ -from pyasn1_modules import pem - -from anchor.asn1 import rfc5280 -from anchor.X509 import errors -from anchor.X509 import extension -from anchor.X509 import name -from anchor.X509 import signature -from anchor.X509 import utils - - -SIGNING_ALGORITHMS = { - ('RSA', 'SHA224'): asn1_univ.ObjectIdentifier('1.2.840.113549.1.1.14'), - ('RSA', 'SHA256'): asn1_univ.ObjectIdentifier('1.2.840.113549.1.1.11'), - ('RSA', 'SHA384'): asn1_univ.ObjectIdentifier('1.2.840.113549.1.1.12'), - ('RSA', 'SHA512'): asn1_univ.ObjectIdentifier('1.2.840.113549.1.1.13'), - ('DSA', 'SHA224'): asn1_univ.ObjectIdentifier('2.16.840.1.101.3.4.3.1'), - ('DSA', 'SHA256'): asn1_univ.ObjectIdentifier('2.16.840.1.101.3.4.3.2'), -} - - -SIGNING_ALGORITHMS_INV = dict((v, k) for k, v in SIGNING_ALGORITHMS.items()) - - -class X509CertificateError(errors.X509Error): - """Specific error for X509 certificate operations.""" - pass - - -class X509Certificate(signature.SignatureMixin): - """X509 certificate class.""" - def __init__(self, certificate=None): - if certificate is None: - self._cert = rfc5280.Certificate() - self._cert['tbsCertificate'] = rfc5280.TBSCertificate() - else: - self._cert = certificate - - @staticmethod - def from_open_file(f): - try: - der_content = pem.readPemFromFile(f) - certificate = decoder.decode(der_content, - asn1Spec=rfc5280.Certificate())[0] - return X509Certificate(certificate) - except Exception: - raise X509CertificateError("Could not read X509 certificate from " - "PEM data.") - - @staticmethod - def from_buffer(data): - """Build this X509 object from a data buffer in memory. - - :param data: A data buffer - """ - return X509Certificate.from_open_file(io.StringIO(data)) - - @staticmethod - def from_file(path): - """Build this X509 certificate object from a data file on disk. - - :param path: A data buffer - """ - with open(path, 'r') as f: - return X509Certificate.from_open_file(f) - - def as_pem(self): - """Serialise this X509 certificate object as PEM string.""" - - header = '-----BEGIN CERTIFICATE-----' - footer = '-----END CERTIFICATE-----' - der_cert = encoder.encode(self._cert) - b64_encoder = (base64.encodestring if str is bytes else - base64.encodebytes) - b64_cert = b64_encoder(der_cert).decode('ascii') - return "%s\n%s%s\n" % (header, b64_cert, footer) - - def set_version(self, v): - """Set the version of this X509 certificate object. - - :param v: The version - """ - self._cert['tbsCertificate']['version'] = v - - def get_version(self): - """Get the version of this X509 certificate object.""" - return self._cert['tbsCertificate']['version'] - - def get_validity(self): - if self._cert['tbsCertificate']['validity'] is None: - self._cert['tbsCertificate']['validity'] = None - return self._cert['tbsCertificate']['validity'] - - def set_not_before(self, t): - """Set the 'not before' date field. - - :param t: time in seconds since the epoch - """ - asn1_time = utils.timestamp_to_asn1_time(t) - validity = self.get_validity() - validity['notBefore'] = asn1_time - - def get_not_before(self): - """Get the 'not before' date field as seconds since the epoch.""" - validity = self.get_validity() - not_before = validity['notBefore'] - return utils.asn1_time_to_timestamp(not_before) - - def set_not_after(self, t): - """Set the 'not after' date field. - - :param t: time in seconds since the epoch - """ - asn1_time = utils.timestamp_to_asn1_time(t) - validity = self.get_validity() - validity['notAfter'] = asn1_time - - def get_not_after(self): - """Get the 'not after' date field as seconds since the epoch.""" - validity = self.get_validity() - not_after = validity['notAfter'] - return utils.asn1_time_to_timestamp(not_after) - - def set_pubkey(self, pkey): - """Set the public key field. - - :param pkey: The public key, rfc5280.SubjectPublicKeyInfo description - """ - self._cert['tbsCertificate']['subjectPublicKeyInfo'] = pkey - - def get_subject(self): - """Get the subject name field value. - - :return: An X509Name object instance - """ - val = self._cert['tbsCertificate']['subject'][0] - return name.X509Name(val) - - def set_subject(self, subject): - """Set the subject name filed value. - - :param subject: An X509Name object instance - """ - val = subject._name_obj - if self._cert['tbsCertificate']['subject'] is None: - self._cert['tbsCertificate']['subject'] = rfc5280.Name() - self._cert['tbsCertificate']['subject'][0] = val - - def set_issuer(self, issuer): - """Set the issuer name field value. - - :param issuer: An X509Name object instance - """ - val = issuer._name_obj - if self._cert['tbsCertificate']['issuer'] is None: - self._cert['tbsCertificate']['issuer'] = rfc5280.Name() - self._cert['tbsCertificate']['issuer'][0] = val - - def get_issuer(self): - """Get the issuer name field value. - - :return: An X509Name object instance - """ - val = self._cert['tbsCertificate']['issuer'][0] - return name.X509Name(val) - - def set_serial_number(self, serial): - """Set the serial number - - The serial number is a 32 bit integer value that should be unique to - each certificate issued by a given certificate authority. - - :param serial: The serial number, 32 bit integer - """ - self._cert['tbsCertificate']['serialNumber'] = serial - - def get_serial_number(self,): - return self._cert['tbsCertificate']['serialNumber'] - - def _get_extensions(self): - if self._cert['tbsCertificate']['extensions'] is None: - # this actually initialises the extensions tag rather than - # assign None - self._cert['tbsCertificate']['extensions'] = None - return self._cert['tbsCertificate']['extensions'] - - def get_extensions(self, ext_type=None): - extensions = self._get_extensions() - return [extension.construct_extension(e) for e in extensions - if ext_type is None or e['extnID'] == ext_type._oid] - - def add_extension(self, ext, index): - """Add an X509 V3 Certificate extension. - - :param ext: An X509Extension instance - :param index: The index of the extension - """ - if not isinstance(ext, extension.X509Extension): - raise errors.X509Error("ext needs to be a pyasn1 extension") - - extensions = self._get_extensions() - extensions[index] = ext.as_asn1() - - def _get_bytes_to_sign(self): - return encoder.encode(self._cert['tbsCertificate']) - - def _embed_signature_algorithm(self, algo_id): - self._cert['tbsCertificate']['signature'] = algo_id - - def _embed_signature(self, algo_id, signature): - self._cert['signature'] = "'%s'H" % ( - str(binascii.hexlify(signature).decode('ascii')),) - self._cert['signatureAlgorithm'] = algo_id - - def _get_signature(self): - return utils.bin_to_bytes(self._cert['signature']) - - def _get_signing_algorithm(self): - tbs_signature = self._cert['tbsCertificate']['signature'] - cert_signature = self._cert['signatureAlgorithm'] - if tbs_signature != cert_signature: - raise errors.X509Error("algorithms mismatch") - - return tbs_signature['algorithm'] - - def as_der(self): - """Return this X509 certificate as DER encoded data.""" - return encoder.encode(self._cert) - - def get_fingerprint(self, md='sha256'): - """Get the fingerprint of this X509 certificate. - - :param md: The message digest algorithm used to compute the fingerprint - :return: The fingerprint encoded as a hex string - """ - hash_class = utils.get_hash_class(md) - if hash_class is None: - raise errors.X509Error( - "Unknown hash %s" % (md,)) - hasher = hashes.Hash(hash_class(), - backend=cio_backends.default_backend()) - hasher.update(self.as_der()) - return binascii.hexlify(hasher.finalize()).upper().decode('ascii') - - def get_key_id(self): - """Construct a key identifier from public key. - - Return the hash useful for keyIdentifier field, constructed as - described in RFC5280 section 4.2.1.2, method 1. The result is - SHA1(subjectPublicKey). - """ - key_info = self._cert['tbsCertificate']['subjectPublicKeyInfo'] - public_key = key_info['subjectPublicKey'] - # get the actual bit string value, without the length and tags - value = ber_encoder.BitStringEncoder().encodeValue( - None, public_key, True, None)[0][1:] - digest = hashes.Hash(hashes.SHA1(), - backend=cio_backends.default_backend()) - digest.update(value) - return digest.finalize() diff --git a/anchor/X509/errors.py b/anchor/X509/errors.py deleted file mode 100644 index b3ed6ef..0000000 --- a/anchor/X509/errors.py +++ /dev/null @@ -1,31 +0,0 @@ -# -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - -# not needed right now, just to be consistent and future-proof -from __future__ import absolute_import - - -class X509Error(Exception): - """Base exception for X509 errors.""" - def __init__(self, what): - super(X509Error, self).__init__(what) - - -class ASN1TimeError(Exception): - """Base exception for ASN1-time related errors.""" - pass - - -class ASN1StringError(X509Error): - """Base exception for ASN1-string related errors.""" - pass diff --git a/anchor/X509/extension.py b/anchor/X509/extension.py deleted file mode 100644 index b00ed51..0000000 --- a/anchor/X509/extension.py +++ /dev/null @@ -1,523 +0,0 @@ -# -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - -from __future__ import absolute_import - -import functools - -import netaddr -from pyasn1.codec.der import decoder -from pyasn1.codec.der import encoder -from pyasn1.type import constraint as asn1_constraint -from pyasn1.type import namedtype as asn1_namedtype -from pyasn1.type import tag as asn1_tag -from pyasn1.type import univ as asn1_univ - -from anchor.asn1 import rfc5280 -from anchor.X509 import errors -from anchor.X509 import utils - - -# missing extended use ids from rfc5280 -id_kp_OCSPSigning = asn1_univ.ObjectIdentifier(rfc5280.id_kp.asTuple() + (9,)) -anyExtendedKeyUsage = asn1_univ.ObjectIdentifier( - rfc5280.id_ce_extKeyUsage.asTuple() + (0,)) - - -# names matching openssl -EXT_KEY_USAGE_NAMES = { - rfc5280.id_kp_serverAuth: "TLS Web Server Authentication", - rfc5280.id_kp_clientAuth: "TLS Web Client Authentication", - rfc5280.id_kp_codeSigning: "Code Signing", - rfc5280.id_kp_emailProtection: "E-mail Protection", - rfc5280.id_kp_timeStamping: "Time Stamping", - id_kp_OCSPSigning: "OCSP Signing", - anyExtendedKeyUsage: "Any Extended Key Usage", -} -EXT_KEY_USAGE_NAMES_INV = dict((v, k) for k, v in EXT_KEY_USAGE_NAMES.items()) - - -EXT_KEY_USAGE_SHORT_NAMES = { - rfc5280.id_kp_serverAuth: "serverAuth", - rfc5280.id_kp_clientAuth: "clientAuth", - rfc5280.id_kp_codeSigning: "codeSigning", - rfc5280.id_kp_emailProtection: "emailProtection", - rfc5280.id_kp_timeStamping: "timeStamping", - id_kp_OCSPSigning: "ocspSigning", - anyExtendedKeyUsage: "anyExtendedKeyUsage", -} -EXT_KEY_USAGE_SHORT_NAMES_INV = dict((v, k) for k, v in - EXT_KEY_USAGE_SHORT_NAMES.items()) - - -EXTENSION_NAMES = { - rfc5280.id_ce_policyConstraints: 'policyConstraints', - rfc5280.id_ce_basicConstraints: 'basicConstraints', - rfc5280.id_ce_subjectDirectoryAttributes: 'subjectDirectoryAttributes', - rfc5280.id_ce_deltaCRLIndicator: 'deltaCRLIndicator', - rfc5280.id_ce_cRLDistributionPoints: 'cRLDistributionPoints', - rfc5280.id_ce_issuingDistributionPoint: 'issuingDistributionPoint', - rfc5280.id_ce_nameConstraints: 'nameConstraints', - rfc5280.id_ce_certificatePolicies: 'certificatePolicies', - rfc5280.id_ce_policyMappings: 'policyMappings', - rfc5280.id_ce_privateKeyUsagePeriod: 'privateKeyUsagePeriod', - rfc5280.id_ce_keyUsage: 'keyUsage', - rfc5280.id_ce_authorityKeyIdentifier: 'authorityKeyIdentifier', - rfc5280.id_ce_subjectKeyIdentifier: 'subjectKeyIdentifier', - rfc5280.id_ce_certificateIssuer: 'certificateIssuer', - rfc5280.id_ce_subjectAltName: 'subjectAltName', - rfc5280.id_ce_issuerAltName: 'issuerAltName', -} - - -LONG_KEY_USAGE_NAMES = { - "Digital Signature": "digitalSignature", - "Non Repudiation": "nonRepudiation", - "Key Encipherment": "keyEncipherment", - "Data Encipherment": "dataEncipherment", - "Key Agreement": "keyAgreement", - "Certificate Sign": "keyCertSign", - "CRL Sign": "cRLSign", - "Encipher Only": "encipherOnly", - "Decipher Only": "decipherOnly", -} - - -def uses_ext_value(f): - """Wrapper allowing reading of extension value. - - Because the value is normally saved in a (double) serialised way, it's - not easily accessible to the member methods. This is made easier by - unpacking the extension value into an extra argument. - """ - @functools.wraps(f) - def ext_value_filled(self, *args, **kwargs): - kwargs['ext_value'] = self._get_value() - return f(self, *args, **kwargs) - return ext_value_filled - - -def modifies_ext_value(f): - """Wrapper allowing modification of extension value. - - Because the value is normally saved in a (double) serialised way, it's - not easily accessible to the member methods. This is made easier by - unpacking the extension value into an extra argument. - New value needs to be returned from the method. - """ - @functools.wraps(f) - def ext_value_filled(self, *args, **kwargs): - value = self._get_value() - kwargs['ext_value'] = value - # since some elements like NamedValue are pure value types, there is - # no interface to modify them and new versions have to be returned - value = f(self, *args, **kwargs) - self._set_value(value) - return ext_value_filled - - -class BasicConstraints(asn1_univ.Sequence): - """Custom BasicConstraint implementation until pyasn1_modules is fixes.""" - componentType = asn1_namedtype.NamedTypes( - asn1_namedtype.DefaultedNamedType('cA', asn1_univ.Boolean(False)), - asn1_namedtype.OptionalNamedType( - 'pathLenConstraint', - asn1_univ.Integer().subtype( - subtypeSpec=asn1_constraint.ValueRangeConstraint(0, 64))) - ) - - -class NameConstraints(asn1_univ.Sequence): - """Custom NameConstraints implementation until pyasn1_modules is fixed.""" - componentType = asn1_namedtype.NamedTypes( - asn1_namedtype.OptionalNamedType( - 'permittedSubtrees', - rfc5280.GeneralSubtrees().subtype( - implicitTag=asn1_tag.Tag(asn1_tag.tagClassContext, - asn1_tag.tagFormatConstructed, 0))), - asn1_namedtype.OptionalNamedType( - 'excludedSubtrees', - rfc5280.GeneralSubtrees().subtype( - implicitTag=asn1_tag.Tag(asn1_tag.tagClassContext, - asn1_tag.tagFormatConstructed, 1))) - ) - - -class X509Extension(object): - """Abstraction for the pyasn1 Extension structures. - - The object should normally be constructed using `construct_extension`, - which will choose the right extension type based on the id. - Each extension has an immutable oid and a spec of the internal value - representation. - Unknown extension types can be still represented by the - X509Extension object and copied/serialised without understanding the - value details. The value will not be displayed properly in the logs - in the case. - """ - _oid = None - spec = None - - """An X509 V3 Certificate extension.""" - def __init__(self, ext=None): - if ext is None: - if self.spec is None: - raise errors.X509Error("cannot create generic extension") - self._ext = rfc5280.Extension() - self._ext['extnID'] = self._oid - self._set_value(self._get_default_value()) - else: - if not isinstance(ext, rfc5280.Extension): - raise errors.X509Error("extension has incorrect type") - self._ext = ext - - @classmethod - def _get_default_value(cls): - # if there are any non-optional fields, this needs to be defined in - # the class - return cls.spec() - - def __str__(self): - return "%s: %s" % (self.get_name(), self.get_value_as_str()) - - def get_value_as_str(self): - return "" - - def get_oid(self): - return self._ext['extnID'] - - def get_name(self): - """Get the extension name as a python string.""" - oid = self.get_oid() - return EXTENSION_NAMES.get(oid, oid) - - def get_critical(self): - return self._ext['critical'] - - def set_critical(self, critical): - self._ext['critical'] = critical - - def _get_value(self): - return decoder.decode(self._ext['extnValue'].asOctets(), - asn1Spec=self.spec())[0] - - def _set_value(self, value): - if not isinstance(value, self.spec): - raise errors.X509Error("extension value has incorrect type") - self._ext['extnValue'] = encoder.encode(value) - - def as_der(self): - return encoder.encode(self._ext) - - def as_asn1(self): - return self._ext - - -class X509ExtensionBasicConstraints(X509Extension): - spec = BasicConstraints - _oid = rfc5280.id_ce_basicConstraints - - @uses_ext_value - def get_ca(self, ext_value=None): - return bool(ext_value['cA']) - - @modifies_ext_value - def set_ca(self, ca, ext_value=None): - ext_value['cA'] = ca - return ext_value - - @uses_ext_value - def get_path_len_constraint(self, ext_value=None): - return ext_value['pathLenConstraint'] - - @modifies_ext_value - def set_path_len_constraint(self, length, ext_value=None): - ext_value['pathLenConstraint'] = length - return ext_value - - def __str__(self): - return "basicConstraints: CA: %s, pathLen: %s" % ( - str(self.get_ca()).upper(), self.get_path_len_constraint()) - - -class X509ExtensionKeyUsage(X509Extension): - spec = rfc5280.KeyUsage - _oid = rfc5280.id_ce_keyUsage - - fields = dict(spec.namedValues.namedValues) - inv_fields = dict((v, k) for k, v in spec.namedValues.namedValues) - - @classmethod - def _get_default_value(cls): - # if there are any non-optional fields, this needs to be defined in - # the class - return cls.spec("''B") - - @uses_ext_value - def get_usage(self, usage, ext_value=None): - usage = LONG_KEY_USAGE_NAMES.get(usage, usage) - pos = self.fields[usage] - if pos >= len(ext_value): - return False - return bool(ext_value[pos]) - - @uses_ext_value - def get_all_usages(self, ext_value=None): - return [self.inv_fields[i] for i, enabled in enumerate(ext_value) - if enabled] - - @modifies_ext_value - def set_usage(self, usage, state, ext_value=None): - usage = LONG_KEY_USAGE_NAMES.get(usage, usage) - pos = self.fields[usage] - values = [x for x in ext_value] - - if state: - while pos >= len(values): - values.append(0) - values[pos] = 1 - else: - if pos < len(values): - values[pos] = 0 - - bits = ''.join(str(x) for x in values) - return self.spec("'%s'B" % bits) - - def __str__(self): - return "keyUsage: " + ", ".join(self.get_all_usages()) - - -class X509ExtensionSubjectAltName(X509Extension): - spec = rfc5280.SubjectAltName - _oid = rfc5280.id_ce_subjectAltName - - @uses_ext_value - def get_dns_ids(self, ext_value=None): - dns_ids = [] - for name in ext_value: - if name.getName() != 'dNSName': - continue - component = name.getComponent() - dns_id = component.asOctets().decode(component.encoding) - dns_ids.append(dns_id) - return dns_ids - - @uses_ext_value - def get_ips(self, ext_value=None): - ips = [] - for name in ext_value: - if name.getName() != 'iPAddress': - continue - ips.append(utils.asn1_to_netaddr(name.getComponent())) - return ips - - @uses_ext_value - def has_unknown_entries(self, ext_value=None): - for name in ext_value: - if name.getName() not in ('dNSName', 'iPAddress'): - return True - return False - - @modifies_ext_value - def add_dns_id(self, dns_id, validate=True, ext_value=None): - new_pos = len(ext_value) - ext_value[new_pos] = None - ext_value[new_pos]['dNSName'] = dns_id - return ext_value - - @modifies_ext_value - def add_ip(self, ip, ext_value=None): - if not isinstance(ip, netaddr.IPAddress): - raise errors.X509Error("not a real ip address provided") - new_pos = len(ext_value) - ext_value[new_pos] = None - ext_value[new_pos]['iPAddress'] = utils.netaddr_to_asn1(ip) - return ext_value - - @uses_ext_value - def __str__(self, ext_value=None): - entries = ["DNS:%s" % (x,) for x in self.get_dns_ids()] - entries += ["IP:%s" % (x,) for x in self.get_ips()] - return "subjectAltName: " + ", ".join(entries) - - -class X509ExtensionNameConstraints(X509Extension): - spec = NameConstraints - _oid = rfc5280.id_ce_nameConstraints - - def _get_permitted(self, ext_value): - return ext_value['permittedSubtrees'] or [] - - def _get_excluded(self, ext_value): - return ext_value['excludedSubtrees'] or [] - - @uses_ext_value - def get_permitted_length(self, ext_value=None): - return len(self._get_permitted(ext_value)) - - @uses_ext_value - def get_permitted_name(self, n, ext_value=None): - name = self._get_permitted(ext_value)[n]['base'] - return (name.getName(), name.getComponent()) - - @uses_ext_value - def get_permitted_range(self, n, ext_value=None): - entry = self._get_permitted(ext_value)[n] - return (entry['minimum'], entry['maximum']) - - @uses_ext_value - def get_excluded_length(self, ext_value=None): - return len(self._get_excluded(ext_value)) - - @uses_ext_value - def get_excluded_name(self, n, ext_value=None): - name = self._get_excluded(ext_value)[n]['base'] - return (name.getName(), name.getComponent()) - - @uses_ext_value - def get_excluded_range(self, n, ext_value=None): - entry = self._get_excluded(ext_value)[n] - return (entry['minimum'], entry['maximum']) - - def _add_to_tree(self, ext_value, tree_name, position, name_type, name): - if ext_value[tree_name] is None: - ext_value[tree_name] = None - ext_value[tree_name][position] = None - ext_value[tree_name][position]['base'] = None - ext_value[tree_name][position]['base'][name_type] = name - ext_value[tree_name][position]['minimum'] = 0 - # maximum should be missing (RFC5280/4.2.1.10) - - @modifies_ext_value - def add_permitted(self, name_type, name, ext_value=None): - last = self.get_permitted_length() - self._add_to_tree(ext_value, 'permittedSubtrees', last, - name_type, name) - return ext_value - - @modifies_ext_value - def add_excluded(self, name_type, name, ext_value=None): - last = self.get_excluded_length() - self._add_to_tree(ext_value, 'excludedSubtrees', last, name_type, name) - return ext_value - - -class X509ExtensionExtendedKeyUsage(X509Extension): - spec = rfc5280.ExtKeyUsageSyntax - _oid = rfc5280.id_ce_extKeyUsage - - _valid = list(EXT_KEY_USAGE_NAMES.keys()) - - @uses_ext_value - def get_all_usages(self, ext_value=None): - return [usage for usage in ext_value] - - @uses_ext_value - def get_usage(self, usage, ext_value=None): - if usage not in self._valid: - raise ValueError("usage not valid") - return (usage in ext_value) - - @modifies_ext_value - def set_usage(self, usage, state, ext_value=None): - if usage not in self._valid: - raise ValueError("usage not valid") - - if state: - if usage not in ext_value: - ext_value[len(ext_value)] = usage - else: - if usage in ext_value: - old = [x for x in ext_value if x != usage] - ext_value.clear() - for i, x in enumerate(old): - ext_value[i] = x - return ext_value - - @uses_ext_value - def __str__(self, ext_value=None): - usages = [EXT_KEY_USAGE_NAMES.get(u) for u in ext_value] - return "extKeyUsage: " + ", ".join(usages) - - -class X509ExtensionAuthorityKeyId(X509Extension): - spec = rfc5280.AuthorityKeyIdentifier - _oid = rfc5280.id_ce_authorityKeyIdentifier - - @uses_ext_value - def get_key_id(self, ext_value=None): - ki = ext_value['keyIdentifier'] - if ki: - return ki.asOctets() - else: - return None - - @uses_ext_value - def get_serial(self, ext_value=None): - return ext_value['authorityCertSerialNumber'] - - @modifies_ext_value - def set_key_id(self, key, ext_value=None): - # new extension, pyasn1 cannot remove values - new_ext = self.spec() - new_ext['keyIdentifier'] = key - return new_ext - - @modifies_ext_value - def set_serial(self, serial, ext_value=None): - # new extension, pyasn1 cannot remove values - new_ext = self.spec() - new_ext['authorityCertSerialNumber'] = int(serial) - return new_ext - - -class X509ExtensionSubjectKeyId(X509Extension): - spec = rfc5280.SubjectKeyIdentifier - _oid = rfc5280.id_ce_subjectKeyIdentifier - - @classmethod - def _get_default_value(cls): - return cls.spec(b"") - - @uses_ext_value - def get_key_id(self, ext_value=None): - return ext_value.asOctets() - - @modifies_ext_value - def set_key_id(self, key, ext_value=None): - return self.spec(key) - - -EXTENSION_CLASSES = { - rfc5280.id_ce_basicConstraints: X509ExtensionBasicConstraints, - rfc5280.id_ce_keyUsage: X509ExtensionKeyUsage, - rfc5280.id_ce_extKeyUsage: X509ExtensionExtendedKeyUsage, - rfc5280.id_ce_subjectAltName: X509ExtensionSubjectAltName, - rfc5280.id_ce_nameConstraints: X509ExtensionNameConstraints, - rfc5280.id_ce_authorityKeyIdentifier: X509ExtensionAuthorityKeyId, - rfc5280.id_ce_subjectKeyIdentifier: X509ExtensionSubjectKeyId, -} - - -def construct_extension(ext): - """Construct an extension object of the right type. - - While X509Extension can provide basic access to the extension elements, - it cannot parse details of extensions. This function detects which type - should be used based on the extension id. - If the type is unknown, generic X509Extension is used instead. - """ - if not isinstance(ext, rfc5280.Extension): - raise errors.X509Error("extension has incorrect type") - ext_class = EXTENSION_CLASSES.get(ext['extnID'], X509Extension) - return ext_class(ext) diff --git a/anchor/X509/name.py b/anchor/X509/name.py deleted file mode 100644 index 72e5343..0000000 --- a/anchor/X509/name.py +++ /dev/null @@ -1,172 +0,0 @@ -# -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - -from __future__ import absolute_import - -from pyasn1.codec.der import decoder -from pyasn1.codec.der import encoder -from pyasn1.type import error as asn1_error -from pyasn1.type import univ as asn1_univ - -from anchor.asn1 import rfc5280 -from anchor.X509 import errors - -OID_commonName = rfc5280.id_at_commonName -OID_localityName = rfc5280.id_at_localityName -OID_stateOrProvinceName = rfc5280.id_at_stateOrProvinceName -OID_organizationName = rfc5280.id_at_organizationName -OID_organizationalUnitName = rfc5280.id_at_organizationalUnitName -OID_countryName = rfc5280.id_at_countryName -OID_pkcs9_emailAddress = rfc5280.id_emailAddress -OID_surname = rfc5280.id_at_surname -OID_givenName = rfc5280.id_at_givenName - -name_oids = { - rfc5280.id_at_name: rfc5280.X520name, - rfc5280.id_at_surname: rfc5280.X520name, - rfc5280.id_at_givenName: rfc5280.X520name, - rfc5280.id_at_initials: rfc5280.X520name, - rfc5280.id_at_generationQualifier: rfc5280.X520name, - rfc5280.id_at_commonName: rfc5280.X520CommonName, - rfc5280.id_at_localityName: rfc5280.X520LocalityName, - rfc5280.id_at_stateOrProvinceName: rfc5280.X520StateOrProvinceName, - rfc5280.id_at_organizationName: rfc5280.X520OrganizationName, - rfc5280.id_at_organizationalUnitName: rfc5280.X520OrganizationalUnitName, - rfc5280.id_at_title: rfc5280.X520Title, - rfc5280.id_at_dnQualifier: rfc5280.X520dnQualifier, - rfc5280.id_at_countryName: rfc5280.X520countryName, - rfc5280.id_emailAddress: rfc5280.EmailAddress, -} - -code_names = { - rfc5280.id_at_commonName: "CN", - rfc5280.id_at_localityName: "L", - rfc5280.id_at_stateOrProvinceName: "ST", - rfc5280.id_at_organizationName: "O", - rfc5280.id_at_organizationalUnitName: "OU", - rfc5280.id_at_countryName: "C", - rfc5280.id_at_givenName: "GN", - rfc5280.id_at_surname: "SN", - rfc5280.id_emailAddress: "emailAddress", -} - -short_names = { - rfc5280.id_at_commonName: "commonName", - rfc5280.id_at_localityName: "localityName", - rfc5280.id_at_stateOrProvinceName: "stateOrProvinceName", - rfc5280.id_at_organizationName: "organizationName", - rfc5280.id_at_organizationalUnitName: "organizationalUnitName", - rfc5280.id_at_countryName: "countryName", - rfc5280.id_at_givenName: "givenName", - rfc5280.id_at_surname: "surname", - rfc5280.id_emailAddress: "emailAddress", -} - - -class X509Name(object): - """An X509 Name object.""" - - class Entry(): - """An X509 Name sub-entry object.""" - def __init__(self, obj): - self._obj = obj - - def __str__(self): - return "%s: %s" % (self.get_name(), self.get_value()) - - def get_oid(self): - return self._obj[0]['type'] - - def get_name(self): - """Get the name of this entry. - - :return: entry name as a python string - """ - oid = self.get_oid() - return short_names.get(oid, str(oid)) - - def get_code(self): - """Get the name of this entry. - - :return: entry name as a python string - """ - oid = self.get_oid() - return code_names.get(oid, str(oid)) - - def get_value(self): - """Get the value of this entry. - - :return: entry value as a python string - """ - value = self._obj[0]['value'] - der = value.asOctets() - oid = self.get_oid() - if oid not in name_oids: - return 'UNKNOWN' - - name_spec = name_oids[oid]() - - value = decoder.decode(der, asn1Spec=name_spec)[0] - if hasattr(value, 'getComponent'): - value = value.getComponent() - return value.asOctets().decode(value.encoding) - - def __init__(self, name_obj=None): - if name_obj is not None: - if not isinstance(name_obj, rfc5280.RDNSequence): - raise TypeError("name is not an RDNSequence") - self._name_obj = name_obj.clone(cloneValueFlag=True) - else: - self._name_obj = rfc5280.RDNSequence() - - def __str__(self): - return '/' + '/'.join("%s=%s" % (e.get_code(), e.get_value()) - for e in self) - - def __len__(self): - return len(self._name_obj) - - def __getitem__(self, idx): - return X509Name.Entry(self._name_obj[idx]) - - def __iter__(self): - for i in range(len(self)): - yield self[i] - - def add_name_entry(self, oid, text): - if not isinstance(oid, asn1_univ.ObjectIdentifier): - raise errors.X509Error("oid '%s' is not valid" % (oid,)) - atv = rfc5280.AttributeTypeAndValue() - atv['type'] = oid - name_type = name_oids[oid] - try: - if name_type in (rfc5280.X520countryName, rfc5280.EmailAddress): - val = name_type(text) - else: - val = name_type() - val['utf8String'] = text - except asn1_error.ValueConstraintError: - raise errors.X509Error("Name '%s' is not valid" % text) - atv['value'] = rfc5280.AttributeValue(encoder.encode(val)) - - entry = rfc5280.RelativeDistinguishedName() - entry[0] = atv - self._name_obj[len(self)] = entry - - def get_entries_by_oid(self, oid): - """Get a name entry corresponding to an NID name. - - :param nid: an NID for the new name entry - :return: An X509Name.Entry object - """ - return [entry for entry in self if entry.get_oid() == oid] diff --git a/anchor/X509/signature.py b/anchor/X509/signature.py deleted file mode 100644 index ef7dfb6..0000000 --- a/anchor/X509/signature.py +++ /dev/null @@ -1,175 +0,0 @@ -# -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - -from __future__ import absolute_import - -import logging - -from cryptography import exceptions as cio_exceptions -from cryptography.hazmat.primitives.asymmetric import dsa -from cryptography.hazmat.primitives.asymmetric import padding -from cryptography.hazmat.primitives.asymmetric import rsa -from cryptography.hazmat.primitives import hashes -from pyasn1.codec.der import encoder -from pyasn1.type import univ as asn1_univ - -from anchor.asn1 import rfc5280 -from anchor.X509 import errors - - -LOG = logging.getLogger(__name__) - -DEPRECATED_ALGORITHM_NAMES = { - asn1_univ.ObjectIdentifier('1.2.840.113549.1.1.2'): 'MD2 with RSA', - asn1_univ.ObjectIdentifier('1.2.840.113549.1.1.3'): 'MD4 with RSA', - asn1_univ.ObjectIdentifier('1.2.840.113549.1.1.4'): 'MD5 with RSA', - asn1_univ.ObjectIdentifier('1.2.840.113549.1.1.5'): 'SHA1 with RSA', - asn1_univ.ObjectIdentifier('1.2.840.10040.4.3'): 'SHA1 with DSA', -} - -# valid algorithms -sha224WithRSAEncryption = asn1_univ.ObjectIdentifier('1.2.840.113549.1.1.14') -sha256WithRSAEncryption = asn1_univ.ObjectIdentifier('1.2.840.113549.1.1.11') -sha384WithRSAEncryption = asn1_univ.ObjectIdentifier('1.2.840.113549.1.1.12') -sha512WithRSAEncryption = asn1_univ.ObjectIdentifier('1.2.840.113549.1.1.13') -id_dsa_with_sha224 = asn1_univ.ObjectIdentifier('2.16.840.1.101.3.4.3.1') -id_dsa_with_sha256 = asn1_univ.ObjectIdentifier('2.16.840.1.101.3.4.3.2') - -SIGNING_ALGORITHMS = { - ('RSA', 'SHA224'): sha224WithRSAEncryption, - ('RSA', 'SHA256'): sha256WithRSAEncryption, - ('RSA', 'SHA384'): sha384WithRSAEncryption, - ('RSA', 'SHA512'): sha512WithRSAEncryption, - ('DSA', 'SHA224'): id_dsa_with_sha224, - ('DSA', 'SHA256'): id_dsa_with_sha256, -} - - -SIGNING_ALGORITHMS_INV = dict((v, k) for k, v in SIGNING_ALGORITHMS.items()) - - -VERIFIER_CONSTRUCTION = { - sha224WithRSAEncryption: (lambda key, signature: key.verifier( - signature, padding.PKCS1v15(), hashes.SHA224())), - sha256WithRSAEncryption: (lambda key, signature: key.verifier( - signature, padding.PKCS1v15(), hashes.SHA256())), - sha384WithRSAEncryption: (lambda key, signature: key.verifier( - signature, padding.PKCS1v15(), hashes.SHA384())), - sha512WithRSAEncryption: (lambda key, signature: key.verifier( - signature, padding.PKCS1v15(), hashes.SHA512())), - id_dsa_with_sha224: (lambda key, signature: key.verifier( - signature, hashes.SHA224())), - id_dsa_with_sha256: (lambda key, signature: key.verifier( - signature, hashes.SHA256())), -} - - -ALGORITHM_PARAMETERS = { - sha224WithRSAEncryption: encoder.encode(asn1_univ.Null()), - sha256WithRSAEncryption: encoder.encode(asn1_univ.Null()), - sha384WithRSAEncryption: encoder.encode(asn1_univ.Null()), - sha512WithRSAEncryption: encoder.encode(asn1_univ.Null()), - id_dsa_with_sha224: None, - id_dsa_with_sha256: None, -} - - -class SignatureMixin(object): - """Provides the sign() and verify() functions. - - Both operations rely on the functions provided by the certificate and - csr classes. - """ - def sign(self, encryption, md, signer): - """Sign the current object.""" - md = md.upper() - - signature_type = SIGNING_ALGORITHMS.get((encryption, md)) - if signature_type is None: - raise errors.X509Error( - "Unknown encryption/hash combination %s/%s" % (encryption, md)) - - algo_id = rfc5280.AlgorithmIdentifier() - algo_id['algorithm'] = signature_type - algo_params = ALGORITHM_PARAMETERS[signature_type] - if algo_params is not None: - algo_id['parameters'] = algo_params - - self._embed_signature_algorithm(algo_id) - to_sign = self._get_bytes_to_sign() - signature = signer(to_sign) - - self._embed_signature(algo_id, signature) - - def verify(self, key=None): - algo_id = self._get_signing_algorithm() - if algo_id not in SIGNING_ALGORITHMS_INV: - LOG.warning("Signature algorithm %s is unknown, cannot verify", - algo_id) - return False - - if key is None: - key = self._get_public_key() - - encryption, hash_algo = SIGNING_ALGORITHMS_INV[algo_id] - to_sign = self._get_bytes_to_sign() - signature = self._get_signature() - if ((encryption == 'RSA' and not isinstance(key, rsa.RSAPublicKey)) or - (encryption == 'DSA' and not isinstance(key, - dsa.DSAPublicKey))): - raise errors.X509Error("Key type mismatch: object %s, key %s" % - (encryption, key.__class__)) - verifier = VERIFIER_CONSTRUCTION[algo_id](key, signature) - - verifier.update(to_sign) - try: - verifier.verify() - return True - except cio_exceptions.InvalidSignature: - return False - - def uses_deprecated_algorithm(self): - """Check for deprecated algorithm in signatures. - - Returns the name of the algorithm found, or None if everything's ok. - """ - name = DEPRECATED_ALGORITHM_NAMES.get(self._get_signing_algorithm()) - return name - - def _get_bytes_to_sign(self): - """Get bytes which are giong to be hashed and signed.""" - raise NotImplementedError() - - def _get_public_key(self): - """Get public key for verifying CSR self-signatures.""" - raise NotImplementedError() - - def _get_signature(self): - """Get the current signature value as bytes.""" - raise NotImplementedError() - - def _get_signing_algorithm(self): - """Get the description of algorithm used to sign object.""" - raise NotImplementedError() - - def _embed_signature_algorithm(self, algo_id): - """Called before the signature is calculated. - - Since signature of the certificate depends on the signature algorithm, - it needs to be saved first. - """ - raise NotImplementedError() - - def _embed_signature(self, algo_id, signature): - """Called after the signature is calculated.""" - raise NotImplementedError() diff --git a/anchor/X509/signing_request.py b/anchor/X509/signing_request.py deleted file mode 100644 index c47be2f..0000000 --- a/anchor/X509/signing_request.py +++ /dev/null @@ -1,244 +0,0 @@ -# -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - -from __future__ import absolute_import - -import binascii -import io - -from pyasn1.codec.der import decoder -from pyasn1.codec.der import encoder -from pyasn1.type import univ as asn1_univ - -from anchor.asn1 import rfc5280 -from anchor.asn1 import rfc6402 -from anchor import util -from anchor.X509 import errors -from anchor.X509 import extension -from anchor.X509 import name -from anchor.X509 import signature -from anchor.X509 import utils as x509_utils - - -OID_extensionRequest = asn1_univ.ObjectIdentifier('1.2.840.113549.1.9.14') - - -class X509CsrError(errors.X509Error): - def __init__(self, what): - super(X509CsrError, self).__init__(what) - - -class X509Csr(signature.SignatureMixin): - """An X509 Certificate Signing Request.""" - def __init__(self, csr=None): - if csr is None: - self._csr = rfc6402.CertificationRequest() - else: - self._csr = csr - - @staticmethod - def from_open_file(f, encoding='pem'): - if encoding == 'pem': - try: - der_content = util.extract_pem(f.read()) - except IOError: - raise X509CsrError("Could not read from source %s" % f) - except Exception: - raise X509CsrError( - "Data source not readable or not in PEM format") - - if not der_content: - raise X509CsrError("No PEM data found") - elif encoding == 'der': - der_content = f.read() - else: - raise X509CsrError("Unknown encoding") - - try: - csr = decoder.decode(der_content, - asn1Spec=rfc6402.CertificationRequest())[0] - return X509Csr(csr) - except Exception: - raise X509CsrError("Could not read X509 certificate from data.") - - @staticmethod - def from_buffer(data, encoding='pem'): - """Create this CSR from a buffer - - :param data: The data buffer - """ - return X509Csr.from_open_file(io.BytesIO(data), encoding) - - @staticmethod - def from_file(path, encoding='pem'): - """Create this CSR from a file on disk - - :param path: Path to the file on disk - """ - try: - with open(path, 'r') as f: - return X509Csr.from_open_file(f, encoding) - except IOError: - raise X509CsrError("Could not read file %s" % path) - - def get_pubkey(self): - """Get the public key from the CSR - - :return: ASN.1 description of public key - """ - return self._csr['certificationRequestInfo']['subjectPublicKeyInfo'] - - def get_request_info(self): - if self._csr['certificationRequestInfo'] is None: - self._csr['certificationRequestInfo'] = None - return self._csr['certificationRequestInfo'] - - def get_subject(self): - """Get the subject name field from the CSR - - :return: an X509Name object - """ - ri = self.get_request_info() - if ri['subject'] is None: - ri['subject'] = None - # setup first RDN sequence - ri['subject'][0] = None - - subject = ri['subject'][0] - return name.X509Name(subject) - - def set_subject(self, subject): - if not isinstance(subject, name.X509Name): - raise TypeError("subject must be an X509Name") - ri = self.get_request_info() - if ri['subject'] is None: - ri['subject'] = None - - ri['subject'][0] = subject._name_obj - - def get_attributes(self): - ri = self.get_request_info() - if ri['attributes'] is None: - ri['attributes'] = None - return ri['attributes'] - - def get_subject_cn(self): - """Get the CN part of subject. - - :return subject's CN - """ - subject = self.get_subject() - cns = subject.get_entries_by_oid(name.OID_commonName) - return [cn.get_value() for cn in cns] - - def get_extensions(self, ext_type=None): - """Get the list of all X509 V3 Extensions on this CSR - - :return: a list of X509Extension objects - """ - ext_attrs = [a for a in self.get_attributes() - if a['attrType'] == OID_extensionRequest] - if len(ext_attrs) == 0: - return [] - else: - exts_der = ext_attrs[0]['attrValues'][0].asOctets() - exts = decoder.decode(exts_der, asn1Spec=rfc5280.Extensions())[0] - return [extension.construct_extension(e) for e in exts - if ext_type is None or e['extnID'] == ext_type._oid] - - def add_extension(self, new_ext): - """Add a new extension or replace existing one.""" - if not isinstance(new_ext, extension.X509Extension): - raise errors.X509Error("ext is not an anchor X509Extension") - attributes = self.get_attributes() - ext_attrs = [a for a in attributes - if a['attrType'] == OID_extensionRequest] - if not ext_attrs: - new_attr_index = len(attributes) - attributes[new_attr_index] = None - ext_attr = attributes[new_attr_index] - ext_attr['attrType'] = OID_extensionRequest - ext_attr['attrValues'] = None - exts = rfc5280.Extensions() - else: - ext_attr = ext_attrs[0] - exts = decoder.decode(ext_attr['attrValues'][0].asOctets(), - asn1Spec=rfc5280.Extensions())[0] - - # the end is the default position - new_ext_index = len(exts) - # unless there's an existing extension with the same OID - for i, ext_i in enumerate(exts): - if ext_i['extnID'] == new_ext.get_oid(): - new_ext_index = i - break - - exts[new_ext_index] = new_ext._ext - - ext_attr['attrValues'][0] = encoder.encode(exts) - - def get_subject_dns_ids(self): - names = [] - for ext in self.get_extensions(extension.X509ExtensionSubjectAltName): - for dns_id in ext.get_dns_ids(): - names.append(dns_id) - return names - - def get_subject_ip_ids(self): - names = [] - for ext in self.get_extensions(extension.X509ExtensionSubjectAltName): - for ip in ext.get_ips(): - names.append(ip) - return names - - def has_unknown_san_entries(self): - for ext in self.get_extensions(extension.X509ExtensionSubjectAltName): - if ext.has_unknown_entries(): - return True - return False - - def get_public_key_algo(self): - csr_info = self._csr['certificationRequestInfo'] - key_info = csr_info['subjectPublicKeyInfo'] - return key_info['algorithm']['algorithm'] - - def get_public_key_size(self): - return self._get_public_key().key_size - - def get_public_key(self): - return self._get_public_key() - - def get_signing_algorithm(self): - return self._get_signing_algorithm() - - def _get_signature(self): - return x509_utils.bin_to_bytes(self._csr['signature']) - - def _get_signing_algorithm(self): - return self._csr['signatureAlgorithm']['algorithm'] - - def _get_public_key(self): - csr_info = self._csr['certificationRequestInfo'] - key_info = csr_info['subjectPublicKeyInfo'] - return x509_utils.get_public_key_from_der(encoder.encode(key_info)) - - def _get_bytes_to_sign(self): - return encoder.encode(self._csr['certificationRequestInfo']) - - def _embed_signature_algorithm(self, algo_id): - pass - - def _embed_signature(self, algo_id, signature): - self._csr['signatureAlgorithm'] = algo_id - self._csr['signature'] = "'%s'H" % ( - str(binascii.hexlify(signature).decode('ascii')),) diff --git a/anchor/X509/utils.py b/anchor/X509/utils.py deleted file mode 100644 index 7fca4e0..0000000 --- a/anchor/X509/utils.py +++ /dev/null @@ -1,180 +0,0 @@ -# -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - -from __future__ import absolute_import - -import calendar -import datetime -import struct - -from cryptography.hazmat import backends -from cryptography.hazmat.primitives import hashes -from cryptography.hazmat.primitives import serialization -import netaddr -from pyasn1.type import useful as asn1_useful - -from anchor.asn1 import rfc5280 -from anchor.X509 import errors - - -def create_timezone(minute_offset): - """Create a new timezone with a specified offset. - - Since tzinfo is just a base class, and tzinfo subclasses need a - no-arguments __init__(), we need to generate a new class dynamically. - - :param minute_offset: total timezone offset in minutes - """ - - class SpecificTZ(datetime.tzinfo): - def utcoffset(self, _dt): - return datetime.timedelta(minutes=minute_offset) - - def dst(self, _dt): - return datetime.timedelta(0) - - def tzname(self, _dt): - return None - - def __repr__(self): - sign = "+" if minute_offset > 0 else "-" - hh = minute_offset / 60 - mm = minute_offset % 60 - return "Timezone %s%02i%02i" % (sign, hh, mm) - - return SpecificTZ() - - -def asn1_time_to_timestamp(t): - """Convert from ASN1_TIME type to a UTC-based timestamp. - - :param t: ASN1_TIME to convert - """ - component = t.getComponent() - timestring = component.asOctets().decode(component.encoding) - if isinstance(component, asn1_useful.UTCTime): - if int(timestring[0]) >= 5: - timestring = "19" + timestring - else: - timestring = "20" + timestring - return asn1_timestring_to_timestamp(timestring) - - -def asn1_timestring_to_timestamp(timestring): - """Convert from ASN1_GENERALIZEDTIME to UTC-based timestamp. - - :param gt: ASN1_GENERALIZEDTIME to convert - """ - - # ASN1_GENERALIZEDTIME is actually a string in known formats, - # so the conversion can be done in this code - before_tz = timestring[:14] - tz_str = timestring[14:] - d = datetime.datetime.strptime(before_tz, "%Y%m%d%H%M%S") - if tz_str == 'Z': - # YYYYMMDDhhmmssZ - d.replace(tzinfo=create_timezone(0)) - else: - # YYYYMMDDhhmmss+hhmm - # YYYYMMDDhhmmss-hhmm - sign = -1 if tz_str[0] == '-' else 1 - hh = tz_str[1:3] - mm = tz_str[3:5] - minute_offset = sign * (int(mm) + int(hh) * 60) - d.replace(tzinfo=create_timezone(minute_offset)) - return calendar.timegm(d.timetuple()) - - -def timestamp_to_asn1_time(t): - """Convert from UTC-based timestamp to ASN1_TIME - - :param t: time in seconds since the epoch - """ - - d = datetime.datetime.utcfromtimestamp(t) - asn1time = rfc5280.Time() - if d.year <= 2049: - time_str = d.strftime("%y%m%d%H%M%SZ").encode('ascii') - asn1time['utcTime'] = time_str - else: - time_str = d.strftime("%Y%m%d%H%M%SZ").encode('ascii') - asn1time['generalTime'] = time_str - return asn1time - - -# chr good for py2 and py3 -_chr = chr if str is bytes else lambda x: bytes([x]) - - -# functions needed for converting the pyasn1 signature fields -def bin_to_bytes(bits): - """Convert bit string to byte string.""" - bits = ''.join(str(b) for b in bits) - bits = _pad_byte(bits) - octets = [bits[8*i:8*(i+1)] for i in range(len(bits)//8)] - byte_list = [_chr(int(x, 2)) for x in octets] - return b"".join(byte_list) - - -# ord good for py2 and py3 -_ord = ord if str is bytes else lambda x: x - - -def _pad_byte(bits): - """Pad a string of bits with zeros to make its length a multiple of 8.""" - r = len(bits) % 8 - return ((8-r) % 8)*'0' + bits - - -def get_hash_class(md): - return getattr(hashes, md.upper(), None) - - -def get_private_key_from_pem(data): - return serialization.load_pem_private_key( - data, None, backend=backends.default_backend()) - - -def get_public_key_from_der(data): - return serialization.load_der_public_key( - data, backend=backends.default_backend()) - - -def get_private_key_from_file(path): - with open(path, 'rb') as f: - return get_private_key_from_pem(f.read()) - - -def asn1_to_netaddr(octet_string): - """Translate the ASN1 IP format to netaddr object.""" - if not isinstance(octet_string, rfc5280.univ.OctetString): - raise TypeError("not an OctetString") - - ip_bytes = octet_string.asOctets() - if len(ip_bytes) == 4: - ip_num = struct.unpack(">I", ip_bytes)[0] - return netaddr.IPAddress(ip_num, 4) - elif len(ip_bytes) == 16: - ip_num_front, ip_num_back = struct.unpack(">QQ", ip_bytes) - ip_num = ip_num_front << 64 | ip_num_back - return netaddr.IPAddress(ip_num, 6) - else: - raise TypeError("ip address is neither v4 nor v6") - - -def netaddr_to_asn1(ip): - """Translate the netaddr object to ASN1 IP format.""" - if not isinstance(ip, netaddr.IPAddress): - raise errors.X509Error("not a real ip address provided") - - return bytes(ip.packed) diff --git a/anchor/__init__.py b/anchor/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/anchor/app.py b/anchor/app.py deleted file mode 100644 index 00f9266..0000000 --- a/anchor/app.py +++ /dev/null @@ -1,237 +0,0 @@ -# -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - -from __future__ import absolute_import - -import logging -import os -import sys - -import paste -from paste import translogger # noqa -import pecan - -from anchor import audit -from anchor import errors -from anchor import jsonloader - -logger = logging.getLogger(__name__) - - -def config_check_domains(validator_set): - for name, step in validator_set.items(): - if 'allowed_domains' in step: - for domain in step['allowed_domains']: - if not domain.startswith('.'): - raise errors.ConfigValidationException( - "Domain that does not start with " - "a '.' <{}>".format(domain)) - - -def validate_config(conf): - for old_name in ['auth', 'ca', 'validators']: - if old_name in conf.config: - raise errors.ConfigValidationException( - "The config seems to be for an old version of Anchor. Please " - "check documentation.") - - if not conf.config.get('registration_authority'): - raise errors.ConfigValidationException( - "No registration authorities present") - - if not conf.config.get('signing_ca'): - raise errors.ConfigValidationException( - "No signing CA configurations present") - - if not conf.config.get('authentication'): - raise errors.ConfigValidationException( - "No authentication methods present") - - for name in conf.registration_authority.keys(): - logger.info("Checking config for registration authority: %s", name) - validate_registration_authority_config(name, conf) - - for name in conf.signing_ca.keys(): - logger.info("Checking config for signing ca: %s", name) - validate_signing_ca_config(name, conf) - - for name in conf.authentication.keys(): - logger.info("Checking config for authentication method: %s", name) - validate_authentication_config(name, conf) - - validate_audit_config(conf) - - -def validate_audit_config(conf): - valid_targets = ('messaging', 'log') - - if not conf.config.get('audit'): - # no audit configuration - that's ok - return - - audit_conf = conf.audit - if audit_conf.get('target', 'log') not in valid_targets: - raise errors.ConfigValidationException( - "Audit target not known (expected one of %s)" % ( - ", ".join(valid_targets),)) - - if audit_conf.get('target') == 'messaging': - if audit_conf.get('url') is None: - raise errors.ConfigValidationException("Audit url required") - - -def validate_authentication_config(name, conf): - auth_conf = conf.authentication[name] - - default_user = "myusername" - default_secret = "simplepassword" - - if not auth_conf.get('backend'): - raise errors.ConfigValidationException( - "Authentication method %s doesn't define backend" % name) - - if auth_conf['backend'] not in ('static', 'keystone', 'ldap'): - raise errors.ConfigValidationException( - "Authentication backend % unknown" % (auth_conf['backend'],)) - - # Check for anchor being run with default user/secret - if auth_conf['backend'] == 'static': - if auth_conf['user'] == default_user: - logger.warning("default user for static auth in use") - if auth_conf['secret'] == default_secret: - logger.warning("default secret for static auth in use") - - -def validate_signing_ca_config(name, conf): - ca_conf = conf.signing_ca[name] - backend_name = ca_conf.get('backend') - if not backend_name: - raise errors.ConfigValidationException( - "Backend type not defined for RA '%s'" % name) - sign_func = jsonloader.conf.get_signing_backend(backend_name) - if not sign_func: - raise errors.ConfigValidationException( - "Backend '%s' could not be found" % backend_name) - - if hasattr(sign_func, "_config_validator"): - sign_func._config_validator(name, ca_conf) - - -def validate_registration_authority_config(ra_name, conf): - ra_conf = conf.registration_authority[ra_name] - auth_name = ra_conf.get('authentication') - if not auth_name: - raise errors.ConfigValidationException( - "No authentication configured for registration authority: %s" % - ra_name) - - if not conf.authentication.get(auth_name): - raise errors.ConfigValidationException( - "Authentication method %s configured for registration authority " - "%s doesn't exist" % (auth_name, ra_name)) - - ca_name = ra_conf.get('signing_ca') - if not ca_name: - raise errors.ConfigValidationException( - "No signing CA configuration present for registration authority: " - "%s" % ra_name) - - if not conf.signing_ca.get(ca_name): - raise errors.ConfigValidationException( - "Signing CA %s configured for registration authority %s doesn't " - "exist" % (ca_name, ra_name)) - - if not ra_conf.get("validators"): - raise errors.ConfigValidationException( - "No validators configured for registration authority: %s" % - ra_name) - - ra_validators = ra_conf['validators'] - - for step in ra_validators.keys(): - try: - jsonloader.conf.get_validator(step) - except KeyError: - raise errors.ConfigValidationException( - "Unknown validator <{}> found (for registration " - "authority {})".format(step, ra_name)) - - config_check_domains(ra_validators) - logger.info("Validators OK for registration authority: %s", ra_name) - - ra_fixups = ra_conf.get('fixups', {}) - - for step in ra_fixups.keys(): - try: - jsonloader.conf.get_fixup(step) - except KeyError: - raise errors.ConfigValidationException( - "Unknown fixup <{}> found (for registration " - "authority {})".format(step, ra_name)) - - logger.info("Fixups OK for registration authority: %s", ra_name) - - -def load_config(): - """Attempt to find and load a JSON configuration file. - - We will search in various locations in order for a valid config file - to use: - - - the contents of 'ANCHOR_CONF' environment variable - - a local 'config.json' file in the invocation folder - - a HOME/.config/anchor/config.json file - - a /etc/anchor/config.json file - """ - config_name = 'ANCHOR_CONF' - local_config_path = 'config.json' - user_config_path = os.path.join( - os.environ['HOME'], '.config', 'anchor', 'config.json') - - prefix = os.environ.get('VIRTUAL_ENV', os.sep) - sys_config_path = os.path.join(prefix, 'etc', 'anchor', 'config.json') - - if 'registration_authority' not in jsonloader.conf.config: - config_path = "" - if config_name in os.environ: - config_path = os.environ[config_name] - elif os.path.isfile(local_config_path): - config_path = local_config_path - elif os.path.isfile(user_config_path): - config_path = user_config_path - elif os.path.isfile(sys_config_path): - config_path = sys_config_path - logger = logging.getLogger("anchor") - logger.info("using config: {}".format(config_path)) - jsonloader.conf.load_file_data(config_path) - - jsonloader.conf.load_extensions() - - -def setup_app(config): - # initial logging, will be re-configured later - logging.basicConfig(stream=sys.stdout, level=logging.DEBUG) - app_conf = dict(config.app) - - load_config() - validate_config(jsonloader.conf) - - audit.init_audit() - - app = pecan.make_app( - app_conf.pop('root'), - logging=config.logging, - **app_conf - ) - - return paste.translogger.TransLogger(app, setup_console_handler=False) diff --git a/anchor/asn1/__init__.py b/anchor/asn1/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/anchor/asn1/rfc3280.py b/anchor/asn1/rfc3280.py deleted file mode 100644 index ff7ca11..0000000 --- a/anchor/asn1/rfc3280.py +++ /dev/null @@ -1,1505 +0,0 @@ -# Auto-generated by asn1ate on 2015-12-18 15:55:07.711326 -from pyasn1.type import univ, char, namedtype, namedval, tag, constraint, useful - -MAX = 64 - - -def _OID(*components): - output = [] - for x in tuple(components): - if isinstance(x, univ.ObjectIdentifier): - output.extend(list(x)) - else: - output.append(int(x)) - - return univ.ObjectIdentifier(output) - - -unformatted_postal_address = univ.Integer(16) - - -ub_organizational_units = univ.Integer(4) - - -ub_organizational_unit_name_length = univ.Integer(32) - - -class OrganizationalUnitName(char.PrintableString): - pass - - -OrganizationalUnitName.subtypeSpec = constraint.ValueSizeConstraint(1, ub_organizational_unit_name_length) - - -class OrganizationalUnitNames(univ.SequenceOf): - pass - - -OrganizationalUnitNames.componentType = OrganizationalUnitName() -OrganizationalUnitNames.subtypeSpec=constraint.ValueSizeConstraint(1, ub_organizational_units) - - -class AttributeType(univ.ObjectIdentifier): - pass - - -id_at = _OID(2, 5, 4) - - -id_at_name = _OID(id_at, 41) - - -ub_pds_parameter_length = univ.Integer(30) - - -class PDSParameter(univ.Set): - pass - - -PDSParameter.componentType = namedtype.NamedTypes( - namedtype.OptionalNamedType('printable-string', char.PrintableString().subtype(subtypeSpec=constraint.ValueSizeConstraint(1, ub_pds_parameter_length))), - namedtype.OptionalNamedType('teletex-string', char.TeletexString().subtype(subtypeSpec=constraint.ValueSizeConstraint(1, ub_pds_parameter_length))) -) - - -class PhysicalDeliveryOrganizationName(PDSParameter): - pass - - -ub_organization_name_length = univ.Integer(64) - - -ub_domain_defined_attribute_type_length = univ.Integer(8) - - -ub_domain_defined_attribute_value_length = univ.Integer(128) - - -class TeletexDomainDefinedAttribute(univ.Sequence): - pass - - -TeletexDomainDefinedAttribute.componentType = namedtype.NamedTypes( - namedtype.NamedType('type', char.TeletexString().subtype(subtypeSpec=constraint.ValueSizeConstraint(1, ub_domain_defined_attribute_type_length))), - namedtype.NamedType('value', char.TeletexString().subtype(subtypeSpec=constraint.ValueSizeConstraint(1, ub_domain_defined_attribute_value_length))) -) - - -id_pkix = _OID(1, 3, 6, 1, 5, 5, 7) - - -id_qt = _OID(id_pkix, 2) - - -class PresentationAddress(univ.Sequence): - pass - - -PresentationAddress.componentType = namedtype.NamedTypes( - namedtype.OptionalNamedType('pSelector', univ.OctetString().subtype(explicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 0))), - namedtype.OptionalNamedType('sSelector', univ.OctetString().subtype(explicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 1))), - namedtype.OptionalNamedType('tSelector', univ.OctetString().subtype(explicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 2))), - namedtype.NamedType('nAddresses', univ.SetOf(componentType=univ.OctetString()).subtype(explicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 3))) -) - - -class AlgorithmIdentifier(univ.Sequence): - pass - - -AlgorithmIdentifier.componentType = namedtype.NamedTypes( - namedtype.NamedType('algorithm', univ.ObjectIdentifier()), - namedtype.OptionalNamedType('parameters', univ.Any()) -) - - -class UniqueIdentifier(univ.BitString): - pass - - -class Extension(univ.Sequence): - pass - - -Extension.componentType = namedtype.NamedTypes( - namedtype.NamedType('extnID', univ.ObjectIdentifier()), - namedtype.DefaultedNamedType('critical', univ.Boolean().subtype(value=0)), - namedtype.NamedType('extnValue', univ.OctetString()) -) - - -class Extensions(univ.SequenceOf): - pass - - -Extensions.componentType = Extension() -Extensions.subtypeSpec=constraint.ValueSizeConstraint(1, MAX) - - -class CertificateSerialNumber(univ.Integer): - pass - - -class SubjectPublicKeyInfo(univ.Sequence): - pass - - -SubjectPublicKeyInfo.componentType = namedtype.NamedTypes( - namedtype.NamedType('algorithm', AlgorithmIdentifier()), - namedtype.NamedType('subjectPublicKey', univ.BitString()) -) - - -class Time(univ.Choice): - pass - - -Time.componentType = namedtype.NamedTypes( - namedtype.NamedType('utcTime', useful.UTCTime()), - namedtype.NamedType('generalTime', useful.GeneralizedTime()) -) - - -class Validity(univ.Sequence): - pass - - -Validity.componentType = namedtype.NamedTypes( - namedtype.NamedType('notBefore', Time()), - namedtype.NamedType('notAfter', Time()) -) - - -class Version(univ.Integer): - pass - - -Version.namedValues = namedval.NamedValues( - ('v1', 0), - ('v2', 1), - ('v3', 2) -) - - -class AttributeValue(univ.Any): - pass - - -class AttributeTypeAndValue(univ.Sequence): - pass - - -AttributeTypeAndValue.componentType = namedtype.NamedTypes( - namedtype.NamedType('type', AttributeType()), - namedtype.NamedType('value', AttributeValue()) -) - - -class RelativeDistinguishedName(univ.SetOf): - pass - - -RelativeDistinguishedName.componentType = AttributeTypeAndValue() -RelativeDistinguishedName.subtypeSpec=constraint.ValueSizeConstraint(1, MAX) - - -class RDNSequence(univ.SequenceOf): - pass - - -RDNSequence.componentType = RelativeDistinguishedName() - - -class Name(univ.Choice): - pass - - -Name.componentType = namedtype.NamedTypes( - namedtype.NamedType('rdnSequence', RDNSequence()) -) - - -class TBSCertificate(univ.Sequence): - pass - - -TBSCertificate.componentType = namedtype.NamedTypes( - namedtype.DefaultedNamedType('version', - Version().subtype(explicitTag=tag.Tag(tag.tagClassContext, - tag.tagFormatSimple, 0)).subtype(value="v1")), - namedtype.NamedType('serialNumber', CertificateSerialNumber()), - namedtype.NamedType('signature', AlgorithmIdentifier()), - namedtype.NamedType('issuer', Name()), - namedtype.NamedType('validity', Validity()), - namedtype.NamedType('subject', Name()), - namedtype.NamedType('subjectPublicKeyInfo', SubjectPublicKeyInfo()), - namedtype.OptionalNamedType('issuerUniqueID', UniqueIdentifier().subtype(implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 1))), - namedtype.OptionalNamedType('subjectUniqueID', UniqueIdentifier().subtype(implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 2))), - namedtype.OptionalNamedType('extensions', Extensions().subtype(explicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 3))) -) - - -class Certificate(univ.Sequence): - pass - - -Certificate.componentType = namedtype.NamedTypes( - namedtype.NamedType('tbsCertificate', TBSCertificate()), - namedtype.NamedType('signatureAlgorithm', AlgorithmIdentifier()), - namedtype.NamedType('signature', univ.BitString()) -) - - -ub_surname_length = univ.Integer(40) - - -class TeletexOrganizationName(char.TeletexString): - pass - - -TeletexOrganizationName.subtypeSpec = constraint.ValueSizeConstraint(1, ub_organization_name_length) - - -ub_e163_4_sub_address_length = univ.Integer(40) - - -teletex_common_name = univ.Integer(2) - - -ub_country_name_alpha_length = univ.Integer(2) - - -ub_country_name_numeric_length = univ.Integer(3) - - -class CountryName(univ.Choice): - pass - - -CountryName.tagSet = univ.Choice.tagSet.tagExplicitly(tag.Tag(tag.tagClassApplication, tag.tagFormatConstructed, 1)) -CountryName.componentType = namedtype.NamedTypes( - namedtype.NamedType('x121-dcc-code', char.NumericString().subtype(subtypeSpec=constraint.ValueSizeConstraint(ub_country_name_numeric_length, ub_country_name_numeric_length))), - namedtype.NamedType('iso-3166-alpha2-code', char.PrintableString().subtype(subtypeSpec=constraint.ValueSizeConstraint(ub_country_name_alpha_length, ub_country_name_alpha_length))) -) - - -extension_OR_address_components = univ.Integer(12) - - -id_at_dnQualifier = _OID(id_at, 46) - - -ub_e163_4_number_length = univ.Integer(15) - - -class ExtendedNetworkAddress(univ.Choice): - pass - - -ExtendedNetworkAddress.componentType = namedtype.NamedTypes( - namedtype.NamedType('e163-4-address', univ.Sequence(componentType=namedtype.NamedTypes( - namedtype.NamedType('number', char.NumericString().subtype(subtypeSpec=constraint.ValueSizeConstraint(1, ub_e163_4_number_length)).subtype(implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 0))), - namedtype.OptionalNamedType('sub-address', char.NumericString().subtype(subtypeSpec=constraint.ValueSizeConstraint(1, ub_e163_4_sub_address_length)).subtype(implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 1))) - )) - ), - namedtype.NamedType('psap-address', PresentationAddress().subtype(implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatConstructed, 0))) -) - - -terminal_type = univ.Integer(23) - - -id_domainComponent = _OID(0, 9, 2342, 19200300, 100, 1, 25) - - -ub_state_name = univ.Integer(128) - - -class X520StateOrProvinceName(univ.Choice): - pass - - -X520StateOrProvinceName.componentType = namedtype.NamedTypes( - namedtype.NamedType('teletexString', char.TeletexString().subtype(subtypeSpec=constraint.ValueSizeConstraint(1, ub_state_name))), - namedtype.NamedType('printableString', char.PrintableString().subtype(subtypeSpec=constraint.ValueSizeConstraint(1, ub_state_name))), - namedtype.NamedType('universalString', char.UniversalString().subtype(subtypeSpec=constraint.ValueSizeConstraint(1, ub_state_name))), - namedtype.NamedType('utf8String', char.UTF8String().subtype(subtypeSpec=constraint.ValueSizeConstraint(1, ub_state_name))), - namedtype.NamedType('bmpString', char.BMPString().subtype(subtypeSpec=constraint.ValueSizeConstraint(1, ub_state_name))) -) - - -ub_organization_name = univ.Integer(64) - - -class X520OrganizationName(univ.Choice): - pass - - -X520OrganizationName.componentType = namedtype.NamedTypes( - namedtype.NamedType('teletexString', char.TeletexString().subtype(subtypeSpec=constraint.ValueSizeConstraint(1, ub_organization_name))), - namedtype.NamedType('printableString', char.PrintableString().subtype(subtypeSpec=constraint.ValueSizeConstraint(1, ub_organization_name))), - namedtype.NamedType('universalString', char.UniversalString().subtype(subtypeSpec=constraint.ValueSizeConstraint(1, ub_organization_name))), - namedtype.NamedType('utf8String', char.UTF8String().subtype(subtypeSpec=constraint.ValueSizeConstraint(1, ub_organization_name))), - namedtype.NamedType('bmpString', char.BMPString().subtype(subtypeSpec=constraint.ValueSizeConstraint(1, ub_organization_name))) -) - - -ub_emailaddress_length = univ.Integer(128) - - -class ExtensionPhysicalDeliveryAddressComponents(PDSParameter): - pass - - -id_at_surname = _OID(id_at, 4) - - -ub_common_name_length = univ.Integer(64) - - -id_ad = _OID(id_pkix, 48) - - -ub_numeric_user_id_length = univ.Integer(32) - - -class NumericUserIdentifier(char.NumericString): - pass - - -NumericUserIdentifier.subtypeSpec = constraint.ValueSizeConstraint(1, ub_numeric_user_id_length) - - -class OrganizationName(char.PrintableString): - pass - - -OrganizationName.subtypeSpec = constraint.ValueSizeConstraint(1, ub_organization_name_length) - - -ub_domain_name_length = univ.Integer(16) - - -class AdministrationDomainName(univ.Choice): - pass - - -AdministrationDomainName.tagSet = univ.Choice.tagSet.tagExplicitly(tag.Tag(tag.tagClassApplication, tag.tagFormatConstructed, 2)) -AdministrationDomainName.componentType = namedtype.NamedTypes( - namedtype.NamedType('numeric', char.NumericString().subtype(subtypeSpec=constraint.ValueSizeConstraint(0, ub_domain_name_length))), - namedtype.NamedType('printable', char.PrintableString().subtype(subtypeSpec=constraint.ValueSizeConstraint(0, ub_domain_name_length))) -) - - -class PrivateDomainName(univ.Choice): - pass - - -PrivateDomainName.componentType = namedtype.NamedTypes( - namedtype.NamedType('numeric', char.NumericString().subtype(subtypeSpec=constraint.ValueSizeConstraint(1, ub_domain_name_length))), - namedtype.NamedType('printable', char.PrintableString().subtype(subtypeSpec=constraint.ValueSizeConstraint(1, ub_domain_name_length))) -) - - -ub_generation_qualifier_length = univ.Integer(3) - - -ub_given_name_length = univ.Integer(16) - - -ub_initials_length = univ.Integer(5) - - -class PersonalName(univ.Set): - pass - - -PersonalName.componentType = namedtype.NamedTypes( - namedtype.NamedType('surname', char.PrintableString().subtype(subtypeSpec=constraint.ValueSizeConstraint(1, ub_surname_length)).subtype(implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 0))), - namedtype.OptionalNamedType('given-name', char.PrintableString().subtype(subtypeSpec=constraint.ValueSizeConstraint(1, ub_given_name_length)).subtype(implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 1))), - namedtype.OptionalNamedType('initials', char.PrintableString().subtype(subtypeSpec=constraint.ValueSizeConstraint(1, ub_initials_length)).subtype(implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 2))), - namedtype.OptionalNamedType('generation-qualifier', char.PrintableString().subtype(subtypeSpec=constraint.ValueSizeConstraint(1, ub_generation_qualifier_length)).subtype(implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 3))) -) - - -ub_terminal_id_length = univ.Integer(24) - - -class TerminalIdentifier(char.PrintableString): - pass - - -TerminalIdentifier.subtypeSpec = constraint.ValueSizeConstraint(1, ub_terminal_id_length) - - -ub_x121_address_length = univ.Integer(16) - - -class X121Address(char.NumericString): - pass - - -X121Address.subtypeSpec = constraint.ValueSizeConstraint(1, ub_x121_address_length) - - -class NetworkAddress(X121Address): - pass - - -class BuiltInStandardAttributes(univ.Sequence): - pass - - -BuiltInStandardAttributes.componentType = namedtype.NamedTypes( - namedtype.OptionalNamedType('country-name', CountryName()), - namedtype.OptionalNamedType('administration-domain-name', AdministrationDomainName()), - namedtype.OptionalNamedType('network-address', NetworkAddress().subtype(implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 0))), - namedtype.OptionalNamedType('terminal-identifier', TerminalIdentifier().subtype(implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 1))), - namedtype.OptionalNamedType('private-domain-name', PrivateDomainName().subtype(explicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatConstructed, 2))), - namedtype.OptionalNamedType('organization-name', OrganizationName().subtype(implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 3))), - namedtype.OptionalNamedType('numeric-user-identifier', NumericUserIdentifier().subtype(implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 4))), - namedtype.OptionalNamedType('personal-name', PersonalName().subtype(implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatConstructed, 5))), - namedtype.OptionalNamedType('organizational-unit-names', OrganizationalUnitNames().subtype(implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 6))) -) - - -ub_domain_defined_attributes = univ.Integer(4) - - -class BuiltInDomainDefinedAttribute(univ.Sequence): - pass - - -BuiltInDomainDefinedAttribute.componentType = namedtype.NamedTypes( - namedtype.NamedType('type', char.PrintableString().subtype(subtypeSpec=constraint.ValueSizeConstraint(1, ub_domain_defined_attribute_type_length))), - namedtype.NamedType('value', char.PrintableString().subtype(subtypeSpec=constraint.ValueSizeConstraint(1, ub_domain_defined_attribute_value_length))) -) - - -class BuiltInDomainDefinedAttributes(univ.SequenceOf): - pass - - -BuiltInDomainDefinedAttributes.componentType = BuiltInDomainDefinedAttribute() -BuiltInDomainDefinedAttributes.subtypeSpec=constraint.ValueSizeConstraint(1, ub_domain_defined_attributes) - - -ub_extension_attributes = univ.Integer(256) - - -class ExtensionAttribute(univ.Sequence): - pass - - -ExtensionAttribute.componentType = namedtype.NamedTypes( - namedtype.NamedType('extension-attribute-type', univ.Integer().subtype(subtypeSpec=constraint.ValueRangeConstraint(0, ub_extension_attributes)).subtype(implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 0))), - namedtype.NamedType('extension-attribute-value', univ.Any().subtype(explicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 1))) -) - - -class ExtensionAttributes(univ.SetOf): - pass - - -ExtensionAttributes.componentType = ExtensionAttribute() -ExtensionAttributes.subtypeSpec=constraint.ValueSizeConstraint(1, ub_extension_attributes) - - -class ORAddress(univ.Sequence): - pass - - -ORAddress.componentType = namedtype.NamedTypes( - namedtype.NamedType('built-in-standard-attributes', BuiltInStandardAttributes()), - namedtype.OptionalNamedType('built-in-domain-defined-attributes', BuiltInDomainDefinedAttributes()), - namedtype.OptionalNamedType('extension-attributes', ExtensionAttributes()) -) - - -id_pe = _OID(id_pkix, 1) - - -ub_title = univ.Integer(64) - - -class X520Title(univ.Choice): - pass - - -X520Title.componentType = namedtype.NamedTypes( - namedtype.NamedType('teletexString', char.TeletexString().subtype(subtypeSpec=constraint.ValueSizeConstraint(1, ub_title))), - namedtype.NamedType('printableString', char.PrintableString().subtype(subtypeSpec=constraint.ValueSizeConstraint(1, ub_title))), - namedtype.NamedType('universalString', char.UniversalString().subtype(subtypeSpec=constraint.ValueSizeConstraint(1, ub_title))), - namedtype.NamedType('utf8String', char.UTF8String().subtype(subtypeSpec=constraint.ValueSizeConstraint(1, ub_title))), - namedtype.NamedType('bmpString', char.BMPString().subtype(subtypeSpec=constraint.ValueSizeConstraint(1, ub_title))) -) - - -id_at_organizationalUnitName = _OID(id_at, 11) - - -class EmailAddress(char.IA5String): - pass - - -EmailAddress.subtypeSpec = constraint.ValueSizeConstraint(1, ub_emailaddress_length) - - -physical_delivery_country_name = univ.Integer(8) - - -id_at_givenName = _OID(id_at, 42) - - -class TeletexCommonName(char.TeletexString): - pass - - -TeletexCommonName.subtypeSpec = constraint.ValueSizeConstraint(1, ub_common_name_length) - - -id_qt_cps = _OID(id_qt, 1) - - -class LocalPostalAttributes(PDSParameter): - pass - - -class StreetAddress(PDSParameter): - pass - - -id_kp = _OID(id_pkix, 3) - - -class DirectoryString(univ.Choice): - pass - - -DirectoryString.componentType = namedtype.NamedTypes( - namedtype.NamedType('teletexString', char.TeletexString().subtype(subtypeSpec=constraint.ValueSizeConstraint(1, MAX))), - namedtype.NamedType('printableString', char.PrintableString().subtype(subtypeSpec=constraint.ValueSizeConstraint(1, MAX))), - namedtype.NamedType('universalString', char.UniversalString().subtype(subtypeSpec=constraint.ValueSizeConstraint(1, MAX))), - namedtype.NamedType('utf8String', char.UTF8String().subtype(subtypeSpec=constraint.ValueSizeConstraint(1, MAX))), - namedtype.NamedType('bmpString', char.BMPString().subtype(subtypeSpec=constraint.ValueSizeConstraint(1, MAX))) -) - - -class DomainComponent(char.IA5String): - pass - - -id_at_initials = _OID(id_at, 43) - - -id_qt_unotice = _OID(id_qt, 2) - - -ub_pds_name_length = univ.Integer(16) - - -class PDSName(char.PrintableString): - pass - - -PDSName.subtypeSpec = constraint.ValueSizeConstraint(1, ub_pds_name_length) - - -class PosteRestanteAddress(PDSParameter): - pass - - -class DistinguishedName(RDNSequence): - pass - - -class CommonName(char.PrintableString): - pass - - -CommonName.subtypeSpec = constraint.ValueSizeConstraint(1, ub_common_name_length) - - -ub_serial_number = univ.Integer(64) - - -class X520SerialNumber(char.PrintableString): - pass - - -X520SerialNumber.subtypeSpec = constraint.ValueSizeConstraint(1, ub_serial_number) - - -id_at_generationQualifier = _OID(id_at, 44) - - -ub_organizational_unit_name = univ.Integer(64) - - -id_ad_ocsp = _OID(id_ad, 1) - - -class TeletexOrganizationalUnitName(char.TeletexString): - pass - - -TeletexOrganizationalUnitName.subtypeSpec = constraint.ValueSizeConstraint(1, ub_organizational_unit_name_length) - - -class TeletexPersonalName(univ.Set): - pass - - -TeletexPersonalName.componentType = namedtype.NamedTypes( - namedtype.NamedType('surname', char.TeletexString().subtype(subtypeSpec=constraint.ValueSizeConstraint(1, ub_surname_length)).subtype(implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 0))), - namedtype.OptionalNamedType('given-name', char.TeletexString().subtype(subtypeSpec=constraint.ValueSizeConstraint(1, ub_given_name_length)).subtype(implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 1))), - namedtype.OptionalNamedType('initials', char.TeletexString().subtype(subtypeSpec=constraint.ValueSizeConstraint(1, ub_initials_length)).subtype(implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 2))), - namedtype.OptionalNamedType('generation-qualifier', char.TeletexString().subtype(subtypeSpec=constraint.ValueSizeConstraint(1, ub_generation_qualifier_length)).subtype(implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 3))) -) - - -class TeletexDomainDefinedAttributes(univ.SequenceOf): - pass - - -TeletexDomainDefinedAttributes.componentType = TeletexDomainDefinedAttribute() -TeletexDomainDefinedAttributes.subtypeSpec=constraint.ValueSizeConstraint(1, ub_domain_defined_attributes) - - -class TBSCertList(univ.Sequence): - pass - - -TBSCertList.componentType = namedtype.NamedTypes( - namedtype.OptionalNamedType('version', Version()), - namedtype.NamedType('signature', AlgorithmIdentifier()), - namedtype.NamedType('issuer', Name()), - namedtype.NamedType('thisUpdate', Time()), - namedtype.OptionalNamedType('nextUpdate', Time()), - namedtype.OptionalNamedType('revokedCertificates', univ.SequenceOf(componentType=univ.Sequence(componentType=namedtype.NamedTypes( - namedtype.NamedType('userCertificate', CertificateSerialNumber()), - namedtype.NamedType('revocationDate', Time()), - namedtype.OptionalNamedType('crlEntryExtensions', Extensions()) - )) - )), - namedtype.OptionalNamedType('crlExtensions', Extensions().subtype(explicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 0))) -) - - -local_postal_attributes = univ.Integer(21) - - -pkcs_9 = _OID(1, 2, 840, 113549, 1, 9) - - -class PhysicalDeliveryCountryName(univ.Choice): - pass - - -PhysicalDeliveryCountryName.componentType = namedtype.NamedTypes( - namedtype.NamedType('x121-dcc-code', char.NumericString().subtype(subtypeSpec=constraint.ValueSizeConstraint(ub_country_name_numeric_length, ub_country_name_numeric_length))), - namedtype.NamedType('iso-3166-alpha2-code', char.PrintableString().subtype(subtypeSpec=constraint.ValueSizeConstraint(ub_country_name_alpha_length, ub_country_name_alpha_length))) -) - - -ub_name = univ.Integer(32768) - - -class X520name(univ.Choice): - pass - - -X520name.componentType = namedtype.NamedTypes( - namedtype.NamedType('teletexString', char.TeletexString().subtype(subtypeSpec=constraint.ValueSizeConstraint(1, ub_name))), - namedtype.NamedType('printableString', char.PrintableString().subtype(subtypeSpec=constraint.ValueSizeConstraint(1, ub_name))), - namedtype.NamedType('universalString', char.UniversalString().subtype(subtypeSpec=constraint.ValueSizeConstraint(1, ub_name))), - namedtype.NamedType('utf8String', char.UTF8String().subtype(subtypeSpec=constraint.ValueSizeConstraint(1, ub_name))), - namedtype.NamedType('bmpString', char.BMPString().subtype(subtypeSpec=constraint.ValueSizeConstraint(1, ub_name))) -) - - -id_emailAddress = _OID(pkcs_9, 1) - - -class TerminalType(univ.Integer): - pass - - -TerminalType.namedValues = namedval.NamedValues( - ('telex', 3), - ('teletex', 4), - ('g3-facsimile', 5), - ('g4-facsimile', 6), - ('ia5-terminal', 7), - ('videotex', 8) -) - - -class X520OrganizationalUnitName(univ.Choice): - pass - - -X520OrganizationalUnitName.componentType = namedtype.NamedTypes( - namedtype.NamedType('teletexString', char.TeletexString().subtype(subtypeSpec=constraint.ValueSizeConstraint(1, ub_organizational_unit_name))), - namedtype.NamedType('printableString', char.PrintableString().subtype(subtypeSpec=constraint.ValueSizeConstraint(1, ub_organizational_unit_name))), - namedtype.NamedType('universalString', char.UniversalString().subtype(subtypeSpec=constraint.ValueSizeConstraint(1, ub_organizational_unit_name))), - namedtype.NamedType('utf8String', char.UTF8String().subtype(subtypeSpec=constraint.ValueSizeConstraint(1, ub_organizational_unit_name))), - namedtype.NamedType('bmpString', char.BMPString().subtype(subtypeSpec=constraint.ValueSizeConstraint(1, ub_organizational_unit_name))) -) - - -id_at_commonName = _OID(id_at, 3) - - -pds_name = univ.Integer(7) - - -post_office_box_address = univ.Integer(18) - - -ub_locality_name = univ.Integer(128) - - -class X520LocalityName(univ.Choice): - pass - - -X520LocalityName.componentType = namedtype.NamedTypes( - namedtype.NamedType('teletexString', char.TeletexString().subtype(subtypeSpec=constraint.ValueSizeConstraint(1, ub_locality_name))), - namedtype.NamedType('printableString', char.PrintableString().subtype(subtypeSpec=constraint.ValueSizeConstraint(1, ub_locality_name))), - namedtype.NamedType('universalString', char.UniversalString().subtype(subtypeSpec=constraint.ValueSizeConstraint(1, ub_locality_name))), - namedtype.NamedType('utf8String', char.UTF8String().subtype(subtypeSpec=constraint.ValueSizeConstraint(1, ub_locality_name))), - namedtype.NamedType('bmpString', char.BMPString().subtype(subtypeSpec=constraint.ValueSizeConstraint(1, ub_locality_name))) -) - - -id_ad_timeStamping = _OID(id_ad, 3) - - -id_at_countryName = _OID(id_at, 6) - - -physical_delivery_personal_name = univ.Integer(13) - - -teletex_personal_name = univ.Integer(4) - - -teletex_organizational_unit_names = univ.Integer(5) - - -class PhysicalDeliveryPersonalName(PDSParameter): - pass - - -ub_postal_code_length = univ.Integer(16) - - -class PostalCode(univ.Choice): - pass - - -PostalCode.componentType = namedtype.NamedTypes( - namedtype.NamedType('numeric-code', char.NumericString().subtype(subtypeSpec=constraint.ValueSizeConstraint(1, ub_postal_code_length))), - namedtype.NamedType('printable-code', char.PrintableString().subtype(subtypeSpec=constraint.ValueSizeConstraint(1, ub_postal_code_length))) -) - - -class X520countryName(char.PrintableString): - pass - - -X520countryName.subtypeSpec = constraint.ValueSizeConstraint(2, 2) - - -postal_code = univ.Integer(9) - - -id_ad_caRepository = _OID(id_ad, 5) - - -extension_physical_delivery_address_components = univ.Integer(15) - - -class PostOfficeBoxAddress(PDSParameter): - pass - - -class PhysicalDeliveryOfficeName(PDSParameter): - pass - - -id_at_title = _OID(id_at, 12) - - -id_at_serialNumber = _OID(id_at, 5) - - -id_ad_caIssuers = _OID(id_ad, 2) - - -ub_integer_options = univ.Integer(256) - - -class CertificateList(univ.Sequence): - pass - - -CertificateList.componentType = namedtype.NamedTypes( - namedtype.NamedType('tbsCertList', TBSCertList()), - namedtype.NamedType('signatureAlgorithm', AlgorithmIdentifier()), - namedtype.NamedType('signature', univ.BitString()) -) - - -class PhysicalDeliveryOfficeNumber(PDSParameter): - pass - - -class TeletexOrganizationalUnitNames(univ.SequenceOf): - pass - - -TeletexOrganizationalUnitNames.componentType = TeletexOrganizationalUnitName() -TeletexOrganizationalUnitNames.subtypeSpec=constraint.ValueSizeConstraint(1, ub_organizational_units) - - -physical_delivery_office_name = univ.Integer(10) - - -ub_common_name = univ.Integer(64) - - -class ExtensionORAddressComponents(PDSParameter): - pass - - -ub_pseudonym = univ.Integer(128) - - -poste_restante_address = univ.Integer(19) - - -id_at_organizationName = _OID(id_at, 10) - - -physical_delivery_office_number = univ.Integer(11) - - -id_at_pseudonym = _OID(id_at, 65) - - -class X520CommonName(univ.Choice): - pass - - -X520CommonName.componentType = namedtype.NamedTypes( - namedtype.NamedType('teletexString', char.TeletexString().subtype(subtypeSpec=constraint.ValueSizeConstraint(1, ub_common_name))), - namedtype.NamedType('printableString', char.PrintableString().subtype(subtypeSpec=constraint.ValueSizeConstraint(1, ub_common_name))), - namedtype.NamedType('universalString', char.UniversalString().subtype(subtypeSpec=constraint.ValueSizeConstraint(1, ub_common_name))), - namedtype.NamedType('utf8String', char.UTF8String().subtype(subtypeSpec=constraint.ValueSizeConstraint(1, ub_common_name))), - namedtype.NamedType('bmpString', char.BMPString().subtype(subtypeSpec=constraint.ValueSizeConstraint(1, ub_common_name))) -) - - -physical_delivery_organization_name = univ.Integer(14) - - -class X520dnQualifier(char.PrintableString): - pass - - -id_at_stateOrProvinceName = _OID(id_at, 8) - - -common_name = univ.Integer(1) - - -id_at_localityName = _OID(id_at, 7) - - -ub_match = univ.Integer(128) - - -ub_unformatted_address_length = univ.Integer(180) - - -class Attribute(univ.Sequence): - pass - - -Attribute.componentType = namedtype.NamedTypes( - namedtype.NamedType('type', AttributeType()), - namedtype.NamedType('values', univ.SetOf(componentType=AttributeValue())) -) - - -extended_network_address = univ.Integer(22) - - -unique_postal_name = univ.Integer(20) - - -ub_pds_physical_address_lines = univ.Integer(6) - - -class UnformattedPostalAddress(univ.Set): - pass - - -UnformattedPostalAddress.componentType = namedtype.NamedTypes( - namedtype.OptionalNamedType('printable-address', univ.SequenceOf(componentType=char.PrintableString().subtype(subtypeSpec=constraint.ValueSizeConstraint(1, ub_pds_parameter_length)))), - namedtype.OptionalNamedType('teletex-string', char.TeletexString().subtype(subtypeSpec=constraint.ValueSizeConstraint(1, ub_unformatted_address_length))) -) - - -class UniquePostalName(PDSParameter): - pass - - -class X520Pseudonym(univ.Choice): - pass - - -X520Pseudonym.componentType = namedtype.NamedTypes( - namedtype.NamedType('teletexString', char.TeletexString().subtype(subtypeSpec=constraint.ValueSizeConstraint(1, ub_pseudonym))), - namedtype.NamedType('printableString', char.PrintableString().subtype(subtypeSpec=constraint.ValueSizeConstraint(1, ub_pseudonym))), - namedtype.NamedType('universalString', char.UniversalString().subtype(subtypeSpec=constraint.ValueSizeConstraint(1, ub_pseudonym))), - namedtype.NamedType('utf8String', char.UTF8String().subtype(subtypeSpec=constraint.ValueSizeConstraint(1, ub_pseudonym))), - namedtype.NamedType('bmpString', char.BMPString().subtype(subtypeSpec=constraint.ValueSizeConstraint(1, ub_pseudonym))) -) - - -teletex_organization_name = univ.Integer(3) - - -teletex_domain_defined_attributes = univ.Integer(6) - - -street_address = univ.Integer(17) - - -id_kp_OCSPSigning = _OID(id_kp, 9) - - -id_ce = _OID(2, 5, 29) - - -id_ce_certificatePolicies = _OID(id_ce, 32) - - -class EDIPartyName(univ.Sequence): - pass - - -EDIPartyName.componentType = namedtype.NamedTypes( - namedtype.OptionalNamedType('nameAssigner', DirectoryString().subtype(implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 0))), - namedtype.NamedType('partyName', DirectoryString().subtype(implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 1))) -) - - -class AnotherName(univ.Sequence): - pass - - -AnotherName.componentType = namedtype.NamedTypes( - namedtype.NamedType('type-id', univ.ObjectIdentifier()), - namedtype.NamedType('value', univ.Any().subtype(explicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 0))) -) - - -class GeneralName(univ.Choice): - pass - - -GeneralName.componentType = namedtype.NamedTypes( - namedtype.NamedType('otherName', AnotherName().subtype(implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatConstructed, 0))), - namedtype.NamedType('rfc822Name', char.IA5String().subtype(implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 1))), - namedtype.NamedType('dNSName', char.IA5String().subtype(implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 2))), - namedtype.NamedType('x400Address', ORAddress().subtype(implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 3))), - namedtype.NamedType('directoryName', Name().subtype(implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatConstructed, 4))), - namedtype.NamedType('ediPartyName', EDIPartyName().subtype(implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatConstructed, 5))), - namedtype.NamedType('uniformResourceIdentifier', char.IA5String().subtype(implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 6))), - namedtype.NamedType('iPAddress', univ.OctetString().subtype(implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 7))), - namedtype.NamedType('registeredID', univ.ObjectIdentifier().subtype(implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 8))) -) - - -class GeneralNames(univ.SequenceOf): - pass - - -GeneralNames.componentType = GeneralName() -GeneralNames.subtypeSpec=constraint.ValueSizeConstraint(1, MAX) - - -class IssuerAltName(GeneralNames): - pass - - -id_ce_cRLDistributionPoints = _OID(id_ce, 31) - - -class CertPolicyId(univ.ObjectIdentifier): - pass - - -class PolicyMappings(univ.SequenceOf): - pass - - -PolicyMappings.componentType = univ.Sequence(componentType=namedtype.NamedTypes( - namedtype.NamedType('issuerDomainPolicy', CertPolicyId()), - namedtype.NamedType('subjectDomainPolicy', CertPolicyId()) -)) - -PolicyMappings.subtypeSpec=constraint.ValueSizeConstraint(1, MAX) - - -class PolicyQualifierId(univ.ObjectIdentifier): - pass - - -holdInstruction = _OID(2, 2, 840, 10040, 2) - - -id_ce_subjectDirectoryAttributes = _OID(id_ce, 9) - - -id_holdinstruction_callissuer = _OID(holdInstruction, 2) - - -class SubjectDirectoryAttributes(univ.SequenceOf): - pass - - -SubjectDirectoryAttributes.componentType = Attribute() -SubjectDirectoryAttributes.subtypeSpec=constraint.ValueSizeConstraint(1, MAX) - - -anyPolicy = _OID(id_ce_certificatePolicies, 0) - - -id_ce_subjectAltName = _OID(id_ce, 17) - - -id_kp_emailProtection = _OID(id_kp, 4) - - -class ReasonFlags(univ.BitString): - pass - - -ReasonFlags.namedValues = namedval.NamedValues( - ('unused', 0), - ('keyCompromise', 1), - ('cACompromise', 2), - ('affiliationChanged', 3), - ('superseded', 4), - ('cessationOfOperation', 5), - ('certificateHold', 6), - ('privilegeWithdrawn', 7), - ('aACompromise', 8) -) - - -class DistributionPointName(univ.Choice): - pass - - -DistributionPointName.componentType = namedtype.NamedTypes( - namedtype.NamedType('fullName', GeneralNames().subtype(implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 0))), - namedtype.NamedType('nameRelativeToCRLIssuer', RelativeDistinguishedName().subtype(implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 1))) -) - - -class DistributionPoint(univ.Sequence): - pass - - -DistributionPoint.componentType = namedtype.NamedTypes( - namedtype.OptionalNamedType('distributionPoint', DistributionPointName().subtype(implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatConstructed, 0))), - namedtype.OptionalNamedType('reasons', ReasonFlags().subtype(implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 1))), - namedtype.OptionalNamedType('cRLIssuer', GeneralNames().subtype(implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 2))) -) - - -id_ce_keyUsage = _OID(id_ce, 15) - - -class PolicyQualifierInfo(univ.Sequence): - pass - - -PolicyQualifierInfo.componentType = namedtype.NamedTypes( - namedtype.NamedType('policyQualifierId', PolicyQualifierId()), - namedtype.NamedType('qualifier', univ.Any()) -) - - -class PolicyInformation(univ.Sequence): - pass - - -PolicyInformation.componentType = namedtype.NamedTypes( - namedtype.NamedType('policyIdentifier', CertPolicyId()), - namedtype.OptionalNamedType('policyQualifiers', univ.SequenceOf(componentType=PolicyQualifierInfo())) -) - - -class CertificatePolicies(univ.SequenceOf): - pass - - -CertificatePolicies.componentType = PolicyInformation() -CertificatePolicies.subtypeSpec=constraint.ValueSizeConstraint(1, MAX) - - -id_ce_basicConstraints = _OID(id_ce, 19) - - -class HoldInstructionCode(univ.ObjectIdentifier): - pass - - -class KeyPurposeId(univ.ObjectIdentifier): - pass - - -class ExtKeyUsageSyntax(univ.SequenceOf): - pass - - -ExtKeyUsageSyntax.componentType = KeyPurposeId() -ExtKeyUsageSyntax.subtypeSpec=constraint.ValueSizeConstraint(1, MAX) - - -class SubjectAltName(GeneralNames): - pass - - -class BasicConstraints(univ.Sequence): - pass - - -BasicConstraints.componentType = namedtype.NamedTypes( - namedtype.DefaultedNamedType('cA', univ.Boolean().subtype(value=0)), - namedtype.OptionalNamedType('pathLenConstraint', univ.Integer().subtype(subtypeSpec=constraint.ValueRangeConstraint(0, MAX))) -) - - -class SkipCerts(univ.Integer): - pass - - -SkipCerts.subtypeSpec = constraint.ValueRangeConstraint(0, MAX) - - -class InhibitAnyPolicy(SkipCerts): - pass - - -class CRLNumber(univ.Integer): - pass - - -CRLNumber.subtypeSpec = constraint.ValueRangeConstraint(0, MAX) - - -class BaseCRLNumber(CRLNumber): - pass - - -class KeyIdentifier(univ.OctetString): - pass - - -class AuthorityKeyIdentifier(univ.Sequence): - pass - - -AuthorityKeyIdentifier.componentType = namedtype.NamedTypes( - namedtype.OptionalNamedType('keyIdentifier', KeyIdentifier().subtype(implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 0))), - namedtype.OptionalNamedType('authorityCertIssuer', GeneralNames().subtype(implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 1))), - namedtype.OptionalNamedType('authorityCertSerialNumber', CertificateSerialNumber().subtype(implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 2))) -) - - -id_ce_nameConstraints = _OID(id_ce, 30) - - -id_kp_serverAuth = _OID(id_kp, 1) - - -id_ce_freshestCRL = _OID(id_ce, 46) - - -id_ce_cRLReasons = _OID(id_ce, 21) - - -class CRLDistributionPoints(univ.SequenceOf): - pass - - -CRLDistributionPoints.componentType = DistributionPoint() -CRLDistributionPoints.subtypeSpec=constraint.ValueSizeConstraint(1, MAX) - - -class FreshestCRL(CRLDistributionPoints): - pass - - -id_ce_inhibitAnyPolicy = _OID(id_ce, 54) - - -class CRLReason(univ.Enumerated): - pass - - -CRLReason.namedValues = namedval.NamedValues( - ('unspecified', 0), - ('keyCompromise', 1), - ('cACompromise', 2), - ('affiliationChanged', 3), - ('superseded', 4), - ('cessationOfOperation', 5), - ('certificateHold', 6), - ('removeFromCRL', 8), - ('privilegeWithdrawn', 9), - ('aACompromise', 10) -) - - -class BaseDistance(univ.Integer): - pass - - -BaseDistance.subtypeSpec = constraint.ValueRangeConstraint(0, MAX) - - -class GeneralSubtree(univ.Sequence): - pass - - -GeneralSubtree.componentType = namedtype.NamedTypes( - namedtype.NamedType('base', GeneralName()), - namedtype.DefaultedNamedType('minimum', BaseDistance().subtype(implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 0)).subtype(value=0)), - namedtype.OptionalNamedType('maximum', BaseDistance().subtype(implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 1))) -) - - -class GeneralSubtrees(univ.SequenceOf): - pass - - -GeneralSubtrees.componentType = GeneralSubtree() -GeneralSubtrees.subtypeSpec=constraint.ValueSizeConstraint(1, MAX) - - -class NameConstraints(univ.Sequence): - pass - - -NameConstraints.componentType = namedtype.NamedTypes( - namedtype.OptionalNamedType('permittedSubtrees', GeneralSubtrees().subtype(implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 0))), - namedtype.OptionalNamedType('excludedSubtrees', GeneralSubtrees().subtype(implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 1))) -) - - -id_pe_authorityInfoAccess = _OID(id_pe, 1) - - -id_pe_subjectInfoAccess = _OID(id_pe, 11) - - -id_ce_certificateIssuer = _OID(id_ce, 29) - - -id_ce_invalidityDate = _OID(id_ce, 24) - - -class DirectoryString(univ.Choice): - pass - - -DirectoryString.componentType = namedtype.NamedTypes( - namedtype.NamedType('any', univ.Any()) -) - - -id_ce_authorityKeyIdentifier = _OID(id_ce, 35) - - -class AccessDescription(univ.Sequence): - pass - - -AccessDescription.componentType = namedtype.NamedTypes( - namedtype.NamedType('accessMethod', univ.ObjectIdentifier()), - namedtype.NamedType('accessLocation', GeneralName()) -) - - -class AuthorityInfoAccessSyntax(univ.SequenceOf): - pass - - -AuthorityInfoAccessSyntax.componentType = AccessDescription() -AuthorityInfoAccessSyntax.subtypeSpec=constraint.ValueSizeConstraint(1, MAX) - - -id_ce_issuingDistributionPoint = _OID(id_ce, 28) - - -class CPSuri(char.IA5String): - pass - - -class DisplayText(univ.Choice): - pass - - -DisplayText.componentType = namedtype.NamedTypes( - namedtype.NamedType('ia5String', char.IA5String().subtype(subtypeSpec=constraint.ValueSizeConstraint(1, 200))), - namedtype.NamedType('visibleString', char.VisibleString().subtype(subtypeSpec=constraint.ValueSizeConstraint(1, 200))), - namedtype.NamedType('bmpString', char.BMPString().subtype(subtypeSpec=constraint.ValueSizeConstraint(1, 200))), - namedtype.NamedType('utf8String', char.UTF8String().subtype(subtypeSpec=constraint.ValueSizeConstraint(1, 200))) -) - - -class NoticeReference(univ.Sequence): - pass - - -NoticeReference.componentType = namedtype.NamedTypes( - namedtype.NamedType('organization', DisplayText()), - namedtype.NamedType('noticeNumbers', univ.SequenceOf(componentType=univ.Integer())) -) - - -class UserNotice(univ.Sequence): - pass - - -UserNotice.componentType = namedtype.NamedTypes( - namedtype.OptionalNamedType('noticeRef', NoticeReference()), - namedtype.OptionalNamedType('explicitText', DisplayText()) -) - - -class PrivateKeyUsagePeriod(univ.Sequence): - pass - - -PrivateKeyUsagePeriod.componentType = namedtype.NamedTypes( - namedtype.OptionalNamedType('notBefore', useful.GeneralizedTime().subtype(implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 0))), - namedtype.OptionalNamedType('notAfter', useful.GeneralizedTime().subtype(implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 1))) -) - - -id_ce_subjectKeyIdentifier = _OID(id_ce, 14) - - -class CertificateIssuer(GeneralNames): - pass - - -class InvalidityDate(useful.GeneralizedTime): - pass - - -class SubjectInfoAccessSyntax(univ.SequenceOf): - pass - - -SubjectInfoAccessSyntax.componentType = AccessDescription() -SubjectInfoAccessSyntax.subtypeSpec=constraint.ValueSizeConstraint(1, MAX) - - -class KeyUsage(univ.BitString): - pass - - -KeyUsage.namedValues = namedval.NamedValues( - ('digitalSignature', 0), - ('nonRepudiation', 1), - ('keyEncipherment', 2), - ('dataEncipherment', 3), - ('keyAgreement', 4), - ('keyCertSign', 5), - ('cRLSign', 6), - ('encipherOnly', 7), - ('decipherOnly', 8) -) - - -id_ce_extKeyUsage = _OID(id_ce, 37) - - -anyExtendedKeyUsage = _OID(id_ce_extKeyUsage, 0) - - -id_ce_privateKeyUsagePeriod = _OID(id_ce, 16) - - -id_ce_policyMappings = _OID(id_ce, 33) - - -id_ce_cRLNumber = _OID(id_ce, 20) - - -id_ce_policyConstraints = _OID(id_ce, 36) - - -id_holdinstruction_none = _OID(holdInstruction, 1) - - -id_holdinstruction_reject = _OID(holdInstruction, 3) - - -id_kp_timeStamping = _OID(id_kp, 8) - - -class PolicyConstraints(univ.Sequence): - pass - - -PolicyConstraints.componentType = namedtype.NamedTypes( - namedtype.OptionalNamedType('requireExplicitPolicy', SkipCerts().subtype(implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 0))), - namedtype.OptionalNamedType('inhibitPolicyMapping', SkipCerts().subtype(implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 1))) -) - - -class SubjectKeyIdentifier(KeyIdentifier): - pass - - -id_kp_clientAuth = _OID(id_kp, 2) - - -id_ce_deltaCRLIndicator = _OID(id_ce, 27) - - -id_ce_issuerAltName = _OID(id_ce, 18) - - -id_kp_codeSigning = _OID(id_kp, 3) - - -id_ce_holdInstructionCode = _OID(id_ce, 23) - - -class IssuingDistributionPoint(univ.Sequence): - pass - - -IssuingDistributionPoint.componentType = namedtype.NamedTypes( - namedtype.OptionalNamedType('distributionPoint', DistributionPointName().subtype(implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatConstructed, 0))), - namedtype.DefaultedNamedType('onlyContainsUserCerts', univ.Boolean().subtype(implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 1)).subtype(value=0)), - namedtype.DefaultedNamedType('onlyContainsCACerts', univ.Boolean().subtype(implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 2)).subtype(value=0)), - namedtype.OptionalNamedType('onlySomeReasons', ReasonFlags().subtype(implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 3))), - namedtype.DefaultedNamedType('indirectCRL', univ.Boolean().subtype(implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 4)).subtype(value=0)), - namedtype.DefaultedNamedType('onlyContainsAttributeCerts', univ.Boolean().subtype(implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 5)).subtype(value=0)) -) - - diff --git a/anchor/asn1/rfc3281.py b/anchor/asn1/rfc3281.py deleted file mode 100644 index f218bbd..0000000 --- a/anchor/asn1/rfc3281.py +++ /dev/null @@ -1,344 +0,0 @@ -# Auto-generated by asn1ate on 2015-12-17 15:14:22.594350 -from pyasn1.type import univ -from pyasn1.type import char -from pyasn1.type import namedtype -from pyasn1.type import namedval -from pyasn1.type import tag -from pyasn1.type import constraint -from pyasn1.type import useful - -from . import rfc3280 - -MAX=64 - -def _OID(*components): - output = [] - for x in tuple(components): - if isinstance(x, univ.ObjectIdentifier): - output.extend(list(x)) - else: - output.append(int(x)) - - return univ.ObjectIdentifier(output) - - -class ObjectDigestInfo(univ.Sequence): - pass - - -ObjectDigestInfo.componentType = namedtype.NamedTypes( - namedtype.NamedType('digestedObjectType', univ.Enumerated(namedValues=namedval.NamedValues(('publicKey', 0), ('publicKeyCert', 1), ('otherObjectTypes', 2)))), - namedtype.OptionalNamedType('otherObjectTypeID', univ.ObjectIdentifier()), - namedtype.NamedType('digestAlgorithm', rfc3280.AlgorithmIdentifier()), - namedtype.NamedType('objectDigest', univ.BitString()) -) - - -class IssuerSerial(univ.Sequence): - pass - - -IssuerSerial.componentType = namedtype.NamedTypes( - namedtype.NamedType('issuer', rfc3280.GeneralNames()), - namedtype.NamedType('serial', rfc3280.CertificateSerialNumber()), - namedtype.OptionalNamedType('issuerUID', rfc3280.UniqueIdentifier()) -) - - -class TargetCert(univ.Sequence): - pass - - -TargetCert.componentType = namedtype.NamedTypes( - namedtype.NamedType('targetCertificate', IssuerSerial()), - namedtype.OptionalNamedType('targetName', rfc3280.GeneralName()), - namedtype.OptionalNamedType('certDigestInfo', ObjectDigestInfo()) -) - - -class Target(univ.Choice): - pass - - -Target.componentType = namedtype.NamedTypes( - namedtype.NamedType('targetName', rfc3280.GeneralName().subtype(implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 0))), - namedtype.NamedType('targetGroup', rfc3280.GeneralName().subtype(implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 1))), - namedtype.NamedType('targetCert', TargetCert().subtype(implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatConstructed, 2))) -) - - -class Targets(univ.SequenceOf): - pass - - -Targets.componentType = Target() - - -class ProxyInfo(univ.SequenceOf): - pass - - -ProxyInfo.componentType = Targets() - - - -id_at_role = _OID(rfc3280.id_at, 72) - - -id_pe_aaControls = _OID(rfc3280.id_pe, 6) - - -id_at_role = _OID(rfc3280.id_at, 72) - - -id_ce_targetInformation = _OID(rfc3280.id_ce, 55) - - -id_pe_ac_auditIdentity = _OID(rfc3280.id_pe, 4) - - -class ClassList(univ.BitString): - pass - - -ClassList.namedValues = namedval.NamedValues( - ('unmarked', 0), - ('unclassified', 1), - ('restricted', 2), - ('confidential', 3), - ('secret', 4), - ('topSecret', 5) -) - - -class SecurityCategory(univ.Sequence): - pass - - -SecurityCategory.componentType = namedtype.NamedTypes( - namedtype.NamedType('type', univ.ObjectIdentifier().subtype(implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 0))), - namedtype.NamedType('value', univ.Any().subtype(implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 1))) -) - - -class Clearance(univ.Sequence): - pass - - -Clearance.componentType = namedtype.NamedTypes( - namedtype.NamedType('policyId', univ.ObjectIdentifier().subtype(implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 0))), - namedtype.DefaultedNamedType('classList', - ClassList().subtype(implicitTag=tag.Tag(tag.tagClassContext, - tag.tagFormatSimple, 1)).subtype(value="unclassified")), - namedtype.OptionalNamedType('securityCategories', univ.SetOf(componentType=SecurityCategory()).subtype(implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 2))) -) - - -class AttCertVersion(univ.Integer): - pass - - -AttCertVersion.namedValues = namedval.NamedValues( - ('v2', 1) -) - - -id_aca = _OID(rfc3280.id_pkix, 10) - - -id_at_clearance = _OID(2, 5, 1, 5, 55) - - -class AttrSpec(univ.SequenceOf): - pass - - -AttrSpec.componentType = univ.ObjectIdentifier() - - -class AAControls(univ.Sequence): - pass - - -AAControls.componentType = namedtype.NamedTypes( - namedtype.OptionalNamedType('pathLenConstraint', univ.Integer().subtype(subtypeSpec=constraint.ValueRangeConstraint(0, MAX))), - namedtype.OptionalNamedType('permittedAttrs', AttrSpec().subtype(implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 0))), - namedtype.OptionalNamedType('excludedAttrs', AttrSpec().subtype(implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 1))), - namedtype.DefaultedNamedType('permitUnSpecified', univ.Boolean().subtype(value=1)) -) - - -id_aca = _OID(rfc3280.id_pkix, 10) - - -class AttCertValidityPeriod(univ.Sequence): - pass - - -AttCertValidityPeriod.componentType = namedtype.NamedTypes( - namedtype.NamedType('notBeforeTime', useful.GeneralizedTime()), - namedtype.NamedType('notAfterTime', useful.GeneralizedTime()) -) - - -id_pe_ac_auditIdentity = _OID(rfc3280.id_pe, 4) - - -id_at_clearance = _OID(2, 5, 1, 5, 55) - - -id_aca_authenticationInfo = _OID(id_aca, 1) - - -class V2Form(univ.Sequence): - pass - - -V2Form.componentType = namedtype.NamedTypes( - namedtype.OptionalNamedType('issuerName', rfc3280.GeneralNames()), - namedtype.OptionalNamedType('baseCertificateID', IssuerSerial().subtype(implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatConstructed, 0))), - namedtype.OptionalNamedType('objectDigestInfo', ObjectDigestInfo().subtype(implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatConstructed, 1))) -) - - -class AttCertIssuer(univ.Choice): - pass - - -AttCertIssuer.componentType = namedtype.NamedTypes( - namedtype.NamedType('v1Form', rfc3280.GeneralNames()), - namedtype.NamedType('v2Form', V2Form().subtype(implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatConstructed, 0))) -) - - -class Holder(univ.Sequence): - pass - - -Holder.componentType = namedtype.NamedTypes( - namedtype.OptionalNamedType('baseCertificateID', IssuerSerial().subtype(implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatConstructed, 0))), - namedtype.OptionalNamedType('entityName', rfc3280.GeneralNames().subtype(implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 1))), - namedtype.OptionalNamedType('objectDigestInfo', ObjectDigestInfo().subtype(implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatConstructed, 2))) -) - - -class AttributeCertificateInfo(univ.Sequence): - pass - - -AttributeCertificateInfo.componentType = namedtype.NamedTypes( - namedtype.NamedType('version', AttCertVersion()), - namedtype.NamedType('holder', Holder()), - namedtype.NamedType('issuer', AttCertIssuer()), - namedtype.NamedType('signature', rfc3280.AlgorithmIdentifier()), - namedtype.NamedType('serialNumber', rfc3280.CertificateSerialNumber()), - namedtype.NamedType('attrCertValidityPeriod', AttCertValidityPeriod()), - namedtype.NamedType('attributes', univ.SequenceOf(componentType=rfc3280.Attribute())), - namedtype.OptionalNamedType('issuerUniqueID', rfc3280.UniqueIdentifier()), - namedtype.OptionalNamedType('extensions', rfc3280.Extensions()) -) - - -class AttributeCertificate(univ.Sequence): - pass - - -AttributeCertificate.componentType = namedtype.NamedTypes( - namedtype.NamedType('acinfo', AttributeCertificateInfo()), - namedtype.NamedType('signatureAlgorithm', rfc3280.AlgorithmIdentifier()), - namedtype.NamedType('signatureValue', univ.BitString()) -) - - -id_aca_authenticationInfo = _OID(id_aca, 1) - - -id_mod = _OID(rfc3280.id_pkix, 0) - - -id_mod_attribute_cert = _OID(id_mod, 12) - - -id_aca_accessIdentity = _OID(id_aca, 2) - - -id_aca_accessIdentity = _OID(id_aca, 2) - - -class RoleSyntax(univ.Sequence): - pass - - -RoleSyntax.componentType = namedtype.NamedTypes( - namedtype.OptionalNamedType('roleAuthority', rfc3280.GeneralNames().subtype(implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 0))), - namedtype.NamedType('roleName', rfc3280.GeneralName().subtype(implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 1))) -) - - -id_aca_chargingIdentity = _OID(id_aca, 3) - - -id_aca_chargingIdentity = _OID(id_aca, 3) - - -class ACClearAttrs(univ.Sequence): - pass - - -ACClearAttrs.componentType = namedtype.NamedTypes( - namedtype.NamedType('acIssuer', rfc3280.GeneralName()), - namedtype.NamedType('acSerial', univ.Integer()), - namedtype.NamedType('attrs', univ.SequenceOf(componentType=rfc3280.Attribute())) -) - - -id_ce_targetInformation = _OID(rfc3280.id_ce, 55) - - -id_aca_group = _OID(id_aca, 4) - - -id_aca_group = _OID(id_aca, 4) - - -id_pe_ac_proxying = _OID(rfc3280.id_pe, 10) - - -id_pe_aaControls = _OID(rfc3280.id_pe, 6) - - -class SvceAuthInfo(univ.Sequence): - pass - - -SvceAuthInfo.componentType = namedtype.NamedTypes( - namedtype.NamedType('service', rfc3280.GeneralName()), - namedtype.NamedType('ident', rfc3280.GeneralName()), - namedtype.OptionalNamedType('authInfo', univ.OctetString()) -) - - -class IetfAttrSyntax(univ.Sequence): - pass - - -IetfAttrSyntax.componentType = namedtype.NamedTypes( - namedtype.OptionalNamedType('policyAuthority', rfc3280.GeneralNames().subtype(implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 0))), - namedtype.NamedType('values', univ.SequenceOf(componentType=univ.Choice(componentType=namedtype.NamedTypes( - namedtype.NamedType('octets', univ.OctetString()), - namedtype.NamedType('oid', univ.ObjectIdentifier()), - namedtype.NamedType('string', char.UTF8String()) - )) - )) -) - - -id_aca_encAttrs = _OID(id_aca, 6) - - -id_aca_encAttrs = _OID(id_aca, 6) - - -id_pe_ac_proxying = _OID(rfc3280.id_pe, 10) - - diff --git a/anchor/asn1/rfc3852.py b/anchor/asn1/rfc3852.py deleted file mode 100644 index 438ed58..0000000 --- a/anchor/asn1/rfc3852.py +++ /dev/null @@ -1,663 +0,0 @@ -# Auto-generated by asn1ate on 2015-12-18 17:39:54.470347 -from pyasn1.type import univ, char, namedtype, namedval, tag, constraint, useful - -MAX = 64 - -from . import rfc3280 -from . import rfc3281 - -def _OID(*components): - output = [] - for x in tuple(components): - if isinstance(x, univ.ObjectIdentifier): - output.extend(list(x)) - else: - output.append(int(x)) - - return univ.ObjectIdentifier(output) - - -class AttributeValue(univ.Any): - pass - - -class Attribute(univ.Sequence): - pass - - -Attribute.componentType = namedtype.NamedTypes( - namedtype.NamedType('attrType', univ.ObjectIdentifier()), - namedtype.NamedType('attrValues', univ.SetOf(componentType=AttributeValue())) -) - - -class SignedAttributes(univ.SetOf): - pass - - -SignedAttributes.componentType = Attribute() -SignedAttributes.subtypeSpec=constraint.ValueSizeConstraint(1, MAX) - - -class OtherRevocationInfoFormat(univ.Sequence): - pass - - -OtherRevocationInfoFormat.componentType = namedtype.NamedTypes( - namedtype.NamedType('otherRevInfoFormat', univ.ObjectIdentifier()), - namedtype.NamedType('otherRevInfo', univ.Any()) -) - - -class RevocationInfoChoice(univ.Choice): - pass - - -RevocationInfoChoice.componentType = namedtype.NamedTypes( - namedtype.NamedType('crl', rfc3280.CertificateList()), - namedtype.NamedType('other', OtherRevocationInfoFormat().subtype(implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatConstructed, 1))) -) - - -class RevocationInfoChoices(univ.SetOf): - pass - - -RevocationInfoChoices.componentType = RevocationInfoChoice() - - -class OtherKeyAttribute(univ.Sequence): - pass - - -OtherKeyAttribute.componentType = namedtype.NamedTypes( - namedtype.NamedType('keyAttrId', univ.ObjectIdentifier()), - namedtype.OptionalNamedType('keyAttr', univ.Any()) -) - - -id_signedData = _OID(1, 2, 840, 113549, 1, 7, 2) - - -class KeyEncryptionAlgorithmIdentifier(rfc3280.AlgorithmIdentifier): - pass - - -class EncryptedKey(univ.OctetString): - pass - - -class CMSVersion(univ.Integer): - pass - - -CMSVersion.namedValues = namedval.NamedValues( - ('v0', 0), - ('v1', 1), - ('v2', 2), - ('v3', 3), - ('v4', 4), - ('v5', 5) -) - - -class KEKIdentifier(univ.Sequence): - pass - - -KEKIdentifier.componentType = namedtype.NamedTypes( - namedtype.NamedType('keyIdentifier', univ.OctetString()), - namedtype.OptionalNamedType('date', useful.GeneralizedTime()), - namedtype.OptionalNamedType('other', OtherKeyAttribute()) -) - - -class KEKRecipientInfo(univ.Sequence): - pass - - -KEKRecipientInfo.componentType = namedtype.NamedTypes( - namedtype.NamedType('version', CMSVersion()), - namedtype.NamedType('kekid', KEKIdentifier()), - namedtype.NamedType('keyEncryptionAlgorithm', KeyEncryptionAlgorithmIdentifier()), - namedtype.NamedType('encryptedKey', EncryptedKey()) -) - - -class KeyDerivationAlgorithmIdentifier(rfc3280.AlgorithmIdentifier): - pass - - -class PasswordRecipientInfo(univ.Sequence): - pass - - -PasswordRecipientInfo.componentType = namedtype.NamedTypes( - namedtype.NamedType('version', CMSVersion()), - namedtype.OptionalNamedType('keyDerivationAlgorithm', KeyDerivationAlgorithmIdentifier().subtype(implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 0))), - namedtype.NamedType('keyEncryptionAlgorithm', KeyEncryptionAlgorithmIdentifier()), - namedtype.NamedType('encryptedKey', EncryptedKey()) -) - - -class OtherRecipientInfo(univ.Sequence): - pass - - -OtherRecipientInfo.componentType = namedtype.NamedTypes( - namedtype.NamedType('oriType', univ.ObjectIdentifier()), - namedtype.NamedType('oriValue', univ.Any()) -) - - -class IssuerAndSerialNumber(univ.Sequence): - pass - - -IssuerAndSerialNumber.componentType = namedtype.NamedTypes( - namedtype.NamedType('issuer', rfc3280.Name()), - namedtype.NamedType('serialNumber', rfc3280.CertificateSerialNumber()) -) - - -class SubjectKeyIdentifier(univ.OctetString): - pass - - -class RecipientKeyIdentifier(univ.Sequence): - pass - - -RecipientKeyIdentifier.componentType = namedtype.NamedTypes( - namedtype.NamedType('subjectKeyIdentifier', SubjectKeyIdentifier()), - namedtype.OptionalNamedType('date', useful.GeneralizedTime()), - namedtype.OptionalNamedType('other', OtherKeyAttribute()) -) - - -class KeyAgreeRecipientIdentifier(univ.Choice): - pass - - -KeyAgreeRecipientIdentifier.componentType = namedtype.NamedTypes( - namedtype.NamedType('issuerAndSerialNumber', IssuerAndSerialNumber()), - namedtype.NamedType('rKeyId', RecipientKeyIdentifier().subtype(implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatConstructed, 0))) -) - - -class RecipientEncryptedKey(univ.Sequence): - pass - - -RecipientEncryptedKey.componentType = namedtype.NamedTypes( - namedtype.NamedType('rid', KeyAgreeRecipientIdentifier()), - namedtype.NamedType('encryptedKey', EncryptedKey()) -) - - -class RecipientEncryptedKeys(univ.SequenceOf): - pass - - -RecipientEncryptedKeys.componentType = RecipientEncryptedKey() - - -class UserKeyingMaterial(univ.OctetString): - pass - - -class OriginatorPublicKey(univ.Sequence): - pass - - -OriginatorPublicKey.componentType = namedtype.NamedTypes( - namedtype.NamedType('algorithm', rfc3280.AlgorithmIdentifier()), - namedtype.NamedType('publicKey', univ.BitString()) -) - - -class OriginatorIdentifierOrKey(univ.Choice): - pass - - -OriginatorIdentifierOrKey.componentType = namedtype.NamedTypes( - namedtype.NamedType('issuerAndSerialNumber', IssuerAndSerialNumber()), - namedtype.NamedType('subjectKeyIdentifier', SubjectKeyIdentifier().subtype(implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 0))), - namedtype.NamedType('originatorKey', OriginatorPublicKey().subtype(implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatConstructed, 1))) -) - - -class KeyAgreeRecipientInfo(univ.Sequence): - pass - - -KeyAgreeRecipientInfo.componentType = namedtype.NamedTypes( - namedtype.NamedType('version', CMSVersion()), - namedtype.NamedType('originator', OriginatorIdentifierOrKey().subtype(explicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatConstructed, 0))), - namedtype.OptionalNamedType('ukm', UserKeyingMaterial().subtype(explicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 1))), - namedtype.NamedType('keyEncryptionAlgorithm', KeyEncryptionAlgorithmIdentifier()), - namedtype.NamedType('recipientEncryptedKeys', RecipientEncryptedKeys()) -) - - -class RecipientIdentifier(univ.Choice): - pass - - -RecipientIdentifier.componentType = namedtype.NamedTypes( - namedtype.NamedType('issuerAndSerialNumber', IssuerAndSerialNumber()), - namedtype.NamedType('subjectKeyIdentifier', SubjectKeyIdentifier().subtype(implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 0))) -) - - -class KeyTransRecipientInfo(univ.Sequence): - pass - - -KeyTransRecipientInfo.componentType = namedtype.NamedTypes( - namedtype.NamedType('version', CMSVersion()), - namedtype.NamedType('rid', RecipientIdentifier()), - namedtype.NamedType('keyEncryptionAlgorithm', KeyEncryptionAlgorithmIdentifier()), - namedtype.NamedType('encryptedKey', EncryptedKey()) -) - - -class RecipientInfo(univ.Choice): - pass - - -RecipientInfo.componentType = namedtype.NamedTypes( - namedtype.NamedType('ktri', KeyTransRecipientInfo()), - namedtype.NamedType('kari', KeyAgreeRecipientInfo().subtype(implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatConstructed, 1))), - namedtype.NamedType('kekri', KEKRecipientInfo().subtype(implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatConstructed, 2))), - namedtype.NamedType('pwri', PasswordRecipientInfo().subtype(implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatConstructed, 3))), - namedtype.NamedType('ori', OtherRecipientInfo().subtype(implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatConstructed, 4))) -) - - -class RecipientInfos(univ.SetOf): - pass - - -RecipientInfos.componentType = RecipientInfo() -RecipientInfos.subtypeSpec=constraint.ValueSizeConstraint(1, MAX) - - -class DigestAlgorithmIdentifier(rfc3280.AlgorithmIdentifier): - pass - - -class Signature(univ.BitString): - pass - - -class SignerIdentifier(univ.Choice): - pass - - -SignerIdentifier.componentType = namedtype.NamedTypes( - namedtype.NamedType('issuerAndSerialNumber', IssuerAndSerialNumber()), - namedtype.NamedType('subjectKeyIdentifier', SubjectKeyIdentifier().subtype(implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 0))) -) - - -class UnprotectedAttributes(univ.SetOf): - pass - - -UnprotectedAttributes.componentType = Attribute() -UnprotectedAttributes.subtypeSpec=constraint.ValueSizeConstraint(1, MAX) - - -class ContentType(univ.ObjectIdentifier): - pass - - -class EncryptedContent(univ.OctetString): - pass - - -class ContentEncryptionAlgorithmIdentifier(rfc3280.AlgorithmIdentifier): - pass - - -class EncryptedContentInfo(univ.Sequence): - pass - - -EncryptedContentInfo.componentType = namedtype.NamedTypes( - namedtype.NamedType('contentType', ContentType()), - namedtype.NamedType('contentEncryptionAlgorithm', ContentEncryptionAlgorithmIdentifier()), - namedtype.OptionalNamedType('encryptedContent', EncryptedContent().subtype(implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 0))) -) - - -class EncryptedData(univ.Sequence): - pass - - -EncryptedData.componentType = namedtype.NamedTypes( - namedtype.NamedType('version', CMSVersion()), - namedtype.NamedType('encryptedContentInfo', EncryptedContentInfo()), - namedtype.OptionalNamedType('unprotectedAttrs', UnprotectedAttributes().subtype(implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 1))) -) - - -id_contentType = _OID(1, 2, 840, 113549, 1, 9, 3) - - -id_data = _OID(1, 2, 840, 113549, 1, 7, 1) - - -id_messageDigest = _OID(1, 2, 840, 113549, 1, 9, 4) - - -class DigestAlgorithmIdentifiers(univ.SetOf): - pass - - -DigestAlgorithmIdentifiers.componentType = DigestAlgorithmIdentifier() - - -class EncapsulatedContentInfo(univ.Sequence): - pass - - -EncapsulatedContentInfo.componentType = namedtype.NamedTypes( - namedtype.NamedType('eContentType', ContentType()), - namedtype.OptionalNamedType('eContent', univ.OctetString().subtype(explicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 0))) -) - - -class Digest(univ.OctetString): - pass - - -class DigestedData(univ.Sequence): - pass - - -DigestedData.componentType = namedtype.NamedTypes( - namedtype.NamedType('version', CMSVersion()), - namedtype.NamedType('digestAlgorithm', DigestAlgorithmIdentifier()), - namedtype.NamedType('encapContentInfo', EncapsulatedContentInfo()), - namedtype.NamedType('digest', Digest()) -) - - -class ContentInfo(univ.Sequence): - pass - - -ContentInfo.componentType = namedtype.NamedTypes( - namedtype.NamedType('contentType', ContentType()), - namedtype.NamedType('content', univ.Any().subtype(explicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 0))) -) - - -class UnauthAttributes(univ.SetOf): - pass - - -UnauthAttributes.componentType = Attribute() -UnauthAttributes.subtypeSpec=constraint.ValueSizeConstraint(1, MAX) - - -class ExtendedCertificateInfo(univ.Sequence): - pass - - -ExtendedCertificateInfo.componentType = namedtype.NamedTypes( - namedtype.NamedType('version', CMSVersion()), - namedtype.NamedType('certificate', rfc3280.Certificate()), - namedtype.NamedType('attributes', UnauthAttributes()) -) - - -class SignatureAlgorithmIdentifier(rfc3280.AlgorithmIdentifier): - pass - - -class ExtendedCertificate(univ.Sequence): - pass - - -ExtendedCertificate.componentType = namedtype.NamedTypes( - namedtype.NamedType('extendedCertificateInfo', ExtendedCertificateInfo()), - namedtype.NamedType('signatureAlgorithm', SignatureAlgorithmIdentifier()), - namedtype.NamedType('signature', Signature()) -) - - -class OtherCertificateFormat(univ.Sequence): - pass - - -OtherCertificateFormat.componentType = namedtype.NamedTypes( - namedtype.NamedType('otherCertFormat', univ.ObjectIdentifier()), - namedtype.NamedType('otherCert', univ.Any()) -) - - -class AttributeCertificateV2(rfc3281.AttributeCertificate): - pass - - -class AttCertVersionV1(univ.Integer): - pass - - -AttCertVersionV1.namedValues = namedval.NamedValues( - ('v1', 0) -) - - -class AttributeCertificateInfoV1(univ.Sequence): - pass - - -AttributeCertificateInfoV1.componentType = namedtype.NamedTypes( - namedtype.DefaultedNamedType('version', AttCertVersionV1().subtype(value="v1")), - namedtype.NamedType('subject', univ.Choice(componentType=namedtype.NamedTypes( - namedtype.NamedType('baseCertificateID', rfc3281.IssuerSerial().subtype(explicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 0))), - namedtype.NamedType('subjectName', rfc3280.GeneralNames().subtype(explicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 1))) - )) - ), - namedtype.NamedType('issuer', rfc3280.GeneralNames()), - namedtype.NamedType('signature', rfc3280.AlgorithmIdentifier()), - namedtype.NamedType('serialNumber', rfc3280.CertificateSerialNumber()), - namedtype.NamedType('attCertValidityPeriod', rfc3281.AttCertValidityPeriod()), - namedtype.NamedType('attributes', univ.SequenceOf(componentType=rfc3280.Attribute())), - namedtype.OptionalNamedType('issuerUniqueID', rfc3280.UniqueIdentifier()), - namedtype.OptionalNamedType('extensions', rfc3280.Extensions()) -) - - -class AttributeCertificateV1(univ.Sequence): - pass - - -AttributeCertificateV1.componentType = namedtype.NamedTypes( - namedtype.NamedType('acInfo', AttributeCertificateInfoV1()), - namedtype.NamedType('signatureAlgorithm', rfc3280.AlgorithmIdentifier()), - namedtype.NamedType('signature', univ.BitString()) -) - - -class CertificateChoices(univ.Choice): - pass - - -CertificateChoices.componentType = namedtype.NamedTypes( - namedtype.NamedType('certificate', rfc3280.Certificate()), - namedtype.NamedType('extendedCertificate', ExtendedCertificate().subtype(implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatConstructed, 0))), - namedtype.NamedType('v1AttrCert', AttributeCertificateV1().subtype(implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 1))), - namedtype.NamedType('v2AttrCert', AttributeCertificateV2().subtype(implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 2))), - namedtype.NamedType('other', OtherCertificateFormat().subtype(implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatConstructed, 3))) -) - - -class CertificateSet(univ.SetOf): - pass - - -CertificateSet.componentType = CertificateChoices() - - -class MessageAuthenticationCode(univ.OctetString): - pass - - -class UnsignedAttributes(univ.SetOf): - pass - - -UnsignedAttributes.componentType = Attribute() -UnsignedAttributes.subtypeSpec=constraint.ValueSizeConstraint(1, MAX) - - -class SignatureValue(univ.OctetString): - pass - - -class SignerInfo(univ.Sequence): - pass - - -SignerInfo.componentType = namedtype.NamedTypes( - namedtype.NamedType('version', CMSVersion()), - namedtype.NamedType('sid', SignerIdentifier()), - namedtype.NamedType('digestAlgorithm', DigestAlgorithmIdentifier()), - namedtype.OptionalNamedType('signedAttrs', SignedAttributes().subtype(implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 0))), - namedtype.NamedType('signatureAlgorithm', SignatureAlgorithmIdentifier()), - namedtype.NamedType('signature', SignatureValue()), - namedtype.OptionalNamedType('unsignedAttrs', UnsignedAttributes().subtype(implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 1))) -) - - -class SignerInfos(univ.SetOf): - pass - - -SignerInfos.componentType = SignerInfo() - - -class SignedData(univ.Sequence): - pass - - -SignedData.componentType = namedtype.NamedTypes( - namedtype.NamedType('version', CMSVersion()), - namedtype.NamedType('digestAlgorithms', DigestAlgorithmIdentifiers()), - namedtype.NamedType('encapContentInfo', EncapsulatedContentInfo()), - namedtype.OptionalNamedType('certificates', CertificateSet().subtype(implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 0))), - namedtype.OptionalNamedType('crls', RevocationInfoChoices().subtype(implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 1))), - namedtype.NamedType('signerInfos', SignerInfos()) -) - - -class MessageAuthenticationCodeAlgorithm(rfc3280.AlgorithmIdentifier): - pass - - -class MessageDigest(univ.OctetString): - pass - - -class Time(univ.Choice): - pass - - -Time.componentType = namedtype.NamedTypes( - namedtype.NamedType('utcTime', useful.UTCTime()), - namedtype.NamedType('generalTime', useful.GeneralizedTime()) -) - - -class OriginatorInfo(univ.Sequence): - pass - - -OriginatorInfo.componentType = namedtype.NamedTypes( - namedtype.OptionalNamedType('certs', CertificateSet().subtype(implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 0))), - namedtype.OptionalNamedType('crls', RevocationInfoChoices().subtype(implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 1))) -) - - -class AuthAttributes(univ.SetOf): - pass - - -AuthAttributes.componentType = Attribute() -AuthAttributes.subtypeSpec=constraint.ValueSizeConstraint(1, MAX) - - -class AuthenticatedData(univ.Sequence): - pass - - -AuthenticatedData.componentType = namedtype.NamedTypes( - namedtype.NamedType('version', CMSVersion()), - namedtype.OptionalNamedType('originatorInfo', OriginatorInfo().subtype(implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatConstructed, 0))), - namedtype.NamedType('recipientInfos', RecipientInfos()), - namedtype.NamedType('macAlgorithm', MessageAuthenticationCodeAlgorithm()), - namedtype.OptionalNamedType('digestAlgorithm', DigestAlgorithmIdentifier().subtype(implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 1))), - namedtype.NamedType('encapContentInfo', EncapsulatedContentInfo()), - namedtype.OptionalNamedType('authAttrs', AuthAttributes().subtype(implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 2))), - namedtype.NamedType('mac', MessageAuthenticationCode()), - namedtype.OptionalNamedType('unauthAttrs', UnauthAttributes().subtype(implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 3))) -) - - -id_ct_contentInfo = _OID(1, 2, 840, 113549, 1, 9, 16, 1, 6) - - -id_envelopedData = _OID(1, 2, 840, 113549, 1, 7, 3) - - -class EnvelopedData(univ.Sequence): - pass - - -EnvelopedData.componentType = namedtype.NamedTypes( - namedtype.NamedType('version', CMSVersion()), - namedtype.OptionalNamedType('originatorInfo', OriginatorInfo().subtype(implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatConstructed, 0))), - namedtype.NamedType('recipientInfos', RecipientInfos()), - namedtype.NamedType('encryptedContentInfo', EncryptedContentInfo()), - namedtype.OptionalNamedType('unprotectedAttrs', UnprotectedAttributes().subtype(implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 1))) -) - - -class Countersignature(SignerInfo): - pass - - -id_digestedData = _OID(1, 2, 840, 113549, 1, 7, 5) - - -id_signingTime = _OID(1, 2, 840, 113549, 1, 9, 5) - - -class ExtendedCertificateOrCertificate(univ.Choice): - pass - - -ExtendedCertificateOrCertificate.componentType = namedtype.NamedTypes( - namedtype.NamedType('certificate', rfc3280.Certificate()), - namedtype.NamedType('extendedCertificate', ExtendedCertificate().subtype(implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatConstructed, 0))) -) - - -id_encryptedData = _OID(1, 2, 840, 113549, 1, 7, 6) - - -id_ct_authData = _OID(1, 2, 840, 113549, 1, 9, 16, 1, 2) - - -class SigningTime(Time): - pass - - -id_countersignature = _OID(1, 2, 840, 113549, 1, 9, 6) - - diff --git a/anchor/asn1/rfc4211.py b/anchor/asn1/rfc4211.py deleted file mode 100644 index df72507..0000000 --- a/anchor/asn1/rfc4211.py +++ /dev/null @@ -1,349 +0,0 @@ -# Auto-generated by asn1ate on 2015-12-21 15:05:42.666261 -from pyasn1.type import univ, char, namedtype, namedval, tag, constraint, useful - -from . import rfc3280 -from . import rfc3852 - -MAX = 64 - - -def _OID(*components): - output = [] - for x in tuple(components): - if isinstance(x, univ.ObjectIdentifier): - output.extend(list(x)) - else: - output.append(int(x)) - - return univ.ObjectIdentifier(output) - - -id_pkix = _OID(1, 3, 6, 1, 5, 5, 7) - - -id_pkip = _OID(id_pkix, 5) - - -id_regCtrl = _OID(id_pkip, 1) - - -class SinglePubInfo(univ.Sequence): - pass - - -SinglePubInfo.componentType = namedtype.NamedTypes( - namedtype.NamedType('pubMethod', univ.Integer(namedValues=namedval.NamedValues(('dontCare', 0), ('x500', 1), ('web', 2), ('ldap', 3)))), - namedtype.OptionalNamedType('pubLocation', rfc3280.GeneralName()) -) - - -class UTF8Pairs(char.UTF8String): - pass - - -class PKMACValue(univ.Sequence): - pass - - -PKMACValue.componentType = namedtype.NamedTypes( - namedtype.NamedType('algId', rfc3280.AlgorithmIdentifier()), - namedtype.NamedType('value', univ.BitString()) -) - - -class POPOSigningKeyInput(univ.Sequence): - pass - - -POPOSigningKeyInput.componentType = namedtype.NamedTypes( - namedtype.NamedType('authInfo', univ.Choice(componentType=namedtype.NamedTypes( - namedtype.NamedType('sender', rfc3280.GeneralName().subtype(implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatConstructed, 0))), - namedtype.NamedType('publicKeyMAC', PKMACValue()) - )) - ), - namedtype.NamedType('publicKey', rfc3280.SubjectPublicKeyInfo()) -) - - -class POPOSigningKey(univ.Sequence): - pass - - -POPOSigningKey.componentType = namedtype.NamedTypes( - namedtype.OptionalNamedType('poposkInput', POPOSigningKeyInput().subtype(implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatConstructed, 0))), - namedtype.NamedType('algorithmIdentifier', rfc3280.AlgorithmIdentifier()), - namedtype.NamedType('signature', univ.BitString()) -) - - -class Attributes(univ.SetOf): - pass - - -Attributes.componentType = rfc3280.Attribute() - - -class PrivateKeyInfo(univ.Sequence): - pass - - -PrivateKeyInfo.componentType = namedtype.NamedTypes( - namedtype.NamedType('version', univ.Integer()), - namedtype.NamedType('privateKeyAlgorithm', rfc3280.AlgorithmIdentifier()), - namedtype.NamedType('privateKey', univ.OctetString()), - namedtype.OptionalNamedType('attributes', Attributes().subtype(implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 0))) -) - - -class EncryptedValue(univ.Sequence): - pass - - -EncryptedValue.componentType = namedtype.NamedTypes( - namedtype.OptionalNamedType('intendedAlg', rfc3280.AlgorithmIdentifier().subtype(implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 0))), - namedtype.OptionalNamedType('symmAlg', rfc3280.AlgorithmIdentifier().subtype(implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 1))), - namedtype.OptionalNamedType('encSymmKey', univ.BitString().subtype(implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 2))), - namedtype.OptionalNamedType('keyAlg', rfc3280.AlgorithmIdentifier().subtype(implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 3))), - namedtype.OptionalNamedType('valueHint', univ.OctetString().subtype(implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 4))), - namedtype.NamedType('encValue', univ.BitString()) -) - - -class EncryptedKey(univ.Choice): - pass - - -EncryptedKey.componentType = namedtype.NamedTypes( - namedtype.NamedType('encryptedValue', EncryptedValue()), - namedtype.NamedType('envelopedData', rfc3852.EnvelopedData().subtype(implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 0))) -) - - -class KeyGenParameters(univ.OctetString): - pass - - -class PKIArchiveOptions(univ.Choice): - pass - - -PKIArchiveOptions.componentType = namedtype.NamedTypes( - namedtype.NamedType('encryptedPrivKey', EncryptedKey().subtype(implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatConstructed, 0))), - namedtype.NamedType('keyGenParameters', KeyGenParameters().subtype(implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 1))), - namedtype.NamedType('archiveRemGenPrivKey', univ.Boolean().subtype(implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 2))) -) - - -id_regCtrl_authenticator = _OID(id_regCtrl, 2) - - -id_regInfo = _OID(id_pkip, 2) - - -id_regInfo_certReq = _OID(id_regInfo, 2) - - -class ProtocolEncrKey(rfc3280.SubjectPublicKeyInfo): - pass - - -class Authenticator(char.UTF8String): - pass - - -class SubsequentMessage(univ.Integer): - pass - - -SubsequentMessage.namedValues = namedval.NamedValues( - ('encrCert', 0), - ('challengeResp', 1) -) - - -class AttributeTypeAndValue(univ.Sequence): - pass - - -AttributeTypeAndValue.componentType = namedtype.NamedTypes( - namedtype.NamedType('type', univ.ObjectIdentifier()), - namedtype.NamedType('value', univ.Any()) -) - - -class POPOPrivKey(univ.Choice): - pass - - -POPOPrivKey.componentType = namedtype.NamedTypes( - namedtype.NamedType('thisMessage', univ.BitString().subtype(implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 0))), - namedtype.NamedType('subsequentMessage', SubsequentMessage().subtype(implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 1))), - namedtype.NamedType('dhMAC', univ.BitString().subtype(implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 2))), - namedtype.NamedType('agreeMAC', PKMACValue().subtype(implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatConstructed, 3))), - namedtype.NamedType('encryptedKey', rfc3852.EnvelopedData().subtype(implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 4))) -) - - -class ProofOfPossession(univ.Choice): - pass - - -ProofOfPossession.componentType = namedtype.NamedTypes( - namedtype.NamedType('raVerified', univ.Null().subtype(implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 0))), - namedtype.NamedType('signature', POPOSigningKey().subtype(implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatConstructed, 1))), - namedtype.NamedType('keyEncipherment', POPOPrivKey().subtype(implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatConstructed, 2))), - namedtype.NamedType('keyAgreement', POPOPrivKey().subtype(implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatConstructed, 3))) -) - - -class OptionalValidity(univ.Sequence): - pass - - -OptionalValidity.componentType = namedtype.NamedTypes( - namedtype.OptionalNamedType('notBefore', rfc3280.Time().subtype(implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatConstructed, 0))), - namedtype.OptionalNamedType('notAfter', rfc3280.Time().subtype(implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatConstructed, 1))) -) - - -class CertTemplate(univ.Sequence): - pass - - -CertTemplate.componentType = namedtype.NamedTypes( - namedtype.OptionalNamedType('version', rfc3280.Version().subtype(implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 0))), - namedtype.OptionalNamedType('serialNumber', univ.Integer().subtype(implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 1))), - namedtype.OptionalNamedType('signingAlg', rfc3280.AlgorithmIdentifier().subtype(implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 2))), - namedtype.OptionalNamedType('issuer', rfc3280.Name().subtype(implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatConstructed, 3))), - namedtype.OptionalNamedType('validity', OptionalValidity().subtype(implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatConstructed, 4))), - namedtype.OptionalNamedType('subject', rfc3280.Name().subtype(implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatConstructed, 5))), - namedtype.OptionalNamedType('publicKey', rfc3280.SubjectPublicKeyInfo().subtype(implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 6))), - namedtype.OptionalNamedType('issuerUID', rfc3280.UniqueIdentifier().subtype(implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 7))), - namedtype.OptionalNamedType('subjectUID', rfc3280.UniqueIdentifier().subtype(implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 8))), - namedtype.OptionalNamedType('extensions', rfc3280.Extensions().subtype(implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 9))) -) - - -class Controls(univ.SequenceOf): - pass - - -Controls.componentType = AttributeTypeAndValue() -Controls.subtypeSpec=constraint.ValueSizeConstraint(1, MAX) - - -class CertRequest(univ.Sequence): - pass - - -CertRequest.componentType = namedtype.NamedTypes( - namedtype.NamedType('certReqId', univ.Integer()), - namedtype.NamedType('certTemplate', CertTemplate()), - namedtype.OptionalNamedType('controls', Controls()) -) - - -class CertReqMsg(univ.Sequence): - pass - - -CertReqMsg.componentType = namedtype.NamedTypes( - namedtype.NamedType('certReq', CertRequest()), - namedtype.OptionalNamedType('popo', ProofOfPossession()), - namedtype.OptionalNamedType('regInfo', univ.SequenceOf(componentType=AttributeTypeAndValue())) -) - - -class CertReqMessages(univ.SequenceOf): - pass - - -CertReqMessages.componentType = CertReqMsg() -CertReqMessages.subtypeSpec=constraint.ValueSizeConstraint(1, MAX) - - -class CertReq(CertRequest): - pass - - -id_regCtrl_pkiPublicationInfo = _OID(id_regCtrl, 3) - - -class CertId(univ.Sequence): - pass - - -CertId.componentType = namedtype.NamedTypes( - namedtype.NamedType('issuer', rfc3280.GeneralName()), - namedtype.NamedType('serialNumber', univ.Integer()) -) - - -class OldCertId(CertId): - pass - - -class PKIPublicationInfo(univ.Sequence): - pass - - -PKIPublicationInfo.componentType = namedtype.NamedTypes( - namedtype.NamedType('action', univ.Integer(namedValues=namedval.NamedValues(('dontPublish', 0), ('pleasePublish', 1)))), - namedtype.OptionalNamedType('pubInfos', univ.SequenceOf(componentType=SinglePubInfo())) -) - - -class EncKeyWithID(univ.Sequence): - pass - - -EncKeyWithID.componentType = namedtype.NamedTypes( - namedtype.NamedType('privateKey', PrivateKeyInfo()), - namedtype.OptionalNamedType('identifier', univ.Choice(componentType=namedtype.NamedTypes( - namedtype.NamedType('string', char.UTF8String()), - namedtype.NamedType('generalName', rfc3280.GeneralName()) - )) - ) -) - - -id_regCtrl_protocolEncrKey = _OID(id_regCtrl, 6) - - -id_regCtrl_oldCertID = _OID(id_regCtrl, 5) - - -id_smime = _OID(1, 2, 840, 113549, 1, 9, 16) - - -class PBMParameter(univ.Sequence): - pass - - -PBMParameter.componentType = namedtype.NamedTypes( - namedtype.NamedType('salt', univ.OctetString()), - namedtype.NamedType('owf', rfc3280.AlgorithmIdentifier()), - namedtype.NamedType('iterationCount', univ.Integer()), - namedtype.NamedType('mac', rfc3280.AlgorithmIdentifier()) -) - - -id_regCtrl_regToken = _OID(id_regCtrl, 1) - - -id_regCtrl_pkiArchiveOptions = _OID(id_regCtrl, 4) - - -id_regInfo_utf8Pairs = _OID(id_regInfo, 1) - - -id_ct = _OID(id_smime, 1) - - -id_ct_encKeyWithID = _OID(id_ct, 21) - - -class RegToken(char.UTF8String): - pass - - diff --git a/anchor/asn1/rfc5280.py b/anchor/asn1/rfc5280.py deleted file mode 100644 index 011968a..0000000 --- a/anchor/asn1/rfc5280.py +++ /dev/null @@ -1,1502 +0,0 @@ -from pyasn1.type import univ -from pyasn1.type import char -from pyasn1.type import namedtype -from pyasn1.type import namedval -from pyasn1.type import tag -from pyasn1.type import constraint -from pyasn1.type import useful - - -MAX = 64 - - -def _OID(*components): - output = [] - for x in tuple(components): - if isinstance(x, univ.ObjectIdentifier): - output.extend(list(x)) - else: - output.append(int(x)) - - return univ.ObjectIdentifier(output) - - -ub_e163_4_sub_address_length = univ.Integer(40) - - -ub_e163_4_number_length = univ.Integer(15) - - -unformatted_postal_address = univ.Integer(16) - - -class TerminalType(univ.Integer): - pass - - -TerminalType.namedValues = namedval.NamedValues( - ('telex', 3), - ('teletex', 4), - ('g3-facsimile', 5), - ('g4-facsimile', 6), - ('ia5-terminal', 7), - ('videotex', 8) -) - - -class Extension(univ.Sequence): - pass - - -Extension.componentType = namedtype.NamedTypes( - namedtype.NamedType('extnID', univ.ObjectIdentifier()), - namedtype.DefaultedNamedType('critical', univ.Boolean().subtype(value=0)), - namedtype.NamedType('extnValue', univ.OctetString()) -) - - -class Extensions(univ.SequenceOf): - pass - - -Extensions.componentType = Extension() -Extensions.subtypeSpec=constraint.ValueSizeConstraint(1, MAX) - - -physical_delivery_personal_name = univ.Integer(13) - - -ub_unformatted_address_length = univ.Integer(180) - - -ub_pds_parameter_length = univ.Integer(30) - - -ub_pds_physical_address_lines = univ.Integer(6) - - -class UnformattedPostalAddress(univ.Set): - pass - - -UnformattedPostalAddress.componentType = namedtype.NamedTypes( - namedtype.OptionalNamedType('printable-address', univ.SequenceOf(componentType=char.PrintableString().subtype(subtypeSpec=constraint.ValueSizeConstraint(1, ub_pds_parameter_length)))), - namedtype.OptionalNamedType('teletex-string', char.TeletexString().subtype(subtypeSpec=constraint.ValueSizeConstraint(1, ub_unformatted_address_length))) -) - - -ub_organization_name = univ.Integer(64) - - -class X520OrganizationName(univ.Choice): - pass - - -X520OrganizationName.componentType = namedtype.NamedTypes( - namedtype.NamedType('teletexString', char.TeletexString().subtype(subtypeSpec=constraint.ValueSizeConstraint(1, ub_organization_name))), - namedtype.NamedType('printableString', char.PrintableString().subtype(subtypeSpec=constraint.ValueSizeConstraint(1, ub_organization_name))), - namedtype.NamedType('universalString', char.UniversalString().subtype(subtypeSpec=constraint.ValueSizeConstraint(1, ub_organization_name))), - namedtype.NamedType('utf8String', char.UTF8String().subtype(subtypeSpec=constraint.ValueSizeConstraint(1, ub_organization_name))), - namedtype.NamedType('bmpString', char.BMPString().subtype(subtypeSpec=constraint.ValueSizeConstraint(1, ub_organization_name))) -) - - -ub_x121_address_length = univ.Integer(16) - - -pds_name = univ.Integer(7) - - -id_pkix = _OID(1, 3, 6, 1, 5, 5, 7) - - -id_kp = _OID(id_pkix, 3) - - -ub_postal_code_length = univ.Integer(16) - - -class PostalCode(univ.Choice): - pass - - -PostalCode.componentType = namedtype.NamedTypes( - namedtype.NamedType('numeric-code', char.NumericString().subtype(subtypeSpec=constraint.ValueSizeConstraint(1, ub_postal_code_length))), - namedtype.NamedType('printable-code', char.PrintableString().subtype(subtypeSpec=constraint.ValueSizeConstraint(1, ub_postal_code_length))) -) - - -ub_generation_qualifier_length = univ.Integer(3) - - -unique_postal_name = univ.Integer(20) - - -class DomainComponent(char.IA5String): - pass - - -ub_domain_defined_attribute_value_length = univ.Integer(128) - - -ub_match = univ.Integer(128) - - -id_at = _OID(2, 5, 4) - - -class AttributeType(univ.ObjectIdentifier): - pass - - -id_at_organizationalUnitName = _OID(id_at, 11) - - -terminal_type = univ.Integer(23) - - -class PDSParameter(univ.Set): - pass - - -PDSParameter.componentType = namedtype.NamedTypes( - namedtype.OptionalNamedType('printable-string', char.PrintableString().subtype(subtypeSpec=constraint.ValueSizeConstraint(1, ub_pds_parameter_length))), - namedtype.OptionalNamedType('teletex-string', char.TeletexString().subtype(subtypeSpec=constraint.ValueSizeConstraint(1, ub_pds_parameter_length))) -) - - -class PhysicalDeliveryPersonalName(PDSParameter): - pass - - -ub_surname_length = univ.Integer(40) - - -id_ad = _OID(id_pkix, 48) - - -ub_domain_defined_attribute_type_length = univ.Integer(8) - - -class TeletexDomainDefinedAttribute(univ.Sequence): - pass - - -TeletexDomainDefinedAttribute.componentType = namedtype.NamedTypes( - namedtype.NamedType('type', char.TeletexString().subtype(subtypeSpec=constraint.ValueSizeConstraint(1, ub_domain_defined_attribute_type_length))), - namedtype.NamedType('value', char.TeletexString().subtype(subtypeSpec=constraint.ValueSizeConstraint(1, ub_domain_defined_attribute_value_length))) -) - - -ub_domain_defined_attributes = univ.Integer(4) - - -class TeletexDomainDefinedAttributes(univ.SequenceOf): - pass - - -TeletexDomainDefinedAttributes.componentType = TeletexDomainDefinedAttribute() -TeletexDomainDefinedAttributes.subtypeSpec=constraint.ValueSizeConstraint(1, ub_domain_defined_attributes) - - -extended_network_address = univ.Integer(22) - - -ub_locality_name = univ.Integer(128) - - -class X520LocalityName(univ.Choice): - pass - - -X520LocalityName.componentType = namedtype.NamedTypes( - namedtype.NamedType('teletexString', char.TeletexString().subtype(subtypeSpec=constraint.ValueSizeConstraint(1, ub_locality_name))), - namedtype.NamedType('printableString', char.PrintableString().subtype(subtypeSpec=constraint.ValueSizeConstraint(1, ub_locality_name))), - namedtype.NamedType('universalString', char.UniversalString().subtype(subtypeSpec=constraint.ValueSizeConstraint(1, ub_locality_name))), - namedtype.NamedType('utf8String', char.UTF8String().subtype(subtypeSpec=constraint.ValueSizeConstraint(1, ub_locality_name))), - namedtype.NamedType('bmpString', char.BMPString().subtype(subtypeSpec=constraint.ValueSizeConstraint(1, ub_locality_name))) -) - - -teletex_organization_name = univ.Integer(3) - - -ub_given_name_length = univ.Integer(16) - - -ub_initials_length = univ.Integer(5) - - -class PersonalName(univ.Set): - pass - - -PersonalName.componentType = namedtype.NamedTypes( - namedtype.NamedType('surname', char.PrintableString().subtype(subtypeSpec=constraint.ValueSizeConstraint(1, ub_surname_length)).subtype(implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 0))), - namedtype.OptionalNamedType('given-name', char.PrintableString().subtype(subtypeSpec=constraint.ValueSizeConstraint(1, ub_given_name_length)).subtype(implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 1))), - namedtype.OptionalNamedType('initials', char.PrintableString().subtype(subtypeSpec=constraint.ValueSizeConstraint(1, ub_initials_length)).subtype(implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 2))), - namedtype.OptionalNamedType('generation-qualifier', char.PrintableString().subtype(subtypeSpec=constraint.ValueSizeConstraint(1, ub_generation_qualifier_length)).subtype(implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 3))) -) - - -ub_organizational_unit_name_length = univ.Integer(32) - - -class OrganizationalUnitName(char.PrintableString): - pass - - -OrganizationalUnitName.subtypeSpec = constraint.ValueSizeConstraint(1, ub_organizational_unit_name_length) - - -id_at_generationQualifier = _OID(id_at, 44) - - -class Version(univ.Integer): - pass - - -Version.namedValues = namedval.NamedValues( - ('v1', 0), - ('v2', 1), - ('v3', 2) -) - - -class CertificateSerialNumber(univ.Integer): - pass - - -class AlgorithmIdentifier(univ.Sequence): - pass - - -AlgorithmIdentifier.componentType = namedtype.NamedTypes( - namedtype.NamedType('algorithm', univ.ObjectIdentifier()), - namedtype.OptionalNamedType('parameters', univ.Any()) -) - - -class Time(univ.Choice): - pass - - -Time.componentType = namedtype.NamedTypes( - namedtype.NamedType('utcTime', useful.UTCTime()), - namedtype.NamedType('generalTime', useful.GeneralizedTime()) -) - - -class AttributeValue(univ.Any): - pass - - -class AttributeTypeAndValue(univ.Sequence): - pass - - -AttributeTypeAndValue.componentType = namedtype.NamedTypes( - namedtype.NamedType('type', AttributeType()), - namedtype.NamedType('value', AttributeValue()) -) - - -class RelativeDistinguishedName(univ.SetOf): - pass - - -RelativeDistinguishedName.componentType = AttributeTypeAndValue() -RelativeDistinguishedName.subtypeSpec=constraint.ValueSizeConstraint(1, MAX) - - -class RDNSequence(univ.SequenceOf): - pass - - -RDNSequence.componentType = RelativeDistinguishedName() - - -class Name(univ.Choice): - pass - - -Name.componentType = namedtype.NamedTypes( - namedtype.NamedType('rdnSequence', RDNSequence()) -) - - -class TBSCertList(univ.Sequence): - pass - - -TBSCertList.componentType = namedtype.NamedTypes( - namedtype.OptionalNamedType('version', Version()), - namedtype.NamedType('signature', AlgorithmIdentifier()), - namedtype.NamedType('issuer', Name()), - namedtype.NamedType('thisUpdate', Time()), - namedtype.OptionalNamedType('nextUpdate', Time()), - namedtype.OptionalNamedType('revokedCertificates', univ.SequenceOf(componentType=univ.Sequence(componentType=namedtype.NamedTypes( - namedtype.NamedType('userCertificate', CertificateSerialNumber()), - namedtype.NamedType('revocationDate', Time()), - namedtype.OptionalNamedType('crlEntryExtensions', Extensions()) - )) - )), - namedtype.OptionalNamedType('crlExtensions', Extensions().subtype(explicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 0))) -) - - -class CertificateList(univ.Sequence): - pass - - -CertificateList.componentType = namedtype.NamedTypes( - namedtype.NamedType('tbsCertList', TBSCertList()), - namedtype.NamedType('signatureAlgorithm', AlgorithmIdentifier()), - namedtype.NamedType('signature', univ.BitString()) -) - - -class PhysicalDeliveryOfficeName(PDSParameter): - pass - - -ub_extension_attributes = univ.Integer(256) - - -class ExtensionAttribute(univ.Sequence): - pass - - -ExtensionAttribute.componentType = namedtype.NamedTypes( - namedtype.NamedType('extension-attribute-type', univ.Integer().subtype(subtypeSpec=constraint.ValueRangeConstraint(0, ub_extension_attributes)).subtype(implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 0))), - namedtype.NamedType('extension-attribute-value', univ.Any().subtype(explicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 1))) -) - - -id_qt = _OID(id_pkix, 2) - - -id_qt_cps = _OID(id_qt, 1) - - -id_at_stateOrProvinceName = _OID(id_at, 8) - - -id_at_title = _OID(id_at, 12) - - -id_at_serialNumber = _OID(id_at, 5) - - -class X520dnQualifier(char.PrintableString): - pass - - -class PosteRestanteAddress(PDSParameter): - pass - - -poste_restante_address = univ.Integer(19) - - -class UniqueIdentifier(univ.BitString): - pass - - -class Validity(univ.Sequence): - pass - - -Validity.componentType = namedtype.NamedTypes( - namedtype.NamedType('notBefore', Time()), - namedtype.NamedType('notAfter', Time()) -) - - -class SubjectPublicKeyInfo(univ.Sequence): - pass - - -SubjectPublicKeyInfo.componentType = namedtype.NamedTypes( - namedtype.NamedType('algorithm', AlgorithmIdentifier()), - namedtype.NamedType('subjectPublicKey', univ.BitString()) -) - - -class TBSCertificate(univ.Sequence): - pass - - -TBSCertificate.componentType = namedtype.NamedTypes( - namedtype.DefaultedNamedType('version', - Version().subtype(explicitTag=tag.Tag(tag.tagClassContext, - tag.tagFormatSimple, 0)).subtype(value="v1")), - namedtype.NamedType('serialNumber', CertificateSerialNumber()), - namedtype.NamedType('signature', AlgorithmIdentifier()), - namedtype.NamedType('issuer', Name()), - namedtype.NamedType('validity', Validity()), - namedtype.NamedType('subject', Name()), - namedtype.NamedType('subjectPublicKeyInfo', SubjectPublicKeyInfo()), - namedtype.OptionalNamedType('issuerUniqueID', UniqueIdentifier().subtype(implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 1))), - namedtype.OptionalNamedType('subjectUniqueID', UniqueIdentifier().subtype(implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 2))), - namedtype.OptionalNamedType('extensions', Extensions().subtype(explicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 3))) -) - - -physical_delivery_office_name = univ.Integer(10) - - -ub_name = univ.Integer(32768) - - -class X520name(univ.Choice): - pass - - -X520name.componentType = namedtype.NamedTypes( - namedtype.NamedType('teletexString', char.TeletexString().subtype(subtypeSpec=constraint.ValueSizeConstraint(1, ub_name))), - namedtype.NamedType('printableString', char.PrintableString().subtype(subtypeSpec=constraint.ValueSizeConstraint(1, ub_name))), - namedtype.NamedType('universalString', char.UniversalString().subtype(subtypeSpec=constraint.ValueSizeConstraint(1, ub_name))), - namedtype.NamedType('utf8String', char.UTF8String().subtype(subtypeSpec=constraint.ValueSizeConstraint(1, ub_name))), - namedtype.NamedType('bmpString', char.BMPString().subtype(subtypeSpec=constraint.ValueSizeConstraint(1, ub_name))) -) - - -id_at_dnQualifier = _OID(id_at, 46) - - -ub_serial_number = univ.Integer(64) - - -ub_pseudonym = univ.Integer(128) - - -pkcs_9 = _OID(1, 2, 840, 113549, 1, 9) - - -class X121Address(char.NumericString): - pass - - -X121Address.subtypeSpec = constraint.ValueSizeConstraint(1, ub_x121_address_length) - - -class NetworkAddress(X121Address): - pass - - -ub_integer_options = univ.Integer(256) - - -id_at_commonName = _OID(id_at, 3) - - -ub_organization_name_length = univ.Integer(64) - - -id_ad_ocsp = _OID(id_ad, 1) - - -ub_country_name_numeric_length = univ.Integer(3) - - -ub_country_name_alpha_length = univ.Integer(2) - - -class PhysicalDeliveryCountryName(univ.Choice): - pass - - -PhysicalDeliveryCountryName.componentType = namedtype.NamedTypes( - namedtype.NamedType('x121-dcc-code', char.NumericString().subtype(subtypeSpec=constraint.ValueSizeConstraint(ub_country_name_numeric_length, ub_country_name_numeric_length))), - namedtype.NamedType('iso-3166-alpha2-code', char.PrintableString().subtype(subtypeSpec=constraint.ValueSizeConstraint(ub_country_name_alpha_length, ub_country_name_alpha_length))) -) - - -id_emailAddress = _OID(pkcs_9, 1) - - -common_name = univ.Integer(1) - - -class X520Pseudonym(univ.Choice): - pass - - -X520Pseudonym.componentType = namedtype.NamedTypes( - namedtype.NamedType('teletexString', char.TeletexString().subtype(subtypeSpec=constraint.ValueSizeConstraint(1, ub_pseudonym))), - namedtype.NamedType('printableString', char.PrintableString().subtype(subtypeSpec=constraint.ValueSizeConstraint(1, ub_pseudonym))), - namedtype.NamedType('universalString', char.UniversalString().subtype(subtypeSpec=constraint.ValueSizeConstraint(1, ub_pseudonym))), - namedtype.NamedType('utf8String', char.UTF8String().subtype(subtypeSpec=constraint.ValueSizeConstraint(1, ub_pseudonym))), - namedtype.NamedType('bmpString', char.BMPString().subtype(subtypeSpec=constraint.ValueSizeConstraint(1, ub_pseudonym))) -) - - -ub_domain_name_length = univ.Integer(16) - - -class AdministrationDomainName(univ.Choice): - pass - - -AdministrationDomainName.tagSet = univ.Choice.tagSet.tagExplicitly(tag.Tag(tag.tagClassApplication, tag.tagFormatConstructed, 2)) -AdministrationDomainName.componentType = namedtype.NamedTypes( - namedtype.NamedType('numeric', char.NumericString().subtype(subtypeSpec=constraint.ValueSizeConstraint(0, ub_domain_name_length))), - namedtype.NamedType('printable', char.PrintableString().subtype(subtypeSpec=constraint.ValueSizeConstraint(0, ub_domain_name_length))) -) - - -class PresentationAddress(univ.Sequence): - pass - - -PresentationAddress.componentType = namedtype.NamedTypes( - namedtype.OptionalNamedType('pSelector', univ.OctetString().subtype(explicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 0))), - namedtype.OptionalNamedType('sSelector', univ.OctetString().subtype(explicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 1))), - namedtype.OptionalNamedType('tSelector', univ.OctetString().subtype(explicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 2))), - namedtype.NamedType('nAddresses', univ.SetOf(componentType=univ.OctetString()).subtype(explicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 3))) -) - - -class ExtendedNetworkAddress(univ.Choice): - pass - - -ExtendedNetworkAddress.componentType = namedtype.NamedTypes( - namedtype.NamedType('e163-4-address', univ.Sequence(componentType=namedtype.NamedTypes( - namedtype.NamedType('number', char.NumericString().subtype(subtypeSpec=constraint.ValueSizeConstraint(1, ub_e163_4_number_length)).subtype(implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 0))), - namedtype.OptionalNamedType('sub-address', char.NumericString().subtype(subtypeSpec=constraint.ValueSizeConstraint(1, ub_e163_4_sub_address_length)).subtype(implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 1))) - )) - ), - namedtype.NamedType('psap-address', PresentationAddress().subtype(implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatConstructed, 0))) -) - - -class TeletexOrganizationName(char.TeletexString): - pass - - -TeletexOrganizationName.subtypeSpec = constraint.ValueSizeConstraint(1, ub_organization_name_length) - - -ub_terminal_id_length = univ.Integer(24) - - -class TerminalIdentifier(char.PrintableString): - pass - - -TerminalIdentifier.subtypeSpec = constraint.ValueSizeConstraint(1, ub_terminal_id_length) - - -id_ad_caIssuers = _OID(id_ad, 2) - - -id_at_countryName = _OID(id_at, 6) - - -class StreetAddress(PDSParameter): - pass - - -postal_code = univ.Integer(9) - - -id_at_givenName = _OID(id_at, 42) - - -ub_title = univ.Integer(64) - - -class ExtensionAttributes(univ.SetOf): - pass - - -ExtensionAttributes.componentType = ExtensionAttribute() -ExtensionAttributes.subtypeSpec=constraint.ValueSizeConstraint(1, ub_extension_attributes) - - -ub_emailaddress_length = univ.Integer(255) - - -id_ad_caRepository = _OID(id_ad, 5) - - -class ExtensionORAddressComponents(PDSParameter): - pass - - -ub_organizational_unit_name = univ.Integer(64) - - -class X520OrganizationalUnitName(univ.Choice): - pass - - -X520OrganizationalUnitName.componentType = namedtype.NamedTypes( - namedtype.NamedType('teletexString', char.TeletexString().subtype(subtypeSpec=constraint.ValueSizeConstraint(1, ub_organizational_unit_name))), - namedtype.NamedType('printableString', char.PrintableString().subtype(subtypeSpec=constraint.ValueSizeConstraint(1, ub_organizational_unit_name))), - namedtype.NamedType('universalString', char.UniversalString().subtype(subtypeSpec=constraint.ValueSizeConstraint(1, ub_organizational_unit_name))), - namedtype.NamedType('utf8String', char.UTF8String().subtype(subtypeSpec=constraint.ValueSizeConstraint(1, ub_organizational_unit_name))), - namedtype.NamedType('bmpString', char.BMPString().subtype(subtypeSpec=constraint.ValueSizeConstraint(1, ub_organizational_unit_name))) -) - - -class LocalPostalAttributes(PDSParameter): - pass - - -teletex_organizational_unit_names = univ.Integer(5) - - -class X520Title(univ.Choice): - pass - - -X520Title.componentType = namedtype.NamedTypes( - namedtype.NamedType('teletexString', char.TeletexString().subtype(subtypeSpec=constraint.ValueSizeConstraint(1, ub_title))), - namedtype.NamedType('printableString', char.PrintableString().subtype(subtypeSpec=constraint.ValueSizeConstraint(1, ub_title))), - namedtype.NamedType('universalString', char.UniversalString().subtype(subtypeSpec=constraint.ValueSizeConstraint(1, ub_title))), - namedtype.NamedType('utf8String', char.UTF8String().subtype(subtypeSpec=constraint.ValueSizeConstraint(1, ub_title))), - namedtype.NamedType('bmpString', char.BMPString().subtype(subtypeSpec=constraint.ValueSizeConstraint(1, ub_title))) -) - - -id_at_localityName = _OID(id_at, 7) - - -id_at_initials = _OID(id_at, 43) - - -ub_state_name = univ.Integer(128) - - -class X520StateOrProvinceName(univ.Choice): - pass - - -X520StateOrProvinceName.componentType = namedtype.NamedTypes( - namedtype.NamedType('teletexString', char.TeletexString().subtype(subtypeSpec=constraint.ValueSizeConstraint(1, ub_state_name))), - namedtype.NamedType('printableString', char.PrintableString().subtype(subtypeSpec=constraint.ValueSizeConstraint(1, ub_state_name))), - namedtype.NamedType('universalString', char.UniversalString().subtype(subtypeSpec=constraint.ValueSizeConstraint(1, ub_state_name))), - namedtype.NamedType('utf8String', char.UTF8String().subtype(subtypeSpec=constraint.ValueSizeConstraint(1, ub_state_name))), - namedtype.NamedType('bmpString', char.BMPString().subtype(subtypeSpec=constraint.ValueSizeConstraint(1, ub_state_name))) -) - - -physical_delivery_organization_name = univ.Integer(14) - - -id_at_surname = _OID(id_at, 4) - - -class X520countryName(char.PrintableString): - pass - - -X520countryName.subtypeSpec = constraint.ValueSizeConstraint(2, 2) - - -physical_delivery_office_number = univ.Integer(11) - - -id_qt_unotice = _OID(id_qt, 2) - - -class X520SerialNumber(char.PrintableString): - pass - - -X520SerialNumber.subtypeSpec = constraint.ValueSizeConstraint(1, ub_serial_number) - - -class Attribute(univ.Sequence): - pass - - -Attribute.componentType = namedtype.NamedTypes( - namedtype.NamedType('type', AttributeType()), - namedtype.NamedType('values', univ.SetOf(componentType=AttributeValue())) -) - - -ub_common_name = univ.Integer(64) - - -id_pe = _OID(id_pkix, 1) - - -class ExtensionPhysicalDeliveryAddressComponents(PDSParameter): - pass - - -class EmailAddress(char.IA5String): - pass - - -EmailAddress.subtypeSpec = constraint.ValueSizeConstraint(1, ub_emailaddress_length) - - -id_at_organizationName = _OID(id_at, 10) - - -post_office_box_address = univ.Integer(18) - - -class BuiltInDomainDefinedAttribute(univ.Sequence): - pass - - -BuiltInDomainDefinedAttribute.componentType = namedtype.NamedTypes( - namedtype.NamedType('type', char.PrintableString().subtype(subtypeSpec=constraint.ValueSizeConstraint(1, ub_domain_defined_attribute_type_length))), - namedtype.NamedType('value', char.PrintableString().subtype(subtypeSpec=constraint.ValueSizeConstraint(1, ub_domain_defined_attribute_value_length))) -) - - -class BuiltInDomainDefinedAttributes(univ.SequenceOf): - pass - - -BuiltInDomainDefinedAttributes.componentType = BuiltInDomainDefinedAttribute() -BuiltInDomainDefinedAttributes.subtypeSpec=constraint.ValueSizeConstraint(1, ub_domain_defined_attributes) - - -id_at_pseudonym = _OID(id_at, 65) - - -id_domainComponent = _OID(0, 9, 2342, 19200300, 100, 1, 25) - - -class X520CommonName(univ.Choice): - pass - - -X520CommonName.componentType = namedtype.NamedTypes( - namedtype.NamedType('teletexString', char.TeletexString().subtype(subtypeSpec=constraint.ValueSizeConstraint(1, ub_common_name))), - namedtype.NamedType('printableString', char.PrintableString().subtype(subtypeSpec=constraint.ValueSizeConstraint(1, ub_common_name))), - namedtype.NamedType('universalString', char.UniversalString().subtype(subtypeSpec=constraint.ValueSizeConstraint(1, ub_common_name))), - namedtype.NamedType('utf8String', char.UTF8String().subtype(subtypeSpec=constraint.ValueSizeConstraint(1, ub_common_name))), - namedtype.NamedType('bmpString', char.BMPString().subtype(subtypeSpec=constraint.ValueSizeConstraint(1, ub_common_name))) -) - - -extension_OR_address_components = univ.Integer(12) - - -ub_organizational_units = univ.Integer(4) - - -teletex_personal_name = univ.Integer(4) - - -ub_numeric_user_id_length = univ.Integer(32) - - -ub_common_name_length = univ.Integer(64) - - -class TeletexCommonName(char.TeletexString): - pass - - -TeletexCommonName.subtypeSpec = constraint.ValueSizeConstraint(1, ub_common_name_length) - - -class PhysicalDeliveryOrganizationName(PDSParameter): - pass - - -extension_physical_delivery_address_components = univ.Integer(15) - - -class NumericUserIdentifier(char.NumericString): - pass - - -NumericUserIdentifier.subtypeSpec = constraint.ValueSizeConstraint(1, ub_numeric_user_id_length) - - -class CountryName(univ.Choice): - pass - - -CountryName.tagSet = univ.Choice.tagSet.tagExplicitly(tag.Tag(tag.tagClassApplication, tag.tagFormatConstructed, 1)) -CountryName.componentType = namedtype.NamedTypes( - namedtype.NamedType('x121-dcc-code', char.NumericString().subtype(subtypeSpec=constraint.ValueSizeConstraint(ub_country_name_numeric_length, ub_country_name_numeric_length))), - namedtype.NamedType('iso-3166-alpha2-code', char.PrintableString().subtype(subtypeSpec=constraint.ValueSizeConstraint(ub_country_name_alpha_length, ub_country_name_alpha_length))) -) - - -class OrganizationName(char.PrintableString): - pass - - -OrganizationName.subtypeSpec = constraint.ValueSizeConstraint(1, ub_organization_name_length) - - -class OrganizationalUnitNames(univ.SequenceOf): - pass - - -OrganizationalUnitNames.componentType = OrganizationalUnitName() -OrganizationalUnitNames.subtypeSpec=constraint.ValueSizeConstraint(1, ub_organizational_units) - - -class PrivateDomainName(univ.Choice): - pass - - -PrivateDomainName.componentType = namedtype.NamedTypes( - namedtype.NamedType('numeric', char.NumericString().subtype(subtypeSpec=constraint.ValueSizeConstraint(1, ub_domain_name_length))), - namedtype.NamedType('printable', char.PrintableString().subtype(subtypeSpec=constraint.ValueSizeConstraint(1, ub_domain_name_length))) -) - - -class BuiltInStandardAttributes(univ.Sequence): - pass - - -BuiltInStandardAttributes.componentType = namedtype.NamedTypes( - namedtype.OptionalNamedType('country-name', CountryName()), - namedtype.OptionalNamedType('administration-domain-name', AdministrationDomainName()), - namedtype.OptionalNamedType('network-address', NetworkAddress().subtype(implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 0))), - namedtype.OptionalNamedType('terminal-identifier', TerminalIdentifier().subtype(implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 1))), - namedtype.OptionalNamedType('private-domain-name', PrivateDomainName().subtype(explicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatConstructed, 2))), - namedtype.OptionalNamedType('organization-name', OrganizationName().subtype(implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 3))), - namedtype.OptionalNamedType('numeric-user-identifier', NumericUserIdentifier().subtype(implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 4))), - namedtype.OptionalNamedType('personal-name', PersonalName().subtype(implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatConstructed, 5))), - namedtype.OptionalNamedType('organizational-unit-names', OrganizationalUnitNames().subtype(implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 6))) -) - - -class ORAddress(univ.Sequence): - pass - - -ORAddress.componentType = namedtype.NamedTypes( - namedtype.NamedType('built-in-standard-attributes', BuiltInStandardAttributes()), - namedtype.OptionalNamedType('built-in-domain-defined-attributes', BuiltInDomainDefinedAttributes()), - namedtype.OptionalNamedType('extension-attributes', ExtensionAttributes()) -) - - -class DistinguishedName(RDNSequence): - pass - - -id_ad_timeStamping = _OID(id_ad, 3) - - -class PhysicalDeliveryOfficeNumber(PDSParameter): - pass - - -teletex_domain_defined_attributes = univ.Integer(6) - - -class UniquePostalName(PDSParameter): - pass - - -physical_delivery_country_name = univ.Integer(8) - - -ub_pds_name_length = univ.Integer(16) - - -class PDSName(char.PrintableString): - pass - - -PDSName.subtypeSpec = constraint.ValueSizeConstraint(1, ub_pds_name_length) - - -class TeletexPersonalName(univ.Set): - pass - - -TeletexPersonalName.componentType = namedtype.NamedTypes( - namedtype.NamedType('surname', char.TeletexString().subtype(subtypeSpec=constraint.ValueSizeConstraint(1, ub_surname_length)).subtype(implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 0))), - namedtype.OptionalNamedType('given-name', char.TeletexString().subtype(subtypeSpec=constraint.ValueSizeConstraint(1, ub_given_name_length)).subtype(implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 1))), - namedtype.OptionalNamedType('initials', char.TeletexString().subtype(subtypeSpec=constraint.ValueSizeConstraint(1, ub_initials_length)).subtype(implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 2))), - namedtype.OptionalNamedType('generation-qualifier', char.TeletexString().subtype(subtypeSpec=constraint.ValueSizeConstraint(1, ub_generation_qualifier_length)).subtype(implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 3))) -) - - -street_address = univ.Integer(17) - - -class PostOfficeBoxAddress(PDSParameter): - pass - - -local_postal_attributes = univ.Integer(21) - - -class DirectoryString(univ.Choice): - pass - - -DirectoryString.componentType = namedtype.NamedTypes( - namedtype.NamedType('teletexString', char.TeletexString().subtype(subtypeSpec=constraint.ValueSizeConstraint(1, MAX))), - namedtype.NamedType('printableString', char.PrintableString().subtype(subtypeSpec=constraint.ValueSizeConstraint(1, MAX))), - namedtype.NamedType('universalString', char.UniversalString().subtype(subtypeSpec=constraint.ValueSizeConstraint(1, MAX))), - namedtype.NamedType('utf8String', char.UTF8String().subtype(subtypeSpec=constraint.ValueSizeConstraint(1, MAX))), - namedtype.NamedType('bmpString', char.BMPString().subtype(subtypeSpec=constraint.ValueSizeConstraint(1, MAX))) -) - - -teletex_common_name = univ.Integer(2) - - -class CommonName(char.PrintableString): - pass - - -CommonName.subtypeSpec = constraint.ValueSizeConstraint(1, ub_common_name_length) - - -class Certificate(univ.Sequence): - pass - - -Certificate.componentType = namedtype.NamedTypes( - namedtype.NamedType('tbsCertificate', TBSCertificate()), - namedtype.NamedType('signatureAlgorithm', AlgorithmIdentifier()), - namedtype.NamedType('signature', univ.BitString()) -) - - -class TeletexOrganizationalUnitName(char.TeletexString): - pass - - -TeletexOrganizationalUnitName.subtypeSpec = constraint.ValueSizeConstraint(1, ub_organizational_unit_name_length) - - -id_at_name = _OID(id_at, 41) - - -class TeletexOrganizationalUnitNames(univ.SequenceOf): - pass - - -TeletexOrganizationalUnitNames.componentType = TeletexOrganizationalUnitName() -TeletexOrganizationalUnitNames.subtypeSpec=constraint.ValueSizeConstraint(1, ub_organizational_units) - - -id_ce = _OID(2, 5, 29) - - -id_ce_issuerAltName = _OID(id_ce, 18) - - -class SkipCerts(univ.Integer): - pass - - -SkipCerts.subtypeSpec = constraint.ValueRangeConstraint(0, MAX) - - -class CRLReason(univ.Enumerated): - pass - - -CRLReason.namedValues = namedval.NamedValues( - ('unspecified', 0), - ('keyCompromise', 1), - ('cACompromise', 2), - ('affiliationChanged', 3), - ('superseded', 4), - ('cessationOfOperation', 5), - ('certificateHold', 6), - ('removeFromCRL', 8), - ('privilegeWithdrawn', 9), - ('aACompromise', 10) -) - - -class PrivateKeyUsagePeriod(univ.Sequence): - pass - - -PrivateKeyUsagePeriod.componentType = namedtype.NamedTypes( - namedtype.OptionalNamedType('notBefore', useful.GeneralizedTime().subtype(implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 0))), - namedtype.OptionalNamedType('notAfter', useful.GeneralizedTime().subtype(implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 1))) -) - - -class AnotherName(univ.Sequence): - pass - - -AnotherName.componentType = namedtype.NamedTypes( - namedtype.NamedType('type-id', univ.ObjectIdentifier()), - namedtype.NamedType('value', univ.Any().subtype(explicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 0))) -) - - -class EDIPartyName(univ.Sequence): - pass - - -EDIPartyName.componentType = namedtype.NamedTypes( - namedtype.OptionalNamedType('nameAssigner', DirectoryString().subtype(implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatConstructed, 0))), - namedtype.NamedType('partyName', DirectoryString().subtype(implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatConstructed, 1))) -) - - -class GeneralName(univ.Choice): - pass - - -GeneralName.componentType = namedtype.NamedTypes( - namedtype.NamedType('otherName', AnotherName().subtype(implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatConstructed, 0))), - namedtype.NamedType('rfc822Name', char.IA5String().subtype(implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 1))), - namedtype.NamedType('dNSName', char.IA5String().subtype(implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 2))), - namedtype.NamedType('x400Address', ORAddress().subtype(implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 3))), - namedtype.NamedType('directoryName', Name().subtype(implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatConstructed, 4))), - namedtype.NamedType('ediPartyName', EDIPartyName().subtype(implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatConstructed, 5))), - namedtype.NamedType('uniformResourceIdentifier', char.IA5String().subtype(implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 6))), - namedtype.NamedType('iPAddress', univ.OctetString().subtype(implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 7))), - namedtype.NamedType('registeredID', univ.ObjectIdentifier().subtype(implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 8))) -) - - -class BaseDistance(univ.Integer): - pass - - -BaseDistance.subtypeSpec = constraint.ValueRangeConstraint(0, MAX) - - -class GeneralSubtree(univ.Sequence): - pass - - -GeneralSubtree.componentType = namedtype.NamedTypes( - namedtype.NamedType('base', GeneralName()), - namedtype.DefaultedNamedType('minimum', BaseDistance().subtype(implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 0)).subtype(value=0)), - namedtype.OptionalNamedType('maximum', BaseDistance().subtype(implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 1))) -) - - -class GeneralNames(univ.SequenceOf): - pass - - -GeneralNames.componentType = GeneralName() -GeneralNames.subtypeSpec=constraint.ValueSizeConstraint(1, MAX) - - -class DistributionPointName(univ.Choice): - pass - - -DistributionPointName.componentType = namedtype.NamedTypes( - namedtype.NamedType('fullName', GeneralNames().subtype(implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 0))), - namedtype.NamedType('nameRelativeToCRLIssuer', RelativeDistinguishedName().subtype(implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 1))) -) - - -class ReasonFlags(univ.BitString): - pass - - -ReasonFlags.namedValues = namedval.NamedValues( - ('unused', 0), - ('keyCompromise', 1), - ('cACompromise', 2), - ('affiliationChanged', 3), - ('superseded', 4), - ('cessationOfOperation', 5), - ('certificateHold', 6), - ('privilegeWithdrawn', 7), - ('aACompromise', 8) -) - - -class IssuingDistributionPoint(univ.Sequence): - pass - - -IssuingDistributionPoint.componentType = namedtype.NamedTypes( - namedtype.OptionalNamedType('distributionPoint', DistributionPointName().subtype(implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatConstructed, 0))), - namedtype.DefaultedNamedType('onlyContainsUserCerts', univ.Boolean().subtype(implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 1)).subtype(value=0)), - namedtype.DefaultedNamedType('onlyContainsCACerts', univ.Boolean().subtype(implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 2)).subtype(value=0)), - namedtype.OptionalNamedType('onlySomeReasons', ReasonFlags().subtype(implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 3))), - namedtype.DefaultedNamedType('indirectCRL', univ.Boolean().subtype(implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 4)).subtype(value=0)), - namedtype.DefaultedNamedType('onlyContainsAttributeCerts', univ.Boolean().subtype(implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 5)).subtype(value=0)) -) - - -id_ce_certificatePolicies = _OID(id_ce, 32) - - -id_kp_emailProtection = _OID(id_kp, 4) - - -class AccessDescription(univ.Sequence): - pass - - -AccessDescription.componentType = namedtype.NamedTypes( - namedtype.NamedType('accessMethod', univ.ObjectIdentifier()), - namedtype.NamedType('accessLocation', GeneralName()) -) - - -class IssuerAltName(GeneralNames): - pass - - -id_ce_cRLDistributionPoints = _OID(id_ce, 31) - - -holdInstruction = _OID(2, 2, 840, 10040, 2) - - -id_holdinstruction_callissuer = _OID(holdInstruction, 2) - - -id_ce_subjectDirectoryAttributes = _OID(id_ce, 9) - - -id_ce_issuingDistributionPoint = _OID(id_ce, 28) - - -class DistributionPoint(univ.Sequence): - pass - - -DistributionPoint.componentType = namedtype.NamedTypes( - namedtype.OptionalNamedType('distributionPoint', DistributionPointName().subtype(implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatConstructed, 0))), - namedtype.OptionalNamedType('reasons', ReasonFlags().subtype(implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 1))), - namedtype.OptionalNamedType('cRLIssuer', GeneralNames().subtype(implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 2))) -) - - -class CRLDistributionPoints(univ.SequenceOf): - pass - - -CRLDistributionPoints.componentType = DistributionPoint() -CRLDistributionPoints.subtypeSpec=constraint.ValueSizeConstraint(1, MAX) - - -class GeneralSubtrees(univ.SequenceOf): - pass - - -GeneralSubtrees.componentType = GeneralSubtree() -GeneralSubtrees.subtypeSpec=constraint.ValueSizeConstraint(1, MAX) - - -class NameConstraints(univ.Sequence): - pass - - -NameConstraints.componentType = namedtype.NamedTypes( - namedtype.OptionalNamedType('permittedSubtrees', GeneralSubtrees().subtype(implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 0))), - namedtype.OptionalNamedType('excludedSubtrees', GeneralSubtrees().subtype(implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 1))) -) - - -class SubjectDirectoryAttributes(univ.SequenceOf): - pass - - -SubjectDirectoryAttributes.componentType = Attribute() -SubjectDirectoryAttributes.subtypeSpec=constraint.ValueSizeConstraint(1, MAX) - - -id_kp_OCSPSigning = _OID(id_kp, 9) - - -id_kp_timeStamping = _OID(id_kp, 8) - - -class DisplayText(univ.Choice): - pass - - -DisplayText.componentType = namedtype.NamedTypes( - namedtype.NamedType('ia5String', char.IA5String().subtype(subtypeSpec=constraint.ValueSizeConstraint(1, 200))), - namedtype.NamedType('visibleString', char.VisibleString().subtype(subtypeSpec=constraint.ValueSizeConstraint(1, 200))), - namedtype.NamedType('bmpString', char.BMPString().subtype(subtypeSpec=constraint.ValueSizeConstraint(1, 200))), - namedtype.NamedType('utf8String', char.UTF8String().subtype(subtypeSpec=constraint.ValueSizeConstraint(1, 200))) -) - - -class NoticeReference(univ.Sequence): - pass - - -NoticeReference.componentType = namedtype.NamedTypes( - namedtype.NamedType('organization', DisplayText()), - namedtype.NamedType('noticeNumbers', univ.SequenceOf(componentType=univ.Integer())) -) - - -class UserNotice(univ.Sequence): - pass - - -UserNotice.componentType = namedtype.NamedTypes( - namedtype.OptionalNamedType('noticeRef', NoticeReference()), - namedtype.OptionalNamedType('explicitText', DisplayText()) -) - - -class PolicyQualifierId(univ.ObjectIdentifier): - pass - - -class PolicyQualifierInfo(univ.Sequence): - pass - - -PolicyQualifierInfo.componentType = namedtype.NamedTypes( - namedtype.NamedType('policyQualifierId', PolicyQualifierId()), - namedtype.NamedType('qualifier', univ.Any()) -) - - -class CertPolicyId(univ.ObjectIdentifier): - pass - - -class PolicyInformation(univ.Sequence): - pass - - -PolicyInformation.componentType = namedtype.NamedTypes( - namedtype.NamedType('policyIdentifier', CertPolicyId()), - namedtype.OptionalNamedType('policyQualifiers', univ.SequenceOf(componentType=PolicyQualifierInfo())) -) - - -class CertificatePolicies(univ.SequenceOf): - pass - - -CertificatePolicies.componentType = PolicyInformation() -CertificatePolicies.subtypeSpec=constraint.ValueSizeConstraint(1, MAX) - - -class SubjectAltName(GeneralNames): - pass - - -id_ce_basicConstraints = _OID(id_ce, 19) - - -id_ce_authorityKeyIdentifier = _OID(id_ce, 35) - - -id_kp_codeSigning = _OID(id_kp, 3) - - -class BasicConstraints(univ.Sequence): - pass - - -BasicConstraints.componentType = namedtype.NamedTypes( - namedtype.DefaultedNamedType('cA', univ.Boolean().subtype(value=0)), - namedtype.OptionalNamedType('pathLenConstraint', univ.Integer().subtype(subtypeSpec=constraint.ValueRangeConstraint(0, MAX))) -) - - -id_ce_certificateIssuer = _OID(id_ce, 29) - - -class PolicyMappings(univ.SequenceOf): - pass - - -PolicyMappings.componentType = univ.Sequence(componentType=namedtype.NamedTypes( - namedtype.NamedType('issuerDomainPolicy', CertPolicyId()), - namedtype.NamedType('subjectDomainPolicy', CertPolicyId()) -)) - -PolicyMappings.subtypeSpec=constraint.ValueSizeConstraint(1, MAX) - - -class InhibitAnyPolicy(SkipCerts): - pass - - -anyPolicy = _OID(id_ce_certificatePolicies, 0) - - -class CRLNumber(univ.Integer): - pass - - -CRLNumber.subtypeSpec = constraint.ValueRangeConstraint(0, MAX) - - -class BaseCRLNumber(CRLNumber): - pass - - -id_ce_nameConstraints = _OID(id_ce, 30) - - -id_kp_serverAuth = _OID(id_kp, 1) - - -id_ce_freshestCRL = _OID(id_ce, 46) - - -id_ce_cRLReasons = _OID(id_ce, 21) - - -id_ce_extKeyUsage = _OID(id_ce, 37) - - -class KeyIdentifier(univ.OctetString): - pass - - -class AuthorityKeyIdentifier(univ.Sequence): - pass - - -AuthorityKeyIdentifier.componentType = namedtype.NamedTypes( - namedtype.OptionalNamedType('keyIdentifier', KeyIdentifier().subtype(implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 0))), - namedtype.OptionalNamedType('authorityCertIssuer', GeneralNames().subtype(implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 1))), - namedtype.OptionalNamedType('authorityCertSerialNumber', CertificateSerialNumber().subtype(implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 2))) -) - - -class FreshestCRL(CRLDistributionPoints): - pass - - -id_ce_policyConstraints = _OID(id_ce, 36) - - -id_pe_authorityInfoAccess = _OID(id_pe, 1) - - -class AuthorityInfoAccessSyntax(univ.SequenceOf): - pass - - -AuthorityInfoAccessSyntax.componentType = AccessDescription() -AuthorityInfoAccessSyntax.subtypeSpec=constraint.ValueSizeConstraint(1, MAX) - - -id_holdinstruction_none = _OID(holdInstruction, 1) - - -class CPSuri(char.IA5String): - pass - - -id_pe_subjectInfoAccess = _OID(id_pe, 11) - - -class SubjectKeyIdentifier(KeyIdentifier): - pass - - -id_ce_subjectAltName = _OID(id_ce, 17) - - -class KeyPurposeId(univ.ObjectIdentifier): - pass - - -class ExtKeyUsageSyntax(univ.SequenceOf): - pass - - -ExtKeyUsageSyntax.componentType = KeyPurposeId() -ExtKeyUsageSyntax.subtypeSpec=constraint.ValueSizeConstraint(1, MAX) - - -class HoldInstructionCode(univ.ObjectIdentifier): - pass - - -id_ce_deltaCRLIndicator = _OID(id_ce, 27) - - -id_ce_keyUsage = _OID(id_ce, 15) - - -id_ce_holdInstructionCode = _OID(id_ce, 23) - - -class SubjectInfoAccessSyntax(univ.SequenceOf): - pass - - -SubjectInfoAccessSyntax.componentType = AccessDescription() -SubjectInfoAccessSyntax.subtypeSpec=constraint.ValueSizeConstraint(1, MAX) - - -class InvalidityDate(useful.GeneralizedTime): - pass - - -class KeyUsage(univ.BitString): - pass - - -KeyUsage.namedValues = namedval.NamedValues( - ('digitalSignature', 0), - ('nonRepudiation', 1), - ('keyEncipherment', 2), - ('dataEncipherment', 3), - ('keyAgreement', 4), - ('keyCertSign', 5), - ('cRLSign', 6), - ('encipherOnly', 7), - ('decipherOnly', 8) -) - - -id_ce_invalidityDate = _OID(id_ce, 24) - - -id_ce_policyMappings = _OID(id_ce, 33) - - -anyExtendedKeyUsage = _OID(id_ce_extKeyUsage, 0) - - -id_ce_privateKeyUsagePeriod = _OID(id_ce, 16) - - -id_ce_cRLNumber = _OID(id_ce, 20) - - -class CertificateIssuer(GeneralNames): - pass - - -id_holdinstruction_reject = _OID(holdInstruction, 3) - - -class PolicyConstraints(univ.Sequence): - pass - - -PolicyConstraints.componentType = namedtype.NamedTypes( - namedtype.OptionalNamedType('requireExplicitPolicy', SkipCerts().subtype(implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 0))), - namedtype.OptionalNamedType('inhibitPolicyMapping', SkipCerts().subtype(implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 1))) -) - - -id_kp_clientAuth = _OID(id_kp, 2) - - -id_ce_subjectKeyIdentifier = _OID(id_ce, 14) - - -id_ce_inhibitAnyPolicy = _OID(id_ce, 54) - - diff --git a/anchor/asn1/rfc5652.py b/anchor/asn1/rfc5652.py deleted file mode 100644 index 279d5e1..0000000 --- a/anchor/asn1/rfc5652.py +++ /dev/null @@ -1,666 +0,0 @@ -from pyasn1.type import char -from pyasn1.type import constraint -from pyasn1.type import namedtype -from pyasn1.type import namedval -from pyasn1.type import tag -from pyasn1.type import univ -from pyasn1.type import useful - -from . import rfc3281 -from . import rfc5280 - -MAX = 64 - -def _OID(*components): - output = [] - for x in tuple(components): - if isinstance(x, univ.ObjectIdentifier): - output.extend(list(x)) - else: - output.append(int(x)) - - return univ.ObjectIdentifier(output) - - -class AttCertVersionV1(univ.Integer): - pass - - -AttCertVersionV1.namedValues = namedval.NamedValues( - ('v1', 0) -) - - -class AttributeCertificateInfoV1(univ.Sequence): - pass - - -AttributeCertificateInfoV1.componentType = namedtype.NamedTypes( - namedtype.DefaultedNamedType('version', AttCertVersionV1().subtype(value="v1")), - namedtype.NamedType('subject', univ.Choice(componentType=namedtype.NamedTypes( - namedtype.NamedType('baseCertificateID', rfc3281.IssuerSerial().subtype(explicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 0))), - namedtype.NamedType('subjectName', rfc5280.GeneralNames().subtype(explicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 1))) - )) - ), - namedtype.NamedType('issuer', rfc5280.GeneralNames()), - namedtype.NamedType('signature', rfc5280.AlgorithmIdentifier()), - namedtype.NamedType('serialNumber', rfc5280.CertificateSerialNumber()), - namedtype.NamedType('attCertValidityPeriod', rfc3281.AttCertValidityPeriod()), - namedtype.NamedType('attributes', univ.SequenceOf(componentType=rfc5280.Attribute())), - namedtype.OptionalNamedType('issuerUniqueID', rfc5280.UniqueIdentifier()), - namedtype.OptionalNamedType('extensions', rfc5280.Extensions()) -) - - -class AttributeCertificateV1(univ.Sequence): - pass - - -AttributeCertificateV1.componentType = namedtype.NamedTypes( - namedtype.NamedType('acInfo', AttributeCertificateInfoV1()), - namedtype.NamedType('signatureAlgorithm', rfc5280.AlgorithmIdentifier()), - namedtype.NamedType('signature', univ.BitString()) -) - - -class AttributeValue(univ.Any): - pass - - -class Attribute(univ.Sequence): - pass - - -Attribute.componentType = namedtype.NamedTypes( - namedtype.NamedType('attrType', univ.ObjectIdentifier()), - namedtype.NamedType('attrValues', univ.SetOf(componentType=AttributeValue())) -) - - -class SignedAttributes(univ.SetOf): - pass - - -SignedAttributes.componentType = Attribute() -SignedAttributes.subtypeSpec=constraint.ValueSizeConstraint(1, MAX) - - -class AttributeCertificateV2(rfc3281.AttributeCertificate): - pass - - -class OtherKeyAttribute(univ.Sequence): - pass - - -OtherKeyAttribute.componentType = namedtype.NamedTypes( - namedtype.NamedType('keyAttrId', univ.ObjectIdentifier()), - namedtype.OptionalNamedType('keyAttr', univ.Any()) -) - - -class UnauthAttributes(univ.SetOf): - pass - - -UnauthAttributes.componentType = Attribute() -UnauthAttributes.subtypeSpec=constraint.ValueSizeConstraint(1, MAX) - - -id_encryptedData = _OID(1, 2, 840, 113549, 1, 7, 6) - - -class SignatureValue(univ.OctetString): - pass - - -class IssuerAndSerialNumber(univ.Sequence): - pass - - -IssuerAndSerialNumber.componentType = namedtype.NamedTypes( - namedtype.NamedType('issuer', rfc5280.Name()), - namedtype.NamedType('serialNumber', rfc5280.CertificateSerialNumber()) -) - - -class SubjectKeyIdentifier(univ.OctetString): - pass - - -class RecipientKeyIdentifier(univ.Sequence): - pass - - -RecipientKeyIdentifier.componentType = namedtype.NamedTypes( - namedtype.NamedType('subjectKeyIdentifier', SubjectKeyIdentifier()), - namedtype.OptionalNamedType('date', useful.GeneralizedTime()), - namedtype.OptionalNamedType('other', OtherKeyAttribute()) -) - - -class KeyAgreeRecipientIdentifier(univ.Choice): - pass - - -KeyAgreeRecipientIdentifier.componentType = namedtype.NamedTypes( - namedtype.NamedType('issuerAndSerialNumber', IssuerAndSerialNumber()), - namedtype.NamedType('rKeyId', RecipientKeyIdentifier().subtype(implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatConstructed, 0))) -) - - -class EncryptedKey(univ.OctetString): - pass - - -class RecipientEncryptedKey(univ.Sequence): - pass - - -RecipientEncryptedKey.componentType = namedtype.NamedTypes( - namedtype.NamedType('rid', KeyAgreeRecipientIdentifier()), - namedtype.NamedType('encryptedKey', EncryptedKey()) -) - - -class RecipientEncryptedKeys(univ.SequenceOf): - pass - - -RecipientEncryptedKeys.componentType = RecipientEncryptedKey() - - -class MessageAuthenticationCode(univ.OctetString): - pass - - -class CMSVersion(univ.Integer): - pass - - -CMSVersion.namedValues = namedval.NamedValues( - ('v0', 0), - ('v1', 1), - ('v2', 2), - ('v3', 3), - ('v4', 4), - ('v5', 5) -) - - -class OtherCertificateFormat(univ.Sequence): - pass - - -OtherCertificateFormat.componentType = namedtype.NamedTypes( - namedtype.NamedType('otherCertFormat', univ.ObjectIdentifier()), - namedtype.NamedType('otherCert', univ.Any()) -) - - -class ExtendedCertificateInfo(univ.Sequence): - pass - - -ExtendedCertificateInfo.componentType = namedtype.NamedTypes( - namedtype.NamedType('version', CMSVersion()), - namedtype.NamedType('certificate', rfc5280.Certificate()), - namedtype.NamedType('attributes', UnauthAttributes()) -) - - -class Signature(univ.BitString): - pass - - -class SignatureAlgorithmIdentifier(rfc5280.AlgorithmIdentifier): - pass - - -class ExtendedCertificate(univ.Sequence): - pass - - -ExtendedCertificate.componentType = namedtype.NamedTypes( - namedtype.NamedType('extendedCertificateInfo', ExtendedCertificateInfo()), - namedtype.NamedType('signatureAlgorithm', SignatureAlgorithmIdentifier()), - namedtype.NamedType('signature', Signature()) -) - - -class CertificateChoices(univ.Choice): - pass - - -CertificateChoices.componentType = namedtype.NamedTypes( - namedtype.NamedType('certificate', rfc5280.Certificate()), - namedtype.NamedType('extendedCertificate', ExtendedCertificate().subtype(implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatConstructed, 0))), - namedtype.NamedType('v1AttrCert', AttributeCertificateV1().subtype(implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 1))), - namedtype.NamedType('v2AttrCert', AttributeCertificateV2().subtype(implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 2))), - namedtype.NamedType('other', OtherCertificateFormat().subtype(implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatConstructed, 3))) -) - - -class CertificateSet(univ.SetOf): - pass - - -CertificateSet.componentType = CertificateChoices() - - -class OtherRevocationInfoFormat(univ.Sequence): - pass - - -OtherRevocationInfoFormat.componentType = namedtype.NamedTypes( - namedtype.NamedType('otherRevInfoFormat', univ.ObjectIdentifier()), - namedtype.NamedType('otherRevInfo', univ.Any()) -) - - -class RevocationInfoChoice(univ.Choice): - pass - - -RevocationInfoChoice.componentType = namedtype.NamedTypes( - namedtype.NamedType('crl', rfc5280.CertificateList()), - namedtype.NamedType('other', OtherRevocationInfoFormat().subtype(implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatConstructed, 1))) -) - - -class RevocationInfoChoices(univ.SetOf): - pass - - -RevocationInfoChoices.componentType = RevocationInfoChoice() - - -class OriginatorInfo(univ.Sequence): - pass - - -OriginatorInfo.componentType = namedtype.NamedTypes( - namedtype.OptionalNamedType('certs', CertificateSet().subtype(implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 0))), - namedtype.OptionalNamedType('crls', RevocationInfoChoices().subtype(implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 1))) -) - - -class ContentType(univ.ObjectIdentifier): - pass - - -class EncryptedContent(univ.OctetString): - pass - - -class ContentEncryptionAlgorithmIdentifier(rfc5280.AlgorithmIdentifier): - pass - - -class EncryptedContentInfo(univ.Sequence): - pass - - -EncryptedContentInfo.componentType = namedtype.NamedTypes( - namedtype.NamedType('contentType', ContentType()), - namedtype.NamedType('contentEncryptionAlgorithm', ContentEncryptionAlgorithmIdentifier()), - namedtype.OptionalNamedType('encryptedContent', EncryptedContent().subtype(implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 0))) -) - - -class UnprotectedAttributes(univ.SetOf): - pass - - -UnprotectedAttributes.componentType = Attribute() -UnprotectedAttributes.subtypeSpec=constraint.ValueSizeConstraint(1, MAX) - - -class KeyEncryptionAlgorithmIdentifier(rfc5280.AlgorithmIdentifier): - pass - - -class KEKIdentifier(univ.Sequence): - pass - - -KEKIdentifier.componentType = namedtype.NamedTypes( - namedtype.NamedType('keyIdentifier', univ.OctetString()), - namedtype.OptionalNamedType('date', useful.GeneralizedTime()), - namedtype.OptionalNamedType('other', OtherKeyAttribute()) -) - - -class KEKRecipientInfo(univ.Sequence): - pass - - -KEKRecipientInfo.componentType = namedtype.NamedTypes( - namedtype.NamedType('version', CMSVersion()), - namedtype.NamedType('kekid', KEKIdentifier()), - namedtype.NamedType('keyEncryptionAlgorithm', KeyEncryptionAlgorithmIdentifier()), - namedtype.NamedType('encryptedKey', EncryptedKey()) -) - - -class KeyDerivationAlgorithmIdentifier(rfc5280.AlgorithmIdentifier): - pass - - -class PasswordRecipientInfo(univ.Sequence): - pass - - -PasswordRecipientInfo.componentType = namedtype.NamedTypes( - namedtype.NamedType('version', CMSVersion()), - namedtype.OptionalNamedType('keyDerivationAlgorithm', KeyDerivationAlgorithmIdentifier().subtype(implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 0))), - namedtype.NamedType('keyEncryptionAlgorithm', KeyEncryptionAlgorithmIdentifier()), - namedtype.NamedType('encryptedKey', EncryptedKey()) -) - - -class RecipientIdentifier(univ.Choice): - pass - - -RecipientIdentifier.componentType = namedtype.NamedTypes( - namedtype.NamedType('issuerAndSerialNumber', IssuerAndSerialNumber()), - namedtype.NamedType('subjectKeyIdentifier', SubjectKeyIdentifier().subtype(implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 0))) -) - - -class KeyTransRecipientInfo(univ.Sequence): - pass - - -KeyTransRecipientInfo.componentType = namedtype.NamedTypes( - namedtype.NamedType('version', CMSVersion()), - namedtype.NamedType('rid', RecipientIdentifier()), - namedtype.NamedType('keyEncryptionAlgorithm', KeyEncryptionAlgorithmIdentifier()), - namedtype.NamedType('encryptedKey', EncryptedKey()) -) - - -class UserKeyingMaterial(univ.OctetString): - pass - - -class OriginatorPublicKey(univ.Sequence): - pass - - -OriginatorPublicKey.componentType = namedtype.NamedTypes( - namedtype.NamedType('algorithm', rfc5280.AlgorithmIdentifier()), - namedtype.NamedType('publicKey', univ.BitString()) -) - - -class OriginatorIdentifierOrKey(univ.Choice): - pass - - -OriginatorIdentifierOrKey.componentType = namedtype.NamedTypes( - namedtype.NamedType('issuerAndSerialNumber', IssuerAndSerialNumber()), - namedtype.NamedType('subjectKeyIdentifier', SubjectKeyIdentifier().subtype(implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 0))), - namedtype.NamedType('originatorKey', OriginatorPublicKey().subtype(implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatConstructed, 1))) -) - - -class KeyAgreeRecipientInfo(univ.Sequence): - pass - - -KeyAgreeRecipientInfo.componentType = namedtype.NamedTypes( - namedtype.NamedType('version', CMSVersion()), - namedtype.NamedType('originator', OriginatorIdentifierOrKey().subtype(explicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatConstructed, 0))), - namedtype.OptionalNamedType('ukm', UserKeyingMaterial().subtype(explicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 1))), - namedtype.NamedType('keyEncryptionAlgorithm', KeyEncryptionAlgorithmIdentifier()), - namedtype.NamedType('recipientEncryptedKeys', RecipientEncryptedKeys()) -) - - -class OtherRecipientInfo(univ.Sequence): - pass - - -OtherRecipientInfo.componentType = namedtype.NamedTypes( - namedtype.NamedType('oriType', univ.ObjectIdentifier()), - namedtype.NamedType('oriValue', univ.Any()) -) - - -class RecipientInfo(univ.Choice): - pass - - -RecipientInfo.componentType = namedtype.NamedTypes( - namedtype.NamedType('ktri', KeyTransRecipientInfo()), - namedtype.NamedType('kari', KeyAgreeRecipientInfo().subtype(implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatConstructed, 1))), - namedtype.NamedType('kekri', KEKRecipientInfo().subtype(implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatConstructed, 2))), - namedtype.NamedType('pwri', PasswordRecipientInfo().subtype(implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatConstructed, 3))), - namedtype.NamedType('ori', OtherRecipientInfo().subtype(implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatConstructed, 4))) -) - - -class RecipientInfos(univ.SetOf): - pass - - -RecipientInfos.componentType = RecipientInfo() -RecipientInfos.subtypeSpec=constraint.ValueSizeConstraint(1, MAX) - - -class EnvelopedData(univ.Sequence): - pass - - -EnvelopedData.componentType = namedtype.NamedTypes( - namedtype.NamedType('version', CMSVersion()), - namedtype.OptionalNamedType('originatorInfo', OriginatorInfo().subtype(implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatConstructed, 0))), - namedtype.NamedType('recipientInfos', RecipientInfos()), - namedtype.NamedType('encryptedContentInfo', EncryptedContentInfo()), - namedtype.OptionalNamedType('unprotectedAttrs', UnprotectedAttributes().subtype(implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 1))) -) - - -class DigestAlgorithmIdentifier(rfc5280.AlgorithmIdentifier): - pass - - -id_ct_contentInfo = _OID(1, 2, 840, 113549, 1, 9, 16, 1, 6) - - -id_digestedData = _OID(1, 2, 840, 113549, 1, 7, 5) - - -class EncryptedData(univ.Sequence): - pass - - -EncryptedData.componentType = namedtype.NamedTypes( - namedtype.NamedType('version', CMSVersion()), - namedtype.NamedType('encryptedContentInfo', EncryptedContentInfo()), - namedtype.OptionalNamedType('unprotectedAttrs', UnprotectedAttributes().subtype(implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 1))) -) - - -id_messageDigest = _OID(1, 2, 840, 113549, 1, 9, 4) - - -id_signedData = _OID(1, 2, 840, 113549, 1, 7, 2) - - -class MessageAuthenticationCodeAlgorithm(rfc5280.AlgorithmIdentifier): - pass - - -class UnsignedAttributes(univ.SetOf): - pass - - -UnsignedAttributes.componentType = Attribute() -UnsignedAttributes.subtypeSpec=constraint.ValueSizeConstraint(1, MAX) - - -class SignerIdentifier(univ.Choice): - pass - - -SignerIdentifier.componentType = namedtype.NamedTypes( - namedtype.NamedType('issuerAndSerialNumber', IssuerAndSerialNumber()), - namedtype.NamedType('subjectKeyIdentifier', SubjectKeyIdentifier().subtype(implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 0))) -) - - -class SignerInfo(univ.Sequence): - pass - - -SignerInfo.componentType = namedtype.NamedTypes( - namedtype.NamedType('version', CMSVersion()), - namedtype.NamedType('sid', SignerIdentifier()), - namedtype.NamedType('digestAlgorithm', DigestAlgorithmIdentifier()), - namedtype.OptionalNamedType('signedAttrs', SignedAttributes().subtype(implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 0))), - namedtype.NamedType('signatureAlgorithm', SignatureAlgorithmIdentifier()), - namedtype.NamedType('signature', SignatureValue()), - namedtype.OptionalNamedType('unsignedAttrs', UnsignedAttributes().subtype(implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 1))) -) - - -class SignerInfos(univ.SetOf): - pass - - -SignerInfos.componentType = SignerInfo() - - -class Countersignature(SignerInfo): - pass - - -class ContentInfo(univ.Sequence): - pass - - -ContentInfo.componentType = namedtype.NamedTypes( - namedtype.NamedType('contentType', ContentType()), - namedtype.NamedType('content', univ.Any().subtype(explicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 0))) -) - - -class EncapsulatedContentInfo(univ.Sequence): - pass - - -EncapsulatedContentInfo.componentType = namedtype.NamedTypes( - namedtype.NamedType('eContentType', ContentType()), - namedtype.OptionalNamedType('eContent', univ.OctetString().subtype(explicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 0))) -) - - -id_countersignature = _OID(1, 2, 840, 113549, 1, 9, 6) - - -id_data = _OID(1, 2, 840, 113549, 1, 7, 1) - - -class MessageDigest(univ.OctetString): - pass - - -class AuthAttributes(univ.SetOf): - pass - - -AuthAttributes.componentType = Attribute() -AuthAttributes.subtypeSpec=constraint.ValueSizeConstraint(1, MAX) - - -class Time(univ.Choice): - pass - - -Time.componentType = namedtype.NamedTypes( - namedtype.NamedType('utcTime', useful.UTCTime()), - namedtype.NamedType('generalTime', useful.GeneralizedTime()) -) - - -class AuthenticatedData(univ.Sequence): - pass - - -AuthenticatedData.componentType = namedtype.NamedTypes( - namedtype.NamedType('version', CMSVersion()), - namedtype.OptionalNamedType('originatorInfo', OriginatorInfo().subtype(implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatConstructed, 0))), - namedtype.NamedType('recipientInfos', RecipientInfos()), - namedtype.NamedType('macAlgorithm', MessageAuthenticationCodeAlgorithm()), - namedtype.OptionalNamedType('digestAlgorithm', DigestAlgorithmIdentifier().subtype(implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 1))), - namedtype.NamedType('encapContentInfo', EncapsulatedContentInfo()), - namedtype.OptionalNamedType('authAttrs', AuthAttributes().subtype(implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 2))), - namedtype.NamedType('mac', MessageAuthenticationCode()), - namedtype.OptionalNamedType('unauthAttrs', UnauthAttributes().subtype(implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 3))) -) - - -id_contentType = _OID(1, 2, 840, 113549, 1, 9, 3) - - -class ExtendedCertificateOrCertificate(univ.Choice): - pass - - -ExtendedCertificateOrCertificate.componentType = namedtype.NamedTypes( - namedtype.NamedType('certificate', rfc5280.Certificate()), - namedtype.NamedType('extendedCertificate', ExtendedCertificate().subtype(implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatConstructed, 0))) -) - - -class Digest(univ.OctetString): - pass - - -class DigestedData(univ.Sequence): - pass - - -DigestedData.componentType = namedtype.NamedTypes( - namedtype.NamedType('version', CMSVersion()), - namedtype.NamedType('digestAlgorithm', DigestAlgorithmIdentifier()), - namedtype.NamedType('encapContentInfo', EncapsulatedContentInfo()), - namedtype.NamedType('digest', Digest()) -) - - -id_envelopedData = _OID(1, 2, 840, 113549, 1, 7, 3) - - -class DigestAlgorithmIdentifiers(univ.SetOf): - pass - - -DigestAlgorithmIdentifiers.componentType = DigestAlgorithmIdentifier() - - -class SignedData(univ.Sequence): - pass - - -SignedData.componentType = namedtype.NamedTypes( - namedtype.NamedType('version', CMSVersion()), - namedtype.NamedType('digestAlgorithms', DigestAlgorithmIdentifiers()), - namedtype.NamedType('encapContentInfo', EncapsulatedContentInfo()), - namedtype.OptionalNamedType('certificates', CertificateSet().subtype(implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 0))), - namedtype.OptionalNamedType('crls', RevocationInfoChoices().subtype(implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 1))), - namedtype.NamedType('signerInfos', SignerInfos()) -) - - -id_signingTime = _OID(1, 2, 840, 113549, 1, 9, 5) - - -class SigningTime(Time): - pass - - -id_ct_authData = _OID(1, 2, 840, 113549, 1, 9, 16, 1, 2) diff --git a/anchor/asn1/rfc6402.py b/anchor/asn1/rfc6402.py deleted file mode 100644 index 2c02aa2..0000000 --- a/anchor/asn1/rfc6402.py +++ /dev/null @@ -1,576 +0,0 @@ -# Auto-generated by asn1ate on 2015-12-21 15:40:08.299576 -from pyasn1.type import univ, char, namedtype, namedval, tag, constraint, useful - -from . import rfc4211 -from . import rfc5280 -from . import rfc5652 - -MAX = 64 - - -def _OID(*components): - output = [] - for x in tuple(components): - if isinstance(x, univ.ObjectIdentifier): - output.extend(list(x)) - else: - output.append(int(x)) - - return univ.ObjectIdentifier(output) - - -class ChangeSubjectName(univ.Sequence): - pass - - -ChangeSubjectName.componentType = namedtype.NamedTypes( - namedtype.OptionalNamedType('subject', rfc5280.Name()), - namedtype.OptionalNamedType('subjectAlt', rfc5280.GeneralNames()) -) - - -class AttributeValue(univ.Any): - pass - - -class CMCStatus(univ.Integer): - pass - - -CMCStatus.namedValues = namedval.NamedValues( - ('success', 0), - ('failed', 2), - ('pending', 3), - ('noSupport', 4), - ('confirmRequired', 5), - ('popRequired', 6), - ('partial', 7) -) - - -class PendInfo(univ.Sequence): - pass - - -PendInfo.componentType = namedtype.NamedTypes( - namedtype.NamedType('pendToken', univ.OctetString()), - namedtype.NamedType('pendTime', useful.GeneralizedTime()) -) - - -bodyIdMax = univ.Integer(4294967295) - - -class BodyPartID(univ.Integer): - pass - - -BodyPartID.subtypeSpec = constraint.ValueRangeConstraint(0, bodyIdMax) - - -class BodyPartPath(univ.SequenceOf): - pass - - -BodyPartPath.componentType = BodyPartID() -BodyPartPath.subtypeSpec=constraint.ValueSizeConstraint(1, MAX) - - -class BodyPartReference(univ.Choice): - pass - - -BodyPartReference.componentType = namedtype.NamedTypes( - namedtype.NamedType('bodyPartID', BodyPartID()), - namedtype.NamedType('bodyPartPath', BodyPartPath()) -) - - -class CMCFailInfo(univ.Integer): - pass - - -CMCFailInfo.namedValues = namedval.NamedValues( - ('badAlg', 0), - ('badMessageCheck', 1), - ('badRequest', 2), - ('badTime', 3), - ('badCertId', 4), - ('unsupportedExt', 5), - ('mustArchiveKeys', 6), - ('badIdentity', 7), - ('popRequired', 8), - ('popFailed', 9), - ('noKeyReuse', 10), - ('internalCAError', 11), - ('tryLater', 12), - ('authDataFail', 13) -) - - -class CMCStatusInfoV2(univ.Sequence): - pass - - -CMCStatusInfoV2.componentType = namedtype.NamedTypes( - namedtype.NamedType('cMCStatus', CMCStatus()), - namedtype.NamedType('bodyList', univ.SequenceOf(componentType=BodyPartReference())), - namedtype.OptionalNamedType('statusString', char.UTF8String()), - namedtype.OptionalNamedType('otherInfo', univ.Choice(componentType=namedtype.NamedTypes( - namedtype.NamedType('failInfo', CMCFailInfo()), - namedtype.NamedType('pendInfo', PendInfo()), - namedtype.NamedType('extendedFailInfo', univ.Sequence(componentType=namedtype.NamedTypes( - namedtype.NamedType('failInfoOID', univ.ObjectIdentifier()), - namedtype.NamedType('failInfoValue', AttributeValue()) - )) - ) - )) - ) -) - - -class GetCRL(univ.Sequence): - pass - - -GetCRL.componentType = namedtype.NamedTypes( - namedtype.NamedType('issuerName', rfc5280.Name()), - namedtype.OptionalNamedType('cRLName', rfc5280.GeneralName()), - namedtype.OptionalNamedType('time', useful.GeneralizedTime()), - namedtype.OptionalNamedType('reasons', rfc5280.ReasonFlags()) -) - - -id_pkix = _OID(1, 3, 6, 1, 5, 5, 7) - - -id_cmc = _OID(id_pkix, 7) - - -id_cmc_batchResponses = _OID(id_cmc, 29) - - -id_cmc_popLinkWitness = _OID(id_cmc, 23) - - -class PopLinkWitnessV2(univ.Sequence): - pass - - -PopLinkWitnessV2.componentType = namedtype.NamedTypes( - namedtype.NamedType('keyGenAlgorithm', rfc5280.AlgorithmIdentifier()), - namedtype.NamedType('macAlgorithm', rfc5280.AlgorithmIdentifier()), - namedtype.NamedType('witness', univ.OctetString()) -) - - -id_cmc_popLinkWitnessV2 = _OID(id_cmc, 33) - - -id_cmc_identityProofV2 = _OID(id_cmc, 34) - - -id_cmc_revokeRequest = _OID(id_cmc, 17) - - -id_cmc_recipientNonce = _OID(id_cmc, 7) - - -class ControlsProcessed(univ.Sequence): - pass - - -ControlsProcessed.componentType = namedtype.NamedTypes( - namedtype.NamedType('bodyList', univ.SequenceOf(componentType=BodyPartReference())) -) - - -class CertificationRequest(univ.Sequence): - pass - - -CertificationRequest.componentType = namedtype.NamedTypes( - namedtype.NamedType('certificationRequestInfo', univ.Sequence(componentType=namedtype.NamedTypes( - namedtype.NamedType('version', univ.Integer()), - namedtype.NamedType('subject', rfc5280.Name()), - namedtype.NamedType('subjectPublicKeyInfo', univ.Sequence(componentType=namedtype.NamedTypes( - namedtype.NamedType('algorithm', rfc5280.AlgorithmIdentifier()), - namedtype.NamedType('subjectPublicKey', univ.BitString()) - )) - ), - namedtype.NamedType('attributes', univ.SetOf(componentType=rfc5652.Attribute()).subtype(implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 0))) - )) - ), - namedtype.NamedType('signatureAlgorithm', rfc5280.AlgorithmIdentifier()), - namedtype.NamedType('signature', univ.BitString()) -) - - -class TaggedCertificationRequest(univ.Sequence): - pass - - -TaggedCertificationRequest.componentType = namedtype.NamedTypes( - namedtype.NamedType('bodyPartID', BodyPartID()), - namedtype.NamedType('certificationRequest', CertificationRequest()) -) - - -class TaggedRequest(univ.Choice): - pass - - -TaggedRequest.componentType = namedtype.NamedTypes( - namedtype.NamedType('tcr', TaggedCertificationRequest().subtype(implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatConstructed, 0))), - namedtype.NamedType('crm', rfc4211.CertReqMsg().subtype(implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatSimple, 1))), - namedtype.NamedType('orm', univ.Sequence(componentType=namedtype.NamedTypes( - namedtype.NamedType('bodyPartID', BodyPartID()), - namedtype.NamedType('requestMessageType', univ.ObjectIdentifier()), - namedtype.NamedType('requestMessageValue', univ.Any()) - )) - .subtype(implicitTag=tag.Tag(tag.tagClassContext, tag.tagFormatConstructed, 2))) -) - - -id_cmc_popLinkRandom = _OID(id_cmc, 22) - - -id_cmc_statusInfo = _OID(id_cmc, 1) - - -id_cmc_trustedAnchors = _OID(id_cmc, 26) - - -id_cmc_transactionId = _OID(id_cmc, 5) - - -id_cmc_encryptedPOP = _OID(id_cmc, 9) - - -class PublishTrustAnchors(univ.Sequence): - pass - - -PublishTrustAnchors.componentType = namedtype.NamedTypes( - namedtype.NamedType('seqNumber', univ.Integer()), - namedtype.NamedType('hashAlgorithm', rfc5280.AlgorithmIdentifier()), - namedtype.NamedType('anchorHashes', univ.SequenceOf(componentType=univ.OctetString())) -) - - -class RevokeRequest(univ.Sequence): - pass - - -RevokeRequest.componentType = namedtype.NamedTypes( - namedtype.NamedType('issuerName', rfc5280.Name()), - namedtype.NamedType('serialNumber', univ.Integer()), - namedtype.NamedType('reason', rfc5280.CRLReason()), - namedtype.OptionalNamedType('invalidityDate', useful.GeneralizedTime()), - namedtype.OptionalNamedType('passphrase', univ.OctetString()), - namedtype.OptionalNamedType('comment', char.UTF8String()) -) - - -id_cmc_senderNonce = _OID(id_cmc, 6) - - -id_cmc_authData = _OID(id_cmc, 27) - - -class TaggedContentInfo(univ.Sequence): - pass - - -TaggedContentInfo.componentType = namedtype.NamedTypes( - namedtype.NamedType('bodyPartID', BodyPartID()), - namedtype.NamedType('contentInfo', rfc5652.ContentInfo()) -) - - -class IdentifyProofV2(univ.Sequence): - pass - - -IdentifyProofV2.componentType = namedtype.NamedTypes( - namedtype.NamedType('proofAlgID', rfc5280.AlgorithmIdentifier()), - namedtype.NamedType('macAlgId', rfc5280.AlgorithmIdentifier()), - namedtype.NamedType('witness', univ.OctetString()) -) - - -class CMCPublicationInfo(univ.Sequence): - pass - - -CMCPublicationInfo.componentType = namedtype.NamedTypes( - namedtype.NamedType('hashAlg', rfc5280.AlgorithmIdentifier()), - namedtype.NamedType('certHashes', univ.SequenceOf(componentType=univ.OctetString())), - namedtype.NamedType('pubInfo', rfc4211.PKIPublicationInfo()) -) - - -id_kp_cmcCA = _OID(rfc5280.id_kp, 27) - - -id_cmc_confirmCertAcceptance = _OID(id_cmc, 24) - - -id_cmc_raIdentityWitness = _OID(id_cmc, 35) - - -id_ExtensionReq = _OID(1, 2, 840, 113549, 1, 9, 14) - - -id_cct = _OID(id_pkix, 12) - - -id_cct_PKIData = _OID(id_cct, 2) - - -id_kp_cmcRA = _OID(rfc5280.id_kp, 28) - - -class CMCStatusInfo(univ.Sequence): - pass - - -CMCStatusInfo.componentType = namedtype.NamedTypes( - namedtype.NamedType('cMCStatus', CMCStatus()), - namedtype.NamedType('bodyList', univ.SequenceOf(componentType=BodyPartID())), - namedtype.OptionalNamedType('statusString', char.UTF8String()), - namedtype.OptionalNamedType('otherInfo', univ.Choice(componentType=namedtype.NamedTypes( - namedtype.NamedType('failInfo', CMCFailInfo()), - namedtype.NamedType('pendInfo', PendInfo()) - )) - ) -) - - -class DecryptedPOP(univ.Sequence): - pass - - -DecryptedPOP.componentType = namedtype.NamedTypes( - namedtype.NamedType('bodyPartID', BodyPartID()), - namedtype.NamedType('thePOPAlgID', rfc5280.AlgorithmIdentifier()), - namedtype.NamedType('thePOP', univ.OctetString()) -) - - -id_cmc_addExtensions = _OID(id_cmc, 8) - - -id_cmc_modCertTemplate = _OID(id_cmc, 31) - - -class TaggedAttribute(univ.Sequence): - pass - - -TaggedAttribute.componentType = namedtype.NamedTypes( - namedtype.NamedType('bodyPartID', BodyPartID()), - namedtype.NamedType('attrType', univ.ObjectIdentifier()), - namedtype.NamedType('attrValues', univ.SetOf(componentType=AttributeValue())) -) - - -class OtherMsg(univ.Sequence): - pass - - -OtherMsg.componentType = namedtype.NamedTypes( - namedtype.NamedType('bodyPartID', BodyPartID()), - namedtype.NamedType('otherMsgType', univ.ObjectIdentifier()), - namedtype.NamedType('otherMsgValue', univ.Any()) -) - - -class PKIData(univ.Sequence): - pass - - -PKIData.componentType = namedtype.NamedTypes( - namedtype.NamedType('controlSequence', univ.SequenceOf(componentType=TaggedAttribute())), - namedtype.NamedType('reqSequence', univ.SequenceOf(componentType=TaggedRequest())), - namedtype.NamedType('cmsSequence', univ.SequenceOf(componentType=TaggedContentInfo())), - namedtype.NamedType('otherMsgSequence', univ.SequenceOf(componentType=OtherMsg())) -) - - -class BodyPartList(univ.SequenceOf): - pass - - -BodyPartList.componentType = BodyPartID() -BodyPartList.subtypeSpec=constraint.ValueSizeConstraint(1, MAX) - - -id_cmc_responseBody = _OID(id_cmc, 37) - - -class AuthPublish(BodyPartID): - pass - - -class CMCUnsignedData(univ.Sequence): - pass - - -CMCUnsignedData.componentType = namedtype.NamedTypes( - namedtype.NamedType('bodyPartPath', BodyPartPath()), - namedtype.NamedType('identifier', univ.ObjectIdentifier()), - namedtype.NamedType('content', univ.Any()) -) - - -class CMCCertId(rfc5652.IssuerAndSerialNumber): - pass - - -class PKIResponse(univ.Sequence): - pass - - -PKIResponse.componentType = namedtype.NamedTypes( - namedtype.NamedType('controlSequence', univ.SequenceOf(componentType=TaggedAttribute())), - namedtype.NamedType('cmsSequence', univ.SequenceOf(componentType=TaggedContentInfo())), - namedtype.NamedType('otherMsgSequence', univ.SequenceOf(componentType=OtherMsg())) -) - - -class ResponseBody(PKIResponse): - pass - - -id_cmc_statusInfoV2 = _OID(id_cmc, 25) - - -id_cmc_lraPOPWitness = _OID(id_cmc, 11) - - -class ModCertTemplate(univ.Sequence): - pass - - -ModCertTemplate.componentType = namedtype.NamedTypes( - namedtype.NamedType('pkiDataReference', BodyPartPath()), - namedtype.NamedType('certReferences', BodyPartList()), - namedtype.DefaultedNamedType('replace', univ.Boolean().subtype(value=1)), - namedtype.NamedType('certTemplate', rfc4211.CertTemplate()) -) - - -id_cmc_regInfo = _OID(id_cmc, 18) - - -id_cmc_identityProof = _OID(id_cmc, 3) - - -class ExtensionReq(univ.SequenceOf): - pass - - -ExtensionReq.componentType = rfc5280.Extension() -ExtensionReq.subtypeSpec=constraint.ValueSizeConstraint(1, MAX) - - -id_kp_cmcArchive = _OID(rfc5280.id_kp, 28) - - -id_cmc_publishCert = _OID(id_cmc, 30) - - -id_cmc_dataReturn = _OID(id_cmc, 4) - - -class LraPopWitness(univ.Sequence): - pass - - -LraPopWitness.componentType = namedtype.NamedTypes( - namedtype.NamedType('pkiDataBodyid', BodyPartID()), - namedtype.NamedType('bodyIds', univ.SequenceOf(componentType=BodyPartID())) -) - - -id_aa = _OID(1, 2, 840, 113549, 1, 9, 16, 2) - - -id_aa_cmc_unsignedData = _OID(id_aa, 34) - - -id_cmc_getCert = _OID(id_cmc, 15) - - -id_cmc_batchRequests = _OID(id_cmc, 28) - - -id_cmc_decryptedPOP = _OID(id_cmc, 10) - - -id_cmc_responseInfo = _OID(id_cmc, 19) - - -id_cmc_changeSubjectName = _OID(id_cmc, 36) - - -class GetCert(univ.Sequence): - pass - - -GetCert.componentType = namedtype.NamedTypes( - namedtype.NamedType('issuerName', rfc5280.GeneralName()), - namedtype.NamedType('serialNumber', univ.Integer()) -) - - -id_cmc_identification = _OID(id_cmc, 2) - - -id_cmc_queryPending = _OID(id_cmc, 21) - - -class AddExtensions(univ.Sequence): - pass - - -AddExtensions.componentType = namedtype.NamedTypes( - namedtype.NamedType('pkiDataReference', BodyPartID()), - namedtype.NamedType('certReferences', univ.SequenceOf(componentType=BodyPartID())), - namedtype.NamedType('extensions', univ.SequenceOf(componentType=rfc5280.Extension())) -) - - -class EncryptedPOP(univ.Sequence): - pass - - -EncryptedPOP.componentType = namedtype.NamedTypes( - namedtype.NamedType('request', TaggedRequest()), - namedtype.NamedType('cms', rfc5652.ContentInfo()), - namedtype.NamedType('thePOPAlgID', rfc5280.AlgorithmIdentifier()), - namedtype.NamedType('witnessAlgID', rfc5280.AlgorithmIdentifier()), - namedtype.NamedType('witness', univ.OctetString()) -) - - -id_cmc_getCRL = _OID(id_cmc, 16) - - -id_cct_PKIResponse = _OID(id_cct, 3) - - -id_cmc_controlProcessed = _OID(id_cmc, 32) - - -class NoSignatureValue(univ.OctetString): - pass - - -id_ad_cmc = _OID(rfc5280.id_ad, 12) - - -id_alg_noSignature = _OID(id_pkix, 6, 2) - - diff --git a/anchor/audit/__init__.py b/anchor/audit/__init__.py deleted file mode 100644 index da3117f..0000000 --- a/anchor/audit/__init__.py +++ /dev/null @@ -1,132 +0,0 @@ -# -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - -import logging -import uuid - -from anchor import jsonloader - -import oslo_config -import oslo_messaging -from pycadf import cadftaxonomy -from pycadf import event -from pycadf import identifier -from pycadf import resource - - -logger = logging.getLogger(__name__) -target = None -notifier = None - -ANCHOR_UUID_NS = uuid.UUID('0ff9c8c5-f57e-47aa-bd3d-5407eb907c74') - - -def _emit_event(event_type, payload): - if not payload.is_valid(): - logger.error("created invalid audit event: %s", payload) - return - - if notifier is not None: - notifier.info({}, event_type, payload.as_dict()) - - -def _event_defaults(result): - # eventType, id, eventTime are filled in automatically by pyCADF - return { - 'outcome': (cadftaxonomy.OUTCOME_SUCCESS if result else - cadftaxonomy.OUTCOME_FAILURE), - } - - -def _user_resource(username, result): - if result: - res_id = uuid.uuid5(ANCHOR_UUID_NS, result.username) - user = result.username - else: - if username: - res_id = uuid.uuid5(ANCHOR_UUID_NS, username.encode('utf-8', - 'replace')) - user = username - else: - # Authentication was a failure, but there was no username - # provided either. This can happen with failed token authentication - # for example. - res_id = uuid.uuid4() - user = None - return resource.Resource( - id=str(res_id), - typeURI=cadftaxonomy.ACCOUNT_USER, - name=user) - - -def _auth_resource(ra_name): - return resource.Resource( - id='anchor://authentication', - typeURI=cadftaxonomy.SERVICE_SECURITY, - domain=ra_name) - - -def _policy_resource(ra_name): - return resource.Resource( - id='anchor://certificates/policy', - typeURI=cadftaxonomy.SECURITY_POLICY, - domain=ra_name) - - -def _certificate_resource(fingerprint): - if fingerprint is None: - res_id = identifier.generate_uuid() - else: - res_id = "certificate:%s" % (fingerprint,) - return resource.Resource( - id=res_id, - typeURI=cadftaxonomy.SECURITY_KEY, - ) - - -def emit_auth_event(ra_name, username, result): - success = result is not None - params = _event_defaults(success) - params['action'] = 'authenticate' - params['initiator'] = _user_resource(username, result) - auth_res = _auth_resource(ra_name) - params['observer'] = auth_res - params['target'] = auth_res - _emit_event('audit.auth', event.Event(**params)) - - -def emit_signing_event(ra_name, username, result, fingerprint=None): - params = _event_defaults(result) - params['action'] = 'evaluate' - params['initiator'] = _user_resource(username, result) - params['observer'] = _policy_resource(ra_name) - params['target'] = _certificate_resource(fingerprint) - # add when pycadf merges event names - # params['name'] = "certificate signing" - _emit_event('audit.sign', event.Event(**params)) - - -def init_audit(): - global target - global notifier - audit_conf = jsonloader.config_for_audit() - if audit_conf is None: - return - - target = audit_conf.get('target', 'log') - cfg = oslo_config.cfg.ConfigOpts() - if target == 'messaging': - transport = oslo_messaging.get_transport(cfg, url=audit_conf['url']) - else: - transport = oslo_messaging.get_transport(cfg) - notifier = oslo_messaging.Notifier(transport, 'anchor', driver=target) diff --git a/anchor/auth/__init__.py b/anchor/auth/__init__.py deleted file mode 100644 index 5270b02..0000000 --- a/anchor/auth/__init__.py +++ /dev/null @@ -1,44 +0,0 @@ -# -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - -from __future__ import absolute_import - -import pecan - -from anchor.auth import keystone # noqa -from anchor.auth import ldap # noqa -from anchor.auth import static # noqa -from anchor import jsonloader - - -def validate(ra_name, user, secret): - """Top-level authN entry point. - - This will return an AuthDetails object or abort. This will only - check that a single auth method. That method will either succeed - or fail. - - :param ra_name: name of the registration authority - :param user: user provided user name - :param secret: user provided secret (password or token) - :return: AuthDetails if authenticated or aborts - """ - auth_conf = jsonloader.authentication_for_registration_authority(ra_name) - backend_name = auth_conf['backend'] - backend = jsonloader.conf.get_authentication(backend_name) - res = backend(ra_name, user, secret) - if res: - return res - - # we should only get here if a module failed to abort - pecan.abort(401, "authentication failure") diff --git a/anchor/auth/keystone.py b/anchor/auth/keystone.py deleted file mode 100644 index 342af0b..0000000 --- a/anchor/auth/keystone.py +++ /dev/null @@ -1,55 +0,0 @@ -# -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - -from __future__ import absolute_import - -import logging - -import requests - -from anchor.auth import results -from anchor import jsonloader - - -logger = logging.getLogger(__name__) - - -def login(_, token): - """Authenticate with the keystone endpoint from configuration file - - :param token: A Keystone Token - :returns: AuthDetails -- Class used for authentication information - """ - req = requests.get(jsonloader.conf.auth['keystone']['url'] + - '/v3/auth/tokens', - headers={'X-Auth-Token': token, - 'X-Subject-Token': token}) - if req.status_code != 200: - logger.info("Authentication failed for token <%s>, status %s", - token, req.status_code) - return None - - try: - res = req.json() - user = res['token']['user'] - user_name = user['name'] - user_id = user['id'] - project_id = res['token']['project']['id'] - - roles = [role['name'] for role in res['token']['roles']] - except Exception: - logger.exception("Keystone response was not in the expected format") - return None - - return results.AuthDetails(username=user_name, groups=roles, - user_id=user_id, project_id=project_id) diff --git a/anchor/auth/ldap.py b/anchor/auth/ldap.py deleted file mode 100644 index c70b006..0000000 --- a/anchor/auth/ldap.py +++ /dev/null @@ -1,75 +0,0 @@ -# -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - -from __future__ import absolute_import -import logging - -import ldap3 -from ldap3.core import exceptions as ldap3_exc -from ldap3.utils import dn - -from anchor.auth import results -from anchor import jsonloader - - -logger = logging.getLogger(__name__) - - -def user_get_groups(attributes): - """Retrieve the group membership - - :param attributes: LDAP attributes for user - :returns: List -- A list of groups that the user is a member of - """ - groups = attributes.get('memberOf', []) - group_dns = [dn.parse_dn(g) for g in groups] - return [x[0][1] for x in group_dns if x[1] == ('OU', 'Groups', ',')] - - -def login(ra_name, user, secret): - """Attempt to Authenitcate user using LDAP - - :param ra_name: name of registration authority - :param user: Username - :param secret: Secret/Passphrase - :returns: AuthDetails -- Class used for authentication information - """ - conf = jsonloader.authentication_for_registration_authority(ra_name) - ldap_port = int(conf.get('port', 389)) - use_ssl = conf.get('ssl', ldap_port == 636) - - lds = ldap3.Server(conf['host'], port=ldap_port, - get_info=ldap3.ALL, use_ssl=use_ssl) - - try: - ldap_user = "%s@%s" % (user, conf['domain']) - ldc = ldap3.Connection(lds, auto_bind=True, client_strategy=ldap3.SYNC, - user=ldap_user, password=secret, - authentication=ldap3.SIMPLE, check_names=True) - - filter_str = ('(sAMAccountName=%s)' % - ldap3.utils.conv.escape_bytes(user)) - ldc.search(conf['base'], filter_str, - ldap3.SUBTREE, attributes=['memberOf']) - if ldc.result['result'] != 0: - return None - user_attrs = ldc.response[0]['attributes'] - user_groups = user_get_groups(user_attrs) - return results.AuthDetails(username=user, groups=user_groups) - except ldap3_exc.LDAPSocketOpenError: - logger.error("cannot connect to LDAP host '%s' (authority '%s')", - conf['host'], ra_name) - return None - except ldap3_exc.LDAPBindError: - logger.info("failed ldap auth for user %s", user) - return None diff --git a/anchor/auth/results.py b/anchor/auth/results.py deleted file mode 100644 index cf0bcbc..0000000 --- a/anchor/auth/results.py +++ /dev/null @@ -1,32 +0,0 @@ -# -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - -from __future__ import absolute_import - - -class AuthDetails(object): - def __init__(self, username=None, groups=None, user_id=None, - project_id=None): - self.username = username - self.groups = groups or [] - self.user_id = user_id - self.project_id = project_id - - def __eq__(self, other): - return (self.username == other.username and - self.groups == other.groups and - self.user_id == other.user_id and - self.project_id == other.project_id) - - def __ne__(self, other): - return not self.__eq__(other) diff --git a/anchor/auth/static.py b/anchor/auth/static.py deleted file mode 100644 index 7439475..0000000 --- a/anchor/auth/static.py +++ /dev/null @@ -1,69 +0,0 @@ -# -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - -from __future__ import absolute_import - -import logging - -from anchor.auth import results -from anchor import jsonloader - -from oslo_utils import secretutils as util - -logger = logging.getLogger(__name__) - - -def login(ra_name, user, secret): - """Validates a user supplied user/password against an expected value. - - The expected value is pulled from the pecan config. Note that this - value is currently stored in the clear inside that config, so we - are assuming that the config is protected using file perms, etc. - - This function provides some resistance to timing attacks, but - information on the expected user/password lengths can still be - leaked. It may also be possible to use a timing attack to see - which input failed validation. See comments below for details. - - :param ra_name: name of the registration authority - :param user: The user supplied username (unicode or string) - :param secret: The user supplied password (unicode or string) - :return: None on failure or an AuthDetails object on success - """ - auth_conf = jsonloader.authentication_for_registration_authority(ra_name) - - # convert input to strings - user = str(user) - secret = str(secret) - - # expected values - try: - expected_user = str(auth_conf['user']) - expected_secret = str(auth_conf['secret']) - except (KeyError, TypeError): - logger.warning("auth conf missing static user or secret") - return None - - # This technique is used to provide a constant time string compare - # between the user input and the expected values. - valid_user = util.constant_time_compare(user, expected_user) - valid_secret = util.constant_time_compare(secret, expected_secret) - - # This if statement results in a potential timing attack where the - # statement could return more quickly if valid_secret=False. We - # do not see an obvious solution to this problem, but also believe - # that leaking which input was valid isn't as big of a concern. - if valid_user and valid_secret: - return results.AuthDetails(username=expected_user, groups=[]) - - logger.info("failed static auth for user {}".format(user)) diff --git a/anchor/certificate_ops.py b/anchor/certificate_ops.py deleted file mode 100644 index 2814512..0000000 --- a/anchor/certificate_ops.py +++ /dev/null @@ -1,201 +0,0 @@ -# -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - -from __future__ import absolute_import - -import logging -import os - -import pecan -from webob import exc as http_status - -from anchor import cmc -from anchor import jsonloader -from anchor import util -from anchor import validation -from anchor.X509 import certificate -from anchor.X509 import signing_request - - -logger = logging.getLogger(__name__) - - -# we only support the PEM encoding for now, but this may grow -# to support things like DER in the future -VALID_ENCODINGS = ['pem'] - - -def parse_csr(data, encoding): - """Loads the user provided CSR into the backend X509 library. - - :param data: CSR as provided by the API user - :param encoding: encoding for the CSR (must be PEM today) - :return: CSR object from backend X509 library or aborts - """ - # validate untrusted input - if str(encoding).lower() not in VALID_ENCODINGS: - logger.error("parse_csr failed: bad encoding ({})".format(encoding)) - pecan.abort(400, "invalid CSR") - - if data is None: - logger.error("parse_csr failed: missing CSR") - pecan.abort(400, "invalid CSR") - - # get DER version - der = util.extract_pem(data.encode('ascii')) - if der is None: - logger.error("parse_csr failed: PEM contents not found") - pecan.abort(400, "PEM contents not found") - - # try to unpack the certificate from CMC wrappers - try: - csr = cmc.parse_request(der) - return signing_request.X509Csr(csr) - except cmc.CMCParsingError: - # it's not CMC data, that's fine, it's likely the CSR itself - try: - return signing_request.X509Csr.from_buffer(der, 'der') - except Exception as e: - logger.exception("Exception while parsing the CSR: %s", e) - pecan.abort(400, "CSR cannot be parsed") - - -def validate_csr(ra_name, auth_result, csr, request): - """Validates various aspects of the CSR based on the loaded config. - - The arguments of this method are passed to the underlying validate - methods. Therefore, some may be optional, depending on which - validation routines are specified in the configuration. - - :param ra_name: name of the registration authority - :param auth_result: AuthDetails value from auth.validate - :param csr: CSR value from certificate_ops.parse_csr - :param request: pecan request object associated with this action - """ - try: - valid = validation.validate_csr(ra_name, auth_result, csr, request) - except Exception as e: - logger.exception("Error running validators: %s", e) - pecan.abort(500, "Internal Validation Error") - - if not all(list(valid.values())): - pecan.abort(400, "CSR failed validation") - - -def certificate_fingerprint(cert_pem, hash_name): - """Get certificate fingerprint.""" - cert = certificate.X509Certificate.from_buffer(cert_pem) - return cert.get_fingerprint(hash_name) - - -def get_ca(ra_name): - ca_conf = jsonloader.signing_ca_for_registration_authority(ra_name) - - ca_path = ca_conf.get('cert_path') - if not ca_path: - pecan.abort(404, "CA certificate not available") - - try: - with open(ca_path) as f: - return f.read() - except IOError: - pecan.abort(500, "CA certificate not available") - - -def dispatch_sign(ra_name, csr): - """Dispatch the sign call to the configured backend. - - :param csr: X509 certificate signing request - :return: signed certificate in PEM format - """ - ca_conf = jsonloader.signing_ca_for_registration_authority(ra_name) - backend_name = ca_conf.get('backend', 'anchor') - sign_func = jsonloader.conf.get_signing_backend(backend_name) - try: - cert_pem = sign_func(csr, ca_conf) - except http_status.HTTPException: - logger.exception("Failed to sign certificate") - raise - except Exception: - logger.exception("Failed to sign the certificate") - pecan.abort(500, "certificate signing error") - - fingerprint = certificate_fingerprint(cert_pem, 'sha256') - if ca_conf.get('output_path') is not None: - path = os.path.join( - ca_conf['output_path'], - '%s.crt' % fingerprint) - - logger.info("Saving certificate to: %s", path) - - with open(path, "w") as f: - f.write(cert_pem) - - return cert_pem, fingerprint - - -def _run_fixup(name, body, args): - """Parse the fixup tuple, call the fixup, and return the new csr. - - :param name: the fixup name - :param body: fixup body, directly from config - :param args: additional arguments to pass to the fixup function - :return: the fixed csr - """ - # careful to not modify the master copy of args with local params - new_kwargs = args.copy() - new_kwargs.update(body) - - # perform the actual check - logger.debug("_run_fixup: fixup <%s> with arguments: %s", name, body) - try: - fixup = jsonloader.conf.get_fixup(name) - new_csr = fixup(**new_kwargs) - logger.debug("_run_fixup: success: <%s> ", name) - return new_csr - except Exception: - logger.exception("_run_fixup: failed: <%s>", name) - return None - - -def fixup_csr(ra_name, csr, request): - """Apply configured changes to the certificate. - - :param ra_name: registration authority name - :param csr: X509 certificate signing request - :param request: pecan request - """ - ra_conf = jsonloader.config_for_registration_authority(ra_name) - args = {'csr': csr, - 'conf': ra_conf, - 'request': request} - - fixups = ra_conf.get('fixups', {}) - try: - for fixup_name, fixup in fixups.items(): - new_csr = _run_fixup(fixup_name, fixup, args) - if new_csr is None: - pecan.abort(500, "Could not finish all required modifications") - if not isinstance(new_csr, signing_request.X509Csr): - logger.error("Fixup %s returned incorrect object", fixup_name) - pecan.abort(500, "Could not finish all required modifications") - args['csr'] = new_csr - - except http_status.HTTPInternalServerError: - raise - - except Exception: - logger.exception("Failed to execute fixups") - pecan.abort(500, "Could not finish all required modifications") - - return args['csr'] diff --git a/anchor/cmc.py b/anchor/cmc.py deleted file mode 100644 index 404a072..0000000 --- a/anchor/cmc.py +++ /dev/null @@ -1,80 +0,0 @@ -from anchor.asn1 import rfc5652 -from anchor.asn1 import rfc6402 - -from pyasn1.codec.der import decoder -from pyasn1 import error - - -class CMCParsingError(Exception): - pass - - -class UnexpectedContentType(CMCParsingError): - def __init__(self, content_type): - self.content_type = content_type - - def __str__(self): - return "Unexpected content type, got %s" % self.content_type - - -def _unwrap_signed_data(data): - # Since we don't have trust with anyone signing the requests, this - # signature is not relevant. The request itself is self-signed which - # stops accidents. - result = decoder.decode(data, rfc5652.SignedData())[0] - return _unwrap_generic( - result['encapContentInfo']['eContentType'], - result['encapContentInfo']['eContent']) - - -def _unwrap_content_info(data): - result = decoder.decode(data, rfc5652.ContentInfo())[0] - return _unwrap_generic(result['contentType'], result['content']) - - -def _unwrap_generic(content_type, data): - unwrapper = CONTENT_TYPES.get(content_type) - if unwrapper is None: - return (content_type, data) - return unwrapper(data) - - -def strip_wrappers(data): - # assume the outer wrapper is contentinfo - return _unwrap_content_info(data) - - -CONTENT_TYPES = { - rfc5652.id_ct_contentInfo: _unwrap_content_info, - rfc5652.id_signedData: _unwrap_signed_data, -} - - -def parse_request(data): - try: - content_type, data = strip_wrappers(data) - except error.PyAsn1Error: - raise CMCParsingError("Cannot find valid CMC wrapper") - - if content_type != rfc6402.id_cct_PKIData: - raise UnexpectedContentType(content_type) - - pd = decoder.decode(data, rfc6402.PKIData())[0] - if len(pd['reqSequence']) == 0: - raise CMCParsingError("No certificate requests") - if len(pd['reqSequence']) > 1: - raise CMCParsingError("Can't handle multiple certificates") - req = pd['reqSequence'][0] - - if req.getName() != 'tcr': - raise CMCParsingError("Can handle only tagged cert requests") - - return req['tcr']['certificationRequest'] - - -if __name__ == "__main__": - import sys - with open(sys.argv[1], 'rb') as f: - data = f.read() - cert_req = parse_request(data) - print(cert_req.prettyPrint()) diff --git a/anchor/config.py b/anchor/config.py deleted file mode 100644 index e0dad12..0000000 --- a/anchor/config.py +++ /dev/null @@ -1,48 +0,0 @@ -server = { - 'port': '5016', - 'host': '0.0.0.0' # nosec -} - -# Pecan Application Configurations -app = { - 'root': 'anchor.controllers.RootController', - 'modules': ['anchor'], - # 'static_root': '%(confdir)s/public', - # 'template_path': '%(confdir)s/${package}/templates', - 'debug': True, - 'errors': { - '404': '/error/404', - '__force_dict__': True - }, -} - -logging = { - "formatters": { - "simple": { - "format": ("%(asctime)s %(levelname)-5.5s [%(name)s][%(process)d/" - "%(threadName)s] %(message)s") - }, - }, - "handlers": { - "console": { - "class": "logging.StreamHandler", - "formatter": "simple", - "level": "DEBUG" - }, - }, - "loggers": { - "anchor": { - "level": "DEBUG" - }, - "wsgi": { - "level": "INFO" - }, - "oslo_messaging": { - "level": "DEBUG" - }, - }, - "root": { - "handlers": ["console"], - "level": "INFO" - }, -} diff --git a/anchor/controllers/__init__.py b/anchor/controllers/__init__.py deleted file mode 100644 index a216b09..0000000 --- a/anchor/controllers/__init__.py +++ /dev/null @@ -1,106 +0,0 @@ -# -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - -import logging - -import pecan -from pecan import rest -from webob import exc as http_status - -from anchor import audit -from anchor import auth -from anchor import certificate_ops -from anchor import jsonloader - - -logger = logging.getLogger(__name__) - - -class RobotsController(rest.RestController): - """Serves /robots.txt that disallows search bots.""" - - @pecan.expose(content_type="text/plain") - def get(self): - return "User-agent: *\nDisallow: /\n" - - -class GenericInstanceController(rest.RestController): - """Handles requests to /xxx/ra_name.""" - def __init__(self, ra_name): - self.ra_name = ra_name - - -class SignInstanceController(GenericInstanceController): - """Handles POST requests to /sign/instance.""" - @pecan.expose(content_type="text/plain") - def post(self): - ra_name = self.ra_name - - logger.debug("processing signing request in registration authority %s", - ra_name) - try: - auth_result = auth.validate(ra_name, - pecan.request.POST.get('user'), - pecan.request.POST.get('secret')) - audit.emit_auth_event(ra_name, pecan.request.POST.get('user'), - auth_result) - except http_status.HTTPUnauthorized: - audit.emit_auth_event(ra_name, pecan.request.POST.get('user'), - None) - raise - - try: - csr = certificate_ops.parse_csr(pecan.request.POST.get('csr'), - pecan.request.POST.get('encoding')) - certificate_ops.validate_csr(ra_name, auth_result, csr, - pecan.request) - csr = certificate_ops.fixup_csr(ra_name, csr, pecan.request) - - cert, fingerprint = certificate_ops.dispatch_sign(ra_name, csr) - audit.emit_signing_event(ra_name, pecan.request.POST.get('user'), - auth_result, fingerprint=fingerprint) - except Exception: - audit.emit_signing_event(ra_name, pecan.request.POST.get('user'), - auth_result) - raise - return cert - - -class CAInstanceController(GenericInstanceController): - """Handles POST requests to /ca/ra_name.""" - @pecan.expose(content_type="text/plain") - def get(self): - ra_name = self.ra_name - - return certificate_ops.get_ca(ra_name) - - -class RAController(rest.RestController): - def __init__(self, subcontroller): - self._subcontroller = subcontroller - - @pecan.expose() - def _lookup(self, ra_name, *remaining): - if ra_name in jsonloader.registration_authority_names(): - return self._subcontroller(ra_name), remaining - pecan.abort(404) - - -class V1Controller(rest.RestController): - sign = RAController(SignInstanceController) - ca = RAController(CAInstanceController) - - -class RootController(object): - robots = RobotsController() - v1 = V1Controller() diff --git a/anchor/errors.py b/anchor/errors.py deleted file mode 100644 index 57f94d9..0000000 --- a/anchor/errors.py +++ /dev/null @@ -1,2 +0,0 @@ -class ConfigValidationException(Exception): - pass diff --git a/anchor/fixups.py b/anchor/fixups.py deleted file mode 100644 index 3dd0969..0000000 --- a/anchor/fixups.py +++ /dev/null @@ -1,44 +0,0 @@ -# -*- coding:utf-8 -*- -# -# Copyright 2015 Hewlett-Packard Development Company, L.P. -# -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - -import netaddr - -from anchor.X509 import extension - - -def enforce_alternative_names_present(csr=None, **kwargs): - """Make sure that if CN is set, it's also present in SAN extension.""" - sans = csr.get_extensions(extension.X509ExtensionSubjectAltName) - if sans: - san = sans[0] - else: - san = extension.X509ExtensionSubjectAltName() - - san_updated = False - for cn in csr.get_subject_cn(): - try: - ip = netaddr.IPAddress(cn) - if ip not in san.get_ips(): - san.add_ip(ip) - san_updated = True - except netaddr.AddrFormatError: - if cn not in san.get_dns_ids(): - san.add_dns_id(cn) - san_updated = True - - if san_updated: - csr.add_extension(san) - return csr diff --git a/anchor/jsonloader.py b/anchor/jsonloader.py deleted file mode 100644 index 1ca594a..0000000 --- a/anchor/jsonloader.py +++ /dev/null @@ -1,135 +0,0 @@ -# -*- coding:utf-8 -*- -# -# Copyright 2014 Hewlett-Packard Development Company, L.P. -# -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - -from __future__ import absolute_import - -import json -import logging - -import stevedore - -logger = logging.getLogger(__name__) - - -class AnchorConf(): - - def __init__(self, logger): - '''Attempt to initialize a config dictionary from a JSON file. - - Error out if loading the yaml file fails for any reason. - :param logger: Logger to be used in the case of errors - :param config_file: The Anchor JSON config file - :return: - - ''' - - self._logger = logger - self._config = {} - - def _load_json_file(self, config_file): - try: - with open(config_file, 'r') as f: - return json.load(f) - except IOError: - logger.error("could not open config file: %s" % config_file) - raise - except ValueError: - logger.error("error parsing config file: %s" % config_file) - raise - - def load_file_data(self, config_file): - '''Load a config from a file.''' - self._config = self._load_json_file(config_file) - - def load_str_data(self, data): - '''Load a config from string data.''' - self._config = json.loads(data) - - def load_extensions(self): - self._signing_backends = stevedore.ExtensionManager( - "anchor.signing_backends") - self._validators = stevedore.ExtensionManager("anchor.validators") - self._authentication = stevedore.ExtensionManager( - "anchor.authentication") - self._fixups = stevedore.ExtensionManager("anchor.fixups") - - def get_signing_backend(self, name): - return self._signing_backends[name].plugin - - def get_validator(self, name): - return self._validators[name].plugin - - def get_authentication(self, name): - return self._authentication[name].plugin - - def get_fixup(self, name): - return self._fixups[name].plugin - - @property - def config(self): - '''Property to return the config dictionary - - :return: Config dictionary - ''' - return self._config - - def __getattr__(self, name): - try: - return self._config[name] - except KeyError: - raise AttributeError("'AnchorConf' object has no attribute '%s'" % - name) - - -conf = AnchorConf(logger) - - -def config_for_audit(): - """Get configuration for a given name.""" - try: - return conf.audit - except AttributeError: - # it's ok not to configure audit - return None - - -def config_for_registration_authority(ra_name): - """Get configuration for a given name.""" - return conf.registration_authority[ra_name] - - -def authentication_for_registration_authority(ra_name): - """Get authentication config for a given name. - - This is only supposed to be called after config validation. All the right - elements are expected to be in place. - """ - auth_name = conf.registration_authority[ra_name]['authentication'] - return conf.authentication[auth_name] - - -def signing_ca_for_registration_authority(ra_name): - """Get signing ca config for a given name. - - This is only supposed to be called after config validation. All the right - elements are expected to be in place. - """ - ca_name = conf.registration_authority[ra_name]['signing_ca'] - return conf.signing_ca[ca_name] - - -def registration_authority_names(): - """List the names of supported registration authorities.""" - return conf.registration_authority.keys() diff --git a/anchor/signers/__init__.py b/anchor/signers/__init__.py deleted file mode 100644 index 450896c..0000000 --- a/anchor/signers/__init__.py +++ /dev/null @@ -1,91 +0,0 @@ -import logging -import time -import uuid - -from anchor.X509 import certificate -from anchor.X509 import extension - - -logger = logging.getLogger(__name__) - - -def config_validator(val): - def patcher(f): - setattr(f, "_config_validator", val) - return f - return patcher - - -class SigningError(Exception): - pass - - -def sign_generic(csr, ca_conf, encryption, signer): - """Generate an X.509 certificate and sign it. - - :param csr: X509 certificate signing request - :param ca_conf: signing CA configuration - :return: signed certificate in PEM format - """ - try: - ca = certificate.X509Certificate.from_file( - ca_conf['cert_path']) - except Exception as e: - raise SigningError("Cannot load the signing CA: %s" % (e,)) - - new_cert = certificate.X509Certificate() - new_cert.set_version(2) - - start_time = int(time.time()) - end_time = start_time + (ca_conf['valid_hours'] * 60 * 60) - new_cert.set_not_before(start_time) - new_cert.set_not_after(end_time) - - new_cert.set_pubkey(pkey=csr.get_pubkey()) - new_cert.set_subject(csr.get_subject()) - new_cert.set_issuer(ca.get_subject()) - - serial = int(uuid.uuid4().hex, 16) - new_cert.set_serial_number(serial) - - exts = csr.get_extensions() - - ext_i = 0 - for ext in exts: - # this check is separate from standards validator - the signing backend - # may know about more/fewer extensions than we do - if ext.get_oid() not in extension.EXTENSION_CLASSES.keys(): - if ext.get_critical(): - logger.warning("CSR submitted with unknown extension oid %s, " - "refusing to sign", ext.get_oid()) - raise SigningError("Unknown critical extension %s" % ( - ext.get_oid(),)) - else: - logger.info("CSR submitted with non-critical unknown oid %s, " - "not including extension", (ext.get_oid(),)) - else: - logger.info("Adding certificate extension: %i %s", ext_i, str(ext)) - # authority id will be replaced with current signer - # this cannot be a fixup, because they don't get access to the CA - if isinstance(ext, extension.X509ExtensionAuthorityKeyId): - continue - - new_cert.add_extension(ext, ext_i) - ext_i += 1 - - ca_exts = ca.get_extensions(extension.X509ExtensionSubjectKeyId) - auth_key_id = extension.X509ExtensionAuthorityKeyId() - if ca_exts: - auth_key_id.set_key_id(ca_exts[0].get_key_id()) - else: - auth_key_id.set_key_id(ca.get_key_id()) - new_cert.add_extension(auth_key_id, ext_i) - - logger.info("Signing certificate for <%s> with serial <%s>", - csr.get_subject(), serial) - - new_cert.sign(encryption, ca_conf['signing_hash'], signer) - - cert_pem = new_cert.as_pem() - - return cert_pem diff --git a/anchor/signers/cryptography_io.py b/anchor/signers/cryptography_io.py deleted file mode 100644 index 5ce0978..0000000 --- a/anchor/signers/cryptography_io.py +++ /dev/null @@ -1,74 +0,0 @@ -from cryptography.hazmat.primitives.asymmetric import dsa -from cryptography.hazmat.primitives.asymmetric import padding -from cryptography.hazmat.primitives.asymmetric import rsa -from cryptography.hazmat.primitives import hashes - -from anchor import errors -from anchor import signers -from anchor import util -from anchor.X509 import utils as x509_utils - - -SIGNER_CONSTRUCTION = { - ('RSA', 'SHA224'): (lambda key: key.signer(padding.PKCS1v15(), - hashes.SHA224())), - ('RSA', 'SHA256'): (lambda key: key.signer(padding.PKCS1v15(), - hashes.SHA256())), - ('RSA', 'SHA384'): (lambda key: key.signer(padding.PKCS1v15(), - hashes.SHA384())), - ('RSA', 'SHA512'): (lambda key: key.signer(padding.PKCS1v15(), - hashes.SHA512())), - ('DSA', 'SHA224'): (lambda key: key.signer(hashes.SHA224())), - ('DSA', 'SHA256'): (lambda key: key.signer(hashes.SHA256())), -} - - -def conf_validator(name, ca_conf): - # mandatory CA settings - ca_config_requirements = ["cert_path", "key_path", "output_path", - "signing_hash", "valid_hours"] - - for requirement in ca_config_requirements: - if requirement not in ca_conf.keys(): - raise errors.ConfigValidationException( - "CA config missing: %s (for signing CA %s)" % (requirement, - name)) - - # all are specified, check the CA certificate and key are readable with - # sane permissions - util.check_file_exists(ca_conf['cert_path']) - util.check_file_exists(ca_conf['key_path']) - - util.check_file_permissions(ca_conf['key_path']) - - -def make_signer(key, encryption, md): - signer = SIGNER_CONSTRUCTION.get((encryption, md.upper())) - if signer is None: - raise signers.SigningError( - "Unknown hash/encryption combination (%s/%s)" % (md, encryption)) - signer = signer(key) - - def cryptography_io_signer(to_sign): - signer.update(to_sign) - return signer.finalize() - - return cryptography_io_signer - - -@signers.config_validator(conf_validator) -def sign(csr, ca_conf): - try: - key = x509_utils.get_private_key_from_file(ca_conf['key_path']) - except Exception as e: - raise signers.SigningError("Cannot load the signing CA key: %s" % (e,)) - - if isinstance(key, rsa.RSAPrivateKey): - encryption = 'RSA' - elif isinstance(key, dsa.DSAPrivateKey): - encryption = 'DSA' - else: - raise signers.SigningError("Unknown key type: %s" % (key.__class__,)) - - signer = make_signer(key, encryption, ca_conf['signing_hash']) - return signers.sign_generic(csr, ca_conf, encryption, signer) diff --git a/anchor/signers/pkcs11.py b/anchor/signers/pkcs11.py deleted file mode 100644 index a971f60..0000000 --- a/anchor/signers/pkcs11.py +++ /dev/null @@ -1,120 +0,0 @@ -from cryptography.hazmat import backends as cio_backends -from cryptography.hazmat.primitives import hashes -from pyasn1.codec.der import encoder -from pyasn1.type import univ as asn1_univ -from pyasn1_modules import rfc2315 - -from anchor import errors -from anchor import signers -from anchor import util - - -def import_pkcs(): - # separate function for mocking the import failure - return __import__("PyKCS11") - - -def conf_validator(name, ca_conf): - # mandatory CA settings - ca_config_requirements = ["cert_path", "output_path", "signing_hash", - "valid_hours", "slot", "pin", "key_id", - "pkcs11_path"] - - for requirement in ca_config_requirements: - if requirement not in ca_conf.keys(): - raise errors.ConfigValidationException( - "CA config missing: %s (for signing CA %s)" % (requirement, - name)) - - # all are specified, check the CA certificate and key are readable with - # sane permissions - util.check_file_exists(ca_conf['cert_path']) - util.check_file_exists(ca_conf['pkcs11_path']) - - # PyKCS11 is an optional dependency - try: - PyKCS11 = import_pkcs() - except ImportError: - raise errors.ConfigValidationException( - "PyKCS11 library cannot be imported") - - # library at the selected path should be possible to load - try: - pkcslib = PyKCS11.PyKCS11Lib() - pkcslib.load(ca_conf['pkcs11_path']) - except PyKCS11.PyKCS11Error: - raise errors.ConfigValidationException( - "Selected pkcs11 library failed to load") - - slot = ca_conf['slot'] - slots = pkcslib.getSlotList() - if slot not in slots: - raise errors.ConfigValidationException( - "Slot %s cannot be found in the pkcs11 store" % slot) - - try: - session = pkcslib.openSession(slot) - session.login(ca_conf['pin']) - except PyKCS11.PyKCS11Error: - raise errors.ConfigValidationException( - "Cannot login to the selected slot") - - -def make_signer(key_id, slot, pin, pkcs11_path, md): - HASH_OIDS = { - 'SHA256': asn1_univ.ObjectIdentifier('2.16.840.1.101.3.4.2.1'), - 'SHA384': asn1_univ.ObjectIdentifier('2.16.840.1.101.3.4.2.2'), - 'SHA512': asn1_univ.ObjectIdentifier('2.16.840.1.101.3.4.2.3'), - 'SHA224': asn1_univ.ObjectIdentifier('2.16.840.1.101.3.4.2.4'), - } - - PyKCS11 = import_pkcs() - try: - pkcslib = PyKCS11.PyKCS11Lib() - pkcslib.load(pkcs11_path) - session = pkcslib.openSession(slot) - session.login(pin) - except PyKCS11.PyKCS11Error: - raise signers.SigningError("Could not setup the pkcs11 session") - - keys = session.findObjects(( - (PyKCS11.CKA_CLASS, PyKCS11.CKO_PRIVATE_KEY), - (PyKCS11.CKA_KEY_TYPE, PyKCS11.CKK_RSA), - (PyKCS11.CKA_SIGN, True), - (PyKCS11.CKA_ID, key_id), - )) - if not keys: - raise signers.SigningError("Cannot find the requested key") - key = keys[0] - cio_hash = getattr(hashes, md, None) - if not cio_hash: - raise signers.SigningError("Requested hash is not supported") - - h = hashes.Hash(cio_hash(), cio_backends.default_backend()) - - def pkcs11_signer(to_sign): - pkcslib.getInfo # just to keep pkcslib in scope, it's a NOOP - h.update(to_sign) - di = rfc2315.DigestInfo() - di['digestAlgorithm'] = None - di['digestAlgorithm'][0] = HASH_OIDS[md] - di['digest'] = h.finalize() - signature = bytes(session.sign(key, encoder.encode(di), - PyKCS11.MechanismRSAPKCS1)) - session.logout() - return signature - - return pkcs11_signer - - -@signers.config_validator(conf_validator) -def sign(csr, ca_conf): - slot = ca_conf['slot'] - pin = ca_conf['pin'] - pkcs11_path = ca_conf['pkcs11_path'] - key_id = [int(ca_conf['key_id'][i:i+2], 16) for - i in range(0, len(ca_conf['key_id']), 2)] - signing_hash = ca_conf['signing_hash'].upper() - - signer = make_signer(key_id, slot, pin, pkcs11_path, signing_hash) - return signers.sign_generic(csr, ca_conf, 'RSA', signer) diff --git a/anchor/util.py b/anchor/util.py deleted file mode 100644 index 437bf46..0000000 --- a/anchor/util.py +++ /dev/null @@ -1,86 +0,0 @@ -# -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - -from __future__ import absolute_import - -import base64 -import os -import stat - -from anchor import errors - - -def verify_domain(domain, label_re_comp, allow_wildcards=False): - labels = domain.split('.') - if labels[-1] == "": - # single trailing . is ok, ignore - labels.pop(-1) - - for i, label in enumerate(labels): - if len(label) > 63: - raise ValueError( - "domain <%s> it too long (RFC5280/4.2.1.6)" % (domain,)) - - # check for wildcard labels, ignore partial-wildcard labels - if '*' == label and allow_wildcards: - if i != 0: - raise ValueError( - "domain <%s> has wildcard that's not in the " - "left-most label (RFC6125/6.4.3)" % (domain,)) - else: - if label_re_comp.match(label) is None: - raise ValueError( - "domain <%s> contains invalid characters " - "(RFC1034/3.5)" % (domain,)) - - -def extract_pem(data, use_markers=True): - """Extract and unpack PEM data - - Anything between the BEGIN and END lines will be unpacked using base64. The - specific BEGIN/END content name is ignored since it's not standard anyway. - """ - if not isinstance(data, bytes): - raise TypeError("data must be bytes") - lines = data.splitlines() - seen_start = not use_markers - b64_content = b"" - for line in lines: - if line.startswith(b"-----END ") and line.endswith(b"-----"): - break - if seen_start: - b64_content += line - if line.startswith(b"-----BEGIN ") and line.endswith(b"-----"): - seen_start = True - - if not b64_content: - return None - decoder = getattr(base64, 'decodebytes', base64.decodestring) - return decoder(b64_content) - - -def check_file_permissions(path): - # checks that file is owner readable only - expected_permissions = (stat.S_IRUSR | stat.S_IFREG) # 0o100400 - st = os.stat(path) - if st.st_mode != expected_permissions: - raise errors.ConfigValidationException("CA file: %s has incorrect " - "permissions set, expected " - "owner readable only" % path) - - -def check_file_exists(path): - if not (os.path.isfile(path) and - os.access(path, os.R_OK)): - raise errors.ConfigValidationException("could not read file: %s" % - path) diff --git a/anchor/validation.py b/anchor/validation.py deleted file mode 100644 index 62f8410..0000000 --- a/anchor/validation.py +++ /dev/null @@ -1,84 +0,0 @@ -# -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - -from __future__ import absolute_import - -import logging - -from anchor import jsonloader -from anchor.validators import errors -from anchor.validators import internal - -logger = logging.getLogger(__name__) - -# some validators will be always active because they enforce Anchor design -# ideas rather than user configuration -ENFORCED_VALIDATORS = [ - internal.ca_status - ] - - -def _run_validator(name, validator, body, args): - """Parse the validator tuple, call the validator, and return result. - - :param name: the validator name - :param validator: the validator callable - :param body: validator body, directly from config - :param args: additional arguments to pass to the validator function - :return: True on success, else False - """ - # careful to not modify the master copy of args with local params - new_kwargs = args.copy() - new_kwargs.update(body) - - # perform the actual check - logger.debug("_run_validator: checking <%s> with rules: %s", name, body) - try: - validator(**new_kwargs) - logger.debug("_run_validator: success: <%s> ", name) - return True # validator passed b/c no exceptions - except errors.ValidationError as e: - logger.exception("_run_validator: FAILED: <%s> - %s", name, e) - return False - - -def validate_csr(ra_name, auth_result, csr, request): - """Validates various aspects of the CSR based on the loaded config. - - The arguments of this method are passed to the underlying validate - methods. Therefore, some may be optional, depending on which - validation routines are specified in the configuration. - - :param ra_name: name of the registration authority - :param auth_result: AuthDetails value from auth.validate - :param csr: CSR value from certificate_ops.parse_csr - :param request: pecan request object associated with this action - """ - - ra_conf = jsonloader.config_for_registration_authority(ra_name) - args = {'auth_result': auth_result, - 'csr': csr, - 'conf': ra_conf, - 'request': request} - - # It is ok if the config doesn't have any validators listed - valid = {} - for validator in ENFORCED_VALIDATORS: - vname = validator.__name__ - valid[vname] = _run_validator(vname, validator, {}, args) - - for vname, options in ra_conf['validators'].items(): - validator = jsonloader.conf.get_validator(vname) - valid[vname] = _run_validator(vname, validator, options, args) - - return valid diff --git a/anchor/validators/__init__.py b/anchor/validators/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/anchor/validators/custom.py b/anchor/validators/custom.py deleted file mode 100644 index fc7be8b..0000000 --- a/anchor/validators/custom.py +++ /dev/null @@ -1,313 +0,0 @@ -# -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - -from __future__ import absolute_import - -import logging - -import netaddr -from pyasn1.type import univ as pyasn1_univ -from pyasn1_modules import rfc2437 # PKCS#1 -from pyasn1_modules import rfc2459 - -from anchor.validators import errors as v_errors -from anchor.validators import utils -from anchor.X509 import extension -from anchor.X509 import name as x509_name - - -logger = logging.getLogger(__name__) - - -def common_name(csr, allowed_domains=[], allowed_networks=[], **kwargs): - """Check the CN entry is a known domain. - - Refuse requests for certificates if they contain multiple CN - entries, or the domain does not match the list of known suffixes. - """ - alt_present = any(ext.get_name() == "subjectAltName" - for ext in csr.get_extensions()) - - CNs = csr.get_subject().get_entries_by_oid(x509_name.OID_commonName) - - if len(CNs) > 1: - raise v_errors.ValidationError("Too many CNs in the request") - - # rfc2459#section-4.2.1.6 says so - if len(CNs) == 0 and not alt_present: - raise v_errors.ValidationError("Alt subjects have to exist if the main" - " subject doesn't") - - if len(CNs) > 0: - cn = utils.csr_require_cn(csr) - try: - # is it an IP rather than domain? - ip = netaddr.IPAddress(cn) - if not (utils.check_networks(ip, allowed_networks)): - raise v_errors.ValidationError( - "Address '%s' not allowed (does not match known networks)" - % cn) - except netaddr.AddrFormatError: - if not (utils.check_domains(cn, allowed_domains)): - raise v_errors.ValidationError( - "Domain '%s' not allowed (does not match known domains)" - % cn) - - -def alternative_names(csr, allowed_domains=[], **kwargs): - """Check known domain alternative names. - - Refuse requests for certificates if the domain does not match - the list of known suffixes, or network ranges. - """ - - for _, name in utils.iter_alternative_names(csr, ['DNS']): - if not utils.check_domains(name, allowed_domains): - raise v_errors.ValidationError("Domain '%s' not allowed (doesn't" - " match known domains)" % name) - - -def alternative_names_ip(csr, allowed_domains=[], allowed_networks=[], - **kwargs): - """Check known domain and ip alternative names. - - Refuse requests for certificates if the domain does not match - the list of known suffixes, or network ranges. - """ - - for name_type, name in utils.iter_alternative_names(csr, - ['DNS', 'IP Address']): - if name_type == 'DNS' and not utils.check_domains(name, - allowed_domains): - raise v_errors.ValidationError("Domain '%s' not allowed (doesn't" - " match known domains)" % name) - if name_type == 'IP Address': - if not utils.check_networks(name, allowed_networks): - raise v_errors.ValidationError("IP '%s' not allowed (doesn't" - " match known networks)" % name) - - -def blacklist_names(csr, domains=[], **kwargs): - """Check for blacklisted names in CN and altNames.""" - - if not domains: - logger.warning("No domains were configured for the blacklist filter, " - "consider disabling the step or providing a list") - return - - CNs = csr.get_subject().get_entries_by_oid(x509_name.OID_commonName) - if len(CNs) > 0: - cn = utils.csr_require_cn(csr) - if utils.check_domains(cn, domains): - raise v_errors.ValidationError("Domain '%s' not allowed " - "(CN blacklisted)" % cn) - - for _, name in utils.iter_alternative_names(csr, ['DNS'], - fail_other_types=False): - if utils.check_domains(name, domains): - raise v_errors.ValidationError("Domain '%s' not allowed " - "(alt blacklisted)" % name) - - -def server_group(auth_result=None, csr=None, group_prefixes={}, **kwargs): - """Check Team prefix. - - Make sure that for server names containing a team prefix, the team is - verified against the groups the user is a member of. - """ - - cn = utils.csr_require_cn(csr) - parts = cn.split('-') - if len(parts) == 1 or '.' in parts[0]: - return # no prefix - - if parts[0] in group_prefixes: - if group_prefixes[parts[0]] not in auth_result.groups: - raise v_errors.ValidationError( - "Server prefix doesn't match user groups") - - -def extensions(csr=None, allowed_extensions=[], **kwargs): - """Ensure only accepted extensions are used.""" - exts = csr.get_extensions() or [] - for ext in exts: - if (ext.get_name() not in allowed_extensions and - str(ext.get_oid()) not in allowed_extensions): - raise v_errors.ValidationError("Extension '%s' not allowed" - % ext.get_name()) - - -def key_usage(csr=None, allowed_usage=None, **kwargs): - """Ensure only accepted key usages are specified.""" - allowed = set(extension.LONG_KEY_USAGE_NAMES.get(x, x) for x in - allowed_usage) - denied = set() - - for ext in (csr.get_extensions() or []): - if isinstance(ext, extension.X509ExtensionKeyUsage): - usages = set(ext.get_all_usages()) - denied = denied | (usages - allowed) - if denied: - raise v_errors.ValidationError("Found some prohibited key usages: %s" - % ', '.join(denied)) - - -def ext_key_usage(csr=None, allowed_usage=None, **kwargs): - """Ensure only accepted extended key usages are specified.""" - - # transform all possible names into oids we actually check - for i, usage in enumerate(allowed_usage): - if usage in extension.EXT_KEY_USAGE_NAMES_INV: - allowed_usage[i] = extension.EXT_KEY_USAGE_NAMES_INV[usage] - elif usage in extension.EXT_KEY_USAGE_SHORT_NAMES_INV: - allowed_usage[i] = extension.EXT_KEY_USAGE_SHORT_NAMES_INV[usage] - else: - try: - oid = pyasn1_univ.ObjectIdentifier(usage) - allowed_usage[i] = oid - except Exception: - raise v_errors.ValidationError("Unknown usage: %s" % (usage,)) - - allowed = set(allowed_usage) - denied = set() - - for ext in csr.get_extensions(extension.X509ExtensionExtendedKeyUsage): - usages = set(ext.get_all_usages()) - denied = denied | (usages - allowed) - if denied: - text_denied = [extension.EXT_KEY_USAGE_SHORT_NAMES.get(x) - for x in denied] - raise v_errors.ValidationError("Found some prohibited key usages: %s" - % ', '.join(text_denied)) - - -def source_cidrs(request=None, cidrs=None, **kwargs): - """Ensure that the request comes from a known source.""" - for cidr in cidrs: - try: - r = netaddr.IPNetwork(cidr) - if request.client_addr in r: - return - except netaddr.AddrFormatError: - raise v_errors.ValidationError( - "Cidr '%s' does not describe a valid network" % cidr) - raise v_errors.ValidationError( - "No network matched the request source '%s'" % - request.client_addr) - - -def public_key(csr=None, allowed_keys=None, **kwargs): - """Ensure the public key has the known type and size. - - Configuration provides a dictionary of key types and minimum sizes. - """ - if allowed_keys is None or not isinstance(allowed_keys, dict): - raise v_errors.ValidationError("Allowed keys configuration missing") - - algo = csr.get_public_key_algo() - algo_names = { - rfc2437.rsaEncryption: 'RSA', - rfc2459.id_dsa: 'DSA', - } - algo_name = algo_names.get(algo) - if algo_name is None: - raise v_errors.ValidationError("Unknown public key type") - - min_size = allowed_keys.get(algo_name) - if min_size is None: - raise v_errors.ValidationError( - "Key type not allowed (%s)" % (algo_name,)) - if min_size == 0: - # key size is not enforced - return - - if csr.get_public_key_size() < min_size: - raise v_errors.ValidationError("Key size too small") - - -def _split_names_by_type(names): - """Identify ips and network ranges in a list of strings.""" - allowed_domains = [] - allowed_ips = [] - allowed_ranges = [] - for name in names: - ip = utils.maybe_ip(name) - if ip: - allowed_ips.append(ip) - continue - net = utils.maybe_range(name) - if net: - allowed_ranges.append(net) - continue - allowed_domains.append(name) - - return (allowed_domains, allowed_ips, allowed_ranges) - - -def whitelist_names(csr=None, names=[], allow_cn_id=False, allow_dns_id=False, - allow_ip_id=False, allow_wildcard=False, **kwargs): - """Ensure names match the whitelist in the allowed name slots.""" - - allowed_domains, allowed_ips, allowed_ranges = _split_names_by_type(names) - - for dns_id in csr.get_subject_dns_ids(): - if not allow_dns_id: - raise v_errors.ValidationError("IP-ID not allowed") - valid = False - for allowed_domain in allowed_domains: - if utils.compare_name_pattern(dns_id, allowed_domain, - allow_wildcard): - valid = True - break - if not valid: - raise v_errors.ValidationError( - "Value `%s` not allowed in DNS-ID" % (dns_id,)) - - for ip_id in csr.get_subject_ip_ids(): - if not allow_ip_id: - raise v_errors.ValidationError("IP-ID not allowed") - if ip_id in allowed_ips: - continue - for net in allowed_ranges: - if ip_id in net: - continue - raise v_errors.ValidationError( - "Value `%s` not allowed in IP-ID" % (ip_id,)) - - for cn_id in csr.get_subject_cn(): - if not allow_cn_id: - raise v_errors.ValidationError("CN-ID not allowed") - ip = utils.maybe_ip(cn_id) - if ip: - # current CN is an ip address - if ip in allowed_ips: - continue - if any((ip in net) for net in allowed_ranges): - continue - raise v_errors.ValidationError( - "Value `%s` not allowed in CN-ID" % (cn_id,)) - else: - # current CN is a domain - valid = False - for allowed_domain in allowed_domains: - if utils.compare_name_pattern(cn_id, allowed_domain, - allow_wildcard): - valid = True - break - if valid: - continue - raise v_errors.ValidationError( - "Value `%s` not allowed in CN-ID" % (cn_id,)) - - if csr.has_unknown_san_entries(): - raise v_errors.ValidationError("Request contains unknown SAN entries") diff --git a/anchor/validators/errors.py b/anchor/validators/errors.py deleted file mode 100644 index 7918d24..0000000 --- a/anchor/validators/errors.py +++ /dev/null @@ -1,16 +0,0 @@ -# -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - - -class ValidationError(Exception): - pass diff --git a/anchor/validators/internal.py b/anchor/validators/internal.py deleted file mode 100644 index 0ec7ed0..0000000 --- a/anchor/validators/internal.py +++ /dev/null @@ -1,42 +0,0 @@ -# -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - -"""Anchor internally used validators. They should not be exposed to the -users. -""" - -from anchor.validators import errors as v_errors -from anchor.X509 import extension - - -def ca_status(csr=None, **kwargs): - """Ensure the request hasn't got the CA or cert signing flag. - - This validation applies both to the BasicConstraints extension and to the - KeyUsage extension. - """ - basic_constraint = csr.get_extensions( - extension.X509ExtensionBasicConstraints) - if basic_constraint: - if basic_constraint[0].get_ca(): - raise v_errors.ValidationError( - "Request is for a CA certificate") - - key_usage = csr.get_extensions(extension.X509ExtensionKeyUsage) - if key_usage: - if key_usage[0].get_usage('keyCertSign'): - raise v_errors.ValidationError( - "Request contains certificates signing usage flag") - if key_usage[0].get_usage('cRLSign'): - raise v_errors.ValidationError( - "Request contains CRL signing usage flag") diff --git a/anchor/validators/standards.py b/anchor/validators/standards.py deleted file mode 100644 index 5fe6c0d..0000000 --- a/anchor/validators/standards.py +++ /dev/null @@ -1,111 +0,0 @@ -# -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - -""" -Standards based validator. - -This module provides validators which should be included in all deployments and -which are based directly on the standards documents. All exceptions must have a -comment referencing the document / section they're based on. - -All the rules are pulled into a single validator: ``standards_compliance``. -""" - -from __future__ import absolute_import - -from anchor import util -from anchor.validators import errors -from anchor.X509 import errors as x509_errors -from anchor.X509 import extension - -import re - - -# RFC1034 allows a simple " " too, but it's not allowed in certificates, so it -# will not match -# -# This pattern is RFC1034 compatible otherwise, but since newer RFCs actually -# allow any binary value as the domain label, some operators may want to relax -# the pattern in the configuration, for example to allow leading digits or -# hyphens. -def standards_compliance(csr=None, label_re="^[a-z](?:[-a-z0-9]*[a-z0-9])?$", - **kwargs): - """Collection of separate cases of standards validation.""" - _no_extension_duplicates(csr) - _critical_flags(csr) - _valid_domains(csr, label_re) - _csr_signature(csr) - # TODO(stan): validate srv/uri, distinct DNs, email format, identity keys - - -def _no_extension_duplicates(csr): - """Only one extension with a given oid is allowed. - - See RFC5280 section 4.2 - """ - seen_oids = set() - for ext in csr.get_extensions(): - oid = ext.get_oid() - if oid in seen_oids: - raise errors.ValidationError( - "Duplicate extension with oid %s (RFC5280/4.2)" % oid) - seen_oids.add(oid) - - -def _critical_flags(csr): - """Various rules define whether critical flag is required.""" - for ext in csr.get_extensions(): - if isinstance(ext, extension.X509ExtensionSubjectAltName): - if len(csr.get_subject()) == 0 and not ext.get_critical(): - raise errors.ValidationError( - "SAN must be critical if subject is empty " - "(RFC5280/4.1.2.6)") - if isinstance(ext, extension.X509ExtensionBasicConstraints): - if not ext.get_critical(): - raise errors.ValidationError( - "Basic constraints has to be marked critical " - "(RFC5280/4.1.2.9)") - - -def _valid_domains(csr, label_re="^[a-z](?:[-a-z0-9]*[a-z0-9])?$"): - """Format of the domin names - - See RFC5280 section 4.2.1.6 / RFC6125 / RFC1034 - """ - sans = csr.get_extensions(extension.X509ExtensionSubjectAltName) - if not sans: - return - - label_re_comp = re.compile(label_re, re.IGNORECASE) - - ext = sans[0] - for domain in ext.get_dns_ids(): - try: - util.verify_domain(domain, label_re_comp, allow_wildcards=True) - except ValueError as e: - raise errors.ValidationError(str(e)) - - -def _csr_signature(csr): - """Ensure that the CSR has a valid self-signature.""" - # first check for deprecated signatures - verification on those will fail - algo = csr.uses_deprecated_algorithm() - if algo: - raise errors.ValidationError("CSR rejected for using a known broken, " - "or deprecated algorithm: %s" % algo) - - try: - if not csr.verify(): - raise errors.ValidationError("Signature on the CSR is not valid") - except x509_errors.X509Error: - raise errors.ValidationError("Signature on the CSR is not valid") diff --git a/anchor/validators/utils.py b/anchor/validators/utils.py deleted file mode 100644 index e48ac93..0000000 --- a/anchor/validators/utils.py +++ /dev/null @@ -1,137 +0,0 @@ -# -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - -from __future__ import absolute_import - -import logging - -import netaddr - -from anchor.validators import errors -from anchor.X509 import extension - - -logger = logging.getLogger(__name__) - - -def csr_require_cn(csr): - cns = csr.get_subject_cn() - if not cns: - raise errors.ValidationError("CSR is lacking a CN in the Subject") - if len(cns) > 1: - raise errors.ValidationError("CSR has too many CN entries") - return cns[0] - - -def check_domains(domain, allowed_domains): - if allowed_domains: - if not any(domain.endswith(suffix) for suffix in allowed_domains): - # no domain matched - return False - else: - # no valid domains were provided, so we can't make any assertions - logger.warning("No domains were configured for validation. Anchor " - "will issue certificates for any domain, this is not a " - "recommended configuration for production environments") - return True - - -def iter_alternative_names(csr, types, fail_other_types=True): - for ext in csr.get_extensions(): - if isinstance(ext, extension.X509ExtensionSubjectAltName): - # TODO(stan): fail on other types - if 'DNS' in types: - for dns_id in ext.get_dns_ids(): - yield ('DNS', dns_id) - if 'IP Address' in types: - for ip in ext.get_ips(): - yield ('IP Address', ip) - - -def check_networks(ip, allowed_networks): - """Check the IP is within an allowed network.""" - if not isinstance(ip, netaddr.IPAddress): - raise TypeError("ip must be a netaddr ip address") - - if not allowed_networks: - # no valid networks were provided, so we can't make any assertions - logger.warning("No valid network IP ranges were given, skipping") - return True - - if any(ip in netaddr.IPNetwork(net) for net in allowed_networks): - return True - - return False - - -def maybe_ip(name): - try: - return netaddr.IPAddress(name) - except ValueError: - # happens when trying to pass a subnet prefix - return None - except netaddr.AddrFormatError: - return None - - -def maybe_range(name): - try: - return netaddr.IPNetwork(name) - except netaddr.AddrFormatError: - return None - - -def compare_name_pattern(name, pattern, allow_wildcard): - """Compare domain names including wildcards. - - Wilcard means local Anchor wildcard which is '%'. This allows the pattern - to match an actual wildcard entry (*) or name which can be expanded. - Partial matches using % are allowed, but % matches only in one label. - - In practice that means: - name: pattern: wildard: result: - example.com example.com - match - *.example.com *.example.com - match - *.example.com %.example.com true match - *.example.com %.example.com false fail - abc.example.com %.example.com - match - abc.def.example.com %.example.com - fail - abc.def.example.com %.%.example.com - match - host-123.example.com host-%.example.com - match - """ - - name_labels = name.split('.') - patt_labels = pattern.split('.') - if len(name_labels) != len(patt_labels): - return False - - for nl, pl in zip(name_labels, patt_labels): - if '%' in pl: - pre, _, post = pl.partition('%') - - if not nl.startswith(pre): - return False - nl = nl[len(pre):] # strip the pre part of pattern - - if not nl.endswith(post): - return False - if len(post) > 0: - nl = nl[:-len(post)] # strip the post part of pattern - - if '*' in nl and not allow_wildcard: - return False - else: - if nl != pl: - return False - - return True diff --git a/asn/autogenerated.txt b/asn/autogenerated.txt deleted file mode 100644 index dfb330b..0000000 --- a/asn/autogenerated.txt +++ /dev/null @@ -1,10 +0,0 @@ -Files in "anchor/asn1" have been generated from the asn1 modules in "asn" -directory using asn1ate (https://github.com/kimgr/asn1ate/) - -They can be regenerated by: -- running asn1ate on each module -- putting .i and .e results together (implicit / explicit modules) -- removing faked imports -- linking missing classes to other rfcXXXX files - -There's currently no fully automatic way to do it. diff --git a/asn/rfc3280.e.asn b/asn/rfc3280.e.asn deleted file mode 100644 index e23ac96..0000000 --- a/asn/rfc3280.e.asn +++ /dev/null @@ -1,628 +0,0 @@ -PKIX1Explicit88 { iso(1) identified-organization(3) dod(6) internet(1) - security(5) mechanisms(5) pkix(7) id-mod(0) id-pkix1-explicit(18) } - -DEFINITIONS EXPLICIT TAGS ::= - -BEGIN - --- EXPORTS ALL -- - --- IMPORTS NONE -- - --- UNIVERSAL Types defined in 1993 and 1998 ASN.1 --- and required by this specification - ---UniversalString ::= [UNIVERSAL 28] IMPLICIT OCTET STRING - -- UniversalString is defined in ASN.1:1993 - ---BMPString ::= [UNIVERSAL 30] IMPLICIT OCTET STRING - -- BMPString is the subtype of UniversalString and models - -- the Basic Multilingual Plane of ISO/IEC/ITU 10646-1 - ---UTF8String ::= [UNIVERSAL 12] IMPLICIT OCTET STRING - -- The content of this type conforms to RFC 2279. - --- PKIX specific OIDs - -id-pkix OBJECT IDENTIFIER ::= - { iso(1) identified-organization(3) dod(6) internet(1) - security(5) mechanisms(5) pkix(7) } - --- PKIX arcs - -id-pe OBJECT IDENTIFIER ::= { id-pkix 1 } - -- arc for private certificate extensions -id-qt OBJECT IDENTIFIER ::= { id-pkix 2 } - -- arc for policy qualifier types -id-kp OBJECT IDENTIFIER ::= { id-pkix 3 } - -- arc for extended key purpose OIDS -id-ad OBJECT IDENTIFIER ::= { id-pkix 48 } - -- arc for access descriptors - --- policyQualifierIds for Internet policy qualifiers - -id-qt-cps OBJECT IDENTIFIER ::= { id-qt 1 } - -- OID for CPS qualifier -id-qt-unotice OBJECT IDENTIFIER ::= { id-qt 2 } - -- OID for user notice qualifier - --- access descriptor definitions - -id-ad-ocsp OBJECT IDENTIFIER ::= { id-ad 1 } -id-ad-caIssuers OBJECT IDENTIFIER ::= { id-ad 2 } -id-ad-timeStamping OBJECT IDENTIFIER ::= { id-ad 3 } -id-ad-caRepository OBJECT IDENTIFIER ::= { id-ad 5 } - --- attribute data types - -Attribute ::= SEQUENCE { - type AttributeType, - values SET OF AttributeValue } - -- at least one value is required - -AttributeType ::= OBJECT IDENTIFIER - -AttributeValue ::= ANY - -AttributeTypeAndValue ::= SEQUENCE { - type AttributeType, - value AttributeValue } - --- suggested naming attributes: Definition of the following --- information object set may be augmented to meet local --- requirements. Note that deleting members of the set may --- prevent interoperability with conforming implementations. --- presented in pairs: the AttributeType followed by the --- type definition for the corresponding AttributeValue ---Arc for standard naming attributes -id-at OBJECT IDENTIFIER ::= { joint-iso-ccitt(2) ds(5) 4 } - --- Naming attributes of type X520name - -id-at-name AttributeType ::= { id-at 41 } -id-at-surname AttributeType ::= { id-at 4 } -id-at-givenName AttributeType ::= { id-at 42 } -id-at-initials AttributeType ::= { id-at 43 } -id-at-generationQualifier AttributeType ::= { id-at 44 } - -X520name ::= CHOICE { - teletexString TeletexString (SIZE (1..ub-name)), - printableString PrintableString (SIZE (1..ub-name)), - universalString UniversalString (SIZE (1..ub-name)), - utf8String UTF8String (SIZE (1..ub-name)), - bmpString BMPString (SIZE (1..ub-name)) } - --- Naming attributes of type X520CommonName - -id-at-commonName AttributeType ::= { id-at 3 } - -X520CommonName ::= CHOICE { - teletexString TeletexString (SIZE (1..ub-common-name)), - printableString PrintableString (SIZE (1..ub-common-name)), - universalString UniversalString (SIZE (1..ub-common-name)), - utf8String UTF8String (SIZE (1..ub-common-name)), - bmpString BMPString (SIZE (1..ub-common-name)) } - --- Naming attributes of type X520LocalityName - -id-at-localityName AttributeType ::= { id-at 7 } - -X520LocalityName ::= CHOICE { - teletexString TeletexString (SIZE (1..ub-locality-name)), - printableString PrintableString (SIZE (1..ub-locality-name)), - universalString UniversalString (SIZE (1..ub-locality-name)), - utf8String UTF8String (SIZE (1..ub-locality-name)), - bmpString BMPString (SIZE (1..ub-locality-name)) } - --- Naming attributes of type X520StateOrProvinceName - -id-at-stateOrProvinceName AttributeType ::= { id-at 8 } - -X520StateOrProvinceName ::= CHOICE { - teletexString TeletexString (SIZE (1..ub-state-name)), - printableString PrintableString (SIZE (1..ub-state-name)), - universalString UniversalString (SIZE (1..ub-state-name)), - utf8String UTF8String (SIZE (1..ub-state-name)), - bmpString BMPString (SIZE(1..ub-state-name)) } - - --- Naming attributes of type X520OrganizationName - -id-at-organizationName AttributeType ::= { id-at 10 } - -X520OrganizationName ::= CHOICE { - teletexString TeletexString - (SIZE (1..ub-organization-name)), - printableString PrintableString - (SIZE (1..ub-organization-name)), - universalString UniversalString - (SIZE (1..ub-organization-name)), - utf8String UTF8String - (SIZE (1..ub-organization-name)), - bmpString BMPString - (SIZE (1..ub-organization-name)) } - --- Naming attributes of type X520OrganizationalUnitName - -id-at-organizationalUnitName AttributeType ::= { id-at 11 } - -X520OrganizationalUnitName ::= CHOICE { - teletexString TeletexString - (SIZE (1..ub-organizational-unit-name)), - printableString PrintableString - (SIZE (1..ub-organizational-unit-name)), - universalString UniversalString - (SIZE (1..ub-organizational-unit-name)), - utf8String UTF8String - (SIZE (1..ub-organizational-unit-name)), - bmpString BMPString - (SIZE (1..ub-organizational-unit-name)) } - --- Naming attributes of type X520Title - -id-at-title AttributeType ::= { id-at 12 } - -X520Title ::= CHOICE { - teletexString TeletexString (SIZE (1..ub-title)), - printableString PrintableString (SIZE (1..ub-title)), - universalString UniversalString (SIZE (1..ub-title)), - utf8String UTF8String (SIZE (1..ub-title)), - bmpString BMPString (SIZE (1..ub-title)) } - --- Naming attributes of type X520dnQualifier - -id-at-dnQualifier AttributeType ::= { id-at 46 } - -X520dnQualifier ::= PrintableString - --- Naming attributes of type X520countryName (digraph from IS 3166) - -id-at-countryName AttributeType ::= { id-at 6 } - -X520countryName ::= PrintableString (SIZE (2)) - --- Naming attributes of type X520SerialNumber - -id-at-serialNumber AttributeType ::= { id-at 5 } - -X520SerialNumber ::= PrintableString (SIZE (1..ub-serial-number)) - --- Naming attributes of type X520Pseudonym - -id-at-pseudonym AttributeType ::= { id-at 65 } - -X520Pseudonym ::= CHOICE { - teletexString TeletexString (SIZE (1..ub-pseudonym)), - printableString PrintableString (SIZE (1..ub-pseudonym)), - universalString UniversalString (SIZE (1..ub-pseudonym)), - utf8String UTF8String (SIZE (1..ub-pseudonym)), - bmpString BMPString (SIZE (1..ub-pseudonym)) } - --- Naming attributes of type DomainComponent (from RFC 2247) - -id-domainComponent AttributeType ::= - { 0 9 2342 19200300 100 1 25 } - -DomainComponent ::= IA5String - --- Legacy attributes - -pkcs-9 OBJECT IDENTIFIER ::= - { iso(1) member-body(2) us(840) rsadsi(113549) pkcs(1) 9 } - -id-emailAddress AttributeType ::= { pkcs-9 1 } - -EmailAddress ::= IA5String (SIZE (1..ub-emailaddress-length)) - --- naming data types -- - -Name ::= CHOICE { -- only one possibility for now -- - rdnSequence RDNSequence } - -RDNSequence ::= SEQUENCE OF RelativeDistinguishedName - -DistinguishedName ::= RDNSequence - - -RelativeDistinguishedName ::= - SET SIZE (1 .. MAX) OF AttributeTypeAndValue - --- Directory string type -- - -DirectoryString ::= CHOICE { - teletexString TeletexString (SIZE (1..MAX)), - printableString PrintableString (SIZE (1..MAX)), - universalString UniversalString (SIZE (1..MAX)), - utf8String UTF8String (SIZE (1..MAX)), - bmpString BMPString (SIZE (1..MAX)) } - --- certificate and CRL specific structures begin here - -Certificate ::= SEQUENCE { - tbsCertificate TBSCertificate, - signatureAlgorithm AlgorithmIdentifier, - signature BIT STRING } - -TBSCertificate ::= SEQUENCE { - version [0] Version DEFAULT v1, - serialNumber CertificateSerialNumber, - signature AlgorithmIdentifier, - issuer Name, - validity Validity, - subject Name, - subjectPublicKeyInfo SubjectPublicKeyInfo, - issuerUniqueID [1] IMPLICIT UniqueIdentifier OPTIONAL, - -- If present, version MUST be v2 or v3 - subjectUniqueID [2] IMPLICIT UniqueIdentifier OPTIONAL, - -- If present, version MUST be v2 or v3 - extensions [3] Extensions OPTIONAL - -- If present, version MUST be v3 -- } - -Version ::= INTEGER { v1(0), v2(1), v3(2) } - -CertificateSerialNumber ::= INTEGER - -Validity ::= SEQUENCE { - notBefore Time, - notAfter Time } - -Time ::= CHOICE { - utcTime UTCTime, - generalTime GeneralizedTime } - -UniqueIdentifier ::= BIT STRING - - -SubjectPublicKeyInfo ::= SEQUENCE { - algorithm AlgorithmIdentifier, - subjectPublicKey BIT STRING } - -Extensions ::= SEQUENCE SIZE (1..MAX) OF Extension - -Extension ::= SEQUENCE { - extnID OBJECT IDENTIFIER, - critical BOOLEAN DEFAULT FALSE, - extnValue OCTET STRING } - --- CRL structures - -CertificateList ::= SEQUENCE { - tbsCertList TBSCertList, - signatureAlgorithm AlgorithmIdentifier, - signature BIT STRING } - -TBSCertList ::= SEQUENCE { - version Version OPTIONAL, - -- if present, MUST be v2 - signature AlgorithmIdentifier, - issuer Name, - thisUpdate Time, - nextUpdate Time OPTIONAL, - revokedCertificates SEQUENCE OF SEQUENCE { - userCertificate CertificateSerialNumber, - revocationDate Time, - crlEntryExtensions Extensions OPTIONAL - -- if present, MUST be v2 - } OPTIONAL, - crlExtensions [0] Extensions OPTIONAL } - -- if present, MUST be v2 - --- Version, Time, CertificateSerialNumber, and Extensions were --- defined earlier for use in the certificate structure - -AlgorithmIdentifier ::= SEQUENCE { - algorithm OBJECT IDENTIFIER, - parameters ANY DEFINED BY algorithm OPTIONAL } - -- contains a value of the type - -- registered for use with the - -- algorithm object identifier value - --- X.400 address syntax starts here - - - -ORAddress ::= SEQUENCE { - built-in-standard-attributes BuiltInStandardAttributes, - built-in-domain-defined-attributes - BuiltInDomainDefinedAttributes OPTIONAL, - -- see also teletex-domain-defined-attributes - extension-attributes ExtensionAttributes OPTIONAL } - --- Built-in Standard Attributes - -BuiltInStandardAttributes ::= SEQUENCE { - country-name CountryName OPTIONAL, - administration-domain-name AdministrationDomainName OPTIONAL, - network-address [0] IMPLICIT NetworkAddress OPTIONAL, - -- see also extended-network-address - terminal-identifier [1] IMPLICIT TerminalIdentifier OPTIONAL, - private-domain-name [2] PrivateDomainName OPTIONAL, - organization-name [3] IMPLICIT OrganizationName OPTIONAL, - -- see also teletex-organization-name - numeric-user-identifier [4] IMPLICIT NumericUserIdentifier - OPTIONAL, - personal-name [5] IMPLICIT PersonalName OPTIONAL, - -- see also teletex-personal-name - organizational-unit-names [6] IMPLICIT OrganizationalUnitNames - OPTIONAL } - -- see also teletex-organizational-unit-names - -CountryName ::= [APPLICATION 1] CHOICE { - x121-dcc-code NumericString - (SIZE (ub-country-name-numeric-length)), - iso-3166-alpha2-code PrintableString - (SIZE (ub-country-name-alpha-length)) } - -AdministrationDomainName ::= [APPLICATION 2] CHOICE { - numeric NumericString (SIZE (0..ub-domain-name-length)), - printable PrintableString (SIZE (0..ub-domain-name-length)) } - -NetworkAddress ::= X121Address -- see also extended-network-address - -X121Address ::= NumericString (SIZE (1..ub-x121-address-length)) - -TerminalIdentifier ::= PrintableString (SIZE -(1..ub-terminal-id-length)) - -PrivateDomainName ::= CHOICE { - numeric NumericString (SIZE (1..ub-domain-name-length)), - printable PrintableString (SIZE (1..ub-domain-name-length)) } - - - -OrganizationName ::= PrintableString - (SIZE (1..ub-organization-name-length)) - -- see also teletex-organization-name - -NumericUserIdentifier ::= NumericString - (SIZE (1..ub-numeric-user-id-length)) - -PersonalName ::= SET { - surname [0] IMPLICIT PrintableString - (SIZE (1..ub-surname-length)), - given-name [1] IMPLICIT PrintableString - (SIZE (1..ub-given-name-length)) OPTIONAL, - initials [2] IMPLICIT PrintableString - (SIZE (1..ub-initials-length)) OPTIONAL, - generation-qualifier [3] IMPLICIT PrintableString - (SIZE (1..ub-generation-qualifier-length)) - OPTIONAL } - -- see also teletex-personal-name - -OrganizationalUnitNames ::= SEQUENCE SIZE (1..ub-organizational-units) - OF OrganizationalUnitName - -- see also teletex-organizational-unit-names - -OrganizationalUnitName ::= PrintableString (SIZE - (1..ub-organizational-unit-name-length)) - --- Built-in Domain-defined Attributes - -BuiltInDomainDefinedAttributes ::= SEQUENCE SIZE - (1..ub-domain-defined-attributes) OF - BuiltInDomainDefinedAttribute - -BuiltInDomainDefinedAttribute ::= SEQUENCE { - type PrintableString (SIZE - (1..ub-domain-defined-attribute-type-length)), - value PrintableString (SIZE - (1..ub-domain-defined-attribute-value-length)) } - --- Extension Attributes - -ExtensionAttributes ::= SET SIZE (1..ub-extension-attributes) OF - ExtensionAttribute - -ExtensionAttribute ::= SEQUENCE { - extension-attribute-type [0] IMPLICIT INTEGER - (0..ub-extension-attributes), - extension-attribute-value [1] - ANY DEFINED BY extension-attribute-type } - --- Extension types and attribute values - -common-name INTEGER ::= 1 - -CommonName ::= PrintableString (SIZE (1..ub-common-name-length)) - -teletex-common-name INTEGER ::= 2 - -TeletexCommonName ::= TeletexString (SIZE (1..ub-common-name-length)) - -teletex-organization-name INTEGER ::= 3 - -TeletexOrganizationName ::= - TeletexString (SIZE (1..ub-organization-name-length)) - -teletex-personal-name INTEGER ::= 4 - -TeletexPersonalName ::= SET { - surname [0] IMPLICIT TeletexString - (SIZE (1..ub-surname-length)), - given-name [1] IMPLICIT TeletexString - (SIZE (1..ub-given-name-length)) OPTIONAL, - initials [2] IMPLICIT TeletexString - (SIZE (1..ub-initials-length)) OPTIONAL, - generation-qualifier [3] IMPLICIT TeletexString - (SIZE (1..ub-generation-qualifier-length)) - OPTIONAL } - -teletex-organizational-unit-names INTEGER ::= 5 - -TeletexOrganizationalUnitNames ::= SEQUENCE SIZE - (1..ub-organizational-units) OF TeletexOrganizationalUnitName - -TeletexOrganizationalUnitName ::= TeletexString - (SIZE (1..ub-organizational-unit-name-length)) - -pds-name INTEGER ::= 7 - -PDSName ::= PrintableString (SIZE (1..ub-pds-name-length)) - -physical-delivery-country-name INTEGER ::= 8 - -PhysicalDeliveryCountryName ::= CHOICE { - x121-dcc-code NumericString (SIZE -(ub-country-name-numeric-length)), - iso-3166-alpha2-code PrintableString - (SIZE (ub-country-name-alpha-length)) } - - -postal-code INTEGER ::= 9 - -PostalCode ::= CHOICE { - numeric-code NumericString (SIZE (1..ub-postal-code-length)), - printable-code PrintableString (SIZE (1..ub-postal-code-length)) } - -physical-delivery-office-name INTEGER ::= 10 - -PhysicalDeliveryOfficeName ::= PDSParameter - -physical-delivery-office-number INTEGER ::= 11 - -PhysicalDeliveryOfficeNumber ::= PDSParameter - -extension-OR-address-components INTEGER ::= 12 - -ExtensionORAddressComponents ::= PDSParameter - -physical-delivery-personal-name INTEGER ::= 13 - -PhysicalDeliveryPersonalName ::= PDSParameter - -physical-delivery-organization-name INTEGER ::= 14 - -PhysicalDeliveryOrganizationName ::= PDSParameter - -extension-physical-delivery-address-components INTEGER ::= 15 - -ExtensionPhysicalDeliveryAddressComponents ::= PDSParameter - -unformatted-postal-address INTEGER ::= 16 - -UnformattedPostalAddress ::= SET { - printable-address SEQUENCE SIZE (1..ub-pds-physical-address-lines) - OF PrintableString (SIZE (1..ub-pds-parameter-length)) - OPTIONAL, - teletex-string TeletexString - (SIZE (1..ub-unformatted-address-length)) OPTIONAL } - -street-address INTEGER ::= 17 - -StreetAddress ::= PDSParameter - -post-office-box-address INTEGER ::= 18 - -PostOfficeBoxAddress ::= PDSParameter - -poste-restante-address INTEGER ::= 19 - -PosteRestanteAddress ::= PDSParameter - -unique-postal-name INTEGER ::= 20 - -UniquePostalName ::= PDSParameter - -local-postal-attributes INTEGER ::= 21 - -LocalPostalAttributes ::= PDSParameter - -PDSParameter ::= SET { - printable-string PrintableString - (SIZE(1..ub-pds-parameter-length)) OPTIONAL, - teletex-string TeletexString - (SIZE(1..ub-pds-parameter-length)) OPTIONAL } - -extended-network-address INTEGER ::= 22 - -ExtendedNetworkAddress ::= CHOICE { - e163-4-address SEQUENCE { - number [0] IMPLICIT NumericString - (SIZE (1..ub-e163-4-number-length)), - sub-address [1] IMPLICIT NumericString - (SIZE (1..ub-e163-4-sub-address-length)) - OPTIONAL }, - psap-address [0] IMPLICIT PresentationAddress } - -PresentationAddress ::= SEQUENCE { - pSelector [0] EXPLICIT OCTET STRING OPTIONAL, - sSelector [1] EXPLICIT OCTET STRING OPTIONAL, - tSelector [2] EXPLICIT OCTET STRING OPTIONAL, - nAddresses [3] EXPLICIT SET SIZE (1..MAX) OF OCTET STRING } - -terminal-type INTEGER ::= 23 - -TerminalType ::= INTEGER { - telex (3), - teletex (4), - g3-facsimile (5), - g4-facsimile (6), - ia5-terminal (7), - videotex (8) } --(0..ub-integer-options) - --- Extension Domain-defined Attributes - -teletex-domain-defined-attributes INTEGER ::= 6 - - -TeletexDomainDefinedAttributes ::= SEQUENCE SIZE - (1..ub-domain-defined-attributes) OF TeletexDomainDefinedAttribute - -TeletexDomainDefinedAttribute ::= SEQUENCE { - type TeletexString - (SIZE (1..ub-domain-defined-attribute-type-length)), - value TeletexString - (SIZE (1..ub-domain-defined-attribute-value-length)) } - --- specifications of Upper Bounds MUST be regarded as mandatory --- from Annex B of ITU-T X.411 Reference Definition of MTS Parameter --- Upper Bounds - --- Upper Bounds -ub-name INTEGER ::= 32768 -ub-common-name INTEGER ::= 64 -ub-locality-name INTEGER ::= 128 -ub-state-name INTEGER ::= 128 -ub-organization-name INTEGER ::= 64 -ub-organizational-unit-name INTEGER ::= 64 -ub-title INTEGER ::= 64 -ub-serial-number INTEGER ::= 64 -ub-match INTEGER ::= 128 -ub-emailaddress-length INTEGER ::= 128 -ub-common-name-length INTEGER ::= 64 -ub-country-name-alpha-length INTEGER ::= 2 -ub-country-name-numeric-length INTEGER ::= 3 -ub-domain-defined-attributes INTEGER ::= 4 -ub-domain-defined-attribute-type-length INTEGER ::= 8 -ub-domain-defined-attribute-value-length INTEGER ::= 128 -ub-domain-name-length INTEGER ::= 16 -ub-extension-attributes INTEGER ::= 256 -ub-e163-4-number-length INTEGER ::= 15 -ub-e163-4-sub-address-length INTEGER ::= 40 -ub-generation-qualifier-length INTEGER ::= 3 -ub-given-name-length INTEGER ::= 16 -ub-initials-length INTEGER ::= 5 -ub-integer-options INTEGER ::= 256 -ub-numeric-user-id-length INTEGER ::= 32 -ub-organization-name-length INTEGER ::= 64 -ub-organizational-unit-name-length INTEGER ::= 32 -ub-organizational-units INTEGER ::= 4 -ub-pds-name-length INTEGER ::= 16 -ub-pds-parameter-length INTEGER ::= 30 -ub-pds-physical-address-lines INTEGER ::= 6 -ub-postal-code-length INTEGER ::= 16 -ub-pseudonym INTEGER ::= 128 -ub-surname-length INTEGER ::= 40 -ub-terminal-id-length INTEGER ::= 24 -ub-unformatted-address-length INTEGER ::= 180 -ub-x121-address-length INTEGER ::= 16 - --- Note - upper bounds on string types, such as TeletexString, are --- measured in characters. Excepting PrintableString or IA5String, a --- significantly greater number of octets will be required to hold --- such a value. As a minimum, 16 octets, or twice the specified --- upper bound, whichever is the larger, should be allowed for --- TeletexString. For UTF8String or UniversalString at least four --- times the upper bound should be allowed. - -END diff --git a/asn/rfc3280.i.asn b/asn/rfc3280.i.asn deleted file mode 100644 index 300869c..0000000 --- a/asn/rfc3280.i.asn +++ /dev/null @@ -1,347 +0,0 @@ -PKIX1Implicit88 { iso(1) identified-organization(3) dod(6) internet(1) - security(5) mechanisms(5) pkix(7) id-mod(0) id-pkix1-implicit(19) } - -DEFINITIONS IMPLICIT TAGS ::= - -BEGIN - --- EXPORTS ALL -- - --- fake imports -id-pe OBJECT IDENTIFIER ::= { id-pkix 1 } -id-kp OBJECT IDENTIFIER ::= { id-pkix 3 } -ORAddress ::= ANY -Name ::= CHOICE { any ANY } -RelativeDistinguishedName ::= ANY -CertificateSerialNumber ::= INTEGER -Attribute ::= ANY -DirectoryString ::= CHOICE { any ANY } - --- ISO arc for standard certificate and CRL extensions - -id-ce OBJECT IDENTIFIER ::= {joint-iso-ccitt(2) ds(5) 29} - --- authority key identifier OID and syntax - -id-ce-authorityKeyIdentifier OBJECT IDENTIFIER ::= { id-ce 35 } - -AuthorityKeyIdentifier ::= SEQUENCE { - keyIdentifier [0] KeyIdentifier OPTIONAL, - authorityCertIssuer [1] GeneralNames OPTIONAL, - authorityCertSerialNumber [2] CertificateSerialNumber OPTIONAL } - -- authorityCertIssuer and authorityCertSerialNumber MUST both - -- be present or both be absent - -KeyIdentifier ::= OCTET STRING - --- subject key identifier OID and syntax - -id-ce-subjectKeyIdentifier OBJECT IDENTIFIER ::= { id-ce 14 } - -SubjectKeyIdentifier ::= KeyIdentifier - --- key usage extension OID and syntax - -id-ce-keyUsage OBJECT IDENTIFIER ::= { id-ce 15 } - -KeyUsage ::= BIT STRING { - digitalSignature (0), - nonRepudiation (1), - keyEncipherment (2), - dataEncipherment (3), - keyAgreement (4), - keyCertSign (5), - cRLSign (6), - encipherOnly (7), - decipherOnly (8) } - --- private key usage period extension OID and syntax - -id-ce-privateKeyUsagePeriod OBJECT IDENTIFIER ::= { id-ce 16 } - -PrivateKeyUsagePeriod ::= SEQUENCE { - notBefore [0] GeneralizedTime OPTIONAL, - notAfter [1] GeneralizedTime OPTIONAL } - -- either notBefore or notAfter MUST be present - --- certificate policies extension OID and syntax - -id-ce-certificatePolicies OBJECT IDENTIFIER ::= { id-ce 32 } - -anyPolicy OBJECT IDENTIFIER ::= { id-ce-certificatePolicies 0 } - -CertificatePolicies ::= SEQUENCE SIZE (1..MAX) OF PolicyInformation - -PolicyInformation ::= SEQUENCE { - policyIdentifier CertPolicyId, - policyQualifiers SEQUENCE SIZE (1..MAX) OF - PolicyQualifierInfo OPTIONAL } - -CertPolicyId ::= OBJECT IDENTIFIER - -PolicyQualifierInfo ::= SEQUENCE { - policyQualifierId PolicyQualifierId, - qualifier ANY DEFINED BY policyQualifierId } - --- Implementations that recognize additional policy qualifiers MUST --- augment the following definition for PolicyQualifierId - -PolicyQualifierId ::= - OBJECT IDENTIFIER --( id-qt-cps | id-qt-unotice ) - --- CPS pointer qualifier - -CPSuri ::= IA5String - --- user notice qualifier - -UserNotice ::= SEQUENCE { - noticeRef NoticeReference OPTIONAL, - explicitText DisplayText OPTIONAL} - -NoticeReference ::= SEQUENCE { - organization DisplayText, - noticeNumbers SEQUENCE OF INTEGER } - -DisplayText ::= CHOICE { - ia5String IA5String (SIZE (1..200)), - visibleString VisibleString (SIZE (1..200)), - bmpString BMPString (SIZE (1..200)), - utf8String UTF8String (SIZE (1..200)) } - --- policy mapping extension OID and syntax - -id-ce-policyMappings OBJECT IDENTIFIER ::= { id-ce 33 } - -PolicyMappings ::= SEQUENCE SIZE (1..MAX) OF SEQUENCE { - issuerDomainPolicy CertPolicyId, - subjectDomainPolicy CertPolicyId } - --- subject alternative name extension OID and syntax - -id-ce-subjectAltName OBJECT IDENTIFIER ::= { id-ce 17 } - -SubjectAltName ::= GeneralNames - -GeneralNames ::= SEQUENCE SIZE (1..MAX) OF GeneralName - -GeneralName ::= CHOICE { - otherName [0] AnotherName, - rfc822Name [1] IA5String, - dNSName [2] IA5String, - x400Address [3] ORAddress, - directoryName [4] Name, - ediPartyName [5] EDIPartyName, - uniformResourceIdentifier [6] IA5String, - iPAddress [7] OCTET STRING, - registeredID [8] OBJECT IDENTIFIER } - --- AnotherName replaces OTHER-NAME ::= TYPE-IDENTIFIER, as --- TYPE-IDENTIFIER is not supported in the '88 ASN.1 syntax - -AnotherName ::= SEQUENCE { - type-id OBJECT IDENTIFIER, - value [0] EXPLICIT ANY DEFINED BY type-id } - -EDIPartyName ::= SEQUENCE { - nameAssigner [0] DirectoryString OPTIONAL, - partyName [1] DirectoryString } - --- issuer alternative name extension OID and syntax - -id-ce-issuerAltName OBJECT IDENTIFIER ::= { id-ce 18 } - -IssuerAltName ::= GeneralNames - -id-ce-subjectDirectoryAttributes OBJECT IDENTIFIER ::= { id-ce 9 } - -SubjectDirectoryAttributes ::= SEQUENCE SIZE (1..MAX) OF Attribute - --- basic constraints extension OID and syntax - -id-ce-basicConstraints OBJECT IDENTIFIER ::= { id-ce 19 } - -BasicConstraints ::= SEQUENCE { - cA BOOLEAN DEFAULT FALSE, - pathLenConstraint INTEGER (0..MAX) OPTIONAL } - --- name constraints extension OID and syntax - -id-ce-nameConstraints OBJECT IDENTIFIER ::= { id-ce 30 } - -NameConstraints ::= SEQUENCE { - permittedSubtrees [0] GeneralSubtrees OPTIONAL, - excludedSubtrees [1] GeneralSubtrees OPTIONAL } - -GeneralSubtrees ::= SEQUENCE SIZE (1..MAX) OF GeneralSubtree - -GeneralSubtree ::= SEQUENCE { - base GeneralName, - minimum [0] BaseDistance DEFAULT 0, - maximum [1] BaseDistance OPTIONAL } - -BaseDistance ::= INTEGER (0..MAX) - --- policy constraints extension OID and syntax - -id-ce-policyConstraints OBJECT IDENTIFIER ::= { id-ce 36 } - -PolicyConstraints ::= SEQUENCE { - requireExplicitPolicy [0] SkipCerts OPTIONAL, - inhibitPolicyMapping [1] SkipCerts OPTIONAL } - -SkipCerts ::= INTEGER (0..MAX) - --- CRL distribution points extension OID and syntax - -id-ce-cRLDistributionPoints OBJECT IDENTIFIER ::= {id-ce 31} - -CRLDistributionPoints ::= SEQUENCE SIZE (1..MAX) OF DistributionPoint - -DistributionPoint ::= SEQUENCE { - distributionPoint [0] DistributionPointName OPTIONAL, - reasons [1] ReasonFlags OPTIONAL, - cRLIssuer [2] GeneralNames OPTIONAL } - -DistributionPointName ::= CHOICE { - fullName [0] GeneralNames, - nameRelativeToCRLIssuer [1] RelativeDistinguishedName } - -ReasonFlags ::= BIT STRING { - unused (0), - keyCompromise (1), - cACompromise (2), - affiliationChanged (3), - superseded (4), - cessationOfOperation (5), - certificateHold (6), - privilegeWithdrawn (7), - aACompromise (8) } - --- extended key usage extension OID and syntax - -id-ce-extKeyUsage OBJECT IDENTIFIER ::= {id-ce 37} - -ExtKeyUsageSyntax ::= SEQUENCE SIZE (1..MAX) OF KeyPurposeId - - -KeyPurposeId ::= OBJECT IDENTIFIER - --- permit unspecified key uses - -anyExtendedKeyUsage OBJECT IDENTIFIER ::= { id-ce-extKeyUsage 0 } - --- extended key purpose OIDs - -id-kp-serverAuth OBJECT IDENTIFIER ::= { id-kp 1 } -id-kp-clientAuth OBJECT IDENTIFIER ::= { id-kp 2 } -id-kp-codeSigning OBJECT IDENTIFIER ::= { id-kp 3 } -id-kp-emailProtection OBJECT IDENTIFIER ::= { id-kp 4 } -id-kp-timeStamping OBJECT IDENTIFIER ::= { id-kp 8 } -id-kp-OCSPSigning OBJECT IDENTIFIER ::= { id-kp 9 } - --- inhibit any policy OID and syntax - -id-ce-inhibitAnyPolicy OBJECT IDENTIFIER ::= { id-ce 54 } - -InhibitAnyPolicy ::= SkipCerts - --- freshest (delta)CRL extension OID and syntax - -id-ce-freshestCRL OBJECT IDENTIFIER ::= { id-ce 46 } - -FreshestCRL ::= CRLDistributionPoints - --- authority info access - -id-pe-authorityInfoAccess OBJECT IDENTIFIER ::= { id-pe 1 } - -AuthorityInfoAccessSyntax ::= - SEQUENCE SIZE (1..MAX) OF AccessDescription - -AccessDescription ::= SEQUENCE { - accessMethod OBJECT IDENTIFIER, - accessLocation GeneralName } - --- subject info access - -id-pe-subjectInfoAccess OBJECT IDENTIFIER ::= { id-pe 11 } - -SubjectInfoAccessSyntax ::= - SEQUENCE SIZE (1..MAX) OF AccessDescription - --- CRL number extension OID and syntax - -id-ce-cRLNumber OBJECT IDENTIFIER ::= { id-ce 20 } - -CRLNumber ::= INTEGER (0..MAX) - --- issuing distribution point extension OID and syntax - -id-ce-issuingDistributionPoint OBJECT IDENTIFIER ::= { id-ce 28 } - -IssuingDistributionPoint ::= SEQUENCE { - distributionPoint [0] DistributionPointName OPTIONAL, - onlyContainsUserCerts [1] BOOLEAN DEFAULT FALSE, - onlyContainsCACerts [2] BOOLEAN DEFAULT FALSE, - onlySomeReasons [3] ReasonFlags OPTIONAL, - indirectCRL [4] BOOLEAN DEFAULT FALSE, - onlyContainsAttributeCerts [5] BOOLEAN DEFAULT FALSE } - -id-ce-deltaCRLIndicator OBJECT IDENTIFIER ::= { id-ce 27 } - -BaseCRLNumber ::= CRLNumber - --- CRL reasons extension OID and syntax - -id-ce-cRLReasons OBJECT IDENTIFIER ::= { id-ce 21 } - -CRLReason ::= ENUMERATED { - unspecified (0), - keyCompromise (1), - cACompromise (2), - affiliationChanged (3), - superseded (4), - cessationOfOperation (5), - certificateHold (6), - removeFromCRL (8), - privilegeWithdrawn (9), - aACompromise (10) } - --- certificate issuer CRL entry extension OID and syntax - -id-ce-certificateIssuer OBJECT IDENTIFIER ::= { id-ce 29 } - -CertificateIssuer ::= GeneralNames - --- hold instruction extension OID and syntax - -id-ce-holdInstructionCode OBJECT IDENTIFIER ::= { id-ce 23 } - -HoldInstructionCode ::= OBJECT IDENTIFIER - --- ANSI x9 holdinstructions - --- ANSI x9 arc holdinstruction arc - -holdInstruction OBJECT IDENTIFIER ::= - {joint-iso-itu-t(2) member-body(2) us(840) x9cm(10040) 2} - --- ANSI X9 holdinstructions referenced by this standard - -id-holdinstruction-none OBJECT IDENTIFIER ::= - {holdInstruction 1} -- deprecated - -id-holdinstruction-callissuer OBJECT IDENTIFIER ::= - {holdInstruction 2} - -id-holdinstruction-reject OBJECT IDENTIFIER ::= - {holdInstruction 3} - --- invalidity date CRL entry extension OID and syntax - -id-ce-invalidityDate OBJECT IDENTIFIER ::= { id-ce 24 } - -InvalidityDate ::= GeneralizedTime - -END diff --git a/asn/rfc3852.e.asn b/asn/rfc3852.e.asn deleted file mode 100644 index 5caf366..0000000 --- a/asn/rfc3852.e.asn +++ /dev/null @@ -1,51 +0,0 @@ - AttributeCertificateVersion1 - { iso(1) member-body(2) us(840) rsadsi(113549) - pkcs(1) pkcs-9(9) smime(16) modules(0) v1AttrCert(15) } - - DEFINITIONS EXPLICIT TAGS ::= - BEGIN - - -- EXPORTS All - - -- fake imports - -- Imports from RFC 3280 [PROFILE], Appendix A.1 -AlgorithmIdentifier ::= ANY -Attribute ::= ANY -CertificateSerialNumber ::= INTEGER -Extensions ::= ANY -UniqueIdentifier ::= BIT STRING - - -- Imports from RFC 3280 [PROFILE], Appendix A.2 -GeneralNames ::= ANY - - -- Imports from RFC 3281 [ACPROFILE], Appendix B -AttCertValidityPeriod ::= ANY -IssuerSerial ::= ANY - - -- Definition extracted from X.509-1997 [X.509-97], but - -- different type names are used to avoid collisions. - - - AttributeCertificateV1 ::= SEQUENCE { - acInfo AttributeCertificateInfoV1, - signatureAlgorithm AlgorithmIdentifier, - signature BIT STRING } - - AttributeCertificateInfoV1 ::= SEQUENCE { - version AttCertVersionV1 DEFAULT v1, - subject CHOICE { - baseCertificateID [0] IssuerSerial, - -- associated with a Public Key Certificate - subjectName [1] GeneralNames }, - -- associated with a name - issuer GeneralNames, - signature AlgorithmIdentifier, - serialNumber CertificateSerialNumber, - attCertValidityPeriod AttCertValidityPeriod, - attributes SEQUENCE OF Attribute, - issuerUniqueID UniqueIdentifier OPTIONAL, - extensions Extensions OPTIONAL } - - AttCertVersionV1 ::= INTEGER { v1(0) } - - END -- of AttributeCertificateVersion1 diff --git a/asn/rfc3852.i.asn b/asn/rfc3852.i.asn deleted file mode 100644 index 6098c76..0000000 --- a/asn/rfc3852.i.asn +++ /dev/null @@ -1,333 +0,0 @@ - CryptographicMessageSyntax2004 - { iso(1) member-body(2) us(840) rsadsi(113549) - pkcs(1) pkcs-9(9) smime(16) modules(0) cms-2004(24) } - - DEFINITIONS IMPLICIT TAGS ::= - BEGIN - - -- EXPORTS All - -- The types and values defined in this module are exported for use - -- in the other ASN.1 modules. Other applications may use them for - -- their own purposes. - - -- fake imports - -- Imports from RFC 3280 [PROFILE], Appendix A.1 -AlgorithmIdentifier ::= ANY -Certificate ::= ANY -CertificateList ::= ANY -CertificateSerialNumber ::= INTEGER -Name ::= CHOICE { any ANY } - - -- Imports from RFC 3281 [ACPROFILE], Appendix B -AttributeCertificate ::= ANY - - -- Imports from Appendix B of this document -AttributeCertificateV1 ::= ANY - - -- Cryptographic Message Syntax - - ContentInfo ::= SEQUENCE { - contentType ContentType, - content [0] EXPLICIT ANY DEFINED BY contentType } - - ContentType ::= OBJECT IDENTIFIER - - - SignedData ::= SEQUENCE { - version CMSVersion, - digestAlgorithms DigestAlgorithmIdentifiers, - encapContentInfo EncapsulatedContentInfo, - certificates [0] IMPLICIT CertificateSet OPTIONAL, - crls [1] IMPLICIT RevocationInfoChoices OPTIONAL, - signerInfos SignerInfos } - - DigestAlgorithmIdentifiers ::= SET OF DigestAlgorithmIdentifier - - SignerInfos ::= SET OF SignerInfo - - EncapsulatedContentInfo ::= SEQUENCE { - eContentType ContentType, - eContent [0] EXPLICIT OCTET STRING OPTIONAL } - - SignerInfo ::= SEQUENCE { - version CMSVersion, - sid SignerIdentifier, - digestAlgorithm DigestAlgorithmIdentifier, - signedAttrs [0] IMPLICIT SignedAttributes OPTIONAL, - signatureAlgorithm SignatureAlgorithmIdentifier, - signature SignatureValue, - unsignedAttrs [1] IMPLICIT UnsignedAttributes OPTIONAL } - - SignerIdentifier ::= CHOICE { - issuerAndSerialNumber IssuerAndSerialNumber, - subjectKeyIdentifier [0] SubjectKeyIdentifier } - - SignedAttributes ::= SET SIZE (1..MAX) OF Attribute - - UnsignedAttributes ::= SET SIZE (1..MAX) OF Attribute - - Attribute ::= SEQUENCE { - attrType OBJECT IDENTIFIER, - attrValues SET OF AttributeValue } - - AttributeValue ::= ANY - - SignatureValue ::= OCTET STRING - - - - - - - - - EnvelopedData ::= SEQUENCE { - version CMSVersion, - originatorInfo [0] IMPLICIT OriginatorInfo OPTIONAL, - recipientInfos RecipientInfos, - encryptedContentInfo EncryptedContentInfo, - unprotectedAttrs [1] IMPLICIT UnprotectedAttributes OPTIONAL } - - OriginatorInfo ::= SEQUENCE { - certs [0] IMPLICIT CertificateSet OPTIONAL, - crls [1] IMPLICIT RevocationInfoChoices OPTIONAL } - - RecipientInfos ::= SET SIZE (1..MAX) OF RecipientInfo - - EncryptedContentInfo ::= SEQUENCE { - contentType ContentType, - contentEncryptionAlgorithm ContentEncryptionAlgorithmIdentifier, - encryptedContent [0] IMPLICIT EncryptedContent OPTIONAL } - - EncryptedContent ::= OCTET STRING - - UnprotectedAttributes ::= SET SIZE (1..MAX) OF Attribute - - RecipientInfo ::= CHOICE { - ktri KeyTransRecipientInfo, - kari [1] KeyAgreeRecipientInfo, - kekri [2] KEKRecipientInfo, - pwri [3] PasswordRecipientInfo, - ori [4] OtherRecipientInfo } - - EncryptedKey ::= OCTET STRING - - KeyTransRecipientInfo ::= SEQUENCE { - version CMSVersion, -- always set to 0 or 2 - rid RecipientIdentifier, - keyEncryptionAlgorithm KeyEncryptionAlgorithmIdentifier, - encryptedKey EncryptedKey } - - RecipientIdentifier ::= CHOICE { - issuerAndSerialNumber IssuerAndSerialNumber, - subjectKeyIdentifier [0] SubjectKeyIdentifier } - - KeyAgreeRecipientInfo ::= SEQUENCE { - version CMSVersion, -- always set to 3 - originator [0] EXPLICIT OriginatorIdentifierOrKey, - ukm [1] EXPLICIT UserKeyingMaterial OPTIONAL, - keyEncryptionAlgorithm KeyEncryptionAlgorithmIdentifier, - recipientEncryptedKeys RecipientEncryptedKeys } - - - OriginatorIdentifierOrKey ::= CHOICE { - issuerAndSerialNumber IssuerAndSerialNumber, - subjectKeyIdentifier [0] SubjectKeyIdentifier, - originatorKey [1] OriginatorPublicKey } - - OriginatorPublicKey ::= SEQUENCE { - algorithm AlgorithmIdentifier, - publicKey BIT STRING } - - RecipientEncryptedKeys ::= SEQUENCE OF RecipientEncryptedKey - - RecipientEncryptedKey ::= SEQUENCE { - rid KeyAgreeRecipientIdentifier, - encryptedKey EncryptedKey } - - KeyAgreeRecipientIdentifier ::= CHOICE { - issuerAndSerialNumber IssuerAndSerialNumber, - rKeyId [0] IMPLICIT RecipientKeyIdentifier } - - RecipientKeyIdentifier ::= SEQUENCE { - subjectKeyIdentifier SubjectKeyIdentifier, - date GeneralizedTime OPTIONAL, - other OtherKeyAttribute OPTIONAL } - - SubjectKeyIdentifier ::= OCTET STRING - - KEKRecipientInfo ::= SEQUENCE { - version CMSVersion, -- always set to 4 - kekid KEKIdentifier, - keyEncryptionAlgorithm KeyEncryptionAlgorithmIdentifier, - encryptedKey EncryptedKey } - - KEKIdentifier ::= SEQUENCE { - keyIdentifier OCTET STRING, - date GeneralizedTime OPTIONAL, - other OtherKeyAttribute OPTIONAL } - - PasswordRecipientInfo ::= SEQUENCE { - version CMSVersion, -- always set to 0 - keyDerivationAlgorithm [0] KeyDerivationAlgorithmIdentifier - OPTIONAL, - keyEncryptionAlgorithm KeyEncryptionAlgorithmIdentifier, - encryptedKey EncryptedKey } - - OtherRecipientInfo ::= SEQUENCE { - oriType OBJECT IDENTIFIER, - oriValue ANY DEFINED BY oriType } - - - DigestedData ::= SEQUENCE { - version CMSVersion, - digestAlgorithm DigestAlgorithmIdentifier, - encapContentInfo EncapsulatedContentInfo, - digest Digest } - - Digest ::= OCTET STRING - - EncryptedData ::= SEQUENCE { - version CMSVersion, - encryptedContentInfo EncryptedContentInfo, - unprotectedAttrs [1] IMPLICIT UnprotectedAttributes OPTIONAL } - - AuthenticatedData ::= SEQUENCE { - version CMSVersion, - originatorInfo [0] IMPLICIT OriginatorInfo OPTIONAL, - recipientInfos RecipientInfos, - macAlgorithm MessageAuthenticationCodeAlgorithm, - digestAlgorithm [1] DigestAlgorithmIdentifier OPTIONAL, - encapContentInfo EncapsulatedContentInfo, - authAttrs [2] IMPLICIT AuthAttributes OPTIONAL, - mac MessageAuthenticationCode, - unauthAttrs [3] IMPLICIT UnauthAttributes OPTIONAL } - - AuthAttributes ::= SET SIZE (1..MAX) OF Attribute - - UnauthAttributes ::= SET SIZE (1..MAX) OF Attribute - - MessageAuthenticationCode ::= OCTET STRING - - DigestAlgorithmIdentifier ::= AlgorithmIdentifier - - SignatureAlgorithmIdentifier ::= AlgorithmIdentifier - - KeyEncryptionAlgorithmIdentifier ::= AlgorithmIdentifier - - ContentEncryptionAlgorithmIdentifier ::= AlgorithmIdentifier - - MessageAuthenticationCodeAlgorithm ::= AlgorithmIdentifier - - KeyDerivationAlgorithmIdentifier ::= AlgorithmIdentifier - - RevocationInfoChoices ::= SET OF RevocationInfoChoice - - RevocationInfoChoice ::= CHOICE { - crl CertificateList, - other [1] IMPLICIT OtherRevocationInfoFormat } - - - OtherRevocationInfoFormat ::= SEQUENCE { - otherRevInfoFormat OBJECT IDENTIFIER, - otherRevInfo ANY DEFINED BY otherRevInfoFormat } - - CertificateChoices ::= CHOICE { - certificate Certificate, - extendedCertificate [0] IMPLICIT ExtendedCertificate, -- Obsolete - v1AttrCert [1] IMPLICIT AttributeCertificateV1, -- Obsolete - v2AttrCert [2] IMPLICIT AttributeCertificateV2, - other [3] IMPLICIT OtherCertificateFormat } - - AttributeCertificateV2 ::= AttributeCertificate - - OtherCertificateFormat ::= SEQUENCE { - otherCertFormat OBJECT IDENTIFIER, - otherCert ANY DEFINED BY otherCertFormat } - - CertificateSet ::= SET OF CertificateChoices - - IssuerAndSerialNumber ::= SEQUENCE { - issuer Name, - serialNumber CertificateSerialNumber } - - CMSVersion ::= INTEGER { v0(0), v1(1), v2(2), v3(3), v4(4), v5(5) } - - UserKeyingMaterial ::= OCTET STRING - - OtherKeyAttribute ::= SEQUENCE { - keyAttrId OBJECT IDENTIFIER, - keyAttr ANY DEFINED BY keyAttrId OPTIONAL } - - -- Content Type Object Identifiers - - id-ct-contentInfo OBJECT IDENTIFIER ::= { iso(1) member-body(2) - us(840) rsadsi(113549) pkcs(1) pkcs9(9) smime(16) ct(1) 6 } - - id-data OBJECT IDENTIFIER ::= { iso(1) member-body(2) - us(840) rsadsi(113549) pkcs(1) pkcs7(7) 1 } - - id-signedData OBJECT IDENTIFIER ::= { iso(1) member-body(2) - us(840) rsadsi(113549) pkcs(1) pkcs7(7) 2 } - - id-envelopedData OBJECT IDENTIFIER ::= { iso(1) member-body(2) - us(840) rsadsi(113549) pkcs(1) pkcs7(7) 3 } - - id-digestedData OBJECT IDENTIFIER ::= { iso(1) member-body(2) - us(840) rsadsi(113549) pkcs(1) pkcs7(7) 5 } - - - id-encryptedData OBJECT IDENTIFIER ::= { iso(1) member-body(2) - us(840) rsadsi(113549) pkcs(1) pkcs7(7) 6 } - - id-ct-authData OBJECT IDENTIFIER ::= { iso(1) member-body(2) - us(840) rsadsi(113549) pkcs(1) pkcs-9(9) smime(16) ct(1) 2 } - - -- The CMS Attributes - - MessageDigest ::= OCTET STRING - - SigningTime ::= Time - - Time ::= CHOICE { - utcTime UTCTime, - generalTime GeneralizedTime } - - Countersignature ::= SignerInfo - - -- Attribute Object Identifiers - - id-contentType OBJECT IDENTIFIER ::= { iso(1) member-body(2) - us(840) rsadsi(113549) pkcs(1) pkcs9(9) 3 } - - id-messageDigest OBJECT IDENTIFIER ::= { iso(1) member-body(2) - us(840) rsadsi(113549) pkcs(1) pkcs9(9) 4 } - - id-signingTime OBJECT IDENTIFIER ::= { iso(1) member-body(2) - us(840) rsadsi(113549) pkcs(1) pkcs9(9) 5 } - - id-countersignature OBJECT IDENTIFIER ::= { iso(1) member-body(2) - us(840) rsadsi(113549) pkcs(1) pkcs9(9) 6 } - - -- Obsolete Extended Certificate syntax from PKCS#6 - - ExtendedCertificateOrCertificate ::= CHOICE { - certificate Certificate, - extendedCertificate [0] IMPLICIT ExtendedCertificate } - - ExtendedCertificate ::= SEQUENCE { - extendedCertificateInfo ExtendedCertificateInfo, - signatureAlgorithm SignatureAlgorithmIdentifier, - signature Signature } - - - - ExtendedCertificateInfo ::= SEQUENCE { - version CMSVersion, - certificate Certificate, - attributes UnauthAttributes } - - Signature ::= BIT STRING - - END -- of CryptographicMessageSyntax2004 - diff --git a/asn/rfc4211.asn b/asn/rfc4211.asn deleted file mode 100644 index 8a118ac..0000000 --- a/asn/rfc4211.asn +++ /dev/null @@ -1,284 +0,0 @@ -PKIXCRMF-2005 {iso(1) identified-organization(3) dod(6) internet(1) -security(5) mechanisms(5) pkix(7) id-mod(0) id-mod-crmf2005(36)} - -DEFINITIONS IMPLICIT TAGS ::= -BEGIN - --- fake imports - - -- Directory Authentication Framework (X.509) -Version ::= INTEGER -AlgorithmIdentifier ::= ANY -Name ::= CHOICE { any ANY } -Time ::= CHOICE { any ANY } -SubjectPublicKeyInfo ::= ANY -Extensions ::= ANY -UniqueIdentifier ::= BIT STRING -Attribute ::= ANY - - -- Certificate Extensions (X.509) -GeneralName ::= CHOICE { any ANY } - - -- Cryptographic Message Syntax -EnvelopedData ::= ANY - --- The following definition may be uncommented for use with --- ASN.1 compilers that do not understand UTF8String. - --- UTF8String ::= [UNIVERSAL 12] IMPLICIT OCTET STRING - -- The contents of this type correspond to RFC 2279. - -id-pkix OBJECT IDENTIFIER ::= { iso(1) identified-organization(3) -dod(6) internet(1) security(5) mechanisms(5) 7 } - --- arc for Internet X.509 PKI protocols and their components - -id-pkip OBJECT IDENTIFIER ::= { id-pkix 5 } - -id-smime OBJECT IDENTIFIER ::= { iso(1) member-body(2) - us(840) rsadsi(113549) pkcs(1) pkcs9(9) 16 } - -id-ct OBJECT IDENTIFIER ::= { id-smime 1 } -- content types - --- Core definitions for this module - -CertReqMessages ::= SEQUENCE SIZE (1..MAX) OF CertReqMsg - -CertReqMsg ::= SEQUENCE { - certReq CertRequest, - popo ProofOfPossession OPTIONAL, - -- content depends upon key type - regInfo SEQUENCE SIZE(1..MAX) OF AttributeTypeAndValue OPTIONAL } - -CertRequest ::= SEQUENCE { - certReqId INTEGER, -- ID for matching request and reply - certTemplate CertTemplate, -- Selected fields of cert to be issued - controls Controls OPTIONAL } -- Attributes affecting issuance - -CertTemplate ::= SEQUENCE { - version [0] Version OPTIONAL, - serialNumber [1] INTEGER OPTIONAL, - signingAlg [2] AlgorithmIdentifier OPTIONAL, - issuer [3] Name OPTIONAL, - validity [4] OptionalValidity OPTIONAL, - subject [5] Name OPTIONAL, - publicKey [6] SubjectPublicKeyInfo OPTIONAL, - issuerUID [7] UniqueIdentifier OPTIONAL, - subjectUID [8] UniqueIdentifier OPTIONAL, - extensions [9] Extensions OPTIONAL } - -OptionalValidity ::= SEQUENCE { - notBefore [0] Time OPTIONAL, - notAfter [1] Time OPTIONAL } -- at least one MUST be present - -Controls ::= SEQUENCE SIZE(1..MAX) OF AttributeTypeAndValue -AttributeTypeAndValue ::= SEQUENCE { - type OBJECT IDENTIFIER, - value ANY DEFINED BY type } - -ProofOfPossession ::= CHOICE { - raVerified [0] NULL, - -- used if the RA has already verified that the requester is in - -- possession of the private key - signature [1] POPOSigningKey, - keyEncipherment [2] POPOPrivKey, - keyAgreement [3] POPOPrivKey } - -POPOSigningKey ::= SEQUENCE { - poposkInput [0] POPOSigningKeyInput OPTIONAL, - algorithmIdentifier AlgorithmIdentifier, - signature BIT STRING } - - -- The signature (using "algorithmIdentifier") is on the - -- DER-encoded value of poposkInput. NOTE: If the CertReqMsg - -- certReq CertTemplate contains the subject and publicKey values, - -- then poposkInput MUST be omitted and the signature MUST be - -- computed over the DER-encoded value of CertReqMsg certReq. If - -- the CertReqMsg certReq CertTemplate does not contain both the - -- public key and subject values (i.e., if it contains only one - -- of these, or neither), then poposkInput MUST be present and - -- MUST be signed. - - -POPOSigningKeyInput ::= SEQUENCE { - authInfo CHOICE { - sender [0] GeneralName, - -- used only if an authenticated identity has been - -- established for the sender (e.g., a DN from a - -- previously-issued and currently-valid certificate) - publicKeyMAC PKMACValue }, - -- used if no authenticated GeneralName currently exists for - -- the sender; publicKeyMAC contains a password-based MAC - -- on the DER-encoded value of publicKey - publicKey SubjectPublicKeyInfo } -- from CertTemplate - -PKMACValue ::= SEQUENCE { -algId AlgorithmIdentifier, --- algorithm value shall be PasswordBasedMac {1 2 840 113533 7 66 13} --- parameter value is PBMParameter -value BIT STRING } - -PBMParameter ::= SEQUENCE { - salt OCTET STRING, - owf AlgorithmIdentifier, - -- AlgId for a One-Way Function (SHA-1 recommended) - iterationCount INTEGER, - -- number of times the OWF is applied - mac AlgorithmIdentifier - -- the MAC AlgId (e.g., DES-MAC, Triple-DES-MAC [PKCS11], -} -- or HMAC [HMAC, RFC2202]) - -POPOPrivKey ::= CHOICE { - thisMessage [0] BIT STRING, -- Deprecated - -- possession is proven in this message (which contains the private - -- key itself (encrypted for the CA)) - subsequentMessage [1] SubsequentMessage, - -- possession will be proven in a subsequent message - dhMAC [2] BIT STRING, -- Deprecated - agreeMAC [3] PKMACValue, - encryptedKey [4] EnvelopedData } - - -- for keyAgreement (only), possession is proven in this message - -- (which contains a MAC (over the DER-encoded value of the - -- certReq parameter in CertReqMsg, which MUST include both subject - -- and publicKey) based on a key derived from the end entity's - -- private DH key and the CA's public DH key); - -SubsequentMessage ::= INTEGER { - encrCert (0), - -- requests that resulting certificate be encrypted for the - -- end entity (following which, POP will be proven in a - -- confirmation message) - challengeResp (1) } - -- requests that CA engage in challenge-response exchange with - -- end entity in order to prove private key possession - --- Object identifier assignments -- - --- Registration Controls in CRMF -id-regCtrl OBJECT IDENTIFIER ::= { id-pkip 1 } - - -id-regCtrl-regToken OBJECT IDENTIFIER ::= { id-regCtrl 1 } ---with syntax: -RegToken ::= UTF8String - -id-regCtrl-authenticator OBJECT IDENTIFIER ::= { id-regCtrl 2 } ---with syntax: -Authenticator ::= UTF8String - -id-regCtrl-pkiPublicationInfo OBJECT IDENTIFIER ::= { id-regCtrl 3 } ---with syntax: - -PKIPublicationInfo ::= SEQUENCE { -action INTEGER { - dontPublish (0), - pleasePublish (1) }, -pubInfos SEQUENCE SIZE (1..MAX) OF SinglePubInfo OPTIONAL } - -- pubInfos MUST NOT be present if action is "dontPublish" - -- (if action is "pleasePublish" and pubInfos is omitted, - -- "dontCare" is assumed) - -SinglePubInfo ::= SEQUENCE { - pubMethod INTEGER { - dontCare (0), - x500 (1), - web (2), - ldap (3) }, - pubLocation GeneralName OPTIONAL } - -id-regCtrl-pkiArchiveOptions OBJECT IDENTIFIER ::= { id-regCtrl 4 } ---with syntax: -PKIArchiveOptions ::= CHOICE { - encryptedPrivKey [0] EncryptedKey, - -- the actual value of the private key - keyGenParameters [1] KeyGenParameters, - -- parameters that allow the private key to be re-generated - archiveRemGenPrivKey [2] BOOLEAN } - -- set to TRUE if sender wishes receiver to archive the private - -- key of a key pair that the receiver generates in response to - -- this request; set to FALSE if no archival is desired. - -EncryptedKey ::= CHOICE { - encryptedValue EncryptedValue, -- Deprecated - envelopedData [0] EnvelopedData } - -- The encrypted private key MUST be placed in the envelopedData - -- encryptedContentInfo encryptedContent OCTET STRING. - -EncryptedValue ::= SEQUENCE { - intendedAlg [0] AlgorithmIdentifier OPTIONAL, - -- the intended algorithm for which the value will be used - symmAlg [1] AlgorithmIdentifier OPTIONAL, - -- the symmetric algorithm used to encrypt the value - encSymmKey [2] BIT STRING OPTIONAL, - -- the (encrypted) symmetric key used to encrypt the value - keyAlg [3] AlgorithmIdentifier OPTIONAL, - -- algorithm used to encrypt the symmetric key - valueHint [4] OCTET STRING OPTIONAL, - -- a brief description or identifier of the encValue content - -- (may be meaningful only to the sending entity, and used only - -- if EncryptedValue might be re-examined by the sending entity - -- in the future) - encValue BIT STRING } - -- the encrypted value itself --- When EncryptedValue is used to carry a private key (as opposed to --- a certificate), implementations MUST support the encValue field --- containing an encrypted PrivateKeyInfo as defined in [PKCS11], --- section 12.11. If encValue contains some other format/encoding --- for the private key, the first octet of valueHint MAY be used --- to indicate the format/encoding (but note that the possible values --- of this octet are not specified at this time). In all cases, the --- intendedAlg field MUST be used to indicate at least the OID of --- the intended algorithm of the private key, unless this information --- is known a priori to both sender and receiver by some other means. - -KeyGenParameters ::= OCTET STRING - -id-regCtrl-oldCertID OBJECT IDENTIFIER ::= { id-regCtrl 5 } ---with syntax: -OldCertId ::= CertId - -CertId ::= SEQUENCE { - issuer GeneralName, - serialNumber INTEGER } - -id-regCtrl-protocolEncrKey OBJECT IDENTIFIER ::= { id-regCtrl 6 } ---with syntax: -ProtocolEncrKey ::= SubjectPublicKeyInfo - --- Registration Info in CRMF -id-regInfo OBJECT IDENTIFIER ::= { id-pkip 2 } - -id-regInfo-utf8Pairs OBJECT IDENTIFIER ::= { id-regInfo 1 } ---with syntax -UTF8Pairs ::= UTF8String - - -id-regInfo-certReq OBJECT IDENTIFIER ::= { id-regInfo 2 } ---with syntax -CertReq ::= CertRequest - --- id-ct-encKeyWithID is a new content type used for CMS objects. --- it contains both a private key and an identifier for key escrow --- agents to check against recovery requestors. - -id-ct-encKeyWithID OBJECT IDENTIFIER ::= {id-ct 21} - -EncKeyWithID ::= SEQUENCE { - privateKey PrivateKeyInfo, - identifier CHOICE { - string UTF8String, - generalName GeneralName - } OPTIONAL -} - -PrivateKeyInfo ::= SEQUENCE { - version INTEGER, - privateKeyAlgorithm AlgorithmIdentifier, - privateKey OCTET STRING, - attributes [0] IMPLICIT Attributes OPTIONAL -} - -Attributes ::= SET OF Attribute - -END diff --git a/asn/rfc6402.asn b/asn/rfc6402.asn deleted file mode 100644 index c35b7b6..0000000 --- a/asn/rfc6402.asn +++ /dev/null @@ -1,425 +0,0 @@ - EnrollmentMessageSyntax-2011-v88 - { iso(1) identified-organization(3) dod(6) internet(1) - security(5) mechanisms(5) pkix(7) id-mod(0) - id-mod-enrollMsgSyntax-2011-88(76) } - - DEFINITIONS IMPLICIT TAGS ::= - BEGIN - - -- EXPORTS All -- - -- The types and values defined in this module are exported for use - -- in the other ASN.1 modules. Other applications may use them for - -- their own purposes. - --- fake imports - - -- PKIX Part 1 - Implicit From [RFC5280] -GeneralName ::= CHOICE { any ANY } -CRLReason ::= INTEGER -ReasonFlags ::= BIT STRING -GeneralNames ::= ANY - - -- PKIX Part 1 - Explicit From [RFC5280] -AlgorithmIdentifier ::= ANY -Extension ::= ANY -Name ::= CHOICE { any ANY } -CertificateSerialNumber ::= INTEGER - - -- Cryptographic Message Syntax FROM [CMS] -ContentInfo ::= ANY -Attribute ::= ANY -IssuerAndSerialNumber ::= ANY - - -- CRMF FROM [RFC4211] -CertReqMsg ::= ANY -PKIPublicationInfo ::= ANY -CertTemplate ::= ANY - - -- Global Types - -- UTF8String ::= [UNIVERSAL 12] IMPLICIT OCTET STRING - -- The content of this type conforms to RFC 3629. - - id-pkix OBJECT IDENTIFIER ::= { iso(1) identified-organization(3) - dod(6) internet(1) security(5) mechanisms(5) pkix(7) } -id-ad OBJECT IDENTIFIER ::= { id-pkix 48 } -id-kp OBJECT IDENTIFIER ::= { id-pkix 3 } - - id-cmc OBJECT IDENTIFIER ::= {id-pkix 7} -- CMC controls - id-cct OBJECT IDENTIFIER ::= {id-pkix 12} -- CMC content types - - -- The following controls have the type OCTET STRING - - id-cmc-identityProof OBJECT IDENTIFIER ::= {id-cmc 3} - id-cmc-dataReturn OBJECT IDENTIFIER ::= {id-cmc 4} - id-cmc-regInfo OBJECT IDENTIFIER ::= {id-cmc 18} - id-cmc-responseInfo OBJECT IDENTIFIER ::= {id-cmc 19} - id-cmc-queryPending OBJECT IDENTIFIER ::= {id-cmc 21} - id-cmc-popLinkRandom OBJECT IDENTIFIER ::= {id-cmc 22} - id-cmc-popLinkWitness OBJECT IDENTIFIER ::= {id-cmc 23} - - -- The following controls have the type UTF8String - - id-cmc-identification OBJECT IDENTIFIER ::= {id-cmc 2} - - -- The following controls have the type INTEGER - - id-cmc-transactionId OBJECT IDENTIFIER ::= {id-cmc 5} - - -- The following controls have the type OCTET STRING - - id-cmc-senderNonce OBJECT IDENTIFIER ::= {id-cmc 6} - id-cmc-recipientNonce OBJECT IDENTIFIER ::= {id-cmc 7} - - -- This is the content type used for a request message - -- in the protocol - - id-cct-PKIData OBJECT IDENTIFIER ::= { id-cct 2 } - - PKIData ::= SEQUENCE { - controlSequence SEQUENCE SIZE(0..MAX) OF TaggedAttribute, - reqSequence SEQUENCE SIZE(0..MAX) OF TaggedRequest, - cmsSequence SEQUENCE SIZE(0..MAX) OF TaggedContentInfo, - otherMsgSequence SEQUENCE SIZE(0..MAX) OF OtherMsg - } - - bodyIdMax INTEGER ::= 4294967295 - - BodyPartID ::= INTEGER(0..bodyIdMax) - - TaggedAttribute ::= SEQUENCE { - bodyPartID BodyPartID, - attrType OBJECT IDENTIFIER, - attrValues SET OF AttributeValue - } - - AttributeValue ::= ANY - - TaggedRequest ::= CHOICE { - tcr [0] TaggedCertificationRequest, - crm [1] CertReqMsg, - orm [2] SEQUENCE { - bodyPartID BodyPartID, - requestMessageType OBJECT IDENTIFIER, - requestMessageValue ANY DEFINED BY requestMessageType - } - } - - TaggedCertificationRequest ::= SEQUENCE { - bodyPartID BodyPartID, - certificationRequest CertificationRequest - } - - CertificationRequest ::= SEQUENCE { - certificationRequestInfo SEQUENCE { - version INTEGER, - subject Name, - subjectPublicKeyInfo SEQUENCE { - algorithm AlgorithmIdentifier, - subjectPublicKey BIT STRING }, - attributes [0] IMPLICIT SET OF Attribute }, - signatureAlgorithm AlgorithmIdentifier, - signature BIT STRING - } - - TaggedContentInfo ::= SEQUENCE { - bodyPartID BodyPartID, - contentInfo ContentInfo - } - - OtherMsg ::= SEQUENCE { - bodyPartID BodyPartID, - otherMsgType OBJECT IDENTIFIER, - otherMsgValue ANY DEFINED BY otherMsgType } - - -- This defines the response message in the protocol - id-cct-PKIResponse OBJECT IDENTIFIER ::= { id-cct 3 } - - - ResponseBody ::= PKIResponse - - PKIResponse ::= SEQUENCE { - controlSequence SEQUENCE SIZE(0..MAX) OF TaggedAttribute, - cmsSequence SEQUENCE SIZE(0..MAX) OF TaggedContentInfo, - otherMsgSequence SEQUENCE SIZE(0..MAX) OF OtherMsg - - } - - -- Used to return status state in a response - - id-cmc-statusInfo OBJECT IDENTIFIER ::= {id-cmc 1} - - CMCStatusInfo ::= SEQUENCE { - cMCStatus CMCStatus, - bodyList SEQUENCE SIZE (1..MAX) OF BodyPartID, - statusString UTF8String OPTIONAL, - otherInfo CHOICE { - failInfo CMCFailInfo, - pendInfo PendInfo } OPTIONAL - } - - PendInfo ::= SEQUENCE { - pendToken OCTET STRING, - pendTime GeneralizedTime - } - - CMCStatus ::= INTEGER { - success (0), - failed (2), - pending (3), - noSupport (4), - confirmRequired (5), - popRequired (6), - partial (7) - } - - - -- Note: - -- The spelling of unsupportedExt is corrected in this version. - -- In RFC 2797, it was unsuportedExt. - - CMCFailInfo ::= INTEGER { - badAlg (0), - badMessageCheck (1), - badRequest (2), - badTime (3), - badCertId (4), - unsupportedExt (5), - mustArchiveKeys (6), - badIdentity (7), - popRequired (8), - popFailed (9), - noKeyReuse (10), - internalCAError (11), - tryLater (12), - authDataFail (13) - } - - -- Used for RAs to add extensions to certification requests - id-cmc-addExtensions OBJECT IDENTIFIER ::= {id-cmc 8} - - AddExtensions ::= SEQUENCE { - pkiDataReference BodyPartID, - certReferences SEQUENCE OF BodyPartID, - extensions SEQUENCE OF Extension - } - - - id-cmc-encryptedPOP OBJECT IDENTIFIER ::= {id-cmc 9} - id-cmc-decryptedPOP OBJECT IDENTIFIER ::= {id-cmc 10} - - EncryptedPOP ::= SEQUENCE { - request TaggedRequest, - cms ContentInfo, - thePOPAlgID AlgorithmIdentifier, - witnessAlgID AlgorithmIdentifier, - witness OCTET STRING - } - - DecryptedPOP ::= SEQUENCE { - bodyPartID BodyPartID, - thePOPAlgID AlgorithmIdentifier, - thePOP OCTET STRING - } - - id-cmc-lraPOPWitness OBJECT IDENTIFIER ::= {id-cmc 11} - - LraPopWitness ::= SEQUENCE { - pkiDataBodyid BodyPartID, - bodyIds SEQUENCE OF BodyPartID - } - - -- - id-cmc-getCert OBJECT IDENTIFIER ::= {id-cmc 15} - - GetCert ::= SEQUENCE { - issuerName GeneralName, - serialNumber INTEGER } - - id-cmc-getCRL OBJECT IDENTIFIER ::= {id-cmc 16} - - GetCRL ::= SEQUENCE { - issuerName Name, - cRLName GeneralName OPTIONAL, - time GeneralizedTime OPTIONAL, - reasons ReasonFlags OPTIONAL } - - id-cmc-revokeRequest OBJECT IDENTIFIER ::= {id-cmc 17} - - RevokeRequest ::= SEQUENCE { - issuerName Name, - serialNumber INTEGER, - reason CRLReason, - invalidityDate GeneralizedTime OPTIONAL, - passphrase OCTET STRING OPTIONAL, - comment UTF8String OPTIONAL } - - id-cmc-confirmCertAcceptance OBJECT IDENTIFIER ::= {id-cmc 24} - - CMCCertId ::= IssuerAndSerialNumber - - -- The following is used to request V3 extensions be added to a - -- certificate - - id-ExtensionReq OBJECT IDENTIFIER ::= {iso(1) member-body(2) - us(840) rsadsi(113549) pkcs(1) pkcs-9(9) 14} - - ExtensionReq ::= SEQUENCE SIZE (1..MAX) OF Extension - - -- The following exists to allow Diffie-Hellman Certification - -- Request Messages to be well-formed - - id-alg-noSignature OBJECT IDENTIFIER ::= {id-pkix id-alg(6) 2} - - NoSignatureValue ::= OCTET STRING - - -- Unauthenticated attribute to carry removable data. - -- This could be used in an update of "CMC Extensions: Server - -- Side Key Generation and Key Escrow" (February 2005) and in - -- other documents. - - id-aa OBJECT IDENTIFIER ::= { iso(1) member-body(2) us(840) - rsadsi(113549) pkcs(1) pkcs-9(9) smime(16) id-aa(2)} - id-aa-cmc-unsignedData OBJECT IDENTIFIER ::= {id-aa 34} - - CMCUnsignedData ::= SEQUENCE { - bodyPartPath BodyPartPath, - identifier OBJECT IDENTIFIER, - content ANY DEFINED BY identifier - } - - -- Replaces CMC Status Info - -- - - id-cmc-statusInfoV2 OBJECT IDENTIFIER ::= {id-cmc 25} - - CMCStatusInfoV2 ::= SEQUENCE { - cMCStatus CMCStatus, - bodyList SEQUENCE SIZE (1..MAX) OF - BodyPartReference, - statusString UTF8String OPTIONAL, - otherInfo CHOICE { - failInfo CMCFailInfo, - pendInfo PendInfo, - extendedFailInfo SEQUENCE { - failInfoOID OBJECT IDENTIFIER, - failInfoValue AttributeValue - } - } OPTIONAL - } - - BodyPartReference ::= CHOICE { - bodyPartID BodyPartID, - bodyPartPath BodyPartPath - } - - BodyPartPath ::= SEQUENCE SIZE (1..MAX) OF BodyPartID - - -- Allow for distribution of trust anchors - -- - - id-cmc-trustedAnchors OBJECT IDENTIFIER ::= {id-cmc 26} - - PublishTrustAnchors ::= SEQUENCE { - seqNumber INTEGER, - hashAlgorithm AlgorithmIdentifier, - anchorHashes SEQUENCE OF OCTET STRING - } - - id-cmc-authData OBJECT IDENTIFIER ::= {id-cmc 27} - - AuthPublish ::= BodyPartID - - -- These two items use BodyPartList - id-cmc-batchRequests OBJECT IDENTIFIER ::= {id-cmc 28} - id-cmc-batchResponses OBJECT IDENTIFIER ::= {id-cmc 29} - - BodyPartList ::= SEQUENCE SIZE (1..MAX) OF BodyPartID - - -- - id-cmc-publishCert OBJECT IDENTIFIER ::= {id-cmc 30} - - CMCPublicationInfo ::= SEQUENCE { - hashAlg AlgorithmIdentifier, - certHashes SEQUENCE OF OCTET STRING, - pubInfo PKIPublicationInfo - } - - id-cmc-modCertTemplate OBJECT IDENTIFIER ::= {id-cmc 31} - - ModCertTemplate ::= SEQUENCE { - pkiDataReference BodyPartPath, - certReferences BodyPartList, - replace BOOLEAN DEFAULT TRUE, - certTemplate CertTemplate - } - - -- Inform follow-on servers that one or more controls have already - -- been processed - - id-cmc-controlProcessed OBJECT IDENTIFIER ::= {id-cmc 32} - - ControlsProcessed ::= SEQUENCE { - bodyList SEQUENCE SIZE(1..MAX) OF BodyPartReference - } - - -- Identity Proof control w/ algorithm agility - - id-cmc-identityProofV2 OBJECT IDENTIFIER ::= { id-cmc 34 } - - - - IdentifyProofV2 ::= SEQUENCE { - proofAlgID AlgorithmIdentifier, - macAlgId AlgorithmIdentifier, - witness OCTET STRING - } - - id-cmc-popLinkWitnessV2 OBJECT IDENTIFIER ::= { id-cmc 33 } - PopLinkWitnessV2 ::= SEQUENCE { - keyGenAlgorithm AlgorithmIdentifier, - macAlgorithm AlgorithmIdentifier, - witness OCTET STRING - } - - -- - - id-cmc-raIdentityWitness OBJECT IDENTIFIER ::= {id-cmc 35} - - - -- - -- Allow for an End-Entity to request a change in name. - -- This item is added to RegControlSet in CRMF. - -- - - id-cmc-changeSubjectName OBJECT IDENTIFIER ::= {id-cmc 36} - - ChangeSubjectName ::= SEQUENCE { - subject Name OPTIONAL, - subjectAlt GeneralNames OPTIONAL - } - -- (WITH COMPONENTS {..., subject PRESENT} | - -- WITH COMPONENTS {..., subjectAlt PRESENT} ) - - -- - -- Embedded response from a third party for processing - -- - - id-cmc-responseBody OBJECT IDENTIFIER ::= {id-cmc 37} - - -- - -- Key purpose identifiers are in the Extended Key Usage extension - -- - - id-kp-cmcCA OBJECT IDENTIFIER ::= { id-kp 27 } - id-kp-cmcRA OBJECT IDENTIFIER ::= { id-kp 28 } - id-kp-cmcArchive OBJECT IDENTIFIER ::= { id-kp 28 } - - - - -- - -- Subject Information Access identifier - -- - - id-ad-cmc OBJECT IDENTIFIER ::= { id-ad 12 } - - END diff --git a/bin/anchor b/bin/anchor deleted file mode 100755 index cb03733..0000000 --- a/bin/anchor +++ /dev/null @@ -1,43 +0,0 @@ -#!/bin/sh - -if [ "$1" = "-h" -o "$1" = "--help" ] ; then - echo "Usage: [PY=optional/path/python] $0" - echo - echo "Run Anchor with default uwsgi settings. It will spawn 4 workers" - echo "and use either the default reachable 'python' or one defined in the" - echo "\$PY variable." - echo - exit 0 -fi - -if ! which uwsgi > /dev/null ; then - echo "You need to install uwsgi to run anchor using this script." - exit 1 -fi - -PY=${PY:-python} - -if ! [ -x "$PY" ] ; then - if ! [ -x "$(which "$PY")" ] ; then - echo "Python interpreter not found (use PY variable to specify)." - exit 1 - fi -fi - -STR="import pkg_resources; print(pkg_resources.get_distribution('anchor').location)" -PKG_PATH=$("$PY" -c "$STR") - -if ! [ -d "$PKG_PATH" ] ; then - echo "Cannot find installed anchor package." - exit 1 -fi - -if [ -z "$VIRTUAL_ENV" ]; then - OPTS="-p 4" -else - OPTS="--venv ""${VIRTUAL_ENV}"" -p 4" -fi - -uwsgi --http-socket :5016 \ - --pecan "${PKG_PATH}/anchor/config.py" \ - ${OPTS} diff --git a/bin/anchor_debug b/bin/anchor_debug deleted file mode 100755 index 7963a81..0000000 --- a/bin/anchor_debug +++ /dev/null @@ -1,6 +0,0 @@ -#!/bin/sh -VENV=$1 - -[ -n "$VENV" ] || ( echo "provide virtual env path as parameter" && exit 1 ) - -"$VENV/bin/pecan" serve --reload config.py diff --git a/bin/container_bootstrap.py b/bin/container_bootstrap.py deleted file mode 100644 index 11c3268..0000000 --- a/bin/container_bootstrap.py +++ /dev/null @@ -1,67 +0,0 @@ -import os -import shutil - -from subprocess import call - -import logging - -logging.basicConfig() -logger = logging.getLogger('Anchor_Bootstrap') -logger.setLevel(logging.DEBUG) - -# This script looks for two mounted volumes '/key' and '/config'. They can -# contain key material and configuration files respectively. If data is found -# in either of these volumes it will be used to over-write the defaults within -# the Anchor container. -# In the case that '/key' is empty. This script will generate a new private key -# and copy that over the one to be used by Anchor. -# In the case that '/config' is empty no action will be taken - -# It's worth noting that the default location for key material can be modified -# in the config.json. That's really up to the deployer. - -# The reason we have a separate /key volume is to trigger a new key to be -# created even if we want to use a default configuration. - -newkey_newcert = ["openssl", "req", "-out", "CA/root-ca.crt", "-keyout", - "CA/root-ca-unwrapped.key", "-newkey", "rsa:4096", "-subj", - "/CN=Anchor Test CA", "-nodes", "-x509", "-days", "365"] - -newcert_existkey = ["openssl", "req", "-new" "-out", "CA/root-ca.crt", "-key", - "/key/root-ca-unwrapped.key", "-subj", "/CN=Anchor Test CA", - "-nodes", "-x509", "-days", "365"] - -# Anchor containers no longer build with built in keys. See if a deployer has -# provided a key, if they have, use that. If not then build one now. The key -# built in this way will disappear along with the container. -if os.path.exists('/key/root-ca-unwrapped.key'): - if os.path.exists('/key/root-ca.crt'): - # Provided both a key and a certificate - logger.info("Private key and certificate provided") - shutil.copy2('/key/root-ca-unwrapped.key', 'CA/') - shutil.copy2('/key/root-ca.crt', 'CA/') - os.chmod('CA/root-ca-unwrapped.key', 0400) - else: - # Provided key but no certificate - logger.info("Key provided without certificate. Generating certificate") - call(newcert_existingkey) - shutil.copy2('/key/root-ca-unwrapped.key', 'CA/') - os.chmod('CA/root-ca-unwrapped.key', 0400) -else: - logger.info("No key provided, Anchor will generate a dynamic one") - logger.info("To use a persistent key, create one and provide it in a key volume") - logger.info("Generating new key and certificate") - call(newkey_newcert) #No key or cert provided. Possibly no /key volume at all - os.chmod('CA/root-ca-unwrapped.key', 0400) - - -# If the user has provdided a config file in a /config volume, use that -#/config -if os.path.exists('/config/config.json'): - shutil.copy2('/config/config.json','./') - -if os.path.exists('/config/config.py'): - shutil.copy2('/config/config.py','./') - -#Start the pecan service -call(['pecan','serve','config.py']) diff --git a/certs/.empty b/certs/.empty deleted file mode 100644 index e69de29..0000000 diff --git a/config.json b/config.json deleted file mode 100644 index 38c5044..0000000 --- a/config.json +++ /dev/null @@ -1,36 +0,0 @@ -{ - "authentication": { - "method_1": { - "backend": "static", - "secret": "simplepassword", - "user": "myusername" - } - }, - "signing_ca": { - "local": { - "backend": "anchor", - "cert_path": "CA/root-ca.crt", - "key_path": "CA/root-ca-unwrapped.key", - "output_path": "certs", - "signing_hash": "sha256", - "valid_hours": 24 - } - }, - "registration_authority": { - "default": { - "authentication": "method_1", - "signing_ca": "local", - "validators": { - "standards_compliance": { - "label_re": "^[a-z](?:[-a-z0-9]*[a-z0-9])?$" - }, - "source_cidrs": { - "cidrs": ["127.0.0.0/8"] - } - } - } - }, - "audit": { - "target": "log" - } -} diff --git a/doc/source/api.rst b/doc/source/api.rst deleted file mode 100644 index ad3c538..0000000 --- a/doc/source/api.rst +++ /dev/null @@ -1,48 +0,0 @@ -API version 1 -============= - -The following endpoints are available in version 1 of the API. - -/robots.txt (GET) ------------------ - -Prevents attempts to index the service. - -/v1/sign/ (POST) ----------------------------------------- - -Requests signing of the CSR provided in the POST parameters. The request is -processed by the selected virtual registration authority. - -Request parameters -~~~~~~~~~~~~~~~~~~ - -* ``user``: username used in authentication (optional) -* ``secret``: secret used in authentication -* ``encoding``: request encoding - currently supported: "pem" -* ``csr``: the text of the submitted CSR - -Result -~~~~~~ - -Signed certificate - -/v1/ca/ (GET) ----------------------------------------- - -Requests the CA which would be used to sign the request made to this -registration authority. - -Do *NOT* use this to retrieve the certificate needed to trust communication -with Anchor. Connection to Anchor *MUST* be fully trusted before using this -endpoint for further configuration. - -Request parameters -~~~~~~~~~~~~~~~~~~ - -* ``encoding``: request encoding - currently supported: "pem" - -Result -~~~~~~ - -CA certificate used to sign for this RA. diff --git a/doc/source/audit.rst b/doc/source/audit.rst deleted file mode 100644 index 048b74f..0000000 --- a/doc/source/audit.rst +++ /dev/null @@ -1,27 +0,0 @@ -Audit -===== - -Anchor produces audit messages using the PyCADF library and aims for CADF -compatibility. The two events being emitted right now are ``audit.sign`` and -``audit.auth``, used for certificate signing and authentication events -respectively. - -In the configuration, audit events can be sent either to the log stream, or -to the standard openstack message queue. This is configured using the -``audit.target`` option. See the :doc:`configuration section ` -for more details. - -Capturing events in Ceilometer ------------------------------- - -In order to get events processed by Ceilometer, two configuration files need to -be provided - event pipeline and definitions. The default -``event_pipeline.yaml`` as described in Ceilometer documentation is compatible -with Anchor. As for ``event_definitions.yaml``, it needs to include the -``audit.auth`` and ``audit.sign`` events. - -On the Ceilometer side, it needs the `notification agent`_ installed in order -to receive data from the message queue. Add incoming events will then be saved -and visible after running ``ceilometer event-list``. - -.. _notification agent: http://docs.openstack.org/developer/ceilometer/architecture.html#notification-agents-listening-for-data diff --git a/doc/source/conf.py b/doc/source/conf.py deleted file mode 100644 index 86417f4..0000000 --- a/doc/source/conf.py +++ /dev/null @@ -1,258 +0,0 @@ -# -*- coding: utf-8 -*- -# -# Anchor documentation build configuration file, created by -# sphinx-quickstart on Wed Jul 29 15:52:08 2015. -# -# This file is execfile()d with the current directory set to its -# containing dir. -# -# Note that not all possible configuration values are present in this -# autogenerated file. -# -# All configuration values have a default; values that are commented out -# serve to show the default. - -import sys -import os - -# If extensions (or modules to document with autodoc) are in another directory, -# add these directories to sys.path here. If the directory is relative to the -# documentation root, use os.path.abspath to make it absolute, like shown here. -#sys.path.insert(0, os.path.abspath('.')) - -# -- General configuration ------------------------------------------------ - -# If your documentation needs a minimal Sphinx version, state it here. -#needs_sphinx = '1.0' - -# Add any Sphinx extension module names here, as strings. They can be -# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom -# ones. -extensions = [] - -# Add any paths that contain templates here, relative to this directory. -templates_path = ['_templates'] - -# The suffix of source filenames. -source_suffix = '.rst' - -# The encoding of source files. -#source_encoding = 'utf-8-sig' - -# The master toctree document. -master_doc = 'index' - -# General information about the project. -project = u'Anchor' -copyright = u'2015' - -# The version info for the project you're documenting, acts as replacement for -# |version| and |release|, also used in various other places throughout the -# built documents. -# -# The short X.Y version. -version = 'dev' -# The full version, including alpha/beta/rc tags. -release = 'dev' - -# The language for content autogenerated by Sphinx. Refer to documentation -# for a list of supported languages. -#language = None - -# There are two options for replacing |today|: either, you set today to some -# non-false value, then it is used: -#today = '' -# Else, today_fmt is used as the format for a strftime call. -#today_fmt = '%B %d, %Y' - -# List of patterns, relative to source directory, that match files and -# directories to ignore when looking for source files. -exclude_patterns = ['_build'] - -# The reST default role (used for this markup: `text`) to use for all -# documents. -#default_role = None - -# If true, '()' will be appended to :func: etc. cross-reference text. -#add_function_parentheses = True - -# If true, the current module name will be prepended to all description -# unit titles (such as .. function::). -#add_module_names = True - -# If true, sectionauthor and moduleauthor directives will be shown in the -# output. They are ignored by default. -#show_authors = False - -# The name of the Pygments (syntax highlighting) style to use. -pygments_style = 'sphinx' - -# A list of ignored prefixes for module index sorting. -#modindex_common_prefix = [] - -# If true, keep warnings as "system message" paragraphs in the built documents. -#keep_warnings = False - - -# -- Options for HTML output ---------------------------------------------- - -# The theme to use for HTML and HTML Help pages. See the documentation for -# a list of builtin themes. -#html_theme = 'alabaster' - -# Theme options are theme-specific and customize the look and feel of a theme -# further. For a list of options available for each theme, see the -# documentation. -html_theme_options = {} - -# Add any paths that contain custom themes here, relative to this directory. -#html_theme_path = [] - -# The name for this set of Sphinx documents. If None, it defaults to -# " v documentation". -#html_title = None - -# A shorter title for the navigation bar. Default is the same as html_title. -#html_short_title = None - -# The name of an image file (relative to this directory) to place at the top -# of the sidebar. -#html_logo = None - -# The name of an image file (within the static path) to use as favicon of the -# docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32 -# pixels large. -#html_favicon = None - -# Add any paths that contain custom static files (such as style sheets) here, -# relative to this directory. They are copied after the builtin static files, -# so a file named "default.css" will overwrite the builtin "default.css". -#html_static_path = ['_static'] - -# Add any extra paths that contain custom files (such as robots.txt or -# .htaccess) here, relative to this directory. These files are copied -# directly to the root of the documentation. -#html_extra_path = [] - -# If not '', a 'Last updated on:' timestamp is inserted at every page bottom, -# using the given strftime format. -#html_last_updated_fmt = '%b %d, %Y' - -# If true, SmartyPants will be used to convert quotes and dashes to -# typographically correct entities. -#html_use_smartypants = True - -# Custom sidebar templates, maps document names to template names. -#html_sidebars = {} - -# Additional templates that should be rendered to pages, maps page names to -# template names. -#html_additional_pages = {} - -# If false, no module index is generated. -#html_domain_indices = True - -# If false, no index is generated. -#html_use_index = True - -# If true, the index is split into individual pages for each letter. -#html_split_index = False - -# If true, links to the reST sources are added to the pages. -#html_show_sourcelink = True - -# If true, "Created using Sphinx" is shown in the HTML footer. Default is True. -#html_show_sphinx = True - -# If true, "(C) Copyright ..." is shown in the HTML footer. Default is True. -#html_show_copyright = True - -# If true, an OpenSearch description file will be output, and all pages will -# contain a tag referring to it. The value of this option must be the -# base URL from which the finished HTML is served. -#html_use_opensearch = '' - -# This is the file name suffix for HTML files (e.g. ".xhtml"). -#html_file_suffix = None - -# Output file base name for HTML help builder. -htmlhelp_basename = 'Anchordoc' - - -# -- Options for LaTeX output --------------------------------------------- - -latex_elements = { -# The paper size ('letterpaper' or 'a4paper'). -#'papersize': 'letterpaper', - -# The font size ('10pt', '11pt' or '12pt'). -#'pointsize': '10pt', - -# Additional stuff for the LaTeX preamble. -#'preamble': '', -} - -# Grouping the document tree into LaTeX files. List of tuples -# (source start file, target name, title, -# author, documentclass [howto, manual, or own class]). -latex_documents = [ - ('index', 'Anchor.tex', u'Anchor Documentation', - u'see git log', 'manual'), -] - -# The name of an image file (relative to this directory) to place at the top of -# the title page. -#latex_logo = None - -# For "manual" documents, if this is true, then toplevel headings are parts, -# not chapters. -#latex_use_parts = False - -# If true, show page references after internal links. -#latex_show_pagerefs = False - -# If true, show URL addresses after external links. -#latex_show_urls = False - -# Documents to append as an appendix to all manuals. -#latex_appendices = [] - -# If false, no module index is generated. -#latex_domain_indices = True - - -# -- Options for manual page output --------------------------------------- - -# One entry per manual page. List of tuples -# (source start file, name, description, authors, manual section). -man_pages = [ - ('index', 'anchor', u'Anchor Documentation', - [u'see git log'], 1) -] - -# If true, show URL addresses after external links. -#man_show_urls = False - - -# -- Options for Texinfo output ------------------------------------------- - -# Grouping the document tree into Texinfo files. List of tuples -# (source start file, target name, title, author, -# dir menu entry, description, category) -texinfo_documents = [ - ('index', 'Anchor', u'Anchor Documentation', - u'see git log', 'Anchor', 'One line description of project.', - 'Miscellaneous'), -] - -# Documents to append as an appendix to all manuals. -#texinfo_appendices = [] - -# If false, no module index is generated. -#texinfo_domain_indices = True - -# How to display URL addresses: 'footnote', 'no', or 'inline'. -#texinfo_show_urls = 'footnote' - -# If true, do not generate a @detailmenu in the "Top" node's menu. -#texinfo_no_detailmenu = False diff --git a/doc/source/configuration.rst b/doc/source/configuration.rst deleted file mode 100644 index dcedd6c..0000000 --- a/doc/source/configuration.rst +++ /dev/null @@ -1,240 +0,0 @@ -Configuration files -=================== - -Anchor is configured using two files: ``config.py`` and ``config.json``. The -first one defines the Python and webservice related values. You can change the -listening iterface address and port there, as well as logging details to suit -your deployment. The second configuration defines the service behaviour at -runtime. - -There are three main sections at the moment: ``authentication`` for -authentication parameters, ``signing_ca`` for defining signing authorities, and -``registration_authority`` for listing virtual registration authorities which -can be selected by client requests. - -The main ``config.json`` structure looks like this: - -.. code:: json - - { - "authentication": { ... }, - "signing_ca": { ... }, - "registration_authority": { ... } - } - -Each block apart from ``registration_authority`` defines a number of mapping -from labels to definitions. Those labels can then be used in the -``registration_authority`` block to refer to settings defined earlier. - -Authentication --------------- - -The authentication block can define any number of authentication blocks, each -using one specific authentication backend. - -Currently available authentication methods are: ``static``, ``keystone``, and -``ldap``. - -Static -~~~~~~ - -Username and password are present in ``config.json``. This mode should be used -only for development and testing. - -.. code:: json - - { - "authentication": { - "method_1": { - "backend": "static", - "secret": "simplepassword", - "user": "myusername" - } - } - } - -Keystone -~~~~~~~~ - -Username is ignored, but password is a token valid in the configured keystone -location. - -.. code:: json - - { - "authentication": { - "method_2": { - "backend": "keystone", - "url": "https://keystone.example.com" - } - } - } - -LDAP -~~~~ - -Username and password are used to bind to an LDAP user in a configured domain. -User's groups for the ``server_group`` filter are retrieved from attribute -``memberOf`` in search for ``(sAMAccountName=username@domain)``. The search is done -in the configured base. - -.. code:: json - - { - "authentication": { - "method_3": { - "backend": "ldap", - "host": "ldap.example.com", - "base": "ou=Users,dc=example,dc=com", - "domain": "example.com", - "port": 636, - "ssl": true - } - } - } - - -Signing authority ------------------ - -The ``signing_ca`` section defines any number of signing authorities which can -be referenced later on. Currently there's only one, default implementation -which uses local files. An example configuration looks like this. - -.. code:: json - - { - "signing_ca": { - "local": { - "backend": "anchor", - "cert_path": "CA/root-ca.crt", - "key_path": "CA/root-ca-unwrapped.key", - "output_path": "certs", - "signing_hash": "sha256", - "valid_hours": 24 - } - } - } - -Anchor allows the use of configurable signing backend. While it provides a -default implementation (based on cryptography.io and OpenSSL), other -implementations may be configured. The backend is configured by setting the -``backend`` value to the name of the right entry point. Backend implementations -need to provide only one function: ``sign(csr, config)``, taking the parsed CSR -and their own ``singing_ca`` block of the configuration as parameters and -returning signed certificate in PEM format. - -The backends are loaded using the ``stevedore`` module from the registered -entry points. The name space is ``anchor.signing_backends``. - -Each backend may take different configuration options. Please refer to -:doc:`signing backends section `. - - -Virtual registration authority ------------------------------- - -The registration authority section puts together previously described elements -and the list of validators applied to each request. - -.. code:: json - - { - "registration_authority": { - "default": { - "authentication": "method_1", - "signing_ca": "local", - "validators": { - "ca_status": { - "ca_requested": false - }, - "source_cidrs": { - "cidrs": [ "127.0.0.0/8" ] - } - }, - "fixups": { - } - } - } - } - -In the example above, CSRs sent to registration authority ``default`` will be -authenticated using previously defined block ``method_1``, will be validated -against two validators (``ca_status`` and ``source_cidrs``) and if they pass, -the CSR will be signed by the previously defined signing ca called ``local``. - -Each validator has its own set of parameters described separately in the -:doc:`validators section `. Same for fixups described in -:doc:`fixups section ` - - -Audit ------ - -Audit has two possible targets: ``log`` for output in the standard logging -stream and ``messaging`` for the openstack message queue. The first one doesn't -require any extra options: - -.. code:: json - - { - "audit": { - "target": "log" - } - } - -The message queue version requires defining a target in a way compatible with -``oslo_messaging`` `transport URIs`_. For example: - -.. code:: json - - { - "audit": { - "target": "messaging", - "url": "rabbit:guest@localhost:5672" - } - } - -Example configuration ---------------------- - -.. code:: json - - { - "authentication": { - "method_1": { - "backend": "static", - "secret": "simplepassword", - "user": "myusername" - } - }, - - "signing_ca": { - "local": { - "cert_path": "CA/root-ca.crt", - "key_path": "CA/root-ca-unwrapped.key", - "output_path": "certs", - "signing_hash": "sha256", - "valid_hours": 24 - } - }, - - "registration_authority": { - "default": { - "authentication": "method_1", - "signing_ca": "local", - "validators": { - "ca_status": { - "ca_requested": false - }, - "source_cidrs": { - "cidrs": [ "127.0.0.0/8" ] - } - }, - "fixups": { - } - } - } - } - -.. _transport URIs: https://wiki.openstack.org/wiki/Oslo/Messaging#Transports diff --git a/doc/source/ephemeralPKI.rst b/doc/source/ephemeralPKI.rst deleted file mode 100644 index 90ff310..0000000 --- a/doc/source/ephemeralPKI.rst +++ /dev/null @@ -1,129 +0,0 @@ -Ephemeral PKI -============= - -Anchor is a Certificate and Registration Authority built to provide ephemeral -PKI services for large scale infrastructure deployments such as OpenStack. It -exists to solve two problems that typically affect PKI deployments but that -often go ignored by users; securely provision certificates in live environments -is incredibly difficult and effectively revoking bad certificates is nearly -impossible with the cryptographic libraries that are available to handle PKI -operations today. - -Traditional Provisioning ------------------------- -One of the challenges for managing PKI in large infrastructures is ensuring -that certificates are provisioned securely and effectively. In traditional PKI -a certificate signing request (CSR) would be created by a user who requires a -certificate for some service that they are managing. The user would then -typically submit that CSR to whatever corporate PKI system is in use, likely -Dogtag_ or Active Directory Certificate Services (ADCS_). That submission would -then trigger a process of verification that often includes a PKI administrator -manually inspecting that the various fields within the CSR and approving the -issuing of a certificate. When the certificate is issued the original requestor -needs to be notified, often by way of email - the requestor then accesses the -CA and retrieves their newly signed certificate. - -.. _Dogtag: http://pki.fedoraproject.org/wiki/PKI_Main_Page -.. _ADCS: https://technet.microsoft.com/en-us/windowsserver/dd448615.aspx - -This heavily manual process is fraught with opportunities for human error and -tends to scale very poorly. This workflow may have sufficed for managing the -certificates that an organization might want to provision at it's edge but it -cannot cope with the massive number of certificates required for running large -data centers. - -Methods for automatically issuing certificates such as SCEP and ADCS -auto-enrollment exist to help solve this problem but often require significant -architectural changes to use them securely. For example, SCEP requires a -secure network to work (in most cases, if such a network already exists then -certificates would not be necessary) so it is typically only used when -infrastructure is provisioned - before being moved into production. ADCS -auto-enrollment requires all of your servers to be running on Microsoft -Windows, which is often not the case for large scale cloud-type environments. - -Anchor provides an alternative mechanism for provisioning certificates that -allows each server in a cluster to request its own certificate while -enforcing strong issuing policies that introduce capabilities beyond those that -can be leveraged by the manual process described above - and it can do it at -large scale. - -Anchor Provisioning -------------------- -Anchor expects that a machine which requires a certificate will request it -directly, rather than some user requesting it and then installing it on the -machine. This requires the machine to somehow track existing certificates and -request new ones when they expire. There are many ways to approach this and -often a simple cron.d bash script will suffice. The Cathead_ and Certmonger_ -projects both exist to help with system based certificate management but only -Cathead natively supports Anchor, however Certmonger can be modified to work -with Anchor if required. - -.. _Cathead: https://github.com/stackforge/cathead -.. _Certmonger: https://fedorahosted.org/certmonger/ - -Anchor provides multiple ways for machines to authenticate. The currently -supported options are LDAP, Keystone and a pre-shared Username/Password -combination. As every machine in a data centre can potentially have it's own -set of credentials Anchor can make very fine grained decisions regarding which -machines should be trusted at any given time. There's more information on -Anchor authentication in the :doc:`configuration` section. - -Along with fine grained access control Anchor, supports various -:doc:`validators` that can be used by PKI administrators to set tight policy -constraints on what is allowed within a certificate. These validators provide a -powerful construct for programmatically verifying that a certificate meets -policy requirements for a particular environment. - -Traditional Revocation ----------------------- -Certificates can require revocation for a number of reasons, they may no longer -be required, they may have been incorrectly issued or the private key for a -certificate may have been compromised. - -There are two methods that exist for revoking certificates; Certificate -Revocation Lists (CRL_) and the Online Certificate Status Protocol (OCSP_). -Unfortunately neither system is particularly robust when attempting to use them -within dynamic, large scale environments. CRLs are updated only periodically -and have significant scale issues when used within systems that change -certificates regularly. OCSP was created to address a number of the issues that -hinder CRLs but unfortunately is very poorly supported in cryptographic -libraries outside of web-browser software. Using OCSP incurs some -infrastructure overhead because it needs to maintain a level of availability -that normally requires it to be load balanced to ensure that a responder is -always available, not receiving an OCSP response will cause a client to not -trust a certificate. - -.. _CRL: https://www.ietf.org/rfc/rfc5280.txt -.. _OCSP: https://tools.ietf.org/html/rfc6960 - -To recap; CRLs do not work terribly well in large scale, dynamic environments -where multiple certificates might be required in a machine's lifetime as it is -repurposed. OCSP doesn't work outside of web browsers and is of little value -as a revocation system for large scale infrastructure. - -Passive Revocation ------------------- -During our testing of TLS client libraries it became obvious that OCSP was -poorly supported and that CRLs weren't reliable enough to provide strong -assurance that certificates would be revoked when required. We did observe that -expired certificates were correctly handled in the most common TLS libraries. -Anchor leverages expiry dates and issues very short lifetime certificates, -typically certificates will be issued with an expiry date set just 12-24 hours -into the future. - -Rather than attempting to actively revoke a certificate in the tradition sense, -Anchor will refuse to re-issue a certificate to a bad machine or user. The -assumption being that a change in policy, or modification to the authentication -platform is all that is required to ensure that a bad actor cannot gain access -to certificates. We refer to this process as "Passive Revocation". - -When using passive revocation one accepts that there is a certain window of -compromise when a "bad" certificate may still be used within the system. -Although this may seem like a sub-optimal way to handle revocation it actually -results in better performance than more traditional revocation techniques. As -discussed earlier, CRLs can be unreliable and OCSP is generally not supported -outside of web browsers. However, even if it were, the passive revocation -window typically employed by Anchor will be shorter than the OCSP cached -response when using an OCSP responder. This means that in most typical -configurations, using Anchor will result in more reliable and timely -certificate revocation than any other mechanism available today. diff --git a/doc/source/extensions.rst b/doc/source/extensions.rst deleted file mode 100644 index 7f6bdf5..0000000 --- a/doc/source/extensions.rst +++ /dev/null @@ -1,42 +0,0 @@ -Extension support -================= - -Extensions in Anchor are supported on 3 levels: - -* CSR parser (deciding what OIDs are recognised and the what is the interface - to extensions) -* validators / fixups which operate on extensions -* signing backends which operate on extensions - -Anchor needs to parse the extension to use it in a validator or a fixup. That's -not the case of the signing backends however - external backends may add/update -extensions according to their own configuration. - -Anchor can parse and analyse the following extensions: - -* Basic Constraints -* Key Usage -* Extended Key Usage -* Name Constraints -* Subject Alternative Name - -The following extensions are listed as required or preferred, but due to -Anchor's main purpose (ephemeral certificates) they will be either ignored (if -they're not critical), or will prevent signing (if they are): - -* Certificate Policies -* Policy Mappings -* Inhibit anyPolicy -* CRL Distribution Points -* Freshest CRL - -Other extensions will be added to the implementation when they're needed for -validation / fixups. - -Extension limitations -===================== -Due to how Anchor relies on short-term certificates, issuing a CA certificate -from Anchor doesn't really make sense. Certificates which do have a CA flag set -will be rejected unconditionally. - -Key usage related to CA status will be treated in a similar way. diff --git a/doc/source/fixups.rst b/doc/source/fixups.rst deleted file mode 100644 index 1bd4863..0000000 --- a/doc/source/fixups.rst +++ /dev/null @@ -1,19 +0,0 @@ -Fixups -====== - -Fixups can be used to modify submitted CSRs before signing. That means for -example adding extra name elements, or extensions. Each fixup is loaded from -the "anchor.fixups" namespace using stevedore and gets access to the parsed CSR -and the configuration. - -Unlike validators, each fixup has to return either a new CSR structure or the -modified original. - -Included fixups ---------------- - -``enforce_alternative_names_present`` - No parameters. - - If the value from CN does not exist in subject alternative names, it will - be copied into either then DNS or IP field, depending on the format. diff --git a/doc/source/index.rst b/doc/source/index.rst deleted file mode 100644 index 0039774..0000000 --- a/doc/source/index.rst +++ /dev/null @@ -1,29 +0,0 @@ -Welcome to Anchor! -================================== - -Anchor is an ephemeral PKI service that, based on certain conditions, -automates the verification of CSRs and signs certificates for clients. -The validity period can be set in the config file with hour resolution. - - - -Contents: - -.. toctree:: - :maxdepth: 2 - - configuration - api - extensions - signing_backends - ephemeralPKI - validators - fixups - audit - - -Indices and tables -================== - -* :ref:`genindex` -* :ref:`search` diff --git a/doc/source/signing_backends.rst b/doc/source/signing_backends.rst deleted file mode 100644 index ba0e16e..0000000 --- a/doc/source/signing_backends.rst +++ /dev/null @@ -1,117 +0,0 @@ -Signing backends -================ - -Each signing backend must be registered using an entry point. They're loaded -using the ``stevedore`` module, however this should not affect the calling -behaviour. - -The signing CA configuration block allows the following common options: - -* ``backend``: name of the requested backend ("anchor" not defined) -* ``output_path``: local path where anchor saves the issued certificates - (optional, output not saved if not defined) - -Anchor provides the following backends out of the box: - -anchor ------- - -The default signing backend. It doesn't have any external service dependencies -and all signing happens inside of the Anchor process. - -This backend will ignore all non-critical extensions which are not understood -by Anchor and will reject CSRs with unknown critical extensions. - -A sample configuration for the ``signing_ca`` block looks like this: - -.. code:: json - - { - "local": { - "backend": "anchor", - "cert_path": "CA/root-ca.crt", - "key_path": "CA/root-ca-unwrapped.key", - "output_path": "certs", - "signing_hash": "sha256", - "valid_hours": 24 - } - } - -Valid options for this backend are: - -* ``cert_path``: path to the signing CA certificate -* ``key_path``: path to the matching key -* ``signing_hash``: hash to use when signing the issued certificate ("md5", - "sha1", "sha224, "sha256" are valid options) -* ``valid_hours``: validity period for the issued certificates, defined in - hours - -pkcs11 ------- - -This backend uses a provided pkcs11 library for the signing operation. The -final certificate is created in the same way as with `anchor` backend with -regards to extensions and fixups. - -The interface doesn't rely on any special functionality of the store. Only the -RSA private key needs to be available as a secret. The only used mechanism is -CKM_RSA_PKCS. That means any pkcs11 backend from gnome keyring to tpm and -external HSMs should work. - -This backend requires ``PyKCS11`` package to be installed. - -A sample configuration for the ``signing_ca`` block looks like this: - -.. code:: json - - { - "local": { - "backend": "pkcs11", - "cert_path": "CA/root-ca.crt", - "output_path": "certs", - "signing_hash": "sha256", - "valid_hours": 24, - "slot": 18, - "pin": "the_pin", - "key_id": "b22f6e84a7b29db389b57a24384b95cca0bb4bc0", - "pkcs11_path": "/usr/lib/.../pkcs11/...-pkcs11.so" - } - } - -Valid options for this backend are: - -* ``cert_path``: path to the signing CA certificate -* ``signing_hash``: hash to use when signing the issued certificate ("sha224, - "sha256", "sha384", "sha512" are valid options) -* ``valid_hours``: validity period for the issued certificates, defined in - hours -* ``slot``: slot number where the key can be found -* ``pin``: text version of the pin required to access the right slot -* ``key_id``: key id written as a hex string -* ``pkcs11_path``: path to the dynamic library compatible with pkcs11 interface - -Backend development -------------------- - -Backends are simple functions which need to take 2 parameters: the CSR in PEM -format and the configuration block contents. Configuration can contain any keys -required by the backend. - -The return value must be a signed certificate in PEM format, however in most -cases it's enough to implement the actual hash signing part and rely on -``anchor.signer.sign_generic`` framework. The backend may either throw a -specific ``WebOb`` HTTP exception, or SigningError exception which will result -in a 500 response. - -For security, http exceptions from the signing backend should not expose any -specific information about the reason for failure. Internal exceptions are -preferred for this reason and their details will be logged in Anchor. - -The backend must not rely on the received CSR signature. If any modifications -are applied to the submitted CSR in Anchor, they will invalidate the signature. -Unless the backend is intended to work only with validators, and not any fixup -operations in the future, the signature field should be ignored and the request -treated as already correct/verified. - -Configuration is verified using the function provided using the -``@signers.config_validator(f)`` decorator. diff --git a/doc/source/validators.rst b/doc/source/validators.rst deleted file mode 100644 index 1c895b2..0000000 --- a/doc/source/validators.rst +++ /dev/null @@ -1,184 +0,0 @@ -Validators -========== - -Currently validators can check three things: the CSR, the incoming connection, -and the authentication. The resulting action can be only pass or fail. -Validators are configured in the ``config.json`` file and each one comes with -different options. - -Included validators -------------------- - -The following validators are implemented at the moment: - -``standards_compliance`` - Verifies: CSR. - - Ensures that the CSR does not break any rules defined in the standards - documents (mostly RFC5280). Specific checks may be added over time in new - versions of Anchor. This validator should be only skipped if there's a - known compatibility issue. Otherwise it should be used in all environments. - Any requests produced using standard tooling that fail this check should be - reported as Anchor issues. - - Parameters: - - - ``label_re``: pattern for acceptable domain label format - -``whitelist_names`` - Verifies: CSR. Parameters: - - - ``names``: list of names/ips/ip ranges allowed in various fields - - ``allow_cn_id``: allow name in subject CN - - ``allow_dns_id``: allow name in SAN dns entry - - ``allow_ip_id``: allow name in SAN IP entry - - ``allow_wildcard``: allow wildcard certificate to match '%' - - IDs available in various places in the certificate are matched against the - patterns in the ``names`` list. These can be: - - - IP addresses: ``1.2.3.4`` - - IP ranges: ``1.2.3.0/24`` - - complete names: ``some.example.com`` - - names with wildcards: ``%.example.com``, ``partial-%.example.com`` - - Wildcard (``%``) rules: It matches only a single name label, or part of - one. It can be used only in domain names, not IPs. Only one wildcard is - allowed in a label, but multiple in a name, so ``%.%.example.com`` is - valid. - - Pattern wildcard (``%``) may match a domain wildcard character (``*``) - only if ``allow_wildcard`` is set to true. - - This match will fail if the CSR contains any SAN type not included here. - -``blacklist_names`` - Verifies: CSR. Parameters: ``allowed_domains``, ``allowed_networks``. - - Ensures that the CN and subject alternative names do not contain anything - configured in the ``domains``. - -``common_name`` - Verifies: CSR. Parameters: ``allowed_domains``, ``allowed_networks``. - - Ensures that the CN matches one of names in ``allowed_domains`` or IP - ranges in ``allowed_networks``. - - Deprecated: use ``whitelist_names`` / ``blacklist_names`` instead. - -``alternative_names`` - Verifies: CSR. Parameters: ``allowed_domains``. - - Ensures that names specified in the subject alternative names extension - match one of the names in ``allowed_domains``. - - Deprecated: use ``whitelist_names`` / ``blacklist_names`` instead. - -``alternative_names_ip`` - Verifies: CSR. Parameters: ``allowed_domains``, ``allowed_networks``. - - Ensures that names specified in the subject alternative names extension - match one of the names in ``allowed_domains`` or IP ranges in - ``allowed_networks``. - - Deprecated: use ``whitelist_names`` / ``blacklist_names`` instead. - -``server_group`` - Verifies: Auth, CSR. Parameters: ``group_prefixes``. - - Ensures the requester is authorised to get a certificate for a given - server. This is currently assuming specific server naming scheme which - looks like ``{prefix}-{name}.{domain}``. For example if the prefixes are - defined as ``{"Nova": "nv"}``, and the client authentication returns group - "Nova", then a request for ``nv-compute1.domain`` will succeed, but a - request for ``gl-api1.domain`` will fail. - - Only CN is checked and if there are no dashes in the CN, validation - succeeds. - - Deprecated: use ``whitelist_names`` / ``blacklist_names`` instead. - -``extensions`` - Verifies: CSR. Parameters: ``allowed_extensions``. - - Ensures that only ``allowed_extensions`` are present in the request. The - names recognised by Anchor are: - - policyConstraints, basicConstraints, subjectDirectoryAttributes, - deltaCRLIndicator, cRLDistributionPoints, issuingDistributionPoint, - nameConstraints, certificatePolicies, policyMappings, - privateKeyUsagePeriod, keyUsage, authorityKeyIdentifier, - subjectKeyIdentifier, certificateIssuer, subjectAltName, issuerAltName - - Alternatively, the extension can be specified by the dotted decimal version - of OID. - -``key_usage`` - Verifies: CSR. Parameters: ``allowed_usage``. - - Ensures only ``allowed_usage`` is requested for the certificate. The names - recognised by Anchor are: - - Digital Signature, Non Repudiation, Key Encipherment, Data Encipherment, - Key Agreement, Certificate Sign, CRL Sign, Encipher Only, Decipher Only, - - as well as short versions: - - digitalSignature, nonRepudiation, keyEncipherment, dataEncipherment, - keyAgreement, keyCertSign, cRLSign, encipherOnly, decipherOnly - -``ext_key_usage`` - Verifies: CSR. Parameters: ``allowed_usage``. - - Ensures only ``allowed_usage`` is requested for the certificate. The names - recognised by Anchor are: - - TLS Web Server Authentication, TLS Web Client Authentication, Code Signing, - E-mail Protection, Time Stamping, OCSP Signing, Any Extended Key Usage - - as well as short versions: - - serverAuth, clientAuth, codeSigning, emailProtection, timeStamping, - ocspSigning, anyExtendedKeyUsage - - or text representation of custom OIDs. - -``source_cidrs`` - Verifies: CSR. Parameters: ``cidrs``. - - Ensures the request comes from one of the ranges in `cidrs`. - -``public_key`` - Verifies: CSR. Parameters: ``allowed_keys``. - - Ensures that only selected keys of a minimum specified length can be used - in the CSR. The ``allowed_keys`` parameter is a dictionary where keys are - the uppercase key names and values are minimum key lengths. Valid keys - at the moment are: ``RSA`` and ``DSA``. - -Extension interface -------------------- - -Custom validators can be used with Anchor without changing the application -itself. All validators are exposed as Stevedore_ extensions. They're registered -as entry points in namespace ``anchor.validators`` and each name points to a -simple function which accepts the following keyword arguments: - -``csr`` : anchor.X509.signing_request.X509Csr - An object describing the submitted CSR. - -``auth_result`` : anchor.auth.results.AuthDetails - An object which contains authentication information like username and user - groups. - -``request`` : pecan.Request - The https request which delivered the CSR. - -``conf`` : dict - Dictionary describing the registration authority configuration. - -On successful return, the request is passed on to the next validator or signed -if there are no remining ones. On validation failure an -``anchor.validators.ValidationError`` exception must be raised. - -.. _Stevedore: http://docs.openstack.org/developer/stevedore/index.html diff --git a/requirements.txt b/requirements.txt deleted file mode 100644 index 1b7a944..0000000 --- a/requirements.txt +++ /dev/null @@ -1,17 +0,0 @@ -# The order of packages is significant, because pip processes them in the order -# of appearance. Changing the order has an impact on the overall integration -# process, which may cause wedges in the gate later. -cryptography!=1.3.0,>=1.0 # BSD/Apache-2.0 -pyasn1 # BSD -pyasn1-modules # BSD -WebOb>=1.6.0 # MIT -pecan!=1.0.2,!=1.0.3,!=1.0.4,!=1.2,>=1.0.0 # BSD -Paste # MIT -netaddr!=0.7.16,>=0.7.13 # BSD -ldap3>=1.0.2 # LGPLv3 -requests!=2.12.2,!=2.13.0,>=2.10.0 # Apache-2.0 -stevedore>=1.17.1 # Apache-2.0 -pycadf!=2.0.0,>=1.1.0 # Apache-2.0 -oslo.config!=3.18.0,>=3.14.0 # Apache-2.0 -oslo.messaging>=5.14.0 # Apache-2.0 -oslo.utils>=3.18.0 # Apache-2.0 diff --git a/run_tests.sh b/run_tests.sh deleted file mode 100755 index 46fcf4d..0000000 --- a/run_tests.sh +++ /dev/null @@ -1,161 +0,0 @@ -#!/bin/bash - -# Copyright 2012 OpenStack Foundation -# -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - -set -eu - -function usage { - echo "Usage: $0 [OPTION]..." - echo "Run Keystone's test suite(s)" - echo "" - echo " -V, --virtual-env Always use virtualenv. Install automatically if not present" - echo " -N, --no-virtual-env Don't use virtualenv. Run tests in local environment" - echo " -x, --stop Stop running tests after the first error or failure." - echo " -f, --force Force a clean re-build of the virtual environment. Useful when dependencies have been added." - echo " -u, --update Update the virtual environment with any newer package versions" - echo " -p, --pep8 Just run flake8" - echo " -8, --8 Just run flake8, don't show PEP8 text for each error" - echo " -P, --no-pep8 Don't run flake8" - echo " -c, --coverage Generate coverage report" - echo " -h, --help Print this usage message" - echo "" - echo "Note: with no options specified, the script will try to run the tests in a virtual environment," - echo " If no virtualenv is found, the script will ask if you would like to create one. If you " - echo " prefer to run tests NOT in a virtual environment, simply pass the -N option." - exit -} - -function process_option { - case "$1" in - -h|--help) usage;; - -V|--virtual-env) always_venv=1; never_venv=0;; - -N|--no-virtual-env) always_venv=0; never_venv=1;; - -x|--stop) failfast=1;; - -f|--force) force=1;; - -u|--update) update=1;; - -p|--pep8) just_flake8=1;; - -8|--8) short_flake8=1;; - -P|--no-pep8) no_flake8=1;; - -c|--coverage) coverage=1;; - -*) testropts="$testropts $1";; - *) testrargs="$testrargs $1" - esac -} - -venv=.venv -with_venv=tools/with_venv.sh -always_venv=0 -never_venv=0 -force=0 -failfast=0 -testrargs= -testropts=--subunit -wrapper="" -just_flake8=0 -short_flake8=0 -no_flake8=0 -coverage=0 -update=0 - -for arg in "$@"; do - process_option $arg -done - -TESTRTESTS="python setup.py testr" - -# If enabled, tell nose to collect coverage data -if [ $coverage -eq 1 ]; then - TESTRTESTS="$TESTRTESTS --coverage" -fi - -function run_tests { - set -e - echo ${wrapper} - if [ $failfast -eq 1 ]; then - testrargs="$testrargs -- --failfast" - fi - ${wrapper} $TESTRTESTS --testr-args="$testropts $testrargs" | \ - ${wrapper} subunit-2to1 | \ - ${wrapper} tools/colorizer.py -} - -function run_flake8 { - FLAGS=--show-pep8 - if [ $# -gt 0 ] && [ 'short' == ''$1 ]; then - FLAGS='' - fi - - echo "Running flake8 ..." - # Just run flake8 in current environment - echo ${wrapper} flake8 $FLAGS | tee pep8.txt - ${wrapper} flake8 $FLAGS | tee pep8.txt -} - -if [ $never_venv -eq 0 ]; then - # Remove the virtual environment if --force used - if [ $force -eq 1 ]; then - echo "Cleaning virtualenv..." - rm -rf ${venv} - fi - if [ $update -eq 1 ]; then - echo "Updating virtualenv..." - python tools/install_venv.py - fi - if [ -e ${venv} ]; then - wrapper="${with_venv}" - else - if [ $always_venv -eq 1 ]; then - # Automatically install the virtualenv - python tools/install_venv.py - wrapper="${with_venv}" - else - echo -e "No virtual environment found...create one? (Y/n) \c" - read use_ve - if [ "x$use_ve" = "xY" -o "x$use_ve" = "x" -o "x$use_ve" = "xy" ]; then - # Install the virtualenv and run the test suite in it - python tools/install_venv.py - wrapper=${with_venv} - fi - fi - fi -fi - -# Delete old coverage data from previous runs -if [ $coverage -eq 1 ]; then - ${wrapper} coverage erase -fi - -if [ $just_flake8 -eq 1 ]; then - run_flake8 - exit -fi - -if [ $short_flake8 -eq 1 ]; then - run_flake8 short - exit -fi - - -run_tests - -# NOTE(sirp): we only want to run flake8 when we're running the full-test -# suite, not when we're running tests individually. To handle this, we need to -# distinguish between options (testropts), which begin with a '-', and arguments -# (testrargs). -if [ -z "$testrargs" ]; then - if [ $no_flake8 -eq 0 ]; then - run_flake8 - fi -fi diff --git a/setup.cfg b/setup.cfg deleted file mode 100644 index 5fe1183..0000000 --- a/setup.cfg +++ /dev/null @@ -1,67 +0,0 @@ -[metadata] -name = anchor -summary = Webservice to auto-sign certificates for short amount of time -description-file = - README.rst -author = OpenStack Security Group -author-email = openstack-dev@lists.openstack.org -home-page = https://wiki.openstack.org/wiki/Security/Projects/Anchor -classifier = - Environment :: OpenStack - Intended Audience :: Information Technology - Intended Audience :: System Administrators - Intended Audience :: Developers - License :: OSI Approved :: Apache Software License - Operating System :: POSIX :: Linux - Operating System :: MacOS :: MacOS X - Programming Language :: Python - Programming Language :: Python :: 2 - Programming Language :: Python :: 2.7 - Programming Language :: Python :: 3 - Programming Language :: Python :: 3.5 - Topic :: Security - -[build_sphinx] -all_files = 1 -build-dir = doc/build -source-dir = doc/source - -[entry_points] -anchor.signing_backends = - anchor = anchor.signers.cryptography_io:sign - pkcs11 = anchor.signers.pkcs11:sign - -anchor.validators = - common_name = anchor.validators.custom:common_name - alternative_names = anchor.validators.custom:alternative_names - alternative_names_ip = anchor.validators.custom:alternative_names_ip - blacklist_names = anchor.validators.custom:blacklist_names - server_group = anchor.validators.custom:server_group - extensions = anchor.validators.custom:extensions - key_usage = anchor.validators.custom:key_usage - ext_key_usage = anchor.validators.custom:ext_key_usage - source_cidrs = anchor.validators.custom:source_cidrs - whitelist_names = anchor.validators.custom:whitelist_names - public_key = anchor.validators.custom:public_key - standards_compliance = anchor.validators.standards:standards_compliance - -anchor.authentication = - keystone = anchor.auth.keystone:login - ldap = anchor.auth.ldap:login - static = anchor.auth.static:login - -anchor.fixups = - enforce_alternative_names_present = anchor.fixups:enforce_alternative_names_present - -[files] -data_files = - etc/anchor = - config.json -packages = - anchor -scripts = - bin/anchor - bin/anchor_debug - -[bdist_wheel] -universal=1 diff --git a/setup.py b/setup.py deleted file mode 100644 index 782bb21..0000000 --- a/setup.py +++ /dev/null @@ -1,29 +0,0 @@ -# Copyright (c) 2013 Hewlett-Packard Development Company, L.P. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or -# implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -# THIS FILE IS MANAGED BY THE GLOBAL REQUIREMENTS REPO - DO NOT EDIT -import setuptools - -# In python < 2.7.4, a lazy loading of package `pbr` will break -# setuptools if some other modules registered functions in `atexit`. -# solution from: http://bugs.python.org/issue15881#msg170215 -try: - import multiprocessing # noqa -except ImportError: - pass - -setuptools.setup( - setup_requires=['pbr>=1.8'], - pbr=True) diff --git a/test-requirements.txt b/test-requirements.txt deleted file mode 100644 index 1471ac5..0000000 --- a/test-requirements.txt +++ /dev/null @@ -1,18 +0,0 @@ -# The order of packages is significant, because pip processes them in the order -# of appearance. Changing the order has an impact on the overall integration -# process, which may cause wedges in the gate later. -coverage>=4.0 # Apache-2.0 -fixtures>=3.0.0 # Apache-2.0/BSD -hacking<0.10,>=0.9.2 -mock>=2.0 # BSD -python-subunit>=0.0.18 # Apache-2.0/BSD -testrepository>=0.0.18 # Apache-2.0/BSD -testscenarios>=0.4 # Apache-2.0/BSD -testtools>=1.4.0 # MIT -requests-mock>=1.1 # Apache-2.0 - -# Documentation build requirements -sphinx>=1.5.1 # BSD -oslosphinx>=4.7.0 # Apache-2.0 - -bandit>=1.1.0 # Apache-2.0 diff --git a/tests/CA/root-ca-unwrapped.key b/tests/CA/root-ca-unwrapped.key deleted file mode 100644 index db7b4e6..0000000 --- a/tests/CA/root-ca-unwrapped.key +++ /dev/null @@ -1,15 +0,0 @@ ------BEGIN RSA PRIVATE KEY----- -MIICXQIBAAKBgQDXTICDdXtgyMqmfForj49nr4kOBcs9AdG85iIGCErRYC1tC6Sz -v1E+lblOfadEyf0nykoyptK3aPgXa5S+GGu2zVSQoXmpixbdAr2MIuAjcnHeomKz -EjyjNcbwa5YElhSI3ypiX28ZCFncbVIUN8aUdpfjZCnJKBPpUgT+GGxOFwIDAQAB -AoGBAITpG2UMP7BOBJymo9vEclkmCkv307HDz8D3qQVkVRvQbfqld3Xno7YpJA6K -j5ptv7Sysv918Rt817tNlLONy+AZGY2hxgmXVob4FdwVoRTj7EJhuciIYzecsfHO -PVzc8dF2WCocMWlXQ7a/r2pOa5H/D4x4FyBtpf0ykJps2ZfBAkEA/2SQFYTDBcTX -f1vnL/fnNgUS1T84E6FPlRTO8lpNB1atGf97lLzxv4QafJc3w6PhL1DRMeCmG1QD -7G1pBG4PpwJBANfPiYRg2jyUANbwE47CjsqiviwAC2aboWGWcC/m+LQ/PdvcTD7V -tF83Fn4syEuNKj65xGhmxZmCdn8oHCZBHBECQC0Iam+g7VKDFwyaA/XtXJOl6WA4 -uYaclw/Oj38kdRiqK/O9nOjpOCdw/8qgT3Dr4LUbJwgIeMGw2tBBqpbhYVkCQFN3 -diVX3DAfwe9fbQEC6H0g0lJsNfyaZqE6sOsl9ryn1QHqwyZuOtO0l6N3KIRn9ZXK -/VavoO8NUU0+sxxshDECQQDtwy89tpRQhqTIQkZzcgXmAiBypdh/Wunj1fzAJ98M -Vo8GJXswSuQXDr4mZnsl0F+RRe4LoLM6i3TYeM+qJZmg ------END RSA PRIVATE KEY----- diff --git a/tests/CA/root-ca.crt b/tests/CA/root-ca.crt deleted file mode 100644 index b9af076..0000000 --- a/tests/CA/root-ca.crt +++ /dev/null @@ -1,58 +0,0 @@ -Certificate: - Data: - Version: 3 (0x2) - Serial Number: 16983733478354280881 (0xebb2579d693761b1) - Signature Algorithm: sha256WithRSAEncryption - Issuer: C=AU, ST=Some-State, O=Herp Derp plc, OU=herp.derp.plc, CN=herp.derp.plc - Validity - Not Before: Sep 1 23:29:35 2015 GMT - Not After : Sep 2 23:29:35 2015 GMT - Subject: C=AU, ST=Some-State, O=Herp Derp plc, OU=herp.derp.plc, CN=herp.derp.plc - Subject Public Key Info: - Public Key Algorithm: rsaEncryption - Public-Key: (1024 bit) - Modulus: - 00:9e:7a:a8:35:41:e7:1c:bf:c8:6a:8f:50:4f:f4: - a1:09:5f:94:2c:14:2c:51:eb:63:3c:a6:53:db:e6: - de:2c:2e:8f:14:61:f6:5d:ea:41:4b:70:e3:fc:c7: - 3c:30:bf:1f:de:15:8e:92:bb:1e:76:7a:74:35:f7: - ba:3c:68:cc:32:3f:be:e1:32:16:6a:b5:df:0d:0a: - 02:c9:31:59:54:6d:18:70:2e:d8:b4:4a:41:c5:3e: - 27:34:c0:08:3e:7a:c7:d7:6b:ac:a1:77:94:f1:0b: - e6:ed:8b:b3:20:57:f9:63:03:cd:17:43:11:c7:f3: - 13:a3:74:ea:06:37:40:c7:7d - Exponent: 65537 (0x10001) - X509v3 extensions: - X509v3 Subject Key Identifier: - DE:D6:97:31:61:61:AB:34:2F:EE:92:CB:85:96:80:86:BF:8D:60:DD - X509v3 Authority Key Identifier: - keyid:DE:D6:97:31:61:61:AB:34:2F:EE:92:CB:85:96:80:86:BF:8D:60:DD - - X509v3 Basic Constraints: - CA:TRUE - Signature Algorithm: sha256WithRSAEncryption - 9a:50:80:40:5a:11:3d:99:0c:85:0a:68:e2:ad:8a:c9:db:c0: - 9d:2f:80:1a:f6:52:cb:bd:5d:3c:de:41:b3:50:76:d9:d9:7a: - e9:ae:97:f4:68:dc:78:4c:90:82:5f:e9:57:17:70:49:26:18: - 2b:ab:96:b7:26:0d:6f:63:4e:fd:40:6c:44:6a:5f:b9:26:76: - 8d:1b:4a:74:3b:b2:cf:b5:cc:5b:50:a6:ea:1c:67:3a:13:29: - 69:93:e2:b6:9e:14:97:a0:b2:3f:5f:3a:f4:c9:7f:5d:5a:7a: - 7c:95:d4:2c:dc:83:a2:ba:5f:a9:10:de:f7:80:3d:e6:63:e8: - 5b:ef ------BEGIN CERTIFICATE----- -MIICojCCAgugAwIBAgIJAOuyV51pN2GxMA0GCSqGSIb3DQEBCwUAMGoxCzAJBgNV -BAYTAkFVMRMwEQYDVQQIDApTb21lLVN0YXRlMRYwFAYDVQQKDA1IZXJwIERlcnAg -cGxjMRYwFAYDVQQLDA1oZXJwLmRlcnAucGxjMRYwFAYDVQQDDA1oZXJwLmRlcnAu -cGxjMB4XDTE1MDkwMTIzMjkzNVoXDTE1MDkwMjIzMjkzNVowajELMAkGA1UEBhMC -QVUxEzARBgNVBAgMClNvbWUtU3RhdGUxFjAUBgNVBAoMDUhlcnAgRGVycCBwbGMx -FjAUBgNVBAsMDWhlcnAuZGVycC5wbGMxFjAUBgNVBAMMDWhlcnAuZGVycC5wbGMw -gZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAJ56qDVB5xy/yGqPUE/0oQlflCwU -LFHrYzymU9vm3iwujxRh9l3qQUtw4/zHPDC/H94VjpK7HnZ6dDX3ujxozDI/vuEy -Fmq13w0KAskxWVRtGHAu2LRKQcU+JzTACD56x9drrKF3lPEL5u2LsyBX+WMDzRdD -EcfzE6N06gY3QMd9AgMBAAGjUDBOMB0GA1UdDgQWBBTe1pcxYWGrNC/uksuFloCG -v41g3TAfBgNVHSMEGDAWgBTe1pcxYWGrNC/uksuFloCGv41g3TAMBgNVHRMEBTAD -AQH/MA0GCSqGSIb3DQEBCwUAA4GBAJpQgEBaET2ZDIUKaOKtisnbwJ0vgBr2Usu9 -XTzeQbNQdtnZeumul/Ro3HhMkIJf6VcXcEkmGCurlrcmDW9jTv1AbERqX7kmdo0b -SnQ7ss+1zFtQpuocZzoTKWmT4raeFJegsj9fOvTJf11aenyV1Czcg6K6X6kQ3veA -PeZj6Fvv ------END CERTIFICATE----- \ No newline at end of file diff --git a/tests/X509/__init__.py b/tests/X509/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/tests/X509/test_extension.py b/tests/X509/test_extension.py deleted file mode 100644 index e532846..0000000 --- a/tests/X509/test_extension.py +++ /dev/null @@ -1,270 +0,0 @@ -# -*- coding:utf-8 -*- -# -# Copyright 2014 Hewlett-Packard Development Company, L.P. -# -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - -import unittest - -import netaddr -from pyasn1.codec.der import encoder -from pyasn1.type import univ - -from anchor.asn1 import rfc5280 -from anchor.X509 import errors -from anchor.X509 import extension - - -class TestExtensionBase(unittest.TestCase): - def test_no_spec(self): - with self.assertRaises(errors.X509Error): - extension.X509Extension() - - def test_invalid_asn(self): - with self.assertRaises(errors.X509Error): - extension.X509Extension("foobar") - - def test_unknown_extension_str(self): - asn1 = rfc5280.Extension() - asn1['extnID'] = univ.ObjectIdentifier('1.2.3.4') - asn1['critical'] = False - asn1['extnValue'] = "foobar" - ext = extension.X509Extension(asn1) - self.assertEqual("1.2.3.4: ", str(ext)) - - def test_construct(self): - asn1 = rfc5280.Extension() - asn1['extnID'] = univ.ObjectIdentifier('1.2.3.4') - asn1['critical'] = False - asn1['extnValue'] = "foobar" - ext = extension.construct_extension(asn1) - self.assertIsInstance(ext, extension.X509Extension) - - def test_construct_invalid_type(self): - with self.assertRaises(errors.X509Error): - extension.construct_extension("foobar") - - def test_critical(self): - asn1 = rfc5280.Extension() - asn1['extnID'] = univ.ObjectIdentifier('1.2.3.4') - asn1['critical'] = False - asn1['extnValue'] = "foobar" - ext = extension.construct_extension(asn1) - self.assertFalse(ext.get_critical()) - ext.set_critical(True) - self.assertTrue(ext.get_critical()) - - def test_serialise(self): - asn1 = rfc5280.Extension() - asn1['extnID'] = univ.ObjectIdentifier('1.2.3.4') - asn1['critical'] = False - asn1['extnValue'] = "foobar" - ext = extension.construct_extension(asn1) - self.assertEqual(ext.as_der(), encoder.encode(asn1)) - - def test_broken_set_value(self): - class SomeExt(extension.X509Extension): - spec = rfc5280.Extension - _oid = univ.ObjectIdentifier('1.2.3.4') - - @classmethod - def _get_default_value(cls): - return 1234 - - with self.assertRaisesRegexp(errors.X509Error, 'incorrect type'): - SomeExt() - - -class TestBasicConstraints(unittest.TestCase): - def setUp(self): - self.ext = extension.X509ExtensionBasicConstraints() - - def test_str(self): - self.assertEqual(str(self.ext), - "basicConstraints: CA: FALSE, pathLen: None") - - def test_ca(self): - self.ext.set_ca(True) - self.assertTrue(self.ext.get_ca()) - self.ext.set_ca(False) - self.assertFalse(self.ext.get_ca()) - - def test_pathlen(self): - self.ext.set_path_len_constraint(1) - self.assertEqual(1, self.ext.get_path_len_constraint()) - - -class TestKeyUsage(unittest.TestCase): - def setUp(self): - self.ext = extension.X509ExtensionKeyUsage() - - def test_usage_set(self): - self.ext.set_usage('digitalSignature', True) - self.ext.set_usage('keyAgreement', False) - self.assertTrue(self.ext.get_usage('digitalSignature')) - self.assertFalse(self.ext.get_usage('keyAgreement')) - - def test_usage_reset(self): - self.ext.set_usage('digitalSignature', True) - self.ext.set_usage('digitalSignature', False) - self.assertFalse(self.ext.get_usage('digitalSignature')) - - def test_usage_unset(self): - self.assertFalse(self.ext.get_usage('keyAgreement')) - - def test_get_all_usage(self): - self.ext.set_usage('digitalSignature', True) - self.ext.set_usage('keyAgreement', False) - self.ext.set_usage('keyEncipherment', True) - self.assertEqual(set(['digitalSignature', 'keyEncipherment']), - set(self.ext.get_all_usages())) - - def test_str(self): - self.ext.set_usage('digitalSignature', True) - self.assertEqual("keyUsage: digitalSignature", str(self.ext)) - - -class TestSubjectAltName(unittest.TestCase): - def setUp(self): - self.ext = extension.X509ExtensionSubjectAltName() - self.domain = 'example.com' - self.ip = netaddr.IPAddress('1.2.3.4') - self.ip6 = netaddr.IPAddress('::1') - - def test_dns_ids(self): - self.ext.add_dns_id(self.domain) - self.ext.add_ip(self.ip) - self.assertEqual([self.domain], self.ext.get_dns_ids()) - - def test_ips(self): - self.ext.add_dns_id(self.domain) - self.ext.add_ip(self.ip) - self.assertEqual([self.ip], self.ext.get_ips()) - - def test_ipv6(self): - self.ext.add_ip(self.ip6) - self.assertEqual([self.ip6], self.ext.get_ips()) - - def test_add_ip_invalid(self): - with self.assertRaises(errors.X509Error): - self.ext.add_ip("abcdef") - - def test_str(self): - self.ext.add_dns_id(self.domain) - self.ext.add_ip(self.ip) - self.assertEqual("subjectAltName: DNS:example.com, IP:1.2.3.4", - str(self.ext)) - - -class TestNameConstraints(unittest.TestCase): - def setUp(self): - self.ext = extension.X509ExtensionNameConstraints() - - def test_length(self): - self.assertEqual(0, self.ext.get_permitted_length()) - self.assertEqual(0, self.ext.get_excluded_length()) - - def test_add(self): - test_name = 'example.com' - test_type = 'dNSName' - self.assertEqual(0, self.ext.get_permitted_length()) - self.assertEqual(0, self.ext.get_excluded_length()) - self.ext.add_permitted(test_type, test_name) - self.assertEqual(1, self.ext.get_permitted_length()) - self.assertEqual(0, self.ext.get_excluded_length()) - self.ext.add_excluded(test_type, test_name) - self.assertEqual(1, self.ext.get_permitted_length()) - self.assertEqual(1, self.ext.get_excluded_length()) - - def test_excluded(self): - self.ext.add_excluded('dNSName', 'example.com') - self.assertEqual(self.ext.get_excluded_range(0), (0, None)) - self.assertEqual(self.ext.get_excluded_name(0), - ('dNSName', b'example.com')) - - def test_permitted(self): - self.ext.add_permitted('dNSName', 'example.com') - self.assertEqual(self.ext.get_permitted_range(0), (0, None)) - self.assertEqual(self.ext.get_permitted_name(0), - ('dNSName', b'example.com')) - - -class TestExtendedKeyUsage(unittest.TestCase): - def setUp(self): - self.ext = extension.X509ExtensionExtendedKeyUsage() - - def test_get_all(self): - self.ext.set_usage(rfc5280.id_kp_clientAuth, True) - self.ext.set_usage(rfc5280.id_kp_codeSigning, True) - usages = self.ext.get_all_usages() - self.assertEqual(2, len(usages)) - self.assertIn(rfc5280.id_kp_clientAuth, usages) - - def test_get_one(self): - self.assertFalse(self.ext.get_usage(rfc5280.id_kp_clientAuth)) - self.ext.set_usage(rfc5280.id_kp_clientAuth, True) - self.assertTrue(self.ext.get_usage(rfc5280.id_kp_clientAuth)) - - def test_set(self): - self.assertEqual(0, len(self.ext.get_all_usages())) - self.ext.set_usage(rfc5280.id_kp_clientAuth, True) - self.assertEqual(1, len(self.ext.get_all_usages())) - self.ext.set_usage(rfc5280.id_kp_clientAuth, True) - self.assertEqual(1, len(self.ext.get_all_usages())) - self.ext.set_usage(rfc5280.id_kp_codeSigning, True) - self.assertEqual(2, len(self.ext.get_all_usages())) - - def test_unset(self): - self.ext.set_usage(rfc5280.id_kp_clientAuth, True) - self.ext.set_usage(rfc5280.id_kp_clientAuth, False) - self.assertEqual(0, len(self.ext.get_all_usages())) - self.ext.set_usage(rfc5280.id_kp_clientAuth, False) - self.assertEqual(0, len(self.ext.get_all_usages())) - - def test_str(self): - self.ext.set_usage(rfc5280.id_kp_clientAuth, True) - self.ext.set_usage(rfc5280.id_kp_codeSigning, True) - self.assertEqual( - "extKeyUsage: TLS Web Client Authentication, Code Signing", - str(self.ext)) - - def test_invalid_usage(self): - self.assertRaises(ValueError, self.ext.get_usage, - univ.ObjectIdentifier('1.2.3.4')) - self.assertRaises(ValueError, self.ext.set_usage, True, - univ.ObjectIdentifier('1.2.3.4')) - - -class TestAuthorityKeyId(unittest.TestCase): - def setUp(self): - self.ext = extension.X509ExtensionAuthorityKeyId() - - def test_key_id(self): - key_id = b"12345678" - self.ext.set_key_id(key_id) - self.assertEqual(key_id, self.ext.get_key_id()) - - def test_name_serial(self): - s = 12345678 - self.ext.set_serial(s) - self.assertEqual(s, self.ext.get_serial()) - - -class TestSubjectKeyId(unittest.TestCase): - def setUp(self): - self.ext = extension.X509ExtensionSubjectKeyId() - - def test_key_id(self): - key_id = b"12345678" - self.ext.set_key_id(key_id) - self.assertEqual(key_id, self.ext.get_key_id()) diff --git a/tests/X509/test_utils.py b/tests/X509/test_utils.py deleted file mode 100644 index 5829d0e..0000000 --- a/tests/X509/test_utils.py +++ /dev/null @@ -1,34 +0,0 @@ -# -*- coding:utf-8 -*- -# -# Copyright 2014 Hewlett-Packard Development Company, L.P. -# -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - -import unittest - -from anchor.X509 import utils - - -class TestASN1Time(unittest.TestCase): - def test_round_check(self): - t = 0 - asn1_time = utils.timestamp_to_asn1_time(t) - res = utils.asn1_time_to_timestamp(asn1_time) - self.assertEqual(t, res) - - def test_post_2050(self): - """Test date post 2050, which causes different encoding.""" - t = 2600000000 - asn1_time = utils.timestamp_to_asn1_time(t) - res = utils.asn1_time_to_timestamp(asn1_time) - self.assertEqual(t, res) diff --git a/tests/X509/test_x509_certificate.py b/tests/X509/test_x509_certificate.py deleted file mode 100644 index 639a44c..0000000 --- a/tests/X509/test_x509_certificate.py +++ /dev/null @@ -1,296 +0,0 @@ -# -*- coding:utf-8 -*- -# -# Copyright 2014 Hewlett-Packard Development Company, L.P. -# -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - -import unittest - -import mock -from pyasn1.type import univ as asn1_univ - -import io -import textwrap - -from anchor.X509 import certificate -from anchor.X509 import errors as x509_errors -from anchor.X509 import extension -from anchor.X509 import name as x509_name - - -class TestX509Cert(unittest.TestCase): - cert_data = textwrap.dedent(u""" - -----BEGIN CERTIFICATE----- - MIICuDCCAiGgAwIBAgIJAIaZlZ0Oms2fMA0GCSqGSIb3DQEBCwUAMGoxCzAJBgNV - BAYTAkFVMRMwEQYDVQQIDApTb21lLVN0YXRlMRYwFAYDVQQKDA1IZXJwIERlcnAg - cGxjMRYwFAYDVQQLDA1oZXJwLmRlcnAucGxjMRYwFAYDVQQDDA1oZXJwLmRlcnAu - cGxjMB4XDTE1MDkwMTIzNDcwNVoXDTE1MDkwMjIzNDcwNVowgZQxCzAJBgNVBAYT - AlVLMQ8wDQYDVQQIDAZOYXJuaWExEjAQBgNVBAcMCUZ1bmt5dG93bjEXMBUGA1UE - CgwOQW5jaG9yIFRlc3RpbmcxEDAOBgNVBAsMB3Rlc3RpbmcxFDASBgNVBAMMC2Fu - Y2hvci50ZXN0MR8wHQYJKoZIhvcNAQkBFhB0ZXN0QGFuY2hvci50ZXN0MIGfMA0G - CSqGSIb3DQEBAQUAA4GNADCBiQKBgQCeeqg1Qeccv8hqj1BP9KEJX5QsFCxR62M8 - plPb5t4sLo8UYfZd6kFLcOP8xzwwvx/eFY6Sux52enQ197o8aMwyP77hMhZqtd8N - CgLJMVlUbRhwLti0SkHFPic0wAg+esfXa6yhd5TxC+bti7MgV/ljA80XQxHH8xOj - dOoGN0DHfQIDAQABozswOTAfBgNVHSMEGDAWgBTe1pcxYWGrNC/uksuFloCGv41g - 3TAJBgNVHRMEAjAAMAsGA1UdDwQEAwIE8DANBgkqhkiG9w0BAQsFAAOBgQAy+2HQ - kXyNc5SwjvCXMDWMTKSB5bEWPxuJw3Lf1G4czHAyANzGlm1HJ/h6Z8NSwEy9x0xj - iFnpbc39fGoeApkEqVhY0WyJ7qbCuJsExE+ra6w+iPIKvjez+Ymp+zCDsiTIJEnf - 2jsyzhghVa/FgDpQYQEJHAuGTEAvkQITp8IUvg== - -----END CERTIFICATE-----""") - - key_dsa_data = textwrap.dedent(""" - -----BEGIN DSA PARAMETERS----- - MIICLAKCAQEA59W1OsK9Tv7DRbxzibGVpBAL2Oz8JhbV3ii7WAat+UfTBLAnfdva - 7UE8odu1l8p41N/8H/tDWgPh6tOgdX0YT9HDsILymQxzUEscliFZKmYg7YdSH3Zd - 6DglOT7CqYxX0r9gK/BOh8ESe3gqKncnThHnO8Eu9wP8HNcrN00EOqP+fJpbS0lu - iifD9JdFY5YpCsLDIvpPbM0NCDuANPo10N3qqC8BuNiu0VfZpRSBcqzU1kwABT5n - y7+8RMh5Xaa7xnhGctJ9s9n+QfWcF/vbgiDOBttb3d8r8Pqvoou8v7Q38Q6zILhf - hajevqjGqZwodbvbHGfFbWapgBjpBIr4zwIhAOq6uryEHQglirWCGFJLQlkzxghy - ctHBRXGuKYb+ltRTAoIBAHRUFxzd1vhjKQ5atIdG0AiXUNm7/uboe21EJDLf4lkE - 7UHDZfwsHXxQHfozzIsp7gHcw7F6AVCgiNRi9vBYOemPswevoWiVKqLTVt1wMogD - EJI6VAQEbBmSrtvyuClCkEAlIY6daX9EV9KqbnetS4/xv4WFQ9FPE47VyQ50vvxK - JSyNZnJ1lN6FUD9R5YYfwERgND8EYJBD10UBKIvtORICTJUfaDAweTWhaVcXUID7 - VGNGPauOdVQzWsWTrQn/f/hbXCB/KXgv1l92D6rEoT2j2YrqIv/qD/ZxPwhBfLdr - W241Cb+LT05LVCokRbWUdjfuO8SdSBAIvT9P6umG/uQ= - -----END DSA PARAMETERS----- - -----BEGIN DSA PRIVATE KEY----- - MIIDVwIBAAKCAQEA59W1OsK9Tv7DRbxzibGVpBAL2Oz8JhbV3ii7WAat+UfTBLAn - fdva7UE8odu1l8p41N/8H/tDWgPh6tOgdX0YT9HDsILymQxzUEscliFZKmYg7YdS - H3Zd6DglOT7CqYxX0r9gK/BOh8ESe3gqKncnThHnO8Eu9wP8HNcrN00EOqP+fJpb - S0luiifD9JdFY5YpCsLDIvpPbM0NCDuANPo10N3qqC8BuNiu0VfZpRSBcqzU1kwA - BT5ny7+8RMh5Xaa7xnhGctJ9s9n+QfWcF/vbgiDOBttb3d8r8Pqvoou8v7Q38Q6z - ILhfhajevqjGqZwodbvbHGfFbWapgBjpBIr4zwIhAOq6uryEHQglirWCGFJLQlkz - xghyctHBRXGuKYb+ltRTAoIBAHRUFxzd1vhjKQ5atIdG0AiXUNm7/uboe21EJDLf - 4lkE7UHDZfwsHXxQHfozzIsp7gHcw7F6AVCgiNRi9vBYOemPswevoWiVKqLTVt1w - MogDEJI6VAQEbBmSrtvyuClCkEAlIY6daX9EV9KqbnetS4/xv4WFQ9FPE47VyQ50 - vvxKJSyNZnJ1lN6FUD9R5YYfwERgND8EYJBD10UBKIvtORICTJUfaDAweTWhaVcX - UID7VGNGPauOdVQzWsWTrQn/f/hbXCB/KXgv1l92D6rEoT2j2YrqIv/qD/ZxPwhB - fLdrW241Cb+LT05LVCokRbWUdjfuO8SdSBAIvT9P6umG/uQCggEBAKrZAppbnKf1 - pzSvE3gTaloitAJG+79BML5h1n67EWuv0i+Fq4eUAVJ23R8GR1HrYw6utZoYbu8u - k8eHrArMfTfbFaLwK/Nv33Hfm3aTTXnY6auLNkpbiZXuCQjWBFhb6F+B42V9/JJ8 - RJ1UV6Y2ajjjMvpeh0cPlARw5UpKBgQ933DhefCWyFBPsPToFvd3uPO+GUN6VpNY - iR7G0AH3/LSVJRuz5/QCp86uLIoU3fBEf1KGYJrkVKlc9DtcNmDXgpP0d3fK+4Jw - bGvi5AD1sQOWryNujyS/d2K/PAagsD0M6XJFgkEV592OSlygbYtuo3t4AtAy8F0f - VHNXq2l01FMCIQCrkk1749eQg4W6j7HfLFvjbDcuIFTw98IKyEZuZ93cdA== - -----END DSA PRIVATE KEY-----""").encode('ascii') - - key_rsa_data = textwrap.dedent(""" - -----BEGIN RSA PRIVATE KEY----- - MIICXAIBAAKBgQCeeqg1Qeccv8hqj1BP9KEJX5QsFCxR62M8plPb5t4sLo8UYfZd - 6kFLcOP8xzwwvx/eFY6Sux52enQ197o8aMwyP77hMhZqtd8NCgLJMVlUbRhwLti0 - SkHFPic0wAg+esfXa6yhd5TxC+bti7MgV/ljA80XQxHH8xOjdOoGN0DHfQIDAQAB - AoGBAJ2ozJpe+7qgGJPaCz3f0izvBwtq7kR49fqqRZbo8HHnx7OxWVVI7LhOkKEy - 2/Bq0xsvOu1CdiXL4LynvIDIiQqLaeINzG48Rbk+0HadbXblt3nDkIWdYII6zHKI - W9ewX4KpHEPbrlEO9BjAlAcYsDIvFIMYpQhtQ+0R/gmZ99WJAkEAz5C2a6FIcMbE - o3aTc9ECq99zY7lxh+6aLpUdIeeHyb/QzfGDBdlbpBAkA6EcxSqp0aqH4xIQnYHa - 3P5ZCShqSwJBAMN1sb76xq94xkg2cxShPFPAE6xKRFyKqLgsBYVtulOdfOtOnjh9 - 1SK2XQQfBRIRdG4Q/gDoCP8XQHpJcWMk+FcCQDnuJqulaOVo5GrG5mJ1nCxCAh98 - G06X7lo/7dCPoRtSuMExvaK9RlFk29hTeAcjYCAPWzupyA9dtarmJg1jRT8CQCKf - gYnb8D/6+9yk0IPR/9ayCooVacCeyz48hgnZowzWs98WwQ4utAd/GED3obVOpDov - Bl9wus889i3zPoOac+cCQCZHredQcJGd4dlthbVtP2NhuPXz33JuETGR9pXtsDUZ - uX/nSq1oo9kUh/dPOz6aP5Ues1YVe3LExmExPBQfwIE= - -----END RSA PRIVATE KEY-----""").encode('ascii') - - def setUp(self): - super(TestX509Cert, self).setUp() - self.cert = certificate.X509Certificate.from_buffer( - TestX509Cert.cert_data) - - def tearDown(self): - pass - - def test_bad_data_throws(self): - bad_data = ( - u"some bad data is " - "EHRlc3RAYW5jaG9yLnRlc3QwTDANBgkqhkiG9w0BAQEFAAM7ADA4AjEA6m") - - cert = certificate.X509Certificate() - self.assertRaises(x509_errors.X509Error, - cert.from_buffer, - bad_data) - - def test_get_subject_countryName(self): - name = self.cert.get_subject() - entries = name.get_entries_by_oid(x509_name.OID_countryName) - self.assertEqual(len(entries), 1) - self.assertEqual(entries[0].get_name(), "countryName") - self.assertEqual(entries[0].get_value(), "UK") - - def test_get_subject_stateOrProvinceName(self): - name = self.cert.get_subject() - entries = name.get_entries_by_oid(x509_name.OID_stateOrProvinceName) - self.assertEqual(len(entries), 1) - self.assertEqual(entries[0].get_name(), "stateOrProvinceName") - self.assertEqual(entries[0].get_value(), "Narnia") - - def test_get_subject_localityName(self): - name = self.cert.get_subject() - entries = name.get_entries_by_oid(x509_name.OID_localityName) - self.assertEqual(len(entries), 1) - self.assertEqual(entries[0].get_name(), "localityName") - self.assertEqual(entries[0].get_value(), "Funkytown") - - def test_get_subject_organizationName(self): - name = self.cert.get_subject() - entries = name.get_entries_by_oid(x509_name.OID_organizationName) - self.assertEqual(len(entries), 1) - self.assertEqual(entries[0].get_name(), "organizationName") - self.assertEqual(entries[0].get_value(), "Anchor Testing") - - def test_get_subject_organizationUnitName(self): - name = self.cert.get_subject() - entries = name.get_entries_by_oid(x509_name.OID_organizationalUnitName) - self.assertEqual(len(entries), 1) - self.assertEqual(entries[0].get_name(), "organizationalUnitName") - self.assertEqual(entries[0].get_value(), "testing") - - def test_get_subject_commonName(self): - name = self.cert.get_subject() - entries = name.get_entries_by_oid(x509_name.OID_commonName) - self.assertEqual(len(entries), 1) - self.assertEqual(entries[0].get_name(), "commonName") - self.assertEqual(entries[0].get_value(), "anchor.test") - - def test_get_subject_emailAddress(self): - name = self.cert.get_subject() - entries = name.get_entries_by_oid(x509_name.OID_pkcs9_emailAddress) - self.assertEqual(len(entries), 1) - self.assertEqual(entries[0].get_name(), "emailAddress") - self.assertEqual(entries[0].get_value(), "test@anchor.test") - - def test_get_issuer_countryName(self): - name = self.cert.get_issuer() - entries = name.get_entries_by_oid(x509_name.OID_countryName) - self.assertEqual(len(entries), 1) - self.assertEqual(entries[0].get_name(), "countryName") - self.assertEqual(entries[0].get_value(), "AU") - - def test_get_issuer_stateOrProvinceName(self): - name = self.cert.get_issuer() - entries = name.get_entries_by_oid(x509_name.OID_stateOrProvinceName) - self.assertEqual(len(entries), 1) - self.assertEqual(entries[0].get_name(), "stateOrProvinceName") - self.assertEqual(entries[0].get_value(), "Some-State") - - def test_get_issuer_organizationName(self): - name = self.cert.get_issuer() - entries = name.get_entries_by_oid(x509_name.OID_organizationName) - self.assertEqual(len(entries), 1) - self.assertEqual(entries[0].get_name(), "organizationName") - self.assertEqual(entries[0].get_value(), "Herp Derp plc") - - def test_get_issuer_commonName(self): - name = self.cert.get_issuer() - entries = name.get_entries_by_oid(x509_name.OID_commonName) - self.assertEqual(len(entries), 1) - self.assertEqual(entries[0].get_name(), "commonName") - self.assertEqual(entries[0].get_value(), "herp.derp.plc") - - def test_set_subject(self): - name = x509_name.X509Name() - name.add_name_entry(x509_name.OID_countryName, 'UK') - self.cert.set_subject(name) - - name = self.cert.get_subject() - entries = name.get_entries_by_oid(x509_name.OID_countryName) - self.assertEqual(len(entries), 1) - self.assertEqual(entries[0].get_name(), "countryName") - self.assertEqual(entries[0].get_value(), "UK") - - def test_set_issuer(self): - name = x509_name.X509Name() - name.add_name_entry(x509_name.OID_countryName, 'UK') - self.cert.set_issuer(name) - - name = self.cert.get_issuer() - entries = name.get_entries_by_oid(x509_name.OID_countryName) - self.assertEqual(len(entries), 1) - self.assertEqual(entries[0].get_name(), "countryName") - self.assertEqual(entries[0].get_value(), "UK") - - def test_read_from_file(self): - open_name = 'anchor.X509.certificate.open' - f = io.StringIO(TestX509Cert.cert_data) - with mock.patch(open_name, create=True) as mock_open: - mock_open.return_value = f - - cert = certificate.X509Certificate.from_file("some_path") - name = cert.get_subject() - entries = name.get_entries_by_oid(x509_name.OID_countryName) - self.assertEqual(entries[0].get_value(), "UK") - - def test_get_fingerprint(self): - fp = self.cert.get_fingerprint() - self.assertEqual(fp, '03C6B30446157984C28A3C97F1616B96' - '5DED16744573F203A4EA51AB1AFA1F10') - - def test_get_fingerprint_invalid_hash(self): - with self.assertRaises(x509_errors.X509Error): - self.cert.get_fingerprint('no_such_hash') - - def test_get_version(self): - v = self.cert.get_version() - self.assertEqual(v, 2) - - def test_set_version(self): - self.cert.set_version(5) - v = self.cert.get_version() - self.assertEqual(v, 5) - - def test_get_not_before(self): - val = self.cert.get_not_before() - self.assertEqual(1441151225.0, val) - - def test_set_not_before(self): - self.cert.set_not_before(0) # seconds since epoch - val = self.cert.get_not_before() - self.assertEqual(0, val) - - def test_get_not_after(self): - val = self.cert.get_not_after() - self.assertEqual(1441237625.0, val) - - def test_set_not_after(self): - self.cert.set_not_after(0) # seconds since epoch - val = self.cert.get_not_after() - self.assertEqual(0, val) - - def test_get_extensions(self): - exts = self.cert.get_extensions() - self.assertEqual(3, len(exts)) - - def test_add_extensions(self): - bc = extension.X509ExtensionBasicConstraints() - self.cert.add_extension(bc, 2) - exts = self.cert.get_extensions() - self.assertEqual(3, len(exts)) - - def test_add_extensions_invalid(self): - with self.assertRaises(x509_errors.X509Error): - self.cert.add_extension("abcdef", 2) - - def test_verify_unknown_key(self): - with self.assertRaises(x509_errors.X509Error): - self.cert.verify("abc") - - def test_verify_signature_mismatch(self): - alg = asn1_univ.ObjectIdentifier('1.2.3.4') - self.cert._cert['signatureAlgorithm']['algorithm'] = alg - with self.assertRaises(x509_errors.X509Error): - self.cert.verify() - - def test_verify_algo_mismatch(self): - alg = asn1_univ.ObjectIdentifier('1.2.3.4') - self.cert._cert['signatureAlgorithm']['algorithm'] = alg - with self.assertRaises(x509_errors.X509Error): - self.cert.verify("abc") diff --git a/tests/X509/test_x509_csr.py b/tests/X509/test_x509_csr.py deleted file mode 100644 index a5c5629..0000000 --- a/tests/X509/test_x509_csr.py +++ /dev/null @@ -1,199 +0,0 @@ -# -*- coding:utf-8 -*- -# -# Copyright 2014 Hewlett-Packard Development Company, L.P. -# -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - -import io -import textwrap -import unittest - -import mock -from pyasn1_modules import rfc2459 - -from anchor.signers import cryptography_io -from anchor.X509 import errors as x509_errors -from anchor.X509 import extension -from anchor.X509 import name as x509_name -from anchor.X509 import signing_request -from anchor.X509 import utils -import tests - - -class TestX509Csr(tests.DefaultRequestMixin, unittest.TestCase): - key_rsa_data = textwrap.dedent(""" - -----BEGIN RSA PRIVATE KEY----- - MIICXAIBAAKBgQCeeqg1Qeccv8hqj1BP9KEJX5QsFCxR62M8plPb5t4sLo8UYfZd - 6kFLcOP8xzwwvx/eFY6Sux52enQ197o8aMwyP77hMhZqtd8NCgLJMVlUbRhwLti0 - SkHFPic0wAg+esfXa6yhd5TxC+bti7MgV/ljA80XQxHH8xOjdOoGN0DHfQIDAQAB - AoGBAJ2ozJpe+7qgGJPaCz3f0izvBwtq7kR49fqqRZbo8HHnx7OxWVVI7LhOkKEy - 2/Bq0xsvOu1CdiXL4LynvIDIiQqLaeINzG48Rbk+0HadbXblt3nDkIWdYII6zHKI - W9ewX4KpHEPbrlEO9BjAlAcYsDIvFIMYpQhtQ+0R/gmZ99WJAkEAz5C2a6FIcMbE - o3aTc9ECq99zY7lxh+6aLpUdIeeHyb/QzfGDBdlbpBAkA6EcxSqp0aqH4xIQnYHa - 3P5ZCShqSwJBAMN1sb76xq94xkg2cxShPFPAE6xKRFyKqLgsBYVtulOdfOtOnjh9 - 1SK2XQQfBRIRdG4Q/gDoCP8XQHpJcWMk+FcCQDnuJqulaOVo5GrG5mJ1nCxCAh98 - G06X7lo/7dCPoRtSuMExvaK9RlFk29hTeAcjYCAPWzupyA9dtarmJg1jRT8CQCKf - gYnb8D/6+9yk0IPR/9ayCooVacCeyz48hgnZowzWs98WwQ4utAd/GED3obVOpDov - Bl9wus889i3zPoOac+cCQCZHredQcJGd4dlthbVtP2NhuPXz33JuETGR9pXtsDUZ - uX/nSq1oo9kUh/dPOz6aP5Ues1YVe3LExmExPBQfwIE= - -----END RSA PRIVATE KEY-----""").encode('ascii') - - def setUp(self): - super(TestX509Csr, self).setUp() - self.csr = signing_request.X509Csr.from_buffer( - TestX509Csr.csr_sample_bytes) - - def tearDown(self): - pass - - def test_get_pubkey(self): - pubkey = self.csr.get_pubkey() - self.assertEqual(pubkey['algorithm']['algorithm'], - rfc2459.rsaEncryption) - - def test_get_extensions(self): - exts = self.csr.get_extensions() - self.assertEqual(len(exts), 2) - self.assertFalse(exts[1].get_ca()) - self.assertIsNone(exts[1].get_path_len_constraint()) - self.assertTrue(exts[0].get_usage('digitalSignature')) - self.assertTrue(exts[0].get_usage('nonRepudiation')) - self.assertTrue(exts[0].get_usage('keyEncipherment')) - self.assertFalse(exts[0].get_usage('cRLSign')) - - def test_add_extension(self): - csr = signing_request.X509Csr() - bc = extension.X509ExtensionBasicConstraints() - san = extension.X509ExtensionSubjectAltName() - csr.add_extension(bc) - self.assertEqual(1, len(csr.get_extensions())) - csr.add_extension(bc) - self.assertEqual(1, len(csr.get_extensions())) - csr.add_extension(san) - self.assertEqual(2, len(csr.get_extensions())) - - def test_add_extension_invalid_type(self): - csr = signing_request.X509Csr() - with self.assertRaises(x509_errors.X509Error): - csr.add_extension(1234) - - def test_read_from_file(self): - open_name = 'anchor.X509.signing_request.open' - f = io.BytesIO(self.csr_sample_bytes) - with mock.patch(open_name, create=True) as mock_open: - mock_open.return_value = f - csr = signing_request.X509Csr.from_file("some_path") - - name = csr.get_subject() - entries = name.get_entries_by_oid(x509_name.OID_countryName) - self.assertEqual(entries[0].get_value(), "UK") - - def test_open_failure_throws(self): - open_name = 'anchor.X509.signing_request.open' - with mock.patch(open_name, create=True) as mock_open: - mock_open.side_effect = IOError(2, "No such file or directory", - "some_path") - self.assertRaisesRegexp(x509_errors.X509Error, - "Could not read file", - signing_request.X509Csr.from_file, - "some_path") - - def test_read_failure_throws(self): - f = mock.Mock() - f.read.side_effect = IOError(5, "Read failed") - self.assertRaisesRegexp(x509_errors.X509Error, - "Could not read from source", - signing_request.X509Csr.from_open_file, - f) - - def test_bad_pem_throws(self): - bad_data = ( - b"-----BEGIN SOMETHING-----\n" - b"++++++\n" - b"-----END SOMETHING-----\n" - ) - - csr = signing_request.X509Csr() - self.assertRaisesRegexp(x509_errors.X509Error, "not in PEM format", - csr.from_buffer, - bad_data) - - def test_bad_data_throws(self): - bad_data = ( - b"some bad data is " - b"EHRlc3RAYW5jaG9yLnRlc3QwTDANBgkqhkiG9w0BAQEFAAM7ADA4AjEA6m") - - csr = signing_request.X509Csr() - self.assertRaisesRegexp(x509_errors.X509Error, "No PEM data found", - csr.from_buffer, - bad_data) - - def test_get_subject_countryName(self): - name = self.csr.get_subject() - entries = name.get_entries_by_oid(x509_name.OID_countryName) - self.assertEqual(len(entries), 1) - self.assertEqual(entries[0].get_name(), "countryName") - self.assertEqual(entries[0].get_value(), "UK") - - def test_get_subject_stateOrProvinceName(self): - name = self.csr.get_subject() - entries = name.get_entries_by_oid(x509_name.OID_stateOrProvinceName) - self.assertEqual(len(entries), 1) - self.assertEqual(entries[0].get_name(), "stateOrProvinceName") - self.assertEqual(entries[0].get_value(), "Narnia") - - def test_get_subject_localityName(self): - name = self.csr.get_subject() - entries = name.get_entries_by_oid(x509_name.OID_localityName) - self.assertEqual(len(entries), 1) - self.assertEqual(entries[0].get_name(), "localityName") - self.assertEqual(entries[0].get_value(), "Funkytown") - - def test_get_subject_organizationName(self): - name = self.csr.get_subject() - entries = name.get_entries_by_oid(x509_name.OID_organizationName) - self.assertEqual(len(entries), 1) - self.assertEqual(entries[0].get_name(), "organizationName") - self.assertEqual(entries[0].get_value(), "Anchor Testing") - - def test_get_subject_organizationUnitName(self): - name = self.csr.get_subject() - entries = name.get_entries_by_oid(x509_name.OID_organizationalUnitName) - self.assertEqual(len(entries), 1) - self.assertEqual(entries[0].get_name(), "organizationalUnitName") - self.assertEqual(entries[0].get_value(), "testing") - - def test_get_subject_commonName(self): - name = self.csr.get_subject() - entries = name.get_entries_by_oid(x509_name.OID_commonName) - self.assertEqual(len(entries), 1) - self.assertEqual(entries[0].get_name(), "commonName") - self.assertEqual(entries[0].get_value(), self.csr_sample_cn) - - def test_get_subject_emailAddress(self): - name = self.csr.get_subject() - entries = name.get_entries_by_oid(x509_name.OID_pkcs9_emailAddress) - self.assertEqual(len(entries), 1) - self.assertEqual(entries[0].get_name(), "emailAddress") - self.assertEqual(entries[0].get_value(), "test@example.com") - - def test_sign(self): - key = utils.get_private_key_from_pem(self.key_rsa_data) - signer = cryptography_io.make_signer(key, 'RSA', 'SHA256') - self.csr.sign('RSA', 'SHA256', signer) - # 10 bytes is definitely enough for non malicious case, right? - self.assertEqual(b'\x16\xbd!\x9b\xfb\xfd\x10\xa1\xaf\x92', - self.csr._get_signature()[:10]) - - def test_verify(self): - self.assertTrue(self.csr.verify()) diff --git a/tests/X509/test_x509_name.py b/tests/X509/test_x509_name.py deleted file mode 100644 index f62a232..0000000 --- a/tests/X509/test_x509_name.py +++ /dev/null @@ -1,132 +0,0 @@ -# -*- coding:utf-8 -*- -# -# Copyright 2014 Hewlett-Packard Development Company, L.P. -# -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - -import unittest - -from anchor.X509 import errors as x509_errors -from anchor.X509 import name as x509_name - - -class TestX509Name(unittest.TestCase): - def setUp(self): - super(TestX509Name, self).setUp() - self.name = x509_name.X509Name() - self.name.add_name_entry(x509_name.OID_countryName, - "UK") # must be 2 chars - self.name.add_name_entry(x509_name.OID_stateOrProvinceName, "test_ST") - self.name.add_name_entry(x509_name.OID_localityName, "test_L") - self.name.add_name_entry(x509_name.OID_organizationName, "test_O") - self.name.add_name_entry(x509_name.OID_organizationalUnitName, - "test_OU") - self.name.add_name_entry(x509_name.OID_commonName, "test_CN") - self.name.add_name_entry(x509_name.OID_pkcs9_emailAddress, - "test_Email") - self.name.add_name_entry(x509_name.OID_surname, "test_SN") - self.name.add_name_entry(x509_name.OID_givenName, "test_GN") - - def tearDown(self): - pass - - def test_add_bad_entry_throws(self): - self.assertRaises(x509_errors.X509Error, - self.name.add_name_entry, - -1, "BAD_WRONG") - - def test_set_bad_c_throws(self): - self.assertRaises(x509_errors.X509Error, - self.name.add_name_entry, - x509_name.OID_countryName, "BAD_WRONG") - - def test_name_to_string(self): - val = str(self.name) - self.assertEqual(val, ("/C=UK/ST=test_ST/L=test_L/O=test_O/OU=test_OU" - "/CN=test_CN/emailAddress=test_Email/" - "SN=test_SN/GN=test_GN")) - - def test_get_countryName(self): - entries = self.name.get_entries_by_oid(x509_name.OID_countryName) - self.assertEqual(len(entries), 1) - self.assertEqual(entries[0].get_name(), "countryName") - self.assertEqual(entries[0].get_value(), "UK") - - def test_get_stateOrProvinceName(self): - entries = self.name.get_entries_by_oid( - x509_name.OID_stateOrProvinceName) - self.assertEqual(len(entries), 1) - self.assertEqual(entries[0].get_name(), "stateOrProvinceName") - self.assertEqual(entries[0].get_value(), "test_ST") - - def test_get_subject_localityName(self): - entries = self.name.get_entries_by_oid(x509_name.OID_localityName) - self.assertEqual(len(entries), 1) - self.assertEqual(entries[0].get_name(), "localityName") - self.assertEqual(entries[0].get_value(), "test_L") - - def test_get_organizationName(self): - entries = self.name.get_entries_by_oid(x509_name.OID_organizationName) - self.assertEqual(len(entries), 1) - self.assertEqual(entries[0].get_name(), "organizationName") - self.assertEqual(entries[0].get_value(), "test_O") - - def test_get_organizationUnitName(self): - entries = self.name.get_entries_by_oid( - x509_name.OID_organizationalUnitName) - self.assertEqual(len(entries), 1) - self.assertEqual(entries[0].get_name(), "organizationalUnitName") - self.assertEqual(entries[0].get_value(), "test_OU") - - def test_get_commonName(self): - entries = self.name.get_entries_by_oid(x509_name.OID_commonName) - self.assertEqual(len(entries), 1) - self.assertEqual(entries[0].get_name(), "commonName") - self.assertEqual(entries[0].get_value(), "test_CN") - - def test_get_emailAddress(self): - entries = self.name.get_entries_by_oid( - x509_name.OID_pkcs9_emailAddress) - self.assertEqual(len(entries), 1) - self.assertEqual(entries[0].get_name(), "emailAddress") - self.assertEqual(entries[0].get_value(), "test_Email") - - def test_entry_to_string(self): - entries = self.name.get_entries_by_oid( - x509_name.OID_pkcs9_emailAddress) - self.assertEqual(len(entries), 1) - self.assertEqual(str(entries[0]), "emailAddress: test_Email") - - def test_entry_length(self): - num = len(self.name) - self.assertEqual(num, 9) - - def test_entry_index_good(self): - self.assertEqual("givenName: test_GN", str(self.name[8])) - - def test_entry_index_bad(self): - with self.assertRaises(IndexError): - self.name[9] - - def test_entry_itter(self): - val = [str(e) for e in self.name] - self.assertEqual("countryName: UK", val[0]) - self.assertEqual("givenName: test_GN", val[8]) - - def test_deep_clone(self): - orig = x509_name.X509Name() - orig.add_name_entry(x509_name.OID_countryName, "UK") - clone = x509_name.X509Name(orig._name_obj) - self.assertEqual(str(orig), str(clone)) - clone.add_name_entry(x509_name.OID_stateOrProvinceName, "test_ST") - self.assertNotEqual(str(orig), str(clone)) diff --git a/tests/__init__.py b/tests/__init__.py deleted file mode 100644 index 6db0be4..0000000 --- a/tests/__init__.py +++ /dev/null @@ -1,102 +0,0 @@ -# -*- coding:utf-8 -*- -# -# Copyright 2014 Hewlett-Packard Development Company, L.P. -# -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - - -import logging -import textwrap - -# NOTE(tkelsey): by default Python 2.7 has no default logging handler -# this fixes the "No handler for logger ..." message spam -# -handler = logging.NullHandler() -logging.getLogger().addHandler(handler) - - -class DefaultConfigMixin(object): - """Mixin for reuse in any test class which needs to load a config. - - `sample_conf` is always a valid, no thrills configuration. It can be - reused in any test case. Constructing it in setUp() guarantees that it - can be changed without affecting other tests. - """ - - def setUp(self): - self.sample_conf_auth = { - "default_auth": { - "backend": "static", - "user": "myusername", - "secret": "simplepassword" - } - } - self.sample_conf_ca = { - "default_ca": { - "backend": "anchor", - "cert_path": "tests/CA/root-ca.crt", - "key_path": "tests/CA/root-ca-unwrapped.key", - "output_path": "certs", - "signing_hash": "sha256", - "valid_hours": 24 - } - } - self.sample_conf_validators = { - "common_name": { - "allowed_domains": [".example.com"] - } - } - self.sample_conf_fixups = { - } - self.sample_conf_ra = { - "default_ra": { - "authentication": "default_auth", - "signing_ca": "default_ca", - "validators": self.sample_conf_validators, - "fixups": self.sample_conf_fixups, - } - } - self.sample_conf = { - "authentication": self.sample_conf_auth, - "signing_ca": self.sample_conf_ca, - "registration_authority": self.sample_conf_ra, - } - - super(DefaultConfigMixin, self).setUp() - - -class DefaultRequestMixin(object): - # CN=server1.example.com - # 2048 RSA, basicConstraints, keyUsage exts - csr_sample_cn = 'server1.example.com' - csr_sample = textwrap.dedent(""" - -----BEGIN CERTIFICATE REQUEST----- - MIIDDjCCAfYCAQAwgZwxCzAJBgNVBAYTAlVLMQ8wDQYDVQQIEwZOYXJuaWExEjAQ - BgNVBAcTCUZ1bmt5dG93bjEXMBUGA1UEChMOQW5jaG9yIFRlc3RpbmcxEDAOBgNV - BAsTB3Rlc3RpbmcxHDAaBgNVBAMTE3NlcnZlcjEuZXhhbXBsZS5jb20xHzAdBgkq - hkiG9w0BCQEWEHRlc3RAZXhhbXBsZS5jb20wggEiMA0GCSqGSIb3DQEBAQUAA4IB - DwAwggEKAoIBAQDhQloUTMZwBFgbseH5vk4S+mgqwyZDytu9S6x7YPv4aav/FTQd - W/RJB07YvUIZSJ50YScNSzXrtjqqifjdvnyiVYpS+vP8/yZIclJt8BNLwA3ESvHO - 75leRhSahxMkIMW7WfaV4ys8jkGDx3fISCn/jo5zelaLXaiHAzGRRMKefWmy54lX - W6jh1caoadRsnFQbAmAljW0JNQ53Sr2KOwVu6I8/IJ9PcT16D0WembvuOsNZZ8V9 - y2FYiJ4FYesN9JGoKvBC8U1pr+FXpNfEdaniNbfRsz5gCsap3mxMMLKlFS7AB2ar - zw5awegV9M7gMYkg4e6HWl33fS+kt/zSC53rAgMBAAGgLDAqBgkqhkiG9w0BCQ4x - HTAbMAsGA1UdDwQEAwIF4DAMBgNVHRMBAf8EAjAAMA0GCSqGSIb3DQEBCwUAA4IB - AQArTSUNFZHqUnCL+TLVgDSq9oaSutO3vu1g+EKfFxN2rG5HrxbAc2eC8TaMfUVd - D2JaEkhi9X7wPpVKIVwMo4nYVO8ke1MdXRLecNzLRT4sC40ZuOoDxOFEzm5BibGv - OLty0xKx3fylL0qa+wMXQNDWVcbq3OcJNo4v41fl4jlab4Fx5mWaCnKja+LnJT45 - 4wJQQN+UFPwvEt3Ay2UqvzVVUlJ3tO30f5WZitlpYy9txLaV9v6xdc2N/YMgQ7Tz - DxpZNBHlkA6LWaRqAtWws3uvom7IjHGgSr7UITrOR5iO5Hrm85X7K0AT6Bu75RZL - +uYLLfj9Nb/iznREl9E3a/fN - -----END CERTIFICATE REQUEST-----""") - csr_sample_bytes = csr_sample.encode('ascii') diff --git a/tests/auth/__init__.py b/tests/auth/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/tests/auth/test_keystone.py b/tests/auth/test_keystone.py deleted file mode 100644 index f9b8aa0..0000000 --- a/tests/auth/test_keystone.py +++ /dev/null @@ -1,143 +0,0 @@ -# -*- coding:utf-8 -*- -# -# Copyright 2014 Hewlett-Packard Development Company, L.P. -# -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - -import unittest -import uuid - -import mock -import requests -import requests_mock - -from anchor.auth import keystone -from anchor.auth import results - - -class AuthKeystoneTests(unittest.TestCase): - - def setUp(self): - self.config = "anchor.jsonloader.conf._config" - self.data = {'auth': {'keystone': {'url': 'http://localhost:35357'}}} - self.json_response = { - "token": { - "audit_ids": [ - "TPDsHuK_QCaKwvkVlAer8A" - ], - "catalog": [ - { - "endpoints": [ - { - "id": "1390df96096d4bd19add44811db34397", - "interface": "public", - "region": "RegionOne", - "region_id": "RegionOne", - "url": "http://10.0.2.15:5000/v2.0" - }, - { - "id": "534bcae735614781a03069d637b21570", - "interface": "internal", - "region": "RegionOne", - "region_id": "RegionOne", - "url": "http://10.0.2.15:5000/v2.0" - }, - { - "id": "cc7e879d691e4e4b9f4afecb1a3ce8f0", - "interface": "admin", - "region": "RegionOne", - "region_id": "RegionOne", - "url": "http://10.0.2.15:35357/v2.0" - } - ], - "id": "3010a0c9af684db28659f0e9e08ee863", - "name": "keystone", - "type": "identity" - } - ], - "expires_at": "2015-07-27T02:38:09.000000Z", - "extras": {}, - "issued_at": "2015-07-27T01:38:09.409616", - "methods": [ - "password", - "token" - ], - "project": { - "domain": { - "id": "default", - "name": "Default" - }, - "id": "5b2e7bd5d5954fdaa2d931285df8a132", - "name": "demo" - }, - "roles": [ - { - "id": "35a1d29b54f64c969aa9be288ec9d39a", - "name": "anotherrole" - }, - { - "id": "9f64371fcbd64c669ab1a24686a1a367", - "name": "Member" - } - ], - "user": { - "domain": { - "id": "default", - "name": "Default" - }, - "id": "b2016b9338214cda926d5631c1fbc40c", - "name": "demo" - } - } - } - - self.user = self.json_response['token']['user']['name'] - self.roles = [role['name'] - for role in self.json_response['token']['roles']] - self.user_id = self.json_response['token']['user']['id'] - self.project_id = self.json_response['token']['project']['id'] - self.expected = results.AuthDetails( - username=self.user, groups=self.roles, - user_id=self.user_id, project_id=self.project_id) - - self.keystone_url = self.data['auth'][ - 'keystone']['url'] + '/v3/auth/tokens' - self.keystone_token = uuid.uuid4().hex - - super(AuthKeystoneTests, self).setUp() - - def tearDown(self): - pass - - def test_parse_keystone_valid_response(self): - with mock.patch.dict(self.config, self.data): - with requests_mock.mock() as m: - m.get(self.keystone_url, json=self.json_response, - status_code=200) - requests.get(self.keystone_url) - self.assertEqual(keystone.login( - None, self.keystone_token), self.expected) - - def test_parse_keystone_auth_fail(self): - with mock.patch.dict(self.config, self.data): - with requests_mock.mock() as m: - m.get(self.keystone_url, status_code=401) - self.assertEqual(keystone.login( - None, self.keystone_token), None) - - def test_parse_keystone_ok_but_malformed_response(self): - with mock.patch.dict(self.config, self.data): - with requests_mock.mock() as m: - m.get(self.keystone_url, json={}, status_code=200) - self.assertEqual(keystone.login( - None, self.keystone_token), None) diff --git a/tests/auth/test_ldap.py b/tests/auth/test_ldap.py deleted file mode 100644 index ee9889f..0000000 --- a/tests/auth/test_ldap.py +++ /dev/null @@ -1,117 +0,0 @@ -# -*- coding:utf-8 -*- -# -# Copyright 2015 Hewlett-Packard Development Company, L.P. -# -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - -import unittest - -from ldap3.core import exceptions as ldap3_exc -import mock -from webob import exc as http_status - -from anchor import auth -from anchor.auth import results -from anchor import jsonloader -import tests - - -class AuthLdapTests(tests.DefaultConfigMixin, unittest.TestCase): - - def setUp(self): - super(AuthLdapTests, self).setUp() - self.sample_conf_auth['default_auth'] = { - "backend": "ldap", - "host": "ldap.example.com", - "base": "CN=Users,DC=example,DC=com", - "domain": "example.com", - "port": 636, - "ssl": True - } - - def tearDown(self): - pass - - @mock.patch('ldap3.Connection') - def test_login_good(self, mock_connection): - """Test all static user/pass authentication paths.""" - jsonloader.conf.load_extensions() - config = "anchor.jsonloader.conf._config" - - mock_ldc = mock.Mock() - mock_connection.return_value = mock_ldc - mock_ldc.result = {'result': 0} - mock_ldc.response = [{'attributes': {}}] - - with mock.patch.dict(config, self.sample_conf): - expected = results.AuthDetails(username='user', groups=[]) - self.assertEqual(auth.validate('default_ra', 'user', 'pass'), - expected) - - @mock.patch('ldap3.Connection') - def test_login_good_with_groups(self, mock_connection): - """Test all static user/pass authentication paths.""" - jsonloader.conf.load_extensions() - config = "anchor.jsonloader.conf._config" - - mock_ldc = mock.Mock() - mock_connection.return_value = mock_ldc - mock_ldc.result = {'result': 0} - mock_ldc.response = [{'attributes': {'memberOf': [ - u'CN=some_group,OU=Groups,DC=example,DC=com', - u'CN=other_group,OU=Groups,DC=example,DC=com']}}] - - with mock.patch.dict(config, self.sample_conf): - expected = results.AuthDetails( - username='user', - groups=[u'some_group', u'other_group']) - self.assertEqual(auth.validate('default_ra', 'user', 'pass'), - expected) - - @mock.patch('ldap3.Connection') - def test_login_search_fail(self, mock_connection): - """Test all static user/pass authentication paths.""" - jsonloader.conf.load_extensions() - config = "anchor.jsonloader.conf._config" - - mock_ldc = mock.Mock() - mock_connection.return_value = mock_ldc - mock_ldc.result = {'result': 1} - - with mock.patch.dict(config, self.sample_conf): - with self.assertRaises(http_status.HTTPUnauthorized): - auth.validate('default_ra', 'user', 'pass') - - @mock.patch('ldap3.Connection') - def test_login_bind_fail(self, mock_connection): - """Test all static user/pass authentication paths.""" - jsonloader.conf.load_extensions() - config = "anchor.jsonloader.conf._config" - - mock_connection.side_effect = ldap3_exc.LDAPBindError() - - with mock.patch.dict(config, self.sample_conf): - with self.assertRaises(http_status.HTTPUnauthorized): - auth.validate('default_ra', 'user', 'pass') - - @mock.patch('ldap3.Connection') - def test_login_connection_fail(self, mock_connection): - """Test all static user/pass authentication paths.""" - jsonloader.conf.load_extensions() - config = "anchor.jsonloader.conf._config" - - mock_connection.side_effect = ldap3_exc.LDAPSocketOpenError() - - with mock.patch.dict(config, self.sample_conf): - with self.assertRaises(http_status.HTTPUnauthorized): - auth.validate('default_ra', 'user', 'pass') diff --git a/tests/auth/test_static.py b/tests/auth/test_static.py deleted file mode 100644 index edddf3c..0000000 --- a/tests/auth/test_static.py +++ /dev/null @@ -1,70 +0,0 @@ -# -*- coding:utf-8 -*- -# -# Copyright 2015 Nebula Inc. -# -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - -import unittest - -import mock -from webob import exc as http_status - -from anchor import auth -from anchor.auth import results -from anchor import jsonloader -import tests - - -class AuthStaticTests(tests.DefaultConfigMixin, unittest.TestCase): - - def setUp(self): - super(AuthStaticTests, self).setUp() - - def tearDown(self): - pass - - def test_validate_static(self): - """Test all static user/pass authentication paths.""" - jsonloader.conf.load_extensions() - config = "anchor.jsonloader.conf._config" - self.sample_conf_auth['default_auth'] = { - "backend": "static", - "user": "myusername", - "secret": "simplepassword" - } - data = self.sample_conf - - with mock.patch.dict(config, data): - valid_user = self.sample_conf_auth['default_auth']['user'] - valid_pass = self.sample_conf_auth['default_auth']['secret'] - - expected = results.AuthDetails(username=valid_user, groups=[]) - self.assertEqual(auth.validate('default_ra', valid_user, - valid_pass), expected) - with self.assertRaises(http_status.HTTPUnauthorized): - auth.validate('default_ra', valid_user, 'badpass') - with self.assertRaises(http_status.HTTPUnauthorized): - auth.validate('default_ra', 'baduser', valid_pass) - with self.assertRaises(http_status.HTTPUnauthorized): - auth.validate('default_ra', 'baduser', 'badpass') - - def test_validate_static_malformed1(self): - """Test static user/pass authentication with malformed config.""" - jsonloader.conf.load_extensions() - config = "anchor.jsonloader.conf._config" - self.sample_conf_auth['default_auth'] = {'backend': 'static'} - data = self.sample_conf - - with mock.patch.dict(config, data): - with self.assertRaises(http_status.HTTPUnauthorized): - auth.validate('default_ra', 'baduser', 'badpass') diff --git a/tests/controllers/__init__.py b/tests/controllers/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/tests/controllers/test_app.py b/tests/controllers/test_app.py deleted file mode 100644 index 6c5bab0..0000000 --- a/tests/controllers/test_app.py +++ /dev/null @@ -1,256 +0,0 @@ -# -*- coding:utf-8 -*- -# -# Copyright 2014 Hewlett-Packard Development Company, L.P. -# -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - - -import json -import os -import stat -import unittest - -import mock - -from anchor import app -from anchor import errors -from anchor import jsonloader -from anchor import util -import tests - - -class TestApp(tests.DefaultConfigMixin, unittest.TestCase): - def setUp(self): - self.expected_key_permissions = (stat.S_IRUSR | stat.S_IFREG) - jsonloader.conf.load_extensions() - super(TestApp, self).setUp() - - def tearDown(self): - jsonloader.conf._config = {} - super(TestApp, self).tearDown() - - def test_self_test(self): - self.assertTrue(True) - - @mock.patch('anchor.util.check_file_exists') - @mock.patch('anchor.util.check_file_permissions') - def test_config_check_domains_good(self, a, b): - self.sample_conf_ra['default_ra']['validators'] = { - "common_name": { - "allowed_domains": [".example.com"] - } - } - config = json.dumps(self.sample_conf) - jsonloader.conf.load_str_data(config) - - config = {'return_value.st_mode': (stat.S_IRUSR | stat.S_IFREG)} - with mock.patch("os.stat", **config): - self.assertEqual(app.validate_config(jsonloader.conf), None) - - @mock.patch('anchor.util.check_file_exists') - @mock.patch('anchor.util.check_file_permissions') - def test_config_check_domains_bad(self, a, b): - self.sample_conf_ra['default_ra']['validators'] = { - "common_name": { - "allowed_domains": ["error.example.com"] - } - } - config = json.dumps(self.sample_conf) - jsonloader.conf.load_str_data(config) - - config = {'return_value.st_mode': (stat.S_IRUSR | stat.S_IFREG)} - with mock.patch("os.stat", **config): - self.assertRaises( - errors.ConfigValidationException, - app.validate_config, - jsonloader.conf - ) - - def test_check_file_permissions_good(self): - config = {'return_value.st_mode': (stat.S_IRUSR | stat.S_IFREG)} - with mock.patch("os.stat", **config): - util.check_file_permissions("/mock/path") - - def test_check_file_permissions_bad(self): - config = {'return_value.st_mode': (stat.S_IWOTH | stat.S_IFREG)} - with mock.patch("os.stat", **config): - self.assertRaises(errors.ConfigValidationException, - util.check_file_permissions, "/mock/path") - - def test_validate_old_config(self): - config = json.dumps({ - "ca": {}, - "auth": {}, - "validators": {}, - }) - jsonloader.conf.load_str_data(config) - self.assertRaisesRegexp(errors.ConfigValidationException, - "old version of Anchor", - app.validate_config, jsonloader.conf) - - @mock.patch('anchor.util.check_file_permissions') - def test_validate_config_no_registration_authorities(self, - mock_check_perm): - del self.sample_conf['registration_authority'] - config = json.dumps(self.sample_conf) - jsonloader.conf.load_str_data(config) - self.assertRaisesRegexp(errors.ConfigValidationException, - "No registration authorities present", - app.validate_config, jsonloader.conf) - - @mock.patch('anchor.util.check_file_permissions') - def test_validate_config_no_auth(self, mock_check_perm): - del self.sample_conf['authentication'] - config = json.dumps(self.sample_conf) - jsonloader.conf.load_str_data(config) - self.assertRaisesRegexp(errors.ConfigValidationException, - "No authentication methods present", - app.validate_config, jsonloader.conf) - - @mock.patch('anchor.util.check_file_permissions') - def test_validate_config_no_auth_backend(self, mock_check_perm): - del self.sample_conf_auth['default_auth']['backend'] - config = json.dumps(self.sample_conf) - jsonloader.conf.load_str_data(config) - self.assertRaisesRegexp(errors.ConfigValidationException, - "Authentication method .* doesn't define " - "backend", - app.validate_config, jsonloader.conf) - - @mock.patch('anchor.util.check_file_permissions') - def test_validate_config_no_ra_auth(self, mock_check_perm): - del self.sample_conf_ra['default_ra']['authentication'] - config = json.dumps(self.sample_conf) - jsonloader.conf.load_str_data(config) - self.assertRaisesRegexp(errors.ConfigValidationException, - "No authentication .* for .* default_ra", - app.validate_config, jsonloader.conf) - - def test_validate_config_no_ca(self): - del self.sample_conf['signing_ca'] - config = json.dumps(self.sample_conf) - jsonloader.conf.load_str_data(config) - self.assertRaisesRegexp(errors.ConfigValidationException, - "No signing CA configurations present", - app.validate_config, jsonloader.conf) - - @mock.patch('anchor.util.check_file_permissions') - def test_validate_config_no_ra_ca(self, mock_check_perm): - del self.sample_conf_ra['default_ra']['signing_ca'] - config = json.dumps(self.sample_conf) - jsonloader.conf.load_str_data(config) - self.assertRaisesRegexp(errors.ConfigValidationException, - "No signing CA .* for .* default_ra", - app.validate_config, jsonloader.conf) - - @mock.patch('anchor.util.check_file_permissions') - def test_validate_config_ca_config_reqs(self, mock_check_perm): - ca_config_requirements = ["cert_path", "key_path", "output_path", - "signing_hash", "valid_hours"] - - config = json.dumps(self.sample_conf) - jsonloader.conf.load_str_data(config) - - # Iterate through the ca_config_requirements, replace each one in turn - # with 'missing_req', perform validation. Each should raise in turn - for req in ca_config_requirements: - jsonloader.conf.load_str_data(config.replace(req, "missing_req")) - self.assertRaisesRegexp(errors.ConfigValidationException, - "CA config missing: %s" % req, - app.validate_config, jsonloader.conf) - - @mock.patch('os.path.isfile') - def test_validate_config_no_ca_cert_file(self, isfile): - config = json.dumps(self.sample_conf) - jsonloader.conf.load_str_data(config) - isfile.return_value = False - self.assertRaisesRegexp(errors.ConfigValidationException, - "could not read file: tests/CA/root-ca.crt", - app.validate_config, jsonloader.conf) - - @mock.patch('anchor.util.check_file_permissions') - @mock.patch('os.path.isfile') - @mock.patch('os.access') - @mock.patch('os.stat') - def test_validate_config_no_validators(self, stat, access, isfile, - mock_check_perm): - self.sample_conf_ra['default_ra']['validators'] = {} - config = json.dumps(self.sample_conf) - jsonloader.conf.load_str_data(config) - isfile.return_value = True - access.return_value = True - stat.return_value.st_mode = self.expected_key_permissions - self.assertRaisesRegexp(errors.ConfigValidationException, - "No validators configured", - app.validate_config, jsonloader.conf) - - @mock.patch('anchor.util.check_file_permissions') - @mock.patch('os.path.isfile') - @mock.patch('os.access') - @mock.patch('os.stat') - def test_validate_config_unknown_validator(self, stat, access, isfile, - mock_check_perm): - self.sample_conf_validators['unknown_validator'] = {} - config = json.dumps(self.sample_conf) - jsonloader.conf.load_str_data(config) - isfile.return_value = True - access.return_value = True - stat.return_value.st_mode = self.expected_key_permissions - with self.assertRaises(errors.ConfigValidationException, - msg="Unknown validator " - "found (for registration authority " - "default)"): - app.validate_config(jsonloader.conf) - - @mock.patch('anchor.util.check_file_permissions') - @mock.patch('os.path.isfile') - @mock.patch('os.access') - @mock.patch('os.stat') - def test_validate_config_good(self, stat, access, isfile, mock_check_perm): - config = json.dumps(self.sample_conf) - jsonloader.conf.load_str_data(config) - isfile.return_value = True - access.return_value = True - stat.return_value.st_mode = self.expected_key_permissions - app.validate_config(jsonloader.conf) - - @mock.patch('anchor.jsonloader.conf.load_file_data') - def test_config_paths_env(self, conf): - with mock.patch.dict('os.environ', {'ANCHOR_CONF': '/fake/fake'}): - app.load_config() - conf.assert_called_with('/fake/fake') - - @mock.patch('anchor.jsonloader.conf.load_file_data') - def test_config_paths_local(self, conf): - ret = lambda x: True if x == 'config.json' else False - with mock.patch("os.path.isfile", ret): - app.load_config() - conf.assert_called_with('config.json') - - @mock.patch('anchor.jsonloader.conf.load_file_data') - def test_config_paths_user(self, conf): - ret = (lambda x: True if x == '/fake/.config/anchor/config.json' - else False) - with mock.patch('os.path.isfile', ret): - with mock.patch.dict('os.environ', {'HOME': '/fake'}): - app.load_config() - conf.assert_called_with('/fake/.config/anchor/config.json') - - @mock.patch('anchor.jsonloader.conf.load_file_data') - def test_config_paths_system(self, conf): - path = os.path.join(os.environ.get('VIRTUAL_ENV', os.sep), - 'etc/anchor/config.json') - ret = lambda x: x == path - with mock.patch('os.path.isfile', ret): - app.load_config() - conf.assert_called_with(path) diff --git a/tests/fixups/__init__.py b/tests/fixups/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/tests/fixups/test_fixup_ensure_alternative_names_present.py b/tests/fixups/test_fixup_ensure_alternative_names_present.py deleted file mode 100644 index c68b56b..0000000 --- a/tests/fixups/test_fixup_ensure_alternative_names_present.py +++ /dev/null @@ -1,109 +0,0 @@ -# -*- coding:utf-8 -*- -# -# Copyright 2015 Hewlett-Packard Development Company, L.P. -# -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - -import unittest - -import netaddr - -from anchor import fixups -from anchor.X509 import extension -from anchor.X509 import name -from anchor.X509 import signing_request - - -class TestEnsureAlternativeNamesPresent(unittest.TestCase): - def setUp(self): - super(TestEnsureAlternativeNamesPresent, self).setUp() - - def _csr_with_cn(self, cn): - csr = signing_request.X509Csr() - subject = name.X509Name() - subject.add_name_entry(name.OID_commonName, cn) - csr.set_subject(subject) - return csr - - def test_no_cn(self): - csr = signing_request.X509Csr() - subject = name.X509Name() - subject.add_name_entry(name.OID_localityName, "somewhere") - csr.set_subject(subject) - - new_csr = fixups.enforce_alternative_names_present(csr=csr) - self.assertEqual(0, len(new_csr.get_extensions())) - - def test_cn_only_ip(self): - csr = self._csr_with_cn("1.2.3.4") - - new_csr = fixups.enforce_alternative_names_present(csr=csr) - self.assertEqual(1, len(new_csr.get_extensions())) - ext = new_csr.get_extensions(extension.X509ExtensionSubjectAltName)[0] - self.assertEqual([netaddr.IPAddress("1.2.3.4")], ext.get_ips()) - - def test_cn_only_dns(self): - csr = self._csr_with_cn("example.com") - - new_csr = fixups.enforce_alternative_names_present(csr=csr) - self.assertEqual(1, len(new_csr.get_extensions())) - ext = new_csr.get_extensions(extension.X509ExtensionSubjectAltName)[0] - self.assertEqual(["example.com"], ext.get_dns_ids()) - - def test_cn_existing_ip(self): - csr = self._csr_with_cn("1.2.3.4") - san = extension.X509ExtensionSubjectAltName() - san.add_ip(netaddr.IPAddress("1.2.3.4")) - csr.add_extension(san) - - new_csr = fixups.enforce_alternative_names_present(csr=csr) - self.assertEqual(1, len(new_csr.get_extensions())) - ext = new_csr.get_extensions(extension.X509ExtensionSubjectAltName)[0] - self.assertEqual([netaddr.IPAddress("1.2.3.4")], ext.get_ips()) - - def test_cn_existing_dns(self): - csr = self._csr_with_cn("example.com") - san = extension.X509ExtensionSubjectAltName() - san.add_dns_id("example.com") - csr.add_extension(san) - - new_csr = fixups.enforce_alternative_names_present(csr=csr) - self.assertEqual(1, len(new_csr.get_extensions())) - ext = new_csr.get_extensions(extension.X509ExtensionSubjectAltName)[0] - self.assertEqual(["example.com"], ext.get_dns_ids()) - - def test_cn_extra_ip(self): - csr = self._csr_with_cn("1.2.3.4") - san = extension.X509ExtensionSubjectAltName() - san.add_ip(netaddr.IPAddress("2.3.4.5")) - csr.add_extension(san) - - new_csr = fixups.enforce_alternative_names_present(csr=csr) - self.assertEqual(1, len(new_csr.get_extensions())) - ext = new_csr.get_extensions(extension.X509ExtensionSubjectAltName)[0] - ips = ext.get_ips() - self.assertIn(netaddr.IPAddress("1.2.3.4"), ips) - self.assertIn(netaddr.IPAddress("2.3.4.5"), ips) - - def test_cn_extra_dns(self): - csr = self._csr_with_cn("example.com") - san = extension.X509ExtensionSubjectAltName() - san.add_dns_id("other.example.com") - csr.add_extension(san) - - new_csr = fixups.enforce_alternative_names_present(csr=csr) - self.assertEqual(1, len(new_csr.get_extensions())) - ext = new_csr.get_extensions(extension.X509ExtensionSubjectAltName)[0] - ids = ext.get_dns_ids() - self.assertIn("example.com", ids) - self.assertIn("other.example.com", ids) diff --git a/tests/fixups/test_fixup_functionality.py b/tests/fixups/test_fixup_functionality.py deleted file mode 100644 index 4324fc6..0000000 --- a/tests/fixups/test_fixup_functionality.py +++ /dev/null @@ -1,84 +0,0 @@ -# -*- coding:utf-8 -*- -# -# Copyright 2014 Hewlett-Packard Development Company, L.P. -# -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - -import unittest - -import mock -import webob - -from anchor import certificate_ops -from anchor import jsonloader -from anchor.X509 import signing_request -import tests - - -class TestFixupFunctionality(tests.DefaultConfigMixin, - tests.DefaultRequestMixin, - unittest.TestCase): - def setUp(self): - super(TestFixupFunctionality, self).setUp() - jsonloader.conf.load_extensions() - self.csr = signing_request.X509Csr.from_buffer( - TestFixupFunctionality.csr_sample_bytes) - - def test_with_noop(self): - """Ensure single fixup is processed.""" - - self.sample_conf_ra['default_ra']['fixups'] = {'noop': {}} - data = self.sample_conf - - config = "anchor.jsonloader.conf._config" - mock_noop = mock.MagicMock() - mock_noop.name = "noop" - mock_noop.plugin.return_value = self.csr - - jsonloader.conf._fixups = jsonloader.conf._fixups.make_test_instance( - [mock_noop], 'anchor.fixups') - - with mock.patch.dict(config, data): - certificate_ops.fixup_csr('default_ra', self.csr, None) - - mock_noop.plugin.assert_called_with( - csr=self.csr, conf=self.sample_conf_ra['default_ra'], request=None) - - def test_with_no_fixups(self): - """Ensure no fixups is ok.""" - - self.sample_conf_ra['default_ra']['fixups'] = {} - data = self.sample_conf - - config = "anchor.jsonloader.conf._config" - with mock.patch.dict(config, data): - res = certificate_ops.fixup_csr('default_ra', self.csr, None) - self.assertIs(res, self.csr) - - def test_with_broken_fixup(self): - """Ensure broken fixups stop processing.""" - - self.sample_conf_ra['default_ra']['fixups'] = {'broken': {}} - data = self.sample_conf - - config = "anchor.jsonloader.conf._config" - mock_noop = mock.MagicMock() - mock_noop.name = "broken" - mock_noop.plugin.side_effects = Exception("BOOM") - - jsonloader.conf._fixups = jsonloader.conf._fixups.make_test_instance( - [mock_noop], 'anchor.fixups') - - with mock.patch.dict(config, data): - with self.assertRaises(webob.exc.WSGIHTTPException): - certificate_ops.fixup_csr('default_ra', self.csr, None) diff --git a/tests/test_certificate_ops.py b/tests/test_certificate_ops.py deleted file mode 100644 index faf96a7..0000000 --- a/tests/test_certificate_ops.py +++ /dev/null @@ -1,148 +0,0 @@ -# -*- coding:utf-8 -*- -# -# Copyright 2015 Nebula Inc. -# -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - -import unittest - -import mock -from webob import exc as http_status - -from anchor import certificate_ops -from anchor import jsonloader -from anchor.X509 import name as x509_name -import tests - - -class CertificateOpsTests(tests.DefaultConfigMixin, tests.DefaultRequestMixin, - unittest.TestCase): - - def setUp(self): - jsonloader.conf.load_extensions() - super(CertificateOpsTests, self).setUp() - - def tearDown(self): - pass - - def test_parse_csr_success1(self): - """Test basic success path for parse_csr.""" - result = certificate_ops.parse_csr(self.csr_sample, 'pem') - subject = result.get_subject() - actual_cn = subject.get_entries_by_oid( - x509_name.OID_commonName)[0].get_value() - self.assertEqual(actual_cn, self.csr_sample_cn) - - def test_parse_csr_success2(self): - """Test basic success path for parse_csr.""" - result = certificate_ops.parse_csr(self.csr_sample, 'PEM') - subject = result.get_subject() - actual_cn = subject.get_entries_by_oid( - x509_name.OID_commonName)[0].get_value() - self.assertEqual(actual_cn, self.csr_sample_cn) - - def test_parse_csr_fail1(self): - """Test invalid CSR format (wrong value) for parse_csr.""" - with self.assertRaises(http_status.HTTPClientError): - certificate_ops.parse_csr(self.csr_sample, 'blah') - - def test_parse_csr_fail2(self): - """Test invalid CSR format (wrong type) for parse_csr.""" - with self.assertRaises(http_status.HTTPClientError): - certificate_ops.parse_csr(self.csr_sample, True) - - def test_parse_csr_fail3(self): - """Test invalid CSR (None) format for parse_csr.""" - with self.assertRaises(http_status.HTTPClientError): - certificate_ops.parse_csr(None, 'pem') - - def test_parse_csr_fail4(self): - """Test invalid CSR (wrong value) format for parse_csr.""" - with self.assertRaises(http_status.HTTPClientError): - certificate_ops.parse_csr('invalid csr input', 'pem') - - def test_validate_csr_success(self): - """Test basic success path for validate_csr.""" - csr_obj = certificate_ops.parse_csr(self.csr_sample, 'pem') - config = "anchor.jsonloader.conf._config" - self.sample_conf_ra['default_ra']['validators'] = {'extensions': { - 'allowed_extensions': ['basicConstraints', 'keyUsage']}} - data = self.sample_conf - - with mock.patch.dict(config, data): - certificate_ops.validate_csr('default_ra', None, csr_obj, None) - - def test_validate_csr_bypass(self): - """Test empty validator set for validate_csr.""" - csr_obj = certificate_ops.parse_csr(self.csr_sample, 'pem') - config = "anchor.jsonloader.conf._config" - self.sample_conf_ra['default_ra']['validators'] = {} - data = self.sample_conf - - with mock.patch.dict(config, data): - # this should work, it allows people to bypass validation - certificate_ops.validate_csr('default_ra', None, csr_obj, None) - - def test_validate_csr_fail(self): - """Test failure path for validate_csr.""" - csr_obj = certificate_ops.parse_csr(self.csr_sample, 'pem') - config = "anchor.jsonloader.conf._config" - self.sample_conf_ra['default_ra']['validators'] = { - 'common_name': { - 'allowed_domains': ['.testing.example.com'] - } - } - data = self.sample_conf - - with mock.patch.dict(config, data): - with self.assertRaises(http_status.HTTPException) as cm: - certificate_ops.validate_csr('default_ra', None, csr_obj, None) - self.assertEqual(cm.exception.code, 400) - - def test_ca_cert_read_failure(self): - """Test CA certificate read failure.""" - csr_obj = certificate_ops.parse_csr(self.csr_sample, 'pem') - config = "anchor.jsonloader.conf._config" - ca_conf = self.sample_conf_ca['default_ca'] - ca_conf['cert_path'] = '/xxx/not/a/valid/path' - ca_conf['key_path'] = 'tests/CA/root-ca-unwrapped.key' - data = self.sample_conf - - with mock.patch.dict(config, data): - with self.assertRaises(http_status.HTTPException) as cm: - certificate_ops.dispatch_sign('default_ra', csr_obj) - self.assertEqual(cm.exception.code, 500) - - def test_ca_key_read_failure(self): - """Test CA key read failure.""" - csr_obj = certificate_ops.parse_csr(self.csr_sample, 'pem') - config = "anchor.jsonloader.conf._config" - self.sample_conf_ca['default_ca']['cert_path'] = 'tests/CA/root-ca.crt' - self.sample_conf_ca['default_ca']['key_path'] = '/xxx/not/a/valid/path' - data = self.sample_conf - - with mock.patch.dict(config, data): - with self.assertRaises(http_status.HTTPException) as cm: - certificate_ops.dispatch_sign('default_ra', csr_obj) - self.assertEqual(cm.exception.code, 500) - - def test_ca_cert_not_configured(self): - """Test CA cert read failure.""" - config = "anchor.jsonloader.conf._config" - self.sample_conf_ca['default_ca']['cert_path'] = None - data = self.sample_conf - - with mock.patch.dict(config, data): - with self.assertRaises(http_status.HTTPException) as cm: - certificate_ops.get_ca('default_ra') - self.assertEqual(cm.exception.code, 404) diff --git a/tests/test_config.py b/tests/test_config.py deleted file mode 100644 index 7f25839..0000000 --- a/tests/test_config.py +++ /dev/null @@ -1,98 +0,0 @@ -# -*- coding:utf-8 -*- -# -# Copyright 2015 Hewlett-Packard Development Company, L.P. -# -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - -from anchor import jsonloader - -import json -import logging -import sys -import unittest - -import mock - -import tests - - -logger = logging.getLogger(__name__) - -# find the class representing an open file; it depends on the python version -# it's used later for mocking -if sys.version_info[0] < 3: - file_class = file # noqa -else: - import _io - file_class = _io.TextIOWrapper - - -class TestConfig(tests.DefaultConfigMixin, unittest.TestCase): - def test_wrong_key(self): - """Wrong config key should raise the right error.""" - jsonloader.conf = jsonloader.AnchorConf(logger) - - with self.assertRaises(AttributeError): - jsonloader.conf.abcdef - - def test_load_file(self): - """Test loading of a correct configuration.""" - jsonloader.conf = jsonloader.AnchorConf(logger) - - open_name = 'anchor.jsonloader.open' - with mock.patch(open_name, create=True) as mock_open: - mock_open.return_value = mock.MagicMock(spec=file_class) - m_file = mock_open.return_value.__enter__.return_value - m_file.read.return_value = json.dumps(self.sample_conf) - - jsonloader.conf.load_file_data('/tmp/impossible_path') - - self.assertEqual( - (jsonloader.conf.registration_authority['default_ra'] - ['authentication']), - 'default_auth') - self.assertEqual( - jsonloader.conf.signing_ca['default_ca']['valid_hours'], - 24) - - def test_load_file_cant_open(self): - """Test failures when opening files.""" - jsonloader.conf = jsonloader.AnchorConf(logger) - - open_name = 'anchor.jsonloader.open' - with mock.patch(open_name, create=True) as mock_open: - mock_open.return_value = mock.MagicMock(spec=file_class) - mock_open.side_effect = IOError("can't open file") - - with self.assertRaises(IOError): - jsonloader.conf.load_file_data('/tmp/impossible_path') - - def test_load_file_cant_parse(self): - """Test failues when parsing json format.""" - jsonloader.conf = jsonloader.AnchorConf(logger) - - open_name = 'anchor.jsonloader.open' - with mock.patch(open_name, create=True) as mock_open: - mock_open.return_value = mock.MagicMock(spec=file_class) - m_file = mock_open.return_value.__enter__.return_value - m_file.read.return_value = "{{{{ bad json" - - with self.assertRaises(ValueError): - jsonloader.conf.load_file_data('/tmp/impossible_path') - - def test_registration_authority_names(self): - """Instances should be listed once config is loaded.""" - jsonloader.conf = jsonloader.AnchorConf(logger) - jsonloader.conf.load_str_data(json.dumps(self.sample_conf)) - self.assertEqual(list(jsonloader.registration_authority_names()), - ['default_ra']) diff --git a/tests/test_functional.py b/tests/test_functional.py deleted file mode 100644 index b05b7f9..0000000 --- a/tests/test_functional.py +++ /dev/null @@ -1,149 +0,0 @@ -# -*- coding:utf-8 -*- -# -# Copyright 2014 Hewlett-Packard Development Company, L.P. -# -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - -import copy -import json -import os -import stat -import tempfile -import unittest - -import mock -import pecan -from pecan import testing as pecan_testing -import stevedore - -from anchor import config -from anchor import jsonloader -from anchor.X509 import certificate as X509_cert -import tests - - -class TestFunctional(tests.DefaultConfigMixin, tests.DefaultRequestMixin, - unittest.TestCase): - def setUp(self): - super(TestFunctional, self).setUp() - - # Load config from json test config - jsonloader.conf.load_str_data(json.dumps(self.sample_conf)) - jsonloader.conf.load_extensions() - self.conf = jsonloader.conf._config - ca_conf = self.conf["signing_ca"]["default_ca"] - ca_conf["output_path"] = tempfile.mkdtemp() - - # Set CA file permissions - os.chmod(ca_conf["cert_path"], stat.S_IRUSR | stat.S_IFREG) - os.chmod(ca_conf["key_path"], stat.S_IRUSR | stat.S_IFREG) - - app_conf = {"app": copy.deepcopy(config.app), - "logging": copy.deepcopy(config.logging)} - self.app = pecan_testing.load_test_app(app_conf) - - def tearDown(self): - pecan.set_config({}, overwrite=True) - self.app.reset() - - def test_check_unauthorised(self): - resp = self.app.post('/v1/sign/default_ra', expect_errors=True) - self.assertEqual(401, resp.status_int) - - def test_robots(self): - resp = self.app.get('/robots.txt') - self.assertEqual(200, resp.status_int) - self.assertEqual("User-agent: *\nDisallow: /\n", resp.text) - - def test_check_missing_csr(self): - data = {'user': 'myusername', - 'secret': 'simplepassword', - 'encoding': 'pem'} - - resp = self.app.post('/v1/sign/default_ra', data, expect_errors=True) - self.assertEqual(400, resp.status_int) - - def test_check_unknown_instance(self): - data = {'user': 'myusername', - 'secret': 'simplepassword', - 'encoding': 'pem', - 'csr': self.csr_sample} - - resp = self.app.post('/v1/sign/unknown', data, expect_errors=True) - self.assertEqual(404, resp.status_int) - - def test_check_bad_csr(self): - data = {'user': 'myusername', - 'secret': 'simplepassword', - 'encoding': 'unknown', - 'csr': self.csr_sample} - - resp = self.app.post('/v1/sign/default_ra', data, expect_errors=True) - self.assertEqual(400, resp.status_int) - - def test_check_good_csr(self): - data = {'user': 'myusername', - 'secret': 'simplepassword', - 'encoding': 'pem', - 'csr': self.csr_sample} - - resp = self.app.post('/v1/sign/default_ra', data, expect_errors=False) - self.assertEqual(200, resp.status_int) - - cert = X509_cert.X509Certificate.from_buffer(resp.text) - - # make sure the cert is what we asked for - self.assertEqual(("/C=UK/ST=Narnia/L=Funkytown/O=Anchor Testing" - "/OU=testing/CN=server1.example.com" - "/emailAddress=test@example.com"), - str(cert.get_subject())) - - # make sure the cert was issued by anchor - self.assertEqual("/C=AU/ST=Some-State/O=Herp Derp plc/OU" - "=herp.derp.plc/CN=herp.derp.plc", - str(cert.get_issuer())) - - def test_check_broken_validator(self): - data = {'user': 'myusername', - 'secret': 'simplepassword', - 'encoding': 'pem', - 'csr': self.csr_sample} - - derp = mock.MagicMock() - derp.side_effect = Exception("BOOM") - - derp_ext = stevedore.extension.Extension("broken_validator", None, - derp, None) - manager = jsonloader.conf._validators.make_test_instance([derp_ext]) - jsonloader.conf._validators = manager - - ra = jsonloader.conf.registration_authority['default_ra'] - ra['validators'] = {"broken_validator": {}} - - resp = self.app.post('/v1/sign/default_ra', data, expect_errors=True) - self.assertEqual(500, resp.status_int) - self.assertTrue(("Internal Validation Error") in str(resp)) - self.assertTrue(derp.called) - - def test_get_ca(self): - data = {'encoding': 'pem'} - - resp = self.app.get('/v1/ca/default_ra', data, expect_errors=False) - self.assertEqual(200, resp.status_int) - - cert = X509_cert.X509Certificate.from_buffer(resp.text) - - # make sure the cert is what we asked for - self.assertEqual("/C=AU/ST=Some-State/O=Herp Derp plc/OU" - "=herp.derp.plc/CN=herp.derp.plc", - str(cert.get_subject())) diff --git a/tests/test_signing_backend.py b/tests/test_signing_backend.py deleted file mode 100644 index 678b335..0000000 --- a/tests/test_signing_backend.py +++ /dev/null @@ -1,265 +0,0 @@ -# -*- coding:utf-8 -*- -# -# Copyright 2015 Hewlett-Packard Development Company, L.P. -# -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - -import textwrap -import unittest - -import mock -from pyasn1.type import univ as asn1_univ - -from anchor import errors -from anchor import signers -from anchor.signers import cryptography_io -from anchor.signers import pkcs11 -from anchor import util -from anchor.X509 import certificate -from anchor.X509 import extension -from anchor.X509 import signing_request -from anchor.X509 import utils -import tests - - -class UnknownExtension(extension.X509Extension): - _oid = asn1_univ.ObjectIdentifier("1.2.3.4") - spec = asn1_univ.Null - - -class SigningBackendExtensions(tests.DefaultConfigMixin, - tests.DefaultRequestMixin, unittest.TestCase): - def test_copy_good_extensions(self): - csr = signing_request.X509Csr.from_buffer(self.csr_sample_bytes) - ext = extension.X509ExtensionSubjectAltName() - ext.add_dns_id("example.com") - csr.add_extension(ext) - - pem = signers.sign_generic(csr, self.sample_conf_ca['default_ca'], - 'RSA', lambda x: b"") - cert = certificate.X509Certificate.from_buffer(pem) - self.assertEqual(1, len(cert.get_extensions( - extension.X509ExtensionSubjectAltName))) - - def test_ignore_unknown_extensions(self): - csr = signing_request.X509Csr.from_buffer(self.csr_sample_bytes) - ext = UnknownExtension() - csr.add_extension(ext) - - pem = signers.sign_generic(csr, self.sample_conf_ca['default_ca'], - 'RSA', lambda x: b"") - cert = certificate.X509Certificate.from_buffer(pem) - self.assertEqual(0, len(cert.get_extensions(UnknownExtension))) - - def test_fail_critical_unknown_extensions(self): - csr = signing_request.X509Csr.from_buffer(self.csr_sample_bytes) - ext = UnknownExtension() - ext.set_critical(True) - csr.add_extension(ext) - - with self.assertRaises(signers.SigningError): - signers.sign_generic(csr, self.sample_conf_ca['default_ca'], - 'RSA', lambda x: b"") - - -class TestCryptographyBackend(tests.DefaultConfigMixin, - tests.DefaultRequestMixin, unittest.TestCase): - key_rsa_data = textwrap.dedent(""" - -----BEGIN RSA PRIVATE KEY----- - MIICXAIBAAKBgQCeeqg1Qeccv8hqj1BP9KEJX5QsFCxR62M8plPb5t4sLo8UYfZd - 6kFLcOP8xzwwvx/eFY6Sux52enQ197o8aMwyP77hMhZqtd8NCgLJMVlUbRhwLti0 - SkHFPic0wAg+esfXa6yhd5TxC+bti7MgV/ljA80XQxHH8xOjdOoGN0DHfQIDAQAB - AoGBAJ2ozJpe+7qgGJPaCz3f0izvBwtq7kR49fqqRZbo8HHnx7OxWVVI7LhOkKEy - 2/Bq0xsvOu1CdiXL4LynvIDIiQqLaeINzG48Rbk+0HadbXblt3nDkIWdYII6zHKI - W9ewX4KpHEPbrlEO9BjAlAcYsDIvFIMYpQhtQ+0R/gmZ99WJAkEAz5C2a6FIcMbE - o3aTc9ECq99zY7lxh+6aLpUdIeeHyb/QzfGDBdlbpBAkA6EcxSqp0aqH4xIQnYHa - 3P5ZCShqSwJBAMN1sb76xq94xkg2cxShPFPAE6xKRFyKqLgsBYVtulOdfOtOnjh9 - 1SK2XQQfBRIRdG4Q/gDoCP8XQHpJcWMk+FcCQDnuJqulaOVo5GrG5mJ1nCxCAh98 - G06X7lo/7dCPoRtSuMExvaK9RlFk29hTeAcjYCAPWzupyA9dtarmJg1jRT8CQCKf - gYnb8D/6+9yk0IPR/9ayCooVacCeyz48hgnZowzWs98WwQ4utAd/GED3obVOpDov - Bl9wus889i3zPoOac+cCQCZHredQcJGd4dlthbVtP2NhuPXz33JuETGR9pXtsDUZ - uX/nSq1oo9kUh/dPOz6aP5Ues1YVe3LExmExPBQfwIE= - -----END RSA PRIVATE KEY-----""").encode('ascii') - - def test_sign_bad_md(self): - key = utils.get_private_key_from_pem(self.key_rsa_data) - with self.assertRaises(signers.SigningError): - cryptography_io.make_signer(key, "BAD", "RSA") - - def test_sign_bad_key(self): - with self.assertRaises(signers.SigningError): - cryptography_io.make_signer("BAD", "sha256", "RSA") - - -class TestPKCSBackend(unittest.TestCase): - def setUp(self): - self.good_conf = { - "cert_path": "tests/CA/root-ca.crt", - "output_path": "/somepath", - "signing_hash": "sha256", - "valid_hours": 24, - "slot": 5, - "pin": "somepin", - "key_id": "aabbccddeeff", - "pkcs11_path": "/somepath/library.so", - } - - def test_conf_checks_package(self): - with mock.patch.object(util, 'check_file_exists', return_value=True): - with mock.patch.object(pkcs11, 'import_pkcs', - side_effect=ImportError()): - with self.assertRaises(errors.ConfigValidationException): - pkcs11.conf_validator("name", self.good_conf) - - def test_conf_checks_fields(self): - for key in self.good_conf: - conf = self.good_conf.copy() - del conf[key] - with self.assertRaises(errors.ConfigValidationException): - pkcs11.conf_validator("name", conf) - - def test_conf_checks_file_permissions(self): - with mock.patch.object(util, 'check_file_exists', return_value=False): - with self.assertRaises(errors.ConfigValidationException): - pkcs11.conf_validator("name", self.good_conf) - - def test_conf_checks_library_loading(self): - class MockExc(Exception): - pass - - lib = mock.Mock() - lib.load.side_effect = MockExc() - mod = mock.Mock() - mod.PyKCS11Error = MockExc - mod.PyKCS11Lib.return_value = lib - - with mock.patch.object(util, 'check_file_exists', return_value=True): - with mock.patch.object(pkcs11, 'import_pkcs', return_value=mod): - with self.assertRaises(errors.ConfigValidationException): - pkcs11.conf_validator("name", self.good_conf) - - def test_conf_checks_valid_slot(self): - class MockExc(Exception): - pass - - lib = mock.Mock() - lib.getSlotList.return_value = [4, 6] - mod = mock.Mock() - mod.PyKCS11Error = MockExc - mod.PyKCS11Lib.return_value = lib - - with mock.patch.object(util, 'check_file_exists', return_value=True): - with mock.patch.object(pkcs11, 'import_pkcs', return_value=mod): - with self.assertRaises(errors.ConfigValidationException): - pkcs11.conf_validator("name", self.good_conf) - - def test_conf_checks_valid_pin(self): - class MockExc(Exception): - pass - - session = mock.Mock() - session.login.side_effect = MockExc() - lib = mock.Mock() - lib.getSlotList.return_value = [self.good_conf['slot']] - lib.openSession.return_value = session - mod = mock.Mock() - mod.PyKCS11Error = MockExc - mod.PyKCS11Lib.return_value = lib - - with mock.patch.object(util, 'check_file_exists', return_value=True): - with mock.patch.object(pkcs11, 'import_pkcs', return_value=mod): - with self.assertRaises(errors.ConfigValidationException): - pkcs11.conf_validator("name", self.good_conf) - - def test_conf_allows_valid(self): - session = mock.Mock() - lib = mock.Mock() - lib.getSlotList.return_value = [self.good_conf['slot']] - lib.openSession.return_value = session - mod = mock.Mock() - mod.PyKCS11Lib.return_value = lib - - with mock.patch.object(util, 'check_file_exists', return_value=True): - with mock.patch.object(pkcs11, 'import_pkcs', return_value=mod): - pkcs11.conf_validator("name", self.good_conf) - - def test_make_signer_fails(self): - with mock.patch.object(pkcs11, 'make_signer', - side_effect=signers.SigningError): - with self.assertRaises(signers.SigningError): - pkcs11.sign(mock.Mock(), self.good_conf) - - def test_sign_login_fails(self): - class MockExc(Exception): - pass - - session = mock.Mock() - session.login.side_effect = MockExc() - lib = mock.Mock() - lib.openSession.return_value = session - mod = mock.Mock() - mod.PyKCS11Error = MockExc - mod.PyKCS11Lib.return_value = lib - - with mock.patch.object(pkcs11, 'import_pkcs', return_value=mod): - with self.assertRaisesRegexp(signers.SigningError, - "pkcs11 session"): - pkcs11.sign(mock.Mock(), self.good_conf) - - def test_sign_key_missing(self): - class MockExc(Exception): - pass - - session = mock.Mock() - session.findObjects.return_value = [] - lib = mock.Mock() - lib.openSession.return_value = session - mod = mock.Mock() - mod.PyKCS11Lib.return_value = lib - - with mock.patch.object(pkcs11, 'import_pkcs', return_value=mod): - with self.assertRaisesRegexp(signers.SigningError, - "requested key"): - pkcs11.sign(mock.Mock(), self.good_conf) - - def test_sign_bad_hash(self): - session = mock.Mock() - session.findObjects.return_value = [object()] - lib = mock.Mock() - lib.openSession.return_value = session - mod = mock.Mock() - mod.PyKCS11Lib.return_value = lib - self.good_conf['signing_hash'] = 'unknown' - - with mock.patch.object(pkcs11, 'import_pkcs', return_value=mod): - with self.assertRaisesRegexp(signers.SigningError, - "hash is not supported"): - pkcs11.sign(mock.Mock(), self.good_conf) - - def test_working_signer(self): - res = b"123" - - session = mock.Mock() - session.findObjects.return_value = [object()] - session.sign.return_value = res - lib = mock.Mock() - lib.openSession.return_value = session - mod = mock.Mock() - mod.PyKCS11Lib.return_value = lib - - with mock.patch.object(pkcs11, 'import_pkcs', return_value=mod): - signer = pkcs11.make_signer((1, 2, 3), self.good_conf['slot'], - self.good_conf['pin'], - self.good_conf['pkcs11_path'], - self.good_conf['signing_hash'].upper()) - self.assertEqual(res, signer(b"data")) diff --git a/tests/validators/__init__.py b/tests/validators/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/tests/validators/test_base_validation_functions.py b/tests/validators/test_base_validation_functions.py deleted file mode 100644 index 7170a57..0000000 --- a/tests/validators/test_base_validation_functions.py +++ /dev/null @@ -1,82 +0,0 @@ -# -*- coding:utf-8 -*- -# -# Copyright 2014 Hewlett-Packard Development Company, L.P. -# -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - -import unittest - -import netaddr - -from anchor.validators import errors -from anchor.validators import utils -from anchor.X509 import name -from anchor.X509 import signing_request -import tests - - -class TestBaseValidators(tests.DefaultRequestMixin, unittest.TestCase): - def setUp(self): - super(TestBaseValidators, self).setUp() - self.csr = signing_request.X509Csr.from_buffer( - self.csr_sample_bytes) - - def tearDown(self): - super(TestBaseValidators, self).tearDown() - - def test_csr_require_cn(self): - common_name = utils.csr_require_cn(self.csr) - self.assertEqual(common_name, self.csr_sample_cn) - - self.csr.set_subject(name.X509Name()) - with self.assertRaises(errors.ValidationError): - utils.csr_require_cn(self.csr) - - def test_check_domains(self): - test_domain = 'good.example.com' - test_allowed = ['.example.com', '.example.net'] - self.assertTrue(utils.check_domains(test_domain, test_allowed)) - self.assertFalse(utils.check_domains('bad.example.org', - test_allowed)) - - def test_check_networks(self): - good_ip = netaddr.IPAddress('10.2.3.4') - bad_ip = netaddr.IPAddress('88.2.3.4') - test_allowed = ['10/8'] - self.assertTrue(utils.check_networks(good_ip, test_allowed)) - self.assertFalse(utils.check_networks(bad_ip, test_allowed)) - - def test_check_networks_invalid(self): - with self.assertRaises(TypeError): - utils.check_networks('1.2.3.4', ['10/8']) - - def test_check_networks_passthrough(self): - good_ip = netaddr.IPAddress('10.2.3.4') - self.assertTrue(utils.check_networks(good_ip, [])) - - def test_check_compare_name_pattern(self): - cases = [ - ("example.com", "example.com", False, True), - ("*.example.com", "*.example.com", False, True), - ("*.example.com", "%.example.com", True, True), - ("*.example.com", "%.example.com", False, False), - ("abc.example.com", "%.example.com", False, True), - ("abc.def.example.com", "%.example.com", False, False), - ("abc.def.example.com", "%.%.example.com", False, True), - ("host-123.example.com", "host-%.example.com", False, True), - ] - for value, pattern, wildcard, result in cases: - self.assertEqual( - result, - utils.compare_name_pattern(value, pattern, wildcard), - "checking %s against %s failed" % (value, pattern)) diff --git a/tests/validators/test_callable_validators.py b/tests/validators/test_callable_validators.py deleted file mode 100644 index a1cf714..0000000 --- a/tests/validators/test_callable_validators.py +++ /dev/null @@ -1,688 +0,0 @@ -# -*- coding:utf-8 -*- -# -# Copyright 2014 Hewlett-Packard Development Company, L.P. -# -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - -import base64 -import unittest - -import mock -import netaddr -from pyasn1.codec.der import decoder - -from anchor.asn1 import rfc5280 -from anchor.validators import custom -from anchor.validators import errors -from anchor.validators import internal -from anchor.validators import utils -from anchor.X509 import extension as x509_ext -from anchor.X509 import name as x509_name -from anchor.X509 import signing_request as x509_csr -import tests - - -class TestValidators(tests.DefaultRequestMixin, unittest.TestCase): - def setUp(self): - super(TestValidators, self).setUp() - - def tearDown(self): - super(TestValidators, self).tearDown() - - def _csr_with_cn(self, cn): - csr = x509_csr.X509Csr() - name = csr.get_subject() - name.add_name_entry(x509_name.OID_commonName, cn) - csr.set_subject(name) - return csr - - def _csr_with_san_dns(self, dns): - csr = x509_csr.X509Csr() - ext = x509_ext.X509ExtensionSubjectAltName() - ext.add_dns_id(dns) - csr.add_extension(ext) - return csr - - def test_check_networks_good(self): - allowed_networks = ['15/8', '74.125/16'] - self.assertTrue(utils.check_networks( - netaddr.IPAddress('74.125.224.64'), allowed_networks)) - - def test_check_networks_bad(self): - allowed_networks = ['15/8', '74.125/16'] - self.assertFalse(utils.check_networks( - netaddr.IPAddress('12.2.2.2'), allowed_networks)) - - def test_check_domains_empty(self): - self.assertTrue(utils.check_domains( - 'example.com', [])) - - def test_common_name_with_two_CN(self): - csr = x509_csr.X509Csr() - name = csr.get_subject() - name.add_name_entry(x509_name.OID_commonName, "dummy_value") - name.add_name_entry(x509_name.OID_commonName, "dummy_value") - csr.set_subject(name) - - with self.assertRaises(errors.ValidationError) as e: - custom.common_name( - csr=csr, - allowed_domains=[], - allowed_networks=[]) - self.assertEqual("Too many CNs in the request", str(e.exception)) - - def test_common_name_no_CN(self): - csr = x509_csr.X509Csr() - - with self.assertRaises(errors.ValidationError) as e: - custom.common_name( - csr=csr, - allowed_domains=[], - allowed_networks=[]) - self.assertEqual("Alt subjects have to exist if the main subject" - " doesn't", str(e.exception)) - - def test_common_name_good_CN(self): - csr = x509_csr.X509Csr() - name = csr.get_subject() - name.add_name_entry(x509_name.OID_commonName, "good.example.com") - csr.set_subject(name) - - self.assertEqual( - None, - custom.common_name( - csr=csr, - allowed_domains=['.example.com'], - ) - ) - - def test_common_name_bad_CN(self): - csr = x509_csr.X509Csr() - name = csr.get_subject() - name.add_name_entry(x509_name.OID_commonName, 'bad.example.org') - csr.set_subject(name) - - with self.assertRaises(errors.ValidationError) as e: - custom.common_name( - csr=csr, - allowed_domains=['.example.com']) - self.assertEqual("Domain 'bad.example.org' not allowed (does not " - "match known domains)", str(e.exception)) - - def test_common_name_ip_good(self): - csr = x509_csr.X509Csr() - name = csr.get_subject() - name.add_name_entry(x509_name.OID_commonName, '10.1.1.1') - csr.set_subject(name) - - self.assertEqual( - None, - custom.common_name( - csr=csr, - allowed_domains=['.example.com'], - allowed_networks=['10/8'] - ) - ) - - def test_common_name_ip_bad(self): - csr = x509_csr.X509Csr() - name = csr.get_subject() - name.add_name_entry(x509_name.OID_commonName, '15.1.1.1') - csr.set_subject(name) - - with self.assertRaises(errors.ValidationError) as e: - custom.common_name( - csr=csr, - allowed_domains=['.example.com'], - allowed_networks=['10/8']) - self.assertEqual("Address '15.1.1.1' not allowed (does not " - "match known networks)", str(e.exception)) - - def test_alternative_names_good_domain(self): - csr = x509_csr.X509Csr() - ext = x509_ext.X509ExtensionSubjectAltName() - ext.add_dns_id('good.example.com') - csr.add_extension(ext) - - self.assertEqual( - None, - custom.alternative_names( - csr=csr, - allowed_domains=['.example.com'], - ) - ) - - def test_alternative_names_bad_domain(self): - csr = x509_csr.X509Csr() - ext = x509_ext.X509ExtensionSubjectAltName() - ext.add_dns_id('bad.example.org') - csr.add_extension(ext) - - with self.assertRaises(errors.ValidationError) as e: - custom.alternative_names( - csr=csr, - allowed_domains=['.example.com']) - self.assertEqual("Domain 'bad.example.org' not allowed (doesn't " - "match known domains)", str(e.exception)) - - def test_alternative_names_ip_good(self): - csr = x509_csr.X509Csr() - ext = x509_ext.X509ExtensionSubjectAltName() - ext.add_ip(netaddr.IPAddress('10.1.1.1')) - csr.add_extension(ext) - - self.assertEqual( - None, - custom.alternative_names_ip( - csr=csr, - allowed_domains=['.example.com'], - allowed_networks=['10/8'] - ) - ) - - def test_alternative_names_ip_bad(self): - csr = x509_csr.X509Csr() - ext = x509_ext.X509ExtensionSubjectAltName() - ext.add_ip(netaddr.IPAddress('10.1.1.1')) - csr.add_extension(ext) - - with self.assertRaises(errors.ValidationError) as e: - custom.alternative_names_ip( - csr=csr, - allowed_domains=['.example.com'], - allowed_networks=['99/8']) - self.assertEqual("IP '10.1.1.1' not allowed (doesn't match known " - "networks)", str(e.exception)) - - def test_alternative_names_ip_bad_domain(self): - csr = x509_csr.X509Csr() - ext = x509_ext.X509ExtensionSubjectAltName() - ext.add_dns_id('bad.example.org') - csr.add_extension(ext) - - with self.assertRaises(errors.ValidationError) as e: - custom.alternative_names_ip( - csr=csr, - allowed_domains=['.example.com']) - self.assertEqual("Domain 'bad.example.org' not allowed (doesn't " - "match known domains)", str(e.exception)) - - def test_server_group_no_prefix1(self): - csr = x509_csr.X509Csr() - name = csr.get_subject() - name.add_name_entry(x509_name.OID_commonName, "master.example.com") - csr.set_subject(name) - - self.assertEqual( - None, - custom.server_group( - auth_result=None, - csr=csr, - group_prefixes={} - ) - ) - - def test_server_group_no_prefix2(self): - csr = x509_csr.X509Csr() - name = csr.get_subject() - name.add_name_entry(x509_name.OID_commonName, "nv_master.example.com") - csr.set_subject(name) - - self.assertEqual( - None, - custom.server_group( - auth_result=None, - csr=csr, - group_prefixes={} - ) - ) - - def test_server_group_good_prefix(self): - # 'nv' in prefix means only Nova members should be able to issue - auth_result = mock.Mock() - auth_result.groups = ['nova'] - - csr = x509_csr.X509Csr() - name = csr.get_subject() - name.add_name_entry(x509_name.OID_commonName, "nv_master.example.com") - csr.set_subject(name) - - self.assertEqual( - None, - custom.server_group( - auth_result=auth_result, - csr=csr, - group_prefixes={'nv': 'nova', 'sw': 'swift'} - ) - ) - - def test_server_group_bad(self): - auth_result = mock.Mock() - auth_result.groups = ['glance'] - - csr = x509_csr.X509Csr() - name = csr.get_subject() - name.add_name_entry(x509_name.OID_commonName, "nv-master.example.com") - csr.set_subject(name) - - with self.assertRaises(errors.ValidationError) as e: - custom.server_group( - auth_result=auth_result, - csr=csr, - group_prefixes={'nv': 'nova', 'sw': 'swift'}) - self.assertEqual("Server prefix doesn't match user groups", - str(e.exception)) - - def test_extensions_bad(self): - csr = x509_csr.X509Csr() - ext = x509_ext.X509ExtensionKeyUsage() - ext.set_usage('keyCertSign', True) - csr.add_extension(ext) - - with self.assertRaises(errors.ValidationError) as e: - custom.extensions( - csr=csr, - allowed_extensions=['basicConstraints', 'nameConstraints']) - self.assertEqual("Extension 'keyUsage' not allowed", str(e.exception)) - - def test_extensions_good_name(self): - csr = x509_csr.X509Csr() - ext = x509_ext.X509ExtensionKeyUsage() - ext.set_usage('keyCertSign', True) - csr.add_extension(ext) - - self.assertEqual( - None, - custom.extensions( - csr=csr, - allowed_extensions=['basicConstraints', 'keyUsage'] - ) - ) - - def test_extensions_good_oid(self): - csr = x509_csr.X509Csr() - ext = x509_ext.X509ExtensionKeyUsage() - ext.set_usage('keyCertSign', True) - csr.add_extension(ext) - - self.assertEqual( - None, - custom.extensions( - csr=csr, - allowed_extensions=['basicConstraints', '2.5.29.15'] - ) - ) - - def test_key_usage_bad(self): - allowed_usage = ['Digital Signature', - 'Non Repudiation', - 'Key Encipherment'] - - csr = x509_csr.X509Csr() - ext = x509_ext.X509ExtensionKeyUsage() - ext.set_usage('keyCertSign', True) - csr.add_extension(ext) - - with self.assertRaises(errors.ValidationError) as e: - custom.key_usage( - csr=csr, - allowed_usage=allowed_usage) - self.assertEqual("Found some prohibited key usages: " - "keyCertSign", str(e.exception)) - - def test_key_usage_good(self): - allowed_usage = ['Digital Signature', - 'Non Repudiation', - 'Key Encipherment'] - - csr = x509_csr.X509Csr() - ext = x509_ext.X509ExtensionKeyUsage() - ext.set_usage('keyEncipherment', True) - ext.set_usage('digitalSignature', True) - csr.add_extension(ext) - - self.assertEqual( - None, - custom.key_usage( - csr=csr, - allowed_usage=allowed_usage - ) - ) - - def test_ext_key_usage_good_short(self): - allowed_usage = ['serverAuth'] - - csr = x509_csr.X509Csr() - ext = x509_ext.X509ExtensionExtendedKeyUsage() - ext.set_usage(rfc5280.id_kp_serverAuth, True) - csr.add_extension(ext) - - self.assertEqual( - None, - custom.ext_key_usage( - csr=csr, - allowed_usage=allowed_usage - ) - ) - - def test_ext_key_usage_good_long(self): - allowed_usage = ['TLS Web Server Authentication'] - - csr = x509_csr.X509Csr() - ext = x509_ext.X509ExtensionExtendedKeyUsage() - ext.set_usage(rfc5280.id_kp_serverAuth, True) - csr.add_extension(ext) - - self.assertEqual( - None, - custom.ext_key_usage( - csr=csr, - allowed_usage=allowed_usage - ) - ) - - def test_ext_key_usage_good_oid(self): - allowed_usage = ["1.3.6.1.5.5.7.3.1"] - - csr = x509_csr.X509Csr() - ext = x509_ext.X509ExtensionExtendedKeyUsage() - ext.set_usage(rfc5280.id_kp_serverAuth, True) - csr.add_extension(ext) - - self.assertEqual( - None, - custom.ext_key_usage( - csr=csr, - allowed_usage=allowed_usage - ) - ) - - def test_ext_key_usage_bad(self): - allowed_usage = ['serverAuth'] - - csr = x509_csr.X509Csr() - ext = x509_ext.X509ExtensionExtendedKeyUsage() - ext.set_usage(rfc5280.id_kp_clientAuth, True) - csr.add_extension(ext) - - with self.assertRaises(errors.ValidationError) as e: - custom.ext_key_usage( - csr=csr, - allowed_usage=allowed_usage) - self.assertEqual("Found some prohibited key usages: " - "clientAuth", str(e.exception)) - - def test_ca_status_good(self): - csr = x509_csr.X509Csr() - ext = x509_ext.X509ExtensionBasicConstraints() - ext.set_ca(False) - csr.add_extension(ext) - - self.assertIsNone(internal.ca_status(csr=csr)) - - def test_ca_status_forbidden(self): - csr = x509_csr.X509Csr() - ext = x509_ext.X509ExtensionBasicConstraints() - ext.set_ca(True) - csr.add_extension(ext) - - with self.assertRaises(errors.ValidationError) as e: - internal.ca_status(csr=csr) - self.assertEqual("Request is for a CA certificate", - str(e.exception)) - - def test_ca_status_pathlen(self): - csr = x509_csr.X509Csr() - ext = x509_ext.X509ExtensionBasicConstraints() - ext.set_path_len_constraint(1) - csr.add_extension(ext) - - self.assertIsNone(internal.ca_status(csr=csr)) - - def test_ca_status_key_usage_bad1(self): - csr = x509_csr.X509Csr() - ext = x509_ext.X509ExtensionKeyUsage() - ext.set_usage('keyCertSign', True) - csr.add_extension(ext) - - with self.assertRaises(errors.ValidationError) as e: - internal.ca_status(csr=csr) - self.assertEqual("Request contains certificates signing usage flag", - str(e.exception)) - - def test_ca_status_key_usage_bad2(self): - csr = x509_csr.X509Csr() - ext = x509_ext.X509ExtensionKeyUsage() - ext.set_usage('cRLSign', True) - csr.add_extension(ext) - - with self.assertRaises(errors.ValidationError) as e: - internal.ca_status(csr=csr) - self.assertEqual("Request contains CRL signing usage flag", - str(e.exception)) - - def test_source_cidrs_good(self): - request = mock.Mock(client_addr='127.0.0.1') - self.assertEqual( - None, - custom.source_cidrs( - request=request, - cidrs=['127/8', '10/8'] - ) - ) - - def test_source_cidrs_out_of_range(self): - request = mock.Mock(client_addr='99.0.0.1') - with self.assertRaises(errors.ValidationError) as e: - custom.source_cidrs( - request=request, - cidrs=['127/8', '10/8']) - self.assertEqual("No network matched the request source '99.0.0.1'", - str(e.exception)) - - def test_source_cidrs_bad_cidr(self): - request = mock.Mock(client_addr='127.0.0.1') - with self.assertRaises(errors.ValidationError) as e: - custom.source_cidrs( - request=request, - cidrs=['bad']) - self.assertEqual("Cidr 'bad' does not describe a valid network", - str(e.exception)) - - def test_blacklist_names_good(self): - csr = x509_csr.X509Csr() - ext = x509_ext.X509ExtensionSubjectAltName() - ext.add_dns_id('good.example.com') - csr.add_extension(ext) - - self.assertEqual( - None, - custom.blacklist_names( - csr=csr, - domains=['.example.org'], - ) - ) - - def test_blacklist_names_bad(self): - csr = x509_csr.X509Csr() - ext = x509_ext.X509ExtensionSubjectAltName() - ext.add_dns_id('bad.example.com') - csr.add_extension(ext) - - with self.assertRaises(errors.ValidationError): - custom.blacklist_names( - csr=csr, - domains=['.example.com'], - ) - - def test_blacklist_names_bad_cn(self): - csr = x509_csr.X509Csr() - name = csr.get_subject() - name.add_name_entry(x509_name.OID_commonName, "bad.example.com") - csr.set_subject(name) - - with self.assertRaises(errors.ValidationError): - custom.blacklist_names( - csr=csr, - domains=['.example.com'], - ) - - def test_blacklist_names_mix(self): - csr = x509_csr.X509Csr() - ext = x509_ext.X509ExtensionSubjectAltName() - ext.add_dns_id('bad.example.org') - ext.add_dns_id('good.example.com') - csr.add_extension(ext) - - with self.assertRaises(errors.ValidationError): - custom.blacklist_names( - csr=csr, - domains=['.example.org'], - ) - - def test_blacklist_names_empty_list(self): - # empty blacklist should pass everything through - csr = x509_csr.X509Csr() - ext = x509_ext.X509ExtensionSubjectAltName() - ext.add_dns_id('good.example.com') - csr.add_extension(ext) - - self.assertEqual( - None, - custom.blacklist_names( - csr=csr, - ) - ) - - def test_public_key_good_rsa(self): - csr = x509_csr.X509Csr.from_buffer(self.csr_sample_bytes) - self.assertIsNone(custom.public_key(csr=csr, - allowed_keys={'RSA': 1024})) - - def test_public_key_good_dsa(self): - dsa_key_pem = """ - MIIBtjCCASsGByqGSM44BAEwggEeAoGBAJv/ZwltxEMrACE71R+AvxOuvWgTIKAd - iVq9ATbcuiaMq5P+iyhsI0k5A29bLNxkU/kkUCBYEEOoM2R1+8eO6UVr40+dtVw8 - OzqHI6nFVmWMNUDGdPFoIIWsh5KRavhgy3Z8CKDqvGf4hxR1QWEN4Jz51xtHS3fI - 1SKJybWdu2ifAhUAgoQ1AiWH9zLU6AOafUdv6iNdxKsCgYA66IS+XsIZwQvkHJkA - rf9hbOGC8aZeuafm7PlU6C+7TRB+7hoPzrwkn0ROYhv3yGsFYKWBEjAorW/skNJQ - cmdPsZV9tGdkfyvj5lxmAAbu+4ofozUvwKlSvpa/e/PLY7aZCq8u+fSHsF+xpUNl - GlCRV1DL13tDWZb+XS8w7RD3EQOBhAACgYBu77erOhm/hF6l6u6wuyaM0GfgdMxg - eU5WnfcTJOzXXZBcv3cetn/OF0OG3e81R+/78xIjpx+b1q5bjXvqNRfZWr8Vov+Y - ox6WOB2kdxa+tRgpK1Bs6FqJgI7AWMYVSxgjpx+9Q/j6aZe6+r8m6k9HOU0cw+0L - 7PFU2eVGvF/DYA== - """ - dsa_key_der = base64.b64decode(dsa_key_pem) - spki = decoder.decode(dsa_key_der, - asn1Spec=rfc5280.SubjectPublicKeyInfo())[0] - csr = x509_csr.X509Csr.from_buffer(self.csr_sample_bytes) - csr._csr['certificationRequestInfo']['subjectPublicKeyInfo'] = spki - self.assertIsNone(custom.public_key(csr=csr, - allowed_keys={'DSA': 1024})) - - def test_public_key_too_short(self): - csr = x509_csr.X509Csr.from_buffer(self.csr_sample_bytes) - with self.assertRaises(errors.ValidationError): - custom.public_key(csr=csr, allowed_keys={'RSA': 99999999}) - - def test_public_key_wrong_algo(self): - csr = x509_csr.X509Csr.from_buffer(self.csr_sample_bytes) - with self.assertRaises(errors.ValidationError): - custom.public_key(csr=csr, allowed_keys={'XXX': 0}) - - def test_whitelist_names_empty_list(self): - # empty whitelist should block everything - csr = self._csr_with_san_dns('example.com') - - with self.assertRaises(errors.ValidationError): - custom.whitelist_names(csr=csr, domains=[],) - - def test_whitelist_names_full_dnsid_match(self): - csr = self._csr_with_san_dns('example.com') - custom.whitelist_names(csr=csr, allow_dns_id=True, - names=['example.com']) - - def test_whitelist_names_partial_dnsid_match(self): - csr = self._csr_with_san_dns('good-123.example.com') - custom.whitelist_names(csr=csr, allow_dns_id=True, - names=['good-%.example.com']) - - def test_whitelist_names_full_dnsid_fail(self): - csr = self._csr_with_san_dns('bad.example.com') - with self.assertRaises(errors.ValidationError): - custom.whitelist_names(csr=csr, allow_dns_id=True, - names=['good.example.com']) - - def test_whitelist_names_full_ipid_match(self): - csr = x509_csr.X509Csr() - ext = x509_ext.X509ExtensionSubjectAltName() - ext.add_ip(netaddr.IPAddress('1.2.3.4')) - csr.add_extension(ext) - - custom.whitelist_names(csr=csr, allow_ip_id=True, names=['1.2.3.4']) - - def test_whitelist_names_full_ipid_fail(self): - csr = x509_csr.X509Csr() - ext = x509_ext.X509ExtensionSubjectAltName() - ext.add_ip(netaddr.IPAddress('4.3.2.1')) - csr.add_extension(ext) - - with self.assertRaises(errors.ValidationError): - custom.whitelist_names(csr=csr, allow_ip_id=True, - names=['1.2.3.4']) - - def test_whitelist_names_cn_not_allowed(self): - csr = self._csr_with_cn("bad.example.com") - with self.assertRaises(errors.ValidationError): - custom.whitelist_names(csr=csr, names=[],) - - def test_whitelist_names_cn_ip_fail(self): - csr = self._csr_with_cn("4.3.2.1") - with self.assertRaises(errors.ValidationError): - custom.whitelist_names(csr=csr, allow_cn_id=True, - names=["1.2.3.4"]) - - def test_whitelist_names_cn_ip_match(self): - csr = self._csr_with_cn("1.2.3.4") - custom.whitelist_names(csr=csr, allow_cn_id=True, names=["1.2.3.4"]) - - def test_whitelist_names_cn_ip_net_fail(self): - csr = self._csr_with_cn("4.3.2.1") - with self.assertRaises(errors.ValidationError): - custom.whitelist_names(csr=csr, allow_cn_id=True, names=["1/8"]) - - def test_whitelist_names_cn_ip_net_match(self): - csr = self._csr_with_cn("1.2.3.4") - custom.whitelist_names(csr=csr, allow_cn_id=True, names=["1/8"]) - - def test_whitelist_names_cn_name_fail(self): - csr = self._csr_with_cn("bad.example.com") - with self.assertRaises(errors.ValidationError): - custom.whitelist_names(csr=csr, allow_cn_id=True, - names=["good.example.com"]) - - def test_whitelist_names_cn_name_match(self): - csr = self._csr_with_cn("good.example.com") - custom.whitelist_names(csr=csr, allow_cn_id=True, - names=["good.example.com"]) - - def test_whitelist_names_cn_partial_name_fail(self): - csr = self._csr_with_cn("bad.example.com") - with self.assertRaises(errors.ValidationError): - custom.whitelist_names(csr=csr, allow_cn_id=True, - names=[".good.example.com"]) - - def test_whitelist_names_cn_partial_name_match(self): - csr = self._csr_with_cn("good.example.com") - custom.whitelist_names(csr=csr, allow_cn_id=True, - names=["%.example.com"]) diff --git a/tests/validators/test_standards_validator.py b/tests/validators/test_standards_validator.py deleted file mode 100644 index 094f7fd..0000000 --- a/tests/validators/test_standards_validator.py +++ /dev/null @@ -1,194 +0,0 @@ -# -*- coding:utf-8 -*- -# -# Copyright 2015 Hewlett-Packard Development Company, L.P. -# -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - -import unittest - -import mock -from pyasn1.codec.der import encoder -from pyasn1_modules import rfc2459 - -from anchor.asn1 import rfc5280 -from anchor.validators import errors -from anchor.validators import standards -from anchor.X509 import extension -from anchor.X509 import name -from anchor.X509 import signing_request -import tests - - -class TestStandardsValidator(tests.DefaultRequestMixin, unittest.TestCase): - def test_passing(self): - csr = signing_request.X509Csr.from_buffer(self.csr_sample_bytes) - standards.standards_compliance(csr=csr) - - -class TestExtensionDuplicates(unittest.TestCase): - def test_no_extensions(self): - csr = signing_request.X509Csr() - standards._no_extension_duplicates(csr) - - def test_no_duplicates(self): - csr = signing_request.X509Csr() - ext = extension.X509ExtensionSubjectAltName() - csr.add_extension(ext) - standards._no_extension_duplicates(csr) - - def test_with_duplicates(self): - csr = signing_request.X509Csr() - ext = extension.X509ExtensionSubjectAltName() - ext.add_dns_id('example.com') - exts = rfc5280.Extensions() - exts[0] = ext._ext - exts[1] = ext._ext - # Anchor doesn't allow this normally, so tests need to cheat - attrs = csr.get_attributes() - attrs[0] = None - attrs[0]['attrType'] = signing_request.OID_extensionRequest - attrs[0]['attrValues'] = None - attrs[0]['attrValues'][0] = encoder.encode(exts) - with self.assertRaises(errors.ValidationError): - standards._no_extension_duplicates(csr) - - -class TestExtensionCriticalFlags(unittest.TestCase): - def test_no_subject_san_not_critical(self): - csr = signing_request.X509Csr() - ext = extension.X509ExtensionSubjectAltName() - ext.set_critical(False) - ext.add_dns_id('example.com') - csr.add_extension(ext) - with self.assertRaises(errors.ValidationError): - standards._critical_flags(csr) - - def test_no_subject_san_critical(self): - csr = signing_request.X509Csr() - ext = extension.X509ExtensionSubjectAltName() - ext.set_critical(True) - ext.add_dns_id('example.com') - csr.add_extension(ext) - standards._critical_flags(csr) - - def test_with_subject_san_not_critical(self): - csr = signing_request.X509Csr() - subject = name.X509Name() - subject.add_name_entry(name.OID_commonName, "example.com") - csr.set_subject(subject) - ext = extension.X509ExtensionSubjectAltName() - ext.set_critical(False) - ext.add_dns_id('example.com') - csr.add_extension(ext) - standards._critical_flags(csr) - - def test_basic_constraints_not_critical(self): - csr = signing_request.X509Csr() - ext = extension.X509ExtensionBasicConstraints() - ext.set_critical(False) - csr.add_extension(ext) - with self.assertRaises(errors.ValidationError): - standards._critical_flags(csr) - - def test_basic_constraints_critical(self): - csr = signing_request.X509Csr() - ext = extension.X509ExtensionBasicConstraints() - ext.set_critical(True) - csr.add_extension(ext) - standards._critical_flags(csr) - - -class TestValidDomains(unittest.TestCase): - def _create_csr_with_domain_san(self, domain): - csr = signing_request.X509Csr() - ext = extension.X509ExtensionSubjectAltName() - # add without validation - we want to test the _valid_domains - # here, not adding - ext.add_dns_id(domain, validate=False) - csr.add_extension(ext) - return csr - - def test_all_valid(self): - csr = self._create_csr_with_domain_san('a-123.example.com') - standards._valid_domains(csr) - - def test_all_valid_trailing_dot(self): - csr = self._create_csr_with_domain_san('a-123.example.com.') - standards._valid_domains(csr) - - def test_too_long(self): - csr = self._create_csr_with_domain_san( - 'very-long-label-over-63-characters-' - 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa.example.com') - with self.assertRaises(errors.ValidationError): - standards._valid_domains(csr) - - def test_beginning_hyphen(self): - csr = self._create_csr_with_domain_san('-label.example.com.') - with self.assertRaises(errors.ValidationError): - standards._valid_domains(csr) - - def test_trailing_hyphen(self): - csr = self._create_csr_with_domain_san('label-.example.com.') - with self.assertRaises(errors.ValidationError): - standards._valid_domains(csr) - - def test_san_space(self): - # valid domain, but not in CSRs - csr = self._create_csr_with_domain_san(' ') - with self.assertRaises(errors.ValidationError): - standards._valid_domains(csr) - - def test_wildcard(self): - csr = self._create_csr_with_domain_san('*.example.com') - standards._valid_domains(csr) - - def test_wildcard_middle(self): - csr = self._create_csr_with_domain_san('foo.*.example.com') - with self.assertRaises(errors.ValidationError): - standards._valid_domains(csr) - - def test_wildcard_partial(self): - csr = self._create_csr_with_domain_san('foo*.example.com') - with self.assertRaises(errors.ValidationError): - standards._valid_domains(csr) - - def test_custom_re(self): - csr = self._create_csr_with_domain_san('123.example.com.') - with self.assertRaises(errors.ValidationError): - standards._valid_domains(csr, "^\s\+$") - - -class TestCsrSignature(tests.DefaultRequestMixin, unittest.TestCase): - def test_csr_signature(self): - csr = signing_request.X509Csr.from_buffer(self.csr_sample_bytes) - self.assertIsNone(standards._csr_signature(csr=csr)) - - def test_csr_signature_bad_sig(self): - csr = signing_request.X509Csr.from_buffer(self.csr_sample_bytes) - with mock.patch.object(signing_request.X509Csr, '_get_signature', - return_value=(b'A'*49)): - with self.assertRaisesRegexp(errors.ValidationError, - "Signature on the CSR is not valid"): - standards._csr_signature(csr=csr) - - def test_csr_signature_old_algo(self): - csr = signing_request.X509Csr.from_buffer(self.csr_sample_bytes) - with mock.patch.object(signing_request.X509Csr, - '_get_signing_algorithm', - return_value=rfc2459.id_dsa_with_sha1): - with self.assertRaisesRegexp(errors.ValidationError, - "CSR rejected for using a known " - "broken, or deprecated algorithm: " - "SHA1 with DSA"): - standards._csr_signature(csr=csr) diff --git a/tools/apparmor.anchor_debug b/tools/apparmor.anchor_debug deleted file mode 100644 index 39e31ee..0000000 --- a/tools/apparmor.anchor_debug +++ /dev/null @@ -1,61 +0,0 @@ -# -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - -#include - -@{ANCHOR_BASE}="/replace/with/path/to/anchor" -@{ANCHOR_VENV}="@{ANCHOR_BASE}/.venv" -@{ANCHOR_CA_DIR}="@{ANCHOR_BASE}/CA" -@{ANCHOR_CERTS_DIR}="@{ANCHOR_BASE}/certs" - -/replace/with/path/to/anchor/bin/anchor_debug { - #include - #include - - /bin/dash ix, - @{ANCHOR_BASE}/ r, - @{ANCHOR_BASE}/bin/anchor_debug mixr, - - @{ANCHOR_VENV}/bin/pecan cix, - - profile /replace/with/path/to/bin/pecan { - #include - #include - #include - #include - #include - - network inet stream, - - /bin/dash ix, - /bin/uname ix, - /etc/mime.types r, - - /sbin/ldconfig mUxr, - - @{ANCHOR_CA_DIR}/* r, - @{ANCHOR_CERTS_DIR}/{,*.crt} w, - - @{ANCHOR_BASE}/ r, - @{ANCHOR_BASE}/anchor/**.py{,c} r, - @{ANCHOR_BASE}/anchor/{,**/} r, - @{ANCHOR_BASE}/config.py r, - - @{ANCHOR_VENV}/bin/python mixr, - @{ANCHOR_VENV}/bin/pecan mixr, - @{ANCHOR_VENV}/bin/ r, - @{ANCHOR_VENV}/lib/python2.7/ r, - @{ANCHOR_VENV}/lib/python2.7/** r, - @{ANCHOR_VENV}/lib/python2.7/**/*.so m, - } -} diff --git a/tools/apparmor.anchor_production b/tools/apparmor.anchor_production deleted file mode 100644 index a173108..0000000 --- a/tools/apparmor.anchor_production +++ /dev/null @@ -1,62 +0,0 @@ -# -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - -#include - -@{ANCHOR_BASE}="/path/to/anchor" -@{ANCHOR_VENV}="@{ANCHOR_BASE}/.venv" -@{ANCHOR_CA_DIR}="@{ANCHOR_BASE}/CA" -@{ANCHOR_CERTS_DIR}="@{ANCHOR_BASE}/certs" - -/path/to/anchor/bin/anchor_production { - #include - #include - - /bin/dash ix, - @{ANCHOR_BASE}/ r, - @{ANCHOR_BASE}/bin/anchor_production mixr, - - @{ANCHOR_VENV}/bin/uwsgi cix, - - profile /path/to/anchor/.venv/bin/uwsgi { - #include - #include - #include - #include - #include - - network inet stream, - - /bin/dash ix, - /bin/uname ix, - /etc/mime.types r, - /sbin/ldconfig mUxr, - - @{PROC}/sys/net/core/somaxconn r, - - @{ANCHOR_CA_DIR}/* r, - @{ANCHOR_CERTS_DIR}/{,*.crt} w, - - @{ANCHOR_BASE}/ r, - @{ANCHOR_BASE}/anchor/**.py{,c} r, - @{ANCHOR_BASE}/anchor/{,**/} r, - @{ANCHOR_BASE}/config.py r, - - @{ANCHOR_VENV}/bin/python mixr, - @{ANCHOR_VENV}/bin/uwsgi mixr, - @{ANCHOR_VENV}/bin/ r, - @{ANCHOR_VENV}/lib/python2.7/ r, - @{ANCHOR_VENV}/lib/python2.7/** r, - @{ANCHOR_VENV}/lib/python2.7/**/*.so m, - } -} diff --git a/tools/bootstrap_test_ca.sh b/tools/bootstrap_test_ca.sh deleted file mode 100755 index 068ec08..0000000 --- a/tools/bootstrap_test_ca.sh +++ /dev/null @@ -1,3 +0,0 @@ -#!/bin/bash - -openssl req -x509 -newkey rsa:384 -keyout CA/root-ca-unwrapped.key -out CA/root-ca.crt -nodes -batch diff --git a/tools/cmc_wrap.vbs b/tools/cmc_wrap.vbs deleted file mode 100755 index dbc1cd3..0000000 --- a/tools/cmc_wrap.vbs +++ /dev/null @@ -1,26 +0,0 @@ -' Generate the CMC request with a hardcoded CN from the current user context - -Const ContextUser = 1 -const XCN_CERT_X500_NAME_STR = 3 - -Set fso = CreateObject ("Scripting.FileSystemObject") - -Set req = CreateObject("X509Enrollment.CX509CertificateRequestCmc") - -Set xreq = CreateObject("X509Enrollment.CX509CertificateRequestPkcs10") -xreq.Initialize ContextUser - -xreq.Subject = CreateObject( "X509Enrollment.CX500DistinguishedName" ) -xreq.Subject.Encode "CN=anchor-test.example.com", XCN_CERT_X500_NAME_STR - -req.InitializeFromInnerRequest xreq - -req.Encode - -outFile="cmc.req" -Set objFile = fso.CreateTextFile(outFile,True) -objFile.WriteLine "-----BEGIN CERTIFICATE REQUEST-----" -objFile.WriteLine req.RawData -objFile.WriteLine "-----END CERTIFICATE REQUEST-----" -objFile.Close - diff --git a/tools/colorizer.py b/tools/colorizer.py deleted file mode 100755 index a16c620..0000000 --- a/tools/colorizer.py +++ /dev/null @@ -1,333 +0,0 @@ -#!/usr/bin/env python - -# Copyright (c) 2013, Nebula, Inc. -# Copyright 2010 United States Government as represented by the -# Administrator of the National Aeronautics and Space Administration. -# All Rights Reserved. -# -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. -# -# Colorizer Code is borrowed from Twisted: -# Copyright (c) 2001-2010 Twisted Matrix Laboratories. -# -# Permission is hereby granted, free of charge, to any person obtaining -# a copy of this software and associated documentation files (the -# "Software"), to deal in the Software without restriction, including -# without limitation the rights to use, copy, modify, merge, publish, -# distribute, sublicense, and/or sell copies of the Software, and to -# permit persons to whom the Software is furnished to do so, subject to -# the following conditions: -# -# The above copyright notice and this permission notice shall be -# included in all copies or substantial portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - -"""Display a subunit stream through a colorized unittest test runner.""" - -import heapq -import sys -import unittest - -import six -import subunit -import testtools - - -class _AnsiColorizer(object): - """Colorizer allows callers to write text in a particular color. - - A colorizer is an object that loosely wraps around a stream, allowing - callers to write text to the stream in a particular color. - - Colorizer classes must implement C{supported()} and C{write(text, color)}. - """ - _colors = dict(black=30, red=31, green=32, yellow=33, - blue=34, magenta=35, cyan=36, white=37) - - def __init__(self, stream): - self.stream = stream - - def supported(cls, stream=sys.stdout): - """Check is the current platform supports coloring terminal output. - - A class method that returns True if the current platform supports - coloring terminal output using this method. Returns False otherwise. - """ - if not stream.isatty(): - return False # auto color only on TTYs - try: - import curses - except ImportError: - return False - else: - try: - try: - return curses.tigetnum("colors") > 2 - except curses.error: - curses.setupterm() - return curses.tigetnum("colors") > 2 - except Exception: - # guess false in case of error - return False - supported = classmethod(supported) - - def write(self, text, color): - """Write the given text to the stream in the given color. - - @param text: Text to be written to the stream. - - @param color: A string label for a color. e.g. 'red', 'white'. - """ - color = self._colors[color] - self.stream.write('\x1b[%s;1m%s\x1b[0m' % (color, text)) - - -class _Win32Colorizer(object): - """See _AnsiColorizer docstring.""" - def __init__(self, stream): - import win32console - red, green, blue, bold = (win32console.FOREGROUND_RED, - win32console.FOREGROUND_GREEN, - win32console.FOREGROUND_BLUE, - win32console.FOREGROUND_INTENSITY) - self.stream = stream - self.screenBuffer = win32console.GetStdHandle( - win32console.STD_OUT_HANDLE) - self._colors = { - 'normal': red | green | blue, - 'red': red | bold, - 'green': green | bold, - 'blue': blue | bold, - 'yellow': red | green | bold, - 'magenta': red | blue | bold, - 'cyan': green | blue | bold, - 'white': red | green | blue | bold, - } - - def supported(cls, stream=sys.stdout): - try: - import win32console - screenBuffer = win32console.GetStdHandle( - win32console.STD_OUT_HANDLE) - except ImportError: - return False - import pywintypes - try: - screenBuffer.SetConsoleTextAttribute( - win32console.FOREGROUND_RED | - win32console.FOREGROUND_GREEN | - win32console.FOREGROUND_BLUE) - except pywintypes.error: - return False - else: - return True - supported = classmethod(supported) - - def write(self, text, color): - color = self._colors[color] - self.screenBuffer.SetConsoleTextAttribute(color) - self.stream.write(text) - self.screenBuffer.SetConsoleTextAttribute(self._colors['normal']) - - -class _NullColorizer(object): - """See _AnsiColorizer docstring.""" - def __init__(self, stream): - self.stream = stream - - def supported(cls, stream=sys.stdout): - return True - supported = classmethod(supported) - - def write(self, text, color): - self.stream.write(text) - - -def get_elapsed_time_color(elapsed_time): - if elapsed_time > 1.0: - return 'red' - elif elapsed_time > 0.25: - return 'yellow' - else: - return 'green' - - -class OpenStackTestResult(testtools.TestResult): - def __init__(self, stream, descriptions, verbosity): - super(OpenStackTestResult, self).__init__() - self.stream = stream - self.showAll = verbosity > 1 - self.num_slow_tests = 10 - self.slow_tests = [] # this is a fixed-sized heap - self.colorizer = None - # NOTE(vish): reset stdout for the terminal check - stdout = sys.stdout - sys.stdout = sys.__stdout__ - for colorizer in [_Win32Colorizer, _AnsiColorizer, _NullColorizer]: - if colorizer.supported(): - self.colorizer = colorizer(self.stream) - break - sys.stdout = stdout - self.start_time = None - self.last_time = {} - self.results = {} - self.last_written = None - - def _writeElapsedTime(self, elapsed): - color = get_elapsed_time_color(elapsed) - self.colorizer.write(" %.2f" % elapsed, color) - - def _addResult(self, test, *args): - try: - name = test.id() - except AttributeError: - name = 'Unknown.unknown' - test_class, test_name = name.rsplit('.', 1) - - elapsed = (self._now() - self.start_time).total_seconds() - item = (elapsed, test_class, test_name) - if len(self.slow_tests) >= self.num_slow_tests: - heapq.heappushpop(self.slow_tests, item) - else: - heapq.heappush(self.slow_tests, item) - - self.results.setdefault(test_class, []) - self.results[test_class].append((test_name, elapsed) + args) - self.last_time[test_class] = self._now() - self.writeTests() - - def _writeResult(self, test_name, elapsed, long_result, color, - short_result, success): - if self.showAll: - self.stream.write(' %s' % str(test_name).ljust(66)) - self.colorizer.write(long_result, color) - if success: - self._writeElapsedTime(elapsed) - self.stream.writeln() - else: - self.colorizer.write(short_result, color) - - def addSuccess(self, test): - super(OpenStackTestResult, self).addSuccess(test) - self._addResult(test, 'OK', 'green', '.', True) - - def addFailure(self, test, err): - if test.id() == 'process-returncode': - return - super(OpenStackTestResult, self).addFailure(test, err) - self._addResult(test, 'FAIL', 'red', 'F', False) - - def addError(self, test, err): - super(OpenStackTestResult, self).addFailure(test, err) - self._addResult(test, 'ERROR', 'red', 'E', False) - - def addSkip(self, test, reason=None, details=None): - super(OpenStackTestResult, self).addSkip(test, reason, details) - self._addResult(test, 'SKIP', 'blue', 'S', True) - - def startTest(self, test): - self.start_time = self._now() - super(OpenStackTestResult, self).startTest(test) - - def writeTestCase(self, cls): - if not self.results.get(cls): - return - if cls != self.last_written: - self.colorizer.write(cls, 'white') - self.stream.writeln() - for result in self.results[cls]: - self._writeResult(*result) - del self.results[cls] - self.stream.flush() - self.last_written = cls - - def writeTests(self): - time = self.last_time.get(self.last_written, self._now()) - if not self.last_written or (self._now() - time).total_seconds() > 2.0: - diff = 3.0 - while diff > 2.0: - classes = self.results.keys() - oldest = min(classes, key=lambda x: self.last_time[x]) - diff = (self._now() - self.last_time[oldest]).total_seconds() - self.writeTestCase(oldest) - else: - self.writeTestCase(self.last_written) - - def done(self): - self.stopTestRun() - - def stopTestRun(self): - for cls in list(six.iterkeys(self.results)): - self.writeTestCase(cls) - self.stream.writeln() - self.writeSlowTests() - - def writeSlowTests(self): - # Pare out 'fast' tests - slow_tests = [item for item in self.slow_tests - if get_elapsed_time_color(item[0]) != 'green'] - if slow_tests: - slow_total_time = sum(item[0] for item in slow_tests) - slow = ("Slowest %i tests took %.2f secs:" - % (len(slow_tests), slow_total_time)) - self.colorizer.write(slow, 'yellow') - self.stream.writeln() - last_cls = None - # sort by name - for elapsed, cls, name in sorted(slow_tests, - key=lambda x: x[1] + x[2]): - if cls != last_cls: - self.colorizer.write(cls, 'white') - self.stream.writeln() - last_cls = cls - self.stream.write(' %s' % str(name).ljust(68)) - self._writeElapsedTime(elapsed) - self.stream.writeln() - - def printErrors(self): - if self.showAll: - self.stream.writeln() - self.printErrorList('ERROR', self.errors) - self.printErrorList('FAIL', self.failures) - - def printErrorList(self, flavor, errors): - for test, err in errors: - self.colorizer.write("=" * 70, 'red') - self.stream.writeln() - self.colorizer.write(flavor, 'red') - self.stream.writeln(": %s" % test.id()) - self.colorizer.write("-" * 70, 'red') - self.stream.writeln() - self.stream.writeln("%s" % err) - - -test = subunit.ProtocolTestCase(sys.stdin, passthrough=None) - -if sys.version_info[0:2] <= (2, 6): - runner = unittest.TextTestRunner(verbosity=2) -else: - runner = unittest.TextTestRunner(verbosity=2, - resultclass=OpenStackTestResult) - -if runner.run(test).wasSuccessful(): - exit_code = 0 -else: - exit_code = 1 -sys.exit(exit_code) diff --git a/tools/install_venv.py b/tools/install_venv.py deleted file mode 100644 index b985945..0000000 --- a/tools/install_venv.py +++ /dev/null @@ -1,72 +0,0 @@ -# Copyright 2013 IBM Corp. -# Copyright 2012 OpenStack Foundation -# Copyright 2010 United States Government as represented by the -# Administrator of the National Aeronautics and Space Administration. -# All Rights Reserved. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or -# implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -""" -virtualenv installation script -""" - -import os -import sys - -import install_venv_common as install_venv - - -def print_help(): - help = """ - Anchor development environment setup is complete. - - Anchor development uses virtualenv to track and manage Python - dependencies while in development and testing. - - To activate the Anchor virtualenv for the extent of your current shell - session you can run: - - $ source .venv/bin/activate - - Or, if you prefer, you can run commands in the virtualenv on a case by case - basis by running: - - $ tools/with_venv.sh - - Also, make test will automatically use the virtualenv. - """ - print(help) - - -def main(argv): - root = os.path.dirname(os.path.dirname(os.path.realpath(__file__))) - venv = os.path.join(root, '.venv') - pip_requires = os.path.join(root, 'requirements.txt') - test_requires = os.path.join(root, 'test-requirements.txt') - py_version = "python%s.%s" % (sys.version_info[0], sys.version_info[1]) - project = 'Anchor' - install = install_venv.InstallVenv(root, venv, pip_requires, test_requires, - py_version, project) - options = install.parse_args(argv) - install.check_python_version() - install.check_dependencies() - install.create_virtualenv(no_site_packages=options.no_site_packages) - install.install_dependencies() - install.run_command([os.path.join(venv, 'bin/python'), - 'setup.py', 'develop']) - print_help() - - -if __name__ == '__main__': - main(sys.argv) diff --git a/tools/install_venv_common.py b/tools/install_venv_common.py deleted file mode 100644 index e279159..0000000 --- a/tools/install_venv_common.py +++ /dev/null @@ -1,172 +0,0 @@ -# Copyright 2013 OpenStack Foundation -# Copyright 2013 IBM Corp. -# -# Licensed under the Apache License, Version 2.0 (the "License"); you may -# not use this file except in compliance with the License. You may obtain -# a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT -# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the -# License for the specific language governing permissions and limitations -# under the License. - -"""Provides methods needed by installation script for OpenStack development -virtual environments. - -Since this script is used to bootstrap a virtualenv from the system's Python -environment, it should be kept strictly compatible with Python 2.6. - -Synced in from openstack-common -""" - -from __future__ import print_function - -import optparse -import os -import subprocess -import sys - - -class InstallVenv(object): - - def __init__(self, root, venv, requirements, - test_requirements, py_version, - project): - self.root = root - self.venv = venv - self.requirements = requirements - self.test_requirements = test_requirements - self.py_version = py_version - self.project = project - - def die(self, message, *args): - print(message % args, file=sys.stderr) - sys.exit(1) - - def check_python_version(self): - if sys.version_info < (2, 6): - self.die("Need Python Version >= 2.6") - - def run_command_with_code(self, cmd, redirect_output=True, - check_exit_code=True): - """Runs a command in an out-of-process shell. - - Returns the output of that command. Working directory is self.root. - """ - if redirect_output: - stdout = subprocess.PIPE - else: - stdout = None - - proc = subprocess.Popen(cmd, cwd=self.root, stdout=stdout) - output = proc.communicate()[0] - if check_exit_code and proc.returncode != 0: - self.die('Command "%s" failed.\n%s', ' '.join(cmd), output) - return (output, proc.returncode) - - def run_command(self, cmd, redirect_output=True, check_exit_code=True): - return self.run_command_with_code(cmd, redirect_output, - check_exit_code)[0] - - def get_distro(self): - if (os.path.exists('/etc/fedora-release') or - os.path.exists('/etc/redhat-release')): - return Fedora( - self.root, self.venv, self.requirements, - self.test_requirements, self.py_version, self.project) - else: - return Distro( - self.root, self.venv, self.requirements, - self.test_requirements, self.py_version, self.project) - - def check_dependencies(self): - self.get_distro().install_virtualenv() - - def create_virtualenv(self, no_site_packages=True): - """Creates the virtual environment and installs PIP. - - Creates the virtual environment and installs PIP only into the - virtual environment. - """ - if not os.path.isdir(self.venv): - print('Creating venv...', end=' ') - if no_site_packages: - self.run_command(['virtualenv', '-q', '--no-site-packages', - self.venv]) - else: - self.run_command(['virtualenv', '-q', self.venv]) - print('done.') - else: - print("venv already exists...") - pass - - def pip_install(self, *args): - self.run_command(['tools/with_venv.sh', - 'pip', 'install', '--upgrade'] + list(args), - redirect_output=False) - - def install_dependencies(self): - print('Installing dependencies with pip (this can take a while)...') - - # First things first, make sure our venv has the latest pip and - # setuptools and pbr - self.pip_install('pip>=1.4') - self.pip_install('setuptools') - self.pip_install('pbr') - - self.pip_install('-r', self.requirements, '-r', self.test_requirements) - - def parse_args(self, argv): - """Parses command-line arguments.""" - parser = optparse.OptionParser() - parser.add_option('-n', '--no-site-packages', - action='store_true', - help="Do not inherit packages from global Python " - "install.") - return parser.parse_args(argv[1:])[0] - - -class Distro(InstallVenv): - - def check_cmd(self, cmd): - return bool(self.run_command(['which', cmd], - check_exit_code=False).strip()) - - def install_virtualenv(self): - if self.check_cmd('virtualenv'): - return - - if self.check_cmd('easy_install'): - print('Installing virtualenv via easy_install...', end=' ') - if self.run_command(['easy_install', 'virtualenv']): - print('Succeeded') - return - else: - print('Failed') - - self.die('ERROR: virtualenv not found.\n\n%s development' - ' requires virtualenv, please install it using your' - ' favorite package management tool' % self.project) - - -class Fedora(Distro): - """This covers all Fedora-based distributions. - - Includes: Fedora, RHEL, CentOS, Scientific Linux - """ - - def check_pkg(self, pkg): - return self.run_command_with_code(['rpm', '-q', pkg], - check_exit_code=False)[1] == 0 - - def install_virtualenv(self): - if self.check_cmd('virtualenv'): - return - - if not self.check_pkg('python-virtualenv'): - self.die("Please install 'python-virtualenv'.") - - super(Fedora, self).install_virtualenv() diff --git a/tools/with_venv.sh b/tools/with_venv.sh deleted file mode 100755 index 7303990..0000000 --- a/tools/with_venv.sh +++ /dev/null @@ -1,7 +0,0 @@ -#!/bin/bash -TOOLS_PATH=${TOOLS_PATH:-$(dirname $0)} -VENV_PATH=${VENV_PATH:-${TOOLS_PATH}} -VENV_DIR=${VENV_NAME:-/../.venv} -TOOLS=${TOOLS_PATH} -VENV=${VENV:-${VENV_PATH}/${VENV_DIR}} -source ${VENV}/bin/activate && "$@" diff --git a/tox.ini b/tox.ini deleted file mode 100644 index fac67de..0000000 --- a/tox.ini +++ /dev/null @@ -1,50 +0,0 @@ -[tox] -minversion = 1.6 -envlist = pypy,py35,py27,pep8,docs -skipsdist = True - -[testenv] -usedevelop = True -install_command = pip install -U {opts} {packages} -setenv = - VIRTUAL_ENV={envdir} - PYTHONWARNINGS=default::DeprecationWarning -deps = -r{toxinidir}/requirements.txt - -r{toxinidir}/test-requirements.txt -commands = - coverage erase - python setup.py testr --coverage --slowest --testr-args='{posargs}' - coverage report -m - coverage erase - -[testenv:docs] -deps = - doc8 - sphinx -commands = - sphinx-build -W -b html -d {envtmpdir}/doctrees doc/source doc/build/html - doc8 --allow-long-titles doc/source - -[testenv:pep8] -commands = - flake8 {posargs} anchor - flake8 {posargs} tests - bandit -r anchor - -[testenv:venv] -commands = {posargs} - -[testenv:cover] -commands = - python setup.py testr --coverage --testr-args='{posargs}' - coverage combine - coverage xml - -[testenv:bandit] -deps = -r{toxinidir}/test-requirements.txt -commands = bandit -r anchor - -[flake8] -show-source = True -exclude=.venv,.git,.tox,dist,doc,*openstack/common*,*lib/python*,*egg,build,anchor/asn1/*py -max-complexity=25