A Windows DLL implementing the SQL Server Extensible Key Management (EKM) provider interface, backed by the Cosmian KMS.
The library exposes the SqlCrypt* C ABI required by SQL Server and is built as a cdylib (a Windows .dll).
If you are only interested in deploying the DLL, check the Deployment Instructions.
For a high-level overview of the architecture and call flows, see FLOWS.md.
For development and testing, see below.
Table of Contents
- 1. Build Prerequisites
- 2. Building the DLL
- 3. Signing the DLL
- 4. Deploying files and setting permissions
- 5. Configuration file (
config.toml) - 6. Log files
- 7. Connecting to SQL Server with
sqlcmd - 8. Installing the EKM provider in SQL Server
- 9. Starting / restarting SQL Server
- 10. Creating a test database and testing encryption
- Step 10.1 - Create the test database
- Step 10.2 - Create the database master key
- Step 10.3 - Enable Transparent Data Encryption (TDE) with the EKM key
- Step 10.4 - Create a symmetric key for column-level encryption
- Step 10.5 - Create a test table and insert encrypted data
- Step 10.6 - Read back the decrypted data
- 11. Uninstalling the provider
- 12. Troubleshooting
- Msg 33029 - Cannot initialize cryptographic provider. Provider error code: 3 (Not Supported)
- Msg 33029 - Cannot initialize cryptographic provider. Provider error code: 0 (Success)
- Msg 33029 - Provider error code: 1 (Failure) or signature-related
- Execution policy error when running scripts
- No log file appears
- How to check which provider functions were called
- 13. Running the integration tests
- Project structure
- License
| Tool | Notes |
|---|---|
| Rust toolchain ≥ 1.85 (edition 2024) | rustup update stable |
MSVC target x86_64-pc-windows-msvc |
rustup target add x86_64-pc-windows-msvc |
| LLVM / Clang | Required by bindgen at build time. Add <llvm>\bin to PATH and set LIBCLANG_PATH=<llvm>\lib. |
| Windows SDK (signtool) | Included with Visual Studio or the standalone Windows SDK. |
| A code-signing certificate | Self-signed is fine for dev; must be trusted by the machine. |
| SQL Server Developer / Enterprise edition | EKM is not available in Express or Web editions. |
sqlcmd or SQL Server Management Studio |
To execute T-SQL commands. |
| OpenSSL | See instructions below |
Follow the prerequisites below, or use the provided PowerShell helpers.
Prerequisites (manual):
- Install Visual Studio (C++ workload + clang), Strawberry Perl, and
vcpkg. - Install OpenSSL 3.6.0 with vcpkg:
In this project root directory, run:
vcpkg install --triplet x64-windows-static
$env:OPENSSL_DIR=(Get-Item .).FullName+"\vcpkg_installed\vcpkg\pkgs\openssl_x64-windows-static"All commands are run in an elevated PowerShell prompt from the repository root.
cargo build
# Output: target\debug\cosmian_ekm_sql_server.dllcargo build --release
# Output: target\release\cosmian_ekm_sql_server.dllThis step is mandatory.
SQL Server callsCREATE CRYPTOGRAPHIC PROVIDERonly if the DLL is digitally signed with a certificate whose chain is trusted by the Windows machine.
An unsigned DLL will cause error 33085 or a signature verification failure.
Two scripts handle this. Both must be run in an elevated PowerShell session.
PowerShell execution policy
On a fresh Windows installation scripts are disabled by default. If you see:
cannot be loaded because running scripts is disabled on this system
run this once in your elevated PowerShell session:Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Scope LocalMachine
RemoteSignedallows locally created scripts to run freely while still requiring a signature on scripts downloaded from the internet.
To check the current policy:Get-ExecutionPolicy -List
Run once on the target machine.
# From the repository root, in an elevated PowerShell:
.\scripts\New-EkmCertificate.ps1What it does:
- Creates a self-signed RSA-2048 code-signing certificate
CN=Cosmian EKM DevinLocalMachine\My. - Adds it to
LocalMachine\Rootso SQL Server trusts the chain. - Exports the public certificate to
scripts\CosmianEKM.cerfor reference.
If the certificate already exists the script is a no-op - safe to re-run.
Run after every cargo build --release.
# From the repository root, in an elevated PowerShell:
.\scripts\Sign-EkmDll.ps1What it does:
- Finds the certificate created in Step 3a.
- Calls
Set-AuthenticodeSignatureontarget\release\cosmian_ekm_sql_server.dll. - Verifies the resulting signature status and exits with an error if it is not
Valid.
Custom DLL path (e.g. debug build):
.\scripts\Sign-EkmDll.ps1 -DllPath target\debug\cosmian_ekm_sql_server.dllIf you have an existing trusted code-signing certificate, skip Step 3a and sign directly:
$cert = Get-ChildItem Cert:\LocalMachine\My |
Where-Object { $_.Subject -like "*Cosmian*" } |
Select-Object -First 1
Set-AuthenticodeSignature `
-FilePath "target\release\cosmian_ekm_sql_server.dll" `
-Certificate $cert `
-TimestampServer "http://timestamp.digicert.com"Two scripts handle deployment.
Run once on the target machine, before the first deployment.
# From the repository root, in an elevated PowerShell:
.\scripts\Initialize-EkmEnvironment.ps1What it does:
- Creates
C:\Program Files\Cosmian\EKM\(DLL install location). - Creates
C:\ProgramData\Cosmian\EKM\and...\logs\. - Grants the SQL Server service account
ModifyonC:\ProgramData\Cosmian\EKM\andReadAndExecuteon the install directory. - Writes a template
config.tomlif none exists (see Section 5).
Named SQL Server instance:
.\scripts\Initialize-EkmEnvironment.ps1 -SqlServiceAccount "NT SERVICE\MSSQL`$MyInstance"Run after every build + sign cycle to push a new version to SQL Server.
# From the repository root, in an elevated PowerShell:
.\scripts\Deploy-EkmDll.ps1What it does:
- Validates the DLL's Authenticode signature (refuses to deploy unsigned/invalid DLLs).
- Stops the SQL Server service.
- Overwrites
C:\Program Files\Cosmian\EKM\cosmian_ekm_sql_server.dll. - Restarts SQL Server and waits until it is running.
- Re-runs the
CREATE CRYPTOGRAPHIC PROVIDERstatement to update the DLL path in SQL Server's catalog (see Section 8.2).
Do I need to re-register the provider after updating the DLL?
No.CREATE CRYPTOGRAPHIC PROVIDERis a one-time operation that records the DLL path in the SQL Server catalog. Replacing the file at that path with a new version is all that is needed - SQL Server will load the updated DLL on the next startup with no SQL changes required.Do I need to stop and restart SQL Server every time?
Yes. SQL Server loads the EKM DLL directly into its process and holds an exclusive file lock on it. You cannot overwrite a locked file, and the new code only takes effect once the process reloads the DLL from disk. TheDeploy-EkmDll.ps1script handles the stop/copy/start sequence automatically.
Named instance or custom DLL path:
.\scripts\Deploy-EkmDll.ps1 -SqlServiceName "MSSQL`$MyInstance"
.\scripts\Deploy-EkmDll.ps1 -DllPath target\debug\cosmian_ekm_sql_server.dllIf SQL Server is not yet installed or you want to restart it yourself:
.\scripts\Deploy-EkmDll.ps1 -SkipServiceRestartIf the provider is already registered and you only want to update the DLL without re-running CREATE CRYPTOGRAPHIC PROVIDER:
.\scripts\Deploy-EkmDll.ps1 -SkipRegistration# 1. Build
cargo build --release
# 2. Sign
.\scripts\Sign-EkmDll.ps1
# 3.a Deploy (stops SQL Server, copies DLL, restarts SQL Server, re-registers the provider)
.\scripts\Deploy-EkmDll.ps1
# 3.b Deploy (once the provider is successfully registered, and a credential has been created for the Database Engine login, you must skip the provider registration step on subsequent deployments)
.\scripts\Deploy-EkmDll.ps1 -SkipRegistrationThe provider reads its settings from:
C:\ProgramData\Cosmian\EKM\config.toml
Create this file before starting SQL Server.
# ── Session settings ──────────────────────────────────────────────────────────
# Maximum session idle time in seconds (default: 1800 = 30 minutes).
max_age_seconds = 1800
# ── Cosmian KMS connection ────────────────────────────────────────────────────
[kms]
# Base URL of the Cosmian KMS REST API.
server_url = "https://kms.example.com:9998"
# Set to true only for development / self-signed KMS certificates.
accept_invalid_certs = false
# ── Per-user mTLS client certificates ─────────────────────────────────────────
# One section per SQL Server login that needs to create or manage keys.
# The certificate's Subject CN (or SAN) must match the username field.
[[kms.certificates]]
username = "admin"
client_cert = 'C:\ProgramData\Cosmian\EKM\certificates\admin.cert.pem'
client_key = 'C:\ProgramData\Cosmian\EKM\certificates\admin.key.pem'# Create a minimal config (edit values before use)
@"
max_age_seconds = 1800
[kms]
server_url = "https://kms.example.com:9998"
accept_invalid_certs = false
[[kms.certificates]]
username = "admin"
client_cert = 'C:\ProgramData\Cosmian\EKM\certificates\admin.cert.pem'
client_key = 'C:\ProgramData\Cosmian\EKM\certificates\admin.key.pem'
"@ | Set-Content "C:\ProgramData\Cosmian\EKM\config.toml" -Encoding UTF8Why
C:\ProgramData?
SQL Server runs under a Windows service account (NT SERVICE\MSSQLSERVER) that has no user profile.%APPDATA%and%LOCALAPPDATA%are unavailable to it.C:\ProgramDatais the standard Windows location for machine-wide service data and is accessible to all service accounts.
Rolling daily log files are written automatically to:
C:\ProgramData\Cosmian\EKM\logs\cosmian_ekm.log.<yyyy-MM-dd>The directory is created on the first call to SqlCryptInitializeProvider
(when SQL Server loads the provider). All pending records are flushed and the
background I/O thread is stopped when SqlCryptFreeProvider is called (when SQL
Server unloads the provider).
To tail the current day's log:
$today = Get-Date -Format "yyyy-MM-dd"
Get-Content "C:\ProgramData\Cosmian\EKM\logs\cosmian_ekm.log.$today" -WaitThe T-SQL commands in the following sections must be run as a member of the
sysadmin fixed server role. You do not need an elevated PowerShell shell
for sqlcmd itself - elevation is only needed for the PowerShell deployment
scripts that touch the file system and Windows services.
sqlcmd -S localhost -E-E uses your current Windows login (Trusted Connection). If your Windows
account is a sysadmin this is all you need.
sqlcmd -S localhost\MyInstance -Esqlcmd -S localhost -U sa -P "<YourPassword>"sqlcmd -S localhost -E -i setup.sql- Type T-SQL statements and press Enter to add lines.
- Type
GOand press Enter to execute the accumulated batch. - Type
EXITto quit.
sqlcmdnot found?
It is installed with SQL Server by default. If it is missing from yourPATH, add the SQL Server tools directory:# Adjust the version year as needed $env:PATH += ";C:\Program Files\Microsoft SQL Server\Client SDK\ODBC\170\Tools\Binn"Or install the standalone sqlcmd utility.
(Re)adding your login to
sysadminrole If your current Windows login is not a member ofsysadmin, you can add it using an elevated PowerShell prompt and the Dedicated Administrator Connection (DAC):# 1. Connect via DAC and re-add your Windows login as sysadmin sqlcmd -S admin:localhost -E -Q " CREATE LOGIN [<YOUR_DOMAIN>\<YOUR_LOGIN>] FROM WINDOWS; ALTER SERVER ROLE sysadmin ADD MEMBER [<YOUR_DOMAIN>\<YOUR_LOGIN>]; GO "
Connect to SQL Server as a member of the sysadmin fixed server role (e.g. using
sqlcmd or SSMS) and execute the following T-SQL statements in order.
EKM is disabled by default. Enable it once per SQL Server instance:
EXECUTE sp_configure 'show advanced options', 1;
GO
RECONFIGURE;
GO
EXECUTE sp_configure 'EKM provider enabled', 1;
GO
RECONFIGURE;
GOIF EXISTS (SELECT 1 FROM sys.cryptographic_providers WHERE name='CosmianEKM') DROP CRYPTOGRAPHIC PROVIDER CosmianEKM;
CREATE CRYPTOGRAPHIC PROVIDER CosmianEKM FROM FILE = 'C:\Program Files\Cosmian\EKM\cosmian_ekm_sql_server.dll';
GOsqlcmd -S localhost -E -Q "CREATE CRYPTOGRAPHIC PROVIDER CosmianEKM FROM FILE = 'C:\Program Files\Cosmian\EKM\cosmian_ekm_sql_server.dll';"If this statement returns
Msg 33029: The provider is not registered — a failedCREATE CRYPTOGRAPHIC PROVIDERleaves no entry in the catalog. Fix the underlying issue (consult Section 12 and the log file inC:\ProgramData\Cosmian\EKM\logs\), then:
- Rebuild:
cargo build --release- Redeploy following Step 4b (sign + deploy scripts)
- Re-run the
CREATE CRYPTOGRAPHIC PROVIDERstatement aboveIf a previous attempt did partially register the provider (check with
SELECT name FROM sys.cryptographic_providers), drop it first:DROP CRYPTOGRAPHIC PROVIDER CosmianEKM; GO
Verify registration:
SELECT name, dll_path, is_enabled
FROM sys.cryptographic_providers;The credential carries authentication information (identity / secret) that SQL
Server passes to the EKM provider when opening a session. Adjust the values to
match the KMS authentication scheme you configure in config.toml.
-- Credential used by the sysadmin who will create keys
-- IDENTITY must match the `username` field in a [[kms.certificates]] entry in config.toml.
CREATE CREDENTIAL Cosmian_Admin WITH IDENTITY = 'admin', SECRET = 'unused' FOR CRYPTOGRAPHIC PROVIDER CosmianEKM;
GO
-- Map the credential to your login (replace DOMAIN\YourLogin as appropriate e.g. DESKTOP-7G2ABC\Alice)
ALTER LOGIN [DOMAIN\YourLogin] ADD CREDENTIAL Cosmian_Admin;
GORemoving the credential mapping:
Remove the mapping to your login:
ALTER LOGIN [DOMAIN\YourLogin] DROP CREDENTIAL Cosmian_Admin; GODrop the credential itself:
DROP CREDENTIAL Cosmian_Admin; GO
Listing all the credentials
-- All credentials targeting an EKM provider SELECT credential_id, name, credential_identity, target_id, target_type, create_date FROM sys.credentials WHERE target_type = 'CRYPTOGRAPHIC PROVIDER'; GO-- All credentials mapped to a specific login SELECT sp.name AS login_name, sp.type_desc AS login_type, c.name AS credential_name, c.credential_identity FROM sys.server_principal_credentials spc JOIN sys.server_principals sp ON sp.principal_id = spc.principal_id JOIN sys.credentials c ON c.credential_id = spc.credential_id WHERE c.name = 'Cosmian_Admin'; -- replace with your credential name GO
USE master;
GO
CREATE ASYMMETRIC KEY Cosmian_MasterKey FROM PROVIDER CosmianEKM WITH ALGORITHM = RSA_2048 , PROVIDER_KEY_NAME = 'cosmian-sql-master-key' , CREATION_DISPOSITION = CREATE_NEW;
GOThis is the login the Database Engine uses internally (e.g. for TDE auto-open at startup). Users cannot sign in with it directly.
CREATE LOGIN EKM_DBEngine_Login
FROM ASYMMETRIC KEY Cosmian_MasterKey;
GO
-- Create a second credential for the Database Engine login
-- IDENTITY must match the `username` field in a [[kms.certificates]] entry in config.toml.
CREATE CREDENTIAL Cosmian_DBEngine_Cred
WITH IDENTITY = 'admin',
SECRET = 'unused'
FOR CRYPTOGRAPHIC PROVIDER CosmianEKM;
GO
ALTER LOGIN EKM_DBEngine_Login
ADD CREDENTIAL Cosmian_DBEngine_Cred;
GOAfter changing EKM provider configuration or registering a new provider, restart the SQL Server service so it reloads the DLL.
# Default instance
Restart-Service -Name MSSQLSERVER -Force
# Named instance (replace MyInstance)
# Restart-Service -Name "MSSQL`$MyInstance" -Force- Open SQL Server Configuration Manager (
SQLServerManager17.msc). - Select SQL Server Services in the left pane.
- Right-click SQL Server (MSSQLSERVER) → Restart.
Get-Service MSSQLSERVER | Select-Object Status, DisplayNameThe following T-SQL creates a database, protects its encryption key with the Cosmian EKM asymmetric key (TDE), and then creates a table with a column-level symmetric key also protected by the same EKM key.
Run everything in sqlcmd or SSMS as sysadmin.
CREATE DATABASE CosmianEKMTest;
GOUSE CosmianEKMTest;
GO
CREATE MASTER KEY ENCRYPTION BY PASSWORD = 'AStr0ng!DBMasterKeyPwd';
GOUSE CosmianEKMTest;
GO
-- Create the database encryption key, protected by the EKM asymmetric key
CREATE DATABASE ENCRYPTION KEY
WITH ALGORITHM = AES_256
ENCRYPTION BY SERVER ASYMMETRIC KEY Cosmian_MasterKey;
GO
-- Turn on TDE - the entire database file is now encrypted at rest
ALTER DATABASE CosmianEKMTest SET ENCRYPTION ON;
GOVerify TDE status:
SELECT db.name, dek.encryption_state, dek.encryptor_type, dek.percent_complete
FROM sys.dm_database_encryption_keys dek
JOIN sys.databases db ON dek.database_id = db.database_id
WHERE db.name = 'CosmianEKMTest';
-- encryption_state 3 = encryptedColumn-level encryption (CLE) gives you field-granular control, independent of TDE.
USE CosmianEKMTest;
GO
CREATE SYMMETRIC KEY Cosmian_ColKey
WITH ALGORITHM = AES_256
ENCRYPTION BY SERVER ASYMMETRIC KEY Cosmian_MasterKey;
GOUSE CosmianEKMTest;
GO
CREATE TABLE dbo.SensitiveData
(
Id INT IDENTITY PRIMARY KEY,
PlainLabel NVARCHAR(100) NOT NULL, -- stored in plain text
SecretValue VARBINARY(256) NOT NULL -- stored encrypted
);
GO
-- Open the symmetric key before encrypting
OPEN SYMMETRIC KEY Cosmian_ColKey
DECRYPTION BY SERVER ASYMMETRIC KEY Cosmian_MasterKey;
INSERT INTO dbo.SensitiveData (PlainLabel, SecretValue)
VALUES
('Record A', ENCRYPTBYKEY(KEY_GUID('Cosmian_ColKey'), N'Top secret value A')),
('Record B', ENCRYPTBYKEY(KEY_GUID('Cosmian_ColKey'), N'Top secret value B'));
CLOSE SYMMETRIC KEY Cosmian_ColKey;
GOUSE CosmianEKMTest;
GO
OPEN SYMMETRIC KEY Cosmian_ColKey
DECRYPTION BY SERVER ASYMMETRIC KEY Cosmian_MasterKey;
SELECT
Id,
PlainLabel,
CONVERT(NVARCHAR(200),
DECRYPTBYKEY(SecretValue)) AS DecryptedValue
FROM dbo.SensitiveData;
CLOSE SYMMETRIC KEY Cosmian_ColKey;
GOExpected output:
| Id | PlainLabel | DecryptedValue |
|---|---|---|
| 1 | Record A | Top secret value A |
| 2 | Record B | Top secret value B |
-- 1. Remove TDE from databases that use this provider
ALTER DATABASE CosmianEKMTest SET ENCRYPTION OFF;
GO
-- 2. Drop the database encryption key
USE CosmianEKMTest;
DROP DATABASE ENCRYPTION KEY;
GO
-- 3. Drop the asymmetric key and logins/credentials in master
USE master;
GO
DROP LOGIN EKM_DBEngine_Login;
DROP LOGIN [DOMAIN\YourLogin]; -- only removes the credential mapping
ALTER LOGIN [DOMAIN\YourLogin] DROP CREDENTIAL Cosmian_Admin_Cred;
DROP CREDENTIAL Cosmian_DBEngine_Cred;
DROP CREDENTIAL Cosmian_Admin_Cred;
DROP ASYMMETRIC KEY Cosmian_MasterKey;
DROP CRYPTOGRAPHIC PROVIDER CosmianEKM;
GOThen stop SQL Server, remove the DLL, and clean up:
Stop-Service MSSQLSERVER -Force
Remove-Item "C:\Program Files\Cosmian\EKM\cosmian_ekm_sql_server.dll"
# Optionally remove data directory:
# Remove-Item "C:\ProgramData\Cosmian\EKM" -Recurse
Start-Service MSSQLSERVERMsg 33029, Level 16, State 2
Cannot initialize cryptographic provider. Provider error code: 3.
(Not Supported - Consult EKM Provider for details)
Cause: Error code 3 maps to scp_err_NotSupported in the SQL Crypto ABI.
During CREATE CRYPTOGRAPHIC PROVIDER, SQL Server calls the following functions
in order:
SqlCryptInitializeProviderSqlCryptGetProviderInfo← most likely failure pointSqlCryptGetNextAlgorithmIdSqlCryptFreeProvider
If any of these returns a non-zero error code, SQL Server reports 33029 with that code as the "Provider error code".
Fix: Ensure SqlCryptGetProviderInfo fills in the SqlCpProviderInfo
struct (provider name, GUID, version, API version, auth type, key support flags)
and returns scp_err_Success. Also ensure SqlCryptGetNextAlgorithmId returns
scp_err_NotFound (not scp_err_NotSupported) to signal an empty algorithm
list - NotFound is the correct sentinel for "end of enumeration".
Msg 33029, Level 16, State 2
Cannot initialize cryptographic provider. Provider error code: 0.
(Success - Consult EKM Provider for details)
Cause: All provider functions returned scp_err_Success (0), but SQL Server
internally rejected the contents of the SqlCpProviderInfo struct returned by
SqlCryptGetProviderInfo. The "(Success)" annotation means the last error
code the provider returned was 0 - it does not mean the provider
registration succeeded.
Common struct problems SQL Server validates silently (derived from the official Microsoft sample provider):
| Field | Required value | Notes |
|---|---|---|
name.ws |
Pointer to UTF-16 data | Per spec, ws does not need to be null-terminated; cb is the sole length authority |
name.cb |
Byte count of the string | Must be > 0 and ≤ 2048 |
scpVersion |
{major=1, minor=1, build=0, revision=0} |
Must match x_scp_SqlCpVerMajor/Minor in sqlcrypt.h exactly |
version |
Any {major, minor, build, revision} but fixed forever |
SQL Server stores this on first registration and rejects the DLL if it changes on reload |
cbKeyThumbLen |
sizeof(GUID) = 16 |
SQL Server validates this equals the GUID size; values like 32 cause silent rejection |
symmKeySupport |
At least scp_kf_Supported (0x01) |
SQL Server rejects a provider with zero key support entirely |
asymmKeySupport |
At least scp_kf_Supported (0x01) |
Same |
| Struct padding | All padding bytes must be zero | Zero-initialise the whole struct before filling fields |
Fix (already applied in this codebase):
SqlCryptGetProviderInfocallsstd::ptr::write_bytes(p_provider_info, 0, 1)to zero-initialise the full 64-byteSqlCpProviderInfobefore filling in individual fields.PROVIDER_NAME_UTF16ends with a0x0000null terminator, andname.cbis set to the byte count excluding that null.cbKeyThumbLenis set tosize_of::<GUID>()= 16 (not 32).symmKeySupportis set toscp_kf_Supported;asymmKeySupportlikewise.versionis fixed at{1, 0, 0, 0}— do not change this value after the provider has been registered, or SQL Server will refuse to load the DLL.
If you are building from an older checkout that predates these fixes, rebuild and redeploy:
cargo build --release
.\scripts\Sign-EkmDll.ps1
.\scripts\Deploy-EkmDll.ps1Msg 33029 ... Provider error code: 1.
or
Msg 33095, Level 16 ... The cryptographic provider is not registered.
Cause: The DLL is not digitally signed, or the signing certificate is not in
LocalMachine\Root (Trusted Root CAs) on this machine.
Fix: Run scripts\New-EkmCertificate.ps1 (once) then scripts\Sign-EkmDll.ps1
after every build. Verify with:
Get-AuthenticodeSignature "C:\Program Files\Cosmian\EKM\cosmian_ekm_sql_server.dll"
# Status must be: Validcannot be loaded because running scripts is disabled on this system
Fix: In an elevated PowerShell, run once:
Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Scope LocalMachineThe log directory C:\ProgramData\Cosmian\EKM\logs\ is created automatically
on first load. If it is missing, the SQL Server service account likely lacks
write access. Re-run scripts\Initialize-EkmEnvironment.ps1 (elevated) to
correct the ACLs.
Tail the log file while reproducing the error (SQL Server must have been restarted after deploying the DLL):
$today = Get-Date -Format "yyyy-MM-dd"
Get-Content "C:\ProgramData\Cosmian\EKM\logs\cosmian_ekm.log.$today" -WaitEvery SqlCrypt* entry point logs an INFO line on entry, so the last logged
function before the error is where execution stopped.
The integration tests exercise the deployed DLL end-to-end through sqlcmd
against a live SQL Server instance and a running Cosmian KMS. Everything runs
sequentially because the tests share global SQL Server state.
For a full list of test cases see tests.md.
| Requirement | Notes |
|---|---|
| Cosmian KMS | Running on https://localhost:9998 with mTLS. Use config.test.toml to point the provider at it. |
| SQL Server | Default instance running locally; the EKM feature enabled (sp_configure 'EKM provider enabled'). |
| Deployed DLL | Built, signed, and copied to C:\Program Files\Cosmian\EKM\cosmian_ekm_sql_server.dll. |
CosmianEKM provider registered |
sys.cryptographic_providers must have a row for CosmianEKM. |
config.toml |
The test config (config.test.toml) copied to C:\ProgramData\Cosmian\EKM\config.toml. |
Correct WIN_LOGIN |
The constant at the top of tests/integration.rs must match your Windows login (DOMAIN\username). |
Open tests/integration.rs and update the WIN_LOGIN constant to match your
Windows login name (the one you use to connect to SQL Server with -E):
const WIN_LOGIN: &str = "YOURDOMAIN\\YourLogin"; // e.g. "DESKTOP-ABC\\alice"You can find your login with:
[System.Security.Principal.WindowsIdentity]::GetCurrent().NameRun the preparation script once per test cycle from an elevated PowerShell.
It builds the DLL, signs it, deploys it (stop SQL Server → copy → start), and
installs config.test.toml as the active provider config:
# From the repository root, elevated PowerShell:
.\scripts\Prepare-Integration-Tests.ps1Prerequisites that must have been run at least once before:
.\scripts\New-EkmCertificate.ps1 # create & trust the self-signed code-signing cert
.\scripts\Initialize-EkmEnvironment.ps1 # create dirs, set ACLscargo test --test integration -- --test-threads=1Tests must run sequentially (--test-threads=1): they share the SQL Server
credential, key objects, and test databases.
To run a single test:
cargo test --test integration t05_create_asymmetric_key -- --test-threads=1- Tests are numbered (
t00…t13,t99) so alphabetical ordering matches execution order. t99_cleanupdrops all objects created by the suite. Re-running the suite fromt00is safe.- If a test fails mid-run, re-run from
t04_credential_setupto restore the credential and keys (or runt99_cleanupfirst to reset state). - Log output from the provider DLL is written to
C:\ProgramData\Cosmian\EKM\logs\cosmian_ekm.log.<date>— tail it to diagnose failures.
build.rs # Calls bindgen to generate Rust types from sqlcrypt.h
Cargo.toml
src/
lib.rs # SqlCrypt* entry points
sqlcrypt.h # Microsoft SQL Server EKM C interface header
wrapper.h # Thin bindgen wrapper that includes sqlcrypt.h
scripts/
New-EkmCertificate.ps1 # (once) Create & trust the self-signed cert
Sign-EkmDll.ps1 # (each build) Sign the release DLL
Initialize-EkmEnvironment.ps1 # (once) Create dirs & set permissions
Deploy-EkmDll.ps1 # (each deploy) Stop SQL Server, copy DLL, restart
See LICENSE.