Hi,
Would liketo know if anyone have been succeeded using Qc3VerifySignature to verifya JWT?
I have refereedto both of the below program but still no success:
https://github.com/pabloto/ILEastic/blob/master/plugins/jwt/jwt_rsa/ujwt01r.sqlrpgle
https://github.com/pabloto/ILEastic/blob/master/plugins/jwt/jwt.rpgle
With referenceto above code, I have made up my own program as below to test and make it workbut never succeeded.
For testingpurpose, I have hard coded my Token and Key in the program but
My suspectis the way I am sending the Public Key to 'Qc3VerifySignature'.
Any helpwould be much appreciated.
Thanks,Mahesh
Code:
**FREE
ctl-opt dftactgrp(*no) bnddir('BASE64') option(*srcstmt: *nodebugio);
/copy base64_h
// Entry Parameters
dcl-pi *n ;
token like(jwt_token_t) const;
success like(jwt_success_t) const;
end-pi;
dcl-pr verifySignature ExtProc('Qc3VerifySignature');
// Signature Details
signature Char(4096) ccsid(*hex) const; // fingerprInt
signatureLen Int(10) const;
// Original Data Details
Data Char(8000) ccsid(*utf8) const; // original data
Datalen Int(10) const;
Dataformat Char(8) const; //DATA0100 = data directly
// encryption algo -> RSA
Algo char(32767) options(*varsize :*omit);
AlgoFormat Char(8) const; //ALGD0400 = key parameters
Key char(32767) options(*varsize :*omit) const;
KeyFormat Char(8) const; //KEYD0600 = use key from PEM
CSPcertificate Char(1) const; // 1=Soft,2=hard(fill in DEVICE),0=
CSPDEVICE Char(10) const; // blank if no co-processor
ApiError likeds(ApiError);
end-pr;
dcl-ds payload_json qualified;
iss char(256);
aud char(256);
exp zoned(10:0);
nbf zoned(10:0);
client_id char(100);
scope char(10);
end-ds;
dcl-ds header_json qualified;
typ char(10);
alg char(10);
x5t char(50);
kid char(50);
end-ds;
dcl-ds ApiError qualified inz;
BytPrv int(10) inz(%Size(ApiError));
BytAvl int(10) inz(0);
MsgId char(7);
*n char(1);
MsgDta char(128);
end-ds ApiError;
dcl-ds algoDS qualified;
PublicKeyAlgorithm int(10);
PKABlockFormat char(1);
Reserved char(3) inz(X'000000');
SigningHashAlgorithm int(10);
End-Ds;
dcl-ds KeyD0200 qualified;
KeyType int(10);
KeyStringLen int(10);
KeyFormat char(1);
Reserved char(3);
KeyString char(2400) ccsid(*hex);
end-ds KeyD0200;
// Templates
dcl-s jwt_token_t varchar(10000) ccsid(*utf8) template;
dcl-s valid ind inz(*off);
dcl-s jwt_token like(jwt_token_t);
dcl-s header like(jwt_token_t);
dcl-s payload like(jwt_token_t);
dcl-s datatocheck like(jwt_token_t);
dcl-s json pointer;
dcl-s jwt_success_t Ind Inz(*Off);
dcl-s UTF8_PERIOD char(1) inz('.') ccsid(*utf8);
dcl-s data like(jwt_token_t) ccsid(*utf8);
dcl-s Signature char(1000) ccsid(*hex);
dcl-s SignatureLen int(10);
dcl-s utfcomma Char(1) inz('.');
dcl-s payloadPos int(10);
dcl-s publickey Char(5000) ccsid(*hex);
dcl-c LF x'25';
dcl-s DataLen Int(10);
dcl-c DATA0100_FMT 'DATA0100';
dcl-c KEYD0200_FMT 'KEYD0200';
dcl-c ALGD0400_FMT 'ALGD0400';
dcl-c ANYCSP '0';
dcl-c RSAPUBLICKEYALGORITHM 50;
dcl-c PKCS1 '1';
dcl-c BERSTRING '1';
dcl-s JwtArray like(jwt_token) dim(3);
monitor;
jwt_token =
'eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsIng1dCI6Im1LanBqd' +
'removed some part of the token for security purpose ' +
'RZMHduOWlXZUdBY0FCcjl5ZyJ9.eyJpc3MiOiJodHRwczovL3N0d2' +
'removed some part of the token for security purpose ' +
'4mfNSqc7R8yWSVO5HfslVIt1nuB-p_AZqbiE4DGqz4v-MmHOgZOIG' +
'removed some part of the token for security purpose’;
publickey =
'-----BEGIN PUBLIC KEY-----' + LF
+ 'I Have Removed the public Key here so that it is not' + LF
+ 'exposed to outside world.removed removed removed rem' + LF
+ 'ZXIgTWFuY2hlc3RlcjEQMA4GA1UEBxMHU2FsZm9yZDEYMBYGA1UE' + LF
+ 'ChMPU2VjdGlnbyBMaW1pdGVkMSQwIgYDVQQDExtTZWN0aWdvIFJT' + LF
+ 'QSBDb2RlIFNpZ25pbmcgQ0EwHhcNMTkwNTAyMDAwMDAwWhcNMjEw' + LF
+ 'I Have Removed the public Key here so that it is not' + LF
+ 'exposed to outside world.removed removed removed rem' + LF
+ 'NSA0MTESMBAGA1UECAwJU3RvY2tob2xtMRIwEAYDVQQHDAlTdG9j' + LF
+ 'a2hvbG0xHjAcBgNVBAkMFVRlZ2VsdWRkc3bDpGdlbiAxMS0xMzEm' + LF
+ 'KhMt0rr5UmQmHeGp9OE8sgsa9BcxBdAcb1GNA+x7BodUjH51kLXo' + LF
+ 'I Have Removed the public Key here so that it is not' + LF
+ 'exposed to outside world.removed removed removed rem' + LF
+ '24LQrLkX3p4sA17B01uAW3mo4YbV0LbodjmQvg==' + LF
+ '-----END PUBLIC KEY-----';
JwtArray = %split(jwt_token :UTF8_PERIOD);
// Get the header information
header = decodeBase64( JwtArray(1) );
data-into header_json
%DATA(header :'case=convert allowmissing=yes allowextra=yes')
%PARSER('YAJLINTO');
// Get the payload information
payload = decodeBase64( JwtArray(2) );
data-into payload_json
%DATA(payload :'case=convert allowmissing=yes allowextra=yes')
%PARSER('YAJLINTO');
// Get the Signature information
Signature = decodeBase64( JwtArray(3) );
SignatureLen = %len(%trim(Signature));
datatocheck = JwtArray(1) + '.' +JwtArray(2);
dataLen = %len(%trimr(datatocheck));
algoDS = *allx'00';
algoDS.PublicKeyAlgorithm = RSAPUBLICKEYALGORITHM;
algoDS.PKABlockFormat = PKCS1;
// 3=SHA256 5=SHA512
algoDS.SigningHashAlgorithm = 3;
KeyD0200 = *allx'00';
KeyD0200.KeyType = RSAPUBLICKEYALGORITHM;
KeyD0200.KeyFormat = BERSTRING;
KeyD0200.KeyString = PublicKey;
KeyD0200.KeyStringLen = %len(%trim(PublicKey));
// IBM Crypto API.
// Qc3VerifySignature will send ESCAPE message if in case it fails
verifySignature( signature
: signatureLen
: DatatoCheck
: dataLen
: DATA0100_FMT
: algoDS
: ALGD0400_FMT
: KeyD0200
: KEYD0200_FMT
: ANYCSP
: ''
: ApiError);
if Apierror.MsgId <> ' ';
jwt_success_t = *off;
return;
endif;
// On success we return as below:
jwt_success_t = *On;
return;
on-error;
// If the given token is with wrong strucutre, base64 will fail.
jwt_success_t = *off;
return;
endmon;
dcl-proc decodeBase64;
dcl-pi *n varchar(65530) ccsid(1208);
string varchar(65530) const ccsid(*utf8);
end-pi;
dcl-s workstring varchar(65530) ccsid(*utf8);
dcl-s DecodeString varchar(65530);
dcl-s DecodedString_utf8 varchar(65530) ccsid(*utf8) ;
dcl-s DecodedString_utf8_length int(10);
dcl-s DecodedString_Hex varchar(65530) ccsid(*hex);
dcl-s FROMB64 char(2) inz('+/') ccsid(*utf8);
dcl-s TOB64 char(2) inz('-_') ccsid(*utf8);
dcl-s UGUALEFILL char(2) inz('==') ccsid(*utf8);
dcl-s Remainder int(10);
workstring = %trimr(string);
// Trasformo in base64url
workstring = %xlate( TOB64 :FROMB64 :workstring);
Remainder = %len(workstring);
Remainder = (%rem(%len(workstring) :4));
select;
// when (Remainder = 1);
// StringToDecodedWork = StringToDecodedWork + UGUALEFILL;
when (Remainder = 2);
workstring = workstring + UGUALEFILL;
when (Remainder = 3);
workstring = workstring + %subst(UGUALEFILL :1 :1);
endsl;
// Decoding
DecodeString = %trimr(workstring);
%len(DecodedString_utf8) = %len(DecodedString_utf8:*max);
DecodedString_utf8_length = base64_decode( %addr(DecodeString : *data)
: %len(DecodeString)
: %addr(DecodedString_utf8:*data)
: %len(DecodedString_utf8:*max) );
DecodedString_Hex = DecodedString_utf8;
return DecodedString_utf8;
end-proc;
As an Amazon Associate we earn from qualifying purchases.