Get Cipher used in a SSL Connection

Discussions related to HTTPAPI (An HTTP Client Package for RPG programming.) http://www.scottklement.com/httpapi/
einschan
Posts: 9
Joined: Thu Jul 07, 2022 4:36 am

Get Cipher used in a SSL Connection

Post by einschan »

Hi,

After calling below successfully.
callp SSL_debug_cert_info(wkSSLh : GSK_PARTNER_CERT_INFO )
callp http_dmsg('Protocol Used: ' SSL_protocol(wkSSLh: *OMIT))

I try to get cipher in wkSSLh by
D wwBufferPtr S *
D wwBufSize s 10I 0

C Eval rc = gsk_attribute_get_buffer(wkSSLh:
GSK_CONNECT_SEC_TYPE:
wwBufferPtr:
wwBufSize)
But rc return 6010 ([GSK_IBMI_ERROR_INVALID_POINTER], The numValue pointer is not valid.)

GSKSSL_H
=================================
D gsk_attribute_get_buffer...
D PR 10I 0 extproc('gsk_attribute_get_buffer')
D my_gsk_handle like(gsk_handle) value
D bufID like(GSK_BUF_ID) value
D buffer * value
D bufSize 10I 0
=================================

Any help?

Regards
Scott Klement
Site Admin
Posts: 636
Joined: Sun Jul 04, 2021 5:12 am

Re: Get Cipher used in a SSL Connection

Post by Scott Klement »

The 'buffer' parameter (the third parameter) needs to be a pointer to a pointer. The error message seems to be saying that you aren't passing a valid pointer-to-a-pointer.
einschan
Posts: 9
Joined: Thu Jul 07, 2022 4:36 am

Re: Get Cipher used in a SSL Connection

Post by einschan »

Thank, but I just follow your coding in LIBHTTP145/QRPGLESRC/GSKSSL_H
=================================
D gsk_attribute_get_buffer...
D PR 10I 0 extproc('gsk_attribute_get_buffer')
D my_gsk_handle like(gsk_handle) value
D bufID like(GSK_BUF_ID) value
D buffer * value
D bufSize 10I 0
=================================

And I already know that is const char **, as in
https://www.ibm.com/docs/en/zos/2.2.0?t ... get-buffer
========================================================================
#include <gskssl.h>
gsk_status gsk_attribute_get_buffer (
gsk_handle ssl_handle,
GSK_BUF_ID buffer_id,
const char ** buffer_value,
int * buffer_length)
========================================================================

And according your https://www.scottklement.com/rpg/socktut/tutorial.pdf, page 7,
"char **s" is "It is a pointer to an array. That array
is an array of pointers. Each element of that array points to an alphanumeric string"
=========================================================================
struct servent {
char *s_name;
char **s_aliases;
int s_port;
char *s_proto
};
...
....
can be defined in RPG D-spec as
DName+++++++++++ETDsFrom+++To/L+++IDc.Keywords+++++++++++++++++++++++
D p_servent S *
D servent DS based(p_servent)
D s_name *
D s_aliases *
D s_port 10I 0
D s_proto *
=========================================================================
Is my understanding is correct ?

Regards
Scott Klement
Site Admin
Posts: 636
Joined: Sun Jul 04, 2021 5:12 am

Re: Get Cipher used in a SSL Connection

Post by Scott Klement »

Hello,

I'm not sure that I understand your point, or why you are showing me the "servent" (services entry) data structure.

Can you show me the RPG code for the variable you are passing in the 'buffer' parameter, please? All you've provided so far is the prototype. I need everything related to that parameter, it's definition, how you are using it, and so forth.
einschan
Posts: 9
Joined: Thu Jul 07, 2022 4:36 am

Re: Get Cipher used in a SSL Connection

Post by einschan »

Hi,

Showing "servent" as reference for, how I learn to define a pointer of pointer, after reading "servent"
"const char ** aliases" in C can be defined as "D s aliases *" in RPG

As in https://www.ibm.com/docs/en/i/7.2?topic ... buffer.htm, I need to define "const char ** buffer" written in C.
Then I follow the same way in defining "servent", and use "D s buffer *" in RPG
i.e. defining it as below "D wwBufferPtr S * "


In my RPG, I copy from "CommSSL_Upgrade..." in LIBHTTP145/QRPGLESRC/COMMSSLR4, to make my own "UpgradeSock"
P *+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
P UpgradeSock B export
D UpgradeSock PI like(gsk_handle)
D peSSLEnv like(gsk_handle) value
D peSD 10I 0 value
D peEndHost * value options(*string)
D peTimeout 10P 3 value
*
D wksslh S like(gsk_handle)
D rc s 10I 0
D wwValCode s 10I 0
D wwSniHost s 256a inz(*blanks)
D wwBufferPtr S *
D wwBufSize s 10I 0
....
c callp http_dmsg('Protocol Used: ' +
c SSL_protocol(wwSSLh: *OMIT))
* Get Cipher
C Eval wwBufferPtr = *NULL
c Eval rc = gsk_attribute_get_buffer(wkSSLh:
c GSK_CONNECT_SEC_TYPE:
c wwBufferPtr:
c wwBufSize)

The problem is how can I define the "const char ** buffer" written in C, correctly in RPG, as you mentioned before

Regards
Scott Klement
Site Admin
Posts: 636
Joined: Sun Jul 04, 2021 5:12 am

Re: Get Cipher used in a SSL Connection

Post by Scott Klement »

You appear to be passing wwSlh, which as far as I can tell is set to *null -- so that won't work.

Also, with the way that prototype is written, you'll need to pass %addr(wwBufferPtr) rather than passing wwBufferPtr directly.

Also -- why are you still using fixed format for new code?
einschan
Posts: 9
Joined: Thu Jul 07, 2022 4:36 am

Re: Get Cipher used in a SSL Connection

Post by einschan »

Hi

Thanks for your quick respond
You appear to be passing wwSlh, which as far as I can tell is set to *null -- so that won't work.
-> it is fine, you may refer to your "CommSSL_upgrade..." in COMMSSLR4.
-> I just add the "code for cipher" right after call SSL_protocol() in your coding

Also, with the way that prototype is written, you'll need to pass %addr(wwBufferPtr) rather than passing wwBufferPtr directly.
-> Let me try and report the result,
-> I just follow the source in D-spec about "PR" in "gsk_attribute_get_buffer..." in source
LIBHTTP145/QRPGLESRC/GSKSSL_H
=================================
D gsk_attribute_get_buffer...
D PR 10I 0 extproc('gsk_attribute_get_buffer')
D my_gsk_handle like(gsk_handle) value
D bufID like(GSK_BUF_ID) value
D buffer * value
D bufSize 10I 0
=================================

Also -- why are you still using fixed format for new code?
-> That is not up to me

Regards
einschan
Posts: 9
Joined: Thu Jul 07, 2022 4:36 am

Re: Get Cipher used in a SSL Connection

Post by einschan »

Hi

I just have a trial, but fail.

After changed the parameter wwBufferPtr to %Addr(wwBufferPtr), rc is 0 instead of 6010 ([GSK_IBMI_ERROR_INVALID_POINTER].
But wwBuffer is *NULL and wwBufSize = 0, that is, cannot get the cipher.

<-- Detail refer to "CommSSL_upgrade..." in COMMSSLR4.-->

* adding 2 parameters, wwBufferPtr and wwBufSize, in "CommSSL_upgrade..."
...
D wwBufferPtr S *
D wwBufSize s 10I 0
...
c callp http_dmsg('Protocol Used: ' +
c SSL_protocol(wwSSLh: *OMIT))
* When debug is turned on, the protocol (and also server cert) is written to a IFS file
* But just cannot get the Cipher from "wwSSLh"
*
* Get Cipher
C Eval wwBufferPtr = *NULL
c Eval rc = gsk_attribute_get_buffer(wkSSLh:
c GSK_CONNECT_SEC_TYPE:
c %addr(wwBufferPtr):
c wwBufSize)
..
Please help

Regards
Scott Klement
Site Admin
Posts: 636
Joined: Sun Jul 04, 2021 5:12 am

Re: Get Cipher used in a SSL Connection

Post by Scott Klement »

Here is the documentation for the API:
https://www.ibm.com/docs/en/i/7.4?topic ... buffer.htm
GSK_CONNECT_SEC_TYPE (208) - buffer points to a string containing "SSLV3", "TLSV1", "TLSV11", "TLSV12", or "TLSV13" depending on what was actually negotiated for use by the secure session. For compatibility with previous releases, "TLSV1" is returned for TLS Version 1.0 instead of "TLSV10".
Note that GSK_CONNECT_SEC_TYPE does not even attempt to retrieve cipher information, it only retrieves the strings above.

When you get an rc = 0, your wwBufferPtr should be pointing to the area of memory that contains that string, and wwBufSize should contain the number of bytes to read from that location.

If it is not working for you, you need to troubleshoot/debug and fix your code to make it work properly.

Since this is a part of your custom code -- not a part of my software, I'm limited in how much I can help you.
Scott Klement
Site Admin
Posts: 636
Joined: Sun Jul 04, 2021 5:12 am

Re: Get Cipher used in a SSL Connection

Post by Scott Klement »

As a quick test, I added this code into commsslr4:

Code: Select all

     D wwBufferPtr     s               *
     D wwBufferLen     s             10i 0
     D wwBufferData    s           1000a   based(wwBufferPtr)
     D wwSecType       s             52a   varying
     D wwCipher        s             52a   varying
      :
      :
     c                   eval      rc = gsk_attribute_get_buffer(wwSslh
     c                                  : GSK_CONNECT_SEC_TYPE
     c                                  : %addr(wwBufferPtr)
     c                                  : wwBufferLen)
     c                   if        rc = 0 and wwBufferLen > 0
     c                   eval      wwSecType = %subst( wwBufferData
     c                                               : 1
     c                                               : wwBufferLen)
     c                   dsply                   wwSecType
     c                   endif

     c                   eval      rc = gsk_attribute_get_buffer(wwSslh
     c                                  : GSK_CONNECT_CIPHER_SPEC_EX
     c                                  : %addr(wwBufferPtr)
     c                                  : wwBufferLen)
     c                   if        rc = 0 and wwBufferLen > 0
     c                   eval      wwCipher = %subst( wwBufferData
     c                                              : 1
     c                                              : wwBufferLen)
     c                   dsply                   wwCipher
     c                   endif
This worked perfectly for me -- I did not get any errors, and it displayed the security type and cipher spec on my display.
Post Reply