private static Exception CreateNotSupportedException_CompressionAlgorithm(CompressionAlgorithm compressionAlgorithm) => new NotSupportedException($"Compression algorithm: '{compressionAlgorithm.Name}' is not supported.");
/// <summary>Initializes a new instance of the <see cref="JweDescriptor{TPayload}"/> class.</summary> protected JweDescriptor(Jwk encryptionKey, KeyManagementAlgorithm alg, EncryptionAlgorithm enc, CompressionAlgorithm?zip = null, string?typ = null, string?cty = null) { _encryptionKey = encryptionKey ?? throw new ArgumentNullException(nameof(encryptionKey)); _alg = alg ?? throw new ArgumentNullException(nameof(alg)); _enc = enc ?? throw new ArgumentNullException(nameof(enc)); _zip = zip ?? CompressionAlgorithm.NoCompression; var kid = encryptionKey.Kid; if (!kid.EncodedUtf8Bytes.IsEmpty) { _kid = kid; if (zip != null) { if (cty != null) { _cty = cty; Header.FastAdd( new JwtMember(JwtHeaderParameterNames.Alg, alg.Name), new JwtMember(JwtHeaderParameterNames.Enc, enc.Name), new JwtMember(JwtHeaderParameterNames.Kid, kid), new JwtMember(JwtHeaderParameterNames.Zip, zip.Name), new JwtMember(JwtHeaderParameterNames.Cty, cty)); } else { Header.FastAdd( new JwtMember(JwtHeaderParameterNames.Alg, alg.Name), new JwtMember(JwtHeaderParameterNames.Enc, enc.Name), new JwtMember(JwtHeaderParameterNames.Kid, kid), new JwtMember(JwtHeaderParameterNames.Zip, zip.Name)); } } else { if (cty != null) { _cty = cty; Header.FastAdd( new JwtMember(JwtHeaderParameterNames.Alg, alg.Name), new JwtMember(JwtHeaderParameterNames.Enc, enc.Name), new JwtMember(JwtHeaderParameterNames.Kid, kid), new JwtMember(JwtHeaderParameterNames.Cty, cty)); } else { Header.FastAdd( new JwtMember(JwtHeaderParameterNames.Alg, alg.Name), new JwtMember(JwtHeaderParameterNames.Enc, enc.Name), new JwtMember(JwtHeaderParameterNames.Kid, kid)); } } } else { if (zip != null) { if (cty != null) { _cty = cty; Header.FastAdd( new JwtMember(JwtHeaderParameterNames.Alg, alg.Name), new JwtMember(JwtHeaderParameterNames.Enc, enc.Name), new JwtMember(JwtHeaderParameterNames.Zip, zip.Name), new JwtMember(JwtHeaderParameterNames.Cty, cty)); } else { Header.FastAdd( new JwtMember(JwtHeaderParameterNames.Alg, alg.Name), new JwtMember(JwtHeaderParameterNames.Enc, enc.Name), new JwtMember(JwtHeaderParameterNames.Zip, zip.Name)); } } else { if (cty != null) { _cty = cty; Header.FastAdd( new JwtMember(JwtHeaderParameterNames.Alg, alg.Name), new JwtMember(JwtHeaderParameterNames.Enc, enc.Name), new JwtMember(JwtHeaderParameterNames.Cty, cty)); } else { Header.FastAdd( new JwtMember(JwtHeaderParameterNames.Alg, alg.Name), new JwtMember(JwtHeaderParameterNames.Enc, enc.Name)); } } } if (typ != null) { _typ = typ; Header.Add(JwtHeaderParameterNames.Typ, typ); } }
internal static void ThrowNotSupportedException_CompressionAlgorithm(CompressionAlgorithm compressionAlgorithm) => throw CreateNotSupportedException_CompressionAlgorithm(compressionAlgorithm);
/// <summary> /// Parses the UTF-8 <paramref name="buffer"/> as JSON and returns a <see cref="JwtHeader"/>. /// </summary> /// <param name="buffer"></param> /// <param name="policy"></param> public static JwtHeader ParseHeader(ReadOnlySpan <byte> buffer, TokenValidationPolicy policy) { Utf8JsonReader reader = new Utf8JsonReader(buffer, isFinalBlock: true, state: default); if (!reader.Read() || reader.TokenType != JsonTokenType.StartObject) { ThrowHelper.ThrowFormatException_MalformedJson(); } var header = new JwtHeader(); while (reader.Read()) { if (!(reader.TokenType is JsonTokenType.PropertyName)) { break; } var name = reader.ValueSpan /* reader.HasValueSequence ? reader.ValueSequence.ToArray() : reader.ValueSpan */; reader.Read(); var type = reader.TokenType; if (name.Length == 3) { if (reader.TokenType == JsonTokenType.String) { var refName = IntegerMarshal.ReadUInt24(name); switch (refName) { case Alg: var alg = reader.ValueSpan /* reader.HasValueSequence ? reader.ValueSequence.ToArray() : reader.ValueSpan */; if (SignatureAlgorithm.TryParse(alg, out var signatureAlgorithm)) { header.SignatureAlgorithm = signatureAlgorithm; } else if (KeyManagementAlgorithm.TryParse(alg, out var keyManagementAlgorithm)) { header.KeyManagementAlgorithm = keyManagementAlgorithm; } else if (SignatureAlgorithm.TryParseSlow(ref reader, out signatureAlgorithm)) { header.SignatureAlgorithm = signatureAlgorithm; } else if (KeyManagementAlgorithm.TryParseSlow(ref reader, out keyManagementAlgorithm)) { header.KeyManagementAlgorithm = keyManagementAlgorithm; } else { header.SignatureAlgorithm = SignatureAlgorithm.Create(reader.GetString()); } continue; case Enc: var enc = reader.ValueSpan /* reader.HasValueSequence ? reader.ValueSequence.ToArray() : reader.ValueSpan */; if (EncryptionAlgorithm.TryParse(enc, out var encryptionAlgorithm)) { header.EncryptionAlgorithm = encryptionAlgorithm; } else if (EncryptionAlgorithm.TryParseSlow(ref reader, out encryptionAlgorithm)) { header.EncryptionAlgorithm = encryptionAlgorithm; } else { header.EncryptionAlgorithm = EncryptionAlgorithm.Create(reader.GetString()); } continue; case Zip: var zip = reader.ValueSpan /* reader.HasValueSequence ? reader.ValueSequence.ToArray() : reader.ValueSpan */; if (CompressionAlgorithm.TryParse(zip, out var compressionAlgorithm)) { header.CompressionAlgorithm = compressionAlgorithm; } else if (CompressionAlgorithm.TryParseSlow(ref reader, out compressionAlgorithm)) { header.CompressionAlgorithm = compressionAlgorithm; } else { header.CompressionAlgorithm = CompressionAlgorithm.Create(reader.GetString()); } continue; case Cty: header.Cty = reader.GetString(); continue; case Typ: header.Typ = reader.GetString(); continue; case Kid: header.Kid = reader.GetString(); continue; } } } else if (name.Length == 4) { if (reader.TokenType == JsonTokenType.StartArray && IntegerMarshal.ReadUInt32(name) == Crit) { var handlers = policy.CriticalHandlers; if (handlers.Count != 0) { var criticalHeaderHandlers = new List <KeyValuePair <string, ICriticalHeaderHandler> >(handlers.Count); var criticals = new List <JwtValue>(); while (reader.Read() && reader.TokenType == JsonTokenType.String) { string criticalHeader = reader.GetString(); criticals.Add(new JwtValue(criticalHeader)); if (handlers.TryGetValue(criticalHeader, out var handler)) { criticalHeaderHandlers.Add(new KeyValuePair <string, ICriticalHeaderHandler>(criticalHeader, handler)); } else { criticalHeaderHandlers.Add(new KeyValuePair <string, ICriticalHeaderHandler>(criticalHeader, null !)); } } header.CriticalHeaderHandlers = criticalHeaderHandlers; if (reader.TokenType != JsonTokenType.EndArray) { ThrowHelper.ThrowFormatException_MalformedJson("The 'crit' header parameter must be an array of string."); } header.Inner.Add(name, new JwtArray(criticals)); } else { var criticals = new List <JwtValue>(); while (reader.Read() && reader.TokenType == JsonTokenType.String) { string criticalHeader = reader.GetString(); criticals.Add(new JwtValue(criticalHeader)); } if (reader.TokenType != JsonTokenType.EndArray) { ThrowHelper.ThrowFormatException_MalformedJson("The 'crit' header parameter must be an array of string."); } header.Inner.Add(name, new JwtArray(criticals)); } continue; } } switch (type) { case JsonTokenType.StartObject: header.Inner.Add(name, JsonParser.ReadJsonObject(ref reader)); break; case JsonTokenType.StartArray: header.Inner.Add(name, JsonParser.ReadJsonArray(ref reader)); break; case JsonTokenType.String: header.Inner.Add(name, reader.GetString()); break; case JsonTokenType.True: header.Inner.Add(name, true); break; case JsonTokenType.False: header.Inner.Add(name, false); break; case JsonTokenType.Null: header.Inner.Add(name); break; case JsonTokenType.Number: if (reader.TryGetInt64(out long longValue)) { header.Inner.Add(name, longValue); } else { header.Inner.Add(name, reader.GetDouble()); } break; default: ThrowHelper.ThrowFormatException_MalformedJson(); break; } } if (!(reader.TokenType is JsonTokenType.EndObject)) { ThrowHelper.ThrowFormatException_MalformedJson(); } return(header); }