Using OpenSSL

App Engine supports the native Python OpenSSL for the Python 2.7 runtime via the ssl library, which you must add to your app.

Specifying the SSL library

If you want to use native python SSL, you must enable it using the libraries configuration in your application's app.yaml file where you specify the library name "ssl". There are two libraries available, version 2.7 supports TLS v1.0 only:

libraries:
- name: ssl
  version: 2.7

Version 2.7.11 supports TLS v1.0, v1.1, and v1.2:

libraries:
- name: ssl
  version: 2.7.11

Providing authority certificates

In order to perform an SSL handshake, you must have file that contains concatenated certificate authority certificates. You can upload your own file with your application, or you can use the file provided by App Engine: /etc/ca-certificates.crt.

Performing an SSL handshake

The python 2.7 wrap_socket method takes two file name parameters that contain the client's key and certificate. In the App Engine environment, this is limiting since the application is not able to write files to dynamically provide different keys and certificates. To get around this limitation, the certfile and keyfile parameters for the ssl.wrap_socket method can be "file-like" objects that allow the application to store certificates and keys in other ways than in just uploaded application files. (A "file-like" object is one that has a "read" method returning the entire certificate as a string.)

  # Example of a dynamic key and cert.
  datastore_record_k = ndb.Key('Employee', 'asalieri', 'Address', 1)
  datastore_record = datastore_record_k.get()
  key_str = datastore_record.key_str
  cert_str = datastore_record.cert
  ssl_server = ssl.wrap_socket(server_sock,
                              server_side=False,
                              keyfile=StringIO.StringIO(key_str),
                              certfile=StringIO.StringIO(cert_str),
                              cert_reqs=ssl.CERT_REQUIRED,
                              ssl_version=ssl.PROTOCOL_TLSv1,
                              ca_certs=CERTIFICATE_FILE)

You do not need to specify the ssl_version parameter. If you leave it out, the 2.7 library defaults to PROTOCOL_TLSv1.

The 2.7.11 library defaults to PROTOCOL_SSLv23. You can also specify PROTOCOL_TLSv1, PROTOCOL_TLSv1_1, or PROTOCOL_TLSv1_2.

The App Engine implementation of the wrap_socket method includes the required parameter ca_certs, which is used to specify the special file containing concatenated certificate authority certificates.

Validating the certificate

After you've performed a successful SSL handshake, you must validate that the certificate supplied by the peer matches one of the designated hosts in the peer's certificate. This provides security and can prevent "man in the middle" attacks.

Use the match_hostname which is backported from Python 3.2 and is part of the Engine 2.7 SSL module. It is available in both version 2.7 and 2.7.11:

    ssl.match_hostname(ssl_server.getpeercert(), 'a.hostname.com')

Send feedback about...

App Engine standard environment for Python