Merge pull request #2146 from RustPython/coolreader18/test_ftplib

Add ftplib + test_ftplib
This commit is contained in:
Jeong YunWon
2021-01-13 08:05:15 +09:00
committed by GitHub
13 changed files with 1856 additions and 83 deletions

View File

@@ -68,7 +68,5 @@ opt-level = 3
[patch.crates-io]
# REDOX START, Uncommment when you want to compile/check with redoxer
# # following patches are just waiting on a new version to be released to crates.io
# socket2 = { git = "https://github.com/alexcrichton/socket2-rs", branch = "v0.3.x" }
# REDOX END

View File

@@ -0,0 +1,50 @@
-----BEGIN RSA PRIVATE KEY-----
Proc-Type: 4,ENCRYPTED
DEK-Info: DES-EDE3-CBC,E74528136B90D2DD
WRHVD2PJXPqjFSHg92HURIsUzvsTE4a9oi0SC5yMBFKNWA5Z933gK3XTifp6jul5
zpNYi8jBXZ2EqJJBxCuVcefmXSxL0q7CMej25TdIC4BVAFJVveeprHPUFkNB0IM1
go5Lg4YofYqTCg3OE3k7WvfR3Zg1cRYxksDKO+WNZgWyKBex5X4vjOiyUqDl3GKt
kQXnkg1VgPV2Vrx93S9XNdELNRTguwf+XG0fkhtYhp/zCto8uKTgy5elK2P/ulGp
7fe6uj7h/uN9L7EOC6CjRkitywfeBUER739mOcGT4imSFJ9G27TCqPzj2ea3uuaf
/v1xhkQ4M6lNY/gcRfgVpCXhW43aAQV8XXQRMJTqLmz5Y5hYTKn+Ugq5vJ/ngyRM
lu1gUJnYYaemBTb4hbm6aBvnYK9mORa891Pmf+vxU9rYuQIdVAhvvXh4KBreSEBI
1AFy6dFKXl8ZKs6Wrq5wPefmFFkRmZ8OBiiq0fp2ApCRGZw6LsjCgwrRM38JiY7d
3OdsJpKvRYufgUyuuzUE0xA+E4yMvD48M9pPq2fC8O5giuGL1uEekQWXJuq+6ZRI
XYKIeSkuQALbX3RAzCPXTUEMtCYXKm/gxrrwJ+Bet4ob2amf3MX0uvWwOuAq++Fk
J0HFSBxrwvIWOhyQXOPuJdAN8PXA7dWOXfOgOMF0hQYqZCl3T4TiVZJbwVQtg1sN
dO7oAD5ZPHiKzvveZuB6k1FlBG8j0TyAC+44ChxkPDD3jF4dd6zGe62sDf85p4/d
W80gxJeD3xnDxG0ePPns+GuKUpUaWS7WvHtDpeFW1JEhvOqf8p1Li9a7RzWVo8ML
mGTdQgBIYIf6/fk69pFKl0nKtBU75KaunZz4nAmd9bNED4naDurMBg44u5TvODbJ
vgYIYXIYjNvONbskJatVrrTS8zch2NwVIjCi8L/hecwBXbIXzo1pECpc6BU7sQT8
+i9sDKBeJcRipzfKZNHvnO19mUZaPCY8+a/f9c21DgKXz+bgLcJbohpSaeGM8Gfc
aZd3Vp9n3OJ3g2zQR1++HO9v1vR/wLELu6MeydkvMduHLmOPCn54gZ9z51ZNPAwa
qfFIsH+mLh9ks0H74ssF59uIlstkgB9zmZHv/Q0dK9ZfG/VEH6rSgdETWhZxhoMQ
Z92jXBEFT0zhI3rrIPNY+XS7eJCQIc1wc84Ea3cRk7SP+S1og3JtAxX56ykUwtkM
LQ/Dwwa6h1aqD0l2d5x1/BSdavtTuSegISRWQ4iOmSvEdlFP7H4g6RZk/okbLzMD
Evq5gNc7vlXhVawoQU8JCanJ5ZbbWnIRZfiXxBQS4lpYPKvJt4ML9z/x+82XxcXv
Z93N2Wep7wWW5OwS2LcQcOgZRDSIPompwo/0pMFGOS+5oort0ZDRHdmmGLjvBcCb
1KQmKQ4+8brI/3rjRzts6uDLjTGNxSCieNsnqhwHUv9Mg9WDSWupcGa+x27L89x3
rObf6+3umcFLSjIzU8wuv1hx/e/y98Kv7BDBNYpAr6kVMrLnzYjAfJbBmqlxkzkQ
IgQzgrk2QZoTdgwR+S374NAMO0AE5IlO+/qa6qp2SORGTDX64I3UNw==
-----END RSA PRIVATE KEY-----
-----BEGIN CERTIFICATE-----
MIIDWTCCAkGgAwIBAgIJAPm6B21bar2bMA0GCSqGSIb3DQEBCwUAMF8xCzAJBgNV
BAYTAlhZMRcwFQYDVQQHDA5DYXN0bGUgQW50aHJheDEjMCEGA1UECgwaUHl0aG9u
IFNvZnR3YXJlIEZvdW5kYXRpb24xEjAQBgNVBAMMCWxvY2FsaG9zdDAeFw0xODAx
MTkxOTA5MDZaFw0yODAxMTcxOTA5MDZaMF8xCzAJBgNVBAYTAlhZMRcwFQYDVQQH
DA5DYXN0bGUgQW50aHJheDEjMCEGA1UECgwaUHl0aG9uIFNvZnR3YXJlIEZvdW5k
YXRpb24xEjAQBgNVBAMMCWxvY2FsaG9zdDCCASIwDQYJKoZIhvcNAQEBBQADggEP
ADCCAQoCggEBAKvvsX2gEti4shve3iYMc+jE4Se7WHs1Bol2f21H8qNboDOFdeb1
RKHjmq3exHpajywOUEgne9nKHJY/3f2phR4Y5klqG6liLgiSpVyRlcBGbeT2qEAj
9oLiLFUXLGfGDds2mTwivQDLJBWi51j7ff5k2Pr58fN5ugYMn24T9FNyn0moT+qj
SFoBNm58l9jrdkJSlgWfqPlbiMa+mqDn/SFtrwLF2Trbfzu42Sd9UdIzMaSSrzbN
sGm53pNhCh8KndWUQ8GPP2IsLPoUU4qAtmZuTxCx2S1cXrN9EkmT69tlOH84YfSn
96Ih9bWRc7M5y5bfVdEVM+fKQl3hBRf05qMCAwEAAaMYMBYwFAYDVR0RBA0wC4IJ
bG9jYWxob3N0MA0GCSqGSIb3DQEBCwUAA4IBAQAtQ8f37cCEk7/rAcbYR53ce3iK
Vpihb0U2ni1QjG9Tg9UIExkIGkwTiCm7kwQL+GEStBu9AG/QVrOjeTriRiddhWkk
ze8kRaI3AC/63t6Vh9Q1x6PESgeE4OtAO9JpJCf4GILglA789Y/b/GF8zJZQxR13
qpB4ZwWw7gCBhdEW59u6CFeBmfDa58hM8lWvuVoRrTi7bjUeC6PAn5HVMzZSykhu
4HaUfBp6bKFjuym2+h/VvM1n8C3chjVSmutsLb6ELdD8IK0vPV/yf5+LN256zSsS
dyUZYd8XwQaioEMKdbhLvnehyzHiWfQIUR3BdhONxoIJhHv/EAo8eCkHHYIF
-----END CERTIFICATE-----

48
Lib/test/keycert.pem Normal file
View File

@@ -0,0 +1,48 @@
-----BEGIN PRIVATE KEY-----
MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQCr77F9oBLYuLIb
3t4mDHPoxOEnu1h7NQaJdn9tR/KjW6AzhXXm9USh45qt3sR6Wo8sDlBIJ3vZyhyW
P939qYUeGOZJahupYi4IkqVckZXARm3k9qhAI/aC4ixVFyxnxg3bNpk8Ir0AyyQV
oudY+33+ZNj6+fHzeboGDJ9uE/RTcp9JqE/qo0haATZufJfY63ZCUpYFn6j5W4jG
vpqg5/0hba8Cxdk62387uNknfVHSMzGkkq82zbBpud6TYQofCp3VlEPBjz9iLCz6
FFOKgLZmbk8QsdktXF6zfRJJk+vbZTh/OGH0p/eiIfW1kXOzOcuW31XRFTPnykJd
4QUX9OajAgMBAAECggEAHppmXDbuw9Z0FVPg9KLIysioTtsgz6VLiZIm8juZK4x2
glUh/D7xvWL2uDXrgN+3lh7iGUW13LkFx5SMncbbo9TIwI57Z/XKvcnkVwquve+L
RfLFVc1Q5lD9lROv2rS86KTaN4LzYz3FKXi6dvMkpPAsUtfEQhMLkmISypQQq/1z
EJaqo7r85OjN7e0wKazlKZpOzJEa5FQLMVRjTRFhLFNbHXX/tAet2jw+umATKbw8
hYgiuZ44TwSEd9JeIV/oSYWfI/3HetuYW0ru3caiztRF2NySNu8lcsWgNC7fIku9
mcHjtSNzs91QN1Qlu7GQvvhpt6OWDirNDCW+49WGaQKBgQDg9SDhfF0jRYslgYbH
cqO4ggaFdHjrAAYpwnAgvanhFZL/zEqm5G1E7l/e2fCkJ9VOSFO0A208chvwMcr+
dCjHE2tVdE81aQ2v/Eo83VdS1RcOV4Y75yPH48rMhxPaHvxWD/FFDbf0/P2mtPB7
SZ3kIeZMkE1wxdaO3AKUbQoozwKBgQDDqYgg7kVtygyICE1mB8Hwp6nUxFTczG7y
4XcsDqMIrKmw+PbQluvkoHoStxeVrsTloDhkTjIrpmYLyAiazg+PUJdkd6xrfLSj
VV6X93W0S/1egEb1F1CGFxtk8v/PWH4K76EPL2vxXdxjywz3GWlrL9yDYaB2szzS
DqgwVMqx7QKBgDCD7UF0Bsoyl13RX3XoPXLvZ+SkR+e2q52Z94C4JskKVBeiwX7Y
yNAS8M4pBoMArDoj0xmBm69rlKbqtjLGbnzwrTdSzDpim7cWnBQgUFLm7gAD1Elb
AhZ8BCK0Bw4FnLoa2hfga4oEfdfUMgEE0W5/+SEOBgWKRUmuHUhRc911AoGAY2EN
YmSDYSM5wDIvVb5k9B3EtevOiqNPSw/XnsoEZtiEC/44JnQxdltIBY93bDBrk5IQ
cmoBM4h91kgQjshQwOMXMhFSwvmBKmCm/hrTbvMVytTutXfVD3ZXFKwT4DW7N0TF
ElhsxBh/YzRz7mG62JVjtFt2zDN3ld2Z8YpvtXUCgYEA4EJ4ObS5YyvcXAKHJFo6
Fxmavyrf8LSm3MFA65uSnFvWukMVqqRMReQc5jvpxHKCis+XvnHzyOfL0gW9ZTi7
tWGGbBi0TRJCa8BkvgngUZxOxUlMfg/7cVxOIB0TPoUSgxFd/+qVz4GZMvr0dPu7
eAF7J/8ECVvb0wSPTUI1N3c=
-----END PRIVATE KEY-----
-----BEGIN CERTIFICATE-----
MIIDWTCCAkGgAwIBAgIJAPm6B21bar2bMA0GCSqGSIb3DQEBCwUAMF8xCzAJBgNV
BAYTAlhZMRcwFQYDVQQHDA5DYXN0bGUgQW50aHJheDEjMCEGA1UECgwaUHl0aG9u
IFNvZnR3YXJlIEZvdW5kYXRpb24xEjAQBgNVBAMMCWxvY2FsaG9zdDAeFw0xODAx
MTkxOTA5MDZaFw0yODAxMTcxOTA5MDZaMF8xCzAJBgNVBAYTAlhZMRcwFQYDVQQH
DA5DYXN0bGUgQW50aHJheDEjMCEGA1UECgwaUHl0aG9uIFNvZnR3YXJlIEZvdW5k
YXRpb24xEjAQBgNVBAMMCWxvY2FsaG9zdDCCASIwDQYJKoZIhvcNAQEBBQADggEP
ADCCAQoCggEBAKvvsX2gEti4shve3iYMc+jE4Se7WHs1Bol2f21H8qNboDOFdeb1
RKHjmq3exHpajywOUEgne9nKHJY/3f2phR4Y5klqG6liLgiSpVyRlcBGbeT2qEAj
9oLiLFUXLGfGDds2mTwivQDLJBWi51j7ff5k2Pr58fN5ugYMn24T9FNyn0moT+qj
SFoBNm58l9jrdkJSlgWfqPlbiMa+mqDn/SFtrwLF2Trbfzu42Sd9UdIzMaSSrzbN
sGm53pNhCh8KndWUQ8GPP2IsLPoUU4qAtmZuTxCx2S1cXrN9EkmT69tlOH84YfSn
96Ih9bWRc7M5y5bfVdEVM+fKQl3hBRf05qMCAwEAAaMYMBYwFAYDVR0RBA0wC4IJ
bG9jYWxob3N0MA0GCSqGSIb3DQEBCwUAA4IBAQAtQ8f37cCEk7/rAcbYR53ce3iK
Vpihb0U2ni1QjG9Tg9UIExkIGkwTiCm7kwQL+GEStBu9AG/QVrOjeTriRiddhWkk
ze8kRaI3AC/63t6Vh9Q1x6PESgeE4OtAO9JpJCf4GILglA789Y/b/GF8zJZQxR13
qpB4ZwWw7gCBhdEW59u6CFeBmfDa58hM8lWvuVoRrTi7bjUeC6PAn5HVMzZSykhu
4HaUfBp6bKFjuym2+h/VvM1n8C3chjVSmutsLb6ELdD8IK0vPV/yf5+LN256zSsS
dyUZYd8XwQaioEMKdbhLvnehyzHiWfQIUR3BdhONxoIJhHv/EAo8eCkHHYIF
-----END CERTIFICATE-----

49
Lib/test/keycert2.pem Normal file
View File

@@ -0,0 +1,49 @@
-----BEGIN PRIVATE KEY-----
MIIEvwIBADANBgkqhkiG9w0BAQEFAASCBKkwggSlAgEAAoIBAQC3ulRNfhbOAey/
B+wIVYx+d5az7EV4riR6yi/qE6G+bxbTvay2pqySHtDweuaYSh2cVmcasBKKIFJm
rCD1zR8UmLb5i2XFIina1t3eePCuBZMrvZZwkzlQUSM1AZtjGOO/W0I3FwO6y645
9xA5PduKI7SMYkH/VL3zE5W1JwMovv6bvNiT+GU5l6mB9ylCTgLpmUqoQhRqz/35
zCzVyoh+ppDvVcpWYfvXywsXsgQwbAF0QJm8SSFi0TZm5ykv4WE16afQp08yuZS0
3U4K3MJCa4rxO58edcxBopWYfQ29K3iINM8enRfr5q+u5mAAbALAEEvyFjgLWl/u
7arxn7bJAgMBAAECggEBAJfMt8KfHzBunrDnVrk8FayYGkfmOzAOkc1yKEx6k/TH
zFB+Mqlm5MaF95P5t3S0J+r36JBAUdEWC38RUNpF9BwMYYGlDxzlsTdCuGYL/q+J
o6NMLXQt7/jQUQqGnWAvPFzqhbcGqOo5R2ZVH25sEWv9PDuRI35XAepIkDTwWsfa
P6UcJJoP+4v9B++fb3sSL4zNwp1BqS4wxR8YTR0t1zQqOxJ5BGPw1J8aBMs1sq5t
qyosAQAT63kLrdqWotHaM26QxjqEQUMlh12XMWb5GdBXUxbvyGtEabsqskGa/f8B
RdHE437J8D8l+jxb2mZLzrlaH3dq2tbFGCe1rT8qLRECgYEA5CWIvoD/YnQydLGA
OlEhCSocqURuqcotg9Ev0nt/C60jkr/NHFLGppz9lhqjIDjixt3sIMGZMFzxRtwM
pSYal3XiR7rZuHau9iM35yDhpuytEiGbYy1ADakJRzY5jq/Qa8RfPP9Atua5xAeP
q6DiSnq9vhHv9G+O4MxzHBmrw9sCgYEAziiJWFthcwvuXn3Jv9xFYKEb/06puZAx
EgQCz/3rPzv5fmGD/sKVo1U/K4z/eA82DNeKG8QRTFJCxT8TCNRxOmGV7HdCYo/B
4BTNNvbKcdi3l0j75kKoADg+nt5CD5lz6gLG0GrUEnVO1y5HVfCTb3BEAfa36C85
9i0sfQGiwysCgYEAuus9k8cgdct5oz3iLuVVSark/JGCkT2B+OOkaLChsDFUWeEm
7TOsaclpwldkmvvAYOplkZjMJ2GelE2pVo1XcAw3LkmaI5WpVyQXoxe/iQGT8qzy
IFlsh0Scw2lb0tmcyw6CcPk4TiHOxRrkzNrtS9QwLM+JZx0XVHptPPKTVc0CgYAu
j/VFYY5G/8Dc0qhIjyWUR48dQNUQtkJ/ASzpcT46z/7vznKTjbtiYpSb74KbyUO5
7sygrM4DYOj3x+Eys1jHiNbly6HQxQtS4x/edCsRP5NntfI+9XsgYZOzKhvdjhki
F3J0DEzNxnUCIM+311hVaRPTJbgv1srOkTFlIoNydQKBgQC6/OHGaC/OewQqRlRK
Mg5KZm01/pk4iKrpA5nG7OTAeoa70NzXNtG8J3WnaJ4mWanNwNUOyRMAMrsUAy9q
EeGqHM5mMFpY4TeVuNLL21lu/x3KYw6mKL3Ctinn+JLAoYoqEy8deZnEA5/tjYlz
YhFBchnUicjoUN1chdpM6SpV2Q==
-----END PRIVATE KEY-----
-----BEGIN CERTIFICATE-----
MIIDYjCCAkqgAwIBAgIJALJXRr8qF6oIMA0GCSqGSIb3DQEBCwUAMGIxCzAJBgNV
BAYTAlhZMRcwFQYDVQQHDA5DYXN0bGUgQW50aHJheDEjMCEGA1UECgwaUHl0aG9u
IFNvZnR3YXJlIEZvdW5kYXRpb24xFTATBgNVBAMMDGZha2Vob3N0bmFtZTAeFw0x
ODAxMTkxOTA5MDZaFw0yODAxMTcxOTA5MDZaMGIxCzAJBgNVBAYTAlhZMRcwFQYD
VQQHDA5DYXN0bGUgQW50aHJheDEjMCEGA1UECgwaUHl0aG9uIFNvZnR3YXJlIEZv
dW5kYXRpb24xFTATBgNVBAMMDGZha2Vob3N0bmFtZTCCASIwDQYJKoZIhvcNAQEB
BQADggEPADCCAQoCggEBALe6VE1+Fs4B7L8H7AhVjH53lrPsRXiuJHrKL+oTob5v
FtO9rLamrJIe0PB65phKHZxWZxqwEoogUmasIPXNHxSYtvmLZcUiKdrW3d548K4F
kyu9lnCTOVBRIzUBm2MY479bQjcXA7rLrjn3EDk924ojtIxiQf9UvfMTlbUnAyi+
/pu82JP4ZTmXqYH3KUJOAumZSqhCFGrP/fnMLNXKiH6mkO9VylZh+9fLCxeyBDBs
AXRAmbxJIWLRNmbnKS/hYTXpp9CnTzK5lLTdTgrcwkJrivE7nx51zEGilZh9Db0r
eIg0zx6dF+vmr67mYABsAsAQS/IWOAtaX+7tqvGftskCAwEAAaMbMBkwFwYDVR0R
BBAwDoIMZmFrZWhvc3RuYW1lMA0GCSqGSIb3DQEBCwUAA4IBAQCZhHhGItpkqhEq
ntMRd6Hv0GoOJixNvgeMwK4NJSRT/no3OirtUTzccn46h+SWibSa2eVssAV+pAVJ
HbzkN/DH27A1mMx1zJL1ekcOKA1AF6MXhUnrUGXMqW36YNtzHfXJLrwvpLJ13OQg
/Kxo4Nw68bGzM+PyRtKU/mpgYyfcvwR+ZSeIDh1fvUZK/IEVCf8ub42GPVs5wPfv
M+k5aHxWTxeif3K1byTRzxHupYNG2yWO4XEdnBGOuOwzzN4/iQyNcsuQKeuKHGrt
YvIlG/ri04CQ7xISZCj74yjTZ+/A2bXre2mQXAHqKPumHL7cl34+erzbUaxYxbTE
u5FcOmLQ
-----END CERTIFICATE-----

132
Lib/test/keycert3.pem Normal file
View File

@@ -0,0 +1,132 @@
-----BEGIN PRIVATE KEY-----
MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQDgV4G+Zzf2DT5n
oAisIGFhn/bz7Vn5WiXUqbDsxROJOh/7BtOlduZka0pPhFylGbnxS8l1kEWHRI2T
6hOoWzumB6ItKiN+T5J30lAvSyo7iwdFoAQ/S5nPXQfhNARQe/NEOhRtpcuNdyx4
BWdPdPuJQA1ASNJCLwcLOoRxaLbKLvb2V5T5FCAkeNPtRvPuT4gKQItMmiHfAhoV
C8MZWF/GC0RukHINys5MwqeFexam8CznmQPMYrLdhmKTj3DTivCPoh97EDIFGlgZ
SCaaYDVQA+aqlo/q2pi52PFwC1KzhNEA7EeOqSwC1NQjwjHuhcnf9WbxrgTq2zh3
rv5YEW2ZAgMBAAECggEAPfSMtTumPcJskIumuXp7yk02EyliZrWZqwBuBwVqHsS5
nkbFXnXWrLbgn9MrDsFrE5NdgKUmPnQVMVs8sIr5jyGejSCNCs4I4iRn1pfIgwcj
K/xEEALd6GGF0pDd/CgvB5GOoLVf4KKf2kmLvWrOKJpSzoUN5A8+v8AaYYOMr4sC
czbvfGomzEIewEG+Rw9zOVUDlmwyEKPQZ47E7PQ+EEA7oeFdR+1Zj6eT9ndegf8B
54frySYCLRUCk/sHCpWhaJBtBrcpht7Y8CfY7hiH/7x866fvuLnYPz4YALtUb0wN
7zUCNS9ol3n4LbjFFKfZtiRjKaCBRzMjK0rz6ydFcQKBgQDyLI3oGbnW73vqcDe/
6eR0w++fiCAVhfMs3AO/gOaJi2la2JHlJ5u+cIHQIOFwEhn6Zq0AtdmnFx1TS5IQ
C0MdXI0XoQQw7rEF8EJcvfe85Z0QxENVhzydtdb8QpJfnQGfBfLyQlaaRYzRRHB6
VdYUHF3EIPVIhbjbghal+Qep/QKBgQDtJlRPHkWwTMevu0J0fYbWN1ywtVTFUR//
k7VyORSf8yuuSnaQRop4cbcqONxmDKH6Or1fl3NYBsAxtXkkOK1E2OZNo2sfQdRa
wpA7o7mPHRhztQFpT5vflp+8P6+PEFat8D04eBOhNwrwwfhiPjD4gv5KvN4XutRW
VWv/2pnmzQKBgHPvHGg2mJ7quvm6ixXW1MWJX1eSBToIjCe3lBvDi5nhIaiZ8Q4w
7gA3QA3xD7tlDwauzLeAVxgEmsdbcCs6GQEfY3QiYy1Bt4FOSZa4YrcNfSmfq1Rw
j3Y4rRjKjeQz96i3YlzToT3tecJc7zPBj+DEy6au2H3Fdn+vQURneWHJAoGBANG7
XES8mRVaUh/wlM1BVsaNH8SIGfiHzqzRjV7/bGYpQTBbWpAuUrhCmaMVtpXqBjav
TFwGLVRkZAWSYRjPpy2ERenT5SE3rv61o6mbGrifGsj6A82HQmtzYsGx8SmtYXtj
REF0sKebbmmOooUAS379GrguYJzL9o6D7YfRZNrhAoGAVfb/tiFU4S67DSpYpQey
ULhgfsFpDByICY6Potsg67gVFf9jIaB83NPTx3u/r6sHFgxFw7lQsuZcgSuWMu7t
glzOXVIP11Y5sl5CJ5OsfeK1/0umMZF5MWPyAQCx/qrPlZL86vXjt24Y/VaOxsAi
CZYdyJsjgOrJrWoMbo5ta54=
-----END PRIVATE KEY-----
Certificate:
Data:
Version: 3 (0x2)
Serial Number:
82:ed:bf:41:c8:80:91:9c
Signature Algorithm: sha1WithRSAEncryption
Issuer: C=XY, O=Python Software Foundation CA, CN=our-ca-server
Validity
Not Before: Jan 19 19:09:06 2018 GMT
Not After : Nov 28 19:09:06 2027 GMT
Subject: C=XY, L=Castle Anthrax, O=Python Software Foundation, CN=localhost
Subject Public Key Info:
Public Key Algorithm: rsaEncryption
Public-Key: (2048 bit)
Modulus:
00:e0:57:81:be:67:37:f6:0d:3e:67:a0:08:ac:20:
61:61:9f:f6:f3:ed:59:f9:5a:25:d4:a9:b0:ec:c5:
13:89:3a:1f:fb:06:d3:a5:76:e6:64:6b:4a:4f:84:
5c:a5:19:b9:f1:4b:c9:75:90:45:87:44:8d:93:ea:
13:a8:5b:3b:a6:07:a2:2d:2a:23:7e:4f:92:77:d2:
50:2f:4b:2a:3b:8b:07:45:a0:04:3f:4b:99:cf:5d:
07:e1:34:04:50:7b:f3:44:3a:14:6d:a5:cb:8d:77:
2c:78:05:67:4f:74:fb:89:40:0d:40:48:d2:42:2f:
07:0b:3a:84:71:68:b6:ca:2e:f6:f6:57:94:f9:14:
20:24:78:d3:ed:46:f3:ee:4f:88:0a:40:8b:4c:9a:
21:df:02:1a:15:0b:c3:19:58:5f:c6:0b:44:6e:90:
72:0d:ca:ce:4c:c2:a7:85:7b:16:a6:f0:2c:e7:99:
03:cc:62:b2:dd:86:62:93:8f:70:d3:8a:f0:8f:a2:
1f:7b:10:32:05:1a:58:19:48:26:9a:60:35:50:03:
e6:aa:96:8f:ea:da:98:b9:d8:f1:70:0b:52:b3:84:
d1:00:ec:47:8e:a9:2c:02:d4:d4:23:c2:31:ee:85:
c9:df:f5:66:f1:ae:04:ea:db:38:77:ae:fe:58:11:
6d:99
Exponent: 65537 (0x10001)
X509v3 extensions:
X509v3 Subject Alternative Name:
DNS:localhost
X509v3 Key Usage: critical
Digital Signature, Key Encipherment
X509v3 Extended Key Usage:
TLS Web Server Authentication, TLS Web Client Authentication
X509v3 Basic Constraints: critical
CA:FALSE
X509v3 Subject Key Identifier:
85:11:BE:16:47:04:D1:30:EE:86:8A:18:70:BE:A8:28:6F:82:3D:CE
X509v3 Authority Key Identifier:
keyid:9A:CF:CF:6E:EB:71:3D:DB:3C:F1:AE:88:6B:56:72:03:CB:08:A7:48
DirName:/C=XY/O=Python Software Foundation CA/CN=our-ca-server
serial:82:ED:BF:41:C8:80:91:9B
Authority Information Access:
CA Issuers - URI:http://testca.pythontest.net/testca/pycacert.cer
OCSP - URI:http://testca.pythontest.net/testca/ocsp/
X509v3 CRL Distribution Points:
Full Name:
URI:http://testca.pythontest.net/testca/revocation.crl
Signature Algorithm: sha1WithRSAEncryption
7f:a1:7e:3e:68:01:b0:32:b8:57:b8:03:68:13:13:b3:e3:f4:
70:2f:15:e5:0f:87:b9:fd:e0:12:e3:16:f2:91:53:c7:4e:25:
af:ca:cb:a7:d9:9d:57:4d:bf:a2:80:d4:78:aa:04:31:fd:6d:
cc:6d:82:43:e9:62:16:0d:0e:26:8b:e7:f1:3d:57:5c:68:02:
9c:2b:b6:c9:fd:62:2f:10:85:88:cc:44:a5:e7:a2:3e:89:f2:
1f:02:6a:3f:d0:3c:6c:24:2d:bc:51:62:7a:ec:25:c5:86:87:
77:35:8f:f9:7e:d0:17:3d:77:56:bf:1a:0c:be:09:78:ee:ea:
73:97:65:60:94:91:35:b3:5c:46:8a:5e:6d:94:52:de:48:b7:
1f:6c:28:79:7f:ff:08:8d:e4:7d:d0:b9:0b:7c:ae:c4:1d:2a:
a1:b3:50:11:82:03:5e:6c:e7:26:fa:05:32:39:07:83:49:b9:
a2:fa:04:da:0d:e5:ff:4c:db:97:d0:c3:a7:43:37:4c:16:de:
3c:b5:e9:7e:82:d4:b3:10:df:d1:c1:66:72:9c:15:67:19:3b:
7b:91:0a:82:07:67:c5:06:03:5f:80:54:08:81:8a:b1:5c:7c:
4c:d2:07:38:92:eb:12:f5:71:ae:de:05:15:c8:e1:33:f0:e4:
96:0f:0f:1e
-----BEGIN CERTIFICATE-----
MIIE8TCCA9mgAwIBAgIJAILtv0HIgJGcMA0GCSqGSIb3DQEBBQUAME0xCzAJBgNV
BAYTAlhZMSYwJAYDVQQKDB1QeXRob24gU29mdHdhcmUgRm91bmRhdGlvbiBDQTEW
MBQGA1UEAwwNb3VyLWNhLXNlcnZlcjAeFw0xODAxMTkxOTA5MDZaFw0yNzExMjgx
OTA5MDZaMF8xCzAJBgNVBAYTAlhZMRcwFQYDVQQHDA5DYXN0bGUgQW50aHJheDEj
MCEGA1UECgwaUHl0aG9uIFNvZnR3YXJlIEZvdW5kYXRpb24xEjAQBgNVBAMMCWxv
Y2FsaG9zdDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAOBXgb5nN/YN
PmegCKwgYWGf9vPtWflaJdSpsOzFE4k6H/sG06V25mRrSk+EXKUZufFLyXWQRYdE
jZPqE6hbO6YHoi0qI35PknfSUC9LKjuLB0WgBD9Lmc9dB+E0BFB780Q6FG2ly413
LHgFZ090+4lADUBI0kIvBws6hHFotsou9vZXlPkUICR40+1G8+5PiApAi0yaId8C
GhULwxlYX8YLRG6Qcg3KzkzCp4V7FqbwLOeZA8xist2GYpOPcNOK8I+iH3sQMgUa
WBlIJppgNVAD5qqWj+ramLnY8XALUrOE0QDsR46pLALU1CPCMe6Fyd/1ZvGuBOrb
OHeu/lgRbZkCAwEAAaOCAcAwggG8MBQGA1UdEQQNMAuCCWxvY2FsaG9zdDAOBgNV
HQ8BAf8EBAMCBaAwHQYDVR0lBBYwFAYIKwYBBQUHAwEGCCsGAQUFBwMCMAwGA1Ud
EwEB/wQCMAAwHQYDVR0OBBYEFIURvhZHBNEw7oaKGHC+qChvgj3OMH0GA1UdIwR2
MHSAFJrPz27rcT3bPPGuiGtWcgPLCKdIoVGkTzBNMQswCQYDVQQGEwJYWTEmMCQG
A1UECgwdUHl0aG9uIFNvZnR3YXJlIEZvdW5kYXRpb24gQ0ExFjAUBgNVBAMMDW91
ci1jYS1zZXJ2ZXKCCQCC7b9ByICRmzCBgwYIKwYBBQUHAQEEdzB1MDwGCCsGAQUF
BzAChjBodHRwOi8vdGVzdGNhLnB5dGhvbnRlc3QubmV0L3Rlc3RjYS9weWNhY2Vy
dC5jZXIwNQYIKwYBBQUHMAGGKWh0dHA6Ly90ZXN0Y2EucHl0aG9udGVzdC5uZXQv
dGVzdGNhL29jc3AvMEMGA1UdHwQ8MDowOKA2oDSGMmh0dHA6Ly90ZXN0Y2EucHl0
aG9udGVzdC5uZXQvdGVzdGNhL3Jldm9jYXRpb24uY3JsMA0GCSqGSIb3DQEBBQUA
A4IBAQB/oX4+aAGwMrhXuANoExOz4/RwLxXlD4e5/eAS4xbykVPHTiWvysun2Z1X
Tb+igNR4qgQx/W3MbYJD6WIWDQ4mi+fxPVdcaAKcK7bJ/WIvEIWIzESl56I+ifIf
Amo/0DxsJC28UWJ67CXFhod3NY/5ftAXPXdWvxoMvgl47upzl2VglJE1s1xGil5t
lFLeSLcfbCh5f/8IjeR90LkLfK7EHSqhs1ARggNebOcm+gUyOQeDSbmi+gTaDeX/
TNuX0MOnQzdMFt48tel+gtSzEN/RwWZynBVnGTt7kQqCB2fFBgNfgFQIgYqxXHxM
0gc4kusS9XGu3gUVyOEz8OSWDw8e
-----END CERTIFICATE-----

132
Lib/test/keycert4.pem Normal file
View File

@@ -0,0 +1,132 @@
-----BEGIN PRIVATE KEY-----
MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQDH/76hZAZH4cSV
CmVZa5HEqKCjCKrcPwBECs9BS+3ibwN4x9NnFNP+tCeFGgJXl7WGFoeXgg3oK+1p
FsOWpsRHuF3BdqkCnShSydmT8bLaGHwKeL0cPxJP5T/uW7ezPKW2VWXGMwmwRaRJ
9dj2VCUu20vDZWSGFr9zjnjoJczBtH3RsVUgpK7euEHuQ5pIM9QSOaCo+5FPR7s7
1nU7YqbFWtd+NhC8Og1G497B31DQlHciF6BRm6/cNGAmHaAErKUGBFdkGtFPHBn4
vktoEg9fwxJAZLvGpoTZWrB4HRsRwVTmFdGvK+JXK225xF23AXRXp/snhSuSFeLj
E5cpyJJ7AgMBAAECggEAQOv527X2e/sDr0XSpHZQuT/r9UBpBlnFIlFH+fBF5k0X
GWv0ae/O6U1dzs0kmX57xG0n0ry6+vTXeleTYiH8cTOd66EzN9AAOO+hG29IGZf9
HAEZkkO/FARc/mjzdtFnEYsjIHWM3ZWdwQx3Q28JKu6w51rQiN51g3NqOCGdF/uF
rE5XPKsKndn+nLHvsNuApFgUYZEwdrozgUueEgRaPTUCNhzotcA9eWoBdA24XNhk
x8Cm/bZWabXm7gBO75zl3Cu2F21ay+EuwyOZTsx6lZi6YX9/zo1mkO81Zi3tQk50
NMEI0feLNwsdxTbmOcVJadjOgd+QVghlFyr5HGBWMQKBgQD3AH3rhnAo6tOyNkGN
+IzIU1MhUS452O7IavykUYO9sM24BVChpRtlI9Dpev4yE/q3BAO3+oWT3cJrN7/3
iyo1dzAkpGvI65XWfElXFM4nLjEiZzx4W9fiPN91Oucpr0ED6+BZXTtz4gVm0TP/
TUc2xvTB6EKvIyWmKOYEi0snxQKBgQDPSOjbz9jWOrC9XY7PmtLB6QJDDz7XSGVK
wzD+gDAPpAwhk58BEokdOhBx2Lwl8zMJi0CRHgH2vNvkRyhvUQ4UFzisrqann/Tw
klp5sw3iWC6ERC8z9zL7GfHs7sK3mOVeAdK6ffowPM3JrZ2vPusVBdr0MN3oZwki
CtNXqbY1PwKBgGheQNbAW6wubX0kB9chavtKmhm937Z5v4vYCSC1gOEqUAKt3EAx
L74wwBmn6rjmUE382EVpCgBM99WuHONQXmlxD1qsTw763LlgkuzE0cckcYaD8L06
saHa7uDuHrcyYlpx1L5t8q0ol/e19i6uTKUMtGcq6OJwC3yGU4sgAIWxAoGBAMVq
qiQXm2vFL+jafxYoXUvDMJ1PmskMsTP4HOR2j8+FrOwZnVk3HxGP6HOVOPRn4JbZ
YiAT1Uj6a+7I+rCyINdvmlGUcTK6fFzW9oZryvBkjcD483/pkktmVWwTpa2YV/Ml
h16IdsyUTGYlDUYHhXtbPUJOfDpIT4F1j/0wrFGfAoGAO82BcUsehEUQE0xvQLIn
7QaFtUI5z19WW730jVuEobiYlh9Ka4DPbKMvka8MwyOxEwhk39gZQavmfG6+wZm+
kjERU23LhHziJGWS2Um4yIhC7myKbWaLzjHEq72dszLpQku4BzE5fT60fxI7cURD
WGm/Z3Q2weS3ZGIoMj1RNPI=
-----END PRIVATE KEY-----
Certificate:
Data:
Version: 3 (0x2)
Serial Number:
82:ed:bf:41:c8:80:91:9d
Signature Algorithm: sha1WithRSAEncryption
Issuer: C=XY, O=Python Software Foundation CA, CN=our-ca-server
Validity
Not Before: Jan 19 19:09:06 2018 GMT
Not After : Nov 28 19:09:06 2027 GMT
Subject: C=XY, L=Castle Anthrax, O=Python Software Foundation, CN=fakehostname
Subject Public Key Info:
Public Key Algorithm: rsaEncryption
Public-Key: (2048 bit)
Modulus:
00:c7:ff:be:a1:64:06:47:e1:c4:95:0a:65:59:6b:
91:c4:a8:a0:a3:08:aa:dc:3f:00:44:0a:cf:41:4b:
ed:e2:6f:03:78:c7:d3:67:14:d3:fe:b4:27:85:1a:
02:57:97:b5:86:16:87:97:82:0d:e8:2b:ed:69:16:
c3:96:a6:c4:47:b8:5d:c1:76:a9:02:9d:28:52:c9:
d9:93:f1:b2:da:18:7c:0a:78:bd:1c:3f:12:4f:e5:
3f:ee:5b:b7:b3:3c:a5:b6:55:65:c6:33:09:b0:45:
a4:49:f5:d8:f6:54:25:2e:db:4b:c3:65:64:86:16:
bf:73:8e:78:e8:25:cc:c1:b4:7d:d1:b1:55:20:a4:
ae:de:b8:41:ee:43:9a:48:33:d4:12:39:a0:a8:fb:
91:4f:47:bb:3b:d6:75:3b:62:a6:c5:5a:d7:7e:36:
10:bc:3a:0d:46:e3:de:c1:df:50:d0:94:77:22:17:
a0:51:9b:af:dc:34:60:26:1d:a0:04:ac:a5:06:04:
57:64:1a:d1:4f:1c:19:f8:be:4b:68:12:0f:5f:c3:
12:40:64:bb:c6:a6:84:d9:5a:b0:78:1d:1b:11:c1:
54:e6:15:d1:af:2b:e2:57:2b:6d:b9:c4:5d:b7:01:
74:57:a7:fb:27:85:2b:92:15:e2:e3:13:97:29:c8:
92:7b
Exponent: 65537 (0x10001)
X509v3 extensions:
X509v3 Subject Alternative Name:
DNS:fakehostname
X509v3 Key Usage: critical
Digital Signature, Key Encipherment
X509v3 Extended Key Usage:
TLS Web Server Authentication, TLS Web Client Authentication
X509v3 Basic Constraints: critical
CA:FALSE
X509v3 Subject Key Identifier:
F8:76:79:CB:11:85:F0:46:E5:95:E6:7E:69:CB:12:5E:4E:AA:EC:4D
X509v3 Authority Key Identifier:
keyid:9A:CF:CF:6E:EB:71:3D:DB:3C:F1:AE:88:6B:56:72:03:CB:08:A7:48
DirName:/C=XY/O=Python Software Foundation CA/CN=our-ca-server
serial:82:ED:BF:41:C8:80:91:9B
Authority Information Access:
CA Issuers - URI:http://testca.pythontest.net/testca/pycacert.cer
OCSP - URI:http://testca.pythontest.net/testca/ocsp/
X509v3 CRL Distribution Points:
Full Name:
URI:http://testca.pythontest.net/testca/revocation.crl
Signature Algorithm: sha1WithRSAEncryption
6d:50:8d:fb:ee:4e:93:8b:eb:47:56:ba:38:cc:80:e1:9d:c7:
e1:9e:1f:9c:22:0c:d2:08:9b:ed:bf:31:d9:00:ee:af:8c:56:
78:92:d1:7c:ba:4e:81:7f:82:1f:f4:68:99:86:91:c6:cb:57:
d3:b9:41:12:fa:75:53:fd:22:32:21:50:af:6b:4c:b1:34:36:
d1:a8:25:0a:d0:f0:f8:81:7d:69:58:6e:af:e3:d2:c4:32:87:
79:d7:cd:ad:0c:56:f3:15:27:10:0c:f9:57:59:53:00:ed:af:
5d:4d:07:86:7a:e5:f3:97:88:bc:86:b4:f1:17:46:33:55:28:
66:7b:70:d3:a5:12:b9:4f:c7:ed:e6:13:20:2d:f0:9e:ec:17:
64:cf:fd:13:14:1b:76:ba:64:ac:c5:51:b6:cd:13:0a:93:b1:
fd:43:09:a0:0b:44:6c:77:45:43:0b:e5:ed:70:b2:76:dc:08:
4a:5b:73:5f:c1:fc:7f:63:70:f8:b9:ca:3c:98:06:5f:fd:98:
d1:e4:e6:61:5f:09:8f:6c:18:86:98:9c:cb:3f:73:7b:3f:38:
f5:a7:09:20:ee:a5:63:1c:ff:8b:a6:d1:8c:e8:f4:84:3d:99:
38:0f:cc:e0:52:03:f9:18:05:23:76:39:de:52:ce:8e:fb:a6:
6e:f5:4f:c3
-----BEGIN CERTIFICATE-----
MIIE9zCCA9+gAwIBAgIJAILtv0HIgJGdMA0GCSqGSIb3DQEBBQUAME0xCzAJBgNV
BAYTAlhZMSYwJAYDVQQKDB1QeXRob24gU29mdHdhcmUgRm91bmRhdGlvbiBDQTEW
MBQGA1UEAwwNb3VyLWNhLXNlcnZlcjAeFw0xODAxMTkxOTA5MDZaFw0yNzExMjgx
OTA5MDZaMGIxCzAJBgNVBAYTAlhZMRcwFQYDVQQHDA5DYXN0bGUgQW50aHJheDEj
MCEGA1UECgwaUHl0aG9uIFNvZnR3YXJlIEZvdW5kYXRpb24xFTATBgNVBAMMDGZh
a2Vob3N0bmFtZTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMf/vqFk
BkfhxJUKZVlrkcSooKMIqtw/AEQKz0FL7eJvA3jH02cU0/60J4UaAleXtYYWh5eC
Degr7WkWw5amxEe4XcF2qQKdKFLJ2ZPxstoYfAp4vRw/Ek/lP+5bt7M8pbZVZcYz
CbBFpEn12PZUJS7bS8NlZIYWv3OOeOglzMG0fdGxVSCkrt64Qe5Dmkgz1BI5oKj7
kU9HuzvWdTtipsVa1342ELw6DUbj3sHfUNCUdyIXoFGbr9w0YCYdoASspQYEV2Qa
0U8cGfi+S2gSD1/DEkBku8amhNlasHgdGxHBVOYV0a8r4lcrbbnEXbcBdFen+yeF
K5IV4uMTlynIknsCAwEAAaOCAcMwggG/MBcGA1UdEQQQMA6CDGZha2Vob3N0bmFt
ZTAOBgNVHQ8BAf8EBAMCBaAwHQYDVR0lBBYwFAYIKwYBBQUHAwEGCCsGAQUFBwMC
MAwGA1UdEwEB/wQCMAAwHQYDVR0OBBYEFPh2ecsRhfBG5ZXmfmnLEl5OquxNMH0G
A1UdIwR2MHSAFJrPz27rcT3bPPGuiGtWcgPLCKdIoVGkTzBNMQswCQYDVQQGEwJY
WTEmMCQGA1UECgwdUHl0aG9uIFNvZnR3YXJlIEZvdW5kYXRpb24gQ0ExFjAUBgNV
BAMMDW91ci1jYS1zZXJ2ZXKCCQCC7b9ByICRmzCBgwYIKwYBBQUHAQEEdzB1MDwG
CCsGAQUFBzAChjBodHRwOi8vdGVzdGNhLnB5dGhvbnRlc3QubmV0L3Rlc3RjYS9w
eWNhY2VydC5jZXIwNQYIKwYBBQUHMAGGKWh0dHA6Ly90ZXN0Y2EucHl0aG9udGVz
dC5uZXQvdGVzdGNhL29jc3AvMEMGA1UdHwQ8MDowOKA2oDSGMmh0dHA6Ly90ZXN0
Y2EucHl0aG9udGVzdC5uZXQvdGVzdGNhL3Jldm9jYXRpb24uY3JsMA0GCSqGSIb3
DQEBBQUAA4IBAQBtUI377k6Ti+tHVro4zIDhncfhnh+cIgzSCJvtvzHZAO6vjFZ4
ktF8uk6Bf4If9GiZhpHGy1fTuUES+nVT/SIyIVCva0yxNDbRqCUK0PD4gX1pWG6v
49LEMod5182tDFbzFScQDPlXWVMA7a9dTQeGeuXzl4i8hrTxF0YzVShme3DTpRK5
T8ft5hMgLfCe7Bdkz/0TFBt2umSsxVG2zRMKk7H9QwmgC0Rsd0VDC+XtcLJ23AhK
W3Nfwfx/Y3D4uco8mAZf/ZjR5OZhXwmPbBiGmJzLP3N7Pzj1pwkg7qVjHP+LptGM
6PSEPZk4D8zgUgP5GAUjdjneUs6O+6Zu9U/D
-----END CERTIFICATE-----

96
Lib/test/keycertecc.pem Normal file
View File

@@ -0,0 +1,96 @@
-----BEGIN PRIVATE KEY-----
MIG2AgEAMBAGByqGSM49AgEGBSuBBAAiBIGeMIGbAgEBBDDe3QWmhZX07HZbntz4
CFqAOaoYMdYwD7Z3WPNIc2zR7p4D6BMOa7NAWjLV5A7CUw6hZANiAAQ5IVKzLLz4
LCfcpy6fMOp+jk5KwywsU3upPtjA6E3UetxPcfnnv+gghRyDAYLN2OVqZgLMEmUo
F1j1SM1QrbhHIuNcVxI9gPPMdumcNFSz/hqxrBRtA/8Z2gywczdNLjc=
-----END PRIVATE KEY-----
Certificate:
Data:
Version: 3 (0x2)
Serial Number:
82:ed:bf:41:c8:80:91:9e
Signature Algorithm: sha1WithRSAEncryption
Issuer: C=XY, O=Python Software Foundation CA, CN=our-ca-server
Validity
Not Before: Jan 19 19:09:06 2018 GMT
Not After : Nov 28 19:09:06 2027 GMT
Subject: C=XY, L=Castle Anthrax, O=Python Software Foundation, CN=localhost-ecc
Subject Public Key Info:
Public Key Algorithm: id-ecPublicKey
Public-Key: (384 bit)
pub:
04:39:21:52:b3:2c:bc:f8:2c:27:dc:a7:2e:9f:30:
ea:7e:8e:4e:4a:c3:2c:2c:53:7b:a9:3e:d8:c0:e8:
4d:d4:7a:dc:4f:71:f9:e7:bf:e8:20:85:1c:83:01:
82:cd:d8:e5:6a:66:02:cc:12:65:28:17:58:f5:48:
cd:50:ad:b8:47:22:e3:5c:57:12:3d:80:f3:cc:76:
e9:9c:34:54:b3:fe:1a:b1:ac:14:6d:03:ff:19:da:
0c:b0:73:37:4d:2e:37
ASN1 OID: secp384r1
NIST CURVE: P-384
X509v3 extensions:
X509v3 Subject Alternative Name:
DNS:localhost-ecc
X509v3 Key Usage: critical
Digital Signature, Key Encipherment
X509v3 Extended Key Usage:
TLS Web Server Authentication, TLS Web Client Authentication
X509v3 Basic Constraints: critical
CA:FALSE
X509v3 Subject Key Identifier:
33:23:0E:15:04:83:2E:3D:BF:DA:81:6D:10:38:80:C3:C2:B0:A4:74
X509v3 Authority Key Identifier:
keyid:9A:CF:CF:6E:EB:71:3D:DB:3C:F1:AE:88:6B:56:72:03:CB:08:A7:48
DirName:/C=XY/O=Python Software Foundation CA/CN=our-ca-server
serial:82:ED:BF:41:C8:80:91:9B
Authority Information Access:
CA Issuers - URI:http://testca.pythontest.net/testca/pycacert.cer
OCSP - URI:http://testca.pythontest.net/testca/ocsp/
X509v3 CRL Distribution Points:
Full Name:
URI:http://testca.pythontest.net/testca/revocation.crl
Signature Algorithm: sha1WithRSAEncryption
3b:6f:97:af:7e:5f:e0:14:34:ed:57:7e:de:ce:c4:85:1e:aa:
84:52:94:7c:e5:ce:e9:9c:88:8b:ad:b5:4d:16:ac:af:81:ea:
b8:a2:e2:50:2e:cb:e9:11:bd:1b:a6:3f:0c:a2:d7:7b:67:72:
b3:43:16:ad:c6:87:ac:6e:ac:47:78:ef:2f:8c:86:e8:9b:d1:
43:8c:c1:7a:91:30:e9:14:d6:9f:41:8b:9b:0b:24:9b:78:86:
11:8a:fc:2b:cd:c9:13:ee:90:4f:14:33:51:a3:c4:9e:d6:06:
48:f5:41:12:af:f0:f2:71:40:78:f5:96:c2:5d:cf:e1:38:ff:
bf:10:eb:74:2f:c2:23:21:3e:27:f5:f1:f2:af:2c:62:82:31:
00:c8:96:1b:c3:7e:8d:71:89:e7:40:b5:67:1a:33:fb:c0:8b:
96:0c:36:78:25:27:82:d8:27:27:52:0f:f7:69:cd:ff:2b:92:
10:d3:d2:0a:db:65:ed:af:90:eb:db:76:f3:8a:7a:13:9e:c6:
33:57:15:42:06:13:d6:54:49:fa:84:a7:0e:1d:14:72:ca:19:
8e:2b:aa:a4:02:54:3c:f6:1c:23:81:7a:59:54:b0:92:65:72:
c8:e5:ba:9f:03:4e:30:f2:4d:45:85:e3:35:a8:b1:68:58:b9:
3b:20:a3:eb
-----BEGIN CERTIFICATE-----
MIIESzCCAzOgAwIBAgIJAILtv0HIgJGeMA0GCSqGSIb3DQEBBQUAME0xCzAJBgNV
BAYTAlhZMSYwJAYDVQQKDB1QeXRob24gU29mdHdhcmUgRm91bmRhdGlvbiBDQTEW
MBQGA1UEAwwNb3VyLWNhLXNlcnZlcjAeFw0xODAxMTkxOTA5MDZaFw0yNzExMjgx
OTA5MDZaMGMxCzAJBgNVBAYTAlhZMRcwFQYDVQQHDA5DYXN0bGUgQW50aHJheDEj
MCEGA1UECgwaUHl0aG9uIFNvZnR3YXJlIEZvdW5kYXRpb24xFjAUBgNVBAMMDWxv
Y2FsaG9zdC1lY2MwdjAQBgcqhkjOPQIBBgUrgQQAIgNiAAQ5IVKzLLz4LCfcpy6f
MOp+jk5KwywsU3upPtjA6E3UetxPcfnnv+gghRyDAYLN2OVqZgLMEmUoF1j1SM1Q
rbhHIuNcVxI9gPPMdumcNFSz/hqxrBRtA/8Z2gywczdNLjejggHEMIIBwDAYBgNV
HREEETAPgg1sb2NhbGhvc3QtZWNjMA4GA1UdDwEB/wQEAwIFoDAdBgNVHSUEFjAU
BggrBgEFBQcDAQYIKwYBBQUHAwIwDAYDVR0TAQH/BAIwADAdBgNVHQ4EFgQUMyMO
FQSDLj2/2oFtEDiAw8KwpHQwfQYDVR0jBHYwdIAUms/PbutxPds88a6Ia1ZyA8sI
p0ihUaRPME0xCzAJBgNVBAYTAlhZMSYwJAYDVQQKDB1QeXRob24gU29mdHdhcmUg
Rm91bmRhdGlvbiBDQTEWMBQGA1UEAwwNb3VyLWNhLXNlcnZlcoIJAILtv0HIgJGb
MIGDBggrBgEFBQcBAQR3MHUwPAYIKwYBBQUHMAKGMGh0dHA6Ly90ZXN0Y2EucHl0
aG9udGVzdC5uZXQvdGVzdGNhL3B5Y2FjZXJ0LmNlcjA1BggrBgEFBQcwAYYpaHR0
cDovL3Rlc3RjYS5weXRob250ZXN0Lm5ldC90ZXN0Y2Evb2NzcC8wQwYDVR0fBDww
OjA4oDagNIYyaHR0cDovL3Rlc3RjYS5weXRob250ZXN0Lm5ldC90ZXN0Y2EvcmV2
b2NhdGlvbi5jcmwwDQYJKoZIhvcNAQEFBQADggEBADtvl69+X+AUNO1Xft7OxIUe
qoRSlHzlzumciIuttU0WrK+B6rii4lAuy+kRvRumPwyi13tncrNDFq3Gh6xurEd4
7y+Mhuib0UOMwXqRMOkU1p9Bi5sLJJt4hhGK/CvNyRPukE8UM1GjxJ7WBkj1QRKv
8PJxQHj1lsJdz+E4/78Q63QvwiMhPif18fKvLGKCMQDIlhvDfo1xiedAtWcaM/vA
i5YMNnglJ4LYJydSD/dpzf8rkhDT0grbZe2vkOvbdvOKehOexjNXFUIGE9ZUSfqE
pw4dFHLKGY4rqqQCVDz2HCOBellUsJJlcsjlup8DTjDyTUWF4zWosWhYuTsgo+s=
-----END CERTIFICATE-----

1103
Lib/test/test_ftplib.py Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -106,7 +106,7 @@ uname = "0.1.1"
crc32fast = "1.2.0"
adler32 = "1.0.3"
gethostname = "0.2.0"
socket2 = "0.3"
socket2 = "0.3.19"
rustyline = "6.0"
openssl = { version = "0.10", features = ["vendored"], optional = true }
openssl-sys = { version = "0.9", optional = true }

View File

@@ -30,6 +30,25 @@ impl Write for PyWriter<'_> {
}
}
pub fn write_all(
mut buf: &[u8],
mut write: impl FnMut(&[u8]) -> io::Result<usize>,
) -> io::Result<()> {
while !buf.is_empty() {
match write(buf) {
Ok(0) => {
return Err(io::Error::new(
io::ErrorKind::WriteZero,
"failed to write whole buffer",
))
}
Ok(n) => buf = &buf[n..],
Err(e) => return Err(e),
}
}
Ok(())
}
pub fn file_readline(obj: &PyObjectRef, size: Option<usize>, vm: &VirtualMachine) -> PyResult {
let args = size.map_or_else(Vec::new, |size| vec![vm.ctx.new_int(size)]);
let ret = vm.call_method(obj, "readline", args)?;

View File

@@ -170,6 +170,11 @@ fn make_path<'a>(
}
impl IntoPyException for io::Error {
fn into_pyexception(self, vm: &VirtualMachine) -> PyBaseExceptionRef {
(&self).into_pyexception(vm)
}
}
impl IntoPyException for &'_ io::Error {
fn into_pyexception(self, vm: &VirtualMachine) -> PyBaseExceptionRef {
#[allow(unreachable_patterns)] // some errors are just aliases of each other
let exc_type = match self.kind() {

View File

@@ -4,7 +4,7 @@ use gethostname::gethostname;
use nix::unistd::sethostname;
use socket2::{Domain, Protocol, Socket, Type as SocketType};
use std::convert::TryFrom;
use std::io::{self, prelude::*};
use std::io;
use std::net::{Ipv4Addr, Ipv6Addr, Shutdown, SocketAddr, ToSocketAddrs};
use std::time::Duration;
@@ -20,7 +20,7 @@ use crate::pyobject::{
BorrowValue, Either, IntoPyObject, PyClassImpl, PyObjectRef, PyRef, PyResult, PyValue,
StaticType, TryFromObject,
};
use crate::vm::VirtualMachine;
use crate::{py_io, VirtualMachine};
#[cfg(unix)]
type RawSocket = std::os::unix::io::RawFd;
@@ -48,7 +48,8 @@ mod c {
pub use winapi::shared::ws2def::*;
pub use winapi::um::winsock2::{
SD_BOTH as SHUT_RDWR, SD_RECEIVE as SHUT_RD, SD_SEND as SHUT_WR, SOCK_DGRAM, SOCK_RAW,
SOCK_RDM, SOCK_STREAM, SOL_SOCKET, SO_BROADCAST, SO_REUSEADDR, SO_TYPE, *,
SOCK_RDM, SOCK_STREAM, SOL_SOCKET, SO_BROADCAST, SO_ERROR, SO_OOBINLINE, SO_REUSEADDR,
SO_TYPE, *,
};
}
@@ -71,7 +72,7 @@ pub type PySocketRef = PyRef<PySocket>;
#[pyimpl(flags(BASETYPE))]
impl PySocket {
fn sock(&self) -> PyRwLockReadGuard<'_, Socket> {
pub fn sock(&self) -> PyRwLockReadGuard<'_, Socket> {
self.sock.read()
}
@@ -167,52 +168,90 @@ impl PySocket {
}
#[pymethod]
fn recv(&self, bufsize: usize, vm: &VirtualMachine) -> PyResult<Vec<u8>> {
fn recv(
&self,
bufsize: usize,
flags: OptionalArg<i32>,
vm: &VirtualMachine,
) -> PyResult<Vec<u8>> {
let flags = flags.unwrap_or(0);
let mut buffer = vec![0u8; bufsize];
let n = self
.sock()
.recv(&mut buffer)
.recv_with_flags(&mut buffer, flags)
.map_err(|err| convert_sock_error(vm, err))?;
buffer.truncate(n);
Ok(buffer)
}
#[pymethod]
fn recv_into(&self, buf: PyRwBytesLike, vm: &VirtualMachine) -> PyResult<usize> {
buf.with_ref(|buf| self.sock().recv(buf))
fn recv_into(
&self,
buf: PyRwBytesLike,
flags: OptionalArg<i32>,
vm: &VirtualMachine,
) -> PyResult<usize> {
let flags = flags.unwrap_or(0);
buf.with_ref(|buf| self.sock().recv_with_flags(buf, flags))
.map_err(|err| convert_sock_error(vm, err))
}
#[pymethod]
fn recvfrom(&self, bufsize: usize, vm: &VirtualMachine) -> PyResult<(Vec<u8>, AddrTuple)> {
fn recvfrom(
&self,
bufsize: usize,
flags: OptionalArg<i32>,
vm: &VirtualMachine,
) -> PyResult<(Vec<u8>, AddrTuple)> {
let flags = flags.unwrap_or(0);
let mut buffer = vec![0u8; bufsize];
let (n, addr) = self
.sock()
.recv_from(&mut buffer)
.recv_from_with_flags(&mut buffer, flags)
.map_err(|err| convert_sock_error(vm, err))?;
buffer.truncate(n);
Ok((buffer, get_addr_tuple(addr)))
}
#[pymethod]
fn send(&self, bytes: PyBytesLike, vm: &VirtualMachine) -> PyResult<usize> {
fn send(
&self,
bytes: PyBytesLike,
flags: OptionalArg<i32>,
vm: &VirtualMachine,
) -> PyResult<usize> {
let flags = flags.unwrap_or(0);
bytes
.with_ref(|b| self.sock().send(b))
.with_ref(|b| self.sock().send_with_flags(b, flags))
.map_err(|err| convert_sock_error(vm, err))
}
#[pymethod]
fn sendall(&self, bytes: PyBytesLike, vm: &VirtualMachine) -> PyResult<()> {
fn sendall(
&self,
bytes: PyBytesLike,
flags: OptionalArg<i32>,
vm: &VirtualMachine,
) -> PyResult<()> {
let flags = flags.unwrap_or(0);
let sock = self.sock();
bytes
.with_ref(|b| self.sock_mut().write_all(b))
.with_ref(|buf| py_io::write_all(buf, |b| sock.send_with_flags(b, flags)))
.map_err(|err| convert_sock_error(vm, err))
}
#[pymethod]
fn sendto(&self, bytes: PyBytesLike, address: Address, vm: &VirtualMachine) -> PyResult<()> {
fn sendto(
&self,
bytes: PyBytesLike,
address: Address,
flags: OptionalArg<i32>,
vm: &VirtualMachine,
) -> PyResult<()> {
let flags = flags.unwrap_or(0);
let addr = get_addr(vm, address, Some(self.family.load()))?;
bytes
.with_ref(|b| self.sock().send_to(b, &addr))
.with_ref(|b| self.sock().send_to_with_flags(b, &addr, flags))
.map_err(|err| convert_sock_error(vm, err))?;
Ok(())
}
@@ -411,15 +450,15 @@ impl PySocket {
impl io::Read for PySocketRef {
fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
<Socket as io::Read>::read(&mut self.sock_mut(), buf)
<&Socket as io::Read>::read(&mut &*self.sock(), buf)
}
}
impl io::Write for PySocketRef {
fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
<Socket as io::Write>::write(&mut self.sock_mut(), buf)
<&Socket as io::Write>::write(&mut &*self.sock(), buf)
}
fn flush(&mut self) -> io::Result<()> {
<Socket as io::Write>::flush(&mut self.sock_mut())
<&Socket as io::Write>::flush(&mut &*self.sock())
}
}
@@ -850,7 +889,8 @@ pub fn make_module(vm: &VirtualMachine) -> PyObjectRef {
"SO_REUSEADDR" => ctx.new_int(c::SO_REUSEADDR),
"SO_TYPE" => ctx.new_int(c::SO_TYPE),
"SO_BROADCAST" => ctx.new_int(c::SO_BROADCAST),
// "SO_EXCLUSIVEADDRUSE" => ctx.new_int(c::SO_EXCLUSIVEADDRUSE),
"SO_OOBINLINE" => ctx.new_int(c::SO_OOBINLINE),
"SO_ERROR" => ctx.new_int(c::SO_ERROR),
"TCP_NODELAY" => ctx.new_int(c::TCP_NODELAY),
"AI_ALL" => ctx.new_int(c::AI_ALL),
"AI_PASSIVE" => ctx.new_int(c::AI_PASSIVE),

View File

@@ -1,18 +1,19 @@
use super::os::PyPathLike;
use super::socket::PySocketRef;
use crate::builtins::bytearray::PyByteArrayRef;
use crate::builtins::pystr::PyStrRef;
use crate::builtins::{pytype::PyTypeRef, weakref::PyWeak};
use crate::byteslike::PyBytesLike;
use crate::common::lock::{PyRwLock, PyRwLockWriteGuard};
use crate::byteslike::{PyBytesLike, PyRwBytesLike};
use crate::common::lock::{PyRwLock, PyRwLockReadGuard, PyRwLockWriteGuard};
use crate::exceptions::{IntoPyException, PyBaseExceptionRef};
use crate::function::OptionalArg;
use crate::function::{OptionalArg, OptionalOption};
use crate::pyobject::{
BorrowValue, Either, IntoPyObject, ItemProtocol, PyClassImpl, PyObjectRef, PyRef, PyResult,
PyValue, StaticType,
BorrowValue, Either, IntoPyObject, ItemProtocol, PyCallable, PyClassImpl, PyObjectRef, PyRef,
PyResult, PyValue, StaticType,
};
use crate::types::create_simple_type;
use crate::VirtualMachine;
use crossbeam_utils::atomic::AtomicCell;
use foreign_types_shared::{ForeignType, ForeignTypeRef};
use openssl::{
asn1::{Asn1Object, Asn1ObjectRef},
@@ -24,6 +25,7 @@ use openssl::{
use std::convert::TryFrom;
use std::ffi::{CStr, CString};
use std::fmt;
use std::time::Instant;
mod sys {
#![allow(non_camel_case_types, unused)]
@@ -231,7 +233,7 @@ fn _ssl_rand_pseudo_bytes(n: i32, vm: &VirtualMachine) -> PyResult<(Vec<u8>, boo
#[pyclass(module = "ssl", name = "_SSLContext")]
struct PySslContext {
ctx: PyRwLock<SslContextBuilder>,
check_hostname: bool,
check_hostname: AtomicCell<bool>,
}
impl fmt::Debug for PySslContext {
@@ -246,6 +248,10 @@ impl PyValue for PySslContext {
}
}
fn builder_as_ctx(x: &SslContextBuilder) -> &ssl::SslContextRef {
unsafe { ssl::SslContextRef::from_ptr(x.as_ptr()) }
}
#[pyimpl(flags(BASETYPE))]
impl PySslContext {
fn builder(&self) -> PyRwLockWriteGuard<'_, SslContextBuilder> {
@@ -256,7 +262,7 @@ impl PySslContext {
F: Fn(&ssl::SslContextRef) -> R,
{
let c = self.ctx.read();
func(unsafe { &**(&*c as *const SslContextBuilder as *const ssl::SslContext) })
func(builder_as_ctx(&c))
}
fn ptr(&self) -> *mut sys::SSL_CTX {
(*self.ctx.write()).as_ptr()
@@ -309,7 +315,7 @@ impl PySslContext {
PySslContext {
ctx: PyRwLock::new(builder),
check_hostname,
check_hostname: AtomicCell::new(check_hostname),
}
.into_ref_with_type(vm, cls)
}
@@ -338,12 +344,22 @@ impl PySslContext {
unreachable!()
}
}
#[pyproperty]
fn options(&self) -> libc::c_ulong {
self.ctx.read().options().bits()
}
#[pyproperty(setter)]
fn set_options(&self, opts: libc::c_ulong) {
self.builder()
.set_options(SslOptions::from_bits_truncate(opts));
}
#[pyproperty(setter)]
fn set_verify_mode(&self, cert: i32, vm: &VirtualMachine) -> PyResult<()> {
let mut ctx = self.builder();
let cert_req = CertRequirements::try_from(cert)
.map_err(|_| vm.new_value_error("invalid value for verify_mode".to_owned()))?;
let mode = match cert_req {
CertRequirements::None if self.check_hostname => {
CertRequirements::None if self.check_hostname.load() => {
return Err(vm.new_value_error(
"Cannot set verify_mode to CERT_NONE when check_hostname is enabled."
.to_owned(),
@@ -353,9 +369,21 @@ impl PySslContext {
CertRequirements::Optional => SslVerifyMode::PEER,
CertRequirements::Required => SslVerifyMode::PEER | SslVerifyMode::FAIL_IF_NO_PEER_CERT,
};
self.builder().set_verify(mode);
ctx.set_verify(mode);
Ok(())
}
#[pyproperty]
fn check_hostname(&self) -> bool {
self.check_hostname.load()
}
#[pyproperty(setter)]
fn set_check_hostname(&self, ch: bool) {
let mut ctx = self.builder();
if ch && builder_as_ctx(&ctx).verify_mode() == SslVerifyMode::NONE {
ctx.set_verify(SslVerifyMode::PEER | SslVerifyMode::FAIL_IF_NO_PEER_CERT);
}
self.check_hostname.store(ch);
}
#[pymethod]
fn set_default_verify_paths(&self, vm: &VirtualMachine) -> PyResult<()> {
@@ -442,6 +470,30 @@ impl PySslContext {
Ok(vm.ctx.new_list(certs))
}
#[pymethod]
fn load_cert_chain(
&self,
certfile: PyPathLike,
keyfile: OptionalArg<PyPathLike>,
password: OptionalOption<Either<PyStrRef, PyCallable>>,
vm: &VirtualMachine,
) -> PyResult<()> {
// TODO: requires passing a callback to C
if password.flatten().is_some() {
return Err(vm.new_not_implemented_error("password arg not yet supported".to_owned()));
}
let mut ctx = self.builder();
ctx.set_certificate_chain_file(&certfile)
.and_then(|()| {
ctx.set_private_key_file(
keyfile.as_ref().unwrap_or(&certfile),
ssl::SslFiletype::PEM,
)
})
.and_then(|()| ctx.check_private_key())
.map_err(|e| convert_openssl_error(vm, e))
}
#[pymethod]
fn _wrap_socket(
zelf: PyRef<Self>,
@@ -471,7 +523,7 @@ impl PySslContext {
Ok(PySslSocket {
ctx: zelf,
stream: PyRwLock::new(Some(stream)),
stream: PyRwLock::new(stream),
socket_type,
server_hostname: args.server_hostname,
owner: PyRwLock::new(args.owner.as_ref().map(PyWeak::downgrade)),
@@ -507,7 +559,7 @@ struct LoadVerifyLocationsArgs {
#[pyclass(module = "ssl", name = "_SSLSocket")]
struct PySslSocket {
ctx: PyRef<PySslContext>,
stream: PyRwLock<Option<ssl::SslStreamBuilder<PySocketRef>>>,
stream: PyRwLock<ssl::SslStreamBuilder<PySocketRef>>,
socket_type: SslServerOrClient,
server_hostname: Option<PyStrRef>,
owner: PyRwLock<Option<PyWeak>>,
@@ -527,20 +579,19 @@ impl PyValue for PySslSocket {
#[pyimpl]
impl PySslSocket {
fn stream_builder(&self) -> ssl::SslStreamBuilder<PySocketRef> {
std::mem::replace(&mut *self.stream.write(), None).unwrap()
}
fn exec_stream<F, R>(&self, func: F) -> R
where
F: Fn(&mut ssl::SslStream<PySocketRef>) -> R,
{
let mut b = self.stream.write();
func(unsafe {
&mut *(b.as_mut().unwrap() as *mut ssl::SslStreamBuilder<_> as *mut ssl::SslStream<_>)
fn stream(&self) -> impl std::ops::Deref<Target = ssl::SslStream<PySocketRef>> + '_ {
let s = self.stream.read();
// SAFETY: SslStreamBuilder is just a wrapper around SslStream
PyRwLockReadGuard::map(s, |s| unsafe {
&*(s as *const _ as *const ssl::SslStream<_>)
})
}
fn set_stream(&self, stream: ssl::SslStream<PySocketRef>) {
*self.stream.write() = Some(unsafe { std::mem::transmute(stream) });
fn stream_mut(&self) -> impl std::ops::DerefMut<Target = ssl::SslStream<PySocketRef>> + '_ {
let s = self.stream.write();
// SAFETY: SslStreamBuilder is just a wrapper around SslStream
PyRwLockWriteGuard::map(s, |s| unsafe {
&mut *(s as *mut _ as *mut ssl::SslStream<_>)
})
}
#[pyproperty]
@@ -571,35 +622,58 @@ impl PySslSocket {
vm: &VirtualMachine,
) -> PyResult<Option<PyObjectRef>> {
let binary = binary.unwrap_or(false);
if !self.exec_stream(|stream| stream.ssl().is_init_finished()) {
let stream = self.stream();
if !stream.ssl().is_init_finished() {
return Err(vm.new_value_error("handshake not done yet".to_owned()));
}
self.exec_stream(|stream| stream.ssl().peer_certificate())
stream
.ssl()
.peer_certificate()
.map(|cert| cert_to_py(vm, &cert, binary))
.transpose()
}
#[pymethod]
fn do_handshake(&self, vm: &VirtualMachine) -> PyResult<()> {
// Either a stream builder or a mid-handshake stream from WANT_READ or WANT_WRITE
let mut handshaker: Either<_, ssl::MidHandshakeSslStream<_>> =
Either::A(self.stream_builder());
let stream_builder = self.stream.write();
let timeout = stream_builder
.get_ref()
.sock()
.read_timeout()
.ok()
.flatten()
.map(|dur| (dur, Instant::now()));
let mut stream = unsafe { std::ptr::read(&*stream_builder) };
loop {
let handshake_result = match handshaker {
Either::A(s) => s.handshake(),
Either::B(s) => s.handshake(),
};
match handshake_result {
Ok(stream) => {
self.set_stream(stream);
match stream.handshake() {
Ok(s) => {
// s and stream_builder are the same thing
std::mem::forget(s);
return Ok(());
}
Err(ssl::HandshakeError::SetupFailure(e)) => {
return Err(convert_openssl_error(vm, e))
Err(ssl::HandshakeError::SetupFailure(_e)) => {
// handshake() error handling code never constructs this
unreachable!();
// return Err(convert_openssl_error(vm, e))
}
Err(ssl::HandshakeError::WouldBlock(s)) => {
std::mem::forget(s);
stream = unsafe { std::ptr::read(&*stream_builder) };
}
Err(ssl::HandshakeError::WouldBlock(s)) => handshaker = Either::B(s),
Err(ssl::HandshakeError::Failure(s)) => {
return Err(convert_ssl_error(vm, s.into_error()))
let err = convert_ssl_error(vm, s.error());
std::mem::forget(s);
return Err(err);
}
}
if let Some((timeout, ref start)) = timeout {
if start.elapsed() >= timeout {
std::mem::forget(stream);
let socket_timeout = vm.class("_socket", "timeout");
return Err(vm.new_exception_msg(
socket_timeout,
"The handshake operation timed out".to_owned(),
));
}
}
}
@@ -607,25 +681,39 @@ impl PySslSocket {
#[pymethod]
fn write(&self, data: PyBytesLike, vm: &VirtualMachine) -> PyResult<usize> {
data.with_ref(|b| self.exec_stream(|stream| stream.ssl_write(b)))
let mut stream = self.stream_mut();
data.with_ref(|b| stream.ssl_write(b))
.map_err(|e| convert_ssl_error(vm, e))
}
#[pymethod]
fn read(&self, n: usize, buffer: OptionalArg<PyByteArrayRef>, vm: &VirtualMachine) -> PyResult {
if let OptionalArg::Present(buffer) = buffer {
let n = self
.exec_stream(|stream| {
let mut buf = buffer.borrow_value_mut();
stream.ssl_read(&mut buf.elements)
})
.map_err(|e| convert_ssl_error(vm, e))?;
Ok(vm.ctx.new_int(n))
fn read(&self, n: usize, buffer: OptionalArg<PyRwBytesLike>, vm: &VirtualMachine) -> PyResult {
let mut stream = self.stream_mut();
let ret_nread = buffer.is_present();
let ssl_res = if let OptionalArg::Present(buffer) = buffer {
buffer.with_ref(|buf| stream.ssl_read(buf).map(|n| vm.ctx.new_int(n)))
} else {
let mut buf = vec![0u8; n];
buf.truncate(n);
Ok(vm.ctx.new_bytes(buf))
}
stream.ssl_read(&mut buf).map(|n| {
buf.truncate(n);
vm.ctx.new_bytes(buf)
})
};
ssl_res.or_else(|e| {
if e.code() == ssl::ErrorCode::ZERO_RETURN
&& stream.get_shutdown() == ssl::ShutdownState::RECEIVED
{
Ok(if ret_nread {
vm.ctx.new_int(0)
} else {
vm.ctx.new_bytes(vec![])
})
} else {
Err(convert_ssl_error(vm, e))
}
})
// .map_err(|e| convert_ssl_error(vm, e))?;
}
}
@@ -645,15 +733,28 @@ fn convert_openssl_error(vm: &VirtualMachine, err: ErrorStack) -> PyBaseExceptio
// );
// TODO: map the error codes to code names, e.g. "CERTIFICATE_VERIFY_FAILED", just requires a big hashmap/dict
let msg = e.to_string();
vm.new_exception_msg(cls, msg)
vm.new_exception(cls, vec![vm.ctx.new_int(e.code()), vm.ctx.new_str(msg)])
}
None => vm.new_exception_empty(cls),
}
}
fn convert_ssl_error(vm: &VirtualMachine, e: ssl::Error) -> PyBaseExceptionRef {
match e.into_io_error() {
Ok(io_err) => io_err.into_pyexception(vm),
Err(e) => convert_openssl_error(vm, e.ssl_error().unwrap().clone()),
fn convert_ssl_error(
vm: &VirtualMachine,
e: impl std::borrow::Borrow<ssl::Error>,
) -> PyBaseExceptionRef {
let e = e.borrow();
match e.io_error() {
Some(io_err) => io_err.into_pyexception(vm),
None => match e.ssl_error() {
Some(e) => convert_openssl_error(vm, e.clone()),
None => vm.new_exception(
ssl_error(vm),
vec![
vm.ctx.new_int(e.code().as_raw()),
vm.ctx.new_str(e.to_string()),
],
),
},
}
}
@@ -805,7 +906,7 @@ pub fn make_module(vm: &VirtualMachine) -> PyObjectRef {
"SSL_ERROR_SYSCALL" => ctx.new_int(sys::SSL_ERROR_SYSCALL),
"SSL_ERROR_SSL" => ctx.new_int(sys::SSL_ERROR_SSL),
"SSL_ERROR_WANT_CONNECT" => ctx.new_int(sys::SSL_ERROR_WANT_CONNECT),
// "SSL_ERROR_EOF" => ctx.new_int(sys::SSL_ERROR_EOF),
"SSL_ERROR_EOF" => ctx.new_int(8), // custom for python
// "SSL_ERROR_INVALID_ERROR_CODE" => ctx.new_int(sys::SSL_ERROR_INVALID_ERROR_CODE),
// TODO: so many more of these
"ALERT_DESCRIPTION_DECODE_ERROR" => ctx.new_int(sys::SSL_AD_DECODE_ERROR),