public override bool TryValidateSignature(JwtHeaderDocument header, JwtPayloadDocument payload, ReadOnlySpan <byte> contentBytes, ReadOnlySpan <byte> signatureSegment, [NotNullWhen(false)] out SignatureValidationError?error) { if (signatureSegment.IsEmpty) { if (contentBytes.IsEmpty) { // This is not a JWS goto Success; } else { error = SignatureValidationError.MissingSignature(); goto Error; } } byte[]? signatureToReturn = null; try { int signatureBytesLength = Base64Url.GetArraySizeRequiredToDecode(signatureSegment.Length); Span <byte> signatureBytes = signatureBytesLength > Constants.MaxStackallocBytes ? (signatureToReturn = ArrayPool <byte> .Shared.Rent(signatureBytesLength)) : stackalloc byte[Constants.MaxStackallocBytes]; if (Base64Url.Decode(signatureSegment, signatureBytes, out _, out int bytesWritten) != OperationStatus.Done) { error = SignatureValidationError.MalformedSignature(); goto Error; } signatureBytes = signatureBytes.Slice(0, bytesWritten); //Debug.Assert(signatureBytesLength == bytesWritten); bool keysTried = false; var keySet = _keyProvider.GetKeys(header); var algElement = header.Alg; if (keySet != null) { var algorithm = _algorithm; for (int i = 0; i < keySet.Length; i++) { var key = keySet[i]; if (key.CanUseForSignature(algElement)) { var alg = algorithm ?? key.SignatureAlgorithm; if (!(alg is null)) { if (key.TryGetSignatureVerifier(alg, out var signatureVerifier)) { if (signatureVerifier.Verify(contentBytes, signatureBytes.Slice(0, signatureBytesLength))) { goto Success; } } } keysTried = true; } } } error = keysTried ? SignatureValidationError.InvalidSignature() : SignatureValidationError.SignatureKeyNotFound(); } catch (FormatException e) { error = SignatureValidationError.MalformedSignature(e); } finally { if (signatureToReturn != null) { ArrayPool <byte> .Shared.Return(signatureToReturn); } } Error: return(false); Success: #if NET5_0_OR_GREATER Unsafe.SkipInit(out error); #else error = default; #endif return(true); }
public override bool TryValidateSignature(JwtHeaderDocument header, JwtPayloadDocument payload, ReadOnlySpan <byte> contentBytes, ReadOnlySpan <byte> signatureSegment, [NotNullWhen(false)] out SignatureValidationError?error) { if (signatureSegment.IsEmpty) { if (contentBytes.IsEmpty) { // This is not a JWS goto Success; } else { error = SignatureValidationError.MissingSignature(); goto Error; } } try { int signatureBytesLength = Base64Url.GetArraySizeRequiredToDecode(signatureSegment.Length); Span <byte> signatureBytes = stackalloc byte[signatureBytesLength]; if (Base64Url.Decode(signatureSegment, signatureBytes, out int byteConsumed, out int bytesWritten) != OperationStatus.Done) { error = SignatureValidationError.MalformedSignature(); goto Error; } Debug.Assert(bytesWritten == signatureBytes.Length); bool keysTried = false; var keySet = _keyProvider.GetKeys(header); var algElement = header.Alg; if (keySet != null) { var algorithm = _algorithm; for (int i = 0; i < keySet.Length; i++) { var key = keySet[i]; if (key.CanUseForSignature(algElement)) { var alg = algorithm ?? key.SignatureAlgorithm; if (!(alg is null)) { if (key.TryGetSignatureVerifier(alg, out var signatureVerifier)) { if (signatureVerifier.Verify(contentBytes, signatureBytes)) { goto Success; } } } keysTried = true; } } } error = keysTried ? SignatureValidationError.InvalidSignature() : SignatureValidationError.SignatureKeyNotFound(); } catch (FormatException e) { error = SignatureValidationError.MalformedSignature(e); } Error: return(false); Success: error = null; return(true); }