static bool getBigIntegerVectorFromJSON(ExecState* exec, JSObject* json, const char* key, Vector<uint8_t>& result) { String base64urlEncodedNumber; if (!getStringFromJSON(exec, json, key, base64urlEncodedNumber)) return false; if (!base64URLDecode(base64urlEncodedNumber, result)) { throwTypeError(exec, "Cannot decode base64url key data in JWK"); return false; } if (result[0] == 0) { throwTypeError(exec, "JWK BigInteger must utilize the minimum number of octets to represent the value"); return false; } return true; }
RefPtr<CryptoKeyHMAC> CryptoKeyHMAC::importJwk(size_t lengthBits, CryptoAlgorithmIdentifier hash, JsonWebKey&& keyData, bool extractable, CryptoKeyUsageBitmap usages, CheckAlgCallback&& callback) { if (keyData.kty != "oct") return nullptr; if (!keyData.k) return nullptr; Vector<uint8_t> octetSequence; if (!base64URLDecode(keyData.k.value(), octetSequence)) return nullptr; if (!callback(hash, keyData.alg)) return nullptr; if (usages && keyData.use && keyData.use.value() != "sig") return nullptr; if (keyData.usages && ((keyData.usages & usages) != usages)) return nullptr; if (keyData.ext && !keyData.ext.value() && extractable) return nullptr; return CryptoKeyHMAC::importRaw(lengthBits, hash, WTFMove(octetSequence), extractable, usages); }
RefPtr<CryptoKeyAES> CryptoKeyAES::importJwk(CryptoAlgorithmIdentifier algorithm, JsonWebKey&& keyData, bool extractable, CryptoKeyUsageBitmap usages, CheckAlgCallback&& callback) { if (keyData.kty != "oct") return nullptr; if (!keyData.k) return nullptr; Vector<uint8_t> octetSequence; if (!base64URLDecode(keyData.k.value(), octetSequence)) return nullptr; if (!callback(octetSequence.size() * 8, keyData.alg)) return nullptr; if (usages && keyData.use && keyData.use.value() != "enc") return nullptr; if (keyData.usages && ((keyData.usages & usages) != usages)) return nullptr; if (keyData.ext && !keyData.ext.value() && extractable) return nullptr; return adoptRef(new CryptoKeyAES(algorithm, WTFMove(octetSequence), extractable, usages)); }
std::unique_ptr<CryptoKeyData> JSCryptoKeySerializationJWK::keyDataOctetSequence() const { String keyBase64URL; if (!getStringFromJSON(m_exec, m_json.get(), "k", keyBase64URL)) { if (!m_exec->hadException()) throwTypeError(m_exec, "Secret key data is not present is JWK"); return nullptr; } Vector<uint8_t> octetSequence; if (!base64URLDecode(keyBase64URL, octetSequence)) { throwTypeError(m_exec, "Cannot decode base64url key data in JWK"); return nullptr; } if (!keySizeIsValid(octetSequence.size() * 8)) { throwTypeError(m_exec, "Key size is not valid for " + m_jwkAlgorithmName); return nullptr; } return CryptoKeyDataOctetSequence::create(octetSequence); }
// hash-source = "'" hash-algorithm "-" base64-value "'" // hash-algorithm = "sha256" / "sha384" / "sha512" // base64-value = 1*( ALPHA / DIGIT / "+" / "/" / "-" / "_" )*2( "=" ) bool ContentSecurityPolicySourceList::parseHashSource(const UChar* begin, const UChar* end) { if (begin == end) return false; const UChar* position = begin; if (!skipExactly<UChar>(position, end, '\'')) return false; ContentSecurityPolicyHashAlgorithm algorithm; if (!parseHashAlgorithmAdvancingPosition(position, end - position, algorithm)) return false; if (!skipExactly<UChar>(position, end, '-')) return false; const UChar* beginHashValue = position; skipWhile<UChar, isBase64Character>(position, end); skipExactly<UChar>(position, end, '='); skipExactly<UChar>(position, end, '='); if (position >= end || position == beginHashValue || *position != '\'') return false; Vector<uint8_t> digest; StringView hashValue(beginHashValue, position - beginHashValue); // base64url or base64 encoded // FIXME: Normalize Base64URL to Base64 instead of decoding twice. See <https://bugs.webkit.org/show_bug.cgi?id=155186>. if (!base64Decode(hashValue.toStringWithoutCopying(), digest, Base64ValidatePadding)) { if (!base64URLDecode(hashValue.toStringWithoutCopying(), digest)) return false; } if (digest.size() > maximumContentSecurityPolicyDigestLength) return false; m_hashes.add(std::make_pair(algorithm, digest)); m_hashAlgorithmsUsed |= algorithm; return true; }