]> granicus.if.org Git - python/commitdiff
prefer server alpn ordering over the client's
authorBenjamin Peterson <benjamin@python.org>
Fri, 23 Jan 2015 22:30:26 +0000 (17:30 -0500)
committerBenjamin Peterson <benjamin@python.org>
Fri, 23 Jan 2015 22:30:26 +0000 (17:30 -0500)
Doc/library/ssl.rst
Lib/test/test_ssl.py
Modules/_ssl.c

index 11b8aa908508a1e67f0d30ac465f66acb3018aee..e7cf4250e2dc8eae43a4caba010ef74c0a72cfcb 100644 (file)
@@ -970,7 +970,8 @@ SSL sockets also have the following additional methods and attributes:
 
    Return the protocol that was selected during the TLS handshake.  If
    :meth:`SSLContext.set_alpn_protocols` was not called, if the other party does
-   not support ALPN, or if the handshake has not happened yet, ``None`` is
+   not support ALPN, if this socket does not support any of the client's
+   proposed protocols, or if the handshake has not happened yet, ``None`` is
    returned.
 
    .. versionadded:: 3.5
index 30af08d0b0d470d1cde0cc1ca825f71fdb120619..879d6fd788d92b2a00840a303638f4ab8dab47bd 100644 (file)
@@ -3054,9 +3054,9 @@ else:
             server_protocols = ['foo', 'bar', 'milkshake']
             protocol_tests = [
                 (['foo', 'bar'], 'foo'),
-                (['bar', 'foo'], 'bar'),
+                (['bar', 'foo'], 'foo'),
                 (['milkshake'], 'milkshake'),
-                (['http/3.0', 'http/4.0'], 'foo')
+                (['http/3.0', 'http/4.0'], None)
             ]
             for client_protocols, expected in protocol_tests:
                 server_context = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
index 2e19439366d665474c4c58ad69543129a465e16e..f0f362c117148a0cdfefdedca45c1bfca3d90597 100644 (file)
@@ -2276,18 +2276,25 @@ set_ciphers(PySSLContext *self, PyObject *args)
 }
 
 static int
-do_protocol_selection(unsigned char **out, unsigned char *outlen,
-                      const unsigned char *remote_protocols, unsigned int remote_protocols_len,
-                      unsigned char *our_protocols, unsigned int our_protocols_len)
+do_protocol_selection(int alpn, unsigned char **out, unsigned char *outlen,
+                      const unsigned char *server_protocols, unsigned int server_protocols_len,
+                      const unsigned char *client_protocols, unsigned int client_protocols_len)
 {
-    if (our_protocols == NULL) {
-        our_protocols = (unsigned char*)"";
-        our_protocols_len = 0;
+    int ret;
+    if (client_protocols == NULL) {
+        client_protocols = (unsigned char *)"";
+        client_protocols_len = 0;
+    }
+    if (server_protocols == NULL) {
+        server_protocols = (unsigned char *)"";
+        server_protocols_len = 0;
     }
 
-    SSL_select_next_proto(out, outlen,
-                          remote_protocols, remote_protocols_len,
-                          our_protocols, our_protocols_len);
+    ret = SSL_select_next_proto(out, outlen,
+                                server_protocols, server_protocols_len,
+                                client_protocols, client_protocols_len);
+    if (alpn && ret != OPENSSL_NPN_NEGOTIATED)
+        return SSL_TLSEXT_ERR_NOACK;
 
     return SSL_TLSEXT_ERR_OK;
 }
@@ -2319,7 +2326,7 @@ _selectNPN_cb(SSL *s,
               void *args)
 {
     PySSLContext *ctx = (PySSLContext *)args;
-    return do_protocol_selection(out, outlen, server, server_len,
+    return do_protocol_selection(0, out, outlen, server, server_len,
                                  ctx->npn_protocols, ctx->npn_protocols_len);
 }
 #endif
@@ -2371,9 +2378,9 @@ _selectALPN_cb(SSL *s,
               void *args)
 {
     PySSLContext *ctx = (PySSLContext *)args;
-    return do_protocol_selection((unsigned char **)out, outlen,
-                                 client_protocols, client_protocols_len,
-                                 ctx->alpn_protocols, ctx->alpn_protocols_len);
+    return do_protocol_selection(1, (unsigned char **)out, outlen,
+                                 ctx->alpn_protocols, ctx->alpn_protocols_len,
+                                 client_protocols, client_protocols_len);
 }
 #endif