EncryptionDataSerializer
using Azure.Core;
using System;
using System.Collections.Generic;
using System.Text;
using System.Text.Json;
namespace Azure.Storage.Cryptography.Models
{
internal static class EncryptionDataSerializer
{
private const string EncryptionAgent_EncryptionVersionName = "Protocol";
public static string Serialize(EncryptionData data)
{
return Encoding.UTF8.GetString(SerializeEncryptionData(data).ToArray());
}
private static ReadOnlyMemory<byte> SerializeEncryptionData(EncryptionData data)
{
ArrayBufferWriter<byte> arrayBufferWriter = new ArrayBufferWriter<byte>();
using (Utf8JsonWriter utf8JsonWriter = new Utf8JsonWriter(arrayBufferWriter, default(JsonWriterOptions))) {
utf8JsonWriter.WriteStartObject();
WriteEncryptionData(utf8JsonWriter, data);
utf8JsonWriter.WriteEndObject();
utf8JsonWriter.Flush();
return arrayBufferWriter.WrittenMemory;
}
}
public static void WriteEncryptionData(Utf8JsonWriter json, EncryptionData data)
{
json.WriteString("EncryptionMode", data.EncryptionMode);
json.WriteStartObject("WrappedContentKey");
WriteWrappedKey(json, data.WrappedContentKey);
json.WriteEndObject();
json.WriteStartObject("EncryptionAgent");
WriteEncryptionAgent(json, data.EncryptionAgent);
json.WriteEndObject();
if (data.ContentEncryptionIV != null)
json.WriteString("ContentEncryptionIV", Convert.ToBase64String(data.ContentEncryptionIV));
if (data.EncryptedRegionInfo != null) {
json.WriteStartObject("EncryptedRegionInfo");
WriteEncryptedRegionInfo(json, data.EncryptedRegionInfo);
json.WriteEndObject();
}
json.WriteStartObject("KeyWrappingMetadata");
WriteDictionary(json, data.KeyWrappingMetadata);
json.WriteEndObject();
}
private static void WriteEncryptedRegionInfo(Utf8JsonWriter json, EncryptedRegionInfo encryptedRegionInfo)
{
json.WriteNumber("DataLength", encryptedRegionInfo.DataLength);
json.WriteNumber("NonceLength", encryptedRegionInfo.NonceLength);
}
private static void WriteWrappedKey(Utf8JsonWriter json, KeyEnvelope key)
{
json.WriteString("KeyId", key.KeyId);
json.WriteString("EncryptedKey", Convert.ToBase64String(key.EncryptedKey));
json.WriteString("Algorithm", key.Algorithm);
}
private static void WriteEncryptionAgent(Utf8JsonWriter json, EncryptionAgent encryptionAgent)
{
json.WriteString("Protocol", encryptionAgent.EncryptionVersion.Serialize());
json.WriteString("EncryptionAlgorithm", encryptionAgent.EncryptionAlgorithm.ToString());
}
private static void WriteDictionary(Utf8JsonWriter json, IDictionary<string, string> dictionary)
{
foreach (KeyValuePair<string, string> item in dictionary) {
json.WriteString(item.Key, item.Value);
}
}
public static EncryptionData Deserialize(string serializedData)
{
Utf8JsonReader reader = new Utf8JsonReader(Encoding.UTF8.GetBytes(serializedData), default(JsonReaderOptions));
return DeserializeEncryptionData(ref reader);
}
public static EncryptionData DeserializeEncryptionData(ref Utf8JsonReader reader)
{
using (JsonDocument jsonDocument = JsonDocument.ParseValue(ref reader))
return ReadEncryptionData(jsonDocument.RootElement);
}
public static EncryptionData ReadEncryptionData(JsonElement root)
{
EncryptionData encryptionData = new EncryptionData();
foreach (JsonProperty item in root.EnumerateObject()) {
ReadPropertyValue(encryptionData, item);
}
return encryptionData;
}
private static void ReadPropertyValue(EncryptionData data, JsonProperty property)
{
JsonElement value;
JsonElement.ObjectEnumerator objectEnumerator;
JsonElement.ObjectEnumerator enumerator;
if (property.Name.Equals("EncryptionMode", StringComparison.InvariantCultureIgnoreCase)) {
value = property.Value;
data.EncryptionMode = value.GetString();
} else if (property.Name.Equals("WrappedContentKey", StringComparison.InvariantCultureIgnoreCase)) {
KeyEnvelope keyEnvelope = new KeyEnvelope();
value = property.Value;
objectEnumerator = value.EnumerateObject();
enumerator = objectEnumerator.GetEnumerator();
try {
while (enumerator.MoveNext()) {
JsonProperty current = enumerator.Current;
ReadPropertyValue(keyEnvelope, current);
}
} finally {
((IDisposable)enumerator).Dispose();
}
data.WrappedContentKey = keyEnvelope;
} else if (property.Name.Equals("EncryptionAgent", StringComparison.InvariantCultureIgnoreCase)) {
EncryptionAgent encryptionAgent = new EncryptionAgent();
value = property.Value;
objectEnumerator = value.EnumerateObject();
enumerator = objectEnumerator.GetEnumerator();
try {
while (enumerator.MoveNext()) {
JsonProperty current2 = enumerator.Current;
ReadPropertyValue(encryptionAgent, current2);
}
} finally {
((IDisposable)enumerator).Dispose();
}
data.EncryptionAgent = encryptionAgent;
} else if (property.Name.Equals("ContentEncryptionIV", StringComparison.InvariantCultureIgnoreCase)) {
value = property.Value;
data.ContentEncryptionIV = Convert.FromBase64String(value.GetString());
} else if (property.Name.Equals("KeyWrappingMetadata", StringComparison.InvariantCultureIgnoreCase)) {
Dictionary<string, string> dictionary = new Dictionary<string, string>();
value = property.Value;
objectEnumerator = value.EnumerateObject();
enumerator = objectEnumerator.GetEnumerator();
try {
while (enumerator.MoveNext()) {
JsonProperty current3 = enumerator.Current;
Dictionary<string, string> dictionary2 = dictionary;
string name = current3.Name;
value = current3.Value;
dictionary2.Add(name, value.GetString());
}
} finally {
((IDisposable)enumerator).Dispose();
}
data.KeyWrappingMetadata = dictionary;
} else if (property.Name.Equals("EncryptedRegionInfo", StringComparison.InvariantCultureIgnoreCase)) {
EncryptedRegionInfo encryptedRegionInfo = new EncryptedRegionInfo();
value = property.Value;
objectEnumerator = value.EnumerateObject();
enumerator = objectEnumerator.GetEnumerator();
try {
while (enumerator.MoveNext()) {
JsonProperty current4 = enumerator.Current;
ReadPropertyValue(encryptedRegionInfo, current4);
}
} finally {
((IDisposable)enumerator).Dispose();
}
data.EncryptedRegionInfo = encryptedRegionInfo;
}
}
private static void ReadPropertyValue(KeyEnvelope key, JsonProperty property)
{
JsonElement value;
if (property.Name.Equals("Algorithm", StringComparison.InvariantCultureIgnoreCase)) {
value = property.Value;
key.Algorithm = value.GetString();
} else if (property.Name.Equals("EncryptedKey", StringComparison.InvariantCultureIgnoreCase)) {
value = property.Value;
key.EncryptedKey = Convert.FromBase64String(value.GetString());
} else if (property.Name.Equals("KeyId", StringComparison.InvariantCultureIgnoreCase)) {
value = property.Value;
key.KeyId = value.GetString();
}
}
private static void ReadPropertyValue(EncryptionAgent agent, JsonProperty property)
{
JsonElement value;
if (property.Name.Equals("EncryptionAlgorithm", StringComparison.InvariantCultureIgnoreCase)) {
value = property.Value;
agent.EncryptionAlgorithm = new ClientSideEncryptionAlgorithm(value.GetString());
} else if (property.Name.Equals("Protocol", StringComparison.InvariantCultureIgnoreCase)) {
value = property.Value;
agent.EncryptionVersion = value.GetString().ToClientSideEncryptionVersion();
}
}
private static void ReadPropertyValue(EncryptedRegionInfo info, JsonProperty property)
{
JsonElement value;
if (property.Name.Equals("NonceLength", StringComparison.InvariantCultureIgnoreCase)) {
value = property.Value;
info.NonceLength = value.GetInt32();
} else if (property.Name.Equals("DataLength", StringComparison.InvariantCultureIgnoreCase)) {
value = property.Value;
info.DataLength = value.GetInt32();
}
}
}
}