/// <summary>Decodes a string of UTF-8 base64url-encoded text.</summary> /// <remarks>This method allocate an array of bytes. Use <see cref="Decode(ReadOnlySpan{byte}, Span{byte})"/> when possible.</remarks> public static byte[] Decode(string data) { if (data is null) { ThrowHelper.ThrowArgumentNullException(ExceptionArgument.data); } int length = Utf8.GetMaxByteCount(data.Length); byte[]? utf8ArrayToReturn = null; try { Span <byte> tmp = length > Constants.MaxStackallocBytes ? (utf8ArrayToReturn = ArrayPool <byte> .Shared.Rent(length)) : stackalloc byte[Constants.MaxStackallocBytes]; int written = Utf8.GetBytes(data, tmp); return(Decode(tmp.Slice(0, written))); } finally { if (utf8ArrayToReturn != null) { ArrayPool <byte> .Shared.Return(utf8ArrayToReturn); } } }
/// <inheritsdoc /> public override void Encode(EncodingContext context) { if (Payload != null) { int payloadLength = Utf8.GetMaxByteCount(Payload.Length); byte[]? payloadToReturnToPool = null; Span <byte> encodedPayload = payloadLength > Constants.MaxStackallocBytes ? (payloadToReturnToPool = ArrayPool <byte> .Shared.Rent(payloadLength)) : stackalloc byte[payloadLength]; try { int bytesWritten = Utf8.GetBytes(Payload, encodedPayload); EncryptToken(encodedPayload.Slice(0, bytesWritten), context); } finally { if (payloadToReturnToPool != null) { ArrayPool <byte> .Shared.Return(payloadToReturnToPool); } } } else { ThrowHelper.ThrowInvalidOperationException_UndefinedPayload(); } }
/// <summary>Returns a new instance of <see cref="Jwks"/>.</summary> /// <param name="issuer">The issuer of the keys.</param> /// <param name="json">A string that contains JSON Web Key parameters in JSON format.</param> public static Jwks FromJson(string issuer, string json) { if (json is null) { ThrowHelper.ThrowArgumentNullException(ExceptionArgument.json); } byte[]? jsonToReturn = null; try { int length = Utf8.GetMaxByteCount(json.Length); Span <byte> jsonSpan = length <= Constants.MaxStackallocBytes ? stackalloc byte[length] : (jsonToReturn = ArrayPool <byte> .Shared.Rent(length)); length = Utf8.GetBytes(json, jsonSpan); return(FromJson(issuer, jsonSpan.Slice(0, length))); } finally { if (jsonToReturn != null) { ArrayPool <byte> .Shared.Return(jsonToReturn); } } }
/// <summary> /// Initializes a new instance of <see cref="SignatureAlgorithm"/>. /// </summary> /// <param name="id"></param> /// <param name="name"></param> /// <param name="category"></param> /// <param name="requiredKeySizeInBits"></param> /// <param name="hashAlgorithm"></param> public SignatureAlgorithm(int id, string name, AlgorithmCategory category, ushort requiredKeySizeInBits, HashAlgorithmName hashAlgorithm) { _id = id; _utf8Name = Utf8.GetBytes(name); _category = category; _requiredKeySizeInBits = requiredKeySizeInBits; _hashAlgorithm = hashAlgorithm; }
/// <summary> /// Initializes a new instance of <see cref="KeyManagementAlgorithm"/>. /// </summary> /// <param name="id"></param> /// <param name="name"></param> /// <param name="keyType"></param> /// <param name="requiredKeySizeInBits"></param> /// <param name="wrappedAlgorithm"></param> /// <param name="produceEncryptedKey"></param> public KeyManagementAlgorithm(byte id, string name, AlgorithmCategory keyType, ushort requiredKeySizeInBits, KeyManagementAlgorithm?wrappedAlgorithm, bool produceEncryptedKey) { _id = id; _utf8Name = Utf8.GetBytes(name); _category = keyType; _requiredKeySizeInBits = requiredKeySizeInBits; _wrappedAlgorithm = wrappedAlgorithm; _produceEncryptionKey = produceEncryptedKey; }
/// <summary> /// Decodes a string of UTF-8 base64url-encoded text. /// </summary> public static byte[] Decode(string data) { if (data is null) { ThrowHelper.ThrowArgumentNullException(ExceptionArgument.data); } return(Decode(Utf8.GetBytes(data))); }
/// <summary> /// Initializes a new instance of <see cref="EncryptionAlgorithm"/>. /// </summary> /// <param name="id"></param> /// <param name="name"></param> /// <param name="requiredKeySizeInBytes"></param> /// <param name="hashAlgorithm"></param> /// <param name="requiredKeyWrappedSizeInBytes"></param> /// <param name="category"></param> public EncryptionAlgorithm(sbyte id, string name, ushort requiredKeySizeInBytes, SignatureAlgorithm?hashAlgorithm, ushort requiredKeyWrappedSizeInBytes, EncryptionType category) { _id = id; _utf8Name = Utf8.GetBytes(name); _requiredKeySizeInBytes = requiredKeySizeInBytes; _signatureAlgorithm = hashAlgorithm; _keyWrappedSizeInBytes = requiredKeyWrappedSizeInBytes; _category = category; }
/// <summary>Returns a new instance of <see cref="PasswordBasedJwk"/>.</summary> /// <remarks>The passphrase should not be longer that 128 bytes, and at least 16 bytes for "PBES2-HS256+A128KW", /// 24 bytes for "PBES2-HS384+A192KW" and 32 bytes for "PBES2-HS512+A256KW"</remarks> /// <param name="passphrase">The passphrase used for the key derivation. /// This should not be longer that 128 bytes, and at least 16 bytes for "PBES2-HS256+A128KW", /// 24 bytes for "PBES2-HS384+A192KW" and 32 bytes for "PBES2-HS512+A256KW"</param> /// <param name="algorithm">The key encryption algorithm. It must be a PBES2 algorithm.</param> /// <param name="iterationCount">The number of iterations. Should be at least 1000.</param> /// <param name="saltSizeInBytes">The salt size, in bytes. Should be at least 8 bytes. Value greater than 256 bytes is not supported.</param> /// <param name="computeThumbprint">Defines whether the thubpring should be computed.</param> public static PasswordBasedJwk FromPassphrase(string passphrase, KeyManagementAlgorithm algorithm, uint iterationCount = 1000, uint saltSizeInBytes = 8, bool computeThumbprint = true) { if (passphrase is null) { ThrowHelper.ThrowArgumentNullException(ExceptionArgument.bytes); } var innerKey = SymmetricJwk.FromByteArray(Utf8.GetBytes(passphrase), algorithm, computeThumbprint); return(new PasswordBasedJwk(innerKey, iterationCount, saltSizeInBytes, algorithm)); }
/// <summary>Requires a specific issuer. This value is used if no issuer is defined by the method <see cref="RequireSignatureByDefault(string, IKeyProvider, SignatureAlgorithm?)"/>.</summary> public TokenValidationPolicyBuilder DefaultIssuer(string issuer) { if (string.IsNullOrEmpty(issuer)) { throw new ArgumentNullException(nameof(issuer)); } _issuers.Add(Utf8.GetBytes(issuer)); _control |= TokenValidationPolicy.IssuerMask; return(this); }
/// <summary>Requires a specific audience.</summary> public TokenValidationPolicyBuilder RequireAudience(string audience) { if (string.IsNullOrEmpty(audience)) { throw new ArgumentNullException(nameof(audience)); } _audiences.Add(Utf8.GetBytes(audience)); _control |= TokenValidationPolicy.AudienceMask; return(this); }
/// <summary> /// Requires a specific issuer. /// </summary> /// <param name="issuer"></param> /// <returns></returns> public TokenValidationPolicyBuilder RequireIssuer(string issuer) { if (string.IsNullOrEmpty(issuer)) { throw new ArgumentNullException(nameof(issuer)); } _issuer = Utf8.GetBytes(issuer); _control |= TokenValidationPolicy.IssuerFlag; return(this); }
/// <summary> /// Defines the default signature validation when there is no issuer configuration. /// Use the method <see cref="RequireSignature(string, Jwk, SignatureAlgorithm)"/> for linking the issuer with the signature. /// </summary> public TokenValidationPolicyBuilder RequireSignatureByDefault(Jwk key, string algorithm) { if (algorithm is null) { throw new ArgumentNullException(nameof(algorithm)); } if (!SignatureAlgorithm.TryParse(Utf8.GetBytes(algorithm), out var alg)) { throw new NotSupportedException($"The algorithm '{alg}' is not supported."); } return(RequireSignatureByDefault(new Jwks(key), alg)); }
/// <summary> /// Initializes a new instance of the <see cref="CompressionAlgorithm"/> class. /// </summary> /// <param name="id"></param> /// <param name="name"></param> /// <param name="compressor"></param> public CompressionAlgorithm(sbyte id, string name, Compressor compressor) { if (name is null) { ThrowHelper.ThrowArgumentNullException(ExceptionArgument.name); } if (compressor is null) { ThrowHelper.ThrowArgumentNullException(ExceptionArgument.compressor); } _id = id; _utf8Name = Utf8.GetBytes(name); Compressor = compressor; }
internal static int GetUtf8FromText(ReadOnlySpan <char> text, Span <byte> dest) { try { return(Utf8.GetBytes(text, dest)); } catch (EncoderFallbackException ex) { // We want to be consistent with the exception being thrown // so the user only has to catch a single exception. // Since we already throw ArgumentException when validating other arguments, // using that exception for failure to encode invalid UTF-16 chars as well. // Therefore, wrapping the EncoderFallbackException around an ArgumentException. //throw ThrowHelper.GetArgumentException_ReadInvalidUTF16(ex); throw new InvalidOperationException("Invalid UTF16", ex); } }
/// <summary>Requires a least one audience contained in the <paramref name="audiences"/>.</summary> public TokenValidationPolicyBuilder RequireAudience(IEnumerable <string> audiences) { if (audiences == null) { throw new ArgumentNullException(nameof(audiences)); } foreach (var audience in audiences) { if (audience != null) { _audiences.Add(Utf8.GetBytes(audience)); _control |= TokenValidationPolicy.AudienceMask; } } return(this); }
/// <summary>Parses and validates a JWT encoded as a JWS or JWE in compact serialized format.</summary> /// <param name="token">The JWT encoded as JWE or JWS</param> /// <param name="policy">The validation policy.</param> /// <param name="jwt">The resulting <see cref="Jwt"/>.</param> public static bool TryParse(string token, TokenValidationPolicy policy, out Jwt jwt) { if (token is null) { ThrowHelper.ThrowArgumentNullException(ExceptionArgument.token); } if (policy is null) { ThrowHelper.ThrowArgumentNullException(ExceptionArgument.policy); } if (token.Length == 0) { jwt = new Jwt(TokenValidationError.MalformedToken()); return(false); } int length = Utf8.GetMaxByteCount(token.Length); if (length > policy.MaximumTokenSizeInBytes) { jwt = new Jwt(TokenValidationError.MalformedToken()); return(false); } byte[]? utf8ArrayToReturnToPool = null; var utf8Token = length <= Constants.MaxStackallocBytes ? stackalloc byte[length] : (utf8ArrayToReturnToPool = ArrayPool <byte> .Shared.Rent(length)); try { int bytesWritten = Utf8.GetBytes(token, utf8Token); return(TryParse(utf8Token.Slice(0, bytesWritten), policy, out jwt)); } finally { if (utf8ArrayToReturnToPool != null) { ArrayPool <byte> .Shared.Return(utf8ArrayToReturnToPool); } } }
/// <summary>Decodes a span of UTF-8 base64-encoded text into a span of bytes.</summary> /// <returns>The number of the bytes written to <paramref name="data"/>.</returns> public static int Decode(ReadOnlySpan <char> base64, Span <byte> data) { byte[]? arrayToReturn = null; var buffer = base64.Length > Constants.MaxStackallocBytes ? (arrayToReturn = ArrayPool <byte> .Shared.Rent(base64.Length)) : stackalloc byte[Constants.MaxStackallocBytes]; try { int length = Utf8.GetBytes(base64, buffer); return(Decode(buffer.Slice(0, length), data)); } finally { if (arrayToReturn != null) { ArrayPool <byte> .Shared.Return(arrayToReturn); } } }
/// <summary> /// Encodes a string of UTF-8 text. /// </summary> /// <returns>The base64-url encoded string.</returns> public static byte[] Encode(ReadOnlySpan <char> data) { byte[]? utf8ArrayToReturn = null; try { var utf8Data = data.Length > Constants.MaxStackallocBytes ? (utf8ArrayToReturn = ArrayPool <byte> .Shared.Rent(data.Length)).AsSpan(0, data.Length) : stackalloc byte[data.Length]; Utf8.GetBytes(data, utf8Data); return(Encode(utf8Data)); } finally { if (utf8ArrayToReturn != null) { ArrayPool <byte> .Shared.Return(utf8ArrayToReturn); } } }
/// <summary> /// Decodes a span of UTF-8 base64url-encoded text into a span of bytes. /// </summary> /// <returns>The number of the bytes written to <paramref name="data"/>.</returns> public static int Decode(ReadOnlySpan <char> base64Url, Span <byte> data) { byte[]? arrayToReturn = null; var buffer = base64Url.Length > Constants.MaxStackallocBytes ? (arrayToReturn = ArrayPool <byte> .Shared.Rent(base64Url.Length)).AsSpan(0, base64Url.Length) : stackalloc byte[base64Url.Length]; try { Utf8.GetBytes(base64Url, buffer); return(Decode(buffer, data)); } finally { if (arrayToReturn != null) { ArrayPool <byte> .Shared.Return(arrayToReturn); } } }
/// <summary>Encodes a string of UTF-8 text.</summary> /// <returns>The base64-url encoded string.</returns> /// <remarks>This method allocate an array of bytes. Use <see cref="Encode(ReadOnlySpan{byte}, Span{byte})"/> when possible.</remarks> public static byte[] Encode(ReadOnlySpan <char> data) { byte[]? utf8ArrayToReturn = null; try { int length = Utf8.GetMaxByteCount(data.Length); var utf8Data = length > Constants.MaxStackallocBytes ? (utf8ArrayToReturn = ArrayPool <byte> .Shared.Rent(length)) : stackalloc byte[Constants.MaxStackallocBytes]; int written = Utf8.GetBytes(data, utf8Data); return(Encode(utf8Data.Slice(0, written))); } finally { if (utf8ArrayToReturn != null) { ArrayPool <byte> .Shared.Return(utf8ArrayToReturn); } } }
/// <inheritsdoc /> public override void Encode(EncodingContext context, IBufferWriter <byte> output) { int payloadLength = Utf8.GetMaxByteCount(Payload.Length); byte[]? payloadToReturnToPool = null; Span <byte> encodedPayload = payloadLength > Constants.MaxStackallocBytes ? (payloadToReturnToPool = ArrayPool <byte> .Shared.Rent(payloadLength)) : stackalloc byte[payloadLength]; try { int bytesWritten = Utf8.GetBytes(Payload, encodedPayload); EncryptToken(context, encodedPayload.Slice(0, bytesWritten), output); } finally { if (payloadToReturnToPool != null) { ArrayPool <byte> .Shared.Return(payloadToReturnToPool); } } }
/// <summary> /// Initializes a new instance of the <see cref="Jwk"/> class. /// </summary> /// <param name="alg"></param> protected Jwk(string alg) { Alg = Utf8.GetBytes(alg); }
/// <summary> /// Gets or sets the <see cref="JwtProperty"/> at the specified key; /// </summary> /// <param name="key"></param> /// <returns></returns> public JwtProperty this[string key] => this[Utf8.GetBytes(key).AsSpan()];
public SingleIssuerSignatureValidationPolicy(string issuer, SignatureValidationPolicy policy) { _issuer = Utf8.GetBytes(issuer); _policy = policy; }
public MultiIssuersSignatureValidationPolicy(Dictionary <string, SignatureValidationPolicy> policies, SignatureValidationPolicy defaultPolicy) { _policies = policies.ToDictionary(issuer => Utf8.GetBytes(issuer.Key), v => v.Value).ToArray(); _defaultPolicy = defaultPolicy; }
/// <summary> /// Adds a claim. /// </summary> /// <param name="name"></param> /// <param name="value"></param> /// <returns></returns> public JwtDescriptorBuilder AddClaim(string name, JwtObject value) => AddClaim(Utf8.GetBytes(name), value);
/// <summary> /// Initializes a new instance of the <see cref="JwtHeader"/> class. /// </summary> /// <param name="json"></param> public static JwtHeader FromJson(string json) { return(JwtHeaderParser.ParseHeader(Utf8.GetBytes(json), TokenValidationPolicy.NoValidation)); }
/// <summary> /// Adds a claim. /// </summary> /// <param name="name"></param> /// <param name="value"></param> /// <returns></returns> public void AddClaim(string name, JwtProperty value) => AddClaim(Utf8.GetBytes(name), value);
/// <summary> /// Adds a header parameter. /// </summary> /// <param name="name"></param> /// <param name="value"></param> /// <returns></returns> public JwtDescriptorBuilder AddHeader(string name, JwtArray value) => AddHeader(Utf8.GetBytes(name), value);
public static Address FromJson(string json) { return(FromJson(Utf8.GetBytes(json))); }