diff --git a/README.md b/README.md index 04267e3d..8580938c 100644 --- a/README.md +++ b/README.md @@ -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. diff --git a/docker/crypto-test/Dockerfile b/docker/crypto-test/Dockerfile new file mode 100644 index 00000000..988a6805 --- /dev/null +++ b/docker/crypto-test/Dockerfile @@ -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 diff --git a/docker/crypto-test/gen_testdata.sh b/docker/crypto-test/gen_testdata.sh new file mode 100755 index 00000000..e8377cce --- /dev/null +++ b/docker/crypto-test/gen_testdata.sh @@ -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 diff --git a/requirements-crypto-test.txt b/requirements-crypto-test.txt new file mode 100644 index 00000000..00bc942d --- /dev/null +++ b/requirements-crypto-test.txt @@ -0,0 +1,3 @@ +-r requirements-crypto.txt +requests==2.23.0 +pytest==5.4.1 diff --git a/requirements-crypto.txt b/requirements-crypto.txt new file mode 100644 index 00000000..9e27a3d6 --- /dev/null +++ b/requirements-crypto.txt @@ -0,0 +1,2 @@ +pycrypto>=2.6.1,<3.0.0 +pyOpenSSL>=19.1.0,<20.0.0 diff --git a/requirements.txt b/requirements.txt index 3f765a26..fdccba67 100644 --- a/requirements.txt +++ b/requirements.txt @@ -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 diff --git a/ro_help/mobilpay/mobilpay/test.py b/ro_help/mobilpay/mobilpay/test.py new file mode 100755 index 00000000..8eb8e051 --- /dev/null +++ b/ro_help/mobilpay/mobilpay/test.py @@ -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') + +if __name__ == "__main__": + unittest.main()