Metadata-Version: 2.1
Name: cnert
Version: 0.2.0
Summary: Cnert is trying to be a simple API for creating TLS Certificates testing purposes.
Home-page: https://github.com/maartenq/cnert
License: MIT
Keywords: certificate,X.509,TLS,cryptography,testing
Author: Maarten
Author-email: ikmaarten@gmail.com
Requires-Python: >=3.9,<4.0
Classifier: Development Status :: 4 - Beta
Classifier: Environment :: Console
Classifier: Intended Audience :: Developers
Classifier: Intended Audience :: System Administrators
Classifier: License :: OSI Approved :: Apache Software License
Classifier: License :: OSI Approved :: MIT License
Classifier: Natural Language :: English
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.9
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3 :: Only
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.9
Classifier: Programming Language :: Python :: Implementation :: CPython
Classifier: Topic :: Security :: Cryptography
Classifier: Topic :: Software Development :: Libraries :: Python Modules
Classifier: Topic :: Software Development :: Testing
Classifier: Topic :: Software Development :: Testing :: Mocking
Requires-Dist: cryptography (>=40.0.0,<41.0.0)
Requires-Dist: idna (>=3.3,<4.0)
Project-URL: Documentation, https://cnert.readthedocs.io/en/latest/
Project-URL: Repository, https://github.com/maartenq/cnert
Description-Content-Type: text/markdown

# cnert

[![PyPI version](https://badge.fury.io/py/cnert.svg)](https://badge.fury.io/py/cnert)
[![Documentation Status](https://readthedocs.org/projects/cnert/badge/?version=latest)](https://cnert.readthedocs.io/en/latest/?badge=latest)
[![pre-commit.ci status](https://results.pre-commit.ci/badge/github/maartenq/cnert/main.svg)](https://results.pre-commit.ci/latest/github/maartenq/cnert/main)
[![workflow ci](https://github.com/maartenq/cnert/actions/workflows/main.yml/badge.svg)](https://github.com/maartenq/cnert/actions/workflows/main.yml)
[![codecov](https://codecov.io/gh/maartenq/cnert/branch/main/graph/badge.svg?token=XXXXXXXXXX)](https://codecov.io/gh/maartenq/cnert)
[![License](https://img.shields.io/badge/license-MIT%2FApache--2.0-blue.svg)](LICENSE)

# Cnert - TLS Certificates for testing

Cnert is trying to be a simple API for creating TLS Certificates testing
purposes.

[cnert.CA][] makes CAs, intermediate CAs and [certificates][cnert._Cert] and
has several methods for introspection.


## Usage

### Create a root CA

    >>> import cnert
    >>> ca = cnert.CA()

    >>> ca.is_root_ca
    True

    >>> ca.is_intermediate_ca
    False

    >>> ca.parent is None
    True

### Issue an intermediate CA

    >>> intermediate = ca.issue_intermediate()
    >>> intermediate.is_intermediate_ca
    True

    >>> intermediate.is_root_ca
    False

    >>> intermediate.parent is ca
    True


###  Inspect the CA's certificate

    >>> ca.cert
    <cnert.Cert at 0x112a14c50>

    >>> ca.cert.subject_attrs
    NameAttrs(ORGANIZATION_NAME="Root CA")

    >>> ca.cert.ca.cert.issuer_attrs
    NameAttrs(ORGANIZATION_NAME="Root CA")

    >>> ca.cert.not_valid_before
    datetime.datetime(2023, 3, 24, 21, 27, 50, 579389

    >>> ca.cert.not_valid_after
    datetime.datetime(2023, 6, 23, 20, 20, 47, 999034)

    >>> ca.cert.not_valid_after
    datetime.datetime(2023, 6, 23, 20, 20, 47, 999034)

    >>> ca.cert.serial_number
    710111479237500376112637726504312543434663217892

    >>> ca.cert.path_length
    9

    >>> ca.cert.public_key.key_size
    2048

    >>> ca.cert.public_key_pem
    b'-----BEGIN CERTIFICATE-----\nMIIC9zCCAd+gAwIBAgIUGyCBgdyVPVGlYIJj25+x1AMQPHswDQYJKoZIhvcNAQEL\nBQAwEjEQMA4GA1UECgwHUm9vdCBDQTAeFw0yMzA1MDgwODQyNThaFw0yMzA4MDcw\nODQyNThaMBIxEDAOBgNVBAoMB1Jvb3QgQ0EwggEiMA0GCSqGSIb3DQEBAQUAA4IB\nDwAwggEKAoIBAQDK13Q6dZdK17SPmplwTq4Phh7TatM4HQqONEq6+xE2VnJ9eeCh\nQYM5w5dnxIUeV10j3ODPJz5L+6IirV/e6voCWkS6Vgzh/lAVTbUVGANR26NpMnjm\n/qU0NUYuSQo5QFJuwFEx9CZ1xGTac9gspBo1jO7E9m01pRAXlr1HqTZT7mY4LNWb\nDyjKmMa/tfK0+itiKce48hZDxqy3YLnWYyIAZ+rTrf9RW5hpLb6g/KeAf3w5q55Q\nL2dCsC6flZ6NFVRm7okpawwN2tf5c451fMm3B+GtVJJMP+6lmk6MC3h++pcwOimg\nUwB8tYEPoZHuMjd1hacZcbfGFzCGAbme+BZbAgMBAAGjRTBDMB0GA1UdDgQWBBSA\nIsRH6giY94MEfhzafTd5WC2HMzASBgNVHRMBAf8ECDAGAQH/AgEJMA4GA1UdDwEB\n/wQEAwIBpjANBgkqhkiG9w0BAQsFAAOCAQEACLdxWMlmr3drMvA7GaQArzlbe/ny\nx8mThDhZP6gx+yTJ6LXk8CFc7S23JXFZVquwcV5yFa0DavaodBI3RNWknx/Yu5Lm\nM7cOByu2IuJhcEu4o+ZntLZLb7heFMXMIf01lVkYpyYyvS/NvVdu9km8f6ZvxV9r\nDyTDDMjeh+hg5l2Wwc4P6UGoMlmOruUiunsb8hiDLhD+brYBHKHqJY9pCrzJQd0v\nWEkAOsBwaTv/POO0F4VDZSfA5CqjYOkppupw9nXXfJkk9PvKuDI1G2XO7pcW1PWh\nDdGK6Wz0AXMWWbbX8LToDrFA9q7YOxGNOVPhbHZ++bDJvLNmjrtruy3UTQ==\n-----END CERTIFICATE-----\n'



###  Inspect the Intermediate CA

    >>> intermediate.cert.subject_attrs
    NameAttrs(ORGANIZATION_NAME="CA Intermediate 1")

    >>> intermediate.cert.ca.cert.issuer_attrs
    NameAttrs(ORGANIZATION_NAME="Root CA")

    >>> intermediate.cert.path_length
    8


###  Issue a cert from a CA
    >>> cert = ca.issue_cert()

    >>> cert.subject_attrs
    NameAttrs(COMMON_NAME="example.com")

    >>> cert.public_key
    <cryptography.hazmat.backends.openssl.rsa._RSAPublicKey object at 0x10361c150>

    >>> cert.public_key_pem
    b'-----BEGIN CERTIFICATE-----\nMIIDITCCAgmgAwIBAgIUAx6AA8z3BqH/ICCmqOJXGI7PHCswDQYJKoZIhvcNAQEL\nBQAwEjEQMA4GA1UECgwHUm9vdCBDQTAeFw0yMzA1MDgwODU5NTlaFw0yMzA4MDcw\nODU5NTlaMBYxFDASBgNVBAMMC2V4YW1wbGUuY29tMIIBIjANBgkqhkiG9w0BAQEF\nAAOCAQ8AMIIBCgKCAQEAnWAlLvbR0hE8seqI8uBj8ESicJ/nF8I3KF9CFlTexQ73\nKdyqTRCoPZ6uuK0quX+qX5KeeNlWSnJRxSDc0WmLwYxWFVg6hmBDPLK1Ijntc1Uj\n4HENkolgPUBxgf9VBSmojqd1XL0o8PwGFIoyZ6Z/YTc3MqML4QZaB0m+TYlVgoJP\nQgFT9d9nQadvyswIx7nOMkT0Rd3sGl8nWaNgDaBLB6mkylGrtaiyo2M2LWKvNz69\nDWbjlccj65B04cBLwRcA2Zmx80leajX1zNWt0+dhJFo6rnLtmvIgqdLhCrNTmDMK\nrlyVsOrwJfXNreIPDEgYztZlrUdTnynmF4bW6W5KcwIDAQABo2swaTAdBgNVHQ4E\nFgQURd1r0d7XJBtT651AbuR2hg7TQBIwDAYDVR0TAQH/BAIwADAOBgNVHQ8BAf8E\nBAMCBaAwKgYDVR0lAQH/BCAwHgYIKwYBBQUHAwIGCCsGAQUFBwMBBggrBgEFBQcD\nAzANBgkqhkiG9w0BAQsFAAOCAQEANcFmZZkt4Z6jc069IOonGfcpUdnZieSEVyBE\nCQC+QWaHYqcD0ryYV8n1/UzNVcSkptQ5YrbgXNikV6+cuklFq4OjHlUDGOxchrkc\nSFGYAf+j7wAAx+OZWH5IwvMSTWGhfi7FWNFrzbO3JUE1q3OOnsIUmcDpd/8zucyE\njPf6F0MVujwMJq8VAH8UtUpVm1SApEBz9vgx0n7Z0l5fgRw7PMwwDkaoyplSC0VA\n7F7AUX3K0oJ7Gyw+9onfS090GMo6mlTfhtXNpPArleUUOTrp+TKVhwtz8GRRzxEW\nBE1OaNZaipKILZPbgDa5u67pRdU/OhuMFDsBh1GlPopcax+rCQ==\n-----END CERTIFICATE-----\n'



###  Issue a cert from a CA with alt names

    >>> cert = ca.issue_cert("www.example.com", "host1.example.com", "example.com")

    >>> cert.subject_attrs
    NameAttrs(COMMON_NAME="www.example.com")

    >>> cert.sans
    ('www.example.com', 'host1.example.com', 'example.com')

    >>> cert.certificate.extensions[4]
    <Extension(oid=<ObjectIdentifier(oid=2.5.29.17, name=subjectAltName)>, critical=True, value=<SubjectAlte rnativeName(<GeneralNames([<DNSName(value='www.example.com')>, <DNSName(value='host1.example.com')>, <DNSName(val ue='example.com')>])>)>)>

