Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
81 commits
Select commit Hold shift + click to select a range
94b26ec
Merge pull request #2 from abhishek-ram/devel
abhishek-ram Feb 15, 2018
f7fbf8a
add coverage
abhishek-ram Feb 15, 2018
de5f508
make attrs easily available
abhishek-ram Feb 15, 2018
eb40e4a
bump version
abhishek-ram Feb 15, 2018
47461ce
Lots of changes
abhishek-ram Apr 22, 2018
1167781
load si payload in binary
abhishek-ram Apr 22, 2018
35023f0
bump version
abhishek-ram Apr 22, 2018
ce397ea
* Fix an issue with message decompression.
abhishek-ram May 1, 2018
9f4fefd
remove debug logging for now
abhishek-ram May 1, 2018
04179e2
* Remove unnecessary conversions to bytes.
abhishek-ram May 1, 2018
5f24923
Bump version
abhishek-ram May 1, 2018
6af6bc7
check for compression before signatures as well
abhishek-ram Apr 26, 2019
dd883b3
add support for additional algorithms
abhishek-ram Apr 30, 2019
7fac38a
remove support for python 2
abhishek-ram Apr 30, 2019
0fcf070
use binary encoding for encryption and signatures
abhishek-ram Apr 30, 2019
21e0f21
look for all signature types
abhishek-ram Apr 30, 2019
43c7b0f
Bump version
abhishek-ram Apr 30, 2019
e7ff37f
Bump version
abhishek-ram Apr 30, 2019
f239930
Extract certificate information to dictionary function.
Jun 3, 2019
8dbf864
Merge pull request #6 from chadgates/extract_certificate_info
abhishek-ram Jun 3, 2019
3f90d89
remove print statements
abhishek-ram Jun 3, 2019
9d8d04d
Merge remote-tracking branch 'origin/master'
abhishek-ram Jun 3, 2019
afa25f3
some styling fixes
abhishek-ram Jun 3, 2019
bca5d62
bump version to 1.1.1
abhishek-ram Jun 3, 2019
52258be
Prevent RuntimeWarning: DateTimeField received a naive datetime
Jun 4, 2019
6cd2cb0
Prevent RuntimeWarning: DateTimeField received a naive datetime
Jun 4, 2019
bb365f3
Adding option to pass/define disposition notification to when creating
Jun 7, 2019
f21ee0e
Remove unused variable.
Jun 10, 2019
2a41029
Merge pull request #7 from chadgates/timezone_in_datetime
abhishek-ram Jun 10, 2019
946d598
use dataclasses for organization and partner
abhishek-ram Jun 11, 2019
1d6f977
restructure test cases to be part of the library
abhishek-ram Jun 11, 2019
dac1426
use coverage config file
abhishek-ram Jun 11, 2019
d372644
multiple fixes and increase the coverage to 95%
abhishek-ram Jun 11, 2019
5f0c973
correct the algo id for RC4
abhishek-ram Jun 11, 2019
4c3b446
use http policy when flattening messages for cleaner handling
abhishek-ram Jun 12, 2019
e81fd88
use f strings for string formatting
abhishek-ram Jun 12, 2019
b9ccf14
remove the option for cms encoding
abhishek-ram Jun 12, 2019
4b1d113
merge changes with master and fix test case
abhishek-ram Jun 12, 2019
972fa7d
Merge pull request #10 from abhishek-ram/check-line-endings
abhishek-ram Jun 12, 2019
fbafaf0
add the basic usage documentation
abhishek-ram Jun 12, 2019
58f5523
Bump version to 1.2.0
abhishek-ram Jun 12, 2019
215d40d
handle exceptions with parsing signed attributes and more debug logging
abhishek-ram Jun 25, 2019
7ce6726
Bump version of the repository
abhishek-ram Jun 25, 2019
72907fe
Handle MDNNotfound correctly when parsing an mdn
abhishek-ram Jun 25, 2019
50dcec0
Handle MDNNotfound correctly when parsing an mdn
abhishek-ram Jun 25, 2019
e0789e6
Update versions of crypto dependencies
Mar 31, 2020
444c922
Merge pull request #13 from Fabma/bump_up_dependency_versions
abhishek-ram Apr 4, 2020
6cc65c8
add support for python 3.8
abhishek-ram Apr 4, 2020
a98e2bf
update the smime capabilities
abhishek-ram Apr 4, 2020
dd363c6
increase the test coverage
abhishek-ram Apr 4, 2020
adbcdf8
use black to format all the files
abhishek-ram Apr 4, 2020
15f6a7b
add linter and fix linter raised issues
abhishek-ram Apr 4, 2020
89f4736
add linter and fix linter raised issues
abhishek-ram Apr 4, 2020
2f0f9d8
add linter and fix linter raised issues
abhishek-ram Apr 4, 2020
35f2982
Merge pull request #14 from abhishek-ram/bugfixes-20200404
abhishek-ram Apr 5, 2020
6885125
Bump version and update the changelog
abhishek-ram Apr 5, 2020
241ca9d
set the requirement for dataclasses correctly
abhishek-ram Apr 12, 2020
56126aa
Determine correct signature algorithm.
May 8, 2020
b86dec3
Merge pull request #16 from chadgates/sig_alg
abhishek-ram May 8, 2020
1beb1ed
Dont replace "\n" newlines in application/octet-stream payload with "…
May 11, 2020
b1540c2
Raise exception when digest_alg is not known.
May 12, 2020
1fc6b28
Formatting
May 12, 2020
8471521
Adding additional test
May 12, 2020
29e1190
Merge pull request #18 from chadgates/sig_alg
abhishek-ram May 12, 2020
b4e65f4
Merge pull request #17 from Fabma/allow_binary_data_as2_msg
abhishek-ram May 12, 2020
13bda60
Initial fix for binary messages. Missing tests for Message.build
adiroiban Aug 15, 2020
24b01bb
If no Original-Recipient provided, fall back to mandatory Final-Recip…
chadgates Oct 21, 2020
c09648b
Merge pull request #24 from chadgates/mdn_originator
abhishek-ram Oct 23, 2020
1f62d26
disable certificate validation for SI test cases
abhishek-ram Nov 1, 2020
8e811cb
disable certificate validation for SI test cases
abhishek-ram Nov 1, 2020
4fab6de
Merge branch 'fix-binary-messages' of https://github.com/chevah/pyas2…
abhishek-ram Nov 1, 2020
9f5d27c
run black to fix linting
abhishek-ram Nov 1, 2020
0a33440
Merge pull request #25 from abhishek-ram/chevah-fix-binary-messages
abhishek-ram Nov 1, 2020
29a84d8
Use pylava as the linter and freeze versions of test libs
abhishek-ram Nov 1, 2020
06b5eab
Remove support for python 3.6
abhishek-ram Nov 1, 2020
1069918
Bump the version of pyas2 to 1.3.2
abhishek-ram Nov 1, 2020
2dfa9bc
Upgrade oscrypto to 1.2.1
noah-vetcove Jan 11, 2021
ff55aa1
Merge pull request #27 from noah-vetcove/oscrypto-upgrade
abhishek-ram Jan 12, 2021
a0dce40
Bump the version of pyas2 to 1.3.3
abhishek-ram Jan 17, 2021
602bdee
Caught unhandled Openssl exception
elasticdotventures Mar 4, 2021
39214ec
fixed typo in code
elasticdotventures Mar 4, 2021
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 22 additions & 0 deletions .coveragerc
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
[run]
branch = True
omit =
*/site-packages/*
*/tests/*

[report]
exclude_lines =

# Don't complain about missing debug-only code:
def __repr__
def __str__

# Don't complain if tests don't hit defensive assertion code:
raise AssertionError
raise NotImplementedError
assert

# Don't complain if non-runnable code isn't run:
if 0:
pass
if __name__ == .__main__.:
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -90,4 +90,5 @@ ENV/

# IDEA
.idea
experiment.py
.pytest_cache/
.DS_Store
14 changes: 8 additions & 6 deletions .travis.yml
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
dist: xenial
language: python
python:
- '2.7'
- '3.4'
- '3.5'
- '3.6'
- '3.7'
- '3.8'
install:
- python setup.py install
- pip install -e ".[tests]"
script:
- python setup.py test
- pytest --cov=pyas2lib --cov-config .coveragerc --black --pylava
after_success:
- pip install codecov
- codecov
3 changes: 2 additions & 1 deletion AUTHORS.md
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
* Abhishek Ram <abhishek.ram@me.com> @abhishek-ram
* Abhishek Ram <abhishek.ram@me.com> @abhishek-ram
* Chad Gates @chadgates
75 changes: 71 additions & 4 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,74 @@
# Release History

## 0.1.0 - dev
## 1.3.3 - 2021-01-17
* Update the versions of asn1crypto, oscrypto and pyOpenSSL

> **Note:**
>
> This version is not yet released and is under active development.
## 1.3.2 - 2020-11-01
* Use `signature_algo` attribute when detecting the signature algorithm
* Raise exception when unknown `digest_alg` is passed to the sign function
* Add proper support for handling binary messages
* Look for `Final-Recipient` if `Original-Recipient` is not present in the MDN
* Remove support for python 3.6
* Fix linting and change the linter to pylava

## 1.3.1 - 2020-04-12
* Use correct format for setting dataclasses requirement for python 3.6

## 1.3.0 - 2020-04-05
* Fix and update the SMIME capabilities in the Signed attributes of a signature
* Update the versions of crypto dependencies and related changes
* Use black and pylama as code formatter and linter
* Increase test coverage and add support for python 3.8

## 1.2.2 - 2019-06-26
* Handle MDNNotfound correctly when parsing an mdn

## 1.2.1 - 2019-06-25
* Handle exceptions raised when parsing signed attributes in a signature https://github.com/abhishek-ram/django-pyas2/issues/13
* Add more debug logs during build and parse
* Catch errors in MDN parsing and handle accordingly

## 1.2.0 - 2019-06-12

* Use f-strings for string formatting.
* Use HTTP email policy for flattening email messages.
* Add proper support for other encryption algos.
* Use dataclasses for organization and partner.
* Remove support for python 3.5.
* Add utility function for extracting info from certificates.

## 1.1.1 - 2019-06-03

* Remove leftover print statement.
* Add utility for extracting public certificate information.

## 1.1.0 - 2019-04-30

* Handle cases where compression is done before signing.
* Add support for additional encryption algorithms.
* Use binary encoding for encryption and signatures.
* Look for `application/x-pkcs7-signature` when verifying signatures.
* Remove support for Python 2.

## 1.0.3 - 2018-05-01

* Remove unnecessary conversions to bytes.

## 1.0.2 - 2018-05-01

* Fix an issue with message decompression.
* Add optional callback for checking duplicate messages in parse
* Add test cases for decompression and duplicate errors

## 1.0.1 - 2018-04-22

* Check for incorrect passphrase when loading the private key.
* Change field name from `as2_id` to `as2_name` in org and partner
* Change name of class from `MDN` to `Mdn`
* Fix couple of validation issues when loading partner
* Return the traceback along with the exception when parsing messages
* Fix the mechanism for loading and validation partner certs

## 1.0.0 - 2018-02-15

* Initial release.
84 changes: 83 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
# pyas2-lib

[![pypi package](https://img.shields.io/pypi/v/pyas2lib.svg)](https://pypi.python.org/pypi/pyas2lib/)
[![Build Status](https://travis-ci.org/abhishek-ram/pyas2-lib.svg?branch=master)](https://travis-ci.org/abhishek-ram/pyas2-lib)
[![codecov](https://codecov.io/gh/abhishek-ram/pyas2-lib/branch/master/graph/badge.svg)](https://codecov.io/gh/abhishek-ram/pyas2-lib)

A pure python library for building and parsing message as part of the AS2 messaging protocol. The message definitions follow the AS2 version 1.2 as defined in the [RFC 4130][1].The library is intended to decouple the message construction/deconstruction from the web server/client implementation. The following functionality is part of this library:

* Compress, Sign and Encrypt the payload to be transmitted.
Expand All @@ -8,7 +12,85 @@ A pure python library for building and parsing message as part of the AS2 messag
* Parsing a received MIME data and identifying if it as a Message or MDN.
* Decompress, Decrypt and Verify Signature of the received payload.
* Verify Signature of the received MDN and extract original message status.



## Basic Usage

Let us take a look at how we can use this library for building and parsing of AS2 Messages.

### Setup

* First we would need to setup an organization and a partner
```python
from pyas2lib.as2 import Organization, Partner

my_org = Organization(
as2_name='my_unique_id', # Unique AS2 Id for this organization
sign_key=b'signature_key_bytes', # PEM/DER encoded private key for signature
sign_key_pass='password', # Password private key for signature
decrypt_key=b'decrypt_key_bytes', # PEM/DER encoded private key for decryption
decrypt_key_pass='password' # Password private key for decryption
)

a_partner = Partner(
as2_name='partner_unique_id', # Unique AS2 Id of your partner
sign=True, # Set to true for signing the message
verify_cert=b'verify_cert_bytes', # PEM/DER encoded certificate for verifying partner signatures
encrypt=True, # Set to true for encrypting the message
encrypt_cert=b'encrypt_cert_bytes', # PEM/DER encoded certificate for encrypting messages
mdn_mode='SYNC', # Expect to receive synchronous MDNs from this partner
mdn_digest_alg='sha256' # Expect signed MDNs to be returned by this partner
)

```

### Sending a message to your partner

* The partner is now setup we can build and AS2 message
```python
from pyas2lib.as2 import Message

msg = Message(sender=my_org, receiver=a_partner)
msg.build(b'data_to_transmit')

```
* The message is built and now `msg.content` holds the message body and `message.header` dictionary holds the message headers. These need to be passed to any http library for HTTP POSTing to the partner.
* We expect synchronous MDNs so we need to process the response to our HTTP POST
```python
from pyas2lib.as2 import Mdn

msg_mdn = Mdn() # Initialize an Mdn object

# Call the parse method with the HTTP response headers + content and a function that returns the related `pyas2lib.as2.Messsage` object.
status, detailed_status = msg_mdn.parse(b'response_data_with_headers', find_message_func)
```
* We parse the response mdn to get the status and detailed status of the message that was transmitted.

### Receiving a message from your partner

* We need to setup and HTTP server with an endpoint for receiving POST requests fro your partner.
* When a requests is received we need to first check if this is an Async MDN
```python
from pyas2lib.as2 import Mdn

msg_mdn = Mdn() # Initialize an Mdn object
# Call the parse method with the HTTP request headers + content and a function the returns the related `pyas2lib.as2.Messsage` object.
status, detailed_status = msg_mdn.parse(request_body, find_message_fumc)
```
* If this is an Async MDN it will return the status of the original message.
* In case the request is not an MDN then `pyas2lib.exceptions.MDNNotFound` is raised, which needs to be catched and parse the request as a message.
```python
from pyas2lib.as2 import Message

msg = Message()
# Call the parse method with the HTTP request headers + content, a function to return the the related `pyas2lib.as2.Organization` object, a function to return the `pyas2lib.as2.Partner` object and a function to check for duplicates.
status, exception, mdn = msg.parse(
request_body, find_organization, find_partner, check_duplicate_msg)
```
* The parse function returns a 3 element tuple; the status of parsing, exception if any raised during parsing and an `pyas2lib.as2.Mdn` object for the message.
* If the `mdn.mdn_mode` is `SYNC` then the `mdn.content` and `mdn.header` must be returned in the response.
* If the `mdn.mdn_mode` is `ASYNC` then the mdn must be saved for later processing.

## Contribute

1. Check for open issues or open a fresh issue to start a discussion around a feature idea or a bug.
Expand Down
33 changes: 21 additions & 12 deletions pyas2lib/__init__.py
Original file line number Diff line number Diff line change
@@ -1,15 +1,24 @@
from __future__ import absolute_import
import sys
from pyas2lib.constants import (
DIGEST_ALGORITHMS,
ENCRYPTION_ALGORITHMS,
MDN_CONFIRM_TEXT,
MDN_FAILED_TEXT,
)
from pyas2lib.as2 import Mdn
from pyas2lib.as2 import Message
from pyas2lib.as2 import Organization
from pyas2lib.as2 import Partner

VERSION = (1, 0, '0b1')
__version__ = VERSION
__versionstr__ = '.'.join(map(str, VERSION))
__version__ = "1.3.3"


if (2, 7) <= sys.version_info < (3, 2):
# On Python 2.7 and Python3 < 3.2, install no-op handler to silence
# `No handlers could be found for logger "elasticsearch"` message per
# <https://docs.python.org/2/howto/logging.html#configuring-logging-for-a-library>
import logging
logger = logging.getLogger('pyas2lib')
logger.addHandler(logging.NullHandler())
__all__ = [
"DIGEST_ALGORITHMS",
"ENCRYPTION_ALGORITHMS",
"MDN_CONFIRM_TEXT",
"MDN_FAILED_TEXT",
"Partner",
"Organization",
"Message",
"Mdn",
]
Loading