From a1e60da8d42afdaa7eae9965c64cf0c6204434a7 Mon Sep 17 00:00:00 2001
From: "mattm@chromium.org"
 <mattm@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>
Date: Tue, 6 Dec 2011 04:24:58 +0000
Subject: Add NSS function to retrieve TLS client cert types requested by
 server.

BUG=88782
TEST=none

Review URL: http://codereview.chromium.org/8771031

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@113109 0039d316-1c4b-4281-b951-d872f2087c98
---
 net/third_party/nss/README.chromium                |   4 +
 net/third_party/nss/patches/applypatches.sh        |   2 +
 .../nss/patches/getrequestedclientcerttypes.patch  | 103 +++++++++++++++++++++
 net/third_party/nss/ssl/ssl.h                      |  10 ++
 net/third_party/nss/ssl/ssl3con.c                  |   4 +
 net/third_party/nss/ssl/sslimpl.h                  |   4 +
 net/third_party/nss/ssl/sslsock.c                  |  16 +++-
 7 files changed, 142 insertions(+), 1 deletion(-)
 create mode 100644 net/third_party/nss/patches/getrequestedclientcerttypes.patch

(limited to 'net')

diff --git a/net/third_party/nss/README.chromium b/net/third_party/nss/README.chromium
index 4ab79e9..e85e7c4 100644
--- a/net/third_party/nss/README.chromium
+++ b/net/third_party/nss/README.chromium
@@ -82,6 +82,10 @@ Patches:
     https://bugzilla.mozilla.org/show_bug.cgi?id=691991
     patches/encryptedclientcerts.patch
 
+  * Add function to retrieve TLS client cert types requested by server.
+    TODO(mattm): post to bugzilla
+    patches/getrequestedclientcerttypes.patch
+
 Apply the patches to NSS by running the patches/applypatches.sh script.  Read
 the comments at the top of patches/applypatches.sh for instructions.
 
diff --git a/net/third_party/nss/patches/applypatches.sh b/net/third_party/nss/patches/applypatches.sh
index 1cdca865..0f8454f 100755
--- a/net/third_party/nss/patches/applypatches.sh
+++ b/net/third_party/nss/patches/applypatches.sh
@@ -40,3 +40,5 @@ patch -p6 < $patches_dir/restartclientauth.patch
 patch -p6 < $patches_dir/negotiatedextension.patch
 
 patch -p3 < $patches_dir/encryptedclientcerts.patch
+
+patch -p3 < $patches_dir/getrequestedclientcerttypes.patch
diff --git a/net/third_party/nss/patches/getrequestedclientcerttypes.patch b/net/third_party/nss/patches/getrequestedclientcerttypes.patch
new file mode 100644
index 0000000..bc054dc
--- /dev/null
+++ b/net/third_party/nss/patches/getrequestedclientcerttypes.patch
@@ -0,0 +1,103 @@
+Index: security/nss/lib/ssl/ssl.h
+===================================================================
+RCS file: /cvsroot/mozilla/security/nss/lib/ssl/ssl.h,v
+retrieving revision 1.38.2.1
+diff -u -r1.38.2.1 ssl.h
+--- security/nss/lib/ssl/ssl.h	31 Jul 2010 04:33:52 -0000	1.38.2.1
++++ security/nss/lib/ssl/ssl.h	6 Dec 2011 00:24:08 -0000
+@@ -459,6 +459,16 @@
+                                                 PRBool flushCache,
+                                                 PRIntervalTime timeout);
+ 
++/* Returns a SECItem containing the certificate_types field of the
++** CertificateRequest message.  Each byte of the data is a TLS
++** ClientCertificateType value, and they are ordered from most preferred to
++** least.  This function should only be called from the
++** SSL_GetClientAuthDataHook callback, and will return NULL if called at any
++** other time.  The returned value is valid only until the callback returns, and
++** should not be freed.
++*/
++SSL_IMPORT const SECItem *
++SSL_GetRequestedClientCertificateTypes(PRFileDesc *fd);
+ 
+ #ifdef SSL_DEPRECATED_FUNCTION 
+ /* deprecated!
+Index: security/nss/lib/ssl/ssl3con.c
+===================================================================
+RCS file: /cvsroot/mozilla/security/nss/lib/ssl/ssl3con.c,v
+retrieving revision 1.142.2.4
+diff -u -r1.142.2.4 ssl3con.c
+--- security/nss/lib/ssl/ssl3con.c	1 Sep 2010 19:47:11 -0000	1.142.2.4
++++ security/nss/lib/ssl/ssl3con.c	6 Dec 2011 00:24:08 -0000
+@@ -5473,6 +5473,9 @@
+     if (rv != SECSuccess)
+     	goto loser;		/* malformed, alert has been sent */
+ 
++    PORT_Assert(!ss->requestedCertTypes);
++    ss->requestedCertTypes = &cert_types;
++
+     arena = ca_list.arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
+     if (arena == NULL)
+     	goto no_mem;
+@@ -5608,6 +5611,7 @@
+     PORT_SetError(errCode);
+     rv = SECFailure;
+ done:
++    ss->requestedCertTypes = NULL;
+     if (arena != NULL)
+     	PORT_FreeArena(arena, PR_FALSE);
+     return rv;
+Index: security/nss/lib/ssl/sslimpl.h
+===================================================================
+RCS file: /cvsroot/mozilla/security/nss/lib/ssl/sslimpl.h,v
+retrieving revision 1.77.2.1
+diff -u -r1.77.2.1 sslimpl.h
+--- security/nss/lib/ssl/sslimpl.h	31 Jul 2010 04:33:52 -0000	1.77.2.1
++++ security/nss/lib/ssl/sslimpl.h	6 Dec 2011 00:24:08 -0000
+@@ -1044,6 +1044,10 @@
+     unsigned int     sizeCipherSpecs;
+ const unsigned char *  preferredCipher;
+ 
++    /* TLS ClientCertificateTypes requested during HandleCertificateRequest. */
++    /* Will be NULL at all other times. */
++    const SECItem      *requestedCertTypes;
++
+     ssl3KeyPair *         stepDownKeyPair;	/* RSA step down keys */
+ 
+     /* Callbacks */
+Index: security/nss/lib/ssl/sslsock.c
+===================================================================
+RCS file: /cvsroot/mozilla/security/nss/lib/ssl/sslsock.c,v
+retrieving revision 1.67.2.1
+diff -u -r1.67.2.1 sslsock.c
+--- security/nss/lib/ssl/sslsock.c	31 Jul 2010 04:33:52 -0000	1.67.2.1
++++ security/nss/lib/ssl/sslsock.c	6 Dec 2011 00:24:08 -0000
+@@ -1373,6 +1373,20 @@
+     return NULL;
+ }
+ 
++const SECItem *
++SSL_GetRequestedClientCertificateTypes(PRFileDesc *fd)
++{
++  sslSocket *ss = ssl_FindSocket(fd);
++
++  if (!ss) {
++      SSL_DBG(("%d: SSL[%d]: bad socket in "
++               "SSL_GetRequestedClientCertificateTypes", SSL_GETPID(), fd));
++      return NULL;
++  }
++
++  return ss->requestedCertTypes;
++}
++
+ /************************************************************************/
+ /* The following functions are the TOP LEVEL SSL functions.
+ ** They all get called through the NSPRIOMethods table below.
+@@ -2357,6 +2371,7 @@
+ 	    sc->serverKeyPair   = NULL;
+ 	    sc->serverKeyBits   = 0;
+ 	}
++	ss->requestedCertTypes = NULL;
+ 	ss->stepDownKeyPair    = NULL;
+ 	ss->dbHandle           = CERT_GetDefaultCertDB();
+ 
diff --git a/net/third_party/nss/ssl/ssl.h b/net/third_party/nss/ssl/ssl.h
index 18193e2..12896b1 100644
--- a/net/third_party/nss/ssl/ssl.h
+++ b/net/third_party/nss/ssl/ssl.h
@@ -798,6 +798,16 @@ SSL_IMPORT SECStatus SSL_HandshakeNegotiatedExtension(PRFileDesc * socket,
 SSL_IMPORT SECStatus SSL_HandshakeResumedSession(PRFileDesc *fd,
                                                  PRBool *last_handshake_resumed);
 
+/* Returns a SECItem containing the certificate_types field of the
+** CertificateRequest message.  Each byte of the data is a TLS
+** ClientCertificateType value, and they are ordered from most preferred to
+** least.  This function should only be called from the
+** SSL_GetClientAuthDataHook callback, and will return NULL if called at any
+** other time.  The returned value is valid only until the callback returns, and
+** should not be freed.
+*/
+SSL_IMPORT const SECItem *
+SSL_GetRequestedClientCertificateTypes(PRFileDesc *fd);
 
 SEC_END_PROTOS
 
diff --git a/net/third_party/nss/ssl/ssl3con.c b/net/third_party/nss/ssl/ssl3con.c
index 5f920f9..aca77f4 100644
--- a/net/third_party/nss/ssl/ssl3con.c
+++ b/net/third_party/nss/ssl/ssl3con.c
@@ -5551,6 +5551,9 @@ ssl3_HandleCertificateRequest(sslSocket *ss, SSL3Opaque *b, PRUint32 length)
     if (rv != SECSuccess)
     	goto loser;		/* malformed, alert has been sent */
 
+    PORT_Assert(!ss->requestedCertTypes);
+    ss->requestedCertTypes = &cert_types;
+
     arena = ca_list.arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
     if (arena == NULL)
     	goto no_mem;
@@ -5740,6 +5743,7 @@ loser:
     PORT_SetError(errCode);
     rv = SECFailure;
 done:
+    ss->requestedCertTypes = NULL;
     if (arena != NULL)
     	PORT_FreeArena(arena, PR_FALSE);
 #ifdef NSS_PLATFORM_CLIENT_AUTH
diff --git a/net/third_party/nss/ssl/sslimpl.h b/net/third_party/nss/ssl/sslimpl.h
index ad718ef..ba17ed7 100644
--- a/net/third_party/nss/ssl/sslimpl.h
+++ b/net/third_party/nss/ssl/sslimpl.h
@@ -1107,6 +1107,10 @@ struct sslSocketStr {
     unsigned int     sizeCipherSpecs;
 const unsigned char *  preferredCipher;
 
+    /* TLS ClientCertificateTypes requested during HandleCertificateRequest. */
+    /* Will be NULL at all other times. */
+    const SECItem      *requestedCertTypes;
+
     ssl3KeyPair *         stepDownKeyPair;	/* RSA step down keys */
 
     /* Callbacks */
diff --git a/net/third_party/nss/ssl/sslsock.c b/net/third_party/nss/ssl/sslsock.c
index 596ca3d..eae62bf 100644
--- a/net/third_party/nss/ssl/sslsock.c
+++ b/net/third_party/nss/ssl/sslsock.c
@@ -1615,6 +1615,20 @@ SSL_HandshakeResumedSession(PRFileDesc *fd, PRBool *handshake_resumed) {
     return SECSuccess;
 }
 
+const SECItem *
+SSL_GetRequestedClientCertificateTypes(PRFileDesc *fd)
+{
+  sslSocket *ss = ssl_FindSocket(fd);
+
+  if (!ss) {
+      SSL_DBG(("%d: SSL[%d]: bad socket in "
+               "SSL_GetRequestedClientCertificateTypes", SSL_GETPID(), fd));
+      return NULL;
+  }
+
+  return ss->requestedCertTypes;
+}
+
 /************************************************************************/
 /* The following functions are the TOP LEVEL SSL functions.
 ** They all get called through the NSPRIOMethods table below.
@@ -2599,6 +2613,7 @@ ssl_NewSocket(PRBool makeLocks)
 	    sc->serverKeyPair   = NULL;
 	    sc->serverKeyBits   = 0;
 	}
+	ss->requestedCertTypes = NULL;
 	ss->stepDownKeyPair    = NULL;
 	ss->dbHandle           = CERT_GetDefaultCertDB();
 
@@ -2639,4 +2654,3 @@ loser:
     }
     return ss;
 }
-
-- 
cgit v1.1