Merge lp:~exarkun/pyopenssl/mem-bio into lp:~exarkun/pyopenssl/trunk
- mem-bio
- Merge into trunk
Proposed by
Jean-Paul Calderone
Status: | Merged | ||||
---|---|---|---|---|---|
Merged at revision: | not available | ||||
Proposed branch: | lp:~exarkun/pyopenssl/mem-bio | ||||
Merge into: | lp:~exarkun/pyopenssl/trunk | ||||
Diff against target: | None lines | ||||
To merge this branch: | bzr merge lp:~exarkun/pyopenssl/mem-bio | ||||
Related bugs: |
|
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Jean-Paul Calderone | Pending | ||
Review via email: mp+6225@code.launchpad.net |
Commit message
Description of the change
To post a comment you must log in.
lp:~exarkun/pyopenssl/mem-bio
updated
- 110. By Jean-Paul Calderone
-
Make bio_shutdown raise an exception when called on a socket-based Connection
Preview Diff
[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1 | === modified file 'doc/pyOpenSSL.tex' | |||
2 | --- doc/pyOpenSSL.tex 2009-04-25 12:30:11 +0000 | |||
3 | +++ doc/pyOpenSSL.tex 2009-05-03 23:45:07 +0000 | |||
4 | @@ -681,10 +681,12 @@ | |||
5 | 681 | \end{datadesc} | 681 | \end{datadesc} |
6 | 682 | 682 | ||
7 | 683 | \begin{funcdesc}{Connection}{context, socket} | 683 | \begin{funcdesc}{Connection}{context, socket} |
9 | 684 | Factory fucnction that creates a new Connection object given an SSL context and | 684 | Factory function that creates a new Connection object given an SSL context and |
10 | 685 | a socket \footnote{Actually, all that is required is an object that | 685 | a socket \footnote{Actually, all that is required is an object that |
13 | 686 | \emph{behaves} like a socket, you could even use files, even though it'd be | 686 | \emph{behaves} like a socket, you could even use files, even though it'd be |
14 | 687 | tricky to get the handshakes right!} object. | 687 | tricky to get the handshakes right!} object. \var{socket} may be \var{None}; |
15 | 688 | in this case, the Connection is created with a memory BIO: see the | ||
16 | 689 | \method{bio_read}, \method{bio_write}, and \method{bio_shutdown} methods. | ||
17 | 688 | \end{funcdesc} | 690 | \end{funcdesc} |
18 | 689 | 691 | ||
19 | 690 | \begin{excdesc}{Error} | 692 | \begin{excdesc}{Error} |
20 | @@ -978,6 +980,12 @@ | |||
21 | 978 | by \var{bufsize}. | 980 | by \var{bufsize}. |
22 | 979 | \end{methoddesc} | 981 | \end{methoddesc} |
23 | 980 | 982 | ||
24 | 983 | \begin{methoddesc}[Connection]{bio_write}{bytes} | ||
25 | 984 | If the Connection was created with a memory BIO, this method can be used to add | ||
26 | 985 | bytes to the read end of that memory BIO. The Connection can then read the | ||
27 | 986 | bytes (for example, in response to a call to \method{recv}). | ||
28 | 987 | \end{methoddesc} | ||
29 | 988 | |||
30 | 981 | \begin{methoddesc}[Connection]{renegotiate}{} | 989 | \begin{methoddesc}[Connection]{renegotiate}{} |
31 | 982 | Renegotiate the SSL session. Call this if you wish to change cipher suites or | 990 | Renegotiate the SSL session. Call this if you wish to change cipher suites or |
32 | 983 | anything like that. | 991 | anything like that. |
33 | @@ -987,6 +995,13 @@ | |||
34 | 987 | Send the \var{string} data to the Connection. | 995 | Send the \var{string} data to the Connection. |
35 | 988 | \end{methoddesc} | 996 | \end{methoddesc} |
36 | 989 | 997 | ||
37 | 998 | \begin{methoddesc}[Connection]{bio_read}{bufsize} | ||
38 | 999 | If the Connection was created with a memory BIO, this method can be used to | ||
39 | 1000 | read bytes from the write end of that memory BIO. Many Connection methods will | ||
40 | 1001 | add bytes which must be read in this manner or the buffer will eventually fill | ||
41 | 1002 | up and the Connection will be able to take no further actions. | ||
42 | 1003 | \end{methoddesc} | ||
43 | 1004 | |||
44 | 990 | \begin{methoddesc}[Connection]{sendall}{string} | 1005 | \begin{methoddesc}[Connection]{sendall}{string} |
45 | 991 | Send all of the \var{string} data to the Connection. This calls \method{send} | 1006 | Send all of the \var{string} data to the Connection. This calls \method{send} |
46 | 992 | repeatedly until all data is sent. If an error occurs, it's impossible to tell | 1007 | repeatedly until all data is sent. If an error occurs, it's impossible to tell |
47 | @@ -1037,10 +1052,28 @@ | |||
48 | 1037 | Call the \method{shutdown} method of the underlying socket. | 1052 | Call the \method{shutdown} method of the underlying socket. |
49 | 1038 | \end{methoddesc} | 1053 | \end{methoddesc} |
50 | 1039 | 1054 | ||
51 | 1055 | \begin{methoddesc}[Connection]{bio_shutdown}{} | ||
52 | 1056 | If the Connection was created with a memory BIO, this method can be used to | ||
53 | 1057 | indicate that ``end of file'' has been reached on the read end of that memory | ||
54 | 1058 | BIO. | ||
55 | 1059 | \end{methoddesc} | ||
56 | 1060 | |||
57 | 1040 | \begin{methoddesc}[Connection]{state_string}{} | 1061 | \begin{methoddesc}[Connection]{state_string}{} |
58 | 1041 | Retrieve a verbose string detailing the state of the Connection. | 1062 | Retrieve a verbose string detailing the state of the Connection. |
59 | 1042 | \end{methoddesc} | 1063 | \end{methoddesc} |
60 | 1043 | 1064 | ||
61 | 1065 | \begin{methoddesc}[Connection]{client_random}{} | ||
62 | 1066 | Retrieve the random value used with the client hello message. | ||
63 | 1067 | \end{methoddesc} | ||
64 | 1068 | |||
65 | 1069 | \begin{methoddesc}[Connection]{server_random}{} | ||
66 | 1070 | Retrieve the random value used with the server hello message. | ||
67 | 1071 | \end{methoddesc} | ||
68 | 1072 | |||
69 | 1073 | \begin{methoddesc}[Connection]{master_key}{} | ||
70 | 1074 | Retrieve the value of the master key for this session. | ||
71 | 1075 | \end{methoddesc} | ||
72 | 1076 | |||
73 | 1044 | \begin{methoddesc}[Connection]{want_read}{} | 1077 | \begin{methoddesc}[Connection]{want_read}{} |
74 | 1045 | Checks if more data has to be read from the transport layer to complete an | 1078 | Checks if more data has to be read from the transport layer to complete an |
75 | 1046 | operation. | 1079 | operation. |
76 | 1047 | 1080 | ||
77 | === modified file 'src/ssl/connection.c' | |||
78 | --- src/ssl/connection.c 2008-03-21 22:31:12 +0000 | |||
79 | +++ src/ssl/connection.c 2009-05-01 00:24:35 +0000 | |||
80 | @@ -23,8 +23,8 @@ | |||
81 | 23 | #endif | 23 | #endif |
82 | 24 | 24 | ||
83 | 25 | #define SSL_MODULE | 25 | #define SSL_MODULE |
84 | 26 | #include <openssl/bio.h> | ||
85 | 26 | #include <openssl/err.h> | 27 | #include <openssl/err.h> |
86 | 27 | |||
87 | 28 | #include "ssl.h" | 28 | #include "ssl.h" |
88 | 29 | 29 | ||
89 | 30 | /** | 30 | /** |
90 | @@ -125,6 +125,50 @@ | |||
91 | 125 | } | 125 | } |
92 | 126 | 126 | ||
93 | 127 | /* | 127 | /* |
94 | 128 | * Handle errors raised by BIO functions. | ||
95 | 129 | * | ||
96 | 130 | * Arguments: bio - The BIO object | ||
97 | 131 | * ret - The return value of the BIO_ function. | ||
98 | 132 | * Returns: None, the calling function should return NULL; | ||
99 | 133 | */ | ||
100 | 134 | static void | ||
101 | 135 | handle_bio_errors(BIO* bio, int ret) | ||
102 | 136 | { | ||
103 | 137 | if (BIO_should_retry(bio)) { | ||
104 | 138 | if (BIO_should_read(bio)) { | ||
105 | 139 | PyErr_SetNone(ssl_WantReadError); | ||
106 | 140 | } else if (BIO_should_write(bio)) { | ||
107 | 141 | PyErr_SetNone(ssl_WantWriteError); | ||
108 | 142 | } else if (BIO_should_io_special(bio)) { | ||
109 | 143 | /* | ||
110 | 144 | * It's somewhat unclear what this means. From the OpenSSL source, | ||
111 | 145 | * it seems like it should not be triggered by the memory BIO, so | ||
112 | 146 | * for the time being, this case shouldn't come up. The SSL BIO | ||
113 | 147 | * (which I think should be named the socket BIO) may trigger this | ||
114 | 148 | * case if its socket is not yet connected or it is busy doing | ||
115 | 149 | * something related to x509. | ||
116 | 150 | */ | ||
117 | 151 | PyErr_SetString(PyExc_ValueError, "BIO_should_io_special"); | ||
118 | 152 | } else { | ||
119 | 153 | /* | ||
120 | 154 | * I hope this is dead code. The BIO documentation suggests that | ||
121 | 155 | * one of the above three checks should always be true. | ||
122 | 156 | */ | ||
123 | 157 | PyErr_SetString(PyExc_ValueError, "unknown bio failure"); | ||
124 | 158 | } | ||
125 | 159 | } else { | ||
126 | 160 | /* | ||
127 | 161 | * If we aren't to retry, it's really an error, so fall back to the | ||
128 | 162 | * normal error reporting code. However, the BIO interface does not | ||
129 | 163 | * specify a uniform error reporting mechanism. We can only hope that | ||
130 | 164 | * the code which triggered the error also kindly pushed something onto | ||
131 | 165 | * the error stack. | ||
132 | 166 | */ | ||
133 | 167 | exception_from_error_queue(); | ||
134 | 168 | } | ||
135 | 169 | } | ||
136 | 170 | |||
137 | 171 | /* | ||
138 | 128 | * Handle errors raised by SSL I/O functions. NOTE: Not SSL_shutdown ;) | 172 | * Handle errors raised by SSL I/O functions. NOTE: Not SSL_shutdown ;) |
139 | 129 | * | 173 | * |
140 | 130 | * Arguments: ssl - The SSL object | 174 | * Arguments: ssl - The SSL object |
141 | @@ -239,6 +283,49 @@ | |||
142 | 239 | return PyInt_FromLong((long)ret); | 283 | return PyInt_FromLong((long)ret); |
143 | 240 | } | 284 | } |
144 | 241 | 285 | ||
145 | 286 | static char ssl_Connection_bio_write_doc[] = "\n\ | ||
146 | 287 | When using non-socket connections this function sends\n\ | ||
147 | 288 | \"dirty\" data that would have traveled in on the network.\n\ | ||
148 | 289 | \n\ | ||
149 | 290 | Arguments: self - The Connection object\n\ | ||
150 | 291 | args - The Python argument tuple, should be:\n\ | ||
151 | 292 | buf - The string to bio_write\n\ | ||
152 | 293 | Returns: The number of bytes written\n\ | ||
153 | 294 | "; | ||
154 | 295 | static PyObject * | ||
155 | 296 | ssl_Connection_bio_write(ssl_ConnectionObj *self, PyObject *args) | ||
156 | 297 | { | ||
157 | 298 | char *buf; | ||
158 | 299 | int len, ret; | ||
159 | 300 | |||
160 | 301 | if(self->into_ssl == NULL) | ||
161 | 302 | { | ||
162 | 303 | PyErr_SetString(PyExc_TypeError, "Connection sock was not None"); | ||
163 | 304 | return NULL; | ||
164 | 305 | } | ||
165 | 306 | |||
166 | 307 | if (!PyArg_ParseTuple(args, "s#|i:bio_write", &buf, &len)) | ||
167 | 308 | return NULL; | ||
168 | 309 | |||
169 | 310 | ret = BIO_write(self->into_ssl, buf, len); | ||
170 | 311 | |||
171 | 312 | if (PyErr_Occurred()) | ||
172 | 313 | { | ||
173 | 314 | flush_error_queue(); | ||
174 | 315 | return NULL; | ||
175 | 316 | } | ||
176 | 317 | |||
177 | 318 | if (ret <= 0) { | ||
178 | 319 | /* | ||
179 | 320 | * There was a problem with the BIO_write of some sort. | ||
180 | 321 | */ | ||
181 | 322 | handle_bio_errors(self->into_ssl, ret); | ||
182 | 323 | return NULL; | ||
183 | 324 | } | ||
184 | 325 | |||
185 | 326 | return PyInt_FromLong((long)ret); | ||
186 | 327 | } | ||
187 | 328 | |||
188 | 242 | static char ssl_Connection_send_doc[] = "\n\ | 329 | static char ssl_Connection_send_doc[] = "\n\ |
189 | 243 | Send data on the connection. NOTE: If you get one of the WantRead,\n\ | 330 | Send data on the connection. NOTE: If you get one of the WantRead,\n\ |
190 | 244 | WantWrite or WantX509Lookup exceptions on this, you have to call the\n\ | 331 | WantWrite or WantX509Lookup exceptions on this, you have to call the\n\ |
191 | @@ -384,6 +471,63 @@ | |||
192 | 384 | } | 471 | } |
193 | 385 | } | 472 | } |
194 | 386 | 473 | ||
195 | 474 | static char ssl_Connection_bio_read_doc[] = "\n\ | ||
196 | 475 | When using non-socket connections this function reads\n\ | ||
197 | 476 | the \"dirty\" data that would have traveled away on the network.\n\ | ||
198 | 477 | \n\ | ||
199 | 478 | Arguments: self - The Connection object\n\ | ||
200 | 479 | args - The Python argument tuple, should be:\n\ | ||
201 | 480 | bufsiz - The maximum number of bytes to read\n\ | ||
202 | 481 | Returns: The string read.\n\ | ||
203 | 482 | "; | ||
204 | 483 | static PyObject * | ||
205 | 484 | ssl_Connection_bio_read(ssl_ConnectionObj *self, PyObject *args) | ||
206 | 485 | { | ||
207 | 486 | int bufsiz, ret; | ||
208 | 487 | PyObject *buf; | ||
209 | 488 | |||
210 | 489 | if(self->from_ssl == NULL) | ||
211 | 490 | { | ||
212 | 491 | PyErr_SetString(PyExc_TypeError, "Connection sock was not None"); | ||
213 | 492 | return NULL; | ||
214 | 493 | } | ||
215 | 494 | |||
216 | 495 | if (!PyArg_ParseTuple(args, "i:bio_read", &bufsiz)) | ||
217 | 496 | return NULL; | ||
218 | 497 | |||
219 | 498 | buf = PyString_FromStringAndSize(NULL, bufsiz); | ||
220 | 499 | if (buf == NULL) | ||
221 | 500 | return NULL; | ||
222 | 501 | |||
223 | 502 | ret = BIO_read(self->from_ssl, PyString_AsString(buf), bufsiz); | ||
224 | 503 | |||
225 | 504 | if (PyErr_Occurred()) | ||
226 | 505 | { | ||
227 | 506 | Py_DECREF(buf); | ||
228 | 507 | flush_error_queue(); | ||
229 | 508 | return NULL; | ||
230 | 509 | } | ||
231 | 510 | |||
232 | 511 | if (ret <= 0) { | ||
233 | 512 | /* | ||
234 | 513 | * There was a problem with the BIO_read of some sort. | ||
235 | 514 | */ | ||
236 | 515 | handle_bio_errors(self->from_ssl, ret); | ||
237 | 516 | Py_DECREF(buf); | ||
238 | 517 | return NULL; | ||
239 | 518 | } | ||
240 | 519 | |||
241 | 520 | /* | ||
242 | 521 | * Shrink the string to match the number of bytes we actually read. | ||
243 | 522 | */ | ||
244 | 523 | if (ret != bufsiz && _PyString_Resize(&buf, ret) < 0) | ||
245 | 524 | { | ||
246 | 525 | Py_DECREF(buf); | ||
247 | 526 | return NULL; | ||
248 | 527 | } | ||
249 | 528 | return buf; | ||
250 | 529 | } | ||
251 | 530 | |||
252 | 387 | static char ssl_Connection_renegotiate_doc[] = "\n\ | 531 | static char ssl_Connection_renegotiate_doc[] = "\n\ |
253 | 388 | Renegotiate the session\n\ | 532 | Renegotiate the session\n\ |
254 | 389 | \n\ | 533 | \n\ |
255 | @@ -626,6 +770,25 @@ | |||
256 | 626 | return tuple; | 770 | return tuple; |
257 | 627 | } | 771 | } |
258 | 628 | 772 | ||
259 | 773 | static char ssl_Connection_bio_shutdown_doc[] = "\n\ | ||
260 | 774 | When using non-socket connections this function signals end of\n\ | ||
261 | 775 | data on the input for this connection.\n\ | ||
262 | 776 | \n\ | ||
263 | 777 | Arguments: self - The Connection object\n\ | ||
264 | 778 | args - The Python argument tuple, should be empty.\n\ | ||
265 | 779 | Returns: Nothing\n\ | ||
266 | 780 | "; | ||
267 | 781 | |||
268 | 782 | static PyObject * | ||
269 | 783 | ssl_Connection_bio_shutdown(ssl_ConnectionObj *self, PyObject *args) | ||
270 | 784 | { | ||
271 | 785 | BIO_set_mem_eof_return(self->into_ssl, 0); | ||
272 | 786 | Py_INCREF(Py_None); | ||
273 | 787 | return Py_None; | ||
274 | 788 | } | ||
275 | 789 | |||
276 | 790 | |||
277 | 791 | |||
278 | 629 | static char ssl_Connection_shutdown_doc[] = "\n\ | 792 | static char ssl_Connection_shutdown_doc[] = "\n\ |
279 | 630 | Send closure alert\n\ | 793 | Send closure alert\n\ |
280 | 631 | \n\ | 794 | \n\ |
281 | @@ -810,6 +973,66 @@ | |||
282 | 810 | return PyString_FromString(SSL_state_string_long(self->ssl)); | 973 | return PyString_FromString(SSL_state_string_long(self->ssl)); |
283 | 811 | } | 974 | } |
284 | 812 | 975 | ||
285 | 976 | static char ssl_Connection_client_random_doc[] = "\n\ | ||
286 | 977 | Get a copy of the client hello nonce.\n\ | ||
287 | 978 | \n\ | ||
288 | 979 | Arguments: self - The Connection object\n\ | ||
289 | 980 | args - The Python argument tuple, should be empty\n\ | ||
290 | 981 | Returns: A string representing the state\n\ | ||
291 | 982 | "; | ||
292 | 983 | static PyObject * | ||
293 | 984 | ssl_Connection_client_random(ssl_ConnectionObj *self, PyObject *args) | ||
294 | 985 | { | ||
295 | 986 | if (!PyArg_ParseTuple(args, ":client_random")) | ||
296 | 987 | return NULL; | ||
297 | 988 | |||
298 | 989 | if( self->ssl->session == NULL) { | ||
299 | 990 | Py_INCREF(Py_None); | ||
300 | 991 | return Py_None; | ||
301 | 992 | } | ||
302 | 993 | return PyString_FromStringAndSize( (const char *) self->ssl->s3->client_random, SSL3_RANDOM_SIZE); | ||
303 | 994 | } | ||
304 | 995 | |||
305 | 996 | static char ssl_Connection_server_random_doc[] = "\n\ | ||
306 | 997 | Get a copy of the server hello nonce.\n\ | ||
307 | 998 | \n\ | ||
308 | 999 | Arguments: self - The Connection object\n\ | ||
309 | 1000 | args - The Python argument tuple, should be empty\n\ | ||
310 | 1001 | Returns: A string representing the state\n\ | ||
311 | 1002 | "; | ||
312 | 1003 | static PyObject * | ||
313 | 1004 | ssl_Connection_server_random(ssl_ConnectionObj *self, PyObject *args) | ||
314 | 1005 | { | ||
315 | 1006 | if (!PyArg_ParseTuple(args, ":server_random")) | ||
316 | 1007 | return NULL; | ||
317 | 1008 | |||
318 | 1009 | if( self->ssl->session == NULL) { | ||
319 | 1010 | Py_INCREF(Py_None); | ||
320 | 1011 | return Py_None; | ||
321 | 1012 | } | ||
322 | 1013 | return PyString_FromStringAndSize( (const char *) self->ssl->s3->server_random, SSL3_RANDOM_SIZE); | ||
323 | 1014 | } | ||
324 | 1015 | |||
325 | 1016 | static char ssl_Connection_master_key_doc[] = "\n\ | ||
326 | 1017 | Get a copy of the master key.\n\ | ||
327 | 1018 | \n\ | ||
328 | 1019 | Arguments: self - The Connection object\n\ | ||
329 | 1020 | args - The Python argument tuple, should be empty\n\ | ||
330 | 1021 | Returns: A string representing the state\n\ | ||
331 | 1022 | "; | ||
332 | 1023 | static PyObject * | ||
333 | 1024 | ssl_Connection_master_key(ssl_ConnectionObj *self, PyObject *args) | ||
334 | 1025 | { | ||
335 | 1026 | if (!PyArg_ParseTuple(args, ":master_key")) | ||
336 | 1027 | return NULL; | ||
337 | 1028 | |||
338 | 1029 | if( self->ssl->session == NULL) { | ||
339 | 1030 | Py_INCREF(Py_None); | ||
340 | 1031 | return Py_None; | ||
341 | 1032 | } | ||
342 | 1033 | return PyString_FromStringAndSize( (const char *) self->ssl->session->master_key, self->ssl->session->master_key_length); | ||
343 | 1034 | } | ||
344 | 1035 | |||
345 | 813 | static char ssl_Connection_sock_shutdown_doc[] = "\n\ | 1036 | static char ssl_Connection_sock_shutdown_doc[] = "\n\ |
346 | 814 | See shutdown(2)\n\ | 1037 | See shutdown(2)\n\ |
347 | 815 | \n\ | 1038 | \n\ |
348 | @@ -912,6 +1135,8 @@ | |||
349 | 912 | ADD_METHOD(sendall), | 1135 | ADD_METHOD(sendall), |
350 | 913 | ADD_METHOD(recv), | 1136 | ADD_METHOD(recv), |
351 | 914 | ADD_ALIAS (read, recv), | 1137 | ADD_ALIAS (read, recv), |
352 | 1138 | ADD_METHOD(bio_read), | ||
353 | 1139 | ADD_METHOD(bio_write), | ||
354 | 915 | ADD_METHOD(renegotiate), | 1140 | ADD_METHOD(renegotiate), |
355 | 916 | ADD_METHOD(do_handshake), | 1141 | ADD_METHOD(do_handshake), |
356 | 917 | #if defined(OPENSSL_VERSION_NUMBER) && OPENSSL_VERSION_NUMBER >= 0x00907000L | 1142 | #if defined(OPENSSL_VERSION_NUMBER) && OPENSSL_VERSION_NUMBER >= 0x00907000L |
357 | @@ -921,6 +1146,7 @@ | |||
358 | 921 | ADD_METHOD(connect), | 1146 | ADD_METHOD(connect), |
359 | 922 | ADD_METHOD(connect_ex), | 1147 | ADD_METHOD(connect_ex), |
360 | 923 | ADD_METHOD(accept), | 1148 | ADD_METHOD(accept), |
361 | 1149 | ADD_METHOD(bio_shutdown), | ||
362 | 924 | ADD_METHOD(shutdown), | 1150 | ADD_METHOD(shutdown), |
363 | 925 | ADD_METHOD(get_cipher_list), | 1151 | ADD_METHOD(get_cipher_list), |
364 | 926 | ADD_METHOD(makefile), | 1152 | ADD_METHOD(makefile), |
365 | @@ -929,6 +1155,9 @@ | |||
366 | 929 | ADD_METHOD(get_shutdown), | 1155 | ADD_METHOD(get_shutdown), |
367 | 930 | ADD_METHOD(set_shutdown), | 1156 | ADD_METHOD(set_shutdown), |
368 | 931 | ADD_METHOD(state_string), | 1157 | ADD_METHOD(state_string), |
369 | 1158 | ADD_METHOD(server_random), | ||
370 | 1159 | ADD_METHOD(client_random), | ||
371 | 1160 | ADD_METHOD(master_key), | ||
372 | 932 | ADD_METHOD(sock_shutdown), | 1161 | ADD_METHOD(sock_shutdown), |
373 | 933 | ADD_METHOD(get_peer_certificate), | 1162 | ADD_METHOD(get_peer_certificate), |
374 | 934 | ADD_METHOD(want_read), | 1163 | ADD_METHOD(want_read), |
375 | @@ -965,26 +1194,50 @@ | |||
376 | 965 | self->socket = sock; | 1194 | self->socket = sock; |
377 | 966 | 1195 | ||
378 | 967 | self->ssl = NULL; | 1196 | self->ssl = NULL; |
379 | 1197 | self->from_ssl = NULL; | ||
380 | 1198 | self->into_ssl = NULL; | ||
381 | 968 | 1199 | ||
382 | 969 | Py_INCREF(Py_None); | 1200 | Py_INCREF(Py_None); |
383 | 970 | self->app_data = Py_None; | 1201 | self->app_data = Py_None; |
384 | 971 | 1202 | ||
385 | 972 | self->tstate = NULL; | 1203 | self->tstate = NULL; |
386 | 973 | 1204 | ||
387 | 974 | fd = PyObject_AsFileDescriptor(self->socket); | ||
388 | 975 | if (fd < 0) | ||
389 | 976 | { | ||
390 | 977 | Py_DECREF(self); | ||
391 | 978 | return NULL; | ||
392 | 979 | } | ||
393 | 980 | |||
394 | 981 | self->ssl = SSL_new(self->context->ctx); | 1205 | self->ssl = SSL_new(self->context->ctx); |
395 | 982 | SSL_set_app_data(self->ssl, self); | 1206 | SSL_set_app_data(self->ssl, self); |
397 | 983 | SSL_set_fd(self->ssl, (SOCKET_T)fd); | 1207 | |
398 | 1208 | if(self->socket == Py_None) | ||
399 | 1209 | { | ||
400 | 1210 | /* If it's not a socket or file, treat it like a memory buffer, | ||
401 | 1211 | * so crazy people can do things like EAP-TLS. */ | ||
402 | 1212 | self->into_ssl = BIO_new(BIO_s_mem()); | ||
403 | 1213 | self->from_ssl = BIO_new(BIO_s_mem()); | ||
404 | 1214 | if(self->into_ssl == NULL || self->from_ssl == NULL) | ||
405 | 1215 | goto error; | ||
406 | 1216 | SSL_set_bio(self->ssl, self->into_ssl, self->from_ssl); | ||
407 | 1217 | } | ||
408 | 1218 | else | ||
409 | 1219 | { | ||
410 | 1220 | fd = PyObject_AsFileDescriptor(self->socket); | ||
411 | 1221 | if (fd < 0) | ||
412 | 1222 | { | ||
413 | 1223 | Py_DECREF(self); | ||
414 | 1224 | return NULL; | ||
415 | 1225 | } | ||
416 | 1226 | else | ||
417 | 1227 | { | ||
418 | 1228 | SSL_set_fd(self->ssl, (SOCKET_T)fd); | ||
419 | 1229 | } | ||
420 | 1230 | } | ||
421 | 984 | 1231 | ||
422 | 985 | PyObject_GC_Track(self); | 1232 | PyObject_GC_Track(self); |
423 | 986 | 1233 | ||
424 | 987 | return self; | 1234 | return self; |
425 | 1235 | |||
426 | 1236 | error: | ||
427 | 1237 | BIO_free(self->into_ssl); /* NULL safe */ | ||
428 | 1238 | BIO_free(self->from_ssl); /* NULL safe */ | ||
429 | 1239 | Py_DECREF(self); | ||
430 | 1240 | return NULL; | ||
431 | 988 | } | 1241 | } |
432 | 989 | 1242 | ||
433 | 990 | /* | 1243 | /* |
434 | @@ -1050,6 +1303,8 @@ | |||
435 | 1050 | self->socket = NULL; | 1303 | self->socket = NULL; |
436 | 1051 | Py_XDECREF(self->app_data); | 1304 | Py_XDECREF(self->app_data); |
437 | 1052 | self->app_data = NULL; | 1305 | self->app_data = NULL; |
438 | 1306 | self->into_ssl = NULL; /* was cleaned up by SSL_free() */ | ||
439 | 1307 | self->from_ssl = NULL; /* was cleaned up by SSL_free() */ | ||
440 | 1053 | return 0; | 1308 | return 0; |
441 | 1054 | } | 1309 | } |
442 | 1055 | 1310 | ||
443 | 1056 | 1311 | ||
444 | === modified file 'src/ssl/connection.h' | |||
445 | --- src/ssl/connection.h 2008-09-21 21:42:34 +0000 | |||
446 | +++ src/ssl/connection.h 2009-04-01 19:09:23 +0000 | |||
447 | @@ -44,6 +44,7 @@ | |||
448 | 44 | PyObject *socket; | 44 | PyObject *socket; |
449 | 45 | PyThreadState *tstate; /* This field is no longer used. */ | 45 | PyThreadState *tstate; /* This field is no longer used. */ |
450 | 46 | PyObject *app_data; | 46 | PyObject *app_data; |
451 | 47 | BIO *into_ssl, *from_ssl; /* for connections without file descriptors */ | ||
452 | 47 | } ssl_ConnectionObj; | 48 | } ssl_ConnectionObj; |
453 | 48 | 49 | ||
454 | 49 | 50 | ||
455 | 50 | 51 | ||
456 | === modified file 'test/test_crypto.py' | |||
457 | --- test/test_crypto.py 2009-04-01 18:42:32 +0000 | |||
458 | +++ test/test_crypto.py 2009-05-04 22:27:52 +0000 | |||
459 | @@ -732,7 +732,7 @@ | |||
460 | 732 | Run the command line openssl tool with the given arguments and write | 732 | Run the command line openssl tool with the given arguments and write |
461 | 733 | the given PEM to its stdin. | 733 | the given PEM to its stdin. |
462 | 734 | """ | 734 | """ |
464 | 735 | write, read = popen2(" ".join(("openssl",) + args)) | 735 | write, read = popen2(" ".join(("openssl",) + args), "b") |
465 | 736 | write.write(pem) | 736 | write.write(pem) |
466 | 737 | write.close() | 737 | write.close() |
467 | 738 | return read.read() | 738 | return read.read() |
468 | 739 | 739 | ||
469 | === modified file 'test/test_ssl.py' | |||
470 | --- test/test_ssl.py 2009-04-01 16:34:06 +0000 | |||
471 | +++ test/test_ssl.py 2009-05-01 00:24:35 +0000 | |||
472 | @@ -15,12 +15,13 @@ | |||
473 | 15 | from twisted.trial.unittest import TestCase | 15 | from twisted.trial.unittest import TestCase |
474 | 16 | except ImportError: | 16 | except ImportError: |
475 | 17 | # Fall back to the stdlib TestCase though, since it kind of works. | 17 | # Fall back to the stdlib TestCase though, since it kind of works. |
477 | 18 | from unittest import TestCase, main | 18 | from unittest import TestCase |
478 | 19 | 19 | ||
479 | 20 | from OpenSSL.crypto import TYPE_RSA, FILETYPE_PEM, PKey, dump_privatekey, load_certificate, load_privatekey | 20 | from OpenSSL.crypto import TYPE_RSA, FILETYPE_PEM, PKey, dump_privatekey, load_certificate, load_privatekey |
480 | 21 | from OpenSSL.SSL import WantReadError, Context, Connection, Error | 21 | from OpenSSL.SSL import WantReadError, Context, Connection, Error |
481 | 22 | from OpenSSL.SSL import SSLv2_METHOD, SSLv3_METHOD, SSLv23_METHOD, TLSv1_METHOD | 22 | from OpenSSL.SSL import SSLv2_METHOD, SSLv3_METHOD, SSLv23_METHOD, TLSv1_METHOD |
483 | 23 | from OpenSSL.SSL import VERIFY_PEER | 23 | from OpenSSL.SSL import OP_NO_SSLv2, OP_NO_SSLv3, OP_SINGLE_DH_USE |
484 | 24 | from OpenSSL.SSL import VERIFY_PEER, VERIFY_FAIL_IF_NO_PEER_CERT, VERIFY_CLIENT_ONCE | ||
485 | 24 | from OpenSSL.test.test_crypto import _Python23TestCaseHelper, cleartextCertificatePEM, cleartextPrivateKeyPEM | 25 | from OpenSSL.test.test_crypto import _Python23TestCaseHelper, cleartextCertificatePEM, cleartextPrivateKeyPEM |
486 | 25 | try: | 26 | try: |
487 | 26 | from OpenSSL.SSL import OP_NO_QUERY_MTU | 27 | from OpenSSL.SSL import OP_NO_QUERY_MTU |
488 | @@ -313,6 +314,286 @@ | |||
489 | 313 | "OP_NO_TICKET unavailable - OpenSSL version may be too old" | 314 | "OP_NO_TICKET unavailable - OpenSSL version may be too old" |
490 | 314 | 315 | ||
491 | 315 | 316 | ||
495 | 316 | if __name__ == '__main__': | 317 | |
496 | 317 | main() | 318 | root_cert_pem = """-----BEGIN CERTIFICATE----- |
497 | 318 | 319 | MIIC7TCCAlagAwIBAgIIPQzE4MbeufQwDQYJKoZIhvcNAQEFBQAwWDELMAkGA1UE | |
498 | 320 | BhMCVVMxCzAJBgNVBAgTAklMMRAwDgYDVQQHEwdDaGljYWdvMRAwDgYDVQQKEwdU | ||
499 | 321 | ZXN0aW5nMRgwFgYDVQQDEw9UZXN0aW5nIFJvb3QgQ0EwIhgPMjAwOTAzMjUxMjM2 | ||
500 | 322 | NThaGA8yMDE3MDYxMTEyMzY1OFowWDELMAkGA1UEBhMCVVMxCzAJBgNVBAgTAklM | ||
501 | 323 | MRAwDgYDVQQHEwdDaGljYWdvMRAwDgYDVQQKEwdUZXN0aW5nMRgwFgYDVQQDEw9U | ||
502 | 324 | ZXN0aW5nIFJvb3QgQ0EwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAPmaQumL | ||
503 | 325 | urpE527uSEHdL1pqcDRmWzu+98Y6YHzT/J7KWEamyMCNZ6fRW1JCR782UQ8a07fy | ||
504 | 326 | 2xXsKy4WdKaxyG8CcatwmXvpvRQ44dSANMihHELpANTdyVp6DCysED6wkQFurHlF | ||
505 | 327 | 1dshEaJw8b/ypDhmbVIo6Ci1xvCJqivbLFnbAgMBAAGjgbswgbgwHQYDVR0OBBYE | ||
506 | 328 | FINVdy1eIfFJDAkk51QJEo3IfgSuMIGIBgNVHSMEgYAwfoAUg1V3LV4h8UkMCSTn | ||
507 | 329 | VAkSjch+BK6hXKRaMFgxCzAJBgNVBAYTAlVTMQswCQYDVQQIEwJJTDEQMA4GA1UE | ||
508 | 330 | BxMHQ2hpY2FnbzEQMA4GA1UEChMHVGVzdGluZzEYMBYGA1UEAxMPVGVzdGluZyBS | ||
509 | 331 | b290IENBggg9DMTgxt659DAMBgNVHRMEBTADAQH/MA0GCSqGSIb3DQEBBQUAA4GB | ||
510 | 332 | AGGCDazMJGoWNBpc03u6+smc95dEead2KlZXBATOdFT1VesY3+nUOqZhEhTGlDMi | ||
511 | 333 | hkgaZnzoIq/Uamidegk4hirsCT/R+6vsKAAxNTcBjUeZjlykCJWy5ojShGftXIKY | ||
512 | 334 | w/njVbKMXrvc83qmTdGl3TAM0fxQIpqgcglFLveEBgzn | ||
513 | 335 | -----END CERTIFICATE----- | ||
514 | 336 | """ | ||
515 | 337 | |||
516 | 338 | root_key_pem = """-----BEGIN RSA PRIVATE KEY----- | ||
517 | 339 | MIICXQIBAAKBgQD5mkLpi7q6ROdu7khB3S9aanA0Zls7vvfGOmB80/yeylhGpsjA | ||
518 | 340 | jWen0VtSQke/NlEPGtO38tsV7CsuFnSmschvAnGrcJl76b0UOOHUgDTIoRxC6QDU | ||
519 | 341 | 3claegwsrBA+sJEBbqx5RdXbIRGicPG/8qQ4Zm1SKOgotcbwiaor2yxZ2wIDAQAB | ||
520 | 342 | AoGBAPCgMpmLxzwDaUmcFbTJUvlLW1hoxNNYSu2jIZm1k/hRAcE60JYwvBkgz3UB | ||
521 | 343 | yMEh0AtLxYe0bFk6EHah11tMUPgscbCq73snJ++8koUw+csk22G65hOs51bVb7Aa | ||
522 | 344 | 6JBe67oLzdtvgCUFAA2qfrKzWRZzAdhUirQUZgySZk+Xq1pBAkEA/kZG0A6roTSM | ||
523 | 345 | BVnx7LnPfsycKUsTumorpXiylZJjTi9XtmzxhrYN6wgZlDOOwOLgSQhszGpxVoMD | ||
524 | 346 | u3gByT1b2QJBAPtL3mSKdvwRu/+40zaZLwvSJRxaj0mcE4BJOS6Oqs/hS1xRlrNk | ||
525 | 347 | PpQ7WJ4yM6ZOLnXzm2mKyxm50Mv64109FtMCQQDOqS2KkjHaLowTGVxwC0DijMfr | ||
526 | 348 | I9Lf8sSQk32J5VWCySWf5gGTfEnpmUa41gKTMJIbqZZLucNuDcOtzUaeWZlZAkA8 | ||
527 | 349 | ttXigLnCqR486JDPTi9ZscoZkZ+w7y6e/hH8t6d5Vjt48JVyfjPIaJY+km58LcN3 | ||
528 | 350 | 6AWSeGAdtRFHVzR7oHjVAkB4hutvxiOeiIVQNBhM6RSI9aBPMI21DoX2JRoxvNW2 | ||
529 | 351 | cbvAhow217X9V0dVerEOKxnNYspXRrh36h7k4mQA+sDq | ||
530 | 352 | -----END RSA PRIVATE KEY----- | ||
531 | 353 | """ | ||
532 | 354 | |||
533 | 355 | server_cert_pem = """-----BEGIN CERTIFICATE----- | ||
534 | 356 | MIICKDCCAZGgAwIBAgIJAJn/HpR21r/8MA0GCSqGSIb3DQEBBQUAMFgxCzAJBgNV | ||
535 | 357 | BAYTAlVTMQswCQYDVQQIEwJJTDEQMA4GA1UEBxMHQ2hpY2FnbzEQMA4GA1UEChMH | ||
536 | 358 | VGVzdGluZzEYMBYGA1UEAxMPVGVzdGluZyBSb290IENBMCIYDzIwMDkwMzI1MTIz | ||
537 | 359 | NzUzWhgPMjAxNzA2MTExMjM3NTNaMBgxFjAUBgNVBAMTDWxvdmVseSBzZXJ2ZXIw | ||
538 | 360 | gZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAL6m+G653V0tpBC/OKl22VxOi2Cv | ||
539 | 361 | lK4TYu9LHSDP9uDVTe7V5D5Tl6qzFoRRx5pfmnkqT5B+W9byp2NU3FC5hLm5zSAr | ||
540 | 362 | b45meUhjEJ/ifkZgbNUjHdBIGP9MAQUHZa5WKdkGIJvGAvs8UzUqlr4TBWQIB24+ | ||
541 | 363 | lJ+Ukk/CRgasrYwdAgMBAAGjNjA0MB0GA1UdDgQWBBS4kC7Ij0W1TZXZqXQFAM2e | ||
542 | 364 | gKEG2DATBgNVHSUEDDAKBggrBgEFBQcDATANBgkqhkiG9w0BAQUFAAOBgQBh30Li | ||
543 | 365 | dJ+NlxIOx5343WqIBka3UbsOb2kxWrbkVCrvRapCMLCASO4FqiKWM+L0VDBprqIp | ||
544 | 366 | 2mgpFQ6FHpoIENGvJhdEKpptQ5i7KaGhnDNTfdy3x1+h852G99f1iyj0RmbuFcM8 | ||
545 | 367 | uzujnS8YXWvM7DM1Ilozk4MzPug8jzFp5uhKCQ== | ||
546 | 368 | -----END CERTIFICATE----- | ||
547 | 369 | """ | ||
548 | 370 | |||
549 | 371 | server_key_pem = """-----BEGIN RSA PRIVATE KEY----- | ||
550 | 372 | MIICWwIBAAKBgQC+pvhuud1dLaQQvzipdtlcTotgr5SuE2LvSx0gz/bg1U3u1eQ+ | ||
551 | 373 | U5eqsxaEUceaX5p5Kk+QflvW8qdjVNxQuYS5uc0gK2+OZnlIYxCf4n5GYGzVIx3Q | ||
552 | 374 | SBj/TAEFB2WuVinZBiCbxgL7PFM1Kpa+EwVkCAduPpSflJJPwkYGrK2MHQIDAQAB | ||
553 | 375 | AoGAbwuZ0AR6JveahBaczjfnSpiFHf+mve2UxoQdpyr6ROJ4zg/PLW5K/KXrC48G | ||
554 | 376 | j6f3tXMrfKHcpEoZrQWUfYBRCUsGD5DCazEhD8zlxEHahIsqpwA0WWssJA2VOLEN | ||
555 | 377 | j6DuV2pCFbw67rfTBkTSo32ahfXxEKev5KswZk0JIzH3ooECQQDgzS9AI89h0gs8 | ||
556 | 378 | Dt+1m11Rzqo3vZML7ZIyGApUzVan+a7hbc33nbGRkAXjHaUBJO31it/H6dTO+uwX | ||
557 | 379 | msWwNG5ZAkEA2RyFKs5xR5USTFaKLWCgpH/ydV96KPOpBND7TKQx62snDenFNNbn | ||
558 | 380 | FwwOhpahld+vqhYk+pfuWWUpQciE+Bu7ZQJASjfT4sQv4qbbKK/scePicnDdx9th | ||
559 | 381 | 4e1EeB9xwb+tXXXUo/6Bor/AcUNwfiQ6Zt9PZOK9sR3lMZSsP7rMi7kzuQJABie6 | ||
560 | 382 | 1sXXjFH7nNJvRG4S39cIxq8YRYTy68II/dlB2QzGpKxV/POCxbJ/zu0CU79tuYK7 | ||
561 | 383 | NaeNCFfH3aeTrX0LyQJAMBWjWmeKM2G2sCExheeQK0ROnaBC8itCECD4Jsve4nqf | ||
562 | 384 | r50+LF74iLXFwqysVCebPKMOpDWp/qQ1BbJQIPs7/A== | ||
563 | 385 | -----END RSA PRIVATE KEY----- | ||
564 | 386 | """ | ||
565 | 387 | |||
566 | 388 | client_cert_pem = """-----BEGIN CERTIFICATE----- | ||
567 | 389 | MIICJjCCAY+gAwIBAgIJAKxpFI5lODkjMA0GCSqGSIb3DQEBBQUAMFgxCzAJBgNV | ||
568 | 390 | BAYTAlVTMQswCQYDVQQIEwJJTDEQMA4GA1UEBxMHQ2hpY2FnbzEQMA4GA1UEChMH | ||
569 | 391 | VGVzdGluZzEYMBYGA1UEAxMPVGVzdGluZyBSb290IENBMCIYDzIwMDkwMzI1MTIz | ||
570 | 392 | ODA1WhgPMjAxNzA2MTExMjM4MDVaMBYxFDASBgNVBAMTC3VnbHkgY2xpZW50MIGf | ||
571 | 393 | MA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDAZh/SRtNm5ntMT4qb6YzEpTroMlq2 | ||
572 | 394 | rn+GrRHRiZ+xkCw/CGNhbtPir7/QxaUj26BSmQrHw1bGKEbPsWiW7bdXSespl+xK | ||
573 | 395 | iku4G/KvnnmWdeJHqsiXeUZtqurMELcPQAw9xPHEuhqqUJvvEoMTsnCEqGM+7Dtb | ||
574 | 396 | oCRajYyHfluARQIDAQABozYwNDAdBgNVHQ4EFgQUNQB+qkaOaEVecf1J3TTUtAff | ||
575 | 397 | 0fAwEwYDVR0lBAwwCgYIKwYBBQUHAwIwDQYJKoZIhvcNAQEFBQADgYEAyv/Jh7gM | ||
576 | 398 | Q3OHvmsFEEvRI+hsW8y66zK4K5de239Y44iZrFYkt7Q5nBPMEWDj4F2hLYWL/qtI | ||
577 | 399 | 9Zdr0U4UDCU9SmmGYh4o7R4TZ5pGFvBYvjhHbkSFYFQXZxKUi+WUxplP6I0wr2KJ | ||
578 | 400 | PSTJCjJOn3xo2NTKRgV1gaoTf2EhL+RG8TQ= | ||
579 | 401 | -----END CERTIFICATE----- | ||
580 | 402 | """ | ||
581 | 403 | |||
582 | 404 | client_key_pem = """-----BEGIN RSA PRIVATE KEY----- | ||
583 | 405 | MIICXgIBAAKBgQDAZh/SRtNm5ntMT4qb6YzEpTroMlq2rn+GrRHRiZ+xkCw/CGNh | ||
584 | 406 | btPir7/QxaUj26BSmQrHw1bGKEbPsWiW7bdXSespl+xKiku4G/KvnnmWdeJHqsiX | ||
585 | 407 | eUZtqurMELcPQAw9xPHEuhqqUJvvEoMTsnCEqGM+7DtboCRajYyHfluARQIDAQAB | ||
586 | 408 | AoGATkZ+NceY5Glqyl4mD06SdcKfV65814vg2EL7V9t8+/mi9rYL8KztSXGlQWPX | ||
587 | 409 | zuHgtRoMl78yQ4ZJYOBVo+nsx8KZNRCEBlE19bamSbQLCeQMenWnpeYyQUZ908gF | ||
588 | 410 | h6L9qsFVJepgA9RDgAjyDoS5CaWCdCCPCH2lDkdcqC54SVUCQQDseuduc4wi8h4t | ||
589 | 411 | V8AahUn9fn9gYfhoNuM0gdguTA0nPLVWz4hy1yJiWYQe0H7NLNNTmCKiLQaJpAbb | ||
590 | 412 | TC6vE8C7AkEA0Ee8CMJUc20BnGEmxwgWcVuqFWaKCo8jTH1X38FlATUsyR3krjW2 | ||
591 | 413 | dL3yDD9NwHxsYP7nTKp/U8MV7U9IBn4y/wJBAJl7H0/BcLeRmuJk7IqJ7b635iYB | ||
592 | 414 | D/9beFUw3MUXmQXZUfyYz39xf6CDZsu1GEdEC5haykeln3Of4M9d/4Kj+FcCQQCY | ||
593 | 415 | si6xwT7GzMDkk/ko684AV3KPc/h6G0yGtFIrMg7J3uExpR/VdH2KgwMkZXisSMvw | ||
594 | 416 | JJEQjOMCVsEJlRk54WWjAkEAzoZNH6UhDdBK5F38rVt/y4SEHgbSfJHIAmPS32Kq | ||
595 | 417 | f6GGcfNpip0Uk7q7udTKuX7Q/buZi/C4YW7u3VKAquv9NA== | ||
596 | 418 | -----END RSA PRIVATE KEY----- | ||
597 | 419 | """ | ||
598 | 420 | |||
599 | 421 | def verify_cb(conn, cert, errnum, depth, ok): | ||
600 | 422 | return ok | ||
601 | 423 | |||
602 | 424 | class MemoryBIOTests(TestCase): | ||
603 | 425 | """ | ||
604 | 426 | Tests for L{OpenSSL.SSL.Connection} using a memory BIO. | ||
605 | 427 | """ | ||
606 | 428 | def _server(self): | ||
607 | 429 | # Create the server side Connection. This is mostly setup boilerplate | ||
608 | 430 | # - use TLSv1, use a particular certificate, etc. | ||
609 | 431 | server_ctx = Context(TLSv1_METHOD) | ||
610 | 432 | server_ctx.set_options(OP_NO_SSLv2 | OP_NO_SSLv3 | OP_SINGLE_DH_USE ) | ||
611 | 433 | server_ctx.set_verify(VERIFY_PEER|VERIFY_FAIL_IF_NO_PEER_CERT|VERIFY_CLIENT_ONCE, verify_cb) | ||
612 | 434 | server_store = server_ctx.get_cert_store() | ||
613 | 435 | server_ctx.use_privatekey(load_privatekey(FILETYPE_PEM, server_key_pem)) | ||
614 | 436 | server_ctx.use_certificate(load_certificate(FILETYPE_PEM, server_cert_pem)) | ||
615 | 437 | server_ctx.check_privatekey() | ||
616 | 438 | server_store.add_cert(load_certificate(FILETYPE_PEM, root_cert_pem)) | ||
617 | 439 | # Here the Connection is actually created. None is passed as the 2nd | ||
618 | 440 | # parameter, indicating a memory BIO should be created. | ||
619 | 441 | server_conn = Connection(server_ctx, None) | ||
620 | 442 | server_conn.set_accept_state() | ||
621 | 443 | return server_conn | ||
622 | 444 | |||
623 | 445 | |||
624 | 446 | def _client(self): | ||
625 | 447 | # Now create the client side Connection. Similar boilerplate to the above. | ||
626 | 448 | client_ctx = Context(TLSv1_METHOD) | ||
627 | 449 | client_ctx.set_options(OP_NO_SSLv2 | OP_NO_SSLv3 | OP_SINGLE_DH_USE ) | ||
628 | 450 | client_ctx.set_verify(VERIFY_PEER|VERIFY_FAIL_IF_NO_PEER_CERT|VERIFY_CLIENT_ONCE, verify_cb) | ||
629 | 451 | client_store = client_ctx.get_cert_store() | ||
630 | 452 | client_ctx.use_privatekey(load_privatekey(FILETYPE_PEM, client_key_pem)) | ||
631 | 453 | client_ctx.use_certificate(load_certificate(FILETYPE_PEM, client_cert_pem)) | ||
632 | 454 | client_ctx.check_privatekey() | ||
633 | 455 | client_store.add_cert(load_certificate(FILETYPE_PEM, root_cert_pem)) | ||
634 | 456 | # Again, None to create a new memory BIO. | ||
635 | 457 | client_conn = Connection(client_ctx, None) | ||
636 | 458 | client_conn.set_connect_state() | ||
637 | 459 | return client_conn | ||
638 | 460 | |||
639 | 461 | |||
640 | 462 | def _loopback(self, client_conn, server_conn): | ||
641 | 463 | """ | ||
642 | 464 | Try to read application bytes from each of the two L{Connection} | ||
643 | 465 | objects. Copy bytes back and forth between their send/receive buffers | ||
644 | 466 | for as long as there is anything to copy. When there is nothing more | ||
645 | 467 | to copy, return C{None}. If one of them actually manages to deliver | ||
646 | 468 | some application bytes, return a two-tuple of the connection from which | ||
647 | 469 | the bytes were read and the bytes themselves. | ||
648 | 470 | """ | ||
649 | 471 | wrote = True | ||
650 | 472 | while wrote: | ||
651 | 473 | # Loop until neither side has anything to say | ||
652 | 474 | wrote = False | ||
653 | 475 | |||
654 | 476 | # Copy stuff from each side's send buffer to the other side's | ||
655 | 477 | # receive buffer. | ||
656 | 478 | for (read, write) in [(client_conn, server_conn), | ||
657 | 479 | (server_conn, client_conn)]: | ||
658 | 480 | |||
659 | 481 | # Give the side a chance to generate some more bytes, or | ||
660 | 482 | # succeed. | ||
661 | 483 | try: | ||
662 | 484 | bytes = read.recv(2 ** 16) | ||
663 | 485 | except WantReadError: | ||
664 | 486 | # It didn't succeed, so we'll hope it generated some | ||
665 | 487 | # output. | ||
666 | 488 | pass | ||
667 | 489 | else: | ||
668 | 490 | # It did succeed, so we'll stop now and let the caller deal | ||
669 | 491 | # with it. | ||
670 | 492 | return (read, bytes) | ||
671 | 493 | |||
672 | 494 | while True: | ||
673 | 495 | # Keep copying as long as there's more stuff there. | ||
674 | 496 | try: | ||
675 | 497 | dirty = read.bio_read(4096) | ||
676 | 498 | except WantReadError: | ||
677 | 499 | # Okay, nothing more waiting to be sent. Stop | ||
678 | 500 | # processing this send buffer. | ||
679 | 501 | break | ||
680 | 502 | else: | ||
681 | 503 | # Keep track of the fact that someone generated some | ||
682 | 504 | # output. | ||
683 | 505 | wrote = True | ||
684 | 506 | write.bio_write(dirty) | ||
685 | 507 | |||
686 | 508 | |||
687 | 509 | def test_connect(self): | ||
688 | 510 | """ | ||
689 | 511 | Two L{Connection}s which use memory BIOs can be manually connected by | ||
690 | 512 | reading from the output of each and writing those bytes to the input of | ||
691 | 513 | the other and in this way establish a connection and exchange | ||
692 | 514 | application-level bytes with each other. | ||
693 | 515 | """ | ||
694 | 516 | server_conn = self._server() | ||
695 | 517 | client_conn = self._client() | ||
696 | 518 | |||
697 | 519 | # There should be no key or nonces yet. | ||
698 | 520 | self.assertIdentical(server_conn.master_key(), None) | ||
699 | 521 | self.assertIdentical(server_conn.client_random(), None) | ||
700 | 522 | self.assertIdentical(server_conn.server_random(), None) | ||
701 | 523 | |||
702 | 524 | # First, the handshake needs to happen. We'll deliver bytes back and | ||
703 | 525 | # forth between the client and server until neither of them feels like | ||
704 | 526 | # speaking any more. | ||
705 | 527 | self.assertIdentical(self._loopback(client_conn, server_conn), None) | ||
706 | 528 | |||
707 | 529 | # Now that the handshake is done, there should be a key and nonces. | ||
708 | 530 | self.assertNotIdentical(server_conn.master_key(), None) | ||
709 | 531 | self.assertNotIdentical(server_conn.client_random(), None) | ||
710 | 532 | self.assertNotIdentical(server_conn.server_random(), None) | ||
711 | 533 | self.assertNotIdentical(server_conn.client_random(), client_conn.client_random()) | ||
712 | 534 | self.assertNotIdentical(server_conn.server_random(), client_conn.server_random()) | ||
713 | 535 | |||
714 | 536 | # Here are the bytes we'll try to send. | ||
715 | 537 | important_message = 'One if by land, two if by sea.' | ||
716 | 538 | |||
717 | 539 | server_conn.write(important_message) | ||
718 | 540 | self.assertEquals( | ||
719 | 541 | self._loopback(client_conn, server_conn), | ||
720 | 542 | (client_conn, important_message)) | ||
721 | 543 | |||
722 | 544 | client_conn.write(important_message[::-1]) | ||
723 | 545 | self.assertEquals( | ||
724 | 546 | self._loopback(client_conn, server_conn), | ||
725 | 547 | (server_conn, important_message[::-1])) | ||
726 | 548 | |||
727 | 549 | |||
728 | 550 | def test_socketOverridesMemory(self): | ||
729 | 551 | """ | ||
730 | 552 | Test that L{OpenSSL.SSL.bio_read} and L{OpenSSL.SSL.bio_write} don't | ||
731 | 553 | work on L{OpenSSL.SSL.Connection}() that use sockets. | ||
732 | 554 | """ | ||
733 | 555 | context = Context(SSLv3_METHOD) | ||
734 | 556 | client = socket() | ||
735 | 557 | clientSSL = Connection(context, client) | ||
736 | 558 | self.assertRaises( TypeError, clientSSL.bio_read, 100) | ||
737 | 559 | self.assertRaises( TypeError, clientSSL.bio_write, "foo") | ||
738 | 560 | |||
739 | 561 | |||
740 | 562 | def test_outgoingOverflow(self): | ||
741 | 563 | """ | ||
742 | 564 | If more bytes than can be written to the memory BIO are passed to | ||
743 | 565 | L{Connection.send} at once, the number of bytes which were written is | ||
744 | 566 | returned and that many bytes from the beginning of the input can be | ||
745 | 567 | read from the other end of the connection. | ||
746 | 568 | """ | ||
747 | 569 | server = self._server() | ||
748 | 570 | client = self._client() | ||
749 | 571 | |||
750 | 572 | self._loopback(client, server) | ||
751 | 573 | |||
752 | 574 | size = 2 ** 15 | ||
753 | 575 | sent = client.send("x" * size) | ||
754 | 576 | # Sanity check. We're trying to test what happens when the entire | ||
755 | 577 | # input can't be sent. If the entire input was sent, this test is | ||
756 | 578 | # meaningless. | ||
757 | 579 | self.assertTrue(sent < size) | ||
758 | 580 | |||
759 | 581 | receiver, received = self._loopback(client, server) | ||
760 | 582 | self.assertIdentical(receiver, server) | ||
761 | 583 | |||
762 | 584 | # We can rely on all of these bytes being received at once because | ||
763 | 585 | # _loopback passes 2 ** 16 to recv - more than 2 ** 15. | ||
764 | 586 | self.assertEquals(len(received), sent) | ||
765 | 587 | |||
766 | 588 | |||
767 | 589 | def test_shutdown(self): | ||
768 | 590 | """ | ||
769 | 591 | L{Connection.bio_shutdown} signals the end of the data stream from | ||
770 | 592 | which the L{Connection} reads. | ||
771 | 593 | """ | ||
772 | 594 | server = self._server() | ||
773 | 595 | server.bio_shutdown() | ||
774 | 596 | e = self.assertRaises(Error, server.recv, 1024) | ||
775 | 597 | # We don't want WantReadError or ZeroReturnError or anything - it's a | ||
776 | 598 | # handshake failure. | ||
777 | 599 | self.assertEquals(e.__class__, Error) |