diff --git a/dub.json b/dub.json index 5eff98a..a814341 100644 --- a/dub.json +++ b/dub.json @@ -2,7 +2,7 @@ "name": "ipcrypt2", "description": "IP address obfuscation library for D", "license": "MIT", - "version": "0.1.1", + "version": "0.1.2", "toolchainRequirements": { "frontend": "2.111.0" }, @@ -43,9 +43,7 @@ "/LIBPATH:$PACKAGE_DIR\\build" ], "dflags": [ - "-preview=dip1000", - "-preview=in", - "-preview=rvaluerefparam", + "-preview=all", "-P-I$PACKAGE_DIR/include" ], "dflags-ldc": [ diff --git a/examples/simple/dub.json b/examples/simple/dub.json index a4d1a4e..f729bfc 100644 --- a/examples/simple/dub.json +++ b/examples/simple/dub.json @@ -1,6 +1,6 @@ { "dependencies": { - "ipcrypt2": "~>0.1.1" + "ipcrypt2": "~>0.1.2" }, "description": "A minimal D application.", "license": "MIT", diff --git a/examples/simple/source/app.d b/examples/simple/source/app.d index 5bff875..e0094c6 100644 --- a/examples/simple/source/app.d +++ b/examples/simple/source/app.d @@ -1,11 +1,8 @@ -import std; +import std.stdio : printf = writef; import ipcrypt2 : IPCrypt2, IPCRYPT_KEYBYTES; -void main() +void main() @safe { - import core.stdc.stdio; - import core.stdc.string : strcmp; - // Test key ubyte[IPCRYPT_KEYBYTES] key = [ 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, @@ -22,12 +19,7 @@ void main() auto encrypted = crypt.encryptIPStr(original_ip); auto decrypted = crypt.decryptIPStr(encrypted); - // Verify results - assert(original_ip == decrypted, "Decryption failed to match original IP"); - assert(strcmp(&original_ip[0], &encrypted[0]) != 0, "Encryption produced identical output"); - - // Print results - printf("Original IP: %s\n", original_ip.toStringz); - printf("Encrypted IP: %s\n", encrypted.toStringz); - printf("Decrypted IP: %s\n", decrypted.toStringz); + printf("Original IP: %s\n", original_ip); + printf("Encrypted IP: %s\n", encrypted); + printf("Decrypted IP: %s\n", decrypted); } diff --git a/source/ipcrypt2/package.d b/source/ipcrypt2/package.d index e52d981..7eb6d05 100644 --- a/source/ipcrypt2/package.d +++ b/source/ipcrypt2/package.d @@ -40,7 +40,8 @@ SOFTWARE. module ipcrypt2; -public import c.ipcrypt2c; +/// IPCrypt2 C bindings +public import c.ipcrypt2c; // @system import core.stdc.string : strlen; import std.exception; @@ -58,23 +59,20 @@ struct IPCrypt2 * Constructs an IPCrypt2 with the given 16-byte key. * Throws: Exception if the key length is not 16 bytes. */ - this(scope const(ubyte)* key) nothrow @nogc + this(scope const(ubyte)* key) nothrow @nogc @trusted { ipcrypt_init(&context, &key[0]); } /// Ditto, but constructs from a hexadecimal key string. - this(string hexKey) + this(string hexKey) nothrow @nogc @trusted { ubyte[IPCRYPT_KEYBYTES] key; - // enforce(hexKey.length == 32, "Hexadecimal key must be 32 characters (16 bytes)"); - // enforce(ipcrypt_key_from_hex(&key[0], key.length, &hexKey[0], hexKey.length) == 0, - // "Invalid hexadecimal key format"); ipcrypt_init(&context, &key[0]); } /// Destructor ensures the IPCrypt context is cleaned up. - ~this() nothrow @nogc + ~this() nothrow @nogc @trusted { ipcrypt_deinit(&context); } @@ -88,7 +86,7 @@ struct IPCrypt2 * ip16 = The 16-byte IP address to encrypt. * Returns: The encrypted 16-byte IP address. */ - ubyte[IPCRYPT_KEYBYTES] encryptIP16(scope const(ubyte)* ip16) nothrow + ubyte[IPCRYPT_KEYBYTES] encryptIP16(scope const(ubyte)* ip16) nothrow @trusted { ubyte[IPCRYPT_KEYBYTES] result = ( cast(const(ubyte)[IPCRYPT_KEYBYTES]) ip16[0 .. IPCRYPT_KEYBYTES]).dup; @@ -102,7 +100,7 @@ struct IPCrypt2 * ip16 = The 16-byte encrypted IP address. * Returns: The decrypted 16-byte IP address. */ - ubyte[IPCRYPT_KEYBYTES] decryptIP16(scope const(ubyte)* ip16) nothrow + ubyte[IPCRYPT_KEYBYTES] decryptIP16(scope const(ubyte)* ip16) nothrow @trusted { ubyte[IPCRYPT_KEYBYTES] result = ( cast(const(ubyte)[IPCRYPT_KEYBYTES]) ip16[0 .. IPCRYPT_KEYBYTES]).dup; @@ -116,7 +114,7 @@ struct IPCrypt2 * ipStr = The IP address string to encrypt. * Returns: The encrypted IP address as a string. */ - string encryptIPStr(string ipStr) nothrow + string encryptIPStr(string ipStr) nothrow @trusted { char[IPCRYPT_MAX_IP_STR_BYTES] result; size_t len = ipcrypt_encrypt_ip_str(&context, &result[0], &ipStr[0]); @@ -129,7 +127,7 @@ struct IPCrypt2 * encryptedIPStr = The encrypted IP address string. * Returns: The decrypted IP address as a string. */ - string decryptIPStr(string encryptedIPStr) nothrow + string decryptIPStr(string encryptedIPStr) nothrow @trusted { char[IPCRYPT_MAX_IP_STR_BYTES] result; size_t len = ipcrypt_decrypt_ip_str(&context, &result[0], &encryptedIPStr[0]); @@ -143,7 +141,7 @@ struct IPCrypt2 * random = 8-byte random data for non-determinism. * Returns: The 24-byte encrypted IP address. */ - ubyte[24] ndEncryptIP16(scope const(ubyte)* ip16, scope const(ubyte)* random) nothrow @nogc + ubyte[24] ndEncryptIP16(scope const(ubyte)* ip16, scope const(ubyte)* random) nothrow @nogc @trusted { ubyte[24] result; ipcrypt_nd_encrypt_ip16(&context, &result[0], &ip16[0], &random[0]); @@ -156,7 +154,7 @@ struct IPCrypt2 * ndip = The 24-byte encrypted IP address. * Returns: The 16-byte decrypted IP address. */ - ubyte[IPCRYPT_KEYBYTES] ndDecryptIP16(scope const(ubyte)* ndip) nothrow @nogc + ubyte[IPCRYPT_KEYBYTES] ndDecryptIP16(scope const(ubyte)* ndip) nothrow @nogc @trusted { ubyte[IPCRYPT_KEYBYTES] result; ipcrypt_nd_decrypt_ip16(&context, &result[0], &ndip[0]); @@ -170,7 +168,7 @@ struct IPCrypt2 * random = 8-byte random data for non-determinism. * Returns: The encrypted IP address as a string. */ - string ndEncryptIPStr(scope const(char)* ipStr, scope const(ubyte)* random) nothrow + string ndEncryptIPStr(scope const(char)* ipStr, scope const(ubyte)* random) nothrow @trusted { char[49] result; size_t len = ipcrypt_nd_encrypt_ip_str(&context, &result[0], &ipStr[0], &random[0]); @@ -183,7 +181,7 @@ struct IPCrypt2 * encryptedIPStr = The encrypted IP address string. * Returns: The decrypted IP address as a string. */ - string ndDecryptIPStr(scope const(char)* encryptedIPStr) nothrow + string ndDecryptIPStr(scope const(char)* encryptedIPStr) nothrow @trusted { char[46] result; size_t len = ipcrypt_nd_decrypt_ip_str(&context, &result[0], &encryptedIPStr[0]); @@ -192,33 +190,31 @@ struct IPCrypt2 } /** - * RAII wrapper for the IPCryptNDX context, providing extended encryption/decryption. + * IPCryptNDX context, providing extended encryption/decryption. * Ensures proper initialization and cleanup of the underlying IPCryptNDX context. */ -struct IPCryptNDXWrapper +struct IPCryptNDXCtx { private IPCryptNDX context; // Opaque IPCryptNDX context /** - * Constructs an IPCryptNDXWrapper with the given 32-byte key. + * Constructs an IPCryptNDXCtx with the given 32-byte key. * Throws: Exception if the key length is not 32 bytes. */ - this(scope const(ubyte)* key) nothrow @nogc + this(scope const(ubyte)* key) nothrow @nogc @trusted { ipcrypt_ndx_init(&context, &key[0]); } /// Ditto, but constructs from a hexadecimal key string. - this(string hexKey) + this(string hexKey) nothrow @nogc @trusted { ubyte[IPCRYPT_KEYBYTES] key; - // enforce(ipcrypt_key_from_hex(&key[0], key.length, &hexKey[0], hexKey.length) == 0, - // "Invalid hexadecimal key"); ipcrypt_ndx_init(&context, &key[0]); } /// Destructor ensures the IPCryptNDX context is cleaned up. - ~this() nothrow @nogc + ~this() nothrow @nogc @trusted { ipcrypt_ndx_deinit(&context); } @@ -233,9 +229,9 @@ struct IPCryptNDXWrapper * random = 16-byte random data for non-determinism. * Returns: The 32-byte encrypted IP address. */ - ubyte[32] encryptIP16(scope const(ubyte)* ip16, scope const(ubyte)* random) nothrow @nogc + ubyte[IPCRYPT_NDX_KEYBYTES] encryptIP16(scope const(ubyte)* ip16, scope const(ubyte)* random) nothrow @nogc @trusted { - ubyte[32] result; + ubyte[IPCRYPT_NDX_KEYBYTES] result; ipcrypt_ndx_encrypt_ip16(&context, &result[0], &ip16[0], &random[0]); return result; } @@ -246,7 +242,7 @@ struct IPCryptNDXWrapper * ndip = The 32-byte encrypted IP address. * Returns: The 16-byte decrypted IP address. */ - ubyte[IPCRYPT_KEYBYTES] decryptIP16(scope const(ubyte)* ndip) nothrow @nogc + ubyte[IPCRYPT_KEYBYTES] decryptIP16(scope const(ubyte)* ndip) nothrow @nogc @trusted { ubyte[IPCRYPT_KEYBYTES] result; ipcrypt_ndx_decrypt_ip16(&context, &result[0], &ndip[0]); @@ -260,7 +256,7 @@ struct IPCryptNDXWrapper * random = 16-byte random data for non-determinism. * Returns: The encrypted IP address as a string. */ - string encryptIPStr(string ipStr, scope const(ubyte)* random) nothrow + string encryptIPStr(string ipStr, scope const(ubyte)* random) nothrow @trusted { char[65] result; size_t len = ipcrypt_ndx_encrypt_ip_str(&context, &result[0], &ipStr[0], &random[0]); @@ -273,7 +269,7 @@ struct IPCryptNDXWrapper * encryptedIPStr = The encrypted IP address string. * Returns: The decrypted IP address as a string. */ - string decryptIPStr(string encryptedIPStr) nothrow + string decryptIPStr(string encryptedIPStr) nothrow @trusted { char[46] result; size_t len = ipcrypt_ndx_decrypt_ip_str(&context, &result[0], &encryptedIPStr[0]); @@ -288,7 +284,7 @@ struct IPCryptNDXWrapper * Returns: The 16-byte IP address. * Throws: Exception if the conversion fails. */ -ubyte[IPCRYPT_KEYBYTES] ipStrToIP16(string ipStr) +ubyte[IPCRYPT_KEYBYTES] ipStrToIP16(string ipStr) @trusted { ubyte[IPCRYPT_KEYBYTES] result; enforce(ipcrypt_str_to_ip16(&result[0], &ipStr[0]) == 0, "Invalid IP address string"); @@ -301,7 +297,7 @@ ubyte[IPCRYPT_KEYBYTES] ipStrToIP16(string ipStr) * ip16 = The 16-byte IP address. * Returns: The IP address as a string. */ -string ip16ToStr(scope const(ubyte)* ip16) nothrow +string ip16ToStr(scope const(ubyte)* ip16) nothrow @trusted { char[46] result; size_t len = ipcrypt_ip16_to_str(&result[0], &ip16[0]); @@ -315,7 +311,7 @@ string ip16ToStr(scope const(ubyte)* ip16) nothrow * Returns: The 16-byte IP address. * Throws: Exception if the conversion fails. */ -ubyte[IPCRYPT_KEYBYTES] sockaddrToIP16(scope sockaddr* sa) +ubyte[IPCRYPT_KEYBYTES] sockaddrToIP16(scope sockaddr* sa) @trusted { ubyte[IPCRYPT_KEYBYTES] result; enforce(ipcrypt_sockaddr_to_ip16(&result[0], sa) == 0, "Invalid sockaddr"); @@ -328,7 +324,7 @@ ubyte[IPCRYPT_KEYBYTES] sockaddrToIP16(scope sockaddr* sa) * ip16 = The 16-byte IP address. * Returns: The sockaddr_storage structure. */ -sockaddr_storage ip16ToSockaddr(scope const(ubyte)* ip16) nothrow @nogc +sockaddr_storage ip16ToSockaddr(scope const(ubyte)* ip16) nothrow @nogc @trusted { sockaddr_storage result; ipcrypt_ip16_to_sockaddr(&result, &ip16[0]); @@ -367,7 +363,7 @@ sockaddr_storage ip16ToSockaddr(scope const(ubyte)* ip16) nothrow @nogc } @("Related functions") -unittest +@safe unittest { // Test key for IPCrypt2 (16 bytes) ubyte[IPCRYPT_KEYBYTES] key = [ @@ -448,10 +444,10 @@ unittest } } -@("IPCryptNDXWrapper") -unittest +@("IPCryptNDXCtx") +@safe unittest { - // Test key for IPCryptNDXWrapper (16 bytes) + // Test key for IPCryptNDXCtx (16 bytes) ubyte[IPCRYPT_KEYBYTES] key = [ 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x10 @@ -463,13 +459,13 @@ unittest // Test 1: RAII lifecycle (init/deinit) { - auto crypt = IPCryptNDXWrapper(&key[0]); + auto crypt = IPCryptNDXCtx(&key[0]); // Context is initialized; destructor will call ipcrypt_ndx_deinit automatically } // Test 2: Encrypt and decrypt IP16 { - auto crypt = IPCryptNDXWrapper(&key[0]); + auto crypt = IPCryptNDXCtx(&key[0]); ubyte[IPCRYPT_KEYBYTES] random = [ 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F, 0x30 @@ -481,7 +477,7 @@ unittest // Test 3: Encrypt and decrypt IP string { - auto crypt = IPCryptNDXWrapper(&key[0]); + auto crypt = IPCryptNDXCtx(&key[0]); ubyte[IPCRYPT_KEYBYTES] random = [ 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F, 0x30 @@ -495,7 +491,7 @@ unittest { string hexKey = "0102030405060708090A0B0C0D0E0F10" ~ "1112131415161718191A1B1C1D1E1F20"; // Matches `key` - auto crypt = IPCryptNDXWrapper(hexKey); + auto crypt = IPCryptNDXCtx(hexKey); ubyte[IPCRYPT_KEYBYTES] random = [ 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F, 0x30 @@ -508,12 +504,12 @@ unittest // Test 5: Invalid hexadecimal key // { // string invalidHexKey = "invalid_hex_key"; - // assertThrown!Exception(IPCryptNDXWrapper(invalidHexKey), "Expected exception for invalid NDX hex key"); + // assertThrown!Exception(IPCryptNDXCtx(invalidHexKey), "Expected exception for invalid NDX hex key"); // } } @("sockaddr conversions") -unittest +@safe unittest { // Note: Testing sockaddr conversions requires platform-specific setup. // This is a placeholder test; actual sockaddr testing depends on the environment.