title: Client authentication using CAC (smartcard) with python M2Crypto
body: <p>I'm trying to use M2Crypto and urllib2 to communicate with a website protected by a CAC (smartcard). Doing some research, my understanding is that I need to provide client side cert and private key from the card, and the CA certs which I've downloaded online. I can't figure out if I'm missing a step; can't get the a properly authenticated connection. </p>
  
  <pre class="lang-py prettyprint-override"><code>import sys, os, time, cgi, urllib, urlparse
  from M2Crypto import m2urllib2 as urllib2
  from M2Crypto import m2, SSL, Engine
  
  userPin = "SOMEPIN"
  theurl = "https://www.example.com"
  
  rootCertsPath = "/Path/to/folder/with/multiple/certfiles"
  
  # load dynamic engine
  e = Engine.load_dynamic_engine("pkcs11", "/usr/local/Cellar/engine_pkcs11/0.1.8/lib/engines/engine_pkcs11.so")
  pk = Engine.Engine("pkcs11")
  pk.ctrl_cmd_string("MODULE_PATH", "/usr/local/lib/opensc-pkcs11.so")
  if len(userPin) &gt; 0: pk.ctrl_cmd_string("PIN", userPin)
  m2.engine_init(m2.engine_by_id("pkcs11")) 
  
  # grab pkey and cert from smartcard
  key = e.load_private_key("id_01")
  cert = e.load_certificate("id_01")
  
  # create context
  ssl_context = SSL.Context("sslv23")
  ssl_context.set_cipher_list("HIGH:!aNULL:!eNULL:@STRENGTH") 
  ssl_context.set_session_id_ctx("foobar")
  ret = ssl_context.load_verify_locations(capath=rootCertsPath)
  
  m2.ssl_ctx_use_x509(ssl_context.ctx, cert.x509)
  m2.ssl_ctx_use_pkey_privkey(ssl_context.ctx, key.pkey)
  
  opener = urllib2.build_opener(ssl_context)
  urllib2.install_opener(opener)
  
  req = urllib2.Request(theurl)
  res = urllib2.urlopen(req);
  
  print res.read()
  </code></pre>