void JSCryptoKeySerializationJWK::reconcileUsages(CryptoKeyUsage& suggestedUsages) const { CryptoKeyUsage jwkUsages = 0; JSArray* keyOps; if (getJSArrayFromJSON(m_exec, m_json.get(), "key_ops", keyOps)) { for (size_t i = 0; i < keyOps->length(); ++i) { JSValue jsValue = keyOps->getIndex(m_exec, i); String operation; if (!jsValue.getString(m_exec, operation)) { if (!m_exec->hadException()) throwTypeError(m_exec, "JWK key_ops attribute could not be processed"); return; } if (!tryJWKKeyOpsValue(m_exec, jwkUsages, operation, ASCIILiteral("sign"), CryptoKeyUsageSign)) return; if (!tryJWKKeyOpsValue(m_exec, jwkUsages, operation, ASCIILiteral("verify"), CryptoKeyUsageVerify)) return; if (!tryJWKKeyOpsValue(m_exec, jwkUsages, operation, ASCIILiteral("encrypt"), CryptoKeyUsageEncrypt)) return; if (!tryJWKKeyOpsValue(m_exec, jwkUsages, operation, ASCIILiteral("decrypt"), CryptoKeyUsageDecrypt)) return; if (!tryJWKKeyOpsValue(m_exec, jwkUsages, operation, ASCIILiteral("wrapKey"), CryptoKeyUsageWrapKey)) return; if (!tryJWKKeyOpsValue(m_exec, jwkUsages, operation, ASCIILiteral("unwrapKey"), CryptoKeyUsageUnwrapKey)) return; if (!tryJWKKeyOpsValue(m_exec, jwkUsages, operation, ASCIILiteral("deriveKey"), CryptoKeyUsageDeriveKey)) return; if (!tryJWKKeyOpsValue(m_exec, jwkUsages, operation, ASCIILiteral("deriveBits"), CryptoKeyUsageDeriveBits)) return; } } else { if (m_exec->hadException()) return; String jwkUseString; if (!getStringFromJSON(m_exec, m_json.get(), "use", jwkUseString)) { // We have neither key_ops nor use. return; } if (jwkUseString == "enc") jwkUsages |= (CryptoKeyUsageEncrypt | CryptoKeyUsageDecrypt | CryptoKeyUsageWrapKey | CryptoKeyUsageUnwrapKey); else if (jwkUseString == "sig") jwkUsages |= (CryptoKeyUsageSign | CryptoKeyUsageVerify); else { throwTypeError(m_exec, "Unsupported JWK key use value \"" + jwkUseString + "\""); return; } } suggestedUsages = suggestedUsages & jwkUsages; }
std::unique_ptr<CryptoKeyData> JSCryptoKeySerializationJWK::keyDataRSAComponents() const { Vector<uint8_t> modulus; Vector<uint8_t> exponent; Vector<uint8_t> privateExponent; if (!getBigIntegerVectorFromJSON(m_exec, m_json.get(), "n", modulus)) { if (!m_exec->hadException()) throwTypeError(m_exec, "Required JWK \"n\" member is missing"); return nullptr; } if (!keySizeIsValid(modulus.size() * 8)) { throwTypeError(m_exec, "Key size is not valid for " + m_jwkAlgorithmName); return nullptr; } if (!getBigIntegerVectorFromJSON(m_exec, m_json.get(), "e", exponent)) { if (!m_exec->hadException()) throwTypeError(m_exec, "Required JWK \"e\" member is missing"); return nullptr; } if (!getBigIntegerVectorFromJSON(m_exec, m_json.get(), "d", modulus)) { if (m_exec->hadException()) return nullptr; return CryptoKeyDataRSAComponents::createPublic(modulus, exponent); } CryptoKeyDataRSAComponents::PrimeInfo firstPrimeInfo; CryptoKeyDataRSAComponents::PrimeInfo secondPrimeInfo; Vector<CryptoKeyDataRSAComponents::PrimeInfo> otherPrimeInfos; if (!getBigIntegerVectorFromJSON(m_exec, m_json.get(), "p", firstPrimeInfo.primeFactor)) { if (m_exec->hadException()) return nullptr; return CryptoKeyDataRSAComponents::createPrivate(modulus, exponent, privateExponent); } if (!getBigIntegerVectorFromJSON(m_exec, m_json.get(), "dp", firstPrimeInfo.factorCRTExponent)) { if (m_exec->hadException()) return nullptr; return CryptoKeyDataRSAComponents::createPrivate(modulus, exponent, privateExponent); } if (!getBigIntegerVectorFromJSON(m_exec, m_json.get(), "q", secondPrimeInfo.primeFactor)) { if (m_exec->hadException()) return nullptr; return CryptoKeyDataRSAComponents::createPrivate(modulus, exponent, privateExponent); } if (!getBigIntegerVectorFromJSON(m_exec, m_json.get(), "dq", secondPrimeInfo.factorCRTExponent)) { if (m_exec->hadException()) return nullptr; return CryptoKeyDataRSAComponents::createPrivate(modulus, exponent, privateExponent); } if (!getBigIntegerVectorFromJSON(m_exec, m_json.get(), "qi", secondPrimeInfo.factorCRTCoefficient)) { if (m_exec->hadException()) return nullptr; return CryptoKeyDataRSAComponents::createPrivate(modulus, exponent, privateExponent); } JSArray* otherPrimeInfoJSArray; if (!getJSArrayFromJSON(m_exec, m_json.get(), "oth", otherPrimeInfoJSArray)) { if (m_exec->hadException()) return nullptr; return CryptoKeyDataRSAComponents::createPrivateWithAdditionalData(modulus, exponent, privateExponent, firstPrimeInfo, secondPrimeInfo, otherPrimeInfos); } for (size_t i = 0; i < otherPrimeInfoJSArray->length(); ++i) { CryptoKeyDataRSAComponents::PrimeInfo info; JSValue element = otherPrimeInfoJSArray->getIndex(m_exec, i); if (m_exec->hadException()) return nullptr; if (!element.isObject()) { throwTypeError(m_exec, "JWK \"oth\" array member is not an object"); return nullptr; } if (!getBigIntegerVectorFromJSON(m_exec, asObject(element), "r", info.primeFactor)) { if (!m_exec->hadException()) throwTypeError(m_exec, "Cannot get prime factor for a prime in \"oth\" dictionary"); return nullptr; } if (!getBigIntegerVectorFromJSON(m_exec, asObject(element), "d", info.factorCRTExponent)) { if (!m_exec->hadException()) throwTypeError(m_exec, "Cannot get factor CRT exponent for a prime in \"oth\" dictionary"); return nullptr; } if (!getBigIntegerVectorFromJSON(m_exec, asObject(element), "t", info.factorCRTCoefficient)) { if (!m_exec->hadException()) throwTypeError(m_exec, "Cannot get factor CRT coefficient for a prime in \"oth\" dictionary"); return nullptr; } otherPrimeInfos.append(info); } return CryptoKeyDataRSAComponents::createPrivateWithAdditionalData(modulus, exponent, privateExponent, firstPrimeInfo, secondPrimeInfo, otherPrimeInfos); }