New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
V1.Secrets.Transit.ReadEncryptionKeyAsync doesn't work for other than aes256-gcm96 key. #194
Comments
I'll have a look this weekend. |
You did 90% of the work already with a nice bug description and root cause @faddiv The response is pretty dynamic based on the type of key. So the value-datatype of the Dictionary cannot be long. It can be anything and hence I switched it to a Object. (so that it can deserialize primitive values as well as dictionaries etc.) |
Will publish a version in a couple of days. |
@faddiv This should have your fix. https://www.nuget.org/packages/VaultSharp/1.6.2.4 |
Thank you. It's working. |
Makes sense. Exposed both latest version and min version fields. Please use https://www.nuget.org/packages/VaultSharp/1.6.2.5 |
Describe the bug
V1.Secrets.Transit.ReadEncryptionKeyAsync doesn't work for other than aes256-gcm96 key.
VaultSharp Version
1.6.2.3
Vault Version
1.7.2
Does this work with Vault CLI?
Yes
Sample Code Snippet
public async Task<byte[]> GetEncryptionKey(string path)
{
var keyInfo = await _vaultClient.V1.Secrets.Transit.ReadEncryptionKeyAsync(path, mountPoint: "transit");
// ...
}
Exception Details/Stack Trace/Error Message
JsonSerializationException: Cannot deserialize the current JSON object (e.g. {"name":"value"}) into type 'System.Int64' because the type requires a JSON primitive value (e.g. string, number, boolean, null) to deserialize correctly. To fix this error either change the JSON to a JSON primitive value (e.g. string, number, boolean, null) or change the deserialized type so that it is a normal .NET type (e.g. not a primitive type like integer, not a collection type like an array or List) that can be deserialized from a JSON object. JsonObjectAttribute can also be added to the type to force it to deserialize from a JSON object. Path 'data.keys.1.creation_time', line 1, position 231.
Newtonsoft.Json.Serialization.JsonSerializerInternalReader.CreateObject(JsonReader reader, Type objectType, JsonContract contract, JsonProperty member, JsonContainerContract containerContract, JsonProperty containerMember, object existingValue)
Newtonsoft.Json.Serialization.JsonSerializerInternalReader.CreateValueInternal(JsonReader reader, Type objectType, JsonContract contract, JsonProperty member, JsonContainerContract containerContract, JsonProperty containerMember, object existingValue)
Newtonsoft.Json.Serialization.JsonSerializerInternalReader.PopulateDictionary(IDictionary dictionary, JsonReader reader, JsonDictionaryContract contract, JsonProperty containerProperty, string id)
Newtonsoft.Json.Serialization.JsonSerializerInternalReader.CreateObject(JsonReader reader, Type objectType, JsonContract contract, JsonProperty member, JsonContainerContract containerContract, JsonProperty containerMember, object existingValue)
Newtonsoft.Json.Serialization.JsonSerializerInternalReader.CreateValueInternal(JsonReader reader, Type objectType, JsonContract contract, JsonProperty member, JsonContainerContract containerContract, JsonProperty containerMember, object existingValue)
Newtonsoft.Json.Serialization.JsonSerializerInternalReader.SetPropertyValue(JsonProperty property, JsonConverter propertyConverter, JsonContainerContract containerContract, JsonProperty containerProperty, JsonReader reader, object target)
Newtonsoft.Json.Serialization.JsonSerializerInternalReader.PopulateObject(object newObject, JsonReader reader, JsonObjectContract contract, JsonProperty member, string id)
Newtonsoft.Json.Serialization.JsonSerializerInternalReader.CreateObject(JsonReader reader, Type objectType, JsonContract contract, JsonProperty member, JsonContainerContract containerContract, JsonProperty containerMember, object existingValue)
Newtonsoft.Json.Serialization.JsonSerializerInternalReader.CreateValueInternal(JsonReader reader, Type objectType, JsonContract contract, JsonProperty member, JsonContainerContract containerContract, JsonProperty containerMember, object existingValue)
Newtonsoft.Json.Serialization.JsonSerializerInternalReader.SetPropertyValue(JsonProperty property, JsonConverter propertyConverter, JsonContainerContract containerContract, JsonProperty containerProperty, JsonReader reader, object target)
Newtonsoft.Json.Serialization.JsonSerializerInternalReader.PopulateObject(object newObject, JsonReader reader, JsonObjectContract contract, JsonProperty member, string id)
Newtonsoft.Json.Serialization.JsonSerializerInternalReader.CreateObject(JsonReader reader, Type objectType, JsonContract contract, JsonProperty member, JsonContainerContract containerContract, JsonProperty containerMember, object existingValue)
Newtonsoft.Json.Serialization.JsonSerializerInternalReader.CreateValueInternal(JsonReader reader, Type objectType, JsonContract contract, JsonProperty member, JsonContainerContract containerContract, JsonProperty containerMember, object existingValue)
Newtonsoft.Json.Serialization.JsonSerializerInternalReader.Deserialize(JsonReader reader, Type objectType, bool checkAdditionalContent)
Newtonsoft.Json.JsonSerializer.DeserializeInternal(JsonReader reader, Type objectType)
Newtonsoft.Json.JsonSerializer.Deserialize(JsonReader reader, Type objectType)
Newtonsoft.Json.JsonConvert.DeserializeObject(string value, Type type, JsonSerializerSettings settings)
Newtonsoft.Json.JsonConvert.DeserializeObject(string value, JsonSerializerSettings settings)
Newtonsoft.Json.JsonConvert.DeserializeObject(string value)
VaultSharp.Core.Polymath.MakeRequestAsync(string resourcePath, HttpMethod httpMethod, object requestData, IDictionary<string, string> headers, bool rawResponse, Action postResponseAction)
VaultSharp.Core.Polymath.MakeVaultApiRequest(string resourcePath, HttpMethod httpMethod, object requestData, bool rawResponse, Action postResponseAction, string wrapTimeToLive, bool unauthenticated)
VaultSharp.Core.Polymath.MakeVaultApiRequest(string mountPoint, string path, HttpMethod httpMethod, object requestData, bool rawResponse, Action postResponseAction, string wrapTimeToLive, bool unauthenticated)
VaultSharp.V1.SecretsEngines.Transit.TransitSecretsEngineProvider.ReadEncryptionKeyAsync(string keyName, string mountPoint)
NewcomerKeyManagement.Services.HashiCorpVaultFacade.GetEncryptionKey(string path) in HashiCorpVaultFacade.cs
+
var keyInfo = await _vaultClient.V1.Secrets.Transit.ReadEncryptionKeyAsync(path, mountPoint: "transit");
NewcomerKeyManagement.Controllers.KeyProviderController.GetV2() in KeyProviderController.cs
+
var result2 = await _hashi.GetEncryptionKey("database_encryption_key");
lambda_method32(Closure , object )
Microsoft.AspNetCore.Mvc.Infrastructure.ActionMethodExecutor+TaskOfActionResultExecutor.Execute(IActionResultTypeMapper mapper, ObjectMethodExecutor executor, object controller, object[] arguments)
System.Threading.Tasks.ValueTask.get_Result()
System.Runtime.CompilerServices.ValueTaskAwaiter.GetResult()
Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.g__Awaited|12_0(ControllerActionInvoker invoker, ValueTask actionResultValueTask)
Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.g__Awaited|10_0(ControllerActionInvoker invoker, Task lastTask, State next, Scope scope, object state, bool isCompleted)
Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.Rethrow(ActionExecutedContextSealed context)
Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.Next(ref State next, ref Scope scope, ref object state, ref bool isCompleted)
Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.g__Awaited|13_0(ControllerActionInvoker invoker, Task lastTask, State next, Scope scope, object state, bool isCompleted)
Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.g__Awaited|24_0(ResourceInvoker invoker, Task lastTask, State next, Scope scope, object state, bool isCompleted)
Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.Rethrow(ResourceExecutedContextSealed context)
Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.Next(ref State next, ref Scope scope, ref object state, ref bool isCompleted)
Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.g__Awaited|19_0(ResourceInvoker invoker, Task lastTask, State next, Scope scope, object state, bool isCompleted)
Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.g__Awaited|17_0(ResourceInvoker invoker, Task task, IDisposable scope)
Microsoft.AspNetCore.Routing.EndpointMiddleware.g__AwaitRequestTask|6_0(Endpoint endpoint, Task requestTask, ILogger logger)
Microsoft.AspNetCore.Authorization.AuthorizationMiddleware.Invoke(HttpContext context)
Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddleware.Invoke(HttpContext context)
Any additional info
I use an rsa encryption key in the transit and as turns out it returns a slightly different response than it was described in the api documentation.
In the keys property there is a whole object instead of long number.
Here is an example:
{
"request_id": "ce091ea5-d5a8-de2a-9b23-ae46c7cfbf25",
"lease_id": "",
"renewable": false,
"lease_duration": 0,
"data": {
"allow_plaintext_backup": false,
"deletion_allowed": false,
"derived": false,
"exportable": false,
"keys": {
"1": {
"creation_time": "2021-06-10T14:36:45.189648723+02:00",
"name": "rsa-2048",
"public_key": "-----BEGIN PUBLIC KEY-----\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA8ZqGOG6CYms35FgR1QCA\nRd46zTZ7lV5e0BlXnWqag6p5S2TeX201o9HpUP1av/RZGw8APK6mR8LGZUcgn32b\neGSvEIe0hrEPplD+KOkBCd6jpZ0qkctfpFrd8NZoZ8hqw91k0Sxugg6aLr5htBsy\nZSd3velrihoGH0XJufnB+tzdeWIx+K78LFBW/TwFsWI5/Hzmf/FOyyZcsAmqNMNq\njZSyKHgTFE+qKNTODdzg3d+wrIdD2ox/Gm+0VSHf8r6C4jL+we72v/WT+cOEqUue\nBppWc+gHfJE0tYaDzLEhH74+O6msepoEwwpLCuBciNInr0wnn8v5FpViPdb8HNZh\nWwIDAQAB\n-----END PUBLIC KEY-----\n"
}
},
"latest_version": 1,
"min_available_version": 0,
"min_decryption_version": 1,
"min_encryption_version": 0,
"name": "t2",
"supports_decryption": true,
"supports_derivation": false,
"supports_encryption": true,
"supports_signing": true,
"type": "rsa-2048"
},
"wrap_info": null,
"warnings": null,
"auth": null
}
I would like to offer my help to fix this. (And explore all the possible response of this query.)
If I can help then I would like a guidenance about how should I modify the EncryptionKeyInfo class.
(The property in question: public Dictionary<string, long> Keys { get; set; } )
The text was updated successfully, but these errors were encountered: