Bug 942728 - Fix telemetry for cipher suites and crypto algorithms andkey sizes, r=keeler, a=lsblakk
authorBrian Smith <brian@briansmith.org>
Thu, 21 Nov 2013 13:35:23 -0800
changeset 172061 dfd3a8087c267a34f813485741e7e4a6d3506e4c
parent 172060 eda892f23bc7e57f6f9092ef4247ed4214f987f2
child 172062 3eb6d88f78df4dacd314e6820c0786384fa8c4b7
push id3224
push userlsblakk@mozilla.com
push dateTue, 04 Feb 2014 01:06:49 +0000
treeherdermozilla-beta@60c04d0987f1 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerskeeler, lsblakk
bugs942728
milestone28.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 942728 - Fix telemetry for cipher suites and crypto algorithms andkey sizes, r=keeler, a=lsblakk
security/manager/ssl/src/nsNSSCallbacks.cpp
toolkit/components/telemetry/Histograms.json
--- a/security/manager/ssl/src/nsNSSCallbacks.cpp
+++ b/security/manager/ssl/src/nsNSSCallbacks.cpp
@@ -30,16 +30,19 @@ using namespace mozilla;
 using namespace mozilla::psm;
 
 static NS_DEFINE_CID(kNSSComponentCID, NS_NSSCOMPONENT_CID);
 
 #ifdef PR_LOGGING
 extern PRLogModuleInfo* gPIPNSSLog;
 #endif
 
+static void AccumulateCipherSuite(Telemetry::ID probe,
+                                  const SSLChannelInfo& channelInfo);
+
 class nsHTTPDownloadEvent : public nsRunnable {
 public:
   nsHTTPDownloadEvent();
   ~nsHTTPDownloadEvent();
 
   NS_IMETHOD Run();
 
   nsNSSHttpRequestSession *mRequestSession;
@@ -903,65 +906,16 @@ CanFalseStartCallback(PRFileDesc* fd, vo
 
   PreliminaryHandshakeDone(fd);
 
   SSLChannelInfo channelInfo;
   if (SSL_GetChannelInfo(fd, &channelInfo, sizeof(channelInfo)) != SECSuccess) {
     return SECSuccess;
   }
 
-  uint32_t csBucket;
-  switch (channelInfo.cipherSuite) {
-    // ECDHE key exchange
-    case TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256: csBucket = 1; break;
-    case TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256: csBucket = 2; break;
-    case TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA: csBucket = 3; break;
-    case TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA: csBucket = 4; break;
-    case TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA: csBucket = 5; break;
-    case TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA: csBucket = 6; break;
-    case TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA: csBucket = 7; break;
-    case TLS_ECDHE_RSA_WITH_RC4_128_SHA: csBucket = 8; break;
-    case TLS_ECDHE_ECDSA_WITH_RC4_128_SHA: csBucket = 9; break;
-    // DHE key exchange
-    case TLS_DHE_RSA_WITH_AES_128_CBC_SHA: csBucket = 21; break;
-    case TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA: csBucket = 22; break;
-    case TLS_DHE_RSA_WITH_AES_256_CBC_SHA: csBucket = 23; break;
-    case TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA: csBucket = 24; break;
-    case SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA: csBucket = 25; break;
-    case TLS_DHE_DSS_WITH_AES_128_CBC_SHA: csBucket = 26; break;
-    case TLS_DHE_DSS_WITH_CAMELLIA_128_CBC_SHA: csBucket = 27; break;
-    case TLS_DHE_DSS_WITH_AES_256_CBC_SHA: csBucket = 28; break;
-    case TLS_DHE_DSS_WITH_CAMELLIA_256_CBC_SHA: csBucket = 29; break;
-    // ECDH key exchange
-    case TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA: csBucket = 41; break;
-    case TLS_ECDH_RSA_WITH_AES_128_CBC_SHA: csBucket = 42; break;
-    case TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA: csBucket = 43; break;
-    case TLS_ECDH_RSA_WITH_AES_256_CBC_SHA: csBucket = 44; break;
-    case TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA: csBucket = 45; break;
-    case TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA: csBucket = 46; break;
-    case TLS_ECDH_ECDSA_WITH_RC4_128_SHA: csBucket = 47; break;
-    case TLS_ECDH_RSA_WITH_RC4_128_SHA: csBucket = 48; break;
-    // RSA key exchange
-    case TLS_RSA_WITH_AES_128_CBC_SHA: csBucket = 61; break;
-    case TLS_RSA_WITH_CAMELLIA_128_CBC_SHA: csBucket = 62; break;
-    case TLS_RSA_WITH_AES_256_CBC_SHA: csBucket = 63; break;
-    case TLS_RSA_WITH_CAMELLIA_256_CBC_SHA: csBucket = 64; break;
-    case SSL_RSA_FIPS_WITH_3DES_EDE_CBC_SHA: csBucket = 65; break;
-    case SSL_RSA_WITH_3DES_EDE_CBC_SHA: csBucket = 66; break;
-    case TLS_RSA_WITH_SEED_CBC_SHA: csBucket = 67; break;
-    case SSL_RSA_WITH_RC4_128_SHA: csBucket = 68; break;
-    case SSL_RSA_WITH_RC4_128_MD5: csBucket = 69; break;
-    // unknown
-    default:
-      MOZ_CRASH("impossible cipher suite");
-      csBucket = 0;
-      break;
-  }
-  Telemetry::Accumulate(Telemetry::SSL_CIPHER_SUITE, csBucket);
-
   SSLCipherSuiteInfo cipherInfo;
   if (SSL_GetCipherSuiteInfo(channelInfo.cipherSuite, &cipherInfo,
                              sizeof (cipherInfo)) != SECSuccess) {
     PR_LOG(gPIPNSSLog, PR_LOG_DEBUG, ("CanFalseStartCallback [%p] failed - "
                                       " KEA %d\n", fd,
                                       static_cast<int32_t>(cipherInfo.keaType)));
     return SECSuccess;
   }
@@ -1106,16 +1060,69 @@ AccummulateECCCurve(Telemetry::ID probe,
 {
   unsigned int value = bits == 256 ? 23 // P-256
                      : bits == 384 ? 24 // P-384
                      : bits == 521 ? 25 // P-521
                      : 0; // Unknown
   Telemetry::Accumulate(probe, value);
 }
 
+static void
+AccumulateCipherSuite(Telemetry::ID probe, const SSLChannelInfo& channelInfo)
+{
+  uint32_t value;
+  switch (channelInfo.cipherSuite) {
+    // ECDHE key exchange
+    case TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256: value = 1; break;
+    case TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256: value = 2; break;
+    case TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA: value = 3; break;
+    case TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA: value = 4; break;
+    case TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA: value = 5; break;
+    case TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA: value = 6; break;
+    case TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA: value = 7; break;
+    case TLS_ECDHE_RSA_WITH_RC4_128_SHA: value = 8; break;
+    case TLS_ECDHE_ECDSA_WITH_RC4_128_SHA: value = 9; break;
+    // DHE key exchange
+    case TLS_DHE_RSA_WITH_AES_128_CBC_SHA: value = 21; break;
+    case TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA: value = 22; break;
+    case TLS_DHE_RSA_WITH_AES_256_CBC_SHA: value = 23; break;
+    case TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA: value = 24; break;
+    case SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA: value = 25; break;
+    case TLS_DHE_DSS_WITH_AES_128_CBC_SHA: value = 26; break;
+    case TLS_DHE_DSS_WITH_CAMELLIA_128_CBC_SHA: value = 27; break;
+    case TLS_DHE_DSS_WITH_AES_256_CBC_SHA: value = 28; break;
+    case TLS_DHE_DSS_WITH_CAMELLIA_256_CBC_SHA: value = 29; break;
+    // ECDH key exchange
+    case TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA: value = 41; break;
+    case TLS_ECDH_RSA_WITH_AES_128_CBC_SHA: value = 42; break;
+    case TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA: value = 43; break;
+    case TLS_ECDH_RSA_WITH_AES_256_CBC_SHA: value = 44; break;
+    case TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA: value = 45; break;
+    case TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA: value = 46; break;
+    case TLS_ECDH_ECDSA_WITH_RC4_128_SHA: value = 47; break;
+    case TLS_ECDH_RSA_WITH_RC4_128_SHA: value = 48; break;
+    // RSA key exchange
+    case TLS_RSA_WITH_AES_128_CBC_SHA: value = 61; break;
+    case TLS_RSA_WITH_CAMELLIA_128_CBC_SHA: value = 62; break;
+    case TLS_RSA_WITH_AES_256_CBC_SHA: value = 63; break;
+    case TLS_RSA_WITH_CAMELLIA_256_CBC_SHA: value = 64; break;
+    case SSL_RSA_FIPS_WITH_3DES_EDE_CBC_SHA: value = 65; break;
+    case SSL_RSA_WITH_3DES_EDE_CBC_SHA: value = 66; break;
+    case TLS_RSA_WITH_SEED_CBC_SHA: value = 67; break;
+    case SSL_RSA_WITH_RC4_128_SHA: value = 68; break;
+    case SSL_RSA_WITH_RC4_128_MD5: value = 69; break;
+    // unknown
+    default:
+      MOZ_CRASH("impossible cipher suite");
+      value = 0;
+      break;
+  }
+  Telemetry::Accumulate(probe, value);
+}
+
 void HandshakeCallback(PRFileDesc* fd, void* client_data) {
   nsNSSShutDownPreventionLock locker;
   SECStatus rv;
 
   nsNSSSocketInfo* infoObject = (nsNSSSocketInfo*) fd->higher->secret;
 
   // certificate validation sets IsFullHandshake, so if that flag
   // is absent at handshake time we have a resumed session. Check this before
@@ -1219,74 +1226,87 @@ void HandshakeCallback(PRFileDesc* fd, v
   SSLChannelInfo channelInfo;
   rv = SSL_GetChannelInfo(fd, &channelInfo, sizeof(channelInfo));
   MOZ_ASSERT(rv == SECSuccess);
   if (rv == SECSuccess) {
     // Get the protocol version for telemetry
     // 0=ssl3, 1=tls1, 2=tls1.1, 3=tls1.2
     unsigned int versionEnum = channelInfo.protocolVersion & 0xFF;
     Telemetry::Accumulate(Telemetry::SSL_HANDSHAKE_VERSION, versionEnum);
+    AccumulateCipherSuite(
+      infoObject->IsFullHandshake() ? Telemetry::SSL_CIPHER_SUITE_FULL
+                                    : Telemetry::SSL_CIPHER_SUITE_RESUMED,
+      channelInfo);
 
     SSLCipherSuiteInfo cipherInfo;
     rv = SSL_GetCipherSuiteInfo(channelInfo.cipherSuite, &cipherInfo,
                                 sizeof cipherInfo);
     MOZ_ASSERT(rv == SECSuccess);
     if (rv == SECSuccess) {
       status->mHaveKeyLengthAndCipher = true;
       status->mKeyLength = cipherInfo.symKeyBits;
       status->mSecretKeyLength = cipherInfo.effectiveKeyBits;
       status->mCipherName.Assign(cipherInfo.cipherSuiteName);
 
       // keyExchange null=0, rsa=1, dh=2, fortezza=3, ecdh=4
-      Telemetry::Accumulate(Telemetry::SSL_KEY_EXCHANGE_ALGORITHM,
-                            cipherInfo.keaType);
+      Telemetry::Accumulate(
+        infoObject->IsFullHandshake()
+          ? Telemetry::SSL_KEY_EXCHANGE_ALGORITHM_FULL
+          : Telemetry::SSL_KEY_EXCHANGE_ALGORITHM_RESUMED,
+        cipherInfo.keaType);
       infoObject->SetKEAUsed(cipherInfo.keaType);
 
-      switch (cipherInfo.keaType) {
-        case ssl_kea_rsa:
-          AccumulateNonECCKeySize(Telemetry::SSL_KEA_RSA_KEY_SIZE,
-                                  channelInfo.keaKeyBits);
-          break;
-        case ssl_kea_dh:
-          AccumulateNonECCKeySize(Telemetry::SSL_KEA_DHE_KEY_SIZE,
-                                  channelInfo.keaKeyBits);
-          break;
-        case ssl_kea_ecdh:
-          AccummulateECCCurve(Telemetry::SSL_KEA_ECDHE_CURVE,
-                              channelInfo.keaKeyBits);
-          break;
-        default:
-          MOZ_CRASH("impossible KEA");
-          break;
-      }
-
-      Telemetry::Accumulate(Telemetry::SSL_AUTH_ALGORITHM, cipherInfo.authAlgorithm);
-      // RSA key exchange doesn't use a signature for auth.
-      if (cipherInfo.keaType != ssl_kea_rsa) {
-        switch (cipherInfo.authAlgorithm) {
-          case ssl_auth_rsa:
-            AccumulateNonECCKeySize(Telemetry::SSL_AUTH_RSA_KEY_SIZE,
-                                    channelInfo.authKeyBits);
+      if (infoObject->IsFullHandshake()) {
+        switch (cipherInfo.keaType) {
+          case ssl_kea_rsa:
+            AccumulateNonECCKeySize(Telemetry::SSL_KEA_RSA_KEY_SIZE_FULL,
+                                    channelInfo.keaKeyBits);
             break;
-          case ssl_auth_dsa:
-            AccumulateNonECCKeySize(Telemetry::SSL_AUTH_DSA_KEY_SIZE,
-                                    channelInfo.authKeyBits);
+          case ssl_kea_dh:
+            AccumulateNonECCKeySize(Telemetry::SSL_KEA_DHE_KEY_SIZE_FULL,
+                                    channelInfo.keaKeyBits);
             break;
-          case ssl_auth_ecdsa:
-            AccummulateECCCurve(Telemetry::SSL_AUTH_ECDSA_CURVE,
-                                channelInfo.authKeyBits);
+          case ssl_kea_ecdh:
+            AccummulateECCCurve(Telemetry::SSL_KEA_ECDHE_CURVE_FULL,
+                                channelInfo.keaKeyBits);
             break;
           default:
-            MOZ_CRASH("impossible auth algorithm");
+            MOZ_CRASH("impossible KEA");
             break;
         }
+
+        Telemetry::Accumulate(Telemetry::SSL_AUTH_ALGORITHM_FULL,
+                              cipherInfo.authAlgorithm);
+
+        // RSA key exchange doesn't use a signature for auth.
+        if (cipherInfo.keaType != ssl_kea_rsa) {
+          switch (cipherInfo.authAlgorithm) {
+            case ssl_auth_rsa:
+              AccumulateNonECCKeySize(Telemetry::SSL_AUTH_RSA_KEY_SIZE_FULL,
+                                      channelInfo.authKeyBits);
+              break;
+            case ssl_auth_dsa:
+              AccumulateNonECCKeySize(Telemetry::SSL_AUTH_DSA_KEY_SIZE_FULL,
+                                      channelInfo.authKeyBits);
+              break;
+            case ssl_auth_ecdsa:
+              AccummulateECCCurve(Telemetry::SSL_AUTH_ECDSA_CURVE_FULL,
+                                  channelInfo.authKeyBits);
+              break;
+            default:
+              MOZ_CRASH("impossible auth algorithm");
+              break;
+          }
+        }
       }
 
-      Telemetry::Accumulate(Telemetry::SSL_SYMMETRIC_CIPHER,
-                            cipherInfo.symCipher);
-
+      Telemetry::Accumulate(
+          infoObject->IsFullHandshake()
+            ? Telemetry::SSL_SYMMETRIC_CIPHER_FULL
+            : Telemetry::SSL_SYMMETRIC_CIPHER_RESUMED,
+          cipherInfo.symCipher);
       infoObject->SetSymmetricCipherUsed(cipherInfo.symCipher);
     }
   }
 
   infoObject->NoteTimeUntilReady();
   infoObject->SetHandshakeCompleted(isResumedSession);
 }
--- a/toolkit/components/telemetry/Histograms.json
+++ b/toolkit/components/telemetry/Histograms.json
@@ -1043,20 +1043,25 @@
   },
   "CERT_VALIDATION_HTTP_REQUEST_FAILED_TIME": {
     "kind": "exponential",
     "high": "60000",
     "n_buckets": 200,
     "extended_statistics_ok": true,
     "description": "ms elapsed time of OCSP etc.. that failed"
   },
-  "SSL_KEY_EXCHANGE_ALGORITHM": {
+  "SSL_KEY_EXCHANGE_ALGORITHM_FULL": {
     "kind": "enumerated",
     "n_values": 16,
-    "description": "SSL Handshake Key Exchange Algorithm (null=0, rsa=1, dh=2, fortezza=3, ecdh=4)"
+    "description": "SSL Handshake Key Exchange Algorithm for full handshake (null=0, rsa=1, dh=2, fortezza=3, ecdh=4)"
+  },
+  "SSL_KEY_EXCHANGE_ALGORITHM_RESUMED": {
+    "kind": "enumerated",
+    "n_values": 16,
+    "description": "SSL Handshake Key Exchange Algorithm for resumed handshake (null=0, rsa=1, dh=2, fortezza=3, ecdh=4)"
   },
   "WEBSOCKETS_HANDSHAKE_TYPE": {
     "kind": "enumerated",
     "n_values": 16,
     "description": "Websockets Handshake Results (ws-ok-plain, ws-ok-proxy, ws-failed-plain, ws-failed-proxy, wss-ok-plain, wss-ok-proxy, wss-failed-plain, wss-failed-proxy)"
   },
   "SPDY_VERSION2": {
     "kind": "enumerated",
@@ -4544,54 +4549,64 @@
     "n_values": 64,
     "description": "detected symptom of SSL 3.0 intolerance, before considering historical info"
   },
   "SSL_SSL30_INTOLERANCE_REASON_POST": {
     "kind": "enumerated",
     "n_values": 64,
     "description": "detected symptom of SSL 3.0 intolerance, after considering historical info"
   },
-  "SSL_CIPHER_SUITE": {
+  "SSL_CIPHER_SUITE_FULL": {
     "kind": "enumerated",
     "n_values": 128,
-    "description": "Negotiated cipher suite (see key in HandshakeCallback in nsNSSCallbacks.cpp)"
-  },
-  "SSL_KEA_RSA_KEY_SIZE": {
+    "description": "Negotiated cipher suite in full handshake (see key in HandshakeCallback in nsNSSCallbacks.cpp)"
+  },
+  "SSL_CIPHER_SUITE_RESUMED": {
+    "kind": "enumerated",
+    "n_values": 128,
+    "description": "Negotiated cipher suite in resumed handshake (see key in HandshakeCallback in nsNSSCallbacks.cpp)"
+  },
+  "SSL_KEA_RSA_KEY_SIZE_FULL": {
     "kind": "enumerated",
     "n_values": 24,
-    "description": "RSA KEA (TLS_RSA_*) key size"
-  },
-  "SSL_KEA_DHE_KEY_SIZE": {
+    "description": "RSA KEA (TLS_RSA_*) key size in full handshake"
+  },
+  "SSL_KEA_DHE_KEY_SIZE_FULL": {
     "kind": "enumerated",
     "n_values": 24,
-    "description": "DHE KEA (TLS_DHE_*) key size"
-  },
-  "SSL_KEA_ECDHE_CURVE": {
+    "description": "DHE KEA (TLS_DHE_*) key size in full handshake"
+  },
+  "SSL_KEA_ECDHE_CURVE_FULL": {
     "kind": "enumerated",
     "n_values": "36",
-    "description": "ECDHE KEA (TLS_ECDHE_*) curve (1=P-256, 2=P-384, 3=P-521)"
-  },
-  "SSL_AUTH_ALGORITHM": {
+    "description": "ECDHE KEA (TLS_ECDHE_*) curve (1=P-256, 2=P-384, 3=P-521) in full handshake"
+  },
+  "SSL_AUTH_ALGORITHM_FULL": {
     "kind": "enumerated",
     "n_values": 16,
-    "description": "SSL Authentication Algorithm (null=0, rsa=1, dsa=2, ecdsa=4)"
-  },
-  "SSL_AUTH_RSA_KEY_SIZE": {
+    "description": "SSL Authentication Algorithm (null=0, rsa=1, dsa=2, ecdsa=4) in full handshake"
+  },
+  "SSL_AUTH_RSA_KEY_SIZE_FULL": {
     "kind": "enumerated",
     "n_values": 24,
-    "description": "RSA signature key size for TLS_*_RSA_*"
-  },
-  "SSL_AUTH_DSA_KEY_SIZE": {
+    "description": "RSA signature key size for TLS_*_RSA_* in full handshake"
+  },
+  "SSL_AUTH_DSA_KEY_SIZE_FULL": {
     "kind": "enumerated",
     "n_values": 24,
-    "description": "DSA signature key size for TLS_*_DSS_*"
-  },
-  "SSL_AUTH_ECDSA_CURVE": {
+    "description": "DSA signature key size for TLS_*_DSS_* in full handshake"
+  },
+  "SSL_AUTH_ECDSA_CURVE_FULL": {
     "kind": "enumerated",
     "n_values": "36",
-    "description": "ECDSA signature curve for TLS_*_ECDSA_* (1=P-256, 2=P-384, 3=P-521)"
-  },
-  "SSL_SYMMETRIC_CIPHER": {
+    "description": "ECDSA signature curve for TLS_*_ECDSA_* in full handshake (1=P-256, 2=P-384, 3=P-521)"
+  },
+  "SSL_SYMMETRIC_CIPHER_FULL": {
     "kind": "enumerated",
     "n_values": 32,
-    "description": "Symmetric cipher used (null=0, rc4=1, 3des=4, aes-cbc=7, camellia=8, seed=9, aes-gcm=10)"
+    "description": "Symmetric cipher used in full handshake (null=0, rc4=1, 3des=4, aes-cbc=7, camellia=8, seed=9, aes-gcm=10)"
+  },
+  "SSL_SYMMETRIC_CIPHER_RESUMED": {
+    "kind": "enumerated",
+    "n_values": 32,
+    "description": "Symmetric cipher used in resumed handshake (null=0, rc4=1, 3des=4, aes-cbc=7, camellia=8, seed=9, aes-gcm=10)"
   }
 }