1

I am attempting to use rauth to do oauth with twitter, but it seems to be failing with the following error:

requests.exceptions.SSLError: [Errno 1] _ssl.c:504: error:140770FC:SSL routines:SSL23_GET_SERVER_HELLO:unknown protocol

After some testing, I find that requests seems to be breaking when attempting to access api.twitter.com and verifying the https connection. Here is an example, It appears to work for https://github.com, but fails for https://api.twitter.com:

>>> import requests
>>> requests.get('https://github.com', verify=True)
<Response [200]>
>>> requests.get('https://api.twitter.com/oauth/request_token',verify=True)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "requests/api.py", line 65, in get
    return request('get', url, **kwargs)
  File "requests/safe_mode.py", line 39, in wrapped
    return function(method, url, **kwargs)
  File "requests/api.py", line 51, in request
    return session.request(method=method, url=url, **kwargs)
  File "requests/sessions.py", line 252, in request
    r.send(prefetch=prefetch)
  File "requests/models.py", line 632, in send
    raise SSLError(e)
requests.exceptions.SSLError: [Errno 1] _ssl.c:504: error:140770FC:SSL routines:SSL23_GET_SERVER_HELLO:unknown protocol
>>> requests.get('https://api.twitter.com',verify=True)
[SNIP] Same error as above

Is this a bug in requests? This should be similar to what rauth is running, so I am not sure why it is not working on my machine.

With some great disccusion from @thomas-orozco it appears to be an openssl being unable to verify the G2 VeriSign certificate: http://pastebin.com/ZZj3s5uN

It does appear that I have the VeriSign CA by using certool:

certtool y k=/System/Library/Keychains/SystemCACertificates.keychain | grep -i verisign

Which is being used by chrome / safari, just not by openssl on the command line. Is there something that I can do so that Requests will load the right certificate?

maxcountryman
  • 1,562
  • 1
  • 24
  • 51
Alex
  • 293
  • 3
  • 10
  • This is not a `requests` issue but an SSL one. I don't seem to be experiencing the issue either. You might want to have a look at http://marc.info/?l=openssl-users&m=124875408916917 for some ideas on how to debug that. Basically, you should try using `openssl s_client -debug`. – Thomas Orozco Sep 09 '12 at 21:28
  • I am using a pretty much just formatted osx 10.8 install, so I am not sure why that openssl is the problem. Also from my above example github https verifies, but api.twitter does not. Checking out openssl: http://pastebin.com/ZZj3s5uN it seems that it cannot get local issuer certificate. Is there a reason that the twitter chain is not being loaded, but works in chrome on the same system? _Thank you for finding that link_ – Alex Sep 09 '12 at 21:40
  • Your `openssl` install seems to be missing the following certificate: `/C=US/O=VeriSign, Inc./OU=Class 3 Public Primary Certification Authority - G2/OU=(c) 1998 VeriSign, Inc. - For authorized use only/OU=VeriSign Trust Network`. This is pretty surprising though, my OpenSSL install has it - but I'm running Ubuntu. Maybe http://gagravarr.org/writing/openssl-certs/others.shtml#ca-osx could help you. – Thomas Orozco Sep 09 '12 at 21:53
  • Little update, I forgot to tell you to point the `CApath` `s_client` param to the dir where you certificates are located. (No idea where it is on Mac OS, though). – Thomas Orozco Sep 09 '12 at 22:02
  • For others, osx keeps all of the certs under the keychain files. See here for more information: http://stackoverflow.com/questions/10095676/openssl-reasonable-default-for-trusted-ca-certificates. After some digging and this command `certtool y k=/System/Library/Keychains/SystemRootCertificates.keychain | grep -i verisign` it appears that I have the G(eneration)3 certs installed, and twitter is only returning the G2 cert, even though they are suppose to have gone to G3: 12weeks ago: https://dev.twitter.com/discussions/7531. I guess I should talk to twitter. – Alex Sep 09 '12 at 22:10
  • On further thinking, it appears that I do have a VeriSign root: which contains both G2 and G3 `certtool y k=/System/Library/Keychains/SystemCACertificates.keychain | grep -i verisign` but I am still not sure why openssl cannot verify it, but chrome / safari can. – Alex Sep 09 '12 at 22:14
  • Was this ever resolved? I'd be curious to see what happens if you give rauth 0.5.3 a shot (which relies on Requests' 1.1.0 which in turn should provide better SSL support via urllib3). – maxcountryman Mar 28 '13 at 21:54

1 Answers1

0

I gave this a shot with rauth 0.5.3 and Requests 1.1.0; for reference, I'm on a fresh install of OS X 10.8.3. It seems to be working as expected. Here's the example script I used:

from rauth import OAuth1Service

# Get a real consumer key & secret from https://dev.twitter.com/apps/new
twitter = OAuth1Service(
    name='twitter',
    consumer_key='J8MoJG4bQ9gcmGh8H7XhMg',
    consumer_secret='7WAscbSy65GmiVOvMU5EBYn5z80fhQkcFWSLMJJu4',
    request_token_url='https://api.twitter.com/oauth/request_token',
    access_token_url='https://api.twitter.com/oauth/access_token',
    authorize_url='https://api.twitter.com/oauth/authorize',
    base_url='https://api.twitter.com/1/')

request_token, request_token_secret = twitter.get_request_token(verify=True)

authorize_url = twitter.get_authorize_url(request_token)

print 'Visit this URL in your browser: ' + authorize_url
pin = raw_input('Enter PIN from browser: ')

session = twitter.get_auth_session(request_token,
                                   request_token_secret,
                                   method='POST',
                                   data={'oauth_verifier': pin},
                                   verify=True)

params = {'include_rts': 1,  # Include retweets
          'count': 10}       # 10 tweets

r = session.get('statuses/home_timeline.json', params=params, verify=True)

for i, tweet in enumerate(r.json(), 1):
    handle = tweet['user']['screen_name'].encode('utf-8')
    text = tweet['text'].encode('utf-8')
    print '{0}. @{1} - {2}'.format(i, handle, text)

My advice is to try updating, if you can, and see what results that yields. I suspect that the underlying updates to urllib3 with help remedy this situation. Please note that in order to use rauth with > Requests 1.0.0 you must be using rauth 0.5.x; older version are not compatible with Requests 1.0.0 API changes.

maxcountryman
  • 1,562
  • 1
  • 24
  • 51