| Index: content/renderer/webcrypto/webcrypto_impl_nss.cc
 | 
| diff --git a/content/renderer/webcrypto/webcrypto_impl_nss.cc b/content/renderer/webcrypto/webcrypto_impl_nss.cc
 | 
| index f30c8041f64a84b2d66e9aefefeb8a4c4929187c..3c162a123e64028280771386034312a562141474 100644
 | 
| --- a/content/renderer/webcrypto/webcrypto_impl_nss.cc
 | 
| +++ b/content/renderer/webcrypto/webcrypto_impl_nss.cc
 | 
| @@ -437,6 +437,8 @@ bool ImportKeyInternalRaw(
 | 
|        return false;
 | 
|    }
 | 
|  
 | 
| +  // TODO(bryaneyler): Need to split handling for symmetric and asymmetric keys.
 | 
| +  // Currently only supporting symmetric.
 | 
|    CK_MECHANISM_TYPE mechanism = CKM_INVALID_MECHANISM;
 | 
|    // Flags are verified at the Blink layer; here the flags are set to all
 | 
|    // possible operations for this key type.
 | 
| @@ -1058,6 +1060,12 @@ bool WebCryptoImpl::SignInternal(
 | 
|      const unsigned char* data,
 | 
|      unsigned data_size,
 | 
|      blink::WebArrayBuffer* buffer) {
 | 
| +
 | 
| +  // Note: It is not an error to sign empty data.
 | 
| +
 | 
| +  DCHECK(buffer);
 | 
| +  DCHECK_NE(0, key.usages() & blink::WebCryptoKeyUsageSign);
 | 
| +
 | 
|    blink::WebArrayBuffer result;
 | 
|  
 | 
|    switch (algorithm.id()) {
 | 
| @@ -1071,7 +1079,6 @@ bool WebCryptoImpl::SignInternal(
 | 
|  
 | 
|        DCHECK_EQ(PK11_GetMechanism(sym_key->key()),
 | 
|                  WebCryptoHashToHMACMechanism(params->hash()));
 | 
| -      DCHECK_NE(0, key.usages() & blink::WebCryptoKeyUsageSign);
 | 
|  
 | 
|        SECItem param_item = { siBuffer, NULL, 0 };
 | 
|        SECItem data_item = {
 | 
| @@ -1109,6 +1116,53 @@ bool WebCryptoImpl::SignInternal(
 | 
|  
 | 
|        break;
 | 
|      }
 | 
| +    case blink::WebCryptoAlgorithmIdRsaSsaPkcs1v1_5: {
 | 
| +      if (key.type() != blink::WebCryptoKeyTypePrivate ||
 | 
| +          webcrypto::GetInnerHashAlgorithm(algorithm).isNull())
 | 
| +        return false;
 | 
| +
 | 
| +      PrivateKeyHandle* const private_key =
 | 
| +          reinterpret_cast<PrivateKeyHandle*>(key.handle());
 | 
| +      DCHECK(private_key);
 | 
| +      DCHECK(private_key->key());
 | 
| +
 | 
| +      // Pick the NSS signing algorithm by combining RSA-SSA (RSA PKCS1) and the
 | 
| +      // inner hash of the input Web Crypto algorithm.
 | 
| +      SECOidTag sign_alg_tag;
 | 
| +      switch (webcrypto::GetInnerHashAlgorithm(algorithm).id()) {
 | 
| +        case blink::WebCryptoAlgorithmIdSha1:
 | 
| +          sign_alg_tag = SEC_OID_PKCS1_SHA1_WITH_RSA_ENCRYPTION;
 | 
| +          break;
 | 
| +        case blink::WebCryptoAlgorithmIdSha224:
 | 
| +          sign_alg_tag = SEC_OID_PKCS1_SHA224_WITH_RSA_ENCRYPTION;
 | 
| +          break;
 | 
| +        case blink::WebCryptoAlgorithmIdSha256:
 | 
| +          sign_alg_tag = SEC_OID_PKCS1_SHA256_WITH_RSA_ENCRYPTION;
 | 
| +          break;
 | 
| +        case blink::WebCryptoAlgorithmIdSha384:
 | 
| +          sign_alg_tag = SEC_OID_PKCS1_SHA384_WITH_RSA_ENCRYPTION;
 | 
| +          break;
 | 
| +        case blink::WebCryptoAlgorithmIdSha512:
 | 
| +          sign_alg_tag = SEC_OID_PKCS1_SHA512_WITH_RSA_ENCRYPTION;
 | 
| +          break;
 | 
| +        default:
 | 
| +          return false;
 | 
| +      }
 | 
| +
 | 
| +      crypto::ScopedSECItem signature_item(SECITEM_AllocItem(NULL, NULL, 0));
 | 
| +      if (SEC_SignData(signature_item.get(),
 | 
| +                       data,
 | 
| +                       data_size,
 | 
| +                       private_key->key(),
 | 
| +                       sign_alg_tag) != SECSuccess) {
 | 
| +        return false;
 | 
| +      }
 | 
| +
 | 
| +      result = webcrypto::CreateArrayBuffer(signature_item->data,
 | 
| +                                            signature_item->len);
 | 
| +
 | 
| +      break;
 | 
| +    }
 | 
|      default:
 | 
|        return false;
 | 
|    }
 | 
| @@ -1125,6 +1179,11 @@ bool WebCryptoImpl::VerifySignatureInternal(
 | 
|      const unsigned char* data,
 | 
|      unsigned data_size,
 | 
|      bool* signature_match) {
 | 
| +
 | 
| +  if (!signature_size)
 | 
| +    return false;
 | 
| +  DCHECK(signature);
 | 
| +
 | 
|    switch (algorithm.id()) {
 | 
|      case blink::WebCryptoAlgorithmIdHmac: {
 | 
|        blink::WebArrayBuffer result;
 | 
| @@ -1142,6 +1201,54 @@ bool WebCryptoImpl::VerifySignatureInternal(
 | 
|  
 | 
|        break;
 | 
|      }
 | 
| +    case blink::WebCryptoAlgorithmIdRsaSsaPkcs1v1_5: {
 | 
| +      if (key.type() != blink::WebCryptoKeyTypePublic)
 | 
| +        return false;
 | 
| +
 | 
| +      PublicKeyHandle* const public_key =
 | 
| +          reinterpret_cast<PublicKeyHandle*>(key.handle());
 | 
| +      DCHECK(public_key);
 | 
| +      DCHECK(public_key->key());
 | 
| +
 | 
| +      const SECItem signature_item = {
 | 
| +          siBuffer,
 | 
| +          const_cast<unsigned char*>(signature),
 | 
| +          signature_size
 | 
| +      };
 | 
| +
 | 
| +      SECOidTag hash_alg_tag;
 | 
| +      switch (webcrypto::GetInnerHashAlgorithm(algorithm).id()) {
 | 
| +        case blink::WebCryptoAlgorithmIdSha1:
 | 
| +          hash_alg_tag = SEC_OID_SHA1;
 | 
| +          break;
 | 
| +        case blink::WebCryptoAlgorithmIdSha224:
 | 
| +          hash_alg_tag = SEC_OID_SHA224;
 | 
| +          break;
 | 
| +        case blink::WebCryptoAlgorithmIdSha256:
 | 
| +          hash_alg_tag = SEC_OID_SHA256;
 | 
| +          break;
 | 
| +        case blink::WebCryptoAlgorithmIdSha384:
 | 
| +          hash_alg_tag = SEC_OID_SHA384;
 | 
| +          break;
 | 
| +        case blink::WebCryptoAlgorithmIdSha512:
 | 
| +          hash_alg_tag = SEC_OID_SHA512;
 | 
| +          break;
 | 
| +        default:
 | 
| +          return false;
 | 
| +      }
 | 
| +
 | 
| +      *signature_match =
 | 
| +          SECSuccess == VFY_VerifyDataDirect(data,
 | 
| +                                             data_size,
 | 
| +                                             public_key->key(),
 | 
| +                                             &signature_item,
 | 
| +                                             SEC_OID_PKCS1_RSA_ENCRYPTION,
 | 
| +                                             hash_alg_tag,
 | 
| +                                             NULL,
 | 
| +                                             NULL);
 | 
| +
 | 
| +      break;
 | 
| +    }
 | 
|      default:
 | 
|        return false;
 | 
|    }
 | 
| 
 |