Skip to content

Commit

Permalink
Merge pull request #397 from alefend/master
Browse files Browse the repository at this point in the history
Only use pyOpenSSL when using Python < 2.7.9
  • Loading branch information
Brett Hazen committed May 18, 2015
2 parents 2810cea + 8023f22 commit 2008ae1
Show file tree
Hide file tree
Showing 6 changed files with 144 additions and 134 deletions.
86 changes: 48 additions & 38 deletions riak/security.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,34 +16,25 @@
under the License.
"""

import ssl
import warnings
from six import PY2
from riak import RiakError
from riak.util import str_to_long

OPENSSL_VERSION_101G = 268439679
if PY2:
if hasattr(ssl, 'SSLContext'):
# For Python >= 2.7.9 and Python 3.x
USE_STDLIB_SSL = True
else:
# For Python 2.6 and <= 2.7.8
USE_STDLIB_SSL = False

if not USE_STDLIB_SSL:
import OpenSSL.SSL
from OpenSSL import crypto
sslver = OpenSSL.SSL.OPENSSL_VERSION_NUMBER
# Be sure to use at least OpenSSL 1.0.1g
if (sslver < OPENSSL_VERSION_101G) or \
not hasattr(OpenSSL.SSL, 'TLSv1_2_METHOD'):
verstring = OpenSSL.SSL.SSLeay_version(OpenSSL.SSL.SSLEAY_VERSION)
msg = "Found {0} version, but expected at least OpenSSL 1.0.1g. " \
"Security may not support TLS 1.2.".format(verstring)
warnings.warn(msg, UserWarning)
if hasattr(OpenSSL.SSL, 'TLSv1_2_METHOD'):
DEFAULT_TLS_VERSION = OpenSSL.SSL.TLSv1_2_METHOD
elif hasattr(OpenSSL.SSL, 'TLSv1_1_METHOD'):
DEFAULT_TLS_VERSION = OpenSSL.SSL.TLSv1_1_METHOD
elif hasattr(OpenSSL.SSL, 'TLSv1_METHOD'):
DEFAULT_TLS_VERSION = OpenSSL.SSL.TLSv1_METHOD
else:
DEFAULT_TLS_VERSION = OpenSSL.SSL.SSLv23_METHOD
else:
import ssl

OPENSSL_VERSION_101G = 268439679
if hasattr(ssl, 'OPENSSL_VERSION_NUMBER'):
# For Python 2.7 and Python 3.x
sslver = ssl.OPENSSL_VERSION_NUMBER
# Be sure to use at least OpenSSL 1.0.1g
if sslver < OPENSSL_VERSION_101G or \
Expand All @@ -61,6 +52,25 @@
else:
DEFAULT_TLS_VERSION = ssl.PROTOCOL_SSLv23

else:
# For Python 2.6
sslver = OpenSSL.SSL.OPENSSL_VERSION_NUMBER
# Be sure to use at least OpenSSL 1.0.1g
if (sslver < OPENSSL_VERSION_101G) or \
not hasattr(OpenSSL.SSL, 'TLSv1_2_METHOD'):
verstring = OpenSSL.SSL.SSLeay_version(OpenSSL.SSL.SSLEAY_VERSION)
msg = "Found {0} version, but expected at least OpenSSL 1.0.1g. " \
"Security may not support TLS 1.2.".format(verstring)
warnings.warn(msg, UserWarning)
if hasattr(OpenSSL.SSL, 'TLSv1_2_METHOD'):
DEFAULT_TLS_VERSION = OpenSSL.SSL.TLSv1_2_METHOD
elif hasattr(OpenSSL.SSL, 'TLSv1_1_METHOD'):
DEFAULT_TLS_VERSION = OpenSSL.SSL.TLSv1_1_METHOD
elif hasattr(OpenSSL.SSL, 'TLSv1_METHOD'):
DEFAULT_TLS_VERSION = OpenSSL.SSL.TLSv1_METHOD
else:
DEFAULT_TLS_VERSION = OpenSSL.SSL.SSLv23_METHOD


class SecurityError(RiakError):
"""
Expand Down Expand Up @@ -197,7 +207,7 @@ def ssl_version(self):
"""
return self._ssl_version

if PY2:
if not USE_STDLIB_SSL:
@property
def pkey(self):
"""
Expand Down Expand Up @@ -266,20 +276,20 @@ def _has_credential(self, key):
return (getattr(self, internal_key) is not None) or \
(getattr(self, internal_key + "_file") is not None)

def _check_revoked_cert(self, ssl_socket):
"""
Checks whether the server certificate on the passed socket has been
revoked by checking the CRL.
def _check_revoked_cert(self, ssl_socket):
"""
Checks whether the server certificate on the passed socket has been
revoked by checking the CRL.
:param ssl_socket: the SSL/TLS socket
:rtype: bool
:raises SecurityError: when the certificate has been revoked
"""
if not self._has_credential('crl'):
return True

servcert = ssl_socket.get_peer_certificate()
servserial = servcert.get_serial_number()
for rev in self.crl.get_revoked():
if servserial == str_to_long(rev.get_serial(), 16):
raise SecurityError("Server certificate has been revoked")
:param ssl_socket: the SSL/TLS socket
:rtype: bool
:raises SecurityError: when the certificate has been revoked
"""
if not self._has_credential('crl'):
return True

servcert = ssl_socket.get_peer_certificate()
servserial = servcert.get_serial_number()
for rev in self.crl.get_revoked():
if servserial == str_to_long(rev.get_serial(), 16):
raise SecurityError("Server certificate has been revoked")
11 changes: 5 additions & 6 deletions riak/tests/test_security.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,16 +17,15 @@
under the License.
"""

import platform
if platform.python_version() < '2.7':
import sys
if sys.version_info < (2, 7):
unittest = __import__('unittest2')
else:
import unittest
from riak.tests import RUN_SECURITY, SECURITY_USER, SECURITY_PASSWD, \
SECURITY_CACERT, SECURITY_KEY, SECURITY_CERT, SECURITY_REVOKED, \
SECURITY_CERT_USER, SECURITY_CERT_PASSWD, SECURITY_BAD_CERT
from riak.security import SecurityCreds
from six import PY3


class SecurityTests(object):
Expand Down Expand Up @@ -110,9 +109,9 @@ def test_security_revoked_cert(self):
creds = SecurityCreds(username=SECURITY_USER, password=SECURITY_PASSWD,
cacert_file=SECURITY_CACERT,
crl_file=SECURITY_REVOKED)
# Curenly Python 3.x native CRL doesn't seem to work
# as advertised
if PY3:
# Currently Python >= 2.7.9 and Python 3.x native CRL doesn't seem to
# work as advertised
if sys.version_info >= (2, 7, 9):
return
client = self.create_client(credentials=creds)
with self.assertRaises(Exception):
Expand Down
16 changes: 9 additions & 7 deletions riak/transports/http/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,27 +19,29 @@
import socket
import select
from six import PY2
if PY2:
from riak.security import SecurityError, USE_STDLIB_SSL
if USE_STDLIB_SSL:
import ssl
from riak.transports.security import configure_ssl_context
else:
import OpenSSL.SSL
from riak.transports.security import RiakWrappedSocket,\
configure_pyopenssl_context
if PY2:
from httplib import HTTPConnection, \
NotConnected, \
IncompleteRead, \
ImproperConnectionState, \
BadStatusLine, \
HTTPSConnection
from riak.transports.security import RiakWrappedSocket,\
configure_pyopenssl_context
else:
from http.client import HTTPConnection, \
HTTPSConnection, \
NotConnected, \
IncompleteRead, \
ImproperConnectionState, \
BadStatusLine
import ssl
from riak.transports.security import configure_ssl_context

from riak.security import SecurityError
from riak.transports.pool import Pool
from riak.transports.http.transport import RiakHttpTransport

Expand Down Expand Up @@ -106,7 +108,7 @@ def connect(self):
Connect to a host on a given (SSL) port using PyOpenSSL.
"""
sock = socket.create_connection((self.host, self.port), self.timeout)
if PY2:
if not USE_STDLIB_SSL:
ssl_ctx = configure_pyopenssl_context(self.credentials)

# attempt to upgrade the socket to TLS
Expand Down
6 changes: 3 additions & 3 deletions riak/transports/pbc/connection.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
import socket
import struct
import riak_pb
from riak.security import SecurityError
from riak.security import SecurityError, USE_STDLIB_SSL
from riak import RiakError
from riak_pb.messages import (
MESSAGE_CLASSES,
Expand All @@ -30,7 +30,7 @@
)
from riak.util import bytes_to_str, str_to_bytes
from six import PY2
if PY2:
if not USE_STDLIB_SSL:
from OpenSSL.SSL import Connection
from riak.transports.security import configure_pyopenssl_context
else:
Expand Down Expand Up @@ -113,7 +113,7 @@ def _auth(self):
else:
return False

if PY2:
if not USE_STDLIB_SSL:
def _ssl_handshake(self):
"""
Perform an SSL handshake w/ the server.
Expand Down
Loading

0 comments on commit 2008ae1

Please sign in to comment.