Bug 1256488 - Use Base64 URL-encoding in `CryptoBuffer`. r=ttaubert
authorKit Cambridge <kcambridge@mozilla.com>
Thu, 17 Mar 2016 14:13:09 -0700
changeset 332251 f0131a8cfd627a4beeece0c890f20c0c8123788c
parent 332250 296093225409c25a837753a753780d14ae20f965
child 332252 6ce993bd6aec52d4cf9e0c9783418453c423fb27
push id6048
push userkmoir@mozilla.com
push dateMon, 06 Jun 2016 19:02:08 +0000
treeherdermozilla-beta@46d72a56c57d [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersttaubert
bugs1256488
milestone48.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 1256488 - Use Base64 URL-encoding in `CryptoBuffer`. r=ttaubert MozReview-Commit-ID: AGtDUBuDuu0
dom/crypto/CryptoBuffer.cpp
dom/crypto/test/test-vectors.js
--- a/dom/crypto/CryptoBuffer.cpp
+++ b/dom/crypto/CryptoBuffer.cpp
@@ -110,68 +110,40 @@ CryptoBuffer::AppendSECItem(const SECIte
 // * No padding
 // * URL-safe character set
 nsresult
 CryptoBuffer::FromJwkBase64(const nsString& aBase64)
 {
   NS_ConvertUTF16toUTF8 temp(aBase64);
   temp.StripWhitespace();
 
-  // Re-add padding
-  if (temp.Length() % 4 == 3) {
-    temp.AppendLiteral("=");
-  } else if (temp.Length() % 4 == 2) {
-    temp.AppendLiteral("==");
-  } if (temp.Length() % 4 == 1) {
-    return NS_ERROR_FAILURE; // bad Base64
-  }
-
-  // Translate from URL-safe character set to normal
-  temp.ReplaceChar('-', '+');
-  temp.ReplaceChar('_', '/');
-
-  // Perform the actual base64 decode
-  nsCString binaryData;
-  nsresult rv = Base64Decode(temp, binaryData);
+  Base64URLDecodeOptions options;
+  // JWK prohibits padding per RFC 7515, section 2.
+  options.mPadding = Base64URLDecodePadding::Reject;
+  nsresult rv = Base64URLDecode(temp, options, *this);
   NS_ENSURE_SUCCESS(rv, rv);
 
-  if (!Assign((const uint8_t*) binaryData.BeginReading(),
-              binaryData.Length())) {
-    return NS_ERROR_FAILURE;
-  }
-
   return NS_OK;
 }
 
 nsresult
 CryptoBuffer::ToJwkBase64(nsString& aBase64)
 {
   // Shortcut for the empty octet string
   if (Length() == 0) {
     aBase64.Truncate();
     return NS_OK;
   }
 
-  // Perform the actual base64 encode
-  nsCString base64;
-  nsDependentCSubstring binaryData((const char*) Elements(),
-                                   (const char*) (Elements() + Length()));
-  nsresult rv = Base64Encode(binaryData, base64);
+  nsAutoCString base64;
+  Base64URLEncodeOptions options;
+  options.mPad = false;
+  nsresult rv = Base64URLEncode(Length(), Elements(), options, base64);
   NS_ENSURE_SUCCESS(rv, rv);
 
-  // Strip padding
-  base64.Trim("=");
-
-  // Translate to the URL-safe charset
-  base64.ReplaceChar('+', '-');
-  base64.ReplaceChar('/', '_');
-  if (base64.FindCharInSet("+/", 0) != kNotFound) {
-    return NS_ERROR_FAILURE;
-  }
-
   CopyASCIItoUTF16(base64, aBase64);
   return NS_OK;
 }
 
 bool
 CryptoBuffer::ToSECItem(PLArenaPool *aArena, SECItem* aItem) const
 {
   aItem->type = siBuffer;
--- a/dom/crypto/test/test-vectors.js
+++ b/dom/crypto/test/test-vectors.js
@@ -718,17 +718,17 @@ tv = {
       x: "YoV6fhCph4kyt7sUkqiZOtbRs0rF6etPqlnrn1nzSB95NElaw4uTK7Pn2nlFFqqH",
       y: "bf3tRz6icq3-W6hhmoqDTBKjdOQUJ5xHr5kX4X-h5MZk_P_nCrG3IUVl1SAbhWDw"
     },
 
     jwk_priv: {
       kty: "EC",
       crv: "P-384",
       d: "RT8f0pRw4CL1Tgk4rwuNnNbFoQBNTTBkr7WVLLm4fDA3boYZpNB_t-rbMVLx0CRp",
-      x: "_XwhXRnOzEfCsWIRCz3QLClaDkigQFvXmqYNdh/7vJdADykPbfGi1VgAu3XJdXoD",
+      x: "_XwhXRnOzEfCsWIRCz3QLClaDkigQFvXmqYNdh_7vJdADykPbfGi1VgAu3XJdXoD",
       y: "S1P_FBCXYGE-5VPvTCRnFT7bPIPmUPV9qKTM24TQFYEUgIDfzCLsyGCWK-rhP6jU"
     },
 
     secret: util.hex2abv(
       "a3d28aa18f905a48a5f166b4ddbf5f6b499e43858ccdd80b869946aba2c5d461" +
       "db6a1e5b1137687801878ff0f8d9a7b3"
     )
   },