11320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci// Copyright 2014 The Chromium Authors. All rights reserved.
21320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci// Use of this source code is governed by a BSD-style license that can be
31320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci// found in the LICENSE file.
41320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
51320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "base/logging.h"
61320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "base/stl_util.h"
71320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "content/child/webcrypto/algorithm_dispatch.h"
81320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "content/child/webcrypto/crypto_data.h"
91320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "content/child/webcrypto/jwk.h"
101320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "content/child/webcrypto/status.h"
111320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "content/child/webcrypto/test/test_helpers.h"
121320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "content/child/webcrypto/webcrypto_util.h"
131320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "testing/gtest/include/gtest/gtest.h"
141320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "third_party/WebKit/public/platform/WebCryptoAlgorithmParams.h"
151320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "third_party/WebKit/public/platform/WebCryptoKeyAlgorithm.h"
161320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
171320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccinamespace content {
181320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
191320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccinamespace webcrypto {
201320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
211320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccinamespace {
221320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
231320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci// Creates an RSA-OAEP algorithm
241320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucciblink::WebCryptoAlgorithm CreateRsaOaepAlgorithm(
251320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    const std::vector<uint8_t>& label) {
261320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  return blink::WebCryptoAlgorithm::adoptParamsAndCreate(
271320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      blink::WebCryptoAlgorithmIdRsaOaep,
281320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      new blink::WebCryptoRsaOaepParams(
291320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci          !label.empty(), vector_as_array(&label), label.size()));
301320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}
311320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
321320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucciscoped_ptr<base::DictionaryValue> CreatePublicKeyJwkDict() {
331320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  scoped_ptr<base::DictionaryValue> jwk(new base::DictionaryValue());
341320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  jwk->SetString("kty", "RSA");
351320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  jwk->SetString("n",
361320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                 Base64EncodeUrlSafe(HexStringToBytes(kPublicKeyModulusHex)));
371320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  jwk->SetString("e",
381320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                 Base64EncodeUrlSafe(HexStringToBytes(kPublicKeyExponentHex)));
391320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  return jwk.Pass();
401320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}
411320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
421320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci// Import a PKCS#8 private key that uses RSAPrivateKey with the
431320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci// id-rsaEncryption OID.
441320f92c476a1ad9d19dba2a48c72b75566198e9Primiano TucciTEST(WebCryptoRsaOaepTest, ImportPkcs8WithRsaEncryption) {
451320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  if (!SupportsRsaOaep()) {
461320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    LOG(WARNING) << "RSA-OAEP support not present; skipping.";
471320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    return;
481320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  }
491320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
501320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  blink::WebCryptoKey private_key = blink::WebCryptoKey::createNull();
511320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  ASSERT_EQ(Status::Success(),
521320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci            ImportKey(blink::WebCryptoKeyFormatPkcs8,
531320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                      CryptoData(HexStringToBytes(kPrivateKeyPkcs8DerHex)),
541320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                      CreateRsaHashedImportAlgorithm(
551320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                          blink::WebCryptoAlgorithmIdRsaOaep,
561320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                          blink::WebCryptoAlgorithmIdSha1),
571320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                      true,
581320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                      blink::WebCryptoKeyUsageDecrypt,
591320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                      &private_key));
601320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}
611320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
621320f92c476a1ad9d19dba2a48c72b75566198e9Primiano TucciTEST(WebCryptoRsaOaepTest, ImportPublicJwkWithNoAlg) {
631320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  if (!SupportsRsaOaep()) {
641320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    LOG(WARNING) << "RSA-OAEP support not present; skipping.";
651320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    return;
661320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  }
671320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
681320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  scoped_ptr<base::DictionaryValue> jwk(CreatePublicKeyJwkDict());
691320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
701320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  blink::WebCryptoKey public_key = blink::WebCryptoKey::createNull();
711320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  ASSERT_EQ(Status::Success(),
721320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci            ImportKeyJwkFromDict(*jwk.get(),
731320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                                 CreateRsaHashedImportAlgorithm(
741320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                                     blink::WebCryptoAlgorithmIdRsaOaep,
751320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                                     blink::WebCryptoAlgorithmIdSha1),
761320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                                 true,
771320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                                 blink::WebCryptoKeyUsageEncrypt,
781320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                                 &public_key));
791320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}
801320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
811320f92c476a1ad9d19dba2a48c72b75566198e9Primiano TucciTEST(WebCryptoRsaOaepTest, ImportPublicJwkWithMatchingAlg) {
821320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  if (!SupportsRsaOaep()) {
831320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    LOG(WARNING) << "RSA-OAEP support not present; skipping.";
841320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    return;
851320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  }
861320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
871320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  scoped_ptr<base::DictionaryValue> jwk(CreatePublicKeyJwkDict());
881320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  jwk->SetString("alg", "RSA-OAEP");
891320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
901320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  blink::WebCryptoKey public_key = blink::WebCryptoKey::createNull();
911320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  ASSERT_EQ(Status::Success(),
921320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci            ImportKeyJwkFromDict(*jwk.get(),
931320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                                 CreateRsaHashedImportAlgorithm(
941320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                                     blink::WebCryptoAlgorithmIdRsaOaep,
951320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                                     blink::WebCryptoAlgorithmIdSha1),
961320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                                 true,
971320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                                 blink::WebCryptoKeyUsageEncrypt,
981320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                                 &public_key));
991320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}
1001320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
1011320f92c476a1ad9d19dba2a48c72b75566198e9Primiano TucciTEST(WebCryptoRsaOaepTest, ImportPublicJwkWithMismatchedAlgFails) {
1021320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  if (!SupportsRsaOaep()) {
1031320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    LOG(WARNING) << "RSA-OAEP support not present; skipping.";
1041320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    return;
1051320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  }
1061320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
1071320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  scoped_ptr<base::DictionaryValue> jwk(CreatePublicKeyJwkDict());
1081320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  jwk->SetString("alg", "RSA-OAEP-512");
1091320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
1101320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  blink::WebCryptoKey public_key = blink::WebCryptoKey::createNull();
1111320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  ASSERT_EQ(Status::ErrorJwkAlgorithmInconsistent(),
1121320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci            ImportKeyJwkFromDict(*jwk.get(),
1131320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                                 CreateRsaHashedImportAlgorithm(
1141320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                                     blink::WebCryptoAlgorithmIdRsaOaep,
1151320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                                     blink::WebCryptoAlgorithmIdSha1),
1161320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                                 true,
1171320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                                 blink::WebCryptoKeyUsageEncrypt,
1181320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                                 &public_key));
1191320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}
1201320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
1211320f92c476a1ad9d19dba2a48c72b75566198e9Primiano TucciTEST(WebCryptoRsaOaepTest, ImportPublicJwkWithMismatchedTypeFails) {
1221320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  if (!SupportsRsaOaep()) {
1231320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    LOG(WARNING) << "RSA-OAEP support not present; skipping.";
1241320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    return;
1251320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  }
1261320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
1271320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  scoped_ptr<base::DictionaryValue> jwk(CreatePublicKeyJwkDict());
1281320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  jwk->SetString("kty", "oct");
1291320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  jwk->SetString("alg", "RSA-OAEP");
1301320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
1311320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  blink::WebCryptoKey public_key = blink::WebCryptoKey::createNull();
1321320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  ASSERT_EQ(Status::ErrorJwkUnexpectedKty("RSA"),
1331320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci            ImportKeyJwkFromDict(*jwk.get(),
1341320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                                 CreateRsaHashedImportAlgorithm(
1351320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                                     blink::WebCryptoAlgorithmIdRsaOaep,
1361320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                                     blink::WebCryptoAlgorithmIdSha1),
1371320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                                 true,
1381320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                                 blink::WebCryptoKeyUsageEncrypt,
1391320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                                 &public_key));
1401320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}
1411320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
1421320f92c476a1ad9d19dba2a48c72b75566198e9Primiano TucciTEST(WebCryptoRsaOaepTest, ExportPublicJwk) {
1431320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  if (!SupportsRsaOaep()) {
1441320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    LOG(WARNING) << "RSA-OAEP support not present; skipping.";
1451320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    return;
1461320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  }
1471320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
1481320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  struct TestData {
1491320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    blink::WebCryptoAlgorithmId hash_alg;
1501320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    const char* expected_jwk_alg;
1511320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  } kTestData[] = {{blink::WebCryptoAlgorithmIdSha1, "RSA-OAEP"},
1521320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                   {blink::WebCryptoAlgorithmIdSha256, "RSA-OAEP-256"},
1531320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                   {blink::WebCryptoAlgorithmIdSha384, "RSA-OAEP-384"},
1541320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                   {blink::WebCryptoAlgorithmIdSha512, "RSA-OAEP-512"}};
1551320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  for (size_t i = 0; i < ARRAYSIZE_UNSAFE(kTestData); ++i) {
1561320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    const TestData& test_data = kTestData[i];
1571320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    SCOPED_TRACE(test_data.expected_jwk_alg);
1581320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
1591320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    scoped_ptr<base::DictionaryValue> jwk(CreatePublicKeyJwkDict());
1601320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    jwk->SetString("alg", test_data.expected_jwk_alg);
1611320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
1621320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    // Import the key in a known-good format
1631320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    blink::WebCryptoKey public_key = blink::WebCryptoKey::createNull();
1641320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    ASSERT_EQ(Status::Success(),
1651320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci              ImportKeyJwkFromDict(
1661320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                  *jwk.get(),
1671320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                  CreateRsaHashedImportAlgorithm(
1681320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                      blink::WebCryptoAlgorithmIdRsaOaep, test_data.hash_alg),
1691320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                  true,
1701320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                  blink::WebCryptoKeyUsageEncrypt,
1711320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                  &public_key));
1721320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
1731320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    // Now export the key as JWK and verify its contents
1741320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    std::vector<uint8_t> jwk_data;
1751320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    ASSERT_EQ(Status::Success(),
1761320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci              ExportKey(blink::WebCryptoKeyFormatJwk, public_key, &jwk_data));
1771320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    EXPECT_TRUE(VerifyPublicJwk(jwk_data,
1781320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                                test_data.expected_jwk_alg,
1791320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                                kPublicKeyModulusHex,
1801320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                                kPublicKeyExponentHex,
1811320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                                blink::WebCryptoKeyUsageEncrypt));
1821320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  }
1831320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}
1841320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
1851320f92c476a1ad9d19dba2a48c72b75566198e9Primiano TucciTEST(WebCryptoRsaOaepTest, EncryptDecryptKnownAnswerTest) {
1861320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  if (!SupportsRsaOaep()) {
1871320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    LOG(WARNING) << "RSA-OAEP support not present; skipping.";
1881320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    return;
1891320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  }
1901320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
1911320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  scoped_ptr<base::ListValue> tests;
1921320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  ASSERT_TRUE(ReadJsonTestFileToList("rsa_oaep.json", &tests));
1931320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
1941320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  for (size_t test_index = 0; test_index < tests->GetSize(); ++test_index) {
1951320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    SCOPED_TRACE(test_index);
1961320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
1971320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    base::DictionaryValue* test = NULL;
1981320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    ASSERT_TRUE(tests->GetDictionary(test_index, &test));
1991320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
2001320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    blink::WebCryptoAlgorithm digest_algorithm =
2011320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        GetDigestAlgorithm(test, "hash");
2021320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    ASSERT_FALSE(digest_algorithm.isNull());
2031320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    std::vector<uint8_t> public_key_der =
2041320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        GetBytesFromHexString(test, "public_key");
2051320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    std::vector<uint8_t> private_key_der =
2061320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        GetBytesFromHexString(test, "private_key");
2071320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    std::vector<uint8_t> ciphertext = GetBytesFromHexString(test, "ciphertext");
2081320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    std::vector<uint8_t> plaintext = GetBytesFromHexString(test, "plaintext");
2091320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    std::vector<uint8_t> label = GetBytesFromHexString(test, "label");
2101320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
2111320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    blink::WebCryptoAlgorithm import_algorithm = CreateRsaHashedImportAlgorithm(
2121320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        blink::WebCryptoAlgorithmIdRsaOaep, digest_algorithm.id());
2131320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    blink::WebCryptoKey public_key = blink::WebCryptoKey::createNull();
2141320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    blink::WebCryptoKey private_key = blink::WebCryptoKey::createNull();
2151320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
2161320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    ASSERT_NO_FATAL_FAILURE(ImportRsaKeyPair(public_key_der,
2171320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                                             private_key_der,
2181320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                                             import_algorithm,
2191320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                                             false,
2201320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                                             blink::WebCryptoKeyUsageEncrypt,
2211320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                                             blink::WebCryptoKeyUsageDecrypt,
2221320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                                             &public_key,
2231320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                                             &private_key));
2241320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
2251320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    blink::WebCryptoAlgorithm op_algorithm = CreateRsaOaepAlgorithm(label);
2261320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    std::vector<uint8_t> decrypted_data;
2271320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    ASSERT_EQ(Status::Success(),
2281320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci              Decrypt(op_algorithm,
2291320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                      private_key,
2301320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                      CryptoData(ciphertext),
2311320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                      &decrypted_data));
2321320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    EXPECT_BYTES_EQ(plaintext, decrypted_data);
2331320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    std::vector<uint8_t> encrypted_data;
2341320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    ASSERT_EQ(
2351320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        Status::Success(),
2361320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        Encrypt(
2371320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci            op_algorithm, public_key, CryptoData(plaintext), &encrypted_data));
2381320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    std::vector<uint8_t> redecrypted_data;
2391320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    ASSERT_EQ(Status::Success(),
2401320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci              Decrypt(op_algorithm,
2411320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                      private_key,
2421320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                      CryptoData(encrypted_data),
2431320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                      &redecrypted_data));
2441320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    EXPECT_BYTES_EQ(plaintext, redecrypted_data);
2451320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  }
2461320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}
2471320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
2481320f92c476a1ad9d19dba2a48c72b75566198e9Primiano TucciTEST(WebCryptoRsaOaepTest, EncryptWithLargeMessageFails) {
2491320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  if (!SupportsRsaOaep()) {
2501320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    LOG(WARNING) << "RSA-OAEP support not present; skipping.";
2511320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    return;
2521320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  }
2531320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
2541320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  const blink::WebCryptoAlgorithmId kHash = blink::WebCryptoAlgorithmIdSha1;
2551320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  const size_t kHashSize = 20;
2561320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
2571320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  scoped_ptr<base::DictionaryValue> jwk(CreatePublicKeyJwkDict());
2581320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
2591320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  blink::WebCryptoKey public_key = blink::WebCryptoKey::createNull();
2601320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  ASSERT_EQ(Status::Success(),
2611320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci            ImportKeyJwkFromDict(*jwk.get(),
2621320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                                 CreateRsaHashedImportAlgorithm(
2631320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                                     blink::WebCryptoAlgorithmIdRsaOaep, kHash),
2641320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                                 true,
2651320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                                 blink::WebCryptoKeyUsageEncrypt,
2661320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                                 &public_key));
2671320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
2681320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // The maximum size of an encrypted message is:
2691320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  //   modulus length
2701320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  //   - 1 (leading octet)
2711320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  //   - hash size (maskedSeed)
2721320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  //   - hash size (lHash portion of maskedDB)
2731320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  //   - 1 (at least one octet for the padding string)
2741320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  size_t kMaxMessageSize = (kModulusLengthBits / 8) - 2 - (2 * kHashSize);
2751320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
2761320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // The label has no influence on the maximum message size. For simplicity,
2771320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // use the empty string.
2781320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  std::vector<uint8_t> label;
2791320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  blink::WebCryptoAlgorithm op_algorithm = CreateRsaOaepAlgorithm(label);
2801320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
2811320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // Test that a message just before the boundary succeeds.
2821320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  std::string large_message;
2831320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  large_message.resize(kMaxMessageSize - 1, 'A');
2841320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
2851320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  std::vector<uint8_t> ciphertext;
2861320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  ASSERT_EQ(
2871320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      Status::Success(),
2881320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      Encrypt(
2891320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci          op_algorithm, public_key, CryptoData(large_message), &ciphertext));
2901320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
2911320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // Test that a message at the boundary succeeds.
2921320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  large_message.resize(kMaxMessageSize, 'A');
2931320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  ciphertext.clear();
2941320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
2951320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  ASSERT_EQ(
2961320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      Status::Success(),
2971320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      Encrypt(
2981320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci          op_algorithm, public_key, CryptoData(large_message), &ciphertext));
2991320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
3001320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // Test that a message greater than the largest size fails.
3011320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  large_message.resize(kMaxMessageSize + 1, 'A');
3021320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  ciphertext.clear();
3031320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
3041320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  ASSERT_EQ(
3051320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      Status::OperationError(),
3061320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      Encrypt(
3071320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci          op_algorithm, public_key, CryptoData(large_message), &ciphertext));
3081320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}
3091320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
3101320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci// Ensures that if the selected hash algorithm for the RSA-OAEP message is too
3111320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci// large, then it is rejected, independent of the actual message to be
3121320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci// encrypted.
3131320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci// For example, a 1024-bit RSA key is too small to accomodate a message that
3141320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci// uses OAEP with SHA-512, since it requires 1040 bits to encode
3151320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci// (2 * hash size + 2 padding bytes).
3161320f92c476a1ad9d19dba2a48c72b75566198e9Primiano TucciTEST(WebCryptoRsaOaepTest, EncryptWithLargeDigestFails) {
3171320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  if (!SupportsRsaOaep()) {
3181320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    LOG(WARNING) << "RSA-OAEP support not present; skipping.";
3191320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    return;
3201320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  }
3211320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
3221320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  const blink::WebCryptoAlgorithmId kHash = blink::WebCryptoAlgorithmIdSha512;
3231320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
3241320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  scoped_ptr<base::DictionaryValue> jwk(CreatePublicKeyJwkDict());
3251320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
3261320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  blink::WebCryptoKey public_key = blink::WebCryptoKey::createNull();
3271320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  ASSERT_EQ(Status::Success(),
3281320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci            ImportKeyJwkFromDict(*jwk.get(),
3291320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                                 CreateRsaHashedImportAlgorithm(
3301320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                                     blink::WebCryptoAlgorithmIdRsaOaep, kHash),
3311320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                                 true,
3321320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                                 blink::WebCryptoKeyUsageEncrypt,
3331320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                                 &public_key));
3341320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
3351320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // The label has no influence on the maximum message size. For simplicity,
3361320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // use the empty string.
3371320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  std::vector<uint8_t> label;
3381320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  blink::WebCryptoAlgorithm op_algorithm = CreateRsaOaepAlgorithm(label);
3391320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
3401320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  std::string small_message("A");
3411320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  std::vector<uint8_t> ciphertext;
3421320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // This is an operation error, as the internal consistency checking of the
3431320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // algorithm parameters is up to the implementation.
3441320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  ASSERT_EQ(
3451320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      Status::OperationError(),
3461320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      Encrypt(
3471320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci          op_algorithm, public_key, CryptoData(small_message), &ciphertext));
3481320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}
3491320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
3501320f92c476a1ad9d19dba2a48c72b75566198e9Primiano TucciTEST(WebCryptoRsaOaepTest, DecryptWithLargeMessageFails) {
3511320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  if (!SupportsRsaOaep()) {
3521320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    LOG(WARNING) << "RSA-OAEP support not present; skipping.";
3531320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    return;
3541320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  }
3551320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
3561320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  blink::WebCryptoKey private_key = blink::WebCryptoKey::createNull();
3571320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  ASSERT_EQ(Status::Success(),
3581320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci            ImportKey(blink::WebCryptoKeyFormatPkcs8,
3591320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                      CryptoData(HexStringToBytes(kPrivateKeyPkcs8DerHex)),
3601320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                      CreateRsaHashedImportAlgorithm(
3611320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                          blink::WebCryptoAlgorithmIdRsaOaep,
3621320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                          blink::WebCryptoAlgorithmIdSha1),
3631320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                      true,
3641320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                      blink::WebCryptoKeyUsageDecrypt,
3651320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                      &private_key));
3661320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
3671320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // The label has no influence on the maximum message size. For simplicity,
3681320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // use the empty string.
3691320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  std::vector<uint8_t> label;
3701320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  blink::WebCryptoAlgorithm op_algorithm = CreateRsaOaepAlgorithm(label);
3711320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
3721320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  std::string large_dummy_message(kModulusLengthBits / 8, 'A');
3731320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  std::vector<uint8_t> plaintext;
3741320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
3751320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  ASSERT_EQ(Status::OperationError(),
3761320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci            Decrypt(op_algorithm,
3771320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                    private_key,
3781320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                    CryptoData(large_dummy_message),
3791320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                    &plaintext));
3801320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}
3811320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
3821320f92c476a1ad9d19dba2a48c72b75566198e9Primiano TucciTEST(WebCryptoRsaOaepTest, WrapUnwrapRawKey) {
3831320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  if (!SupportsRsaOaep()) {
3841320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    LOG(WARNING) << "RSA-OAEP support not present; skipping.";
3851320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    return;
3861320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  }
3871320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
3881320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  blink::WebCryptoAlgorithm import_algorithm = CreateRsaHashedImportAlgorithm(
3891320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      blink::WebCryptoAlgorithmIdRsaOaep, blink::WebCryptoAlgorithmIdSha1);
3901320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  blink::WebCryptoKey public_key = blink::WebCryptoKey::createNull();
3911320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  blink::WebCryptoKey private_key = blink::WebCryptoKey::createNull();
3921320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
3931320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  ASSERT_NO_FATAL_FAILURE(ImportRsaKeyPair(
3941320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      HexStringToBytes(kPublicKeySpkiDerHex),
3951320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      HexStringToBytes(kPrivateKeyPkcs8DerHex),
3961320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      import_algorithm,
3971320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      false,
3981320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      blink::WebCryptoKeyUsageEncrypt | blink::WebCryptoKeyUsageWrapKey,
3991320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      blink::WebCryptoKeyUsageDecrypt | blink::WebCryptoKeyUsageUnwrapKey,
4001320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      &public_key,
4011320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      &private_key));
4021320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
4031320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  std::vector<uint8_t> label;
4041320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  blink::WebCryptoAlgorithm wrapping_algorithm = CreateRsaOaepAlgorithm(label);
4051320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
4061320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  const std::string key_hex = "000102030405060708090A0B0C0D0E0F";
4071320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  const blink::WebCryptoAlgorithm key_algorithm =
4081320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      CreateAlgorithm(blink::WebCryptoAlgorithmIdAesCbc);
4091320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
4101320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  blink::WebCryptoKey key =
4111320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      ImportSecretKeyFromRaw(HexStringToBytes(key_hex),
4121320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                             key_algorithm,
4131320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                             blink::WebCryptoKeyUsageEncrypt);
4141320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  ASSERT_FALSE(key.isNull());
4151320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
4161320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  std::vector<uint8_t> wrapped_key;
4171320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  ASSERT_EQ(Status::Success(),
4181320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci            WrapKey(blink::WebCryptoKeyFormatRaw,
4191320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                    key,
4201320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                    public_key,
4211320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                    wrapping_algorithm,
4221320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                    &wrapped_key));
4231320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
4241320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // Verify that |wrapped_key| can be decrypted and yields the key data.
4251320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // Because |private_key| supports both decrypt and unwrap, this is valid.
4261320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  std::vector<uint8_t> decrypted_key;
4271320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  ASSERT_EQ(Status::Success(),
4281320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci            Decrypt(wrapping_algorithm,
4291320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                    private_key,
4301320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                    CryptoData(wrapped_key),
4311320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                    &decrypted_key));
4321320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  EXPECT_BYTES_EQ_HEX(key_hex, decrypted_key);
4331320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
4341320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // Now attempt to unwrap the key, which should also decrypt the data.
4351320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  blink::WebCryptoKey unwrapped_key = blink::WebCryptoKey::createNull();
4361320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  ASSERT_EQ(Status::Success(),
4371320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci            UnwrapKey(blink::WebCryptoKeyFormatRaw,
4381320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                      CryptoData(wrapped_key),
4391320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                      private_key,
4401320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                      wrapping_algorithm,
4411320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                      key_algorithm,
4421320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                      true,
4431320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                      blink::WebCryptoKeyUsageEncrypt,
4441320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                      &unwrapped_key));
4451320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  ASSERT_FALSE(unwrapped_key.isNull());
4461320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
4471320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  std::vector<uint8_t> raw_key;
4481320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  ASSERT_EQ(Status::Success(),
4491320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci            ExportKey(blink::WebCryptoKeyFormatRaw, unwrapped_key, &raw_key));
4501320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  EXPECT_BYTES_EQ_HEX(key_hex, raw_key);
4511320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}
4521320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
4531320f92c476a1ad9d19dba2a48c72b75566198e9Primiano TucciTEST(WebCryptoRsaOaepTest, WrapUnwrapJwkSymKey) {
4541320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  if (!SupportsRsaOaep()) {
4551320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    LOG(WARNING) << "RSA-OAEP support not present; skipping.";
4561320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    return;
4571320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  }
4581320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
4591320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // The public and private portions of a 2048-bit RSA key with the
4601320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // id-rsaEncryption OID
4611320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  const char kPublicKey2048SpkiDerHex[] =
4621320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      "30820122300d06092a864886f70d01010105000382010f003082010a0282010100c5d8ce"
4631320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      "137a38168c8ab70229cfa5accc640567159750a312ce2e7d54b6e2fdd59b300c6a6c9764"
4641320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      "f8de6f00519cdb90111453d273a967462786480621f9e7cee5b73d63358448e7183a3a68"
4651320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      "e991186359f26aa88fbca5f53e673e502e4c5a2ba5068aeba60c9d0c44d872458d1b1e2f"
4661320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      "7f339f986076d516e93dc750f0b7680b6f5f02bc0d5590495be04c4ae59d34ba17bc5d08"
4671320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      "a93c75cfda2828f4a55b153af912038438276cb4a14f8116ca94db0ea9893652d02fc606"
4681320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      "36f19975e3d79a4d8ea8bfed6f8e0a24b63d243b08ea70a086ad56dd6341d733711c89ca"
4691320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      "749d4a80b3e6ecd2f8e53731eadeac2ea77788ee55d7b4b47c0f2523fbd61b557c16615d"
4701320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      "5d0203010001";
4711320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  const char kPrivateKey2048Pkcs8DerHex[] =
4721320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      "308204bd020100300d06092a864886f70d0101010500048204a7308204a3020100028201"
4731320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      "0100c5d8ce137a38168c8ab70229cfa5accc640567159750a312ce2e7d54b6e2fdd59b30"
4741320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      "0c6a6c9764f8de6f00519cdb90111453d273a967462786480621f9e7cee5b73d63358448"
4751320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      "e7183a3a68e991186359f26aa88fbca5f53e673e502e4c5a2ba5068aeba60c9d0c44d872"
4761320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      "458d1b1e2f7f339f986076d516e93dc750f0b7680b6f5f02bc0d5590495be04c4ae59d34"
4771320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      "ba17bc5d08a93c75cfda2828f4a55b153af912038438276cb4a14f8116ca94db0ea98936"
4781320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      "52d02fc60636f19975e3d79a4d8ea8bfed6f8e0a24b63d243b08ea70a086ad56dd6341d7"
4791320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      "33711c89ca749d4a80b3e6ecd2f8e53731eadeac2ea77788ee55d7b4b47c0f2523fbd61b"
4801320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      "557c16615d5d02030100010282010074b70feb41a0b0fcbc207670400556c9450042ede3"
4811320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      "d4383fb1ce8f3558a6d4641d26dd4c333fa4db842d2b9cf9d2354d3e16ad027a9f682d8c"
4821320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      "f4145a1ad97b9edcd8a41c402bd9d8db10f62f43df854cdccbbb2100834f083f53ed6d42"
4831320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      "b1b729a59072b004a4e945fc027db15e9c121d1251464d320d4774d5732df6b3dbf751f4"
4841320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      "9b19c9db201e19989c883bbaad5333db47f64f6f7a95b8d4936b10d945aa3f794cfaab62"
4851320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      "e7d47686129358914f3b8085f03698a650ab5b8c7e45813f2b0515ec05b6e5195b6a7c2a"
4861320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      "0d36969745f431ded4fd059f6aa361a4649541016d356297362b778e90f077d48815b339"
4871320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      "ec6f43aba345df93e67fcb6c2cb5b4544e9be902818100e9c90abe5f9f32468c5b6d630c"
4881320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      "54a4d7d75e29a72cf792f21e242aac78fd7995c42dfd4ae871d2619ff7096cb05baa78e3"
4891320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      "23ecab338401a8059adf7a0d8be3b21edc9a9c82c5605634a2ec81ec053271721351868a"
4901320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      "4c2e50c689d7cef94e31ff23658af5843366e2b289c5bf81d72756a7b93487dd8770d69c"
4911320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      "1f4e089d6d89f302818100d8a58a727c4e209132afd9933b98c89aca862a01cc0be74133"
4921320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      "bee517909e5c379e526895ac4af11780c1fe91194c777c9670b6423f0f5a32fd7691a622"
4931320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      "113eef4bed2ef863363a335fd55b0e75088c582437237d7f3ed3f0a643950237bc6e6277"
4941320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      "ccd0d0a1b4170aa1047aa7ffa7c8c54be10e8c7327ae2e0885663963817f6f02818100e5"
4951320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      "aed9ba4d71b7502e6748a1ce247ecb7bd10c352d6d9256031cdf3c11a65e44b0b7ca2945"
4961320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      "134671195af84c6b3bb3d10ebf65ae916f38bd5dbc59a0ad1c69b8beaf57cb3a8335f19b"
4971320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      "c7117b576987b48331cd9fd3d1a293436b7bb5e1a35c6560de4b5688ea834367cb0997eb"
4981320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      "b578f59ed4cb724c47dba94d3b484c1876dcd70281807f15bc7d2406007cac2b138a96af"
4991320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      "2d1e00276b84da593132c253fcb73212732dfd25824c2a615bc3d9b7f2c8d2fa542d3562"
5001320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      "b0c7738e61eeff580a6056239fb367ea9e5efe73d4f846033602e90c36a78db6fa8ea792"
5011320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      "0769675ec58e237bd994d189c8045a96f5dd3a4f12547257ce224e3c9af830a4da3c0eab"
5021320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      "9227a0035ae9028180067caea877e0b23090fc689322b71fbcce63d6596e66ab5fcdbaa0"
5031320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      "0d49e93aba8effb4518c2da637f209028401a68f344865b4956b032c69acde51d29177ca"
5041320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      "3db99fdbf5e74848ed4fa7bdfc2ebb60e2aaa5354770a763e1399ab7a2099762d525fea0"
5051320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      "37f3e1972c45a477e66db95c9609bb27f862700ef93379930786cf751b";
5061320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  blink::WebCryptoAlgorithm import_algorithm = CreateRsaHashedImportAlgorithm(
5071320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      blink::WebCryptoAlgorithmIdRsaOaep, blink::WebCryptoAlgorithmIdSha1);
5081320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  blink::WebCryptoKey public_key = blink::WebCryptoKey::createNull();
5091320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  blink::WebCryptoKey private_key = blink::WebCryptoKey::createNull();
5101320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
5111320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  ASSERT_NO_FATAL_FAILURE(ImportRsaKeyPair(
5121320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      HexStringToBytes(kPublicKey2048SpkiDerHex),
5131320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      HexStringToBytes(kPrivateKey2048Pkcs8DerHex),
5141320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      import_algorithm,
5151320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      false,
5161320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      blink::WebCryptoKeyUsageEncrypt | blink::WebCryptoKeyUsageWrapKey,
5171320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      blink::WebCryptoKeyUsageDecrypt | blink::WebCryptoKeyUsageUnwrapKey,
5181320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      &public_key,
5191320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      &private_key));
5201320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
5211320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  std::vector<uint8_t> label;
5221320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  blink::WebCryptoAlgorithm wrapping_algorithm = CreateRsaOaepAlgorithm(label);
5231320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
5241320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  const std::string key_hex = "000102030405060708090a0b0c0d0e0f";
5251320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  const blink::WebCryptoAlgorithm key_algorithm =
5261320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      CreateAlgorithm(blink::WebCryptoAlgorithmIdAesCbc);
5271320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
5281320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  blink::WebCryptoKey key =
5291320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      ImportSecretKeyFromRaw(HexStringToBytes(key_hex),
5301320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                             key_algorithm,
5311320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                             blink::WebCryptoKeyUsageEncrypt);
5321320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  ASSERT_FALSE(key.isNull());
5331320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
5341320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  std::vector<uint8_t> wrapped_key;
5351320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  ASSERT_EQ(Status::Success(),
5361320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci            WrapKey(blink::WebCryptoKeyFormatJwk,
5371320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                    key,
5381320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                    public_key,
5391320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                    wrapping_algorithm,
5401320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                    &wrapped_key));
5411320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
5421320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // Verify that |wrapped_key| can be decrypted and yields a valid JWK object.
5431320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // Because |private_key| supports both decrypt and unwrap, this is valid.
5441320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  std::vector<uint8_t> decrypted_jwk;
5451320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  ASSERT_EQ(Status::Success(),
5461320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci            Decrypt(wrapping_algorithm,
5471320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                    private_key,
5481320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                    CryptoData(wrapped_key),
5491320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                    &decrypted_jwk));
5501320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  EXPECT_TRUE(VerifySecretJwk(
5511320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      decrypted_jwk, "A128CBC", key_hex, blink::WebCryptoKeyUsageEncrypt));
5521320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
5531320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // Now attempt to unwrap the key, which should also decrypt the data.
5541320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  blink::WebCryptoKey unwrapped_key = blink::WebCryptoKey::createNull();
5551320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  ASSERT_EQ(Status::Success(),
5561320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci            UnwrapKey(blink::WebCryptoKeyFormatJwk,
5571320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                      CryptoData(wrapped_key),
5581320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                      private_key,
5591320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                      wrapping_algorithm,
5601320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                      key_algorithm,
5611320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                      true,
5621320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                      blink::WebCryptoKeyUsageEncrypt,
5631320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                      &unwrapped_key));
5641320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  ASSERT_FALSE(unwrapped_key.isNull());
5651320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
5661320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  std::vector<uint8_t> raw_key;
5671320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  ASSERT_EQ(Status::Success(),
5681320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci            ExportKey(blink::WebCryptoKeyFormatRaw, unwrapped_key, &raw_key));
5691320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  EXPECT_BYTES_EQ_HEX(key_hex, raw_key);
5701320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}
5711320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
5721320f92c476a1ad9d19dba2a48c72b75566198e9Primiano TucciTEST(WebCryptoRsaOaepTest, ImportExportJwkRsaPublicKey) {
5731320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  if (!SupportsRsaOaep()) {
5741320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    LOG(WARNING) << "RSA-OAEP support not present; skipping.";
5751320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    return;
5761320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  }
5771320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
5781320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  struct TestCase {
5791320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    const blink::WebCryptoAlgorithmId hash;
5801320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    const blink::WebCryptoKeyUsageMask usage;
5811320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    const char* const jwk_alg;
5821320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  };
5831320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  const TestCase kTests[] = {{blink::WebCryptoAlgorithmIdSha1,
5841320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                              blink::WebCryptoKeyUsageEncrypt, "RSA-OAEP"},
5851320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                             {blink::WebCryptoAlgorithmIdSha256,
5861320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                              blink::WebCryptoKeyUsageEncrypt, "RSA-OAEP-256"},
5871320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                             {blink::WebCryptoAlgorithmIdSha384,
5881320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                              blink::WebCryptoKeyUsageEncrypt, "RSA-OAEP-384"},
5891320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                             {blink::WebCryptoAlgorithmIdSha512,
5901320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                              blink::WebCryptoKeyUsageEncrypt, "RSA-OAEP-512"}};
5911320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
5921320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  for (size_t test_index = 0; test_index < ARRAYSIZE_UNSAFE(kTests);
5931320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci       ++test_index) {
5941320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    SCOPED_TRACE(test_index);
5951320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    const TestCase& test = kTests[test_index];
5961320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
5971320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    const blink::WebCryptoAlgorithm import_algorithm =
5981320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        CreateRsaHashedImportAlgorithm(blink::WebCryptoAlgorithmIdRsaOaep,
5991320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                                       test.hash);
6001320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
6011320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    // Import the spki to create a public key
6021320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    blink::WebCryptoKey public_key = blink::WebCryptoKey::createNull();
6031320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    ASSERT_EQ(Status::Success(),
6041320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci              ImportKey(blink::WebCryptoKeyFormatSpki,
6051320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                        CryptoData(HexStringToBytes(kPublicKeySpkiDerHex)),
6061320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                        import_algorithm,
6071320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                        true,
6081320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                        test.usage,
6091320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                        &public_key));
6101320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
6111320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    // Export the public key as JWK and verify its contents
6121320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    std::vector<uint8_t> jwk;
6131320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    ASSERT_EQ(Status::Success(),
6141320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci              ExportKey(blink::WebCryptoKeyFormatJwk, public_key, &jwk));
6151320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    EXPECT_TRUE(VerifyPublicJwk(jwk,
6161320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                                test.jwk_alg,
6171320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                                kPublicKeyModulusHex,
6181320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                                kPublicKeyExponentHex,
6191320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                                test.usage));
6201320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
6211320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    // Import the JWK back in to create a new key
6221320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    blink::WebCryptoKey public_key2 = blink::WebCryptoKey::createNull();
6231320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    ASSERT_EQ(Status::Success(),
6241320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci              ImportKey(blink::WebCryptoKeyFormatJwk,
6251320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                        CryptoData(jwk),
6261320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                        import_algorithm,
6271320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                        true,
6281320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                        test.usage,
6291320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci                        &public_key2));
6301320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    ASSERT_TRUE(public_key2.handle());
6311320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    EXPECT_EQ(blink::WebCryptoKeyTypePublic, public_key2.type());
6321320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    EXPECT_TRUE(public_key2.extractable());
6331320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    EXPECT_EQ(import_algorithm.id(), public_key2.algorithm().id());
6341320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
6351320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    // TODO(eroman): Export the SPKI and verify matches.
6361320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  }
6371320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}
6381320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
6391320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}  // namespace
6401320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
6411320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}  // namespace webcrypto
6421320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
6431320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}  // namespace content
644