Using code signing on z/OS

There is an IBM document Task roadmap for program signing and signature verification, this provides some of the information, and some of the information is wrong!

I’ve documented Signing load modules on z/OS.

I hit various problems. The return code from the program signing function are documented here.

Using signed modules on your system

You have been sent some modules which have been signed, and you want to user the signature verification on these modules.

One-of system wide setup

Define the system wide keyring

For the validation of signed modules there is one system wide key ring. It needs to have the signing certificates (or the CA certificates) for all of the modules being used.

RACDCERT ADDRING(VERIFY) ID(COLIN ) 

* now the profile
RDEFINE RDATALIB COLIN.VERIFY.LST UACC(NONE)
PERMIT COLIN.VERIFY.LST CLASS(RDATALIB) ID(COLIN ) ACCESS(UPDATE)
SETROPTS RACLIST(RDATALIB) REFRESH

Connect the IBM CA to the keyring

You need to connect the IBM Provided Certificate authority, to be able to verify the signature of IBM provided modules. See Listing of RACF supplied certificates.

RACDCERT ID(COLIN )CONNECT(RING(VERIFY) - 
CERTAUTH -
LABEL('STG Code Signing CA - G2')

RACDCERT LISTRING(VERIFY) ID(COLIN )

Note the lower case name.

Tell the certificate certificate facility which key ring to use.

 RDEFINE FACILITY IRR.PROGRAM.SIGNATURE.VERIFICATION  - 
APPLDATA('COLIN/VERIFY')

This ring has the certificates needed to verify.

Define the program that does the signature validation.

RDEFINE PROGRAM IRRPVERS ADDMEM('SYS1.SIEALNKE'//NOPADCHK) UACC(READ)- 
SIGVER(SIGREQUIRED(YES) FAILLOAD(ANYBAD) SIGAUDIT(ANYBAD))

Run the IRRVELD job

I had to run this when setting up for the first time. When I next IPLed, I did not need to run it. I think that RACF checks to see if the above RACF profile exists – if so – loads the code.

See here.

//IRRVERLD JOB                        
//IRRVERLD EXEC PGM=IRRVERLD

When successful, this starts and ends with return code 0 and

ICH448I RACF program signature verification function is loaded. Program signature verification is available on this system.

Define your programs that need validation

RDEFINE PROGRAM ZZZDATA  ADDMEM('COLIN.ZWIRESHA.LOAD'//NOPADCHK) - 
UACC(READ) -
SIGVER(SIGREQUIRED(YES) FAILLOAD(ANYBAD) SIGAUDIT(ANYBAD))

SETROPTS WHEN(PROGRAM) REFRESH

Where my program is called ZZZDATA and it is loaded from COLIN.ZWIRESHA.LOAD. The definition SIGVER(SIGREQUIRED(YES) FAILLOAD(ANYBAD) SIGAUDIT(ANYBAD)) says that signature is required, and if verification fails do not load the module, and write an audit record.

Each userid (or group) needs a RACF profile to specify which keyring to use to sign the programs

If you want to do IPL data signing for Validated Boot for z/OS you need the profile IRR.PROGRAM.V2.SIGNING…..

If you want to validate a general program you need the profile IRR.PROGRAM.SIGNING….

Where you can specif userid, group, or group and userid.

  • IRR.PROGRAM.SIGNING.userid
  • IRR.PROGRAM.SIGNING.goup
  • IRR.PROGRAM.SIGNING.group.user
                              
RDELETE FACILITY IRR.PROGRAM.SIGNING.COLIN
RDEFINE FACILITY IRR.PROGRAM.SIGNING.COLIN -
APPLDATA('SHA256 COLIN/SIGNING')
PERMIT IRR.PROGRAM.SIGNING.COLIN CLASS(FACILITY) -
ID(COLIN) ACCESS(CONTROL)
SETROPTS RACLIST(FACILITY) refresh

This says for userid COLIN use SHA256 and keyring COLIN/SIGNING. It will use the default key in the keyring.

You sign a module at bind time, by specifying the binder options SIGN=YES.

I added sign=yes to the binder JCL

Create a certificate to sign it

RACDCERT ID(COLIN) GENCERT -                                 
SUBJECTSDN(CN('10.1.1.2') -
O('SIGNER521') -
OU('SSS')) -
ALTNAME(IP(10.1.1.2))-
SIZE(2048) -
NOTAFTER( DATE(2026-04-22) TIME(15:22:00) ) -
KEYUSAGE(HANDSHAKE DOCSIGN) -
SIGNWITH (CERTAUTH LABEL('SIGNCA')) -
WITHLABEL('SIGNER521')

RACDCERT id(COLIN) ALTER(LABEL('SIGNER521'))TRUST

SETROPTS RACLIST(DIGTCERT) REFRESH
RACDCERT ID(COLIN )CONNECT(RING(SIGNING) -
ID(COLIN) -
DEFAULT -
LABEL('SIGNER521') )

It seems to need KEYUSAGE HANDSHAKE and DOCSIGN.

It needed the default RSA size 2048. It did not work with an ECC algorithm.

It needs to be the default in the keyring.

Execute the program

When you come to execute the signed program, the system uses the keyring defined in the

IRR.PROGRAM.SIGNATURE.VERIFICATION CLASS(FACILITY) profile. I believe this has the certificates needed to verify the programs signature.

I used keyring COLIN/VERIFY.

IEW2494E 9116 A PROBLEM WAS ENCOUNTERED WITH THE SETUP OF THE DIGITAL CERTIFICATES REQUIRED FOR PROGRAM SIGNING. RACF RETURNED SAF RETURN CODE 8 RACF RETURN CODE 8 RACF REASON CODE 00000070.

R_PgmSign 70 Ver Key ring or token does not exist or does not contain a default certificate.

xhttps://www.ibm.com/support/pages/apar/OA49085