@@ -5,32 +5,149 @@ namespace PSModule
55{
66 public static class Sodium
77 {
8- [ DllImport ( "libsodium" , CallingConvention = CallingConvention . Cdecl ) ]
9- public static extern int sodium_init ( ) ;
8+ private static class Native
9+ {
10+ [ DllImport ( "libsodium" , CallingConvention = CallingConvention . Cdecl ) ]
11+ [ DefaultDllImportSearchPaths ( DllImportSearchPath . AssemblyDirectory | DllImportSearchPath . SafeDirectories ) ]
12+ public static extern int sodium_init ( ) ;
1013
11- [ DllImport ( "libsodium" , CallingConvention = CallingConvention . Cdecl ) ]
12- public static extern int crypto_box_keypair ( byte [ ] publicKey , byte [ ] privateKey ) ;
14+ [ DllImport ( "libsodium" , CallingConvention = CallingConvention . Cdecl ) ]
15+ [ DefaultDllImportSearchPaths ( DllImportSearchPath . AssemblyDirectory | DllImportSearchPath . SafeDirectories ) ]
16+ public static extern int crypto_box_keypair ( byte [ ] publicKey , byte [ ] privateKey ) ;
1317
14- [ DllImport ( "libsodium" , CallingConvention = CallingConvention . Cdecl ) ]
15- public static extern int crypto_box_seed_keypair ( byte [ ] publicKey , byte [ ] privateKey , byte [ ] seed ) ;
18+ [ DllImport ( "libsodium" , CallingConvention = CallingConvention . Cdecl ) ]
19+ [ DefaultDllImportSearchPaths ( DllImportSearchPath . AssemblyDirectory | DllImportSearchPath . SafeDirectories ) ]
20+ public static extern int crypto_box_seed_keypair ( byte [ ] publicKey , byte [ ] privateKey , byte [ ] seed ) ;
1621
17- [ DllImport ( "libsodium" , CallingConvention = CallingConvention . Cdecl ) ]
18- public static extern int crypto_box_seal ( byte [ ] ciphertext , byte [ ] message , ulong mlen , byte [ ] publicKey ) ;
22+ [ DllImport ( "libsodium" , CallingConvention = CallingConvention . Cdecl ) ]
23+ [ DefaultDllImportSearchPaths ( DllImportSearchPath . AssemblyDirectory | DllImportSearchPath . SafeDirectories ) ]
24+ public static extern int crypto_box_seal ( byte [ ] ciphertext , byte [ ] message , ulong mlen , byte [ ] publicKey ) ;
1925
20- [ DllImport ( "libsodium" , CallingConvention = CallingConvention . Cdecl ) ]
21- public static extern int crypto_box_seal_open ( byte [ ] decrypted , byte [ ] ciphertext , ulong clen , byte [ ] publicKey , byte [ ] privateKey ) ;
26+ [ DllImport ( "libsodium" , CallingConvention = CallingConvention . Cdecl ) ]
27+ [ DefaultDllImportSearchPaths ( DllImportSearchPath . AssemblyDirectory | DllImportSearchPath . SafeDirectories ) ]
28+ public static extern int crypto_box_seal_open ( byte [ ] decrypted , byte [ ] ciphertext , ulong clen , byte [ ] publicKey , byte [ ] privateKey ) ;
2229
23- [ DllImport ( "libsodium" , CallingConvention = CallingConvention . Cdecl ) ]
24- public static extern UIntPtr crypto_box_publickeybytes ( ) ;
30+ [ DllImport ( "libsodium" , CallingConvention = CallingConvention . Cdecl ) ]
31+ [ DefaultDllImportSearchPaths ( DllImportSearchPath . AssemblyDirectory | DllImportSearchPath . SafeDirectories ) ]
32+ public static extern UIntPtr crypto_box_publickeybytes ( ) ;
2533
26- [ DllImport ( "libsodium" , CallingConvention = CallingConvention . Cdecl ) ]
27- public static extern UIntPtr crypto_box_secretkeybytes ( ) ;
34+ [ DllImport ( "libsodium" , CallingConvention = CallingConvention . Cdecl ) ]
35+ [ DefaultDllImportSearchPaths ( DllImportSearchPath . AssemblyDirectory | DllImportSearchPath . SafeDirectories ) ]
36+ public static extern UIntPtr crypto_box_secretkeybytes ( ) ;
2837
29- [ DllImport ( "libsodium" , CallingConvention = CallingConvention . Cdecl ) ]
30- public static extern UIntPtr crypto_box_sealbytes ( ) ;
38+ [ DllImport ( "libsodium" , CallingConvention = CallingConvention . Cdecl ) ]
39+ [ DefaultDllImportSearchPaths ( DllImportSearchPath . AssemblyDirectory | DllImportSearchPath . SafeDirectories ) ]
40+ public static extern UIntPtr crypto_box_sealbytes ( ) ;
3141
32- [ DllImport ( "libsodium" , CallingConvention = CallingConvention . Cdecl ) ]
33- public static extern int crypto_scalarmult_base ( byte [ ] publicKey , byte [ ] privateKey ) ;
42+ [ DllImport ( "libsodium" , CallingConvention = CallingConvention . Cdecl ) ]
43+ [ DefaultDllImportSearchPaths ( DllImportSearchPath . AssemblyDirectory | DllImportSearchPath . SafeDirectories ) ]
44+ public static extern int crypto_scalarmult_base ( byte [ ] publicKey , byte [ ] privateKey ) ;
45+ }
3446
47+ public static int sodium_init ( )
48+ {
49+ return Native . sodium_init ( ) ;
50+ }
51+
52+ public static int crypto_box_keypair ( byte [ ] publicKey , byte [ ] privateKey )
53+ {
54+ ValidateMinimumBufferLength ( publicKey , GetRequiredLength ( crypto_box_publickeybytes ( ) ) , nameof ( publicKey ) ) ;
55+ ValidateMinimumBufferLength ( privateKey , GetRequiredLength ( crypto_box_secretkeybytes ( ) ) , nameof ( privateKey ) ) ;
56+
57+ return Native . crypto_box_keypair ( publicKey , privateKey ) ;
58+ }
59+
60+ public static int crypto_box_seed_keypair ( byte [ ] publicKey , byte [ ] privateKey , byte [ ] seed )
61+ {
62+ ValidateMinimumBufferLength ( publicKey , GetRequiredLength ( crypto_box_publickeybytes ( ) ) , nameof ( publicKey ) ) ;
63+ ValidateMinimumBufferLength ( privateKey , GetRequiredLength ( crypto_box_secretkeybytes ( ) ) , nameof ( privateKey ) ) ;
64+ ValidateExactBufferLength ( seed , GetRequiredLength ( crypto_box_secretkeybytes ( ) ) , nameof ( seed ) ) ;
65+
66+ return Native . crypto_box_seed_keypair ( publicKey , privateKey , seed ) ;
67+ }
68+
69+ public static int crypto_box_seal ( byte [ ] ciphertext , byte [ ] message , ulong mlen , byte [ ] publicKey )
70+ {
71+ ValidateMinimumBufferLength ( message , mlen , nameof ( message ) ) ;
72+ ValidateMinimumBufferLength ( ciphertext , checked ( mlen + crypto_box_sealbytes ( ) . ToUInt64 ( ) ) , nameof ( ciphertext ) ) ;
73+ ValidateExactBufferLength ( publicKey , GetRequiredLength ( crypto_box_publickeybytes ( ) ) , nameof ( publicKey ) ) ;
74+
75+ return Native . crypto_box_seal ( ciphertext , message , mlen , publicKey ) ;
76+ }
77+
78+ public static int crypto_box_seal_open ( byte [ ] decrypted , byte [ ] ciphertext , ulong clen , byte [ ] publicKey , byte [ ] privateKey )
79+ {
80+ var sealBytes = crypto_box_sealbytes ( ) . ToUInt64 ( ) ;
81+ if ( clen < sealBytes )
82+ {
83+ throw new ArgumentException ( $ "The ciphertext must be at least { sealBytes } bytes.", nameof ( ciphertext ) ) ;
84+ }
85+
86+ ValidateMinimumBufferLength ( ciphertext , clen , nameof ( ciphertext ) ) ;
87+ ValidateMinimumBufferLength ( decrypted , clen - sealBytes , nameof ( decrypted ) ) ;
88+ ValidateExactBufferLength ( publicKey , GetRequiredLength ( crypto_box_publickeybytes ( ) ) , nameof ( publicKey ) ) ;
89+ ValidateExactBufferLength ( privateKey , GetRequiredLength ( crypto_box_secretkeybytes ( ) ) , nameof ( privateKey ) ) ;
90+
91+ return Native . crypto_box_seal_open ( decrypted , ciphertext , clen , publicKey , privateKey ) ;
92+ }
93+
94+ public static UIntPtr crypto_box_publickeybytes ( )
95+ {
96+ return Native . crypto_box_publickeybytes ( ) ;
97+ }
98+
99+ public static UIntPtr crypto_box_secretkeybytes ( )
100+ {
101+ return Native . crypto_box_secretkeybytes ( ) ;
102+ }
103+
104+ public static UIntPtr crypto_box_sealbytes ( )
105+ {
106+ return Native . crypto_box_sealbytes ( ) ;
107+ }
108+
109+ public static int crypto_scalarmult_base ( byte [ ] publicKey , byte [ ] privateKey )
110+ {
111+ ValidateMinimumBufferLength ( publicKey , GetRequiredLength ( crypto_box_publickeybytes ( ) ) , nameof ( publicKey ) ) ;
112+ ValidateExactBufferLength ( privateKey , GetRequiredLength ( crypto_box_secretkeybytes ( ) ) , nameof ( privateKey ) ) ;
113+
114+ return Native . crypto_scalarmult_base ( publicKey , privateKey ) ;
115+ }
116+
117+ private static int GetRequiredLength ( UIntPtr length )
118+ {
119+ var value = length . ToUInt64 ( ) ;
120+ if ( value > int . MaxValue )
121+ {
122+ throw new OverflowException ( "The Sodium buffer length exceeds the maximum supported array length." ) ;
123+ }
124+
125+ return ( int ) value ;
126+ }
127+
128+ private static void ValidateExactBufferLength ( byte [ ] buffer , int expectedLength , string parameterName )
129+ {
130+ ArgumentNullException . ThrowIfNull ( buffer , parameterName ) ;
131+
132+ if ( buffer . Length != expectedLength )
133+ {
134+ throw new ArgumentException ( $ "The buffer must be exactly { expectedLength } bytes.", parameterName ) ;
135+ }
136+ }
137+
138+ private static void ValidateMinimumBufferLength ( byte [ ] buffer , int minimumLength , string parameterName )
139+ {
140+ ValidateMinimumBufferLength ( buffer , ( ulong ) minimumLength , parameterName ) ;
141+ }
142+
143+ private static void ValidateMinimumBufferLength ( byte [ ] buffer , ulong minimumLength , string parameterName )
144+ {
145+ ArgumentNullException . ThrowIfNull ( buffer , parameterName ) ;
146+
147+ if ( ( ulong ) buffer . LongLength < minimumLength )
148+ {
149+ throw new ArgumentException ( $ "The buffer must be at least { minimumLength } bytes.", parameterName ) ;
150+ }
151+ }
35152 }
36153}
0 commit comments