Q: Finding a way to load multiple ssl certificates(2 RSA) in memory(SSL Context)? OpenSSL Trying to load multiple ssl certificates in memory. I tried to code from documentation but failed as documentation seen little hard for me to understand. Seeking help from stackoverflow.
I am finding a way, that both certificates can work simultaneously at the time.
Certificates that I have to load in memory are Symantec and Zuul(.pem format).
Both symantec.pem and zuul.pem file are password protected and it contains (one certificate and one private key).
Below code loading symanctic certificate only.
Openssl version : OpenSSL 1.1.1g FIPS  21 Apr 2020
    if(server_ctx==NULL)
    {
      /* Global system initialization*/
      SSL_library_init();
      SSL_load_error_strings();
    }

    meth=TLS_server_method();

    if(status == true)
    {
        server_ctx=SSL_CTX_new(meth);

        if(server_ctx != NULL)
        {
            if((strcmp(protocol_current_version,"Y") == 0) || (strcmp(protocol_current_version,"y") == 0))
            {
                SSL_CTX_set_min_proto_version(server_ctx, TLS1_VERSION);
            }
            else if((strcmp(protocol_current_version,"N") == 0) || (strcmp(protocol_current_version,"n") == 0))
            {
                SSL_CTX_set_min_proto_version(server_ctx, TLS1_2_VERSION);
            }
        }
    }

    /* Load our keys and certificates*/
    if(!(SSL_CTX_use_certificate_file(server_ctx,keyfile,SSL_FILETYPE_PEM)))
    { 
        status = false; 
        LOG(LEVEL1,"Error!!! Couldn't read certificate file: %s",ERR_error_string(ERR_get_error(),NULL));    
    }


    if(status==true)
    {SSL_CTX_set_default_passwd_cb(server_ctx,password_cb);}
    
    if(status==true)
    {
        if(!(SSL_CTX_use_PrivateKey_file(server_ctx,keyfile,SSL_FILETYPE_PEM)))
        {       
        LOG(LEVEL1,"Error!!! Couldn't read key file: %s",ERR_error_string(ERR_get_error(),NULL));    
        status = false;
        }
    }

    /* Load the CAs we trust*/

    if(status==true)
    {
        if(!(SSL_CTX_load_verify_locations(server_ctx,ca_list,0)))
        {           
        LOG(LEVEL1,"Error!!! Couldn't read CA_LIST: %s",ERR_error_string(ERR_get_error(),NULL));
        status=false;
        }
    }

    //Force Mutual authentication if verify_ssl_peer is set
    if(verify_ssl_peer)
    {
        SSL_CTX_set_verify(server_ctx, SSL_VERIFY_PEER|SSL_VERIFY_CLIENT_ONCE|SSL_VERIFY_FAIL_IF_NO_PEER_CERT,NULL);
    }
    

    SSL_CTX_set_verify_depth(server_ctx,1);

    //Set AUTO MODE RETRY Flag, Will not bother application till data is completely read
    SSL_CTX_set_mode(server_ctx,SSL_MODE_AUTO_RETRY);   

    //Set the list of supported cipher suites. Typically used to force only AES128 or AES256 bit encryption:
    if(status==true)
    {
        //Force the cipher is verify_ssl_cipher is set
        if(verify_ssl_cipher)
        {

        if(cipher_list==NULL)
        {
            LOG(LEVEL1,"[%s]: Error!!! Cipher list is set to NULL, will not initialize",__FUNCTION__);
            status = false;
        }
        else
        {
        
        if(!SSL_CTX_set_cipher_list(server_ctx,cipher_list))
        {LOG(LEVEL1,"Error!!! Failed to set cipher_list for ctx: %s",ERR_error_string(ERR_get_error(),NULL));}

        }

        }
    }   

    if(status==true)
    {
    
    /* Load randomness */
    if(!(RAND_load_file(random_file,1024*1024)))
      {
        LOG(LEVEL1,"Error!!! Load randomness failed:%s",ERR_error_string(ERR_get_error(),NULL));
        status=false;
      }
    }

    if(status==true)
    {
        long opts = SSL_CTX_get_options(server_ctx);
        opts = SSL_CTX_set_options(server_ctx,SSL_OP_ALL|opts);
        
        LOG(LEVEL1,"SSl Server CTX Options set:%04x",opts);                     
    }



A: A possible solution could be to use the Server Name Indication in the TLS Client Hello: Zuul and Symantec Clients could set the TLS SNI field differently so that your Server could elaborate it to select the proper certificate chain.
In details, your server shall first setup one SSL Context for Zuul and another one for Symantec with the right private key and certificate chain, then the servername callback shall be set in each context.
For example, to set the server name callback for your symantec context:
SSL_CTX_set_tlsext_servername_callback(symantec_context, serverNameCallbackHandler);

You can set an argument that will be handled by serverNameCallbackHandler function the for this SSL_CTX:
SSL_CTX_set_tlsext_servername_arg(symantec_context, &your_data);

Then you shall implement the callback that will be invoked durint the TLS handshake. For example:
static int serverNameCallbackHandler(SSL *ssl, int *ad, void *arg)
{
    MyData *data = (MyData *) arg;
    // ...
    const char *servername = SSL_get_servername(ssl, TLSEXT_NAMETYPE_host_name);

    if (servername)
    {
        //Select the proper context
        //...
        
        if (match_found)
        {
            SSL_CTX* ctx = symantec_context;
            SSL_CTX* v = SSL_set_SSL_CTX(ssl, ctx);
            if (v != ctx)
            {
                // Internal Error on ssl context switch!
                return SSL_TLSEXT_ERR_NOACK;
            }
        }
    }
    
    // NOTE: On Server name mismatch use the default context
    return SSL_TLSEXT_ERR_OK;
}

For information about how to handle the SNI on client side, I think that the opensource code of openssl command is very helpful.
Note that you can test your server with the openssl command:
openssl s_client -servername 'your sni name' -CAfile ./RootCA.pem -connect ip:port
