× The internal search function is temporarily non-functional. The current search engine is no longer viable and we are researching alternatives.
As a stop gap measure, we are using Google's custom search engine service.
If you know of an easy to use, open source, search engine ... please contact support@midrange.com.




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.

This thread ...

Follow-Ups:

Follow On AppleNews
Return to Archive home page | Return to MIDRANGE.COM home page

This mailing list archive is Copyright 1997-2024 by midrange.com and David Gibbs as a compilation work. Use of the archive is restricted to research of a business or technical nature. Any other uses are prohibited. Full details are available on our policy page. If you have questions about this, please contact [javascript protected email address].

Operating expenses for this site are earned using the Amazon Associate program and Google Adsense.