Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
7 changes: 7 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,13 @@ black --line-length 120 --target-version py37
```
before a commit will do the trick.


To run the crypto unit tests, one can invoke
```bash
docker build -f docker/crypto-test/Dockerfile .
```
The unit-tests are run from the Dockerfile, if `docker build` succeeds, the tests have passed.

## Deployment
The deployment process is fully automated using AWS CodeBuild and ECS. Each time a PR is merged on master, a new docker image build is trigger and if it's successful, [the staging environment](http://dev.rohelp.ro/) will point to your latest changes.

Expand Down
14 changes: 14 additions & 0 deletions docker/crypto-test/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
# not "-alpine", because "cryptography" has no wheel for it, it tries to
# compile, wants rust, and fails.
FROM python:3.7.4

WORKDIR /build
ADD requirements-crypto*.txt ./
RUN pip install --upgrade pip \
&& pip install -r requirements-crypto-test.txt

ADD docker/crypto-test/gen_testdata.sh .
RUN ./gen_testdata.sh

ADD ro_help/mobilpay mobilpay/
RUN pytest mobilpay/mobilpay/test.py -v
37 changes: 37 additions & 0 deletions docker/crypto-test/gen_testdata.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
#!/bin/sh
# Generate data for crypto tests

for size in 1024 ; do
for side in us them ; do
d=pki/${side}-rsa${size}
mkdir -p $d
openssl genrsa -out $d/private.pem $size
openssl req \
-x509 \
-key $d/private.pem \
-out $d/public.pem \
-subj "/OU=test/CN=$side" \
-days 36525
openssl rsa \
-in $d/private.pem \
-out $d/rawpublic.pem \
-outform PEM \
-pubout
echo "message from $side" > $d/msg.clear
openssl rand 16 > $d/enc.key
openssl enc \
-rc4 \
-nosalt \
-in $d/msg.clear \
-out $d/msg.enc \
-K $(od -tx1 -An < $d/enc.key | tr -d ' ')
base64 -w0 < $d/msg.enc > $d/msg.enc.b64
openssl rsautl \
-encrypt \
-inkey $d/rawpublic.pem \
-pubin \
-in $d/enc.key \
-out $d/enc.key.rsaenc
base64 -w0 < $d/enc.key.rsaenc > $d/enc.key.rsaenc.b64
done
done
3 changes: 3 additions & 0 deletions requirements-crypto-test.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
-r requirements-crypto.txt
requests==2.23.0

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why not use the dev requirements for the test env?

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Because #387 . After that is fixed, I've prepared a rebased v2 branch that could be used instead.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ugh, yeah. 🤕 I will try to find the time to backport the dependency management from https://github.com/code4romania/votong and get this fixed.

pytest==5.4.1
2 changes: 2 additions & 0 deletions requirements-crypto.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
pycrypto>=2.6.1,<3.0.0
pyOpenSSL>=19.1.0,<20.0.0
3 changes: 1 addition & 2 deletions requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,7 @@ django-admin-autocomplete-filter==0.4
boto3>=1.12.24,<2.0.0
django-storages>=1.9.1,<2.0.0
django-recaptcha>=2.0.6,<3.0.0
pycrypto>=2.6.1,<3.0.0
pyOpenSSL>=19.1.0,<20.0.0
-r requirements-crypto.txt
django-file-resubmit>=0.5.2,<1.0.0
django-extensions==2.2.8
requests==2.23.0
Expand Down
35 changes: 35 additions & 0 deletions ro_help/mobilpay/mobilpay/test.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
#!/usr/bin/env python3

import unittest
from mobilpay.mobilpay.util.encrypt_data import Crypto

class TestCrypto(unittest.TestCase):
def test_load_pub(self):
pubkey = Crypto().get_rsa_key('pki/us-rsa1024/public.pem')
self.assertIsNotNone(pubkey)
self.assertTrue(pubkey)
def test_load_priv(self):
privkey = Crypto().get_private_key('pki/us-rsa1024/private.pem')
self.assertIsNotNone(privkey)
self.assertTrue(privkey)
def test_self_roundtrip(self):
pubkey = Crypto().get_rsa_key('pki/us-rsa1024/public.pem')
privkey = Crypto().get_private_key('pki/us-rsa1024/private.pem')
clear_msg = b'forty-two'
enc_msg, enc_block_key = Crypto().encrypt(clear_msg, pubkey)
dec_msg = Crypto().decrypt(enc_msg, privkey, enc_block_key)
self.assertEqual(dec_msg, clear_msg)
def test_decrypt(self):
d = 'pki/them-rsa1024/'
def _slurp(fname):
with open(d + fname, 'r') as fp:
return fp.read()

msg_enc = _slurp('msg.enc.b64')
enc_key_rsaenc = _slurp('enc.key.rsaenc.b64')
privkey = Crypto().get_private_key(d + 'private.pem')
dec_msg = Crypto().decrypt(msg_enc, privkey, enc_key_rsaenc)
self.assertEqual(dec_msg, b'message from them\n')

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These are great. 👍 I would only recommend that we use pytest instead of the unittest library and move this test file in a tests folder in the root of the project.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not sure about moving to tests/; it would place the tests far away from the implementation, and would require at least some tweaking of imports.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fair enough. I would still propose we have a separate ro_help/mobilpay/mobilpay/tests folder here and also add the name of the module you are testing as a suffix to the file name, something like test_encrypt_data.py. What do you say?


if __name__ == "__main__":
unittest.main()