minisignxml


Nameminisignxml JSON
Version 24.6 PyPI version JSON
download
home_pagehttps://github.com/HENNGE/minisignxml
SummaryMinimal XML signature and verification, intended for use with SAML2
upload_time2024-06-10 07:40:09
maintainerNone
docs_urlNone
authorJonas Obrist
requires_python<4.0,>=3.8
licenseApache-2.0
keywords
VCS
bugtrack_url
requirements No requirements were recorded.
Travis-CI No Travis.
coveralls test coverage No coveralls.
            # minisignxml

[![Code style: black](https://img.shields.io/badge/code%20style-black-000000.svg)](https://github.com/psf/black)
[![CircleCI](https://circleci.com/gh/HENNGE/minisignxml.svg?style=svg)](https://circleci.com/gh/HENNGE/minisignxml)


Python library to sign and verify XML documents. 

This library, *on purpose*, only supports a limited part of the xmldsig specification. It is mainly aimed at allowing SAML documents to be signed and verified.

Supported features:

* Simple API.
* Only support enveloped signatures (`http://www.w3.org/2000/09/xmldsig#enveloped-signature`)
* Require and only support exclusive XML canonincalization without comments (`http://www.w3.org/2001/10/xml-exc-c14n#`)
* Support SHA-256 (default) and SHA-1 (for compatibility, not recommended) for signing and digest (`https://www.w3.org/2000/09/xmldsig#sha1`, `https://www.w3.org/2000/09/xmldsig#rsa-sha1`, `http://www.w3.org/2001/04/xmlenc#sha256`, `http://www.w3.org/2001/04/xmldsig-more#rsa-sha256`)
* Only support X509 certificates and RSA private keys
* Uses `lxml` for XML handling and `cryptography` for cryptography.
* Only supports a single signature, with a single reference in a document.
* Support certificate rollover by providing multiple certificates when verifying a document.

`minisignxml` performs no IO and you have to manage and load the keys/certificates yourself.

## API

### Signing

`minisignxml.sign.sign`

```python
def sign(
    *,
    element: Element,
    private_key: RSAPrivateKey,
    certificate: Certificate,
    config: SigningConfig = SigningConfig.default(),
    index: int = 0,
    attribute: str = "ID"
) -> bytes:
```

Signs the given `lxml.etree._Element` with the given `cryptography.hazmat.primitives.asymmetric.rsa.RSAPrivateKey` private key, embedding the `cryptography.x509.Certificate` in the signature. Use `minisignxml.config.SigningConfig` to control the hash algorithms uses (default is SHA-256). The `index` controls at which index the signature element is appended to the element.

If the `element` passed in does not have an attribute matching `attribute`, an exception is raised. It is the callers responsibility to ensure the value of the `attribute` attribute of the `Element` is unique for the whole document.

Returns `bytes` containing the serialized XML including the signature. 

#### SigningConfig

`minisignxml.config.SigningConfig` is a `dataclass` with the following fields:

* `signature_method`: A `cryptography.hazmat.primitives.hashes.HashAlgorithm` to use for the signature. Defaults to an instance of `cryptography.hazmat.primitives.hashes.SHA256`.
* `digest_method`: A `cryptography.hazmat.primitives.hashes.HashAlgorithm` to use for the content digest. Defaults to an instance of `cryptography.hazmat.primitives.hashes.SHA256`.


### Verifying

`minisignxml.verify.extract_verified_element`

```python
def extract_verified_element(
    *, 
    xml: bytes, 
    certificate: Certificate,  
    config: VerifyConfig=VerifyConfig.default(),
    attribute: str = "ID"
) -> Element:
```

Verifies that the XML document given (as bytes) is correctly signed using the private key of the `cryptography.x509.Certificate` provided. 

A successful call to `extract_verified_element` does not guarantee the integrity of the whole document passed to it via the `xml` parameter. Only the sub-tree returned from the function has been verified. The caller should use the returned `lxml.etree._Element` for further processing.

Raises an exception (see `minisignxml.errors`, though other exceptions such as `ValueError`, `KeyError` or others may also be raised) if the verification failed. Otherwise returns the signed `lxml.etree._Element` (not necessarily the whole document passed to `extract_verified_element`), with the signature removed.

You can control the allowed signature and digest method by using a custom `VerifyConfig` instance. By default only SHA-256 is allowed.

`minisignxml.verify.extract_verified_element_and_certificate`

```python
def extract_verified_element_and_certificate(
    *, 
    xml: bytes, 
    certificates: Collection[Certificate],  
    config: VerifyConfig=VerifyConfig.default(),
    attribute: str = "ID"
) -> Tuple[Element, Certificate]:
```

Similar to `extract_verified_element`, but allows specifying multiple certificates to aid certificate rollover.
The certificate that was used to sign the xml will be returned with the verified element.

#### VerifyConfig

`minisignxml.config.SigningConfig` is a `dataclass` with the following fields:

* `allowed_signature_methods`: A container of `cryptography.hazmat.primitives.hashes.HashAlgorithm` types to allow for signing. Defaults to `{cryptography.hazmat.primitives.hashes.SHA256}`.
* `allowed_digest_methods`: A container of `cryptography.hazmat.primitives.hashes.HashAlgorithm` types to allow for the content digest. Defaults to `{cryptography.hazmat.primitives.hashes.SHA256}`.


            

Raw data

            {
    "_id": null,
    "home_page": "https://github.com/HENNGE/minisignxml",
    "name": "minisignxml",
    "maintainer": null,
    "docs_url": null,
    "requires_python": "<4.0,>=3.8",
    "maintainer_email": null,
    "keywords": null,
    "author": "Jonas Obrist",
    "author_email": "jonas.obrist@hennge.com",
    "download_url": "https://files.pythonhosted.org/packages/88/f1/70fa7a930d4210558b22c6dc01df011895e589f3e7f6716f9689fa06f8ac/minisignxml-24.6.tar.gz",
    "platform": null,
    "description": "# minisignxml\n\n[![Code style: black](https://img.shields.io/badge/code%20style-black-000000.svg)](https://github.com/psf/black)\n[![CircleCI](https://circleci.com/gh/HENNGE/minisignxml.svg?style=svg)](https://circleci.com/gh/HENNGE/minisignxml)\n\n\nPython library to sign and verify XML documents. \n\nThis library, *on purpose*, only supports a limited part of the xmldsig specification. It is mainly aimed at allowing SAML documents to be signed and verified.\n\nSupported features:\n\n* Simple API.\n* Only support enveloped signatures (`http://www.w3.org/2000/09/xmldsig#enveloped-signature`)\n* Require and only support exclusive XML canonincalization without comments (`http://www.w3.org/2001/10/xml-exc-c14n#`)\n* Support SHA-256 (default) and SHA-1 (for compatibility, not recommended) for signing and digest (`https://www.w3.org/2000/09/xmldsig#sha1`, `https://www.w3.org/2000/09/xmldsig#rsa-sha1`, `http://www.w3.org/2001/04/xmlenc#sha256`, `http://www.w3.org/2001/04/xmldsig-more#rsa-sha256`)\n* Only support X509 certificates and RSA private keys\n* Uses `lxml` for XML handling and `cryptography` for cryptography.\n* Only supports a single signature, with a single reference in a document.\n* Support certificate rollover by providing multiple certificates when verifying a document.\n\n`minisignxml` performs no IO and you have to manage and load the keys/certificates yourself.\n\n## API\n\n### Signing\n\n`minisignxml.sign.sign`\n\n```python\ndef sign(\n    *,\n    element: Element,\n    private_key: RSAPrivateKey,\n    certificate: Certificate,\n    config: SigningConfig = SigningConfig.default(),\n    index: int = 0,\n    attribute: str = \"ID\"\n) -> bytes:\n```\n\nSigns the given `lxml.etree._Element` with the given `cryptography.hazmat.primitives.asymmetric.rsa.RSAPrivateKey` private key, embedding the `cryptography.x509.Certificate` in the signature. Use `minisignxml.config.SigningConfig` to control the hash algorithms uses (default is SHA-256). The `index` controls at which index the signature element is appended to the element.\n\nIf the `element` passed in does not have an attribute matching `attribute`, an exception is raised. It is the callers responsibility to ensure the value of the `attribute` attribute of the `Element` is unique for the whole document.\n\nReturns `bytes` containing the serialized XML including the signature. \n\n#### SigningConfig\n\n`minisignxml.config.SigningConfig` is a `dataclass` with the following fields:\n\n* `signature_method`: A `cryptography.hazmat.primitives.hashes.HashAlgorithm` to use for the signature. Defaults to an instance of `cryptography.hazmat.primitives.hashes.SHA256`.\n* `digest_method`: A `cryptography.hazmat.primitives.hashes.HashAlgorithm` to use for the content digest. Defaults to an instance of `cryptography.hazmat.primitives.hashes.SHA256`.\n\n\n### Verifying\n\n`minisignxml.verify.extract_verified_element`\n\n```python\ndef extract_verified_element(\n    *, \n    xml: bytes, \n    certificate: Certificate,  \n    config: VerifyConfig=VerifyConfig.default(),\n    attribute: str = \"ID\"\n) -> Element:\n```\n\nVerifies that the XML document given (as bytes) is correctly signed using the private key of the `cryptography.x509.Certificate` provided. \n\nA successful call to `extract_verified_element` does not guarantee the integrity of the whole document passed to it via the `xml` parameter. Only the sub-tree returned from the function has been verified. The caller should use the returned `lxml.etree._Element` for further processing.\n\nRaises an exception (see `minisignxml.errors`, though other exceptions such as `ValueError`, `KeyError` or others may also be raised) if the verification failed. Otherwise returns the signed `lxml.etree._Element` (not necessarily the whole document passed to `extract_verified_element`), with the signature removed.\n\nYou can control the allowed signature and digest method by using a custom `VerifyConfig` instance. By default only SHA-256 is allowed.\n\n`minisignxml.verify.extract_verified_element_and_certificate`\n\n```python\ndef extract_verified_element_and_certificate(\n    *, \n    xml: bytes, \n    certificates: Collection[Certificate],  \n    config: VerifyConfig=VerifyConfig.default(),\n    attribute: str = \"ID\"\n) -> Tuple[Element, Certificate]:\n```\n\nSimilar to `extract_verified_element`, but allows specifying multiple certificates to aid certificate rollover.\nThe certificate that was used to sign the xml will be returned with the verified element.\n\n#### VerifyConfig\n\n`minisignxml.config.SigningConfig` is a `dataclass` with the following fields:\n\n* `allowed_signature_methods`: A container of `cryptography.hazmat.primitives.hashes.HashAlgorithm` types to allow for signing. Defaults to `{cryptography.hazmat.primitives.hashes.SHA256}`.\n* `allowed_digest_methods`: A container of `cryptography.hazmat.primitives.hashes.HashAlgorithm` types to allow for the content digest. Defaults to `{cryptography.hazmat.primitives.hashes.SHA256}`.\n\n",
    "bugtrack_url": null,
    "license": "Apache-2.0",
    "summary": "Minimal XML signature and verification, intended for use with SAML2",
    "version": "24.6",
    "project_urls": {
        "Homepage": "https://github.com/HENNGE/minisignxml",
        "Repository": "https://github.com/HENNGE/minisignxml"
    },
    "split_keywords": [],
    "urls": [
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "919f4af6969a33cc257ee6124aa13b49355b9b04d192653fe8bbed7e55a03d2a",
                "md5": "76348faff2fc5b4d3e3186156b771d2d",
                "sha256": "83d61745607f523783ac6c8638e2ec7a9d16f3ed178c1c4b7af9bfd02c51e944"
            },
            "downloads": -1,
            "filename": "minisignxml-24.6-py3-none-any.whl",
            "has_sig": false,
            "md5_digest": "76348faff2fc5b4d3e3186156b771d2d",
            "packagetype": "bdist_wheel",
            "python_version": "py3",
            "requires_python": "<4.0,>=3.8",
            "size": 9464,
            "upload_time": "2024-06-10T07:40:08",
            "upload_time_iso_8601": "2024-06-10T07:40:08.031157Z",
            "url": "https://files.pythonhosted.org/packages/91/9f/4af6969a33cc257ee6124aa13b49355b9b04d192653fe8bbed7e55a03d2a/minisignxml-24.6-py3-none-any.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "88f170fa7a930d4210558b22c6dc01df011895e589f3e7f6716f9689fa06f8ac",
                "md5": "50bf5eb5f08dbbdda7e67083b956b70c",
                "sha256": "7bb2de078793cdf7b7835047b79d215eb2a7e4c948653f6ecee2d95e1674f114"
            },
            "downloads": -1,
            "filename": "minisignxml-24.6.tar.gz",
            "has_sig": false,
            "md5_digest": "50bf5eb5f08dbbdda7e67083b956b70c",
            "packagetype": "sdist",
            "python_version": "source",
            "requires_python": "<4.0,>=3.8",
            "size": 7955,
            "upload_time": "2024-06-10T07:40:09",
            "upload_time_iso_8601": "2024-06-10T07:40:09.763473Z",
            "url": "https://files.pythonhosted.org/packages/88/f1/70fa7a930d4210558b22c6dc01df011895e589f3e7f6716f9689fa06f8ac/minisignxml-24.6.tar.gz",
            "yanked": false,
            "yanked_reason": null
        }
    ],
    "upload_time": "2024-06-10 07:40:09",
    "github": true,
    "gitlab": false,
    "bitbucket": false,
    "codeberg": false,
    "github_user": "HENNGE",
    "github_project": "minisignxml",
    "travis_ci": false,
    "coveralls": false,
    "github_actions": true,
    "lcname": "minisignxml"
}
        
Elapsed time: 0.34485s