예제 #1
0
        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);
        }
예제 #2
0
        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);
        }
예제 #3
0
 /// <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);
        }