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!
This blog post describes how to set up your environment to sign load modules. I’ve documented Using code signing on z/OS
I hit various problems. The return code from the program signing function are documented here.
Create RACF profiles
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 specify 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 uses the default key in the keyring.
How to sign a load module
You sign a module at bind time, by specifying the binder options SIGN=YES.
I added SIGN=YES to the binder JCL
When it failed, there were messages like
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 00000098.
These are from the R_PgmSignVer (IRRSPS00): Program Sign and Verify callable service. See the return codes. The return codes in the messages are in hex; in the documentation they are in decimal. 0x98 is decimal 152. 152 is CA or signing certificate is expired or not yet active. This was true – my signing certificate had expired.
Create a certificate to sign load modules.
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.
One thought on “Signing load modules on z/OS”