Question
· Mar 8, 2019

Quick way to check if an SSL/TLS configuration name is valid?

Is there a quick way to see if an SSL/TLS configuration name is valid, short of switching over to %SYS and checking Security.SSLConfigs:Exists?

Discussion (7)2
Log in or sign up to continue

Hi Robert.

Exactly.

Programmatically Managing Roles:

This command can only be invoked either from a routine that is part of the CACHESYS database or if the current privileges held include Write permission for the CACHESYS database (%DB_CACHESYS:W).

Note that setting $ROLES only alters a process’s added roles, not its login roles.

There is a third way, but I specifically did not publish it.

You can try to write to a TCP device with SSL. Doesn't require additional permissions:

ClassMethod Exists(ssl As %String) As %Boolean
{
	#dim exists As %Boolean = $$$YES
	set host = "google.com"
	set port = 443
	set timeout = 1
	
	set io = $io
	
	set device = "|TCP|" _ ##class(%PopulateUtils).Integer(5000, 10000)
	try {
		open device:(host:port:/SSL=ssl):timeout	
		use device
		
		// real check
		write "GET /" _ $c(10),*-3
		// real check - end
		
		// should be HTTP/1.0 200 OK but we don't really care
		//read response:timeout
		//write response
	} catch ex {
		set exists = $$$NO
	}
	
	use io
	
	close device
	
	
	quit exists
}

It's slower than direct global check but if you want to do it rarely,  I think it could be okay. Doesn't require additional permissions.

Code to compare times:


ClassMethod ExistGlobal(ssl) [ CodeMode = expression ]
{
$d(^|"%SYS"|SYS("Security","SSLConfigsD",ssl))#10
}

/// do ##class().Compare()
ClassMethod Compare(count = 1, ssl = "GitHub")
{
    Write "Iterations: ", count,!
    Write "Config exists: ", ..Exists(ssl),!

    set start = $zh
    for i=1:1:count {
        set exists = ..Exists(ssl)
    }
    
    set end = $zh
    
    set time = end - start
    Write "Device check: ", time,!
    
    set start = $zh
    for i=1:1:count {
        set exists = ..ExistGlobal(ssl)
    }
    
    set end = $zh
    
    set time2 = end - start
    write "Global check: ", time2,!
}

Results:

Iterations: 1
Config exists: 1
Device check: .054983
Global check: .000032

Iterations: 1
Config exists: 0
Device check: .017351
Global check: .00001

Iterations: 50
Config exists: 1
Device check: 2.804497
Global check: .000097

Iterations: 50
Config exists: 0
Device check: .906424
Global check: .000078

Below are two ways without additional permissions on %DB_CACHESYS:

  #include %systemInclude
  n
  try{

    sslName="Test"

    "1) GetSSLConfigList^%SYS.SECURITY1(.SSLConfigs)",!!
    w $$Test1(sslName)
    
    !!,"2) $$ListSSLConfigs^%SYS.SECURITY(Client/Server)",!!
    w $$Test2(sslName)
    
  }catch(ex){
    "Error "ex.DisplayString(),!
  }

Test1(ssl) {
  GetSSLConfigList^%SYS.SECURITY1(.SSLConfigs)
  i=1:1:SSLConfigs return:SSLConfigs(i)=ssl $$$YES
  q $$$NO
}

Test2(ssl) {
  ''$lf($lfs($$ListSSLConfigs^%SYS.SECURITY("Client")_","_
               $$ListSSLConfigs^%SYS.SECURITY("Server"))
          ,ssl)
}