Download as docx, pdf, or txt
Download as docx, pdf, or txt
You are on page 1of 16

2

ABBREVIATIONS

CHAPTER 1
INTRODUCTION
The project was done to obtain better understanding of Raast is Pakistan’s first instant
payment system that will enable end-to-end digital payments among individuals, businesses
and government entities instantaneously. The state-of-the-art Pakistan’s Faster Payment
System will be used to settle small-value retail payments in real time while at the same time
provide a cheap and universal access to all players in the financial industry including
commercial banks, microfinance banks, government entities and fintech’s (EMIs & PSPs).

Pakistan has had low electronic transactions for a number of reasons including low banking
penetration, lack of trust and awareness of digital payment methods, limited interoperability,
difficult accessibility and high cost of transactions. The Real Time Gross Settlement System
(RTGS) of Pakistan provides instant payment settlements for large value and corporate
transactions only. Raast: Pakistan’s Instant Payment System will facilitate retail payment
settlements with much great efficiency.

1.1 Motivation
Consumers can benefit from the flexibility that faster payments offer, such as the ability to
complete last-minute or emergency payments. With this capability, consumers can avoid late
fees, the risk of account overdrafts, and damage to their credit scores.

1.2 Problem Statement


Raast aims to address some key industry challenges within the payment ecosystem:

Limited interoperability: Financial institutions (i.e. the providers of digital payment services) have
difficulty connecting to each other due to a lack of necessary central infrastructure.

High cost of digital payments to the end user: End users are charged high fees for transferring money
digitally, making digital payments inaccessible for a large portion of the population.

Poor user experience: End users must go through a complex process to make digital payments and there
are no digital modes of payment that are widely accepted by merchants.
2

Lack of security: Currently available digital payment types and infrastructure do not offer
sufficient/adequate data protection and authentication

1.3 Organization of Thesis


The findings begin with the presentation of concepts that serve as the framework for the job
itself.
Furthermore, the report is organized into two key sections, which are separated from other
important aspects such as an overview and appendices. These two key components are
referred to as 'Software Engineering' and 'Project Linked Elements.'
 The Computer Programming part contains all of the software-related information
required to execute this project, such as the Software Engineering life cycle, software
schedule creation, software risk management, and so on.
 Whereas project-related details include things like RAAST Bulk Payment System and
Motivation, Scope, and so on. By the end of the report, it has highlighted the project's
outcomes as well as future work that may be done along the linked route.

CHAPTER 2
LITERATURE REVIEW
2.1 Introduction
This chapter is about the project's Existing Literature, which is conducted to learn about the
research effort based on our study. The review covers the process of functioning of
advanced analytical algorithms in some of the projects, as well as the difficulties that arise.

"What other people here think" is indeed valuable information for many of us while
making judgments. The Internet and the World Wide Web have suddenly made it possible
to learn about the viewpoints and experiences of individuals who are neither our close
friends nor well-known expert critics — in other words, people we have never heard of. On
the other hand, a large number of people are making their thoughts known to strangers over
the Internet. Individual customers' interest in online views regarding products and services,
as well as the potential effect such opinions may have, is a major driving force behind this
field of study. And there are numerous problems associated with this process that must be
overcome to get the desired results. In this study, we examined the fundamental approach
2

that is often used in this procedure as well as the steps which must be followed to
overcome the problems that are confronted.

2.2 Software Used in the Project


2.2.1 IBM App Connect:
A powerful integration platform, designed for business technologists and
integration specialists. IBM App Connect is an industry-leading application
integration platform that connects any of your applications and data no matter where
they reside.

2.2.2 Postman:
Ppostman is an application used for API testing. It is an HTTP client that tests
HTTP requests, utilizing a graphical user interface, through which we obtain different
types of responses that need to be subsequently validated.

2.2.3 SoapUI:
SoapUI is a tool for testing Web Services; these can be the SOAP Web
Services as well RESTful Web Services or HTTP based services. SoapUI is an Open
Source and completely free tool with a commercial companion -Ready API- that has
extra functionality for companies with mission critical Web Services.

CHAPTER 3

3.1 Technologies Used in the Project


Other than equipment, the accompanying apparatuses and methods were utilized to satisfy
the prerequisites of our framework.
3.1.1 ESQL:
Extended Structured Query Language (ESQL) is a programming language defined by
IBM® Integration Bus to define and manipulate data within a message flow.
3.1.2 Oracle:
Oracle SQL provides an easy, elegant, performant architecture for accessing, defining,
and maintaining data. Use SQL with Oracle and PHP, Java, Python, .
2

Figure 1

Figure 2
2

Figure 3

CHAPTER 4

4.1 Use Case:

4.1.1 Validation of instructions by Receiving Bank Sending instructions to Receiving Bank


for validation.
Type of request – asynchronous. API reply after validation contains single instruction or set
of instructions.
Only one reply per batch is allowed. If there are no instructions in reply – all instructions in
batch are accepted. If there are any instructions in reply – they will be accepted in Initiating
Institution as rejected.
2

Figure 4

Used Endpoint –
API Gateway 1. POST /instructions/validate – Initiating Institution calls method ‘Send
instructions’ (refer to 2.1.1 Method ‘Send instructions’ format) to call Receiving Bank and
send instructions for validation. API call contains instructions from one batch.
2.1. Authorize sender participant – API Gateway authorizes calling participant via MPG
database (participant’s user should be registered in MPG).
2.2. Search endpoint – API Gateway searches endpoint (URL) of the Receiving Bank
(Receiver-Participant-Code).
2.3. POST /instructions/validate – API Gateway calls Receiving Bank’s method ‘Send
instructions’ (refer to 2.1.1 Method ‘Send instructions’ format) using found endpoint to
instructions for validation to Receiving Bank.
3.1. Error reply – Receiving Bank replies to API Gateway with error in case of mistakes in
received data.
3.2. Error reply – API Gateway transmits error response to Initiating Institution.
2

4.1. Success reply – Receiving Bank replies to API Gateway with success that data was
accepted.
4.2. Success reply – API Gateway transmits success response to Initiating Institution.
5. Validate instructions – Receiving Bank checks possibility to process instructions, validate
Customers accounts.
6.1. POST /instructions/validate/status – Receiving Bank calls Method ‘Validation status’
format to send result of processing.
6.2. POST /instructions/validate/status – API Gateway transmits request.
7.1. Error reply – Initiating Institution replies to API Gateway with error in case of mistakes
in received data.
7.2. Error reply – API Gateway transmits error response to Receiving Bank.
8.1. Success reply – Initiating Institution replies to API Gateway with success that data was
accepted.
8.2. Success reply – API Gateway transmits success response to Receiving Bank.

4.1.2. Payment from Initiating Institution

Figure 5

Used Endpoint - MPG


1.1. Initiating Institution sends Customer Credit Transfer (pacs.008) message to
MPG.
2

2.1. MPG sends pacs.002 in case of error in business logic of message.


2.2. MPG sends camt.025 in case of technical rejection (wrong data, access rights) of
message.
2.3. MPG sends admi.002 in case of technical rejection (error in format) of message.
3. MPG processes message and sends pacs.008 to Receiving Bank.
4. MPG sends confirmation of successful payment processing to participants

2.3. Return payments from Receiving Bank


1. Receiving Bank sends return payment (pacs.004) message to MPG. This return payment
contains a reference to original pacs.008.
2. MPG processes message and sends pacs.004 to Initiating Institution.
3. MPG sends confirmation of successful payment processing to participant

CHAPTER 5

5.1 Message Flows:

Figure 6
2

Figure 7

Figure 8

CHAPTER 6
6.1 Coding:
BROKER SCHEMA com.systemsltd.mpg.validationservice.esql
2

PATH com.systemsltd.mpgcommon, com.systemsltd.common.cache,


com.systemsltd.common, com.systemsltd.common.util,
com.systemsltd.common.config, com.systemsltd.common.logging;
DECLARE getStatusQuery CHARACTER 'SELECT TD.TRANSACTION_REFERENCE_ID,
TD.TRANSACTION_STATUS, TD.MODIFIED_DATETIME,
TG.BATCH_ID, TG.TRANSACTION_DATETIME FROM TRANSACTION_DETAIL TD LEFT JOIN
TRANSACTION_GROUP TG ON TG.ID = TD.GROUP_ID
WHERE
TRANSACTION_DATETIME = ? AND TRANSACTION_TYPE = ? AND ';
CREATE FILTER MODULE ValidateRequest
CREATE FUNCTION Main() RETURNS BOOLEAN
BEGIN
CALL logInfoDecoratedMessage('Validation Request Received',
Root);
CREATE FIELD Environment.Variables.Transaction.error;
DECLARE envRef REFERENCE TO
Environment.Variables.Transaction.error;
SET Environment.Variables.Transaction.header =
Root.HTTPInputHeader;
DECLARE request CHARACTER CAST(Root.BLOB.BLOB AS CHARACTER
ENCODING Root.Properties.Encoding);
DECLARE publicKeyBytes BLOB NULL;
DECLARE jsonHeader ROW;
DECLARE headerDecoded CHARACTER
urlDecodeString(SUBSTRING(request BEFORE '.'));
DECLARE headerDecodedBlob BLOB CAST(headerDecoded AS BLOB CCSID
Root.Properties.CodedCharSetId);
CREATE LASTCHILD OF jsonHeader DOMAIN('JSON')
PARSE(headerDecodedBlob, Root.Properties.Encoding,
Root.Properties.CodedCharSetId);
DECLARE ldapPassword CHARACTER
decryptPassword(getConfigProperty('LDAP_PASSWORD'));
SET publicKeyBytes =
getPubliKeyFromLdap(jsonHeader.JSON.Data.x5t, NULL,
getConfigProperty('LDAP_HOST_NAME'),
getConfigProperty('LDAP_PORT'),
getConfigProperty('LDAP_USER_NAME'), ldapPassword,
getConfigProperty('LDAP_BASEDN'),
getConfigProperty('REVOCATION_LIST_SEARCH_BASE'));
IF NOT isEmptyString(BASE64ENCODE(publicKeyBytes)) THEN
DECLARE signatureAlgo CHARACTER
getGroupConfigProperty('JWS/JWT', null, 'SIGNATURE_ALGO');
DECLARE keyAlgo CHARACTER getConfigProperty('KEY_ALGO');
DECLARE isValidSignature BOOLEAN verifyJWS(request,
signatureAlgo, publicKeyBytes, keyAlgo);
IF NOT isValidSignature THEN
SET envRef.errorCode = 305;
SET envRef.errorDesc = 'Unable to validate
signature';
CALL logInfoMessage('Signature Validation Failed');
RETURN FALSE;
END IF;
ELSE
SET envRef.errorCode = 305;
SET envRef.errorDesc = 'Unable to validate signature';
CALL logInfoMessage('Signature Validation Failed');
RETURN FALSE;
END IF;
RETURN TRUE;
END;
END MODULE;
2

CREATE COMPUTE MODULE SaveTransactionAndPrepareResponse


CREATE FUNCTION Main() RETURNS BOOLEAN
BEGIN
CALL logInfoDecoratedMessage('Validation Request Received',
InputRoot);
SET OutputRoot.Properties = InputProperties;
DECLARE header REFERENCE TO InputRoot.HTTPInputHeader;
DECLARE hostReferenceId CHARACTER header.{'X-Request-Id'};
DECLARE senderParticipantCode CHARACTER header.{'Sender-
Participant-Code'};
DECLARE remoteAddress CHARACTER header."X-Remote-Host";
DECLARE envRef REFERENCE TO Environment.Variables.Transaction;
DECLARE urlEncodedPayloadBlob BLOB InputRoot.BLOB.BLOB;
DECLARE urlEncodedPayload CHARACTER CAST(urlEncodedPayloadBlob
AS CHARACTER ENCODING InputRoot.Properties.Encoding);
DECLARE jwsEncodedHeader CHARACTER SUBSTRING(urlEncodedPayload
BEFORE '.');
DECLARE payloadRow ROW;
CREATE LASTCHILD OF payloadRow DOMAIN('JSON');
CREATE LASTCHILD OF payloadRow.JSON NAME 'Data';
DECLARE payloadRef REFERENCE TO payloadRow.JSON.Data;
DECLARE groupTransaction, jsonRequest ROW;
DECLARE payloadSignature CHARACTER SUBSTRING(urlEncodedPayload
AFTER '.');
DECLARE payload CHARACTER SUBSTRING(payloadSignature BEFORE
'.');
DECLARE payloadDecoded CHARACTER urlDecodeString(payload);
DECLARE processingMode CHARACTER;
DECLARE httpResponseCode INTEGER;
SET httpResponseCode = 200;
SET jsonRequest.Properties = InputProperties;
DECLARE payloadDecodedBlob BLOB CAST(payloadDecoded AS BLOB
CCSID InputProperties.CodedCharSetId);
CREATE LASTCHILD OF jsonRequest DOMAIN('JSON')
PARSE(payloadDecodedBlob, InputProperties.Encoding,
InputProperties.CodedCharSetId);
DECLARE transactionRef REFERENCE TO jsonRequest.JSON.Data;
DECLARE batchId CHARACTER transactionRef.batchId;
DECLARE valueDate CHARACTER transactionRef.valueDate;
DECLARE groupStatus CHARACTER getTransactionStatusReceived();
IF LENGTH(batchId) < 24 THEN
CALL logInfoMessage('BatchId length less than 24');
SET payloadRef.statusCode = 101;
SET payloadRef.description = '[Path /batchId String] '||
batchId||' is too short (required minimum : 24)';
SET httpResponseCode = 400;
ELSE
DECLARE noOfTransactions INTEGER
CARDINALITY(transactionRef.instructions.[]);
IF (noOfTransactions > 1) THEN
SET processingMode = 'BULK';
ELSE
SET processingMode = 'SINGLE';
END IF;
DECLARE groupPayload CHARACTER
serializeMessage(jsonRequest);
DECLARE transactionGroupId INTEGER
saveGroupTransaction(groupStatus, batchId, hostReferenceId,
noOfTransactions, groupPayload, valueDate,
'VALIDATION.STATUS', transactionRef.batchInitiator,
2

remoteAddress, 'TITLE_FETCH');
DECLARE instructionRef REFERENCE TO
transactionRef.instructions.Item;
CREATE FIELD OutputRoot.JSON.Data;
WHILE LASTMOVE(instructionRef) DO
DECLARE transactionPayload CHARACTER serializeData(instructionRef);
DECLARE transactionReferenceId CHARACTER instructionRef.instructionId;
DECLARE transactionDetailId INTEGER
saveTransactionDetail(transactionGroupId, hostReferenceId,
getTransactionStatusReceived(), transactionPayload, processingMode,
transactionReferenceId,senderParticipantCode,
COALESCE(instructionRef.amount.value, NULL), NULL, 'TF.PROCESSING');
MOVE instructionRef NEXTSIBLING REPEAT TYPE;
END WHILE;
DELETE FIELD OutputRoot.JSON;
SET payloadRef.statusCode = 0;
SET httpResponseCode = 200;
END IF;
DECLARE payloadSerialize CHARACTER
serializeMessage(payloadRow);
CALL createResponseHeader(header, OutputRoot,
httpResponseCode);
DECLARE jwsResponseHeaderSerialize CHARACTER
createJsonSignatureHeader('jose', 'RS256');
DECLARE privateKey BLOB getConfigPropertyBLOB('PRIVATE_KEY');
DECLARE keyAlgo CHARACTER getConfigProperty('KEY_ALGO');
DECLARE signatureAlgo CHARACTER
getGroupConfigProperty('JWS/JWT', '', 'SIGNATURE_ALGO');
DECLARE encodedResponse CHARACTER generateJWS(
jwsResponseHeaderSerialize, payloadSerialize,
signatureAlgo, privateKey , keyAlgo);
SET OutputRoot.BLOB.BLOB = CAST(encodedResponse AS BLOB CCSID
1208);
CALL logInfoDecoratedMessage('Validate Instructions Response Prepared',
OutputRoot);
RETURN TRUE;
END;
END MODULE;
CREATE FILTER MODULE ValidateStatusRequest
CREATE FUNCTION Main() RETURNS BOOLEAN
BEGIN
CALL logInfoDecoratedMessage('GetStatus Request Received',
Root);
CREATE FIELD Environment.Variables.Transaction;
DECLARE envRef REFERENCE TO Environment.Variables.Transaction;
DECLARE queryParms REFERENCE TO
LocalEnvironment.HTTP.Input.QueryString;
CALL validateHeader(Root.HTTPInputHeader, envRef);
IF (NOT fieldAndValueExists(queryParms.instructionId,
'instructionId') AND NOT fieldAndValueExists(queryParms.batchId,
'batchId')) OR
NOT fieldAndValueExists(queryParms.valueDate,
'valueDate') THEN
SET envRef.errorCode = '101';
SET envRef.errorDesc = 'Invalid request';
END IF;
IF NOT EXISTS(Environment.Variables.Transaction.errorCode[])
THEN
IF NOT fieldAndValueExists(Root.HTTPInputHeader.Cryptogram,'Cryptogram')
THEN
SET envRef.errorCode = 305;
2

SET envRef.errorDesc = 'Unable to validate signature';


CALL logInfoMessage('Signature Missing');
RETURN FALSE;
ELSE
DECLARE request CHARACTER CAST(Root.HTTPInputHeader.Cryptogram AS CHARACTER
ENCODING Root.Properties.Encoding);
DECLARE publicKeyBytes BLOB NULL;
DECLARE jsonHeader ROW;
DECLARE headerDecoded CHARACTER
urlDecodeString(SUBSTRING(request BEFORE '.'));
DECLARE headerDecodedBlob BLOB CAST(headerDecoded AS BLOB CCSID
Root.Properties.CodedCharSetId);
CREATE LASTCHILD OF jsonHeader DOMAIN('JSON')
PARSE(headerDecodedBlob, Root.Properties.Encoding,
Root.Properties.CodedCharSetId);
DECLARE ldapPassword CHARACTER
decryptPassword(getConfigProperty('LDAP_PASSWORD'));
SET publicKeyBytes = getPubliKeyFromLdap(jsonHeader.JSON.Data.x5t, NULL,
getConfigProperty('LDAP_HOST_NAME'),getConfigProperty('LDAP_PORT'),
getConfigProperty('LDAP_USER_NAME'),
ldapPassword,getConfigProperty('LDAP_BASEDN'),
getConfigProperty('REVOCATION_LIST_SEARCH_BASE'));
IF NOT isEmptyString(BASE64ENCODE(publicKeyBytes)) THEN
DECLARE signatureAlgo CHARACTER
getGroupConfigProperty('JWS/JWT', null, 'SIGNATURE_ALGO');
DECLARE keyAlgo CHARACTER
getConfigProperty('KEY_ALGO');
DECLARE isValidSignature BOOLEAN
verifyJWS(request, signatureAlgo, publicKeyBytes, keyAlgo);
IF NOT isValidSignature THEN
SET envRef.errorCode = 305;
SET envRef.errorDesc = 'Unable to validate signature';
CALL logInfoMessage('Signature Validation Failed');
RETURN FALSE;
END IF;
ELSE
SET envRef.errorCode = 305;
SET envRef.errorDesc = 'Unable to validate signature';
CALL logInfoMessage('Signature Validation Failed');
RETURN FALSE;
END IF;
END IF;
ELSE
RETURN FALSE;
END IF;

RETURN TRUE;
END;
END MODULE;
CREATE COMPUTE MODULE PrepareFailureResponse
CREATE FUNCTION Main() RETURNS BOOLEAN
BEGIN
SET OutputRoot.Properties = InputProperties;
DECLARE envRef REFERENCE TO Environment.Variables.Transaction.error;
DECLARE header REFERENCE TO InputRoot.HTTPInputHeader;
DECLARE payloadRow ROW;
CREATE LASTCHILD OF payloadRow DOMAIN('JSON');
CREATE LASTCHILD OF payloadRow.JSON NAME 'Data';
DECLARE payloadRef REFERENCE TO payloadRow.JSON.Data;
SET payloadRef.statusCode = envRef.errorCode;
SET payloadRef.description = envRef.errorDesc;
2

DECLARE payloadSerialize CHARACTER serializeMessage(payloadRow);


CALL createResponseHeader(header, OutputRoot, 400);
DECLARE jwsResponseHeaderSerialize CHARACTER
createJsonSignatureHeader('jose', 'RS256');
DECLARE privateKey BLOB getConfigPropertyBLOB('PRIVATE_KEY');
DECLARE keyAlgo CHARACTER getConfigProperty('KEY_ALGO');
DECLARE signatureAlgo CHARACTER getGroupConfigProperty('JWS/JWT', '',
'SIGNATURE_ALGO');
DECLARE response CHARACTER generateJWS( jwsResponseHeaderSerialize,
payloadSerialize, signatureAlgo, privateKey , keyAlgo);
SET OutputRoot.BLOB.BLOB = CAST(response AS BLOB CCSID 1208);

CALL logInfoDecoratedMessage('Validation Response Prepared', OutputRoot);


RETURN TRUE;
END;
END MODULE;
CREATE COMPUTE MODULE GetStatusAndPrepareResponse
CREATE FUNCTION Main() RETURNS BOOLEAN
BEGIN
SET OutputRoot.Properties = InputProperties;
DECLARE header REFERENCE TO InputRoot.HTTPInputHeader;
DECLARE hostReferenceId CHARACTER header.{'X-Request-Id'};
DECLARE senderParticipantCode CHARACTER header.{'Sender-Participant-Code'};
DECLARE queryParms REFERENCE TO
InputLocalEnvironment.HTTP.Input.QueryString;
DECLARE record ROW;
IF queryParms.batchId IS NOT NULL THEN
SET getStatusQuery = getStatusQuery || 'TG.BATCH_ID = ?';
ELSEIF queryParms.instructionId IS NOT NULL THEN
SET getStatusQuery = getStatusQuery || 'TD.TRANSACTION_REFERENCE_ID = ?';
END IF;
DECLARE id CHARACTER COALESCE(queryParms.batchId,
queryParms.instructionId);
DECLARE valueDate CHARACTER queryParms.valueDate;
SET record.data[] = PASSTHRU(getStatusQuery VALUES(valueDate,
'FUND_TRANSFER', id));
DECLARE payloadRow ROW;
CREATE LASTCHILD OF payloadRow DOMAIN('JSON');
CREATE LASTCHILD OF payloadRow.JSON NAME 'Data';
DECLARE payloadRef REFERENCE TO payloadRow.JSON.Data;
DECLARE dataRef REFERENCE TO record.data;
DECLARE httpResponseCode INTEGER 200;
IF NOT LASTMOVE(dataRef) THEN
SET payloadRef.statusCode = 102;
SET payloadRef.description = 'Data not found';
SET httpResponseCode = 400;
ELSE
SET payloadRef.statusCode = 0;
CREATE FIELD payloadRef.replyInstructions
IDENTITY(JSON.Array)replyInstructions;
DECLARE replyInstructionsRef REFERENCE TO payloadRef.replyInstructions;

CREATE FIELD replyInstructionsRef.Item;


DECLARE replyItemRef REFERENCE TO replyInstructionsRef.Item;
SET replyItemRef.batchId = record.data[1].BATCH_ID;
SET replyItemRef.valueDate = valueDate;
CREATE FIELD replyItemRef.instructions
IDENTITY(JSON.Array)instructions;
DECLARE instructionsRef REFERENCE TO replyItemRef.instructions;
DECLARE itemRef REFERENCE TO instructionsRef.Item;
DECLARE responseRow ROW;
2

DECLARE responseRef REFERENCE TO responseRow;


WHILE LASTMOVE(dataRef) DO
CREATE LASTCHILD OF instructionsRef AS itemRef NAME('Item');
SET itemRef.instructionId =
dataRef.TRANSACTION_REFERENCE_ID;
CREATE LASTCHILD OF itemRef AS responseRef NAME ('reportedStatus');
IF dataRef.TRANSACTION_STATUS = getTransactionStatusReturned() THEN
SET responseRef.name = 'Returned';
ELSEIF dataRef.TRANSACTION_STATUS = getTransactionStatusSuccess() THEN
SET responseRef.name = 'Processed';
ELSEIF dataRef.TRANSACTION_STATUS = getTransactionStatusReceived() THEN
SET responseRef.name = 'Suspended';
ELSE
SET responseRef.name = 'Rejected';
END IF;

SET responseRef.modificationDateTime = dataRef.MODIFIED_DATETIME;


MOVE dataRef NEXTSIBLING;
END WHILE;
END IF;
DECLARE payloadSerialize CHARACTER
serializeMessage(payloadRow);
CALL logInfoMessage('GetStatus JSON Response: ' || payloadSerialize);
CALL createResponseHeader(header, OutputRoot, httpResponseCode); DECLARE
jwsResponseHeaderSerialize CHARACTER createJsonSignatureHeader('jose',
'RS256');
DECLARE privateKey BLOB getConfigPropertyBLOB('PRIVATE_KEY');
DECLARE keyAlgo CHARACTER getConfigProperty('KEY_ALGO');
DECLARE signatureAlgo CHARACTER getGroupConfigProperty('JWS/JWT', '',
'SIGNATURE_ALGO');
DECLARE encodedResponse CHARACTER generateJWS( jwsResponseHeaderSerialize,
payloadSerialize,
signatureAlgo, privateKey , keyAlgo);
SET OutputRoot.BLOB.BLOB = CAST(encodedResponse AS BLOB CCSID
1208);
CALL logInfoDecoratedMessage('GetStatus Response Prepared', OutputRoot);
RETURN TRUE;
END;
END MODULE;

CREATE FILTER MODULE ValidateGetStatusRequest


CREATE FUNCTION Main() RETURNS BOOLEAN
BEGIN
CALL logInfoDecoratedMessage('Get Status Request Received',
Root);

CREATE FIELD Environment.Variables.Transaction.error;


DECLARE envRef REFERENCE TO Environment.Variables.Transaction.error;

SET Environment.Variables.Transaction.header = Root.HTTPInputHeader;


--CALL validateHeader(Root.HTTPInputHeader, envRef);

IF NOT EXISTS(envRef.errorCode[]) THEN


DECLARE request CHARACTER CAST(Root.HTTPInputHeader.Cryptogram AS CHARACTER
ENCODING Root.Properties.Encoding);
DECLARE publicKeyBytes BLOB NULL;
DECLARE jsonHeader ROW;
DECLARE headerDecoded CHARACTER urlDecodeString(SUBSTRING(request BEFORE
'.'));
DECLARE headerDecodedBlob BLOB CAST(headerDecoded AS BLOB CCSID
Root.Properties.CodedCharSetId);
2

CREATE LASTCHILD OF jsonHeader DOMAIN('JSON') PARSE(headerDecodedBlob,


Root.Properties.Encoding, Root.Properties.CodedCharSetId);

DECLARE ldapPassword CHARACTER


decryptPassword(getConfigProperty('LDAP_PASSWORD'));
SET publicKeyBytes = getPubliKeyFromLdap(jsonHeader.JSON.Data.x5t, NULL,
getConfigProperty('LDAP_HOST_NAME'),getConfigProperty('LDAP_PORT'),
getConfigProperty('LDAP_USER_NAME'),
ldapPassword,getConfigProperty('LDAP_BASEDN'),
getConfigProperty('REVOCATION_LIST_SEARCH_BASE'));
IF NOT isEmptyString(BASE64ENCODE(publicKeyBytes)) THEN
DECLARE signatureAlgo CHARACTER getGroupConfigProperty('JWS/JWT', null,
'SIGNATURE_ALGO');
DECLARE keyAlgo CHARACTER getConfigProperty('KEY_ALGO');
DECLARE isValidSignature BOOLEAN verifyJWS(request, signatureAlgo,
publicKeyBytes, keyAlgo);
IF NOT isValidSignature THEN
SET envRef.errorCode = 305;
SET envRef.errorDesc = 'Unable to validate signature';
CALL logInfoMessage('Signature Validation Failed');
RETURN FALSE;
END IF;
ELSE
SET envRef.errorCode = 305;
SET envRef.errorDesc = 'Unable to validate signature';
CALL logInfoMessage('Signature Validation Failed');

RETURN FALSE;
END IF;
ELSE
RETURN FALSE;
END IF;

RETURN TRUE;
END;
END MODULE;

CHAPTER 7

7.1 REFERENCE:
Internet : https://www.sbp.org.pk/dfs/Raast.html [Last access on December 13, 2022]
Internet : https://www.arcanainfo.com/ [Last access on December 12, 2022]
Internet : https://www.ibm.com/products/app-connect [Last access on December 02,
2022]

You might also like