Author: Amaury Forgeot d'Arc <[email protected]>
Branch: py3.6
Changeset: r94414:6dc2dbf20397
Date: 2018-04-22 20:41 +0200
http://bitbucket.org/pypy/pypy/changeset/6dc2dbf20397/
Log: Implement SSLSession.
diff --git a/lib_pypy/_cffi_ssl/_cffi_src/openssl/ssl.py
b/lib_pypy/_cffi_ssl/_cffi_src/openssl/ssl.py
--- a/lib_pypy/_cffi_ssl/_cffi_src/openssl/ssl.py
+++ b/lib_pypy/_cffi_ssl/_cffi_src/openssl/ssl.py
@@ -198,6 +198,8 @@
const char *SSL_get_cipher_list(const SSL *, int);
Cryptography_STACK_OF_SSL_CIPHER *SSL_get_ciphers(const SSL *);
+int SSL_is_init_finished(const SSL*);
+
/* context */
void SSL_CTX_free(SSL_CTX *);
long SSL_CTX_set_timeout(SSL_CTX *, long);
@@ -265,6 +267,10 @@
SSL_SESSION *SSL_get_session(const SSL *);
const unsigned char *SSL_SESSION_get_id(const SSL_SESSION *, unsigned int *);
+long SSL_SESSION_get_time(const SSL_SESSION *);
+long SSL_SESSION_get_timeout(const SSL_SESSION *);
+int SSL_SESSION_has_ticket(const SSL_SESSION *);
+long SSL_SESSION_get_ticket_lifetime_hint(const SSL_SESSION *);
/* not a macro, but older OpenSSLs don't pass the args as const */
char *SSL_CIPHER_description(const SSL_CIPHER *, char *, int);
@@ -509,6 +515,14 @@
memcpy(out, session->master_key, outlen);
return outlen;
}
+
+int SSL_SESSION_has_ticket(const SSL_SESSION *s) {
+ return (s->tlsext_ticklen > 0) ? 1 : 0;
+}
+unsigned long SSL_SESSION_get_ticket_lifetime_hint(const SSL_SESSION *s)
+{
+ return s->tlsext_tick_lifetime_hint;
+}
#endif
static const long Cryptography_HAS_SECURE_RENEGOTIATION = 1;
diff --git a/lib_pypy/_cffi_ssl/_stdssl/__init__.py
b/lib_pypy/_cffi_ssl/_stdssl/__init__.py
--- a/lib_pypy/_cffi_ssl/_stdssl/__init__.py
+++ b/lib_pypy/_cffi_ssl/_stdssl/__init__.py
@@ -693,7 +693,20 @@
@property
def session(self):
"Get / set SSLSession."
- return None
+ return Session(self)
+
+ @session.setter
+ def session(self, value):
+ if not isinstance(value, Session):
+ raise TypeError("Value is not a SSLSession.")
+ if self.ctx.ctx != value._ctx.ctx:
+ raise ValueError("Session refers to a different SSLContext.")
+ if self.socket_type != SSL_CLIENT:
+ raise ValueError("Cannot set session for server-side SSLSocket.")
+ if lib.SSL_is_init_finished(self.ssl):
+ raise ValueError("Cannot set session after handshake.")
+ if not lib.SSL_set_session(self.ssl, value._session):
+ raise pyssl_error(self, 0)
@property
def session_reused(self):
@@ -727,6 +740,43 @@
return (cipher_name, cipher_protocol, bits)
+class Session(object):
+ def __new__(cls, ssl):
+ self = object.__new__(cls)
+ session = lib.SSL_get1_session(ssl.ssl)
+ if not session:
+ return None
+ self._session = ffi.gc(session, lib.SSL_SESSION_free)
+ self._ctx = ssl.ctx
+ return self
+
+ def __eq__(self, other):
+ if not isinstance(other, Session):
+ return NotImplemented;
+ return self.id == other.id
+
+ @property
+ def id(self):
+ lenp = ffi.new("unsigned int*")
+ id = lib.SSL_SESSION_get_id(self._session, lenp)
+ return ffi.string(id, lenp[0])
+
+ @property
+ def time(self):
+ return lib.SSL_SESSION_get_time(self._session)
+
+ @property
+ def timeout(self):
+ return lib.SSL_SESSION_get_timeout(self._session)
+
+ @property
+ def has_ticket(self):
+ return bool(lib.SSL_SESSION_has_ticket(self._session))
+
+ @property
+ def ticket_lifetime_hint(self):
+ return lib.SSL_SESSION_get_ticket_lifetime_hint(self._session)
+
SSL_CTX_STATS_NAMES = """
number connect connect_good connect_renegotiate accept accept_good
_______________________________________________
pypy-commit mailing list
[email protected]
https://mail.python.org/mailman/listinfo/pypy-commit