Memory Certificate Collection Mode (TlsCertMemory)
Overview
Memory certificate collection mode is the most flexible TLS configuration method. Certificate data does not come from disk files or Windows Certificate Store, but is dynamically constructed by the program at runtime and stored in a VB6 Collection object, directly passed to the TLS engine.
Function Signature
Public Function TlsCertMemory( _
ByVal Certificates As Collection, _
ByVal PrivateKey As Collection, _
Optional ByVal AlpnProtocols As String = "...") As <ComponentType>Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
Certificates | Collection | Yes | Certificate chain collection, each element is a PEM format certificate text |
PrivateKey | Collection | Yes | Private key collection, each element is a PEM format private key text |
AlpnProtocols | String | No | ALPN protocol negotiation. Default values vary by component |
| Component | AlpnProtocols Default |
|---|---|
| cHttpServer | "http/1.1" |
| cWinsock | "http/1.1" |
| cWebSocketServer | "" (Empty) |
Collection Data Format
Certificates Collection
Each element is a PEM encoded certificate text string:
Dim certs As New Collection
certs.Add "-----BEGIN CERTIFICATE-----" & vbCrLf & _
"MIIFazCCBFOgAwIBAgISA2Q3p..." & vbCrLf & _
"-----END CERTIFICATE-----"
' Intermediate certificate (if any)
certs.Add "-----BEGIN CERTIFICATE-----" & vbCrLf & _
"MIIFazCCBFOgAwIBAgISA3B4q..." & vbCrLf & _
"-----END CERTIFICATE-----"Order Requirement: First element must be the server certificate (leaf certificate), followed by intermediate certificates.
PrivateKey Collection
Each element is a PEM encoded private key text string:
Dim pkeys As New Collection
pkeys.Add "-----BEGIN PRIVATE KEY-----" & vbCrLf & _
"MIIEvgIBADANBgkqhkiG9w0BAQ..." & vbCrLf & _
"-----END PRIVATE KEY-----"Supported Private Key Formats:
-----BEGIN PRIVATE KEY-----(PKCS#8 unencrypted)-----BEGIN RSA PRIVATE KEY-----(PKCS#1 RSA)-----BEGIN EC PRIVATE KEY-----(EC)-----BEGIN ENCRYPTED PRIVATE KEY-----(PKCS#8 encrypted)
Typical Application Scenarios
1. Certificate Embedded in Executable
Compile certificates as resources into EXE/DLL, extract to Collection at runtime, no need to distribute separate .pfx files.
' Load certificates from resource file
Dim certs As New Collection
Dim pkeys As New Collection
certs.Add LoadResData(101, "CERT") ' Custom resource type
pkeys.Add LoadResData(102, "KEY")
Server.TlsCertMemory(certs, pkeys).Start 443Advantages:
- Simple deployment, only one EXE file needed
- Certificates not exposed on disk (somewhat increased security)
- No dependency on external file paths
Limitations:
- Certificate updates require recompilation
- EXE size increases
2. ACME / Let's Encrypt Automatic Issuance
Program automatically applies for certificates at runtime through ACME protocol, loads directly to memory without writing to disk.
' ACME issuance process (pseudocode)
Dim certs As New Collection
Dim pkeys As New Collection
' 1. Create account
AcmeClient.Register "admin@example.com"
' 2. Verify domain ownership (HTTP-01 or DNS-01)
AcmeClient.VerifyDomain "www.example.com"
' 3. Issue certificate
Dim pemCert As String
Dim pemKey As String
pemCert = AcmeClient.IssueCertificate("www.example.com", pemKey)
' 4. Load to Collection
certs.Add pemCert
pkeys.Add pemKey
' 5. Start HTTPS
Server.TlsCertMemory(certs, pkeys).Start 443Advantages:
- Fully automatic, no manual intervention needed
- Certificates never touch disk, reduced leak risk
- Can implement scheduled automatic renewal
3. Dynamic SNI Routing
Based on the domain name requested by the client (SNI), dynamically load corresponding certificates from database or configuration center.
' Concept example: Multi-domain HTTPS server
' Note: Current cTlsSocket initializes certificates at Listen phase, single-port multi-certificate not supported
' Multi-domain scenarios recommend using wildcard certificates or creating separate cHttpServer instances per domain
Dim certs As New Collection
Dim pkeys As New Collection
' Load domain-specific certificate from config database
Dim rs As Recordset
Set rs = DB.Execute("SELECT cert_pem, key_pem FROM certs WHERE domain='www.example.com'")
certs.Add rs!cert_pem
pkeys.Add rs!key_pem
Server.TlsCertMemory(certs, pkeys).Start 4434. Testing Scenarios
Program self-signs temporary certificates for development and testing.
' Use OpenSSL command line to pre-generate test certificates, or use COM components to generate at runtime
Dim certs As New Collection
Dim pkeys As New Collection
' Assume TestCertGenerator is a custom certificate generation class
Dim gen As New TestCertGenerator
gen.CommonName = "localhost"
gen.ValidDays = 1
certs.Add gen.GenerateCertificate()
pkeys.Add gen.GeneratePrivateKey()
Server.TlsCertMemory(certs, pkeys).Start 4435. Load from File to Memory
Read file contents into Collection, implement lazy loading or cache control.
Private Function LoadPemToCollections( _
ByVal CertPaths As String, _
ByVal KeyPath As String) As Boolean
Dim certs As New Collection
Dim pkeys As New Collection
' Load certificates (supports | separated multiple files)
Dim arrCerts() As String
arrCerts = Split(CertPaths, "|")
Dim i As Long
For i = 0 To UBound(arrCerts)
certs.Add ReadTextFile(Trim(arrCerts(i)))
Next
' Load private key
pkeys.Add ReadTextFile(KeyPath)
' Use
Server.TlsCertMemory certs, pkeys
LoadPemToCollections = True
End Function
Private Function ReadTextFile(ByVal Path As String) As String
Dim f As Integer
f = FreeFile
Open Path For Input As #f
ReadTextFile = Input$(LOF(f), f)
Close #f
End FunctionUsage Examples by Component
cHttpServer (HTTPS)
Dim certs As New Collection
Dim pkeys As New Collection
' Load from database
certs.Add DB_GetCertPem("www.example.com")
pkeys.Add DB_GetKeyPem("www.example.com")
Server.TlsCertMemory(certs, pkeys).WebRoot("C:\www").Start 443cWinsock (TLS TCP Server)
Dim certs As New Collection
Dim pkeys As New Collection
certs.Add LoadFromResource(101)
pkeys.Add LoadFromResource(102)
Dim svr As New cWinsock
svr.TlsCertMemory(certs, pkeys).Listen 443cWebSocketServer (wss://)
Dim certs As New Collection
Dim pkeys As New Collection
certs.Add GetCertFromConfig()
pkeys.Add GetKeyFromConfig()
Dim wsSvr As New cWebSocketServer
wsSvr.TlsCertMemory(certs, pkeys).Listen 443PEM Text Format in Memory
Each element in the Collection must be a complete PEM block, including start and end markers:
✅ Correct: Complete PEM block
-----BEGIN CERTIFICATE-----
MIIFazCCBFOgAwIBAgISA2Q3p...
(Base64 content, may contain newlines)
-----END CERTIFICATE-----
❌ Incorrect: Only Base64 content, no PEM markers
MIIFazCCBFOgAwIBAgISA2Q3p...
❌ Incorrect: DER binary data (byte array)Newlines: Newlines in PEM text can be vbCr, vbLf, or vbCrLf, underlying OpenSSL can recognize all.
Underlying Processing Flow
' cTlsSocket.InitServerTls internal
If pvCollectionCount(Certificates) > 0 And pvCollectionCount(PrivateKey) > 0 Then
Set cCerts = Certificates
Set cPrivKey = PrivateKey
GoTo StartTls
End IfTlsCertMemory(certs, pkeys)
│
└─ InitServerTls(Certificates:=certs, PrivateKey:=pkeys)
│
├─ Check Certificates.Count > 0 And PrivateKey.Count > 0
│
└─ TlsInitServer(ctx, hostname, cCerts, cPrivKey, alpn, features)
│
├─ Iterate Certificates collection
│ └─ PEM_read_bio_X509() → Parse certificates one by one
│
├─ Iterate PrivateKey collection
│ └─ PEM_read_bio_PrivateKey() → Parse private key
│
└─ SSL_CTX_use_certificate() + SSL_CTX_use_PrivateKey()Security Considerations
1. Private Key Protection in Memory
Private keys are stored as plaintext PEM text in Collection, readable by debuggers in process memory.
Recommendations:
- Clear Collection and string variables as soon as possible after use
- Avoid outputting private key content in logs
- Consider using Windows DPAPI to encrypt stored private key text
' Clear after use
Set certs = Nothing
Set pkeys = Nothing2. Certificate Source Verification
When loading certificates from external sources (database, API, configuration center), verify data integrity and source.
Recommendations:
- Use TLS connections to obtain certificate data
- Perform signature verification on configuration data
- Restrict database access permissions
3. Memory Limits
Large numbers of certificates or oversized certificate chains will consume more memory.
Recommendations:
- Only load necessary certificate chains
- Avoid storing redundant intermediate certificates in Collection
- Release Collection that is no longer needed in time
Comparison with Other Modes
| Feature | TlsCertFile | TlsCertSubject | TlsCertMemory |
|---|---|---|---|
| Certificate Source | Disk files | Windows Certificate Store | Memory Collection |
| Deployment Convenience | File distribution | System import | Embed/Dynamic load |
| Certificate Update | Replace file | Renew to store | Reload |
| Private Key Protection | File system permissions | OS protection | Process memory |
| Runtime Generation | Not supported | Not supported | Supported |
| ACME Auto Issuance | Needs disk write | Needs import | Native support |
| Resource Embedding | Not supported | Not supported | Supported |
| Deployment Complexity | Low | Medium | High |
| Use Case | Production deployment | Enterprise shared | Dynamic/Embedded |
Certificate Source Priority
In cTlsSocket.InitServerTls, detection priority of three certificate sources:
- Memory Collection (
Certificates+PrivateKey) — Highest priority - Certificate File (
CertFile) - Windows Certificate Store (
CertSubject) — Lowest priority
If multiple sources are passed simultaneously, only the highest priority one takes effect.
FAQ
1. PEM Format Error
LastError: Certificate file does not exist or format errorSolution: Ensure each element in Collection is a complete PEM block, containing -----BEGIN...----- and -----END...----- markers.
2. Certificate and Private Key Mismatch
TLS handshake failedSolution: Ensure certificate and private key are paired. Can verify with OpenSSL:
openssl x509 -noout -modulus -in cert.pem | openssl md5
openssl rsa -noout -modulus -in key.pem | openssl md5
# Two MD5 values should be identical3. Certificate Order Error
Client reports incomplete certificate chainSolution: First element in Certificates collection must be server certificate (leaf certificate), followed by intermediate certificates.
4. Empty Collection
InitServerTls skips memory certificate, attempts other sourcesSolution: Ensure Certificates.Count > 0 and PrivateKey.Count > 0, otherwise underlying layer will skip memory mode.
Related Documentation
- TLS Certificate Configuration Overview
- Certificate File Mode
- Windows Certificate Store Mode
- cHttpServer TLS Support
- cWinsock TLS Support
- cWebSocket TLS Support
Last Updated: 2026-06-09