Skip to content

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

vb
Public Function TlsCertMemory( _
    ByVal Certificates As Collection, _
    ByVal PrivateKey As Collection, _
    Optional ByVal AlpnProtocols As String = "...") As <ComponentType>

Parameters

ParameterTypeRequiredDescription
CertificatesCollectionYesCertificate chain collection, each element is a PEM format certificate text
PrivateKeyCollectionYesPrivate key collection, each element is a PEM format private key text
AlpnProtocolsStringNoALPN protocol negotiation. Default values vary by component
ComponentAlpnProtocols 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:

vb
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:

vb
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.

vb
' 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 443

Advantages:

  • 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.

vb
' 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 443

Advantages:

  • 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.

vb
' 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 443

4. Testing Scenarios

Program self-signs temporary certificates for development and testing.

vb
' 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 443

5. Load from File to Memory

Read file contents into Collection, implement lazy loading or cache control.

vb
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 Function

Usage Examples by Component

cHttpServer (HTTPS)

vb
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 443

cWinsock (TLS TCP Server)

vb
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 443

cWebSocketServer (wss://)

vb
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 443

PEM 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

vb
' cTlsSocket.InitServerTls internal
If pvCollectionCount(Certificates) > 0 And pvCollectionCount(PrivateKey) > 0 Then
    Set cCerts = Certificates
    Set cPrivKey = PrivateKey
    GoTo StartTls
End If
TlsCertMemory(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
vb
' Clear after use
Set certs = Nothing
Set pkeys = Nothing

2. 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

FeatureTlsCertFileTlsCertSubjectTlsCertMemory
Certificate SourceDisk filesWindows Certificate StoreMemory Collection
Deployment ConvenienceFile distributionSystem importEmbed/Dynamic load
Certificate UpdateReplace fileRenew to storeReload
Private Key ProtectionFile system permissionsOS protectionProcess memory
Runtime GenerationNot supportedNot supportedSupported
ACME Auto IssuanceNeeds disk writeNeeds importNative support
Resource EmbeddingNot supportedNot supportedSupported
Deployment ComplexityLowMediumHigh
Use CaseProduction deploymentEnterprise sharedDynamic/Embedded

Certificate Source Priority

In cTlsSocket.InitServerTls, detection priority of three certificate sources:

  1. Memory Collection (Certificates + PrivateKey) — Highest priority
  2. Certificate File (CertFile)
  3. 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 error

Solution: Ensure each element in Collection is a complete PEM block, containing -----BEGIN...----- and -----END...----- markers.

2. Certificate and Private Key Mismatch

TLS handshake failed

Solution: Ensure certificate and private key are paired. Can verify with OpenSSL:

bash
openssl x509 -noout -modulus -in cert.pem | openssl md5
openssl rsa -noout -modulus -in key.pem | openssl md5
# Two MD5 values should be identical

3. Certificate Order Error

Client reports incomplete certificate chain

Solution: First element in Certificates collection must be server certificate (leaf certificate), followed by intermediate certificates.

4. Empty Collection

InitServerTls skips memory certificate, attempts other sources

Solution: Ensure Certificates.Count > 0 and PrivateKey.Count > 0, otherwise underlying layer will skip memory mode.


Last Updated: 2026-06-09

VB6 and LOGO copyright of Microsoft Corporation