public unsafe static byte[] ComputeKeyBytes(string key) { const int bufferLength = 128; byte *pBuffer = stackalloc byte[bufferLength]; int written, consumed; var buffer = new Span <byte>(pBuffer, bufferLength); if (Utf16.ToUtf8(key.AsReadOnlySpan().AsBytes(), buffer, out consumed, out written) != TransformationStatus.Done) { throw new NotImplementedException("need to resize buffer"); } var keyBytes = new byte[64]; var result = Base64.Decode(buffer.Slice(0, written), keyBytes, out consumed, out written); if (result != TransformationStatus.Done || written != 64) { throw new NotImplementedException("need to resize buffer"); } return(keyBytes); }
public static bool TryWrite(Span <byte> output, Sha256 hash, string verb, string canonicalizedResource, DateTime utc, out int bytesWritten) { int written, consumed; bytesWritten = 0; if (verb.Equals("GET", StringComparison.Ordinal)) { if (output.Length < 3) { bytesWritten = 0; return(false); } s_GET.CopyTo(output); bytesWritten += s_GET.Length; } else { if (Utf16.ToUtf8(verb.AsReadOnlySpan().AsBytes(), output, out consumed, out written) != TransformationStatus.Done) { bytesWritten = 0; return(false); } output[written] = (byte)'\n'; bytesWritten += written + 1; } var free = output.Slice(bytesWritten); s_emptyHeaders.CopyTo(free); bytesWritten += s_emptyHeaders.Length; free = output.Slice(bytesWritten); if (!Text.Formatters.Utf8.TryFormat(utc, free, out written, 'R')) { bytesWritten = 0; return(false); } free[written] = (byte)'\n'; bytesWritten += written + 1; free = output.Slice(bytesWritten); if (Utf16.ToUtf8(canonicalizedResource.AsReadOnlySpan().AsBytes(), free, out consumed, out written) != TransformationStatus.Done) { bytesWritten = 0; return(false); } bytesWritten += written; var formatted = output.Slice(0, bytesWritten); hash.Append(formatted); hash.GetHash(output.Slice(0, hash.OutputSize)); if (!Base64.EncodeInPlace(output, hash.OutputSize, out written)) { bytesWritten = 0; return(false); } bytesWritten = written; return(true); }
/// <summary> /// Converts a span containing a sequence of UTF-16 bytes into UTF-8 bytes. /// /// This method will consume as many of the input bytes as possible. /// /// On successful exit, the entire input was consumed and encoded successfully. In this case, <paramref name="bytesConsumed"/> will be /// equal to the length of the <paramref name="source"/> and <paramref name="bytesWritten"/> will equal the total number of bytes written to /// the <paramref name="destination"/>. /// </summary> /// <param name="source">A span containing a sequence of UTF-16 bytes.</param> /// <param name="destination">A span to write the UTF-8 bytes into.</param> /// <param name="bytesConsumed">On exit, contains the number of bytes that were consumed from the <paramref name="source"/>.</param> /// <param name="bytesWritten">On exit, contains the number of bytes written to <paramref name="destination"/></param> /// <returns>A <see cref="OperationStatus"/> value representing the state of the conversion.</returns> public static OperationStatus FromUtf16(ReadOnlySpan <byte> source, Span <byte> destination, out int bytesConsumed, out int bytesWritten) => Utf16.ToUtf8(source, destination, out bytesConsumed, out bytesWritten);
public static bool TryWrite(Span <byte> output, Sha256 hash, string keyType, string verb, string resourceId, string resourceType, string tokenVersion, DateTime utc, out int bytesWritten) { int written, consumed, totalWritten = 0; bytesWritten = 0; Span <byte> buffer; unsafe { var pBuffer = stackalloc byte[AuthenticationHeaderBufferSize]; buffer = new Span <byte>(pBuffer, AuthenticationHeaderBufferSize); } s_type.CopyTo(buffer); totalWritten += s_type.Length; var bufferSlice = buffer.Slice(totalWritten); if (Utf16.ToUtf8(keyType.AsReadOnlySpan().AsBytes(), bufferSlice, out consumed, out written) != TransformationStatus.Done) { throw new NotImplementedException("need to resize buffer"); } totalWritten += written; bufferSlice = buffer.Slice(totalWritten); s_ver.CopyTo(bufferSlice); totalWritten += s_ver.Length; bufferSlice = buffer.Slice(totalWritten); if (Utf16.ToUtf8(tokenVersion.AsReadOnlySpan().AsBytes(), bufferSlice, out consumed, out written) != TransformationStatus.Done) { throw new NotImplementedException("need to resize buffer"); } totalWritten += written; bufferSlice = buffer.Slice(totalWritten); s_sig.CopyTo(bufferSlice); totalWritten += s_sig.Length; var front = buffer.Slice(0, totalWritten); var payload = buffer.Slice(totalWritten); totalWritten = 0; if (verb.Equals("GET", StringComparison.Ordinal) || verb.Equals("get", StringComparison.Ordinal)) { s_get.CopyTo(payload); totalWritten += s_get.Length; } else if (verb.Equals("POST", StringComparison.Ordinal) || verb.Equals("post", StringComparison.Ordinal)) { s_post.CopyTo(payload); totalWritten += s_post.Length; } else if (verb.Equals("DELETE", StringComparison.Ordinal) || verb.Equals("delete", StringComparison.Ordinal)) { s_delete.CopyTo(payload); totalWritten += s_delete.Length; } else { if (Utf16.ToUtf8(verb.AsReadOnlySpan().AsBytes(), payload, out consumed, out written) != TransformationStatus.Done) { throw new NotImplementedException("need to resize buffer"); } if (Ascii.ToLowerInPlace(payload.Slice(0, written), out written) != TransformationStatus.Done) { throw new NotImplementedException("need to resize buffer"); } payload[written] = (byte)'\n'; totalWritten += written + 1; } bufferSlice = payload.Slice(totalWritten); if (Utf16.ToUtf8(resourceType.AsReadOnlySpan().AsBytes(), bufferSlice, out consumed, out written) != TransformationStatus.Done) { throw new NotImplementedException("need to resize buffer"); } if (Ascii.ToLowerInPlace(bufferSlice.Slice(0, written), out written) != TransformationStatus.Done) { throw new NotImplementedException("need to resize buffer"); } bufferSlice[written] = (byte)'\n'; totalWritten += written + 1; bufferSlice = payload.Slice(totalWritten); if (Utf16.ToUtf8(resourceId.AsReadOnlySpan().AsBytes(), bufferSlice, out consumed, out written) != TransformationStatus.Done) { throw new NotImplementedException("need to resize buffer"); } bufferSlice[written] = (byte)'\n'; totalWritten += written + 1; bufferSlice = payload.Slice(totalWritten); if (!Text.Formatters.Utf8.TryFormat(utc, bufferSlice, out written, 'l')) { throw new NotImplementedException("need to resize buffer"); } bufferSlice[written] = (byte)'\n'; totalWritten += written + 1; bufferSlice = payload.Slice(totalWritten); bufferSlice[0] = (byte)'\n'; totalWritten += 1; hash.Append(buffer.Slice(front.Length, totalWritten)); hash.GetHash(buffer.Slice(front.Length, hash.OutputSize)); if (!Base64.EncodeInPlace(buffer.Slice(front.Length), hash.OutputSize, out written)) { throw new NotImplementedException("need to resize buffer"); } var len = front.Length + written; if (!UrlEncoder.TryEncode(buffer.Slice(0, len), output, out bytesWritten)) { bytesWritten = 0; return(false); } return(true); }