public static bool TryWrite(Span <byte> output, Sha256 hash, Utf8Span keyType, Utf8Span verb, Utf8Span resourceId, Utf8Span resourceType, Utf8Span tokenVersion, DateTime utc, out int bytesWritten) { Span <byte> buffer = stackalloc byte[AuthenticationHeaderBufferSize]; var writer = BufferWriter.Create(buffer); writer.Enlarge = (minumumSize) => { return(new byte[minumumSize * 2]); }; // compute signature hash writer.WriteLine(verb, s_toLower); writer.WriteLine(resourceType, s_toLower); writer.WriteLine(resourceId, s_toLower); writer.WriteLine(utc, 'l'); writer.Write('\n'); hash.Append(writer.Written); // combine token writer.WrittenCount = 0; // reuse writer and buffer writer.Write(s_typeLiteral); writer.Write(keyType); writer.Write(s_verLiteral); writer.Write(tokenVersion); writer.Write(s_sigLiteral); writer.WriteBytes(hash, s_toBase64); if (UrlEncoder.Utf8.Encode(writer.Written, output, out var consumed, out bytesWritten) != OperationStatus.Done) { bytesWritten = 0; return(false); } return(true); }
static Utf8String s_emptyHeaders = (Utf8String)"\n\n\n\n\n\n\n\n\n\n\nx-ms-date:"; // this wont be needed once we have UTF8 literals public static bool TryWrite(Span <byte> output, Sha256 hash, string verb, string canonicalizedResource, DateTime utc, out int bytesWritten) { try { var writer = new SpanWriter(output); writer.WriteLine(verb); writer.Write("\n\n\n\n\n\n\n\n\n\n\nx-ms-date:"); writer.WriteLine(utc, 'R'); writer.Write(canonicalizedResource); hash.Append(writer.Written); writer.Index = 0; writer.WriteBytes(hash, default, Base64Experimental.BytesToUtf8Encoder);
public bool TryWrite(Span <byte> buffer, out int written, StandardFormat format = default) { try { var writer = BufferWriter.Create(buffer); writer.Write("SharedKey "); writer.Write(AccountName); writer.Write(':'); int signatureStart = writer.WrittenCount; writer.WriteBytes(HttpVerb); if (ContentLength == 0) { writer.Write("\n\n\n\n\n\n\n\n\n\n\n\n"); } else { writer.Write("\n\n\n"); writer.Write(ContentLength); writer.Write("\n\n\n\n\n\n\n\n\n"); } writer.WriteBytes(CanonicalizedHeaders, s_removeCR); // write canonicalized resource writer.Write('/'); writer.Write(AccountName); writer.Write('/'); writer.Write(CanonicalizedResource); // compute hash Hash.Append(writer.Written.Slice(signatureStart)); writer.WrittenCount = signatureStart; // write hash writer.WriteBytes(Hash, s_toBase64); written = writer.WrittenCount; return(true); } catch (BufferWriter.BufferTooSmallException) { buffer.Clear(); written = 0; return(false); } }
public static bool TryWrite(Span <byte> output, Sha256 hash, Utf8Span verb, Utf8Span canonicalizedResource, DateTime utc, out int bytesWritten) { try { var writer = BufferWriter.Create(output); writer.WriteLine(verb); writer.Write(s_emptyHeaders); writer.WriteLine(utc, 'R'); writer.Write(canonicalizedResource); hash.Append(writer.Written); writer.WrittenCount = 0; writer.WriteBytes(hash, s_toBase64); bytesWritten = writer.WrittenCount; return(true); } catch (BufferWriter.BufferTooSmallException) { bytesWritten = 0; return(false); } }
public static bool TryWrite(Span <byte> output, Sha256 hash, string keyType, string verb, string resourceId, string resourceType, string tokenVersion, DateTime utc, out int bytesWritten) { Span <byte> buffer = stackalloc byte[AuthenticationHeaderBufferSize]; var writer = new SpanWriter(buffer); writer.Enlarge = (minumumSize) => { return(new byte[minumumSize * 2]); }; // compute signature hash writer.WriteLine(verb, Ascii.ToLowercase); writer.WriteLine(resourceType, Ascii.ToLowercase); writer.WriteLine(resourceId, Ascii.ToLowercase); writer.WriteLine(utc, 'l'); writer.Write('\n'); hash.Append(writer.Written); // combine token writer.Index = 0; // reuse writer and buffer writer.Write("type="); writer.Write(keyType); writer.Write("&ver="); writer.Write(tokenVersion); writer.Write("&sig="); writer.WriteBytes(hash, default, Base64Experimental.BytesToUtf8Encoder);
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); }
public static bool TryWritePrimitives(Span <byte> output, Sha256 hash, string keyType, string verb, string resourceId, string resourceType, string tokenVersion, DateTime utc, out int bytesWritten) { int totalWritten = 0; bytesWritten = 0; Span <byte> buffer = stackalloc byte[AuthenticationHeaderBufferSize]; s_type.CopyTo(buffer); totalWritten += s_type.Length; if (Encodings.Utf16.ToUtf8(keyType.AsReadOnlySpan().AsBytes(), buffer.Slice(totalWritten), out int consumed, out int written) != OperationStatus.Done) { throw new NotImplementedException("need to resize buffer"); } totalWritten += written; s_ver.CopyTo(buffer.Slice(totalWritten)); totalWritten += s_ver.Length; if (Encodings.Utf16.ToUtf8(tokenVersion.AsReadOnlySpan().AsBytes(), buffer.Slice(totalWritten), out consumed, out written) != OperationStatus.Done) { throw new NotImplementedException("need to resize buffer"); } totalWritten += written; s_sig.CopyTo(buffer.Slice(totalWritten)); 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 (Encodings.Utf16.ToUtf8(verb.AsReadOnlySpan().AsBytes(), payload, out consumed, out written) != OperationStatus.Done) { throw new NotImplementedException("need to resize buffer"); } if (Encodings.Ascii.ToLowerInPlace(payload.Slice(0, written), out written) != OperationStatus.Done) { throw new NotImplementedException("need to resize buffer"); } payload[written] = (byte)'\n'; totalWritten += written + 1; } var bufferSlice = payload.Slice(totalWritten); if (Encodings.Utf16.ToUtf8(resourceType.AsReadOnlySpan().AsBytes(), bufferSlice, out consumed, out written) != OperationStatus.Done) { throw new NotImplementedException("need to resize buffer"); } if (Encodings.Ascii.ToLowerInPlace(bufferSlice.Slice(0, written), out written) != OperationStatus.Done) { throw new NotImplementedException("need to resize buffer"); } bufferSlice[written] = (byte)'\n'; totalWritten += written + 1; bufferSlice = payload.Slice(totalWritten); if (Encodings.Utf16.ToUtf8(resourceId.AsReadOnlySpan().AsBytes(), bufferSlice, out consumed, out written) != OperationStatus.Done) { throw new NotImplementedException("need to resize buffer"); } bufferSlice[written] = (byte)'\n'; totalWritten += written + 1; bufferSlice = payload.Slice(totalWritten); if (!Utf8Formatter.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)); if (!hash.TryWrite(buffer.Slice(front.Length), out written)) { throw new NotImplementedException("need to resize buffer"); } if (Base64.EncodeToUtf8InPlace(buffer.Slice(front.Length), written, out written) != OperationStatus.Done) { throw new NotImplementedException("need to resize buffer"); } var len = front.Length + written; if (UrlEncoder.Utf8.Encode(buffer.Slice(0, len), output, out consumed, out bytesWritten) != OperationStatus.Done) { bytesWritten = 0; return(false); } return(true); }
static bool TryWritePrimitive(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 (Encodings.Utf16.ToUtf8(MemoryMarshal.AsBytes(verb.AsSpan()), output, out consumed, out written) != OperationStatus.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 (!Utf8Formatter.TryFormat(utc, free, out written, 'R')) { bytesWritten = 0; return(false); } free[written] = (byte)'\n'; bytesWritten += written + 1; free = output.Slice(bytesWritten); if (Encodings.Utf16.ToUtf8(MemoryMarshal.AsBytes(canonicalizedResource.AsSpan()), free, out consumed, out written) != OperationStatus.Done) { bytesWritten = 0; return(false); } bytesWritten += written; var formatted = output.Slice(0, bytesWritten); hash.Append(formatted); if (!hash.TryWrite(output, out written)) { throw new NotImplementedException("need to resize buffer"); } if (Base64.EncodeToUtf8InPlace(output, written, out written) != OperationStatus.Done) { bytesWritten = 0; return(false); } bytesWritten = written; return(true); }