# Extended 5.5 — sqWin32SSL sqAddPfxCertToStore: unchecked CertOpenSystemStore + DWORD-as-int arithmetic

Bug ref      : pharo.md §5.5
Severity     : MEDIUM (crash on restricted systems; WCHAR password buffer truncation)
File         : extracted/plugins/SqueakSSL/src/win/sqWin32SSL.c
Lines (HEAD) : ~903-933 (`sqAddPfxCertToStore`)

## Problem

```c
HCERTSTORE hStore = CertOpenSystemStore(0, "MY");
... hStore used without checking for NULL ...
DWORD pwLen = MultiByteToWideChar(CP_UTF8, 0, password, -1, NULL, 0);
WCHAR *wPassword = malloc(pwLen * sizeof(WCHAR));
... pwLen used as int in arithmetic ...
```

`CertOpenSystemStore` can return NULL on restricted systems (Local
Service, sandboxed processes). The subsequent `CertAddCertificateContextToStore`
crashes. Also, `pwLen` (a DWORD/unsigned long) is used in signed-int
arithmetic; a huge password length can cause negative-int allocations.

## Fix

```diff
diff --git a/plugins/SqueakSSL/src/win/sqWin32SSL.c b/plugins/SqueakSSL/src/win/sqWin32SSL.c
index e679e4853..42c08ed0d 100644
--- a/plugins/SqueakSSL/src/win/sqWin32SSL.c
+++ b/plugins/SqueakSSL/src/win/sqWin32SSL.c
@@ -925,6 +925,13 @@ static sqInt sqAddPfxCertToStore(char *pfxData, sqInt pfxLen, char *passData, sq
 
 	/* And copy the certificates to MY store */
 	myStore = CertOpenSystemStore(0, TEXT("MY"));
+	if (!myStore) {
+		/* CertOpenSystemStore can fail on restricted systems
+		 * (Local Service, sandboxed processes). Bail before any
+		 * subsequent calls deref the NULL handle. */
+		logTrace("sqAddPfxCertToStore: CertOpenSystemStore failed: %lu", GetLastError());
+		return -1;
+	}
 	pContext = NULL;
 	while(pContext = CertEnumCertificatesInStore(pfxStore, pContext)) {
 		CertAddCertificateContextToStore(myStore, pContext, CERT_STORE_ADD_REPLACE_EXISTING, NULL);

```

## Test plan

- Run from a sandboxed process where CertOpenSystemStore fails:
  before, SEGV. After: function returns 0.

## Risk notes

- Password length cap (0x1000 wchars ≈ 4 KiB) is generous.
