I had a string CN=myserver,O=test,C=us in a certificate, which has been encoded
Offset : EBCDIC ASCII 00000000 : 302F310B 30090603 55040613 02757331 ................ 0/1.0...U....us1 00000010 : 0D300B06 0355040A 13047465 73743111 ................ .0...U....test1. 00000020 : 300F0603 55040313 086D7973 65727665 ........._`..... 0...U....myserve 00000030 : 72 . r
Where you can see bits of the string in ASCII on the right. How do I extract the string CN=myserver,O=test,C=us from this?
This format is used for Subjects and Issuers (and other types).
The hex string has an ASN.1 encoding. It usually starts with a 0x30. See here for a good introduction to ASN.1 encoding.
- 30 means this is a sequence
- 2f is the length of the data following
- etc
On z/OS you can use system ssl to decode this back to a printable string. You need two steps.
- Convert to internal format,
- Create the printable EBCDIC string from the internal format.
Step1 create internal format of the data
#pragma runopts(POSIX(ON)) #include <gskcms.h> #include <gskssl.h> void x509_to_string(char * pData, // pointer to the data int lData) // length of the data { x509_name X509; // internal format. int rc; gsk_buffer cert; // intermediate format if (lData == 0) { printf("no data"); return; } cert.length= lData; cert.data = pData ; // convert from 0x302F310B 30090603 to internal rc = gsk_decode_name( & cert, & X509); if ( rc != 0) { //use gsk_strerror(rc) to return a string. printf("\nInternal error:gsk_decode_name %s\n", gsk_strerror(rc)); return; }
Convert from internal format to an EBCDIC string.
char * pName ; // output value // convert from internal to CN=COLIN,C=GB rc = gsk_name_to_dn( &X509, &pName); // free the intermediate value regardless of rc gsk_free_name(&X509); if ( rc != 0) { printf("\nInternal error:gsk_name_dn %s\n", gsk_strerror(rc)); return; } printf("%s.",pName); //free the string gsk_free_string(pName); }
Convert from EBCDIC string to intermediate or certificate format.
There are the reverse functions.
- gsk_dn_to_name( pName, &X509);
- rc = gsk_encode_name( &X509, & cert);
Both C=GB,CN=colin and c=GB,cn=colin produce
00000000 : 301D310E 300C0603 55040313 05636F6C …………..?% 0.1.0…U….col 00000010 : 696E310B 30090603 55040613 024742 .>…………. in1.0…U….GB
JCL
I needed binder input options.
INCLUDE GSK(GSKCMS31) INCLUDE GSK(GSKSSL)
and JCL
//COMPILE EXEC PROC=EDCCB, // LIBPRFX=&LIBPRFX, // CPARM='OPTFILE(DD:SYSOPTF)', // BPARM='SIZE=(900K,124K),RENT,LIST,RMODE=ANY,AMODE=31,AC=1' //COMPILE.SYSLIB DD DISP=SHR,DSN=&LIBPRFX..SCEEH.SYS.H // DD DISP=SHR,DSN=&LIBPRFX..SCEEH.H // DD DISP=SHR,DSN=SYS1.SIEAHDR.H ... //COMPILE.SYSIN DD DSN=&SOURCE(&PROG),DISP=SHR //COMPILE.SYS DD DISP=SHR,DSN=&LIBPRFX..SCEEH.SYS.H //COMPILE.SYSOPTF DD DISP=SHR,DSN=&SOURCE(CCOPTS) //* //* Bind the module //* //BIND.SYSLMOD DD DISP=SHR,DSN=&LOADLIB(&PROG) //BIND.SYSLIB DD DISP=SHR,DSN=&LIBPRFX..SCEELKED // DD DISP=SHR,DSN=SYS1.SIEALNKE //BIND.GSK DD DISP=SHR,DSN=SYS1.SIEALNKE ... //BIND.SYSIN DD DISP=SHR,DSN=&SOURCE(&BINDOPTS)
Where the gskcms.h and gskssl.h are in DSN=SYS1.SIEAHDR.H or /usr/include/, and the binder stubs are in DSN=SYS1.SIEALNKE.
Hello! I was deep in one of your posts on mainframe commands and had to take a moment to see what else you have documented here. Wow, what a treasure! This is a goldmine of knowledge. No one would appreciate it but another old school mainframer. So I came to the latest post to drop a line of thanks. I appreciate your knowledge and your ability to sort it all out so that it’s helpful to others. This is now my new go to site for help when I find myself struggling to remember a subsystem or command.
LikeLike
Thank you – it is always good to hear the site is useful.
LikeLike