blob: 866fb8aba4c202d43dc031554c13b3c0b0b57298 [file] [log] [blame]
Jean-Paul Calderone935d2da2013-03-04 08:11:19 -08001
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -08002from functools import wraps
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08003from itertools import count
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08004from weakref import WeakValueDictionary
5from errno import errorcode
Jean-Paul Calderone935d2da2013-03-04 08:11:19 -08006
7from tls.c import api as _api
8
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -08009from OpenSSL.crypto import (
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -080010 FILETYPE_PEM, _PassphraseHelper, PKey, X509Name, X509, X509Store,
11
12 _raise_current_error, _new_mem_buf)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -080013
14_unspecified = object()
15
Jean-Paul Calderone935d2da2013-03-04 08:11:19 -080016OPENSSL_VERSION_NUMBER = _api.OPENSSL_VERSION_NUMBER
17SSLEAY_VERSION = _api.SSLEAY_VERSION
18SSLEAY_CFLAGS = _api.SSLEAY_CFLAGS
19SSLEAY_PLATFORM = _api.SSLEAY_PLATFORM
20SSLEAY_DIR = _api.SSLEAY_DIR
21SSLEAY_BUILT_ON = _api.SSLEAY_BUILT_ON
22
23SENT_SHUTDOWN = _api.SSL_SENT_SHUTDOWN
24RECEIVED_SHUTDOWN = _api.SSL_RECEIVED_SHUTDOWN
25
26SSLv2_METHOD = 1
27SSLv3_METHOD = 2
28SSLv23_METHOD = 3
29TLSv1_METHOD = 4
30
31OP_NO_SSLv2 = _api.SSL_OP_NO_SSLv2
32OP_NO_SSLv3 = _api.SSL_OP_NO_SSLv3
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -080033OP_NO_TLSv1 = _api.SSL_OP_NO_TLSv1
34
35MODE_RELEASE_BUFFERS = _api.SSL_MODE_RELEASE_BUFFERS
Jean-Paul Calderone935d2da2013-03-04 08:11:19 -080036
37OP_SINGLE_DH_USE = _api.SSL_OP_SINGLE_DH_USE
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -080038OP_EPHEMERAL_RSA = _api.SSL_OP_EPHEMERAL_RSA
39OP_MICROSOFT_SESS_ID_BUG = _api.SSL_OP_MICROSOFT_SESS_ID_BUG
40OP_NETSCAPE_CHALLENGE_BUG = _api.SSL_OP_NETSCAPE_CHALLENGE_BUG
41OP_NETSCAPE_REUSE_CIPHER_CHANGE_BUG = _api.SSL_OP_NETSCAPE_REUSE_CIPHER_CHANGE_BUG
42OP_SSLREF2_REUSE_CERT_TYPE_BUG = _api.SSL_OP_SSLREF2_REUSE_CERT_TYPE_BUG
43OP_MICROSOFT_BIG_SSLV3_BUFFER = _api.SSL_OP_MICROSOFT_BIG_SSLV3_BUFFER
44OP_MSIE_SSLV2_RSA_PADDING = _api.SSL_OP_MSIE_SSLV2_RSA_PADDING
45OP_SSLEAY_080_CLIENT_DH_BUG = _api.SSL_OP_SSLEAY_080_CLIENT_DH_BUG
46OP_TLS_D5_BUG = _api.SSL_OP_TLS_D5_BUG
47OP_TLS_BLOCK_PADDING_BUG = _api.SSL_OP_TLS_BLOCK_PADDING_BUG
48OP_DONT_INSERT_EMPTY_FRAGMENTS = _api.SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS
49OP_CIPHER_SERVER_PREFERENCE = _api.SSL_OP_CIPHER_SERVER_PREFERENCE
50OP_TLS_ROLLBACK_BUG = _api.SSL_OP_TLS_ROLLBACK_BUG
51OP_PKCS1_CHECK_1 = _api.SSL_OP_PKCS1_CHECK_1
52OP_PKCS1_CHECK_2 = _api.SSL_OP_PKCS1_CHECK_2
53OP_NETSCAPE_CA_DN_BUG = _api.SSL_OP_NETSCAPE_CA_DN_BUG
54OP_NETSCAPE_DEMO_CIPHER_CHANGE_BUG= _api.SSL_OP_NETSCAPE_DEMO_CIPHER_CHANGE_BUG
55OP_NO_COMPRESSION = _api.SSL_OP_NO_COMPRESSION
56
57OP_NO_QUERY_MTU = _api.SSL_OP_NO_QUERY_MTU
58OP_COOKIE_EXCHANGE = _api.SSL_OP_COOKIE_EXCHANGE
59OP_NO_TICKET = _api.SSL_OP_NO_TICKET
60
61OP_ALL = _api.SSL_OP_ALL
Jean-Paul Calderone935d2da2013-03-04 08:11:19 -080062
63VERIFY_PEER = _api.SSL_VERIFY_PEER
64VERIFY_FAIL_IF_NO_PEER_CERT = _api.SSL_VERIFY_FAIL_IF_NO_PEER_CERT
65VERIFY_CLIENT_ONCE = _api.SSL_VERIFY_CLIENT_ONCE
66VERIFY_NONE = _api.SSL_VERIFY_NONE
67
68SESS_CACHE_OFF = _api.SSL_SESS_CACHE_OFF
69SESS_CACHE_CLIENT = _api.SSL_SESS_CACHE_CLIENT
70SESS_CACHE_SERVER = _api.SSL_SESS_CACHE_SERVER
71SESS_CACHE_BOTH = _api.SSL_SESS_CACHE_BOTH
72SESS_CACHE_NO_AUTO_CLEAR = _api.SSL_SESS_CACHE_NO_AUTO_CLEAR
73SESS_CACHE_NO_INTERNAL_LOOKUP = _api.SSL_SESS_CACHE_NO_INTERNAL_LOOKUP
74SESS_CACHE_NO_INTERNAL_STORE = _api.SSL_SESS_CACHE_NO_INTERNAL_STORE
75SESS_CACHE_NO_INTERNAL = _api.SSL_SESS_CACHE_NO_INTERNAL
Jean-Paul Calderoned39a3f62013-03-04 12:23:51 -080076
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -080077SSL_ST_CONNECT = _api.SSL_ST_CONNECT
78SSL_ST_ACCEPT = _api.SSL_ST_ACCEPT
79SSL_ST_MASK = _api.SSL_ST_MASK
80SSL_ST_INIT = _api.SSL_ST_INIT
81SSL_ST_BEFORE = _api.SSL_ST_BEFORE
82SSL_ST_OK = _api.SSL_ST_OK
83SSL_ST_RENEGOTIATE = _api.SSL_ST_RENEGOTIATE
84
85SSL_CB_LOOP = _api.SSL_CB_LOOP
86SSL_CB_EXIT = _api.SSL_CB_EXIT
87SSL_CB_READ = _api.SSL_CB_READ
88SSL_CB_WRITE = _api.SSL_CB_WRITE
89SSL_CB_ALERT = _api.SSL_CB_ALERT
90SSL_CB_READ_ALERT = _api.SSL_CB_READ_ALERT
91SSL_CB_WRITE_ALERT = _api.SSL_CB_WRITE_ALERT
92SSL_CB_ACCEPT_LOOP = _api.SSL_CB_ACCEPT_LOOP
93SSL_CB_ACCEPT_EXIT = _api.SSL_CB_ACCEPT_EXIT
94SSL_CB_CONNECT_LOOP = _api.SSL_CB_CONNECT_LOOP
95SSL_CB_CONNECT_EXIT = _api.SSL_CB_CONNECT_EXIT
96SSL_CB_HANDSHAKE_START = _api.SSL_CB_HANDSHAKE_START
97SSL_CB_HANDSHAKE_DONE = _api.SSL_CB_HANDSHAKE_DONE
98
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -080099
100
101class Error(Exception):
102 pass
103
104
105
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800106class WantReadError(Error):
107 pass
108
109
110
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800111class ZeroReturnError(Error):
112 pass
113
114
115class SysCallError(Error):
116 pass
117
118
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800119def _asFileDescriptor(obj):
120 fd = None
121
122 if not isinstance(obj, int):
123 meth = getattr(obj, "fileno", None)
124 if meth is not None:
125 obj = meth()
126
127 if isinstance(obj, int):
128 fd = obj
129
130 if not isinstance(fd, int):
131 raise TypeError("argument must be an int, or have a fileno() method.")
132 elif fd < 0:
133 raise ValueError(
134 "file descriptor cannot be a negative integer (%i)" % (fd,))
135
136 return fd
137
138
139
Jean-Paul Calderoned39a3f62013-03-04 12:23:51 -0800140def SSLeay_version(type):
141 """
142 Return a string describing the version of OpenSSL in use.
143
144 :param type: One of the SSLEAY_ constants defined in this module.
145 """
146 return _api.string(_api.SSLeay_version(type))
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800147
148
149
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800150class Session(object):
151 pass
152
153
154
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800155class Context(object):
156 """
157 :py:obj:`OpenSSL.SSL.Context` instances define the parameters for setting up
158 new SSL connections.
159 """
160 _methods = {
161 # TODO
162 # SSLv2_METHOD: _api.SSLv2_method,
163 SSLv3_METHOD: _api.SSLv3_method,
164 TLSv1_METHOD: _api.TLSv1_method,
165 SSLv23_METHOD: _api.SSLv23_method,
166 }
167
168 def __init__(self, method):
169 """
170 :param method: One of SSLv2_METHOD, SSLv3_METHOD, SSLv23_METHOD, or
171 TLSv1_METHOD.
172 """
173 if not isinstance(method, int):
174 raise TypeError("method must be an integer")
175
176 try:
177 method_func = self._methods[method]
178 except KeyError:
179 raise ValueError("No such protocol")
180
181 method_obj = method_func()
182
183 context = _api.SSL_CTX_new(method_obj)
184 if context == _api.NULL:
185 1/0
Jean-Paul Calderone73b15c22013-03-05 18:30:39 -0800186 context = _api.ffi.gc(context, _api.SSL_CTX_free)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800187
188 self._context = context
Jean-Paul Calderone173cff92013-03-06 10:29:21 -0800189 self._passphrase_helper = None
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800190 self._passphrase_callback = None
Jean-Paul Calderone173cff92013-03-06 10:29:21 -0800191 self._passphrase_userdata = None
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800192 self._verify_callback = None
193 self._info_callback = None
194 self._tlsext_servername_callback = None
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800195 self._app_data = None
196
Jean-Paul Calderone1aba4162013-03-05 18:50:00 -0800197 # SSL_CTX_set_app_data(self->ctx, self);
198 # SSL_CTX_set_mode(self->ctx, SSL_MODE_ENABLE_PARTIAL_WRITE |
199 # SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER |
200 # SSL_MODE_AUTO_RETRY);
201 self.set_mode(_api.SSL_MODE_ENABLE_PARTIAL_WRITE)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800202
203
204 def load_verify_locations(self, cafile, capath=None):
205 """
206 Let SSL know where we can find trusted certificates for the certificate
207 chain
208
209 :param cafile: In which file we can find the certificates
210 :param capath: In which directory we can find the certificates
211 :return: None
212 """
213 if cafile is None:
214 cafile = _api.NULL
215 elif not isinstance(cafile, bytes):
216 raise TypeError("cafile must be None or a byte string")
217
218 if capath is None:
219 capath = _api.NULL
220 elif not isinstance(capath, bytes):
221 raise TypeError("capath must be None or a byte string")
222
223 load_result = _api.SSL_CTX_load_verify_locations(self._context, cafile, capath)
224 if not load_result:
225 _raise_current_error(Error)
226
227
228 def _wrap_callback(self, callback):
229 @wraps(callback)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800230 def wrapper(size, verify, userdata):
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800231 return callback(size, verify, self._passphrase_userdata)
232 return _PassphraseHelper(
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800233 FILETYPE_PEM, wrapper, more_args=True, truncate=True)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800234
235
236 def set_passwd_cb(self, callback, userdata=None):
237 """
238 Set the passphrase callback
239
240 :param callback: The Python callback to use
241 :param userdata: (optional) A Python object which will be given as
242 argument to the callback
243 :return: None
244 """
245 if not callable(callback):
246 raise TypeError("callback must be callable")
247
248 self._passphrase_helper = self._wrap_callback(callback)
249 self._passphrase_callback = self._passphrase_helper.callback
250 _api.SSL_CTX_set_default_passwd_cb(
251 self._context, self._passphrase_callback)
252 self._passphrase_userdata = userdata
253
254
255 def set_default_verify_paths(self):
256 """
257 Use the platform-specific CA certificate locations
258
259 :return: None
260 """
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800261 set_result = _api.SSL_CTX_set_default_verify_paths(self._context)
262 if not set_result:
263 1/0
264 _raise_current_error(Error)
265
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800266
267 def use_certificate_chain_file(self, certfile):
268 """
269 Load a certificate chain from a file
270
271 :param certfile: The name of the certificate chain file
272 :return: None
273 """
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800274 if not isinstance(certfile, bytes):
275 raise TypeError("certfile must be a byte string")
276
277 result = _api.SSL_CTX_use_certificate_chain_file(self._context, certfile)
278 if not result:
279 _raise_current_error(Error)
280
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800281
Jean-Paul Calderone173cff92013-03-06 10:29:21 -0800282 def use_certificate_file(self, certfile, filetype=FILETYPE_PEM):
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800283 """
284 Load a certificate from a file
285
286 :param certfile: The name of the certificate file
287 :param filetype: (optional) The encoding of the file, default is PEM
288 :return: None
289 """
Jean-Paul Calderone173cff92013-03-06 10:29:21 -0800290 if not isinstance(certfile, bytes):
291 raise TypeError("certfile must be a byte string")
292 if not isinstance(filetype, int):
293 raise TypeError("filetype must be an integer")
294
295 use_result = _api.SSL_CTX_use_certificate_file(self._context, certfile, filetype)
296 if not use_result:
297 _raise_current_error(Error)
298
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800299
300 def use_certificate(self, cert):
301 """
302 Load a certificate from a X509 object
303
304 :param cert: The X509 object
305 :return: None
306 """
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800307 if not isinstance(cert, X509):
308 raise TypeError("cert must be an X509 instance")
309
310 use_result = _api.SSL_CTX_use_certificate(self._context, cert._x509)
311 if not use_result:
Jean-Paul Calderone173cff92013-03-06 10:29:21 -0800312 _raise_current_error(Error)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800313
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800314
315 def add_extra_chain_cert(self, certobj):
316 """
317 Add certificate to chain
318
319 :param certobj: The X509 certificate object to add to the chain
320 :return: None
321 """
322 if not isinstance(certobj, X509):
323 raise TypeError("certobj must be an X509 instance")
324
325 copy = _api.X509_dup(certobj._x509)
Jean-Paul Calderone73b15c22013-03-05 18:30:39 -0800326 add_result = _api.SSL_CTX_add_extra_chain_cert(self._context, copy)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800327 if not add_result:
328 # _api.X509_free(copy)
329 # _raise_current_error(Error)
330 1/0
331
Jean-Paul Calderone173cff92013-03-06 10:29:21 -0800332
333 def _raise_passphrase_exception(self):
334 if self._passphrase_helper is None:
335 _raise_current_error(Error)
336 exception = self._passphrase_helper.raise_if_problem(Error)
337 if exception is not None:
338 raise exception
339
340
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800341 def use_privatekey_file(self, keyfile, filetype=_unspecified):
342 """
343 Load a private key from a file
344
345 :param keyfile: The name of the key file
346 :param filetype: (optional) The encoding of the file, default is PEM
347 :return: None
348 """
349 if not isinstance(keyfile, bytes):
350 raise TypeError("keyfile must be a byte string")
351
352 if filetype is _unspecified:
353 filetype = FILETYPE_PEM
354 elif not isinstance(filetype, int):
355 raise TypeError("filetype must be an integer")
356
357 use_result = _api.SSL_CTX_use_PrivateKey_file(
358 self._context, keyfile, filetype)
359 if not use_result:
Jean-Paul Calderone173cff92013-03-06 10:29:21 -0800360 self._raise_passphrase_exception()
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800361
362
363 def use_privatekey(self, pkey):
364 """
365 Load a private key from a PKey object
366
367 :param pkey: The PKey object
368 :return: None
369 """
370 if not isinstance(pkey, PKey):
371 raise TypeError("pkey must be a PKey instance")
372
373 use_result = _api.SSL_CTX_use_PrivateKey(self._context, pkey._pkey)
374 if not use_result:
Jean-Paul Calderone173cff92013-03-06 10:29:21 -0800375 self._raise_passphrase_exception()
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800376
377
378 def check_privatekey(self):
379 """
380 Check that the private key and certificate match up
381
382 :return: None (raises an exception if something's wrong)
383 """
384
385 def load_client_ca(self, cafile):
386 """
387 Load the trusted certificates that will be sent to the client (basically
388 telling the client "These are the guys I trust"). Does not actually
389 imply any of the certificates are trusted; that must be configured
390 separately.
391
392 :param cafile: The name of the certificates file
393 :return: None
394 """
395
396 def set_session_id(self, buf):
397 """
398 Set the session identifier. This is needed if you want to do session
399 resumption.
400
401 :param buf: A Python object that can be safely converted to a string
402 :returns: None
403 """
404
405 def set_session_cache_mode(self, mode):
406 """
407 Enable/disable session caching and specify the mode used.
408
409 :param mode: One or more of the SESS_CACHE_* flags (combine using
410 bitwise or)
411 :returns: The previously set caching mode.
412 """
413 if not isinstance(mode, int):
414 raise TypeError("mode must be an integer")
415
416 return _api.SSL_CTX_set_session_cache_mode(self._context, mode)
417
418
419 def get_session_cache_mode(self):
420 """
421 :returns: The currently used cache mode.
422 """
423 return _api.SSL_CTX_get_session_cache_mode(self._context)
424
425
426 def set_verify(self, mode, callback):
427 """
428 Set the verify mode and verify callback
429
430 :param mode: The verify mode, this is either VERIFY_NONE or
431 VERIFY_PEER combined with possible other flags
432 :param callback: The Python callback to use
433 :return: None
434
435 See SSL_CTX_set_verify(3SSL) for further details.
436 """
437 if not isinstance(mode, int):
438 raise TypeError("mode must be an integer")
439
440 if not callable(callback):
441 raise TypeError("callback must be callable")
442
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800443 @wraps(callback)
444 def wrapper(ok, store_ctx):
445 cert = X509.__new__(X509)
446 cert._x509 = _api.X509_STORE_CTX_get_current_cert(store_ctx)
447 error_number = _api.X509_STORE_CTX_get_error(store_ctx)
448 error_depth = _api.X509_STORE_CTX_get_error_depth(store_ctx)
449
450 try:
451 result = callback(self, cert, error_number, error_depth, ok)
452 except Exception as e:
453 # TODO
454 pass
455 else:
456 if result:
457 _api.X509_STORE_CTX_set_error(store_ctx, _api.X509_V_OK)
458 return 1
459 else:
460 return 0
461
462 self._verify_callback = _api.ffi.callback("verify_callback", wrapper)
463 _api.SSL_CTX_set_verify(self._context, mode, self._verify_callback)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800464
465
466 def set_verify_depth(self, depth):
467 """
468 Set the verify depth
469
470 :param depth: An integer specifying the verify depth
471 :return: None
472 """
473 if not isinstance(depth, int):
474 raise TypeError("depth must be an integer")
475
476 _api.SSL_CTX_set_verify_depth(self._context, depth)
477
478
479 def get_verify_mode(self):
480 """
481 Get the verify mode
482
483 :return: The verify mode
484 """
485 return _api.SSL_CTX_get_verify_mode(self._context)
486
487
488 def get_verify_depth(self):
489 """
490 Get the verify depth
491
492 :return: The verify depth
493 """
494 return _api.SSL_CTX_get_verify_depth(self._context)
495
496
497 def load_tmp_dh(self, dhfile):
498 """
499 Load parameters for Ephemeral Diffie-Hellman
500
501 :param dhfile: The file to load EDH parameters from
502 :return: None
503 """
504 if not isinstance(dhfile, bytes):
505 raise TypeError("dhfile must be a byte string")
506
507 bio = _api.BIO_new_file(dhfile, "r")
508 if bio == _api.NULL:
509 _raise_current_error(Error)
510 bio = _api.ffi.gc(bio, _api.BIO_free)
511
512 dh = _api.PEM_read_bio_DHparams(bio, _api.NULL, _api.NULL, _api.NULL)
513 dh = _api.ffi.gc(dh, _api.DH_free)
514 _api.SSL_CTX_set_tmp_dh(self._context, dh)
515
516
517 def set_cipher_list(self, cipher_list):
518 """
519 Change the cipher list
520
521 :param cipher_list: A cipher list, see ciphers(1)
522 :return: None
523 """
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800524 if not isinstance(cipher_list, bytes):
525 raise TypeError("cipher_list must be a byte string")
526
527 result = _api.SSL_CTX_set_cipher_list(self._context, cipher_list)
528 if not result:
529 _raise_current_error(Error)
530
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800531
532 def set_client_ca_list(self, certificate_authorities):
533 """
534 Set the list of preferred client certificate signers for this server context.
535
536 This list of certificate authorities will be sent to the client when the
537 server requests a client certificate.
538
539 :param certificate_authorities: a sequence of X509Names.
540 :return: None
541 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800542 name_stack = _api.sk_X509_NAME_new_null()
543 if name_stack == _api.NULL:
544 1/0
545 _raise_current_error(Error)
546
547 try:
548 for ca_name in certificate_authorities:
549 if not isinstance(ca_name, X509Name):
550 raise TypeError(
551 "client CAs must be X509Name objects, not %s objects" % (
552 type(ca_name).__name__,))
553 copy = _api.X509_NAME_dup(ca_name._name)
554 if copy == _api.NULL:
555 1/0
556 _raise_current_error(Error)
557 push_result = _api.sk_X509_NAME_push(name_stack, copy)
558 if not push_result:
559 _api.X509_NAME_free(copy)
560 _raise_current_error(Error)
561 except:
562 _api.sk_X509_NAME_free(name_stack)
563 raise
564
565 _api.SSL_CTX_set_client_CA_list(self._context, name_stack)
566
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800567
568 def add_client_ca(self, certificate_authority):
569 """
570 Add the CA certificate to the list of preferred signers for this context.
571
572 The list of certificate authorities will be sent to the client when the
573 server requests a client certificate.
574
575 :param certificate_authority: certificate authority's X509 certificate.
576 :return: None
577 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800578 if not isinstance(certificate_authority, X509):
579 raise TypeError("certificate_authority must be an X509 instance")
580
581 add_result = _api.SSL_CTX_add_client_CA(
582 self._context, certificate_authority._x509)
583 if not add_result:
584 1/0
585 _raise_current_error(Error)
586
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800587
588 def set_timeout(self, timeout):
589 """
590 Set session timeout
591
592 :param timeout: The timeout in seconds
593 :return: The previous session timeout
594 """
595 if not isinstance(timeout, int):
596 raise TypeError("timeout must be an integer")
597
598 return _api.SSL_CTX_set_timeout(self._context, timeout)
599
600
601 def get_timeout(self):
602 """
603 Get the session timeout
604
605 :return: The session timeout
606 """
607 return _api.SSL_CTX_get_timeout(self._context)
608
609
610 def set_info_callback(self, callback):
611 """
612 Set the info callback
613
614 :param callback: The Python callback to use
615 :return: None
616 """
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800617 @wraps(callback)
618 def wrapper(ssl, where, return_code):
619 callback(self, where, return_code)
620 self._info_callback = _api.callback('info_callback', wrapper)
621 _api.SSL_CTX_set_info_callback(self._context, self._info_callback)
622
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800623
624 def get_app_data(self):
625 """
626 Get the application data (supplied via set_app_data())
627
628 :return: The application data
629 """
630 return self._app_data
631
632
633 def set_app_data(self, data):
634 """
635 Set the application data (will be returned from get_app_data())
636
637 :param data: Any Python object
638 :return: None
639 """
640 self._app_data = data
641
642
643 def get_cert_store(self):
644 """
645 Get the certificate store for the context
646
647 :return: A X509Store object
648 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800649 store = _api.SSL_CTX_get_cert_store(self._context)
650 if store == _api.NULL:
651 1/0
652 return None
653
654 pystore = X509Store.__new__(X509Store)
655 pystore._store = store
656 return pystore
657
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800658
659 def set_options(self, options):
660 """
661 Add options. Options set before are not cleared!
662
663 :param options: The options to add.
664 :return: The new option bitmask.
665 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800666 if not isinstance(options, int):
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800667 raise TypeError("options must be an integer")
668
669 return _api.SSL_CTX_set_options(self._context, options)
670
671
672 def set_mode(self, mode):
673 """
674 Add modes via bitmask. Modes set before are not cleared!
675
676 :param mode: The mode to add.
677 :return: The new mode bitmask.
678 """
679 if not isinstance(mode, int):
680 raise TypeError("mode must be an integer")
681
682 return _api.SSL_CTX_set_mode(self._context, mode)
683
684
685 def set_tlsext_servername_callback(self, callback):
686 """
687 Specify a callback function to be called when clients specify a server name.
688
689 :param callback: The callback function. It will be invoked with one
690 argument, the Connection instance.
691 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800692 @wraps(callback)
693 def wrapper(ssl, alert, arg):
694 callback(Connection._reverse_mapping[ssl])
695 return 0
696
697 self._tlsext_servername_callback = _api.callback(
698 "tlsext_servername_callback", wrapper)
699 _api.SSL_CTX_set_tlsext_servername_callback(
700 self._context, self._tlsext_servername_callback)
Jean-Paul Calderone8a1bea52013-03-05 07:57:57 -0800701
702ContextType = Context
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800703
704
705
706class Connection(object):
707 """
708 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800709 _reverse_mapping = WeakValueDictionary()
710
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800711 def __init__(self, context, socket=None):
712 """
713 Create a new Connection object, using the given OpenSSL.SSL.Context
714 instance and socket.
715
716 :param context: An SSL Context to use for this connection
717 :param socket: The socket to use for transport layer
718 """
719 if not isinstance(context, Context):
720 raise TypeError("context must be a Context instance")
721
Jean-Paul Calderone73b15c22013-03-05 18:30:39 -0800722 ssl = _api.SSL_new(context._context)
723 self._ssl = _api.ffi.gc(ssl, _api.SSL_free)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800724 self._context = context
725
726 self._reverse_mapping[self._ssl] = self
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800727
728 if socket is None:
729 self._socket = None
Jean-Paul Calderone73b15c22013-03-05 18:30:39 -0800730 # Don't set up any gc for these, SSL_free will take care of them.
731 self._into_ssl = _api.BIO_new(_api.BIO_s_mem())
732 self._from_ssl = _api.BIO_new(_api.BIO_s_mem())
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800733
734 if self._into_ssl == _api.NULL or self._from_ssl == _api.NULL:
735 1/0
736
737 _api.SSL_set_bio(self._ssl, self._into_ssl, self._from_ssl)
738 else:
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800739 self._into_ssl = None
740 self._from_ssl = None
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800741 self._socket = socket
742 set_result = _api.SSL_set_fd(self._ssl, _asFileDescriptor(self._socket))
743 if not set_result:
744 1/0
745
746
747 def __getattr__(self, name):
748 """
749 Look up attributes on the wrapped socket object if they are not found on
750 the Connection object.
751 """
752 return getattr(self._socket, name)
753
754
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800755 def _raise_ssl_error(self, ssl, result):
756 error = _api.SSL_get_error(ssl, result)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800757 if error == _api.SSL_ERROR_WANT_READ:
758 raise WantReadError()
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800759 elif error == _api.SSL_ERROR_ZERO_RETURN:
760 raise ZeroReturnError()
761 elif error == _api.SSL_ERROR_NONE:
762 pass
763 elif error == _api.SSL_ERROR_SYSCALL:
764 if _api.ERR_peek_error() == 0:
765 if result < 0:
766 raise SysCallError(
767 _api.ffi.errno, errorcode[_api.ffi.errno])
768 else:
769 # TODO
770 raise Exception("unknown syscall error")
771 else:
772 # TODO
773 _raise_current_error(Error)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800774 else:
775 _raise_current_error(Error)
776
777
778 def get_context(self):
779 """
780 Get session context
781 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800782 return self._context
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800783
784
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800785 def set_context(self, context):
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800786 """
787 Switch this connection to a new session context
788
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800789 :param context: A :py:class:`Context` instance giving the new session
790 context to use.
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800791 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800792 if not isinstance(context, Context):
793 raise TypeError("context must be a Context instance")
794
795 _api.SSL_set_SSL_CTX(self._ssl, context._context)
796 self._context = context
797
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800798
799 def get_servername(self):
800 """
801 Retrieve the servername extension value if provided in the client hello
802 message, or None if there wasn't one.
803
804 :return: A byte string giving the server name or :py:data:`None`.
805 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800806 name = _api.SSL_get_servername(self._ssl, _api.TLSEXT_NAMETYPE_host_name)
807 if name == _api.NULL:
808 return None
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800809
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800810 return _api.string(name)
811
812
813 def set_tlsext_host_name(self, name):
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800814 """
815 Set the value of the servername extension to send in the client hello.
816
817 :param name: A byte string giving the name.
818 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800819 if not isinstance(name, bytes):
820 raise TypeError("name must be a byte string")
821 elif "\0" in name:
822 raise TypeError("name must not contain NUL byte")
823
824 # XXX I guess this can fail sometimes?
825 _api.SSL_set_tlsext_host_name(self._ssl, name)
826
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800827
828 def pending(self):
829 """
830 Get the number of bytes that can be safely read from the connection
831
832 :return: The number of bytes available in the receive buffer.
833 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800834 return _api.SSL_pending(self._ssl)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800835
836
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800837 def send(self, buf, flags=0):
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800838 """
839 Send data on the connection. NOTE: If you get one of the WantRead,
840 WantWrite or WantX509Lookup exceptions on this, you have to call the
841 method again with the SAME buffer.
842
843 :param buf: The string to send
844 :param flags: (optional) Included for compatibility with the socket
845 API, the value is ignored
846 :return: The number of bytes written
847 """
Jean-Paul Calderone1aba4162013-03-05 18:50:00 -0800848 if isinstance(buf, memoryview):
849 buf = buf.tobytes()
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800850 if not isinstance(buf, bytes):
851 raise TypeError("data must be a byte string")
852 if not isinstance(flags, int):
853 raise TypeError("flags must be an integer")
854
855 result = _api.SSL_write(self._ssl, buf, len(buf))
856 self._raise_ssl_error(self._ssl, result)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800857 return result
858 write = send
859
860
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800861 def sendall(self, buf, flags=0):
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800862 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800863 Send "all" data on the connection. This calls send() repeatedly until
864 all data is sent. If an error occurs, it's impossible to tell how much
865 data has been sent.
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800866
867 :param buf: The string to send
868 :param flags: (optional) Included for compatibility with the socket
869 API, the value is ignored
870 :return: The number of bytes written
871 """
Jean-Paul Calderone1aba4162013-03-05 18:50:00 -0800872 if isinstance(buf, memoryview):
873 buf = buf.tobytes()
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800874 if not isinstance(buf, bytes):
875 raise TypeError("buf must be a byte string")
876 if not isinstance(flags, int):
877 raise TypeError("flags must be an integer")
878
879 left_to_send = len(buf)
880 total_sent = 0
881 data = _api.new("char[]", buf)
882
883 while left_to_send:
884 result = _api.SSL_write(self._ssl, data + total_sent, left_to_send)
885 self._raise_ssl_error(self._ssl, result)
886 total_sent += result
887 left_to_send -= result
888
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800889
890 def recv(self, bufsiz, flags=None):
891 """
892 Receive data on the connection. NOTE: If you get one of the WantRead,
893 WantWrite or WantX509Lookup exceptions on this, you have to call the
894 method again with the SAME buffer.
895
896 :param bufsiz: The maximum number of bytes to read
897 :param flags: (optional) Included for compatibility with the socket
898 API, the value is ignored
899 :return: The string read from the Connection
900 """
901 buf = _api.new("char[]", bufsiz)
902 result = _api.SSL_read(self._ssl, buf, bufsiz)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800903 self._raise_ssl_error(self._ssl, result)
904 return _api.buffer(buf, result)[:]
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800905 read = recv
906
907
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800908 def _handle_bio_errors(self, bio, result):
909 if _api.BIO_should_retry(bio):
910 if _api.BIO_should_read(bio):
911 raise WantReadError()
912 1/0
913
914
915 def bio_read(self, bufsiz):
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800916 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800917 When using non-socket connections this function reads the "dirty" data
918 that would have traveled away on the network.
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800919
920 :param bufsiz: The maximum number of bytes to read
921 :return: The string read.
922 """
Jean-Paul Calderone97e041d2013-03-05 21:03:12 -0800923 if self._from_ssl is None:
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800924 raise TypeError("Connection sock was not None")
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800925
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800926 if not isinstance(bufsiz, int):
927 raise TypeError("bufsiz must be an integer")
928
929 buf = _api.new("char[]", bufsiz)
930 result = _api.BIO_read(self._from_ssl, buf, bufsiz)
931 if result <= 0:
932 self._handle_bio_errors(self._from_ssl, result)
933
934 return _api.buffer(buf, result)[:]
935
936
937 def bio_write(self, buf):
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800938 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800939 When using non-socket connections this function sends "dirty" data that
940 would have traveled in on the network.
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800941
942 :param buf: The string to put into the memory BIO.
943 :return: The number of bytes written
944 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800945 if self._into_ssl is None:
946 raise TypeError("Connection sock was not None")
947
948 if not isinstance(buf, bytes):
949 raise TypeError("buf must be a byte string")
950
951 result = _api.BIO_write(self._into_ssl, buf, len(buf))
952 if result <= 0:
953 self._handle_bio_errors(self._into_ssl, result)
954 return result
955
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800956
957 def renegotiate(self):
958 """
959 Renegotiate the session
960
961 :return: True if the renegotiation can be started, false otherwise
962 """
963
964 def do_handshake(self):
965 """
966 Perform an SSL handshake (usually called after renegotiate() or one of
967 set_*_state()). This can raise the same exceptions as send and recv.
968
969 :return: None.
970 """
971 result = _api.SSL_do_handshake(self._ssl)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800972 self._raise_ssl_error(self._ssl, result)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800973
974
975 def renegotiate_pending(self):
976 """
977 Check if there's a renegotiation in progress, it will return false once
978 a renegotiation is finished.
979
980 :return: Whether there's a renegotiation in progress
981 """
982
983 def total_renegotiations(self):
984 """
985 Find out the total number of renegotiations.
986
987 :return: The number of renegotiations.
988 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800989 return _api.SSL_total_renegotiations(self._ssl)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800990
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800991
992 def connect(self, addr):
Jean-Paul Calderone131052e2013-03-05 11:56:19 -0800993 """
994 Connect to remote host and set up client-side SSL
995
996 :param addr: A remote address
997 :return: What the socket's connect method returns
998 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -0800999 _api.SSL_set_connect_state(self._ssl)
1000 return self._socket.connect(addr)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001001
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001002
1003 def connect_ex(self, addr):
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001004 """
1005 Connect to remote host and set up client-side SSL. Note that if the socket's
1006 connect_ex method doesn't return 0, SSL won't be initialized.
1007
1008 :param addr: A remove address
1009 :return: What the socket's connect_ex method returns
1010 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001011 connect_ex = self._socket.connect_ex
1012 self.set_connect_state()
1013 return connect_ex(addr)
1014
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001015
1016 def accept(self):
1017 """
1018 Accept incoming connection and set up SSL on it
1019
1020 :return: A (conn,addr) pair where conn is a Connection and addr is an
1021 address
1022 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001023 client, addr = self._socket.accept()
1024 conn = Connection(self._context, client)
1025 conn.set_accept_state()
1026 return (conn, addr)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001027
1028
1029 def bio_shutdown(self):
1030 """
1031 When using non-socket connections this function signals end of
1032 data on the input for this connection.
1033
1034 :return: None
1035 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001036 if self._from_ssl is None:
1037 raise TypeError("Connection sock was not None")
1038
1039 _api.BIO_set_mem_eof_return(self._into_ssl, 0)
1040
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001041
1042 def shutdown(self):
1043 """
1044 Send closure alert
1045
1046 :return: True if the shutdown completed successfully (i.e. both sides
1047 have sent closure alerts), false otherwise (i.e. you have to
1048 wait for a ZeroReturnError on a recv() method call
1049 """
1050 result = _api.SSL_shutdown(self._ssl)
1051 if result < 0:
1052 1/0
1053 elif result > 0:
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001054 return True
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001055 else:
1056 return False
1057
1058
1059 def get_cipher_list(self):
1060 """
1061 Get the session cipher list
1062
1063 :return: A list of cipher strings
1064 """
1065 ciphers = []
1066 for i in count():
1067 result = _api.SSL_get_cipher_list(self._ssl, i)
1068 if result == _api.NULL:
1069 break
1070 ciphers.append(_api.string(result))
1071 return ciphers
1072
1073
1074 def get_client_ca_list(self):
1075 """
1076 Get CAs whose certificates are suggested for client authentication.
1077
1078 :return: If this is a server connection, a list of X509Names representing
1079 the acceptable CAs as set by :py:meth:`OpenSSL.SSL.Context.set_client_ca_list` or
1080 :py:meth:`OpenSSL.SSL.Context.add_client_ca`. If this is a client connection,
1081 the list of such X509Names sent by the server, or an empty list if that
1082 has not yet happened.
1083 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001084 ca_names = _api.SSL_get_client_CA_list(self._ssl)
1085 if ca_names == _api.NULL:
1086 1/0
1087 return []
1088
1089 result = []
1090 for i in range(_api.sk_X509_NAME_num(ca_names)):
1091 name = _api.sk_X509_NAME_value(ca_names, i)
1092 copy = _api.X509_NAME_dup(name)
1093 if copy == _api.NULL:
1094 1/0
1095 _raise_current_error(Error)
1096
1097 pyname = X509Name.__new__(X509Name)
1098 pyname._name = _api.ffi.gc(copy, _api.X509_NAME_free)
1099 result.append(pyname)
1100 return result
1101
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001102
1103 def makefile(self):
1104 """
1105 The makefile() method is not implemented, since there is no dup semantics
1106 for SSL connections
1107
1108 :raise NotImplementedError
1109 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001110 raise NotImplementedError("Cannot make file object of OpenSSL.SSL.Connection")
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001111
1112
1113 def get_app_data(self):
1114 """
1115 Get application data
1116
1117 :return: The application data
1118 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001119 return self._app_data
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001120
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001121
1122 def set_app_data(self, data):
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001123 """
1124 Set application data
1125
1126 :param data - The application data
1127 :return: None
1128 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001129 self._app_data = data
1130
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001131
1132 def get_shutdown(self):
1133 """
1134 Get shutdown state
1135
1136 :return: The shutdown state, a bitvector of SENT_SHUTDOWN, RECEIVED_SHUTDOWN.
1137 """
1138 return _api.SSL_get_shutdown(self._ssl)
1139
1140
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001141 def set_shutdown(self, state):
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001142 """
1143 Set shutdown state
1144
1145 :param state - bitvector of SENT_SHUTDOWN, RECEIVED_SHUTDOWN.
1146 :return: None
1147 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001148 if not isinstance(state, int):
1149 raise TypeError("state must be an integer")
1150
1151 _api.SSL_set_shutdown(self._ssl, state)
1152
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001153
1154 def state_string(self):
1155 """
1156 Get a verbose state description
1157
1158 :return: A string representing the state
1159 """
1160
1161 def server_random(self):
1162 """
1163 Get a copy of the server hello nonce.
1164
1165 :return: A string representing the state
1166 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001167 if self._ssl.session == _api.NULL:
1168 return None
1169 return _api.buffer(
1170 self._ssl.s3.server_random,
1171 _api.SSL3_RANDOM_SIZE)[:]
1172
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001173
1174 def client_random(self):
1175 """
1176 Get a copy of the client hello nonce.
1177
1178 :return: A string representing the state
1179 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001180 if self._ssl.session == _api.NULL:
1181 return None
1182 return _api.buffer(
1183 self._ssl.s3.client_random,
1184 _api.SSL3_RANDOM_SIZE)[:]
1185
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001186
1187 def master_key(self):
1188 """
1189 Get a copy of the master key.
1190
1191 :return: A string representing the state
1192 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001193 if self._ssl.session == _api.NULL:
1194 return None
1195 return _api.buffer(
1196 self._ssl.session.master_key,
1197 self._ssl.session.master_key_length)[:]
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001198
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001199
1200 def sock_shutdown(self, *args, **kwargs):
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001201 """
1202 See shutdown(2)
1203
1204 :return: What the socket's shutdown() method returns
1205 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001206 return self._socket.shutdown(*args, **kwargs)
1207
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001208
1209 def get_peer_certificate(self):
1210 """
1211 Retrieve the other side's certificate (if any)
1212
1213 :return: The peer's certificate
1214 """
1215 cert = _api.SSL_get_peer_certificate(self._ssl)
1216 if cert != _api.NULL:
1217 pycert = X509.__new__(X509)
1218 pycert._x509 = _api.ffi.gc(cert, _api.X509_free)
1219 return pycert
1220 return None
1221
1222
1223 def get_peer_cert_chain(self):
1224 """
1225 Retrieve the other side's certificate (if any)
1226
1227 :return: A list of X509 instances giving the peer's certificate chain,
1228 or None if it does not have one.
1229 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001230 cert_stack = _api.SSL_get_peer_cert_chain(self._ssl)
1231 if cert_stack == _api.NULL:
1232 return None
1233
1234 result = []
1235 for i in range(_api.sk_X509_num(cert_stack)):
Jean-Paul Calderone73b15c22013-03-05 18:30:39 -08001236 # TODO could incref instead of dup here
1237 cert = _api.X509_dup(_api.sk_X509_value(cert_stack, i))
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001238 pycert = X509.__new__(X509)
Jean-Paul Calderone73b15c22013-03-05 18:30:39 -08001239 pycert._x509 = _api.ffi.gc(cert, _api.X509_free)
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001240 result.append(pycert)
1241 return result
1242
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001243
1244 def want_read(self):
1245 """
1246 Checks if more data has to be read from the transport layer to complete an
1247 operation.
1248
1249 :return: True iff more data has to be read
1250 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001251 return _api.SSL_want_read(self._ssl)
1252
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001253
1254 def want_write(self):
1255 """
1256 Checks if there is data to write to the transport layer to complete an
1257 operation.
1258
1259 :return: True iff there is data to write
1260 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001261 return _api.SSL_want_write(self._ssl)
1262
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001263
1264 def set_accept_state(self):
1265 """
1266 Set the connection to work in server mode. The handshake will be handled
1267 automatically by read/write.
1268
1269 :return: None
1270 """
1271 _api.SSL_set_accept_state(self._ssl)
1272
1273
1274 def set_connect_state(self):
1275 """
1276 Set the connection to work in client mode. The handshake will be handled
1277 automatically by read/write.
1278
1279 :return: None
1280 """
1281 _api.SSL_set_connect_state(self._ssl)
1282
1283
1284 def get_session(self):
1285 """
1286 Returns the Session currently used.
1287
1288 @return: An instance of :py:class:`OpenSSL.SSL.Session` or :py:obj:`None` if
1289 no session exists.
1290 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001291 session = _api.SSL_get1_session(self._ssl)
1292 if session == _api.NULL:
1293 return None
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001294
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001295 pysession = Session.__new__(Session)
1296 pysession._session = _api.ffi.gc(session, _api.SSL_SESSION_free)
1297 return pysession
1298
1299
1300 def set_session(self, session):
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001301 """
1302 Set the session to be used when the TLS/SSL connection is established.
1303
1304 :param session: A Session instance representing the session to use.
1305 :returns: None
1306 """
Jean-Paul Calderonea63714c2013-03-05 17:02:26 -08001307 if not isinstance(session, Session):
1308 raise TypeError("session must be a Session instance")
1309
1310 result = _api.SSL_set_session(self._ssl, session._session)
1311 if not result:
1312 _raise_current_error(Error)
Jean-Paul Calderone131052e2013-03-05 11:56:19 -08001313
1314ConnectionType = Connection