{ "info": { "author": "Don Spaulding II", "author_email": "don@mirusresearch.com", "bugtrack_url": null, "classifiers": [], "description": "[![pipeline status](https://gitlab.mirus.io/domains/roadrunner/microacme/badges/master/pipeline.svg)](https://mirus.githost.io/domains/roadrunner/microacme/commits/master)\n[![coverage report](https://gitlab.mirus.io/domains/roadrunner/microacme/badges/master/coverage.svg?job=test)](https://mirus.githost.io/domains/roadrunner/microacme/commits/master)\n\n# microacme\n`microacme` is a library intended to be used with an ACME-speaking API server, such as the one run by the LetsEncrypt service.\n\n# Why another ACME client?\n`microacme`'s main advantage is that it is designed to be easily subclassed and extended\nto allow for custom implementations of solving the ACME challenges,\nwithout having to worry about implementing the ACME RFC from scratch.\n\n\n# History\nIt began life in 2016 as a fork of diafygi's excellent [tiny-acme project](https://github.com/diafygi/acme-tiny).\nThe goals of that original library were to be small, dependency free, and easily audited. This fork \nintends to keep the smallness, but not at the expense of readability or usability as an extendable library.\nAlso, instead of avoiding dependencies it relies on well-regarded third-party libraries for HTTP requests,\nJSON web token signatures, and cryptographic primitives (using `requests`, `jwcrypto`, and `cryptography`, respectively).\n\nAt this point, almost the entire codebase has been rewritten from scratch and bears almost no resemblance to its initial inspiration, `tiny-acme`.\n\n# Installation\n`pip install microacme`\n\n# Usage\nTo use `microacme`, you need to implement a few methods on a subclass of `microacme.ACMEClient`.\n\n```python\n from microacme import ACMEClient\n\n class MyCustomACMEClient(ACMEClient):\n \"\"\"\n Use this class as an example to build your\n ACME client. Override the methods below\n to customize the challenge/response behavior\n of the ACME client.\n \"\"\"\n def select_challenge(self, domain, challenges):\n \"\"\"\n Each domain has multiple options for solving challenges.\n\n Override this function to pick which challenge you want to\n solve for this domain.\n \"\"\"\n pass\n\n def set_challenge(self, domain, challenge):\n \"\"\"\n After a challenge has been selected, it needs to actually exist somewhere.\n\n This is where you fulfill the challenge requirements.\n \"\"\"\n raise NotImplementedError(\"Need to implement a function to set the challenge.\")\n\n def validate_challenge(self, domain, challenge):\n \"\"\"\n Used to give the ACMEClient instance a chance to make sure\n that the outside world will see the changes made by set_challenge.\n\n By default, does nothing. Could be used, for example, to sleep(1) while waiting\n for an asynchronous upload to take place to a remote webserver. Or to wait while\n DNS propagation occurs.\n \"\"\"\n pass\n\n def cleanup_completed_challenge(self, domain, challenge):\n \"\"\"\n This method is called after the challenge has succeeded. It is used\n to cleanup any artifacts of solving the challenge.\n \"\"\"\n pass\n```\n\nOnce you've implemented these methods, you can instantiate your client with an account_key and a CA url.\n\n```python\nimport microacme\n\nmy_client = MyCustomACMEClient(\n account_key=BYTES_OF_KEY_IN_PEM_FORMAT,\n CA=microacme.STAGING_CA\n)\n\n# If you've never used this particular account_key before:\nmy_client.register_account()\n\n# Now you're ready to get a certificate. First, create a key:\nkey = microacme.generate_crypto_key(key_size=3072)\n\n# Next, generate a Certificate Signing Request (CSR):\ncsr = microacme.generate_csr(\n key=key,\n country='US',\n state='Indiana',\n locality='Indianapolis',\n org_name='Widget Maker, Inc.',\n common_name='widgetmaker.com',\n alt_names=[\n 'mail.widgetmaker.com',\n 'dev.widgetmaker.com',\n ],\n auto_www=True\n)\n\n# Finally, ask the ACME server to authorize, validate, and issue the certificate:\ncert, issuer_cert = microacme.get_certificate(csr)\n\n# Congratulations, you're encrypted!\n```\n\n# Helper Methods\n`microacme` has a handful of utility methods which may come in handy as you are shuffling\nkeys and certs around between different systems. Most of them are self explanatory, but\nsome example usage is included below.\n\n```python\n import microacme\n\n # Working with keys\n crypto_key = microacme.generate_crypto_key(key_size=2048):\n pem_bytes = microacme.crypto_key_to_pem(crypto_key, passphrase=None) # Tack on a passphrase to protect the key at rest.\n loaded_crypto_key = microacme.pem_to_crypto_key(pem_bytes, passphrase=None) # Use a passphrase if the key is encrypted\n\n\n # Working with CSRs\n csr_object = microacme.generate_csr(\n private_key,\n country,\n state,\n locality,\n org_name,\n common_name,\n alt_names=None,\n auto_www=True\n )\n csr_pem_bytes = microacme.csr_to_pem(csr_object)\n csr_object = microacme.pem_to_csr(csr_pem_bytes)\n\n\n # Working with Certificates\n cert_pem_bytes = microacme.cert_to_pem(cert_obj)\n cert_object = microacme.pem_to_cert(cert_pem_bytes)\n cert_object = microacme.der_to_cert(cert_der_bytes)\n```\n\n# Contributing\nPlease feel free to open issues on our [Gitlab issue tracker](https://gitlab.mirus.io/domains/roadrunner/microacme/issues).\n\n# License\nThe original inspiration for `microacme` was licensed as MIT. We retain that license as well for this library.\n\n", "description_content_type": null, "docs_url": null, "download_url": "", "downloads": { "last_day": -1, "last_month": -1, "last_week": -1 }, "home_page": "https://gitlab.mirus.io/domains/roadrunner/microacme/", "keywords": "", "license": "", "maintainer": "", "maintainer_email": "", "name": "microacme", "package_url": "https://pypi.org/project/microacme/", "platform": "", "project_url": "https://pypi.org/project/microacme/", "project_urls": { "Homepage": "https://gitlab.mirus.io/domains/roadrunner/microacme/" }, "release_url": "https://pypi.org/project/microacme/3.2.4/", "requires_dist": [ "requests", "jwcrypto", "cryptography", "pytest", "pytest-cov" ], "requires_python": "", "summary": "", "version": "3.2.4" }, "last_serial": 3378927, "releases": { "3.2.0": [ { "comment_text": "", "digests": { "md5": "07ea37e9602b716e79ebe70027a689af", "sha256": "8a4949fbff74eefd00e726e8449a5e266798d5f7e0c39f2eaefff50d14ab4a68" }, "downloads": -1, "filename": "microacme-3.2.0-py3-none-any.whl", "has_sig": false, "md5_digest": "07ea37e9602b716e79ebe70027a689af", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": null, "size": 7206, "upload_time": "2017-11-30T18:54:31", "url": "https://files.pythonhosted.org/packages/f3/6a/f957a8f73824b955c28f85d87a76d63238477d7ab997629bd211ad07e562/microacme-3.2.0-py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "3d494e72d7d69753ecf08abb20d0bb1e", "sha256": "dd90bd7420aa1ab067fbce22c8fa95bb61bf1376c032e12bf818f3865623ab80" }, "downloads": -1, "filename": "microacme-3.2.0.tar.gz", "has_sig": false, "md5_digest": "3d494e72d7d69753ecf08abb20d0bb1e", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 5878, "upload_time": "2017-11-30T18:54:32", "url": "https://files.pythonhosted.org/packages/b4/88/c26a56dccdef631f48cf86199c4f52ca6559e4cc0d40aaf30dcd7fc998ef/microacme-3.2.0.tar.gz" } ], "3.2.1": [ { "comment_text": "", "digests": { "md5": "4e8892410c784e373f1315e781615553", "sha256": "748844cc9555ee0bf6221be6304858bf81540b707fd9508c19baf08c6ef22c44" }, "downloads": -1, "filename": "microacme-3.2.1-py3-none-any.whl", "has_sig": false, "md5_digest": "4e8892410c784e373f1315e781615553", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": null, "size": 11548, "upload_time": "2017-11-30T21:16:42", "url": "https://files.pythonhosted.org/packages/4d/09/bddb826ad6630ed3dbc69d8d5c0ca48547ddd9dd5f8e2de6bf2234b5c49a/microacme-3.2.1-py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "0d223ab351882a5d143c524cca87ab12", "sha256": "5c977c0620446c90b6c8917f49049641079c8a82f81abc725f521c0170b0b302" }, "downloads": -1, "filename": "microacme-3.2.1.tar.gz", "has_sig": false, "md5_digest": "0d223ab351882a5d143c524cca87ab12", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 7981, "upload_time": "2017-11-30T21:16:42", "url": "https://files.pythonhosted.org/packages/40/2e/7505f6586f6519b2eac67e763e07648b4c1f9aee88baa19bc8c7f83aa87a/microacme-3.2.1.tar.gz" } ], "3.2.2": [ { "comment_text": "", "digests": { "md5": "39163eada3b3cefc38ef1a4502992219", "sha256": "9a9f360ab274582547ccacb603c9376642abe8941c5b2587669d881384261e99" }, "downloads": -1, "filename": "microacme-3.2.2-py3-none-any.whl", "has_sig": false, "md5_digest": "39163eada3b3cefc38ef1a4502992219", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": null, "size": 11544, "upload_time": "2017-11-30T21:51:45", "url": "https://files.pythonhosted.org/packages/86/42/dee7bee361cc55fb78edc1ee4f0bb31f69a78f5c70b7a7068304fc598073/microacme-3.2.2-py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "bf8906b207954f748e5689a8b991be8f", "sha256": "ccf5c426ab95b7e00df60fb21b09c4bdbf89c5fd6e58a5d59269086a9787208d" }, "downloads": -1, "filename": "microacme-3.2.2.tar.gz", "has_sig": false, "md5_digest": "bf8906b207954f748e5689a8b991be8f", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 7981, "upload_time": "2017-11-30T21:51:46", "url": "https://files.pythonhosted.org/packages/02/06/323274a113d7334701ae3c45f64e08c343a14a39d69fcd2e4c2df9fef2a6/microacme-3.2.2.tar.gz" } ], "3.2.3": [ { "comment_text": "", "digests": { "md5": "5435bce57b96da60ca858f910ee56706", "sha256": "6814c4b9c7a5780776fdf87fc76039267895c8497125f3ca6381685295ec839b" }, "downloads": -1, "filename": "microacme-3.2.3-py3-none-any.whl", "has_sig": false, "md5_digest": "5435bce57b96da60ca858f910ee56706", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": null, "size": 11553, "upload_time": "2017-11-30T23:25:51", "url": "https://files.pythonhosted.org/packages/5c/06/9f69200bc48fa48e0d7990e9d771b95521e3817c95a21d7de40094f59797/microacme-3.2.3-py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "95a4cd747e3e973fc46eedc3cf2e6c46", "sha256": "fd6bd9f5eb230207711fea8294ecb550ed207ec339adb89491fa04b94da22d27" }, "downloads": -1, "filename": "microacme-3.2.3.tar.gz", "has_sig": false, "md5_digest": "95a4cd747e3e973fc46eedc3cf2e6c46", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 8049, "upload_time": "2017-11-30T23:25:53", "url": "https://files.pythonhosted.org/packages/fb/23/8e5139aed4cc067c2158b7b30b7ada9e5ff3e470ea614327aec87608b4c4/microacme-3.2.3.tar.gz" } ], "3.2.4": [ { "comment_text": "", "digests": { "md5": "bdec858b9e5184d51365673fc8674aac", "sha256": "8e2ea6ba5e933e522860a52bfbb44db08c52a7452321de3e45af738e4d1648e3" }, "downloads": -1, "filename": "microacme-3.2.4-py3-none-any.whl", "has_sig": false, "md5_digest": "bdec858b9e5184d51365673fc8674aac", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": null, "size": 11552, "upload_time": "2017-12-01T00:36:19", "url": "https://files.pythonhosted.org/packages/5c/fa/b801f4f8deb294af5485ce49cc364935015b6418a8fe197c90f2431e205d/microacme-3.2.4-py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "311003a3bdd34ddd064dc66f867fcef7", "sha256": "d2405ce976715c6365a6b308fd80f57df74b4e3f42b2a8234c35bf1d4cd65719" }, "downloads": -1, "filename": "microacme-3.2.4.tar.gz", "has_sig": false, "md5_digest": "311003a3bdd34ddd064dc66f867fcef7", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 8047, "upload_time": "2017-12-01T00:36:20", "url": "https://files.pythonhosted.org/packages/0e/55/76647c1e8fb185ddfe08935bc0e26d819ce2098a24ad8acb27fc76f017ef/microacme-3.2.4.tar.gz" } ] }, "urls": [ { "comment_text": "", "digests": { "md5": "bdec858b9e5184d51365673fc8674aac", "sha256": "8e2ea6ba5e933e522860a52bfbb44db08c52a7452321de3e45af738e4d1648e3" }, "downloads": -1, "filename": "microacme-3.2.4-py3-none-any.whl", "has_sig": false, "md5_digest": "bdec858b9e5184d51365673fc8674aac", "packagetype": "bdist_wheel", "python_version": "py3", "requires_python": null, "size": 11552, "upload_time": "2017-12-01T00:36:19", "url": "https://files.pythonhosted.org/packages/5c/fa/b801f4f8deb294af5485ce49cc364935015b6418a8fe197c90f2431e205d/microacme-3.2.4-py3-none-any.whl" }, { "comment_text": "", "digests": { "md5": "311003a3bdd34ddd064dc66f867fcef7", "sha256": "d2405ce976715c6365a6b308fd80f57df74b4e3f42b2a8234c35bf1d4cd65719" }, "downloads": -1, "filename": "microacme-3.2.4.tar.gz", "has_sig": false, "md5_digest": "311003a3bdd34ddd064dc66f867fcef7", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 8047, "upload_time": "2017-12-01T00:36:20", "url": "https://files.pythonhosted.org/packages/0e/55/76647c1e8fb185ddfe08935bc0e26d819ce2098a24ad8acb27fc76f017ef/microacme-3.2.4.tar.gz" } ] }