aboutsummaryrefslogtreecommitdiff
path: root/back-end
diff options
context:
space:
mode:
authorLibravatar vnugent <public@vaughnnugent.com>2023-12-01 21:00:49 -0500
committerLibravatar vnugent <public@vaughnnugent.com>2023-12-01 21:00:49 -0500
commit54984ef915a3bf640e06015bd294bd2186b3a588 (patch)
tree51bc8384138a5eca389186f178fa5fd669cf3916 /back-end
parentc4205bfe23dc321c77e2ff032fcb355d16e5d6c0 (diff)
internal polish, minor refactors & manifest v3 progression
Diffstat (limited to 'back-end')
-rw-r--r--back-end/libs/NVault.Crypto.Secp256k1/src/ContextExtensions.cs91
-rw-r--r--back-end/libs/NVault.Crypto.Secp256k1/src/LibSecp256k1.cs63
-rw-r--r--back-end/libs/NVault.Crypto.Secp256k1/src/Secp256HashFuncState.cs56
-rw-r--r--back-end/libs/NVault.Crypto.Secp256k1/src/Secp256k1Context.cs10
-rw-r--r--back-end/libs/NVault.Crypto.Secp256k1/src/Secp256k1SecretKey.cs58
-rw-r--r--back-end/plugins/nvault/src/Endpoints/Endpoint.cs4
-rw-r--r--back-end/plugins/nvault/src/INostrCryptoProvider.cs19
-rw-r--r--back-end/plugins/nvault/src/NativeSecp256k1Library.cs4
-rw-r--r--back-end/plugins/nvault/src/NostrOpProvider.cs21
9 files changed, 223 insertions, 103 deletions
diff --git a/back-end/libs/NVault.Crypto.Secp256k1/src/ContextExtensions.cs b/back-end/libs/NVault.Crypto.Secp256k1/src/ContextExtensions.cs
index 9931698..556bba7 100644
--- a/back-end/libs/NVault.Crypto.Secp256k1/src/ContextExtensions.cs
+++ b/back-end/libs/NVault.Crypto.Secp256k1/src/ContextExtensions.cs
@@ -26,69 +26,16 @@ using static NVault.Crypto.Secp256k1.LibSecp256k1;
namespace NVault.Crypto.Secp256k1
{
+ /// <summary>
+ /// The callback function signature required for ECDH hash functions
+ /// </summary>
+ /// <param name="state">The callback state</param>
+ /// <returns>The return value to be passed as a result of the operation</returns>
public delegate int Secp256k1EcdhHashFunc(in Secp256HashFuncState state);
- [StructLayout(LayoutKind.Sequential)]
- public unsafe readonly ref struct Secp256HashFuncState
- {
-
- /// <summary>
- /// The opaque pointer passed to the hash function
- /// </summary>
- public readonly IntPtr Opaque { get; }
-
- private readonly byte* _output;
- private readonly byte* _xCoord;
- private readonly int _outputLength;
- private readonly int _xCoordLength;
-
- internal Secp256HashFuncState(byte* output, int outputLength, byte* xCoord, int xCoordLength, IntPtr opaque)
- {
- Opaque = opaque;
- _output = output;
- _outputLength = outputLength;
- _xCoord = xCoord;
- _xCoordLength = xCoordLength;
- }
-
- /// <summary>
- /// Gets the output buffer as a span
- /// </summary>
- /// <returns>The output buffer span</returns>
- public readonly Span<byte> GetOutput() => new(_output, _outputLength);
-
- /// <summary>
- /// Gets the x coordinate argument as a span
- /// </summary>
- /// <returns>The xcoordinate buffer span</returns>
- public readonly ReadOnlySpan<byte> GetXCoordArg() => new(_xCoord, _xCoordLength);
- }
-
public static unsafe class ContextExtensions
{
/// <summary>
- /// Creates a new <see cref="Secp256k1Context"/> from the current managed library
- /// </summary>
- /// <param name="Lib"></param>
- /// <returns>The new <see cref="Secp256k1Context"/> object from the library</returns>
- /// <exception cref="CryptographicException"></exception>
- public static Secp256k1Context CreateContext(this LibSecp256k1 Lib)
- {
- //Protect for released lib
- Lib.SafeLibHandle.ThrowIfClosed();
-
- //Create new context
- IntPtr context = Lib._create(1);
-
- if (context == IntPtr.Zero)
- {
- throw new CryptographicException("Failed to create the new Secp256k1 context");
- }
-
- return new Secp256k1Context(Lib, context);
- }
-
- /// <summary>
/// Signs a 32byte message digest with the specified secret key on the current context and writes the signature to the specified buffer
/// </summary>
/// <param name="context"></param>
@@ -108,13 +55,22 @@ namespace NVault.Crypto.Secp256k1
if (digest.Length != (int)HashAlg.SHA256)
{
return ERRNO.E_FAIL;
- }
+ }
+
+ //Secret key size must be exactly the size of the secret key struct
+ if(secretKey.Length != sizeof(Secp256k1SecretKey))
+ {
+ return ERRNO.E_FAIL;
+ }
//Stack allocated keypair
KeyPair keyPair = new();
+ //Init the secret key struct from key data
+ Secp256k1SecretKey secKeyStruct = MemoryMarshal.Read<Secp256k1SecretKey>(secretKey);
+
//Randomize the context and create the keypair
- if (!context.CreateKeyPair(&keyPair, secretKey))
+ if (!context.CreateKeyPair(&keyPair, &secKeyStruct))
{
return ERRNO.E_FAIL;
}
@@ -161,9 +117,9 @@ namespace NVault.Crypto.Secp256k1
/// <exception cref="CryptographicException"></exception>
public static ERRNO GeneratePubKeyFromSecret(this in Secp256k1Context context, ReadOnlySpan<byte> secretKey, Span<byte> pubKeyBuffer)
{
- if (secretKey.Length != SecretKeySize)
+ if (secretKey.Length != sizeof(Secp256k1SecretKey))
{
- throw new CryptographicException($"Your secret key must be exactly {SecretKeySize} bytes long");
+ throw new CryptographicException($"Your secret key must be exactly {sizeof(Secp256k1SecretKey)} bytes long");
}
if (pubKeyBuffer.Length < XOnlyPublicKeySize)
@@ -176,12 +132,13 @@ namespace NVault.Crypto.Secp256k1
//Stack allocated keypair and x-only public key
Secp256k1PublicKey xOnlyPubKey = new();
+ Secp256k1SecretKey secKeyStruct = MemoryMarshal.Read<Secp256k1SecretKey>(secretKey);
KeyPair keyPair = new();
try
{
//Init context and keypair
- if (!context.CreateKeyPair(&keyPair, secretKey))
+ if (!context.CreateKeyPair(&keyPair, &secKeyStruct))
{
return ERRNO.E_FAIL;
}
@@ -220,9 +177,9 @@ namespace NVault.Crypto.Secp256k1
/// <exception cref="CryptographicException"></exception>
public static bool VerifySecretKey(this in Secp256k1Context context, ReadOnlySpan<byte> secretKey)
{
- if (secretKey.Length != SecretKeySize)
+ if (secretKey.Length != sizeof(Secp256k1SecretKey))
{
- throw new CryptographicException($"Your secret key must be exactly {SecretKeySize} bytes long");
+ throw new CryptographicException($"Your secret key must be exactly {sizeof(Secp256k1SecretKey)} bytes long");
}
context.Lib.SafeLibHandle.ThrowIfClosed();
@@ -252,9 +209,9 @@ namespace NVault.Crypto.Secp256k1
/// <exception cref="ArgumentException"></exception>
public static bool ComputeSharedKey(this in Secp256k1Context context, Span<byte> data, ReadOnlySpan<byte> xOnlyPubKey, ReadOnlySpan<byte> secretKey, Secp256k1EcdhHashFunc callback, IntPtr opaque)
{
- if (secretKey.Length != SecretKeySize)
+ if (secretKey.Length != sizeof(Secp256k1SecretKey))
{
- throw new ArgumentException($"Your secret key buffer must be exactly {SecretKeySize} bytes long");
+ throw new ArgumentException($"Your secret key buffer must be exactly {sizeof(Secp256k1SecretKey)} bytes long");
}
//Init callback state struct
diff --git a/back-end/libs/NVault.Crypto.Secp256k1/src/LibSecp256k1.cs b/back-end/libs/NVault.Crypto.Secp256k1/src/LibSecp256k1.cs
index f3afc33..907eaa4 100644
--- a/back-end/libs/NVault.Crypto.Secp256k1/src/LibSecp256k1.cs
+++ b/back-end/libs/NVault.Crypto.Secp256k1/src/LibSecp256k1.cs
@@ -23,16 +23,17 @@ using VNLib.Utils.Extensions;
namespace NVault.Crypto.Secp256k1
{
-
+
internal unsafe delegate int EcdhHasFunc(byte* output, byte* x32, byte* y32, void* data);
public unsafe class LibSecp256k1 : VnDisposeable
{
- public const int SecretKeySize = 32;
public const int SignatureSize = 64;
public const int RandomBufferSize = 32;
public const int XOnlyPublicKeySize = 32;
+ public static readonly int SecretKeySize = sizeof(Secp256k1SecretKey);
+
/*
* Unsafe structures that represent the native keypair and x-only public key
* structures. They hold character arrays
@@ -51,15 +52,14 @@ namespace NVault.Crypto.Secp256k1
{
public fixed byte data[64];
}
-
//Native methods
[SafeMethodName("secp256k1_context_create")]
- internal delegate IntPtr CreateContext(int flags);
+ internal delegate IntPtr ContextCreate(int flags);
[SafeMethodName("secp256k1_context_destroy")]
- internal delegate void DestroyContext(IntPtr context);
+ internal delegate void ContextDestroy(IntPtr context);
[SafeMethodName("secp256k1_context_randomize")]
internal delegate int RandomizeContext(IntPtr context, byte* seed32);
@@ -94,7 +94,6 @@ namespace NVault.Crypto.Secp256k1
EcdhHasFunc hashFunc,
void* dataPtr
);
-
/// <summary>
@@ -132,14 +131,32 @@ namespace NVault.Crypto.Secp256k1
}
/// <summary>
+ /// Loads the Secp256k1 library from the specified path and creates a wrapper class (loads methods from the library)
+ /// </summary>
+ /// <param name="handle">The handle to the shared library</param>
+ /// <param name="random">An optional random source to create random entropy and secrets from</param>
+ /// <returns>The <see cref="LibSecp256k1"/> library wrapper class</returns>
+ /// <exception cref="ArgumentNullException"></exception>
+ /// <exception cref="MissingMemberException"></exception>
+ /// <exception cref="EntryPointNotFoundException"></exception>
+ public static LibSecp256k1 FromHandle(SafeLibraryHandle handle, IRandomSource? random)
+ {
+ _ = handle ?? throw new ArgumentNullException(nameof(handle));
+ //setup fallback random source if null
+ random ??= new FallbackRandom();
+ //Create the lib
+ return new LibSecp256k1(handle, random);
+ }
+
+ /// <summary>
/// The underlying library handle
/// </summary>
public SafeLibraryHandle SafeLibHandle { get; }
internal readonly KeypairCreate _createKeyPair;
- internal readonly CreateContext _create;
+ internal readonly ContextCreate _create;
internal readonly RandomizeContext _randomize;
- internal readonly DestroyContext _destroy;
+ internal readonly ContextDestroy _destroy;
internal readonly KeypairXOnlyPub _createXonly;
internal readonly XOnlyPubkeySerialize _serializeXonly;
internal readonly SignHash _signHash;
@@ -165,10 +182,10 @@ namespace NVault.Crypto.Secp256k1
SafeLibHandle = handle ?? throw new ArgumentNullException(nameof(handle));
//Get all method handles and store them
- _create = handle.DangerousGetMethod<CreateContext>();
+ _create = handle.DangerousGetMethod<ContextCreate>();
_createKeyPair = handle.DangerousGetMethod<KeypairCreate>();
_randomize = handle.DangerousGetMethod<RandomizeContext>();
- _destroy = handle.DangerousGetMethod<DestroyContext>();
+ _destroy = handle.DangerousGetMethod<ContextDestroy>();
_createXonly = handle.DangerousGetMethod<KeypairXOnlyPub>();
_serializeXonly = handle.DangerousGetMethod<XOnlyPubkeySerialize>();
_signHash = handle.DangerousGetMethod<SignHash>();
@@ -205,9 +222,9 @@ namespace NVault.Crypto.Secp256k1
//Protect for released lib
SafeLibHandle.ThrowIfClosed();
- if(buffer.Length != SecretKeySize)
+ if(buffer.Length != sizeof(Secp256k1SecretKey))
{
- throw new ArgumentException($"Buffer must be exactly {SecretKeySize} bytes long", nameof(buffer));
+ throw new ArgumentException($"Buffer must be exactly {sizeof(Secp256k1SecretKey)} bytes long", nameof(buffer));
}
//Fill the buffer with random bytes
@@ -227,6 +244,28 @@ namespace NVault.Crypto.Secp256k1
_randomSource.GetRandomBytes(buffer);
}
+ /// <summary>
+ /// Creates a new <see cref="Secp256k1Context"/> from the current managed library
+ /// </summary>
+ /// <param name="Lib"></param>
+ /// <returns>The new <see cref="Secp256k1Context"/> object from the library</returns>
+ /// <exception cref="OutOfMemoryException"></exception>
+ public Secp256k1Context CreateContext()
+ {
+ //Protect for released lib
+ SafeLibHandle.ThrowIfClosed();
+
+ //Create new context
+ IntPtr context = _create(1);
+
+ if (context == IntPtr.Zero)
+ {
+ throw new OutOfMemoryException("Failed to create the new Secp256k1 context");
+ }
+
+ return new Secp256k1Context(this, context);
+ }
+
protected override void Free()
{
//Free native library
diff --git a/back-end/libs/NVault.Crypto.Secp256k1/src/Secp256HashFuncState.cs b/back-end/libs/NVault.Crypto.Secp256k1/src/Secp256HashFuncState.cs
new file mode 100644
index 0000000..4ee745c
--- /dev/null
+++ b/back-end/libs/NVault.Crypto.Secp256k1/src/Secp256HashFuncState.cs
@@ -0,0 +1,56 @@
+// Copyright (C) 2023 Vaughn Nugent
+//
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero General Public License as
+// published by the Free Software Foundation, either version 3 of the
+// License, or (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU Affero General Public License for more details.
+//
+// You should have received a copy of the GNU Affero General Public License
+// along with this program. If not, see <https://www.gnu.org/licenses/>.
+
+using System;
+using System.Runtime.InteropServices;
+
+namespace NVault.Crypto.Secp256k1
+{
+ [StructLayout(LayoutKind.Sequential)]
+ public unsafe readonly ref struct Secp256HashFuncState
+ {
+
+ /// <summary>
+ /// The opaque pointer passed to the hash function
+ /// </summary>
+ public readonly IntPtr Opaque { get; }
+
+ private readonly byte* _output;
+ private readonly byte* _xCoord;
+ private readonly int _outputLength;
+ private readonly int _xCoordLength;
+
+ internal Secp256HashFuncState(byte* output, int outputLength, byte* xCoord, int xCoordLength, IntPtr opaque)
+ {
+ Opaque = opaque;
+ _output = output;
+ _outputLength = outputLength;
+ _xCoord = xCoord;
+ _xCoordLength = xCoordLength;
+ }
+
+ /// <summary>
+ /// Gets the output buffer as a span
+ /// </summary>
+ /// <returns>The output buffer span</returns>
+ public readonly Span<byte> GetOutput() => new(_output, _outputLength);
+
+ /// <summary>
+ /// Gets the x coordinate argument as a span
+ /// </summary>
+ /// <returns>The xcoordinate buffer span</returns>
+ public readonly ReadOnlySpan<byte> GetXCoordArg() => new(_xCoord, _xCoordLength);
+ }
+} \ No newline at end of file
diff --git a/back-end/libs/NVault.Crypto.Secp256k1/src/Secp256k1Context.cs b/back-end/libs/NVault.Crypto.Secp256k1/src/Secp256k1Context.cs
index 67f1d9f..f0a795a 100644
--- a/back-end/libs/NVault.Crypto.Secp256k1/src/Secp256k1Context.cs
+++ b/back-end/libs/NVault.Crypto.Secp256k1/src/Secp256k1Context.cs
@@ -14,7 +14,6 @@
// along with this program. If not, see <https://www.gnu.org/licenses/>.
using System;
-using System.Runtime.InteropServices;
using VNLib.Utils.Extensions;
using VNLib.Utils.Memory;
@@ -54,15 +53,12 @@ namespace NVault.Crypto.Secp256k1
return result;
}
- internal unsafe readonly bool CreateKeyPair(KeyPair* keyPair, ReadOnlySpan<byte> secretKey)
+ internal unsafe readonly bool CreateKeyPair(KeyPair* keyPair, Secp256k1SecretKey* secretKey)
{
Lib.SafeLibHandle.ThrowIfClosed();
- fixed (byte* sk = &MemoryMarshal.GetReference(secretKey))
- {
- //Create the keypair from the secret key
- return Lib._createKeyPair(Context, keyPair, sk) == 1;
- }
+ //Create the keypair from the secret key
+ return Lib._createKeyPair(Context, keyPair, (byte*)secretKey) == 1;
}
/// <summary>
diff --git a/back-end/libs/NVault.Crypto.Secp256k1/src/Secp256k1SecretKey.cs b/back-end/libs/NVault.Crypto.Secp256k1/src/Secp256k1SecretKey.cs
new file mode 100644
index 0000000..7224720
--- /dev/null
+++ b/back-end/libs/NVault.Crypto.Secp256k1/src/Secp256k1SecretKey.cs
@@ -0,0 +1,58 @@
+// Copyright (C) 2023 Vaughn Nugent
+//
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero General Public License as
+// published by the Free Software Foundation, either version 3 of the
+// License, or (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU Affero General Public License for more details.
+//
+// You should have received a copy of the GNU Affero General Public License
+// along with this program. If not, see <https://www.gnu.org/licenses/>.
+
+using System;
+using System.Runtime.InteropServices;
+
+using VNLib.Utils.Memory;
+
+namespace NVault.Crypto.Secp256k1
+{
+ /// <summary>
+ /// Represents a Secp256k1 secret key, the size is fixed, and should use
+ /// the sizeof() operator to get the size
+ /// </summary>
+ [StructLayout(LayoutKind.Sequential, Size = 32)]
+ public unsafe struct Secp256k1SecretKey
+ {
+ private fixed byte data[32];
+
+ /// <summary>
+ /// Implict cast to a span of raw bytes
+ /// </summary>
+ /// <param name="key">The secret key to cast</param>
+ public static implicit operator Span<byte>(Secp256k1SecretKey key) => new(key.data, 32);
+
+ /// <summary>
+ /// Casts the secret key span to a <see cref="Secp256k1SecretKey"/> via a structure copy
+ /// </summary>
+ /// <param name="key">The key data to copy</param>
+ /// <exception cref="ArgumentOutOfRangeException"></exception>
+ public static explicit operator Secp256k1SecretKey(ReadOnlySpan<byte> key) => FromSpan(key);
+
+ /// <summary>
+ /// Creates a new <see cref="Secp256k1SecretKey"/> from a span of bytes
+ /// by copying the bytes into the struct
+ /// </summary>
+ /// <param name="span">The secret key data to copy</param>
+ /// <returns>An initilaized <see cref="Secp256k1SecretKey"/></returns>
+ public static Secp256k1SecretKey FromSpan(ReadOnlySpan<byte> span)
+ {
+ Secp256k1SecretKey newKey = new();
+ MemoryUtil.CopyStruct(span, ref newKey);
+ return newKey;
+ }
+ }
+} \ No newline at end of file
diff --git a/back-end/plugins/nvault/src/Endpoints/Endpoint.cs b/back-end/plugins/nvault/src/Endpoints/Endpoint.cs
index bcebc63..4223a10 100644
--- a/back-end/plugins/nvault/src/Endpoints/Endpoint.cs
+++ b/back-end/plugins/nvault/src/Endpoints/Endpoint.cs
@@ -134,7 +134,7 @@ namespace NVault.Plugins.Vault.Endpoints
//Get the key metadata
NostrKeyMeta? keyMeta = await _publicKeyStore.GetSingleUserRecordAsync(nEvent.KeyId, entity.Session.UserID);
- if(webm.Assert(keyMeta != null, "Key not found"))
+ if(webm.Assert(keyMeta?.Value != null, "Key not found"))
{
return VirtualClose(entity, webm, HttpStatusCode.NotFound);
}
@@ -520,7 +520,7 @@ namespace NVault.Plugins.Vault.Endpoints
.Must(ct => ct.Contains("?iv=", StringComparison.OrdinalIgnoreCase))
.WithMessage("iv not found in ciphertext")
//Check iv is not too long
- .Must(ct => ct.AsSpan().SliceAfterParam("?iv=").Length == NostrOpProvider.MaxBase64EncodedSize)
+ .Must(ct => ct.AsSpan().SliceAfterParam("?iv=").Length == NostrOpProvider.IvMaxBase64EncodedSize)
.WithMessage("iv is not the correct size");
//Pubpkey must be 64 hex characters
diff --git a/back-end/plugins/nvault/src/INostrCryptoProvider.cs b/back-end/plugins/nvault/src/INostrCryptoProvider.cs
index d6c1e8a..b66757c 100644
--- a/back-end/plugins/nvault/src/INostrCryptoProvider.cs
+++ b/back-end/plugins/nvault/src/INostrCryptoProvider.cs
@@ -61,8 +61,27 @@ namespace NVault.Plugins.Vault
/// <returns>True if the operation succeeded, false otherwise</returns>
bool RecoverPublicKey(ReadOnlySpan<byte> privateKey, Span<byte> pubKey);
+ /// <summary>
+ /// Decrypts a Nostr encrypted message by the target's public key, and the local secret key.
+ /// Both keys will be used to compute the shared secret that will be used to decrypt the message.
+ /// </summary>
+ /// <param name="secretKey">The local secret key</param>
+ /// <param name="targetKey">The message's target public key for the shared secret</param>
+ /// <param name="aseIv">The initialization vector used to encrypt the message</param>
+ /// <param name="cyphterText">The cyphertext to decrypt</param>
+ /// <param name="outputBuffer">The output buffer to write plaintext data to</param>
+ /// <returns>The number of bytes written to the output, 0 or negative for an error</returns>
ERRNO DecryptMessage(ReadOnlySpan<byte> secretKey, ReadOnlySpan<byte> targetKey, ReadOnlySpan<byte> aseIv, ReadOnlySpan<byte> cyphterText, Span<byte> outputBuffer);
+ /// <summary>
+ /// Encrypts a message with the specified secret key, target public key, and initialization vector.
+ /// </summary>
+ /// <param name="secretKey"></param>
+ /// <param name="targetKey"></param>
+ /// <param name="aesIv">The initalization vector used by the AES cipher to encrypt data</param>
+ /// <param name="plainText">The plaintext data to encrypt</param>
+ /// <param name="cipherText">The ciphertext output buffer</param>
+ /// <returns>The number of bytes written to the output buffer, 0 or negative on error</returns>
ERRNO EncryptMessage(ReadOnlySpan<byte> secretKey, ReadOnlySpan<byte> targetKey, ReadOnlySpan<byte> aesIv, ReadOnlySpan<byte> plainText, Span<byte> cipherText);
/// <summary>
diff --git a/back-end/plugins/nvault/src/NativeSecp256k1Library.cs b/back-end/plugins/nvault/src/NativeSecp256k1Library.cs
index 0870156..2fcf447 100644
--- a/back-end/plugins/nvault/src/NativeSecp256k1Library.cs
+++ b/back-end/plugins/nvault/src/NativeSecp256k1Library.cs
@@ -76,7 +76,7 @@ namespace NVault.Plugins.Vault
finally
{
//Zero out buffers
- MemoryUtil.InitializeBlock(sharedKeyBuffer.AsSpan());
+ MemoryUtil.InitializeBlock(sharedKeyBuffer);
}
}
@@ -114,7 +114,7 @@ namespace NVault.Plugins.Vault
finally
{
//Zero out buffers
- MemoryUtil.InitializeBlock(sharedKeyBuffer.AsSpan());
+ MemoryUtil.InitializeBlock(sharedKeyBuffer);
}
}
diff --git a/back-end/plugins/nvault/src/NostrOpProvider.cs b/back-end/plugins/nvault/src/NostrOpProvider.cs
index aa4840e..5908e26 100644
--- a/back-end/plugins/nvault/src/NostrOpProvider.cs
+++ b/back-end/plugins/nvault/src/NostrOpProvider.cs
@@ -39,7 +39,7 @@ namespace NVault.Plugins.Vault
internal sealed class NostrOpProvider : INostrOperations
{
public const int AES_IV_SIZE = 16;
- public static int MaxBase64EncodedSize { get; } = Base64.GetMaxEncodedToUtf8Length(AES_IV_SIZE);
+ public static int IvMaxBase64EncodedSize { get; } = Base64.GetMaxEncodedToUtf8Length(AES_IV_SIZE);
private static JavaScriptEncoder _encoder { get; } = GetJsEncoder();
@@ -289,9 +289,7 @@ namespace NVault.Plugins.Vault
string? outText = null, ivText = null;
//Call decipher method
- bool result = Nip04Cipher(secret.ToReadOnlySpan(), nip04Ciphertext.AsSpan(), targetPubkey, ref outText, ref ivText, false);
-
- if (result)
+ if (Nip04Cipher(secret.ToReadOnlySpan(), nip04Ciphertext.AsSpan(), targetPubkey, ref outText, ref ivText, false))
{
return outText;
}
@@ -307,16 +305,13 @@ namespace NVault.Plugins.Vault
//Recover target public key
byte[] targetPubkey = Convert.FromHexString(targetPubKeyHex);
- //Get key data from the vault
- using PrivateString? secret = await _vault.GetSecretAsync(scope, keyMeta.Id, cancellation);
+ //Get key data from the vault (key should always exist, but may get out of sync if manually deleted)
+ using PrivateString? secret = await _vault.GetSecretAsync(scope, keyMeta.Id, cancellation) ?? throw new ArgumentException("Secret key not found in vault");
- string? outputText = null,
- ivText = null;
-
- //Call decipher method
- bool result = Nip04Cipher(secret.ToReadOnlySpan(), plainText, targetPubkey, ref outputText, ref ivText, true);
+ string? outputText = null, ivText = null;
- if (result)
+ //Call encipher method
+ if (Nip04Cipher(secret.ToReadOnlySpan(), plainText, targetPubkey, ref outputText, ref ivText, true))
{
return new()
{
@@ -391,7 +386,7 @@ namespace NVault.Plugins.Vault
ReadOnlySpan<char> cipherText = text.SliceBeforeParam("?iv=");
ReadOnlySpan<char> ivSegment = text.SliceAfterParam("?iv=");
- if (ivSegment.Length > MaxBase64EncodedSize)
+ if (ivSegment.Length > IvMaxBase64EncodedSize)
{
throw new ArgumentException("initialization vector is larger than allowed");
}