All Downloads are FREE. Search and download functionalities are using the official Maven repository.

io.mosip.kernel.websub.api.verifier.AuthenticatedContentVerifier Maven / Gradle / Ivy

package io.mosip.kernel.websub.api.verifier;

import java.io.IOException;
import java.util.stream.Collectors;

import javax.servlet.http.HttpServletRequest;
import javax.xml.bind.DatatypeConverter;

import org.bouncycastle.crypto.digests.SHA1Digest;
import org.bouncycastle.crypto.digests.SHA256Digest;
import org.bouncycastle.crypto.digests.SHA384Digest;
import org.bouncycastle.crypto.digests.SHA512Digest;
import org.bouncycastle.crypto.macs.HMac;
import org.bouncycastle.crypto.params.KeyParameter;
import org.springframework.stereotype.Component;

import io.mosip.kernel.websub.api.constants.WebSubClientConstants;
import io.mosip.kernel.websub.api.constants.WebSubClientErrorCode;
import io.mosip.kernel.websub.api.exception.WebSubClientException;

/**
 * This is a helper class to authenticate content when payload is pushed by hub
 * after update from publisher according to
 * WebSub Specs Note
 * that content only needed to be authenticated if we have passed secret in
 * subscribe request.
 * 
 * 
 * @author Urvil Joshi
 *
 */
public class AuthenticatedContentVerifier {

	private static final String METHOD_SIGNATURE_SPLITTER = "=";

	/**
	 * This method retrive body and signature header from request and used
	 * {@link #isContentVerified(String, String, String)} to authenticate the content.
	 * 
	 * @param httpServletRequest request for delivery of payload.
	 * @param secret             secret send while subscribe operation.
	 * @return authentication result in boolean.
	 */
	public boolean verifyAuthorizedContentVerified(HttpServletRequest httpServletRequest, String secret) {

		String body = null;
		try {
			body = httpServletRequest.getReader().lines().collect(Collectors.joining(System.lineSeparator()));
		} catch (IOException exception) {
			throw new WebSubClientException(WebSubClientErrorCode.IO_ERROR.getErrorCode(),
					WebSubClientErrorCode.IO_ERROR.getErrorMessage().concat(exception.getMessage()));
		}

		String hubSignature = httpServletRequest.getHeader(WebSubClientConstants.HUB_AUTHENTICATED_CONTENT_HEADER);
		return isContentVerified(secret, body, hubSignature);

	}

	/**
	 * This method authenticates the content.
	 * 
	 * @param secret       secret used while subscribe operation.
	 * @param body         payload sent by hub.
	 * @param hubSignature signature header sent by hub.
	 * @return authentication result in boolean.
	 */
	public boolean isContentVerified(String secret, String body, String hubSignature) {
		if (hubSignature != null && !hubSignature.isEmpty()) {
			String[] signatureSplit = hubSignature.split(METHOD_SIGNATURE_SPLITTER);
			String method = signatureSplit[0];
			String signature = signatureSplit[1];
			HMac hMac = null;
			switch (method) {
			case "SHA1":
				hMac = new HMac(new SHA1Digest());
				break;
			case "SHA256":
				hMac = new HMac(new SHA256Digest());
				break;
			case "SHA384":
				hMac = new HMac(new SHA384Digest());
				break;
			case "SHA512":
				hMac = new HMac(new SHA512Digest());
				break;
			default:
				hMac = new HMac(new SHA256Digest());
				break;
			}
			KeyParameter params = new KeyParameter(secret.getBytes());
			hMac.init(params);
			hMac.update(body.getBytes(), 0, body.getBytes().length);
			byte[] result = new byte[hMac.getMacSize()];
			hMac.doFinal(result, 0);
			String expectedHash = DatatypeConverter.printHexBinary(result).toLowerCase();
			return expectedHash.equals(signature);
		} else {
			throw new WebSubClientException(
					WebSubClientErrorCode.AUTHENTTICATED_CONTENT_VERIFICATION_HEADER_ERROR.getErrorCode(),
					WebSubClientErrorCode.AUTHENTTICATED_CONTENT_VERIFICATION_HEADER_ERROR.getErrorMessage());
		}
	}

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy