Skip to content

Commit

Permalink
[INJICERT-585] add support for raw signature
Browse files Browse the repository at this point in the history
* adds support for algos such as Ed25519Signature2020

Signed-off-by: Harsh Vardhan <[email protected]>
  • Loading branch information
vharsh committed Nov 12, 2024
1 parent 83d1076 commit 759f9d3
Show file tree
Hide file tree
Showing 12 changed files with 187 additions and 23 deletions.
16 changes: 13 additions & 3 deletions kernel/kernel-keymanager-service/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
<!-- maven -->
<maven.compiler.source>21</maven.compiler.source>
<maven.compiler.target>21</maven.compiler.target>
<maven.compiler.version>3.9.6</maven.compiler.version>
<maven.compiler.version>3.9.0</maven.compiler.version>

<maven.jar.plugin.version>3.0.2</maven.jar.plugin.version>
<maven.war.plugin.version>3.1.0</maven.war.plugin.version>
Expand Down Expand Up @@ -50,7 +50,12 @@
<bcpkix.jdk18on.version>1.78.1</bcpkix.jdk18on.version>
<mockito.core.version>3.4.3</mockito.core.version>
</properties>

<repositories>
<repository>
<id>jitpack.io</id>
<url>https://jitpack.io</url>
</repository>
</repositories>
<dependencyManagement>
<dependencies>
<dependency>
Expand Down Expand Up @@ -252,6 +257,11 @@
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>com.github.multiformats</groupId>
<artifactId>java-multibase</artifactId>
<version>1.1.1</version>
</dependency>
</dependencies>

<distributionManagement>
Expand Down Expand Up @@ -463,4 +473,4 @@
</developer>
</developers>

</project>
</project>
Original file line number Diff line number Diff line change
Expand Up @@ -69,9 +69,11 @@ public enum KeymanagerErrorConstant {

EC_SIGN_REFERENCE_ID_NOT_SUPPORTED("KER-KMS-030", "EC Sign Reference Id Not Supported for the Application ID."),

INTERNAL_SERVER_ERROR("KER-KMS-500", "Internal server error");
INTERNAL_SERVER_ERROR("KER-KMS-500", "Internal server error"),

/**
INVALID_FORMAT_ERROR("KER-KMS-XXX", "Unsupported output format for the signature");

/**
* The error code.
*/
private final String errorCode;
Expand All @@ -85,7 +87,7 @@ public enum KeymanagerErrorConstant {
* @param errorCode The error code to be set.
* @param errorMessage The error message to be set.
*/
private KeymanagerErrorConstant(String errorCode, String errorMessage) {
KeymanagerErrorConstant(String errorCode, String errorMessage) {
this.errorCode = errorCode;
this.errorMessage = errorMessage;
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
package io.mosip.kernel.keymanagerservice.exception;

import io.mosip.kernel.core.exception.BaseUncheckedException;

/**
* Custom Exception Class in case of invalid signature format
*
* @author Harsh Vardhan
* // TODO: which version will this changeset go?
* @since 1.3.x
*
*/
public class InvalidFormatException extends BaseUncheckedException {

/**
* Generated serial version id
*/
private static final long serialVersionUID = 8621530697947108811L;

/**
* Constructor the initialize Handler exception
*
* @param errorCode The errorcode for this exception
* @param errorMessage The error message for this exception
*/
public InvalidFormatException(String errorCode, String errorMessage) {
super(errorCode, errorMessage);
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@ private SignatureConstant() {

public static final String JWT_SIGN = "JWTSignature";

public static final String RAW_SIGN = "RAW_SIGN";

public static final String BLANK = "";

public static final Boolean DEFAULT_INCLUDES = false;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
package io.mosip.kernel.signature.dto;

import io.swagger.annotations.ApiModelProperty;
import jakarta.validation.constraints.NotBlank;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

/**
*
* @author Mahammed Taheer
* @since 1.2.0-SNAPSHOT
*
*/

@Data
@NoArgsConstructor
@AllArgsConstructor
public class SignRequestDtoV2 {

@NotBlank
@ApiModelProperty(notes = "Base64 encoded JSON Data to sign", example = "ewogICAiYW55S2V5IjogIlRlc3QgSnNvbiIKfQ", required = true)
private String dataToSign;

/**
* Application id of decrypting module
*/
@ApiModelProperty(notes = "Application id to be used for signing", example = "KERNEL", required = false)
private String applicationId;

/**
* Refrence Id
*/
@ApiModelProperty(notes = "Refrence Id", example = "SIGN", required = false)
private String referenceId;


@ApiModelProperty(notes = "Encoding format of the signature: base64url, base58btc")
private String responseEncodingFormat;

/**
* Algorithm to use for data signing. Current supported Algorithm [PS256,...]
*/
@ApiModelProperty(notes = "Algorithm to use for data signing. Current supported Algorithm PS256.", required = false)
// get algo names from rfc7518, except `none`
private String signAlgorithm;

}
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
public class SignResponseDto {

/**
* encrypted data
* signed data encoded as per request input
*/
private String signature;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@
@ApiModel(description = "Model representing a Crypto-Manager-Service Response")
public class SignatureResponseDto {
/**
* Data Encrypted/Decrypted in BASE64 encoding
* Data signed in BASE64 encoding
*/
@ApiModelProperty(notes = "Data encrypted/decrypted in BASE64 encoding")
private String data;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package io.mosip.kernel.signature.service;

import io.mosip.kernel.signature.dto.*;

public interface SignatureServicev2 extends SignatureService {
/**
* JSON Web Signature(JWS) for the input data using input algorithm
*
* @param signatureReq
* @return the {@link SignResponseDto}
*/
public SignResponseDto signv2(SignRequestDtoV2 signatureReq);

}
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,15 @@

import javax.crypto.SecretKey;

import com.mchange.util.Base64Encoder;
import com.nimbusds.jose.JWSAlgorithm;
import io.ipfs.multibase.Multibase;
import io.mosip.kernel.keymanagerservice.exception.InvalidApplicationIdException;
import io.mosip.kernel.keymanagerservice.exception.InvalidFormatException;
import io.mosip.kernel.signature.dto.*;
import io.mosip.kernel.signature.service.SignatureServicev2;
import org.apache.commons.codec.binary.Base64;
import org.bouncycastle.pqc.jcajce.provider.dilithium.DilithiumKeyFactorySpi;
import org.jose4j.jca.ProviderContext;
import org.jose4j.jwa.AlgorithmFactory;
import org.jose4j.jwa.AlgorithmFactoryFactory;
Expand Down Expand Up @@ -67,17 +75,6 @@
import io.mosip.kernel.partnercertservice.service.spi.PartnerCertificateManagerService;
import io.mosip.kernel.signature.constant.SignatureConstant;
import io.mosip.kernel.signature.constant.SignatureErrorCode;
import io.mosip.kernel.signature.dto.JWSSignatureRequestDto;
import io.mosip.kernel.signature.dto.JWTSignatureRequestDto;
import io.mosip.kernel.signature.dto.JWTSignatureResponseDto;
import io.mosip.kernel.signature.dto.JWTSignatureVerifyRequestDto;
import io.mosip.kernel.signature.dto.JWTSignatureVerifyResponseDto;
import io.mosip.kernel.signature.dto.PDFSignatureRequestDto;
import io.mosip.kernel.signature.dto.SignRequestDto;
import io.mosip.kernel.signature.dto.SignatureRequestDto;
import io.mosip.kernel.signature.dto.SignatureResponseDto;
import io.mosip.kernel.signature.dto.TimestampRequestDto;
import io.mosip.kernel.signature.dto.ValidatorResponseDto;
import io.mosip.kernel.signature.exception.CertificateNotValidException;
import io.mosip.kernel.signature.exception.PublicKeyParseException;
import io.mosip.kernel.signature.exception.RequestException;
Expand All @@ -93,7 +90,7 @@
*
*/
@Service
public class SignatureServiceImpl implements SignatureService {
public class SignatureServiceImpl implements SignatureService, SignatureServicev2 {

private static final Logger LOGGER = KeymanagerLogger.getLogger(SignatureServiceImpl.class);

Expand Down Expand Up @@ -629,6 +626,67 @@ public JWTSignatureResponseDto jwsSign(JWSSignatureRequestDto jwsSignRequestDto)
return responseDto;
}

@Override
public SignResponseDto signv2(SignRequestDtoV2 signatureReq) {
LOGGER.info(SignatureConstant.SESSIONID, SignatureConstant.RAW_SIGN, SignatureConstant.BLANK,
"Raw Sign Signature Request.");
String applicationId = signatureReq.getApplicationId();
String referenceId = signatureReq.getReferenceId();
boolean hasAcccess = cryptomanagerUtil.hasKeyAccess(applicationId);
String reqDataToSign = signatureReq.getDataToSign();
if (!hasAcccess) {
LOGGER.error(SignatureConstant.SESSIONID, SignatureConstant.RAW_SIGN, SignatureConstant.BLANK,
"Signing Data is not allowed for the authenticated user for the provided application id.");
throw new RequestException(SignatureErrorCode.SIGN_NOT_ALLOWED.getErrorCode(),
SignatureErrorCode.SIGN_NOT_ALLOWED.getErrorMessage());
}

if (!SignatureUtil.isDataValid(reqDataToSign)) {
LOGGER.error(SignatureConstant.SESSIONID, SignatureConstant.RAW_SIGN, SignatureConstant.BLANK,
"Provided Data to sign is invalid.");
throw new RequestException(SignatureErrorCode.INVALID_INPUT.getErrorCode(),
SignatureErrorCode.INVALID_INPUT.getErrorMessage());
}
byte[] dataToSign = CryptoUtil.decodeURLSafeBase64(reqDataToSign);
String timestamp = DateUtils.getUTCCurrentDateTimeString();
if (!keymanagerUtil.isValidApplicationId(applicationId)) {
applicationId = signApplicationid;
referenceId = signRefid;
}
String signAlgorithm = SignatureUtil.isDataValid(signatureReq.getSignAlgorithm()) ?
signatureReq.getSignAlgorithm(): SignatureConstant.ED25519_ALGORITHM;

SignatureCertificate certificateResponse = keymanagerService.getSignatureCertificate(applicationId,
Optional.of(referenceId), timestamp);
keymanagerUtil.isCertificateValid(certificateResponse.getCertificateEntry(),
DateUtils.parseUTCToDate(timestamp));
PrivateKey privateKey = certificateResponse.getCertificateEntry().getPrivateKey();
certificateResponse.getCertificateEntry().getChain();
String providerName = certificateResponse.getProviderName();
SignatureProvider signatureProvider = SIGNATURE_PROVIDER.get(signAlgorithm);
if (Objects.isNull(signatureProvider)) {
signatureProvider = SIGNATURE_PROVIDER.get(SignatureConstant.JWS_PS256_SIGN_ALGO_CONST);
}
String signature = signatureProvider.sign(privateKey, dataToSign, providerName);
byte[] data = java.util.Base64.getUrlDecoder().decode(signature);
SignResponseDto signedData = new SignResponseDto();
signedData.setTimestamp(DateUtils.getUTCCurrentDateTime());
switch (signatureReq.getResponseEncodingFormat()) {
case "base64url":
signedData.setSignature(
Multibase.encode(Multibase.Base.Base64Url, data));
break;
case "base58btc":
signedData.setSignature(
Multibase.encode(Multibase.Base.Base58BTC, data));
break;
default:
throw new InvalidFormatException(KeymanagerErrorConstant.INVALID_FORMAT_ERROR.getErrorCode(),
KeymanagerErrorConstant.INVALID_FORMAT_ERROR.getErrorMessage());
}
return signedData;
}

public static class EcdsaSECP256K1UsingSha256 extends EcdsaUsingShaAlgorithm
{
public EcdsaSECP256K1UsingSha256() {
Expand Down
2 changes: 1 addition & 1 deletion kernel/keys-generator/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
<!-- maven -->
<maven.compiler.source>21</maven.compiler.source>
<maven.compiler.target>21</maven.compiler.target>
<maven.compiler.version>3.9.6</maven.compiler.version>
<maven.compiler.version>3.9.0</maven.compiler.version>

<maven.jar.plugin.version>3.0.2</maven.jar.plugin.version>
<maven.war.plugin.version>3.1.0</maven.war.plugin.version>
Expand Down
2 changes: 1 addition & 1 deletion kernel/keys-migrator/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
<!-- maven -->
<maven.compiler.source>21</maven.compiler.source>
<maven.compiler.target>21</maven.compiler.target>
<maven.compiler.version>3.9.6</maven.compiler.version>
<maven.compiler.version>3.9.0</maven.compiler.version>

<maven.jar.plugin.version>3.0.2</maven.jar.plugin.version>
<maven.war.plugin.version>3.1.0</maven.war.plugin.version>
Expand Down
2 changes: 1 addition & 1 deletion kernel/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
<!-- maven -->
<maven.compiler.source>21</maven.compiler.source>
<maven.compiler.target>21</maven.compiler.target>
<maven.compiler.version>3.9.6</maven.compiler.version>
<maven.compiler.version>3.9.0</maven.compiler.version>
<maven.surefire.plugin.version>2.22.0</maven.surefire.plugin.version>
<maven.jar.plugin.version>3.0.2</maven.jar.plugin.version>
<maven.war.plugin.version>3.1.0</maven.war.plugin.version>
Expand Down

0 comments on commit 759f9d3

Please sign in to comment.