Merge pull request #178 from jMyles/tls

Ursula now uses TLS.
pull/181/head
Justin Holmes 2018-03-07 16:03:18 -08:00 committed by GitHub
commit 3712dde087
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
25 changed files with 233 additions and 708 deletions

16
Pipfile
View File

@ -1,28 +1,26 @@
[[source]]
[[source]]
url = "https://pypi.python.org/simple"
verify_ssl = true
name = "pypi"
[packages]
rpcudp = {git = "https://github.com/nucypher/rpcudp", ref = "kms-dependency"}
kademlia = {git = "https://github.com/nucypher/kademlia", ref = "kms-dependency"}
lmdb = "*"
PyNaCl = "*"
pynacl = "*"
"pysha3" = "*"
bidict = "*"
py_ecc = "*"
SQLAlchemy = "*"
Twisted = "*"
pyOpenSSL = "*"
service_identity = "*"
py-ecc = "*"
sqlalchemy = "*"
apistar = "*"
mypy = "*"
pytest-mypy = "*"
maya = "*"
kms-depend = {git = "https://github.com/nucypher/pyumbral.git"}
pyumbral = {git = "https://github.com/nucypher/pyumbral.git"}
requests = "*"
hendrix = {git = "https://github.com/hendrix/hendrix", ref = "tags/3.0.0rc1"}
[dev-packages]

327
Pipfile.lock generated
View File

@ -1,20 +1,20 @@
{
"_meta": {
"hash": {
"sha256": "5c83f6b1642270b76ca132879aaa6ba19bd250166ebddce2473140bfe53ed39b"
"sha256": "11bb15e6f17668114a961f86fd5285b0140fa03ba86d7fc68d91425dab566b28"
},
"host-environment-markers": {
"implementation_name": "cpython",
"implementation_version": "3.6.2",
"implementation_version": "3.6.3",
"os_name": "posix",
"platform_machine": "x86_64",
"platform_python_implementation": "CPython",
"platform_release": "17.4.0",
"platform_system": "Darwin",
"platform_version": "Darwin Kernel Version 17.4.0: Sun Dec 17 09:19:54 PST 2017; root:xnu-4570.41.2~1/RELEASE_X86_64",
"python_full_version": "3.6.2",
"platform_release": "4.13.0-36-generic",
"platform_system": "Linux",
"platform_version": "#40-Ubuntu SMP Fri Feb 16 20:07:48 UTC 2018",
"python_full_version": "3.6.3",
"python_version": "3.6",
"sys_platform": "darwin"
"sys_platform": "linux"
},
"pipfile-spec": 6,
"requires": {},
@ -33,13 +33,6 @@
],
"version": "==0.3.9"
},
"asn1crypto": {
"hashes": [
"sha256:2f1adbb7546ed199e3c90ef23ec95c5cf3585bac7d11fb7eb562a3fe89c64e87",
"sha256:9d5c20441baf0cb60a4ac34cc447c6c189024b6b4c6cd7877034f4965c464e49"
],
"version": "==0.24.0"
},
"attrs": {
"hashes": [
"sha256:a17a9573a6f475c99b551c0e0a812707ddda1ec9653bed04c13841404ed6f450",
@ -47,13 +40,6 @@
],
"version": "==17.4.0"
},
"automat": {
"hashes": [
"sha256:2140297df155f7990f6f4c73b2ab0583bd8150db9ed2a1b48122abe66e9908c1",
"sha256:3c1fd04ecf08ac87b4dd3feae409542e9bf7827257097b2b6ed5692f69d6f6a8"
],
"version": "==0.6.0"
},
"bidict": {
"hashes": [
"sha256:3f6ec9df779b919fcf8998be8955ade9c4337df04d215a0a0e4296f66e70eac9"
@ -69,35 +55,35 @@
},
"cffi": {
"hashes": [
"sha256:5d0d7023b72794ea847725680e2156d1d01bc698a9007fccce46d03c904fe093",
"sha256:86903c0afab4a3390170aca61f753f5adad8ffff947030719ee44dedc5b68403",
"sha256:7d35678a54da0d3f1bc30e3a58a232043753d57c691875b5a75e4e062793bc9a",
"sha256:824cac33906be5c8e976f0d950924d88ec058989ef9cd2f77f5cd53cec417635",
"sha256:6ca52651f6bd4b8647cb7dee15c82619de3e13490f8e0bc0620830a2245b51d1",
"sha256:a183959a4b1e01d6172aeed356e2523ec8682596075aa6cf0003fe08da959a49",
"sha256:9532c5bc0108bd0fe43c0eb3faa2ef98a2db60fc0d4019f106b88d46803dd663",
"sha256:96652215ef328262b5f1d5647632bd342ac6b31dfbc495b21f1ab27cb06d621d",
"sha256:6c99d19225e3135f6190a3bfce2a614cae8eaa5dcaf9e0705d4ccb79a3959a3f",
"sha256:12cbf4c04c1ad07124bfc9e928c01e282feac9ec7dd72a18042d4fc56456289a",
"sha256:69c37089ccf10692361c8d14dbf4138b00b46741ffe9628755054499f06ed548",
"sha256:b8d1454ef627098dc76ccfd6211a08065e6f84efe3754d8d112049fec3768e71",
"sha256:cd13f347235410c592f6e36395ee1c136a64b66534f10173bfa4df1dc88f47d0",
"sha256:0640f12f04f257c4467075a804a4920a5d07ef91e11c525fc65d715c08231c81",
"sha256:89a8d05b96bdeca8fdc89c5fa9469a357d30f6c066262e92c0c8d2e4d3c53cae",
"sha256:a67c430a9bde73ae85b0c885fcf41b556760e42ea74c16dc70431a349989b448",
"sha256:7a831170b621e98f45ed1d5758325be19619a593924127a0a47af9a72a117319",
"sha256:796d0379102e6da5215acfcd20e8e69cca9d97309215b4ce088fe175b1c2f586",
"sha256:0fe3b3d571543a4065059d1d3d6d39f4ca6da0f2207ad13547094522e32ead46",
"sha256:678135090c311780382b1dd3f828f715583ea8a69687ed053c047d3cec6625d6",
"sha256:f4992cd7b4c867f453d44c213ee29e8fd484cf81cfece4b6e836d0982b6fa1cf",
"sha256:6d191fb20138fe1948727b20e7b96582b7b7e676135eabf72d910e10bf7bfa65",
"sha256:ec208ca16e57904dd7f4c7568665f80b1f7eb7e3214be014560c28def219060d",
"sha256:b3653644d6411bf4bd64c1f2ca3cb1b093f98c68439ade5cef328609bbfabf8c",
"sha256:f4719d0bafc5f0a67b2ec432086d40f653840698d41fa6e9afa679403dea9d78",
"sha256:87f837459c3c78d75cb4f5aadf08a7104db15e8c7618a5c732e60f252279c7a6",
"sha256:df9083a992b17a28cd4251a3f5c879e0198bb26c9e808c4647e0a18739f1d11d"
"sha256:1b0493c091a1898f1136e3f4f991a784437fac3673780ff9de3bcf46c80b6b50",
"sha256:87f37fe5130574ff76c17cab61e7d2538a16f843bb7bca8ebbc4b12de3078596",
"sha256:1553d1e99f035ace1c0544050622b7bc963374a00c467edafac50ad7bd276aef",
"sha256:151b7eefd035c56b2b2e1eb9963c90c6302dc15fbd8c1c0a83a163ff2c7d7743",
"sha256:edabd457cd23a02965166026fd9bfd196f4324fe6032e866d0f3bd0301cd486f",
"sha256:ba5e697569f84b13640c9e193170e89c13c6244c24400fc57e88724ef610cd31",
"sha256:79f9b6f7c46ae1f8ded75f68cf8ad50e5729ed4d590c74840471fc2823457d04",
"sha256:b0f7d4a3df8f06cf49f9f121bead236e328074de6449866515cea4907bbc63d6",
"sha256:4c91af6e967c2015729d3e69c2e51d92f9898c330d6a851bf8f121236f3defd3",
"sha256:7a33145e04d44ce95bcd71e522b478d282ad0eafaf34fe1ec5bbd73e662f22b6",
"sha256:95d5251e4b5ca00061f9d9f3d6fe537247e145a8524ae9fd30a2f8fbce993b5b",
"sha256:b75110fb114fa366b29a027d0c9be3709579602ae111ff61674d28c93606acca",
"sha256:ae5e35a2c189d397b91034642cb0eab0e346f776ec2eb44a49a459e6615d6e2e",
"sha256:fdf1c1dc5bafc32bc5d08b054f94d659422b05aba244d6be4ddc1c72d9aa70fb",
"sha256:9d1d3e63a4afdc29bd76ce6aa9d58c771cd1599fbba8cf5057e7860b203710dd",
"sha256:be2a9b390f77fd7676d80bc3cdc4f8edb940d8c198ed2d8c0be1319018c778e1",
"sha256:ed01918d545a38998bfa5902c7c00e0fee90e957ce036a4000a88e3fe2264917",
"sha256:857959354ae3a6fa3da6651b966d13b0a8bed6bbc87a0de7b38a549db1d2a359",
"sha256:2ba8a45822b7aee805ab49abfe7eec16b90587f7f26df20c71dd89e45a97076f",
"sha256:a36c5c154f9d42ec176e6e620cb0dd275744aa1d804786a71ac37dc3661a5e95",
"sha256:e55e22ac0a30023426564b1059b035973ec82186ddddbac867078435801c7801",
"sha256:3eb6434197633b7748cea30bf0ba9f66727cdce45117a712b29a443943733257",
"sha256:ecbb7b01409e9b782df5ded849c178a0aa7c906cf8c5a67368047daab282b184",
"sha256:770f3782b31f50b68627e22f91cb182c48c47c02eb405fd689472aa7b7aa16dc",
"sha256:d5d8555d9bfc3f02385c1c37e9f998e2011f0db4f90e250e5bc0c0a85a813085",
"sha256:3c85641778460581c42924384f5e68076d724ceac0f267d66c757f7535069c93",
"sha256:e90f17980e6ab0f3c2f3730e56d1fe9bcba1891eeea58966e89d352492cc74f4"
],
"version": "==1.11.4"
"version": "==1.11.5"
},
"chardet": {
"hashes": [
@ -106,13 +92,6 @@
],
"version": "==3.0.4"
},
"constantly": {
"hashes": [
"sha256:dd2fa9d6b1a51a83f0d7dd76293d734046aa176e384bf6e33b7e44880eb37c5d",
"sha256:586372eb92059873e29eba4f9dec8381541b4d3834660707faf8ba59146dfc35"
],
"version": "==15.1.0"
},
"coreapi": {
"hashes": [
"sha256:bf39d118d6d3e171f10df9ede5666f63ad80bba9a29a8ec17726a66cf52ee6f3",
@ -127,34 +106,6 @@
],
"version": "==0.0.4"
},
"cryptography": {
"hashes": [
"sha256:69285f5615507b6625f89ea1048addd1d9218585fb886eb90bdebb1d2b2d26f5",
"sha256:6cb1224da391fa90f1be524eafb375b62baf8d3df9690b32e8cc475ccfccee5e",
"sha256:4f385ee7d39ee1ed74f1d6b1da03d0734ea82855a7b28a9e6e88c4091bc58664",
"sha256:a5f2c681fd040ed648513939a1dd2242af19bd5e9e79e53b6dcfa33bdae61217",
"sha256:fc2208d95d9ecc8032f5e38330d5ace2e3b0b998e42b08c30c35b2ab3a4a3bc8",
"sha256:0d39a93cf25edeae1f796bbc5960e587f34513a852564f6345ea4491a86c5997",
"sha256:41f94194ae78f83fd94ca94fb8ad65f92210a76a2421169ffa5c33c3ec7605f4",
"sha256:7a2409f1564c84bcf2563d379c9b6148c5bc6b0ae46e109f6a7b4bebadf551df",
"sha256:55555d784cfdf9033e81f044c0df04babed2aa141213765d960d233b0139e353",
"sha256:9a47a80f65f4feaaf8415a40c339806c7d7d867152ddccc6ca87f707c8b7b565",
"sha256:6fb22f63e17813f3d1d8e30dd1e249e2c34233ba1d3de977fd31cb5db764c7d0",
"sha256:ee245f185fae723133511e2450be08a66c2eebb53ad27c0c19b228029f4748a5",
"sha256:9a2945efcff84830c8e237ab037d0269380d75d400a89cc9e5628e52647e21be",
"sha256:2cfcee8829c5dec55597826d52c26bc26e7ce39adb4771584459d0636b0b7108",
"sha256:33b564196dcd563e309a0b07444e31611368afe3a3822160c046f5e4c3b5cdd7",
"sha256:18d0b0fc21f39b35ea469a82584f55eeecec1f65a92d85af712c425bdef627b3",
"sha256:d18df9cf3f3212df28d445ea82ce702c4d7a35817ef7a38ee38879ffa8f7e857",
"sha256:b984523d28737e373c7c35c8b6db6001537609d47534892de189bebebaa42a47",
"sha256:27a208b9600166976182351174948e128818e7fc95cbdba18143f3106a211546",
"sha256:28e4e9a97713aa47b5ef9c5003def2eb58aec89781ef3ef82b1c2916a8b0639b",
"sha256:a3c180d12ffb1d8ee5b33a514a5bcb2a9cc06cc89aa74038015591170c82f55d",
"sha256:8487524a1212223ca6dc7e2c8913024618f7ff29855c98869088e3818d5f6733",
"sha256:e4d967371c5b6b2e67855066471d844c5d52d210c36c28d49a8507b96e2c5291"
],
"version": "==2.1.4"
},
"dateparser": {
"hashes": [
"sha256:b452ef8b36cd78ae86a50721794bc674aa3994e19b570f7ba92810f4e0a2ae03",
@ -162,19 +113,16 @@
],
"version": "==0.7.0"
},
"hendrix": {
"git": "https://github.com/hendrix/hendrix",
"ref": "tags/3.0.0rc1"
},
"humanize": {
"hashes": [
"sha256:a43f57115831ac7c70de098e6ac46ac13be00d69abbf60bdcac251344785bb19"
],
"version": "==0.5.1"
},
"hyperlink": {
"hashes": [
"sha256:1ec8e11fb4f5b330f25864bf8cfd3133dff1a3637dfd14fa441297df15fc7cf9",
"sha256:bc4ffdbde9bdad204d507bd8f554f16bba82dd356f6130cb16f41422909c33bc"
],
"version": "==17.3.1"
},
"idna": {
"hashes": [
"sha256:8c7309c718f94b3a625cb648ace320157ad16ff131ae0af362c9f21b80ef6ec4",
@ -182,13 +130,6 @@
],
"version": "==2.6"
},
"incremental": {
"hashes": [
"sha256:717e12246dddf231a349175f48d74d93e2897244939173b01974ab6661406b9f",
"sha256:7b751696aaf36eebfab537e458929e194460051ccad279c72b755a167eebd4b3"
],
"version": "==17.5.0"
},
"itypes": {
"hashes": [
"sha256:c6e77bb9fd68a4bfeb9d958fea421802282451a25bac4913ec94db82a899c073"
@ -206,9 +147,6 @@
"git": "https://github.com/nucypher/kademlia",
"ref": "kms-dependency"
},
"kms-depend": {
"git": "https://github.com/nucypher/pyumbral.git"
},
"lmdb": {
"hashes": [
"sha256:724234c4df6a8ef987957b6db92417c42afc3091d88765e9a8e52143b1309948",
@ -248,30 +186,30 @@
},
"maya": {
"hashes": [
"sha256:b22d22837f921b8cbe884b6a288d9f795c58d9d9165e4a9ff80df102914e2e49",
"sha256:bad39d8f9c6e2c8f446a2187eafbc2128aa20397787be1e4697bb29b239908f5"
"sha256:ad1969bae78afb148c45a2f63591a7575ec05b4a0ab7ec04987ab7d73649f9d6",
"sha256:d8a7ed8513b2990036fe456c9f595b54d19ec49cb4461cd95a2ef6c487fb55eb"
],
"version": "==0.3.3"
"version": "==0.3.4"
},
"mypy": {
"hashes": [
"sha256:aa668809ae0dbec5e9feb8929f4b5e1f9318a0a397447fa2f38c382a2ed6a036",
"sha256:bd0c9a2fcf0c4f7a54a2b625f466fcc000d415f371298d96fa5d2acc69074aca"
"sha256:884f18f3a40cfcf24cdd5860b84958cfb35e6563e439c5adc1503878df221dc3",
"sha256:83d798f66323f2de6191d66d9ae5ab234e4ee5b400010e19c58d75d308049f25"
],
"version": "==0.560"
"version": "==0.570"
},
"pendulum": {
"hashes": [
"sha256:6340585b4df65b88732127601c7c8556fbcf7f0f9c7270a4afc0a8eb54e62343",
"sha256:ef3a020ecd03cdad9ada397dd868e2c09348880df82e9b41628042e37235898a",
"sha256:755bf25dfe4455af7c296751d10abe54ffcd17394c6005c16db9f84e71b1eacf",
"sha256:dd8b9ebe9f00392f444cf963bed8d81efa59551ca1ccdf9f01837f0fbd52af5a",
"sha256:bffaf9b8b333a3e64527a34bc5891e182b9dcd5811d2ff6fb68452fb771de5b2",
"sha256:d7568452b7ab30a6d6ac15a4905455a924173d17e4801fac681a67c570e6d84e",
"sha256:ec71cea66eb8e0704e314ce693e8188d4f617e1ef84c3cd02fd11b688859062e",
"sha256:3f16fb759e6126dd89d49886f8100caa72e5ab36563bc148b4f7eddfa0099c0f"
"sha256:881efe37328de0785c0731d462e1485a45712f2cd5cb55907d6c15458460ebeb",
"sha256:3c85e8cbc91f45e1cc916cc9180b34153cd6aaaaacfb51a48b3156318314fa82",
"sha256:0c14388546db6605a860b8b7112cb69d0b11c9ce5e072210504544e0d4575799",
"sha256:8798aeca58b3dd7ffdc5a4993c9eaafedc4048165429e8f499ddd62c73bf3964",
"sha256:8199206c479b13947dcac63c025575d035331bb3819d1783dc1d568a11962906",
"sha256:bcca072f82e84b419efec1320cd3ee5c230d263f3a601b146651ed4db77d89f0",
"sha256:ff0c5fa3af4a471a218408c448b804ac6bccb105127727474f4e83c0e4072e97",
"sha256:39a255776528afe11ea0d57814f9bf3729c1e0b99063af2e5c6cfd750c3e1f7f"
],
"version": "==1.4.1"
"version": "==1.4.2"
},
"pluggy": {
"hashes": [
@ -279,20 +217,6 @@
],
"version": "==0.6.0"
},
"psutil": {
"hashes": [
"sha256:82a06785db8eeb637b349006cc28a92e40cd190fefae9875246d18d0de7ccac8",
"sha256:4152ae231709e3e8b80e26b6da20dc965a1a589959c48af1ed024eca6473f60d",
"sha256:230eeb3aeb077814f3a2cd036ddb6e0f571960d327298cc914c02385c3e02a63",
"sha256:a3286556d4d2f341108db65d8e20d0cd3fcb9a91741cb5eb496832d7daf2a97c",
"sha256:94d4e63189f2593960e73acaaf96be235dd8a455fe2bcb37d8ad6f0e87f61556",
"sha256:c91eee73eea00df5e62c741b380b7e5b6fdd553891bee5669817a3a38d036f13",
"sha256:779ec7e7621758ca11a8d99a1064996454b3570154277cc21342a01148a49c28",
"sha256:8a15d773203a1277e57b1d11a7ccdf70804744ef4a9518a87ab8436995c31a4b",
"sha256:e2467e9312c2fa191687b89ff4bc2ad8843be4af6fb4dc95a7cc5f7d7a327b18"
],
"version": "==5.4.3"
},
"py": {
"hashes": [
"sha256:8cca5c229d225f8c1e3085be4fcf306090b00850fefad892f9d96c7b6e2f310f",
@ -307,40 +231,6 @@
],
"version": "==1.4.2"
},
"pyasn1": {
"hashes": [
"sha256:f81c96761fca60d64b1c9b79ec2e40cf9495a745cf570613079ef324aeb9672b",
"sha256:7d626683e3d792cccc608da02498aff37ab4f3dafd8905d6bf755d11f9b26b43",
"sha256:e85895087905c65b5b594eb91f7522664c85545b147d5f4d4e7b1b07da8dcbdc",
"sha256:5a0db897b311d265cde49615cf783f1c78613138605cdd0f907ecfa5b2aba3ee",
"sha256:d5cd6ed995dba16fad0c521cfe31cd2d68400b53fcc2bce93326829be73ab6d1",
"sha256:a7efe807c4b83a859e2735c692b92ed7b567cfddc4163763412920041d876c2b",
"sha256:b5a9ca48055b9a20f6d1b3d68e38692e5431c86a0f99ea602e61294e891fee5b",
"sha256:c07d6e587b2f928366b1f67c09bda026a3e6fcc99e80a744dc67f8fca3895626",
"sha256:d84c2aea3cf43780e9e6a19f4e4dddee9f6976519020e64e47c57e5c7a8c3dd2",
"sha256:758cb50abddc03e4563fd9e7f03db56e3e87b58c0bd01247360326e5c0c7ffa5",
"sha256:0d7f6e959fe53f3960a23d73f35e1fce61348b30915b6664309ca756de7c1f89",
"sha256:d258b0a71994f7770599835249cece1caef3c70def868c4915e6e5ca49b67d15"
],
"version": "==0.4.2"
},
"pyasn1-modules": {
"hashes": [
"sha256:b1f395cae2d669e0830cb023aa86f9f283b7a9aa32317d7f80d8e78aa2745812",
"sha256:854700bbdd01394e2ada9c1bfbd0ed9f5d0c551350dbbd023e88b11d2771ae06",
"sha256:598a6004ec26a8ab40a39ea955068cf2a3949ad9c0030da970f2e1ca4c9f1cc9",
"sha256:f53fe5bcebdf318f51399b250fe8325ef3a26d927f012cc0c8e0f9e9af7f9deb",
"sha256:47fb6757ab78fe966e7c58b2030b546854f78416d653163f0ce9290cf2278e8b",
"sha256:041e9fbafac548d095f5b6c3b328b80792f006196e15a232b731a83c93d59493",
"sha256:0cea139045c38f84abaa803bcb4b5e8775ea12a42af10019d942f227acc426c3",
"sha256:0cdca76a68dcb701fff58c397de0ef9922b472b1cb3ea9695ca19d03f1869787",
"sha256:72fd8b0c11191da088147c6e4678ec53e573923ecf60b57eeac9e97433e09fc2",
"sha256:c6747146e95d2b14cc2a8399b2b0bde3f93778f8f9ec704690d2b589c376c137",
"sha256:0f2e50d20bc670be170966638fa0ae603f0bc9ed6ebe8e97a6d1d4cef30cc889",
"sha256:af00ea8f2022b6287dc375b2c70f31ab5af83989fc6fe9eacd4976ce26cd7ccc"
],
"version": "==0.2.1"
},
"pycparser": {
"hashes": [
"sha256:99a8ca03e29851d96616ad0404b4aad7d9ee16f25c9f9708a11faf2810f7b226"
@ -375,13 +265,6 @@
],
"version": "==1.2.1"
},
"pyopenssl": {
"hashes": [
"sha256:07a2de1a54de07448732a81e38a55df7da109b2f47f599f8bb35b0cbec69d4bd",
"sha256:2c10cfba46a52c0b0950118981d61e72c1e5b1aac451ca1bc77de1a679456773"
],
"version": "==17.5.0"
},
"pysha3": {
"hashes": [
"sha256:6e6a84efb7856f5d760ee55cd2b446972cb7b835676065f6c4f694913ea8f8d9",
@ -410,10 +293,10 @@
},
"pytest": {
"hashes": [
"sha256:95fa025cd6deb5d937e04e368a00552332b58cae23f63b76c8c540ff1733ab6d",
"sha256:6074ea3b9c999bd6d0df5fa9d12dd95ccd23550df2a582f5f5b848331d2e82ca"
"sha256:062027955bccbc04d2fcd5d79690947e018ba31abe4c90b2c6721abec734261b",
"sha256:117bad36c1a787e1a8a659df35de53ba05f9f3398fb9e4ac17e80ad5903eb8c5"
],
"version": "==3.4.0"
"version": "==3.4.2"
},
"pytest-mypy": {
"hashes": [
@ -450,25 +333,28 @@
],
"version": "==2018.3"
},
"pyumbral": {
"git": "https://github.com/nucypher/pyumbral.git"
},
"regex": {
"hashes": [
"sha256:33ddabde9a114e550a9e0b4c3c807b0f6a91a60b40660cadb1161572944911a8",
"sha256:ed1baaa1ebb58fee07f42b6a3b7c65847a8e9e157121bcb54094f4878cb1a28f",
"sha256:b7f892a5390b21748dc68c276879d09095cbabf03f14f2d9c83dc53f026744af",
"sha256:dbd173999c7371f184c9377ead9dcb1462bad5e64fe674098308d72b1ecf3223",
"sha256:cbb48e3bd4e4da3a05a1a6967f8e7bfc2064c7cbf0d1cbec283efd2250865104",
"sha256:a2d1d74296460dc6acc444b99bb142958ec0544a8aec255a5424af4583901d86",
"sha256:2b246e30e7f381dbff535cced74156e29971c1f588af4930d46f51cc8ba68c79",
"sha256:53ce3cab0f41de2171bea75db8f66ee582eb73c1f44c79cdc154eb99d9174680",
"sha256:d57d2e3742098cbe2f9f8567b5b38e3d0a93df88ce94e17672e1b1abd2a5feca",
"sha256:570fae4ae1af7a14029c5795688455009a5851fc8625fe85a2bf7fdc2ff5a2c9",
"sha256:da7ccf77ad5b6c0e72b524d2907f2707062d5619b28d3461a238840e56eea701",
"sha256:b2c3e6d842589a822c6a49fd98809d49ac9e6a06137a2a48b283c5a8928ae132",
"sha256:767b041829e52dafb35823e14cf506f961f42d876a45e7de9dbfeb56b0b7e23d",
"sha256:c37ba8c83a6bfc71ac48885e594ff62fd26e81e5db34cf82456bd73f0607c290",
"sha256:2353c0e983c4029caf32016f1dddef623c3117ac282a818468c6d2f5d541698d"
"sha256:333687d9a44738c486735955993f83bd22061a416c48f5a5f9e765e90cf1b0c9",
"sha256:361a1fd703a35580a4714ec28d85e29780081a4c399a99bbfb2aee695d72aedb",
"sha256:f69d1201a4750f763971ea8364ed95ee888fc128968b39d38883a72a4d005895",
"sha256:a50532f61b23d4ab9d216a6214f359dd05c911c1a1ad20986b6738a782926c1a",
"sha256:1b428a296531ea1642a7da48562746309c5c06471a97bd0c02dd6a82e9cecee8",
"sha256:5b9c0ddd5b4afa08c9074170a2ea9b34ea296e32aeea522faaaaeeeb2fe0af2e",
"sha256:27d72bb42dffb32516c28d218bb054ce128afd3e18464f30837166346758af67",
"sha256:32cf4743debee9ea12d3626ee21eae83052763740e04086304e7a74778bf58c9",
"sha256:35eeccf17af3b017a54d754e160af597036435c58eceae60f1dd1364ae1250c7",
"sha256:be42a601aaaeb7a317f818490a39d153952a97c40c6e9beeb2a1103616405348",
"sha256:eee4d94b1a626490fc8170ffd788883f8c641b576e11ba9b4a29c9f6623371e0",
"sha256:32f6408dbca35040bc65f9f4ae1444d5546411fde989cb71443a182dd643305e",
"sha256:a9243d7b359b72c681a2c32eaa7ace8d346b7e8ce09d172a683acf6853161d9c",
"sha256:494bed6396a20d3aa6376bdf2d3fbb1005b8f4339558d8ac7b53256755f80303",
"sha256:b44624a38d07d3c954c84ad302c29f7930f4bf01443beef5589e9157b14e2a29"
],
"version": "==2018.2.8"
"version": "==2018.2.21"
},
"requests": {
"hashes": [
@ -503,13 +389,6 @@
],
"version": "==0.15.35"
},
"service-identity": {
"hashes": [
"sha256:0e76f3c042cc0f5c7e6da002cf646f59dc4023962d1d1166343ce53bdad39e17",
"sha256:4001fbb3da19e0df22c47a06d29681a398473af4aa9d745eca525b3b2c2302ab"
],
"version": "==17.0.0"
},
"six": {
"hashes": [
"sha256:832dc0e10feb1aa2c68dcc57dbb658f1c7e65b9b61af69048abc87a2db00a0eb",
@ -519,17 +398,9 @@
},
"sqlalchemy": {
"hashes": [
"sha256:64b4720f0a8e033db0154d3824f5bf677cf2797e11d44743cf0aebd2a0499d9d"
"sha256:249000654107a420a40200f1e0b555a79dfd4eff235b2ff60bc77714bd045f2d"
],
"version": "==1.2.2"
},
"twisted": {
"hashes": [
"sha256:7bc3cdfd1ca5e5b84c7936db3c2cb2feb7d5b77410e713fd346da095a3b6a1d2",
"sha256:716805e624f9396fcc1f47e8aef68e629fd31599a74855b6e1636122c042458d",
"sha256:0da1a7e35d5fcae37bc9c7978970b5feb3bc82822155b8654ec63925c05af75c"
],
"version": "==17.9.0"
"version": "==1.2.5"
},
"typed-ast": {
"hashes": [
@ -588,34 +459,6 @@
"sha256:9d81515f2b5b27051910996e1e860b1332e354d9e7bcf30c98f21dcb6713e0dd"
],
"version": "==3.3.1"
},
"zope.interface": {
"hashes": [
"sha256:9902d5fc11309e17cdce6574243dc114b9c30de5c60ab53c90f6e3e962688565",
"sha256:4cb1c56b0356da9a33249ef77a688c47107f54191c12a0055d284b6bee7f447e",
"sha256:ff20038fbc0e7ea050a7e28fcb8ae6ed8378a8d08ac70b848ea39960dda86bbf",
"sha256:f6868378fffbb8651f1f8a767d17e42aed39926c8f6bb9c56f184022fe6c2090",
"sha256:a6375035a4b45d199a8b990e3a2f6b71906c318c56dfc14b2d58350b6ca59392",
"sha256:dec19181cf6af58ccb8ba3fa3ca9d4ec555b2f3cb31f589f6e86d15df0926c31",
"sha256:b8f3491c9df4f0ffed32b275033e74041f420e5dcdefa4b1500d753c64ef42cf",
"sha256:5d8813e438ab67a793b09e1223742b757dd95a4a64d466855a53cb113cc9c9c4",
"sha256:5a8cc535f4212b134e66a3e1c6b93b19d453dbad0e2f89d0df2c01deefc8cad9",
"sha256:bd626cd76b7e5cbecac9d3e0dd8f98e3eada15ead95713238a523f877327633d",
"sha256:16fe824b3d93ee0629aa1f04848a1b515d6b5dc9e98cc7a04feaa35fdb0de5f1",
"sha256:f47d4138405eb67e5f059b9ab74e0a1147adc3277f5fe37d5bae5209b67e89e7",
"sha256:8dfdc1588db31895f81bcba6c36dc981b4cf4a526c62eae3745bbfbe102477ef",
"sha256:88e3d54e88a601f45d03e2a062d5d16852d20e0863a92c19260ae72e2586378a",
"sha256:3d033abd27cd54157cf42a3bfd4d8c28d7fc5c6f775df3332307d2632a79925b",
"sha256:a21d69de2ee89fc59de93e7a43c0379ecedb5149739ff94e910c2bf0ca18e181",
"sha256:aef398a5b92e70b8152d2c4850bad0fe185adb50d948f32d0bba5694d82b67c7",
"sha256:11b068fc9916556f3820f38c2376c28d8e55e4a2c51c34915aaac38b75706d2e",
"sha256:78321a6c0c8cc6ac928e44ef04d50384bc864a7f5e3c25b84110da2ede83739f",
"sha256:4be05f79e952793f31a0c2d6a0672c81a3300315da587ce6a590357595217005",
"sha256:1d954d557b63124a65f2247ac6ed66fa36df18d1e8538d08c9b432e808a634de",
"sha256:a16a3e07511fb6806bb48c8c661d38cdb91cd4bc6c2b6b0b173e72362ec1ceb4",
"sha256:d6d26d5dfbfd60c65152938fcb82f949e8dada37c041f72916fef6621ba5c5ce"
],
"version": "==4.4.3"
}
},
"develop": {
@ -626,14 +469,6 @@
],
"version": "==1.4.3"
},
"appnope": {
"hashes": [
"sha256:5b26757dc6f79a3b7dc9fab95359328d5747fcb2409d331ea66d0272b90ab2a0",
"sha256:8b995ffe925347a2138d7ac0fe77155e4311a0ea6d6da4f5128fe4b3cbe5ed71"
],
"markers": "sys_platform == 'darwin'",
"version": "==0.1.0"
},
"attrs": {
"hashes": [
"sha256:a17a9573a6f475c99b551c0e0a812707ddda1ec9653bed04c13841404ed6f450",
@ -809,10 +644,10 @@
},
"pytest": {
"hashes": [
"sha256:95fa025cd6deb5d937e04e368a00552332b58cae23f63b76c8c540ff1733ab6d",
"sha256:6074ea3b9c999bd6d0df5fa9d12dd95ccd23550df2a582f5f5b848331d2e82ca"
"sha256:062027955bccbc04d2fcd5d79690947e018ba31abe4c90b2c6721abec734261b",
"sha256:117bad36c1a787e1a8a659df35de53ba05f9f3398fb9e4ac17e80ad5903eb8c5"
],
"version": "==3.4.0"
"version": "==3.4.2"
},
"pytest-cov": {
"hashes": [

View File

@ -1,16 +0,0 @@
from kademlia.network import Server
import asyncio
if __name__ == "__main__":
loop = asyncio.get_event_loop()
loop.set_debug(True)
server = Server()
server.listen(8468)
try:
loop.run_forever()
except KeyboardInterrupt:
pass
loop.close()

View File

@ -3,18 +3,35 @@
# It might be (but might not be) useful for determining whether you have
# the proper depedencies and configuration to run an actual mining node.
# WIP w/ hendrix@83519da900a258d8e27a3b1fedee949414d2de26
# WIP w/ hendrix@tags/3.3.0rc1
import os
from cryptography.hazmat.primitives.asymmetric import ec
from hendrix.deploy.ssl import HendrixDeployTLS
from hendrix.facilities.services import ExistingKeyTLSContextFactory
from nkms.characters import Ursula
from OpenSSL.crypto import X509
from OpenSSL.SSL import TLSv1_2_METHOD
from nkms.crypto.api import generate_self_signed_certificate
DB_NAME = "non-mining-proxy-node"
_URSULA = Ursula(dht_port=3501, dht_interface="localhost", db_name=DB_NAME)
_URSULA.listen()
from hendrix.deploy.base import HendrixDeploy
CURVE = ec.SECP256R1
cert, private_key = generate_self_signed_certificate(_URSULA.stamp.fingerprint().decode(), CURVE)
deployer = HendrixDeploy("start", {"wsgi":_URSULA.rest_app, "http_port": 3500})
deployer = HendrixDeployTLS("start",
{"wsgi":_URSULA.rest_app, "https_port": 3550},
key=private_key,
cert=X509.from_cryptography(cert),
context_factory=ExistingKeyTLSContextFactory,
context_factory_kwargs={"curve_name": "prime256v1",
"sslmethod": TLSv1_2_METHOD})
try:
deployer.run()

View File

@ -16,25 +16,25 @@ from umbral import pre
ALICE = Alice()
BOB = Bob()
URSULA = Ursula.from_rest_url(address="http://localhost", port="3500")
URSULA = Ursula.from_rest_url(address="https://localhost", port="3550")
class SandboxNetworkyStuff(NetworkyStuff):
def find_ursula(self, contract=None):
ursula = Ursula.as_discovered_on_network(dht_port=None, dht_interface=None,
rest_address="localhost", rest_port=3500,
rest_address="https://localhost", rest_port=3550,
powers_and_keys={
SigningPower: URSULA.stamp.as_umbral_pubkey(),
EncryptingPower: URSULA.public_key(EncryptingPower)
}
)
response = requests.post("http://localhost:3500/consider_contract", bytes(contract))
response = requests.post("https://localhost:3550/consider_contract", bytes(contract), verify=False)
response.was_accepted = True
return ursula, response
def enact_policy(self, ursula, hrac, payload):
response = requests.post('http://{}:{}/kFrag/{}'.format(ursula.rest_address, ursula.rest_port, hrac.hex()),
payload)
response = requests.post('{}:{}/kFrag/{}'.format(ursula.rest_address, ursula.rest_port, hrac.hex()),
payload, verify=False)
# TODO: Something useful here and it's probably ready to go down into NetworkyStuff.
return response.status_code == 200
@ -46,7 +46,7 @@ n = 1
uri = b"secret/files/and/stuff"
# Alice gets on the network and discovers Ursula, presumably from the blockchain.
ALICE.learn_about_nodes(address="http://localhost", port="3500")
ALICE.learn_about_nodes(address="https://localhost", port="3550")
# Alice grants to Bob.
@ -56,7 +56,7 @@ policy.publish_treasure_map(networky_stuff, use_dht=False)
hrac, treasure_map = policy.hrac(), policy.treasure_map
# Bob learns about Ursula, gets the TreasureMap, and follows it.
BOB.learn_about_nodes(address="http://localhost", port="3500")
BOB.learn_about_nodes(address="https://localhost", port="3550")
networky_stuff = NetworkyStuff()
BOB.get_treasure_map(policy, networky_stuff)
BOB.follow_treasure_map(hrac)

View File

@ -1 +0,0 @@
#from nkms.client import Client

View File

@ -3,22 +3,20 @@ from logging import getLogger
import msgpack
import requests
from typing import Dict
from collections import OrderedDict
from kademlia.network import Server
from kademlia.utils import digest
from typing import Dict
from typing import Union, List
from collections import OrderedDict
from nkms.crypto.api import secure_random, keccak_digest
from nkms.crypto.constants import NOT_SIGNED, NO_DECRYPTION_PERFORMED
from nkms.crypto.constants import NOT_SIGNED, NO_DECRYPTION_PERFORMED, PUBLIC_KEY_LENGTH
from nkms.crypto.kits import MessageKit
from nkms.crypto.powers import CryptoPower, SigningPower, EncryptingPower
from nkms.crypto.signature import Signature
from nkms.crypto.utils import BytestringSplitter
from nkms.crypto.utils import BytestringSplitter, RepeatingBytestringSplitter
from nkms.network import blockchain_client
from nkms.network.constants import BYTESTRING_IS_URSULA_IFACE_INFO, BYTESTRING_IS_TREASURE_MAP
from nkms.network.constants import BYTESTRING_IS_URSULA_IFACE_INFO
from nkms.network.protocols import dht_value_splitter
from nkms.network.server import NuCypherDHTServer, NuCypherSeedOnlyDHTServer, ProxyRESTServer
from nkms.policy.constants import NOT_FROM_ALICE, NON_PAYMENT
@ -115,7 +113,6 @@ class Character(object):
except TypeError:
umbral_key = public_key
crypto_power.consume_power_up(power_up(pubkey=umbral_key))
return cls(is_me=False, crypto_power=crypto_power, *args, **kwargs)
@ -205,12 +202,12 @@ class Character(object):
:return: Whether or not the signature is valid, the decrypted plaintext
or NO_DECRYPTION_PERFORMED
"""
# TODO: In this flow we now essentially have two copies of the public key.
# TODO: In this flow we now essentially have two copies of the public key. See #174.
# One from the actor (first arg) and one from the MessageKit.
# Which do we use in which cases?
# if not signature and not signature_is_on_cleartext:
# TODO: Since a signature can now be in a MessageKit, this might not be accurate anymore.
# TODO: Since a signature can now be in a MessageKit, this might not be accurate anymore. See #174.
# raise ValueError("You need to either provide the Signature or \
# decrypt and find it on the cleartext.")
@ -233,7 +230,6 @@ class Character(object):
if decrypt:
message = message_kit.ciphertext
cleartext = self.decrypt(message_kit)
# TODO: Fully deprecate actor lookup flow?
else:
message = bytes(message_kit)
alice_pubkey = actor_whom_sender_claims_to_be.public_key(SigningPower)
@ -247,8 +243,8 @@ class Character(object):
return is_valid, cleartext
"""
Next we have decrypt() and sign() - these two functions use the private keys of their respective powers;
any character who has these powers can use these functions.
Next we have decrypt(), sign(), and generate_self_signed_certificate() - these use the private
keys of their respective powers; any character who has these powers can use these functions.
If they don't have the correct Power, the appropriate PowerUpError is raised.
"""
@ -259,7 +255,22 @@ class Character(object):
def sign(self, message):
return self._crypto_power.power_ups(SigningPower).sign(message)
def generate_self_signed_certificate(self):
signing_power = self._crypto_power.power_ups(SigningPower)
return signing_power.generate_self_signed_cert(self.stamp.fingerprint().decode())
"""
And finally, some miscellaneous but generally-applicable abilities:
"""
def public_key(self, power_up_class):
"""
Pass a power_up_class, get the public key for this Character which corresponds to that
class.
If the Character doesn't have the power corresponding to that class, raises the
appropriate PowerUpError (ie, NoSigningPower or NoEncryptingPower).
"""
power_up = self._crypto_power.power_ups(power_up_class)
return power_up.public_key()
@ -267,7 +278,7 @@ class Character(object):
"""
Sends a request to node_url to find out about known nodes.
"""
# TODO: Find out about other known nodes, not just this one.
# TODO: Find out about other known nodes, not just this one. #175
node = Ursula.from_rest_url(address, port)
self.known_nodes[node.interface_dht_key()] = node
@ -283,8 +294,8 @@ class Alice(Character):
These KFrags can be used by Ursula to re-encrypt a Capsule for Bob so
that he can activate the Capsule.
:param bob: Bob instance which will be able to decrypt messages re-encrypted with these kfrags.
:param m: Minimum number of KFrags needed to rebuild ciphertext
:param n: Total number of rekey shares to generate
:param m: Minimum number of kfrags needed to activate a Capsule.
:param n: Total number of kfrags to generate
"""
bob_pubkey_enc = bob.public_key(EncryptingPower)
return self._crypto_power.power_ups(EncryptingPower).generate_kfrags(bob_pubkey_enc, m, n)
@ -300,7 +311,6 @@ class Alice(Character):
Generates KFrags and attaches them.
"""
kfrags = self.generate_kfrags(bob, m, n)
# TODO: Access Alice's private key inside this method.
from nkms.policy.models import Policy
policy = Policy.from_alice(
alice=self,
@ -315,16 +325,16 @@ class Alice(Character):
def grant(self, bob, uri, networky_stuff,
m=None, n=None, expiration=None, deposit=None):
if not m:
# TODO: get m from config
# TODO: get m from config #176
raise NotImplementedError
if not n:
# TODO: get n from config
# TODO: get n from config #176
raise NotImplementedError
if not expiration:
# TODO: check default duration in config
# TODO: check default duration in config #176
raise NotImplementedError
if not deposit:
default_deposit = None # TODO: Check default deposit in config.
default_deposit = None # TODO: Check default deposit in config. #176
if not default_deposit:
deposit = networky_stuff.get_competitive_rate()
if deposit == NotImplemented:
@ -342,32 +352,20 @@ class Alice(Character):
# REST call happens here, as does population of TreasureMap.
policy.enact(networky_stuff)
return policy
return policy # Now with TreasureMap affixed!
class Bob(Character):
_server_class = NuCypherSeedOnlyDHTServer
_default_crypto_powerups = [SigningPower, EncryptingPower]
def __init__(self, alice=None, *args, **kwargs):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.treasure_maps = {}
if alice:
self.alice = alice
from nkms.policy.models import WorkOrderHistory # Need a bigger strategy to avoid circulars.
self._saved_work_orders = WorkOrderHistory()
@property
def alice(self):
if not self._alice:
raise Alice.NotFound
else:
return self._alice
@alice.setter
def alice(self, alice_object):
self._alice = alice_object
def follow_treasure_map(self, hrac):
for ursula_interface_id in self.treasure_maps[hrac]:
if ursula_interface_id in self.known_nodes:
@ -379,21 +377,21 @@ class Bob(Character):
value = self.server.get_now(ursula_interface_id)
# TODO: Make this much prettier
header, signature, ursula_pubkey_sig, _hrac, (port, interface, ttl) = dht_value_splitter(value, msgpack_remainder=True)
header, signature, ursula_pubkey_sig, _hrac, (
port, interface, ttl) = dht_value_splitter(value, msgpack_remainder=True)
if header != BYTESTRING_IS_URSULA_IFACE_INFO:
raise TypeError("Unknown DHT value. How did this get on the network?")
# TODO: If we're going to implement TTL, it will be here.
self.known_nodes[ursula_interface_id] =\
Ursula.as_discovered_on_network(
dht_port=port,
dht_interface=interface,
powers_and_keys=({SigningPower: ursula_pubkey_sig})
)
self.known_nodes[ursula_interface_id] = \
Ursula.as_discovered_on_network(
dht_port=port,
dht_interface=interface,
powers_and_keys=({SigningPower: ursula_pubkey_sig})
)
def get_treasure_map(self, policy, networky_stuff, using_dht=False):
map_id = policy.treasure_map_dht_key()
if using_dht:
@ -407,7 +405,7 @@ class Bob(Character):
tmap_message_kit = self.get_treasure_map_from_known_ursulas(networky_stuff, map_id)
verified, packed_node_list = self.verify_from(
self.alice, tmap_message_kit,
policy.alice, tmap_message_kit,
signature_is_on_cleartext=True, decrypt=True
)
@ -513,10 +511,11 @@ class Ursula(Character, ProxyRESTServer):
return self._rest_app
@classmethod
def as_discovered_on_network(cls, dht_port, dht_interface, pubkey_sig_bytes,
rest_address=None, rest_port=None):
def as_discovered_on_network(cls, dht_port, dht_interface,
rest_address=None, rest_port=None,
powers_and_keys=()):
# TODO: We also need the encrypting public key here.
ursula = cls.from_public_keys((SigningPower, pubkey_sig_bytes))
ursula = cls.from_public_keys(powers_and_keys)
ursula.dht_port = dht_port
ursula.dht_interface = dht_interface
ursula.rest_address = rest_address
@ -525,14 +524,20 @@ class Ursula(Character, ProxyRESTServer):
@classmethod
def from_rest_url(cls, address, port):
response = requests.get("{}:{}/public_keys".format(address, port)) # TODO: TLS-only.
response = requests.get("{}:{}/public_keys".format(address, port), verify=False) # TODO: TLS-only.
if not response.status_code == 200:
raise RuntimeError("Got a bad response: {}".format(response))
signing_key_bytes, encrypting_key_bytes = \
BytestringSplitter(PublicKey)(response.content,
return_remainder=True)
key_splitter = RepeatingBytestringSplitter(
(UmbralPublicKey, PUBLIC_KEY_LENGTH, {"as_b64": False}))
signing_key, encrypting_key = key_splitter(response.content)
stranger_ursula_from_public_keys = cls.from_public_keys(
signing=signing_key_bytes, encrypting=encrypting_key_bytes)
{SigningPower: signing_key, EncryptingPower: encrypting_key},
rest_address=address,
rest_port=port
)
return stranger_ursula_from_public_keys
def attach_server(self, ksize=20, alpha=3, id=None,
@ -638,5 +643,5 @@ class StrangerStamp(SignatureStamp):
"""
def __call__(self, *args, **kwargs):
raise TypeError(
"This isn't your SignatureStamp; it belongs to {} (a Stranger). You can't sign with it.".format(self.character))
message = "This isn't your SignatureStamp; it belongs to {} (a Stranger). You can't sign with it."
raise TypeError(message.format(self.character))

View File

@ -7,6 +7,12 @@ from cryptography.hazmat.primitives.asymmetric import ec
from nkms.crypto.constants import BLAKE2B
from umbral.keys import UmbralPrivateKey, UmbralPublicKey
from cryptography import x509
from cryptography.x509.oid import NameOID
from cryptography.hazmat.backends import default_backend
from cryptography.hazmat.primitives import hashes
import datetime
SYSTEM_RAND = SystemRandom()
@ -97,3 +103,26 @@ def ecdsa_verify(
except InvalidSignature:
return False
return True
def generate_self_signed_certificate(common_name, curve, private_key=None, days_valid=365):
if not private_key:
private_key = ec.generate_private_key(curve, default_backend())
public_key = private_key.public_key()
now = datetime.datetime.utcnow()
subject = issuer = x509.Name([
x509.NameAttribute(NameOID.COMMON_NAME, common_name),
])
cert = x509.CertificateBuilder().subject_name(subject)
cert = cert.issuer_name(issuer)
cert = cert.public_key(public_key)
cert = cert.serial_number(x509.random_serial_number())
cert = cert.not_valid_before(now)
cert = cert.not_valid_after(now + datetime.timedelta(days=days_valid))
# TODO: What domain here? Not localhost presumably - ENS? #146
cert = cert.add_extension(x509.SubjectAlternativeName([x509.DNSName(u"localhost")]), critical=False)
cert = cert.sign(private_key, hashes.SHA512(), default_backend())
return cert, private_key

View File

@ -104,7 +104,7 @@ class SigningPower(KeyPairBasedPower):
confers_public_key = True
_keypair_class = SigningKeypair
not_found_error = NoSigningPower
provides = ("sign",)
provides = ("sign", "generate_self_signed_cert")
class EncryptingPower(KeyPairBasedPower):

View File

@ -1,10 +1,11 @@
import sha3
from typing import Union
from nkms.crypto import api as API
from nkms.crypto.api import generate_self_signed_certificate
from umbral.keys import UmbralPrivateKey, UmbralPublicKey
from umbral import pre
from umbral.config import default_curve
from nkms.crypto.kits import MessageKit
from nkms.crypto.signature import Signature
from typing import List
@ -88,7 +89,7 @@ class EncryptingKeypair(Keypair):
:param n: Total number of rekey shares to generate
"""
alice_priv_enc = self._privkey
kfrags, _v_keys = pre.split_rekey(alice_priv_enc, bob_pubkey_enc, m, n)
kfrags = pre.split_rekey(alice_priv_enc, bob_pubkey_enc, m, n)
return kfrags
@ -109,3 +110,8 @@ class SigningKeypair(Keypair):
"""
signature_der_bytes = API.ecdsa_sign(message, self._privkey)
return Signature.from_bytes(signature_der_bytes, der_encoded=True)
def generate_self_signed_cert(self, common_name):
# TODO: Let's have a shortcut method for getting the cryptography key(s).
cryptography_key = self._privkey.bn_key.to_cryptography_priv_key()
return generate_self_signed_certificate(common_name, default_curve(), cryptography_key)

View File

@ -1,38 +0,0 @@
from twisted.python.filepath import FilePath
from twisted.internet.endpoints import SSL4ClientEndpoint
from twisted.internet.ssl import (
PrivateCertificate, Certificate, optionsForClientTLS)
from twisted.internet.defer import Deferred, inlineCallbacks
from twisted.internet.task import react
from twisted.internet.protocol import Protocol, Factory
from nkms.network import generate_certs
class SendAnyData(Protocol):
def connectionMade(self):
self.deferred = Deferred()
self.transport.write(b"HELLO\r\n")
def connectionLost(self, reason):
self.deferred.callback(None)
@inlineCallbacks
def main(reactor):
pem = generate_certs.and_generate()
caPem = FilePath(b"ca-private-cert.pem").getContent()
clientEndpoint = SSL4ClientEndpoint(
reactor, u"localhost", 4321,
optionsForClientTLS(u"the-authority", Certificate.loadPEM(caPem),
PrivateCertificate.loadPEM(pem)),
)
clientEndpoint = SSL4ClientEndpoint(
reactor, u"localhost", 4321,
optionsForClientTLS(u"the-authority", Certificate.loadPEM(caPem),
PrivateCertificate.loadPEM(pem)),
)
proto = yield clientEndpoint.connect(Factory.forProtocol(SendAnyData))
yield proto.deferred
what_happened = react(main)
print(what_happened)

View File

@ -1,24 +0,0 @@
from twisted.python.filepath import FilePath
from twisted.internet.endpoints import SSL4ServerEndpoint
from twisted.internet.ssl import PrivateCertificate, Certificate
from twisted.internet.defer import Deferred
from twisted.internet.task import react
from twisted.internet.protocol import Protocol, Factory
class ReportWhichClient(Protocol):
def dataReceived(self, data):
peerCertificate = Certificate.peerFromTransport(self.transport)
print(peerCertificate.getSubject().commonName.decode('utf-8'))
self.transport.loseConnection()
def main(reactor):
pemBytes = FilePath(b"ca-private-cert.pem").getContent()
certificateAuthority = Certificate.loadPEM(pemBytes)
myCertificate = PrivateCertificate.loadPEM(pemBytes)
serverEndpoint = SSL4ServerEndpoint(
reactor, 4321, myCertificate.options(certificateAuthority)
)
serverEndpoint.listen(Factory.forProtocol(ReportWhichClient))
return Deferred()
react(main, [])

View File

@ -47,15 +47,17 @@ class NetworkyStuff(object):
return NotImplemented
def get_treasure_map_from_node(self, node, map_id):
response = requests.get("{}/treasure_map/{}".format(node.rest_url(), map_id.hex()))
response = requests.get("{}/treasure_map/{}".format(node.rest_url(), map_id.hex()), verify=False)
return response
def push_treasure_map_to_node(self, node, map_id, map_payload):
response = requests.post("{}/treasure_map/{}".format(node.rest_url(), map_id.hex()),
data=map_payload)
data=map_payload, verify=False)
return response
def send_work_order_payload_to_ursula(self, work_order):
payload = work_order.payload()
hrac_as_hex = work_order.kfrag_hrac.hex()
return requests.post('{}/kFrag/{}/reencrypt'.format(work_order.ursula.rest_url(), hrac_as_hex), payload)
return requests.post('{}/kFrag/{}/reencrypt'.format(work_order.ursula.rest_url(), hrac_as_hex),
payload, verify=False)

View File

@ -222,7 +222,6 @@ class Policy(object):
def find_ursulas(self, networky_stuff, deposit, expiration,
num_ursulas=None):
# TODO: This is a number mismatch - we need not one contract, but n contracts.
"""
:param networky_stuff: A compliant interface (maybe a Client instance) to be used to engage the DHT swarm.
"""
@ -325,9 +324,9 @@ class WorkOrder(object):
return bytes(self.receipt_signature) + self.bob.stamp + packed_receipt_and_capsules
def complete(self, cfrags):
# TODO: Verify that this is in fact complete - right of CFrags and properly signed.
# TODO: Verify that this is in fact complete - right number of CFrags and properly signed.
# TODO: Mark it complete with datetime.
self
pass
class WorkOrderHistory:

View File

@ -1,2 +0,0 @@
from .encrypted_file import EncryptedFile
from .header import Header

View File

@ -1,8 +0,0 @@
# Number of random bytes to prefix before the counter
NONCE_RANDOM_PREFIX_SIZE = 20
# Size of the counter in bytes (4 = int)
NONCE_COUNTER_BYTE_SIZE = 4
# Length of padding from NaCl
PADDING_LENGTH = 16

View File

@ -1,112 +0,0 @@
import io
import os
from nkms.storage.header import Header
from nkms.storage.constants import NONCE_COUNTER_BYTE_SIZE, PADDING_LENGTH
# from nkms.crypto import default_algorithm, symmetric_from_algorithm
class EncryptedFile(object):
def __init__(self, key, path, header_path):
"""
Creates an EncryptedFile object that allows the user to encrypt or
decrypt data into a file defined at `path`.
An EncryptedFile object actually is composed of two files:
1) The ciphertext -- This is the chunked and encrypted ciphertext
2) The header -- This contains the metadata of the ciphertext that
tells us how to decrypt it, or add more data.
:param bytes key: Symmetric key to use for encryption/decryption
:param bytes path: Path of ciphertext file to open
:param bytes header_path: Path of header file
"""
cipher = symmetric_from_algorithm(default_algorithm)
self.cipher = cipher(key)
# Opens the header file and parses it, if it exists. If not, creates it
self.header_path = header_path
self.header_obj = Header(self.header_path)
self.path = path
# Always seek the beginning of the file on first open
self.file_obj = open(self.path, mode='a+b')
self.file_obj.seek(0)
@property
def header(self):
return self.header_obj.header
def _read_chunk(self, chunk_size, nonce):
"""
Reads a chunk and decrypts/authenticates it.
:param int chunk_size: Size of chunk to read from self.file_obj
:param bytes nonce: Nonce to use during decryption
:return: Decrypted/Authenticated chunk
:rtype: Bytes
"""
ciphertext = self.file_obj.read(chunk_size + PADDING_LENGTH)
return self.cipher.decrypt(ciphertext, nonce=nonce)
def read(self, num_chunks=0):
"""
Reads num_chunks of encrypted ciphertext and decrypt/authenticate it.
:param int num_chunks: Number of chunks to read. When set to 0, it will
read the all the chunks and decrypt them.
:return: List of decrypted/authenticated ciphertext chunks
:rtype: List
"""
if not num_chunks:
num_chunks = self.header[b'num_chunks']
chunks = []
for chunk_num in range(num_chunks):
nonce = (self.header[b'nonce']
+ chunk_num.to_bytes(NONCE_COUNTER_BYTE_SIZE,
byteorder='big'))
chunks.append(self._read_chunk(self.header[b'chunk_size'], nonce))
return chunks
def write(self, data):
"""
Writes encrypted data to self.file_obj.
:param bytes data: Data to encrypt and write
:param int chunk_num: Chunk number to start writing at
:return: Number of chunks written
:rtype: int
"""
# Always start writing at the end of the file, never overwrite.
self.file_obj.seek(0, os.SEEK_END)
# Start off at the last chunk_num
chunk_num = self.header[b'num_chunks']
buf_data = io.BytesIO(data)
chunks_written = 0
plaintext = buf_data.read(self.header[b'chunk_size'])
while len(plaintext) > 0:
nonce = (self.header[b'nonce']
+ chunk_num.to_bytes(NONCE_COUNTER_BYTE_SIZE,
byteorder='big'))
enc_data = self.cipher.encrypt(plaintext, nonce=nonce)
self.file_obj.write(enc_data.ciphertext)
chunks_written += 1
plaintext = buf_data.read(self.header[b'chunk_size'])
chunk_num += 1
self.header_obj.update_header({b'num_chunks': chunk_num})
return chunks_written
def close(self):
"""
Writes the header to the filesystem and closes the file_obj.
"""
self.header_obj.update_header()
self.file_obj.close()

View File

@ -1,89 +0,0 @@
import msgpack
import pathlib
from nacl.utils import random
from nkms.storage.constants import NONCE_RANDOM_PREFIX_SIZE
class Header(object):
def __init__(self, header_path, header={}):
"""
Initializes a header object that contains metadata about a storage
object (ie: EncryptedFile)
:param bytes header_path: Path to the file containing the header
:param dict header: Header params to use when building the header
"""
self.path = header_path
header_file = pathlib.Path(self.path.decode())
if header_file.is_file():
self.header = self._read_header(self.path)
else:
self.header = self._build_header(**header)
self._write_header(self.path)
def _read_header(self, header_path):
"""
Reads the header file located at `header_path` and loads it from its
msgpack format into the self.header dict.
:param bytes/string header_path: The path to the header file
:return: The loaded dict from the header file
:rtype: Dict
"""
with open(header_path, mode='rb') as f:
# TODO: Use custom Exception (invalid or corrupt header)
try:
header = msgpack.loads(f.read())
except ValueError as e:
raise e
return header
def _build_header(self, version=100, nonce=None, keys=[],
chunk_size=1000000, num_chunks=0):
"""
Builds a header and sets the header dict in the `Header` object.
:param int version: Version of the NuCypher header
:param bytes nonce: Nonce to write to header, default is random(20)
:param list keys: Keys to write to header
:param int chunk_size: Size of each chunk in bytes, default is 1MB
:param int num_chunks: Number of chunks in ciphertext
:return: dict of header
:rtype: Dict
"""
if not nonce:
nonce = random(NONCE_RANDOM_PREFIX_SIZE)
return {
b'version': version,
b'nonce': nonce,
b'keys': keys,
b'chunk_size': chunk_size,
b'num_chunks': num_chunks,
}
def _write_header(self, header_path):
"""
Writes the msgpack dumped self.header dict to the file located at
`header_path`.
:param string/bytes header_path: The path to write the msgpack dumped
header to
"""
with open(header_path, mode='wb') as f:
try:
f.write(msgpack.dumps(self.header))
except ValueError as e:
raise e
def update_header(self, header={}):
"""
Updates the self.header dict with the dict in header and writes it to
the header file.
:param dict header: Values to use in the dict.update call
"""
self.header.update(header)
self._write_header(self.path)

View File

@ -5,7 +5,6 @@ INSTALL_REQUIRES = [
'rpcudp>=3.0',
'lmdb',
'pynacl',
'npre',
'pysha3==1.0.2',
'bidict',
]
@ -23,7 +22,7 @@ TESTS_REQUIRE = [
LINKS = [
'https://github.com/nucypher/kademlia/archive/kms-dependency.tar.gz#egg=kademlia-1.0',
'https://github.com/bmuller/rpcudp/archive/python3.5.tar.gz#egg=rpcudp-3.0.0',
'https://github.com/nucypher/nucypher-pre-python@kms-dependency#egg=npre']
]
setup(name='nkms',
version='0.1',

View File

@ -0,0 +1,9 @@
from nkms.characters import Ursula
from nkms.crypto.powers import SigningPower
def test_ursula_generates_self_signed_cert():
ursula = Ursula(attach_server=False)
cert, cert_private_key = ursula.generate_self_signed_certificate()
public_key_numbers = ursula.public_key(SigningPower).point_key.to_cryptography_pub_key().public_numbers()
assert cert.public_key().public_numbers() == public_key_numbers

View File

@ -58,7 +58,7 @@ def alice(ursulas):
@pytest.fixture(scope="module")
def bob(alice, ursulas):
BOB = Bob(alice=alice)
BOB = Bob()
BOB.server.listen(8475)
EVENT_LOOP.run_until_complete(BOB.server.bootstrap([("127.0.0.1", URSULA_PORT)]))
return BOB

View File

@ -2,8 +2,6 @@ import pytest
from datetime import datetime
from nkms.keystore import keystore, keypairs
from nkms.crypto import api as API
from umbral.keys import UmbralPrivateKey
def test_key_sqlite_keystore(test_keystore, bob):

View File

@ -1,8 +0,0 @@
import unittest
from nkms.storage import constants
class TestConstants(unittest.TestCase):
def test_constants(self):
self.assertEqual(4, constants.NONCE_COUNTER_BYTE_SIZE)
self.assertEqual(20, constants.NONCE_RANDOM_PREFIX_SIZE)

View File

@ -1,72 +0,0 @@
import unittest
import pathlib
import msgpack
import os
from nkms.storage import Header
class TestHeader(unittest.TestCase):
@classmethod
def setUpClass(cls):
cls.header = Header(b'test_header.nuc.header')
@classmethod
def tearDownClass(cls):
os.remove(b'test_header.nuc.header')
def setUp(self):
self.header_obj = TestHeader.header
self.header = TestHeader.header.header
def step1_test_header_defaults(self):
# Test dict values
self.assertEqual(100, self.header[b'version'])
self.assertEqual(20, len(self.header[b'nonce']))
self.assertEqual(list, type(self.header[b'keys']))
self.assertEqual(0, len(self.header[b'keys']))
self.assertEqual(1000000, self.header[b'chunk_size'])
self.assertEqual(0, self.header[b'num_chunks'])
# Test path
self.assertEqual(b'test_header.nuc.header', self.header_obj.path)
# Test that the header exists on the filesystem
self.assertTrue(pathlib.Path(self.header_obj.path.decode()).is_file())
def step2_test_header_update(self):
new_header = {
b'version': 200,
b'keys': [b'test'],
b'chunk_size': 999,
}
self.header_obj.update_header(header=new_header)
self.assertEqual(200, self.header[b'version'])
self.assertEqual(1, len(self.header[b'keys']))
self.assertEqual(b'test', self.header[b'keys'][0])
self.assertEqual(999, self.header[b'chunk_size'])
# Check that the non-updated num_chunks value didn't change
self.assertEqual(0, self.header[b'num_chunks'])
def step3_test_header_read(self):
header = Header(b'test_header.nuc.header').header
self.assertEqual(200, header[b'version'])
self.assertEqual(1, len(header[b'keys']))
self.assertEqual(b'test', header[b'keys'][0])
self.assertEqual(999, header[b'chunk_size'])
self.assertEqual(0, header[b'num_chunks'])
def _steps(self):
for attr in sorted(dir(self)):
if not attr.startswith('step'):
continue
yield attr
def test_header(self):
for _s in self._steps():
try:
getattr(self, _s)()
except Exception as e:
self.fail('{} failed({})'.format(_s, e))

View File

@ -1,13 +1,11 @@
import asyncio
import pytest
from sqlalchemy.engine import create_engine
import requests
from apistar.test import TestClient
from nkms.characters import Ursula
from nkms.crypto.utils import RepeatingBytestringSplitter
from nkms.keystore import keystore
from nkms.keystore.db import Base
from nkms.network.node import NetworkyStuff
from nkms.policy.models import ContractResponse