Skip to content

Commit

Permalink
Merge pull request #357 from peter-szrnka/356-gms-177-secret-value-si…
Browse files Browse the repository at this point in the history
…ze-calculator

GMS-177 secret value size calculator
  • Loading branch information
peter-szrnka authored Dec 10, 2024
2 parents 5485164 + 7fd5a8f commit 25634fe
Show file tree
Hide file tree
Showing 44 changed files with 811 additions and 271 deletions.
6 changes: 0 additions & 6 deletions code/gms-backend/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -421,12 +421,6 @@
<goal>build-info</goal>
</goals>
</execution>
<execution>
<id>process-aot</id>
<goals>
<goal>process-aot</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
package io.github.gms.common.dto;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

import java.io.Serial;
import java.io.Serializable;

/**
* @author Peter Szrnka
* @since 1.0
*/
@Data
@AllArgsConstructor
@NoArgsConstructor
public class BooleanValueDto implements Serializable {
@Serial
private static final long serialVersionUID = -7426749389683654760L;

private Boolean value;
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,13 +16,7 @@
import javax.crypto.NoSuchPaddingException;
import java.io.ByteArrayInputStream;
import java.nio.charset.StandardCharsets;
import java.security.InvalidKeyException;
import java.security.KeyStore;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.UnrecoverableKeyException;
import java.security.*;
import java.security.cert.Certificate;
import java.util.Base64;

Expand Down Expand Up @@ -77,20 +71,23 @@ public String decrypt(SecretEntity secretEntity) {
public void encrypt(SecretEntity secretEntity) {
try {
KeystorePair keyPairData = keystoreDataService.getKeystoreData(secretEntity);
PublicKey publicKey = keyPairData.getKeystore().getCertificate(keyPairData.getEntity().getAlias())
.getPublicKey();

Cipher encrypt = Cipher.getInstance(publicKey.getAlgorithm());
encrypt.init(Cipher.ENCRYPT_MODE, publicKey);
byte[] encryptedMessage = encrypt.doFinal(secretEntity.getValue().getBytes(StandardCharsets.UTF_8));

secretEntity.setValue(Base64.getEncoder().withoutPadding().encodeToString(encryptedMessage));
String encryptedValue = encrypt(secretEntity.getValue(), keyPairData);
secretEntity.setValue(encryptedValue);
} catch (Exception e) {
log.warn("Encrypt failed!", e);
throw new GmsException(e, GMS_001);
}
}

public String encrypt(String value, KeystorePair keyPairData)
throws KeyStoreException, NoSuchPaddingException, NoSuchAlgorithmException, InvalidKeyException, IllegalBlockSizeException, BadPaddingException {
PublicKey publicKey = keyPairData.getKeystore().getCertificate(keyPairData.getEntity().getAlias()).getPublicKey();

Cipher encrypt = Cipher.getInstance(publicKey.getAlgorithm());
encrypt.init(Cipher.ENCRYPT_MODE, publicKey);
byte[] encryptedMessage = encrypt.doFinal(value.getBytes(StandardCharsets.UTF_8));
return Base64.getEncoder().withoutPadding().encodeToString(encryptedMessage);
}

private static void validateAliasDto(KeyStore keystore, KeystoreAliasDto dto)
throws KeyStoreException, InvalidKeyException, NoSuchAlgorithmException, NoSuchPaddingException, IllegalBlockSizeException, BadPaddingException, UnrecoverableKeyException {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

import io.github.gms.common.abstraction.GmsController;
import io.github.gms.common.types.SkipSecurityTestCheck;
import io.github.gms.functions.secret.GetSecretRequestDto;
import io.github.gms.functions.secret.dto.GetSecretRequestDto;
import lombok.RequiredArgsConstructor;
import org.springframework.util.MimeTypeUtils;
import org.springframework.web.bind.annotation.GetMapping;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
package io.github.gms.functions.api;

import io.github.gms.functions.secret.GetSecretRequestDto;
import io.github.gms.functions.secret.dto.GetSecretRequestDto;
import io.github.gms.functions.secret.SecretEntity;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
import io.github.gms.functions.iprestriction.IpRestrictionValidator;
import io.github.gms.functions.secret.ApiKeyRestrictionEntity;
import io.github.gms.functions.secret.ApiKeyRestrictionRepository;
import io.github.gms.functions.secret.GetSecretRequestDto;
import io.github.gms.functions.secret.dto.GetSecretRequestDto;
import io.github.gms.functions.secret.SecretEntity;
import io.github.gms.functions.secret.SecretRepository;
import io.github.gms.functions.user.UserRepository;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
import io.github.gms.common.types.Audited;
import io.github.gms.common.types.SkipSecurityTestCheck;
import io.github.gms.common.util.ConverterUtils;
import io.github.gms.functions.secret.GetSecureValueDto;
import io.github.gms.functions.secret.dto.GetSecureValueDto;
import org.springframework.core.io.ByteArrayResource;
import org.springframework.core.io.Resource;
import org.springframework.http.HttpHeaders;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ public KeystorePair getKeystoreData(SecretEntity secretEntity)
return new KeystorePair(keystoreAliasEntity, keystore);
}

private KeyStore getKeyStore(GetKeystore request)
public KeyStore getKeyStore(GetKeystore request)
throws NoSuchAlgorithmException, CertificateException, IOException, KeyStoreException {
KeystoreEntity keystoreEntity = request.getKeystoreEntity();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
import io.github.gms.common.service.CryptoService;
import io.github.gms.common.service.FileService;
import io.github.gms.common.types.GmsException;
import io.github.gms.functions.secret.GetSecureValueDto;
import io.github.gms.functions.secret.dto.GetSecureValueDto;
import lombok.RequiredArgsConstructor;
import lombok.Setter;
import lombok.extern.slf4j.Slf4j;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,12 +1,17 @@
package io.github.gms.functions.secret;

import io.github.gms.common.abstraction.AbstractClientController;
import io.github.gms.common.dto.BooleanValueDto;
import io.github.gms.common.dto.SaveEntityResponseDto;
import io.github.gms.common.enums.EventOperation;
import io.github.gms.common.enums.EventTarget;
import io.github.gms.common.types.AuditTarget;
import io.github.gms.common.types.Audited;
import io.github.gms.common.util.ConverterUtils;
import io.github.gms.functions.secret.dto.SaveSecretRequestDto;
import io.github.gms.functions.secret.dto.SecretDto;
import io.github.gms.functions.secret.dto.SecretListDto;
import io.github.gms.functions.secret.dto.SecretValueDto;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.security.access.prepost.PreAuthorize;
Expand All @@ -24,10 +29,12 @@
public class SecretController extends AbstractClientController<SecretService> {

private final SecretRotationService secretRotationService;
private final SecretLengthValidatorService secretLengthValidatorService;

public SecretController(SecretService service, SecretRotationService secretRotationService) {
public SecretController(SecretService service, SecretRotationService secretRotationService, SecretLengthValidatorService secretLengthValidatorService) {
super(service);
this.secretRotationService = secretRotationService;
this.secretLengthValidatorService = secretLengthValidatorService;
}

@PostMapping
Expand Down Expand Up @@ -67,4 +74,10 @@ public ResponseEntity<String> rotateSecret(@PathVariable(ID) Long id) {
secretRotationService.rotateSecretById(id);
return new ResponseEntity<>(HttpStatus.OK);
}

@PostMapping("/validate_value_length")
@PreAuthorize(ROLE_USER)
public ResponseEntity<BooleanValueDto> validateValueLength(@RequestBody SecretValueDto dto) {
return new ResponseEntity<>(secretLengthValidatorService.validateValueLength(dto), HttpStatus.OK);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@

import io.github.gms.common.abstraction.GmsConverter;
import io.github.gms.common.enums.EntityStatus;
import io.github.gms.functions.secret.dto.SaveSecretRequestDto;
import io.github.gms.functions.secret.dto.SecretDto;
import io.github.gms.functions.secret.dto.SecretListDto;
import lombok.RequiredArgsConstructor;
import org.springframework.data.domain.Page;
import org.springframework.stereotype.Component;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
package io.github.gms.functions.secret;

import io.github.gms.common.dto.BooleanValueDto;
import io.github.gms.common.model.GetKeystore;
import io.github.gms.common.model.KeystorePair;
import io.github.gms.common.service.CryptoService;
import io.github.gms.common.types.GmsException;
import io.github.gms.functions.keystore.*;
import io.github.gms.functions.secret.dto.SecretValueDto;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import java.security.KeyStore;

import static io.github.gms.common.types.ErrorCode.GMS_002;
import static io.github.gms.common.util.Constants.SLASH;

/**
* @author Peter Szrnka
* @since 1.0
*/
@Slf4j
@Service
@RequiredArgsConstructor
public class SecretLengthValidatorService {

private final KeystoreRepository keystoreRepository;
private final KeystoreAliasRepository keystoreAliasRepository;
private final KeystoreDataService keystoreDataService;
private final CryptoService cryptoService;

@Value("${config.location.keystore.path}")
private String keystorePath;

public BooleanValueDto validateValueLength(SecretValueDto dto) {
try {
KeystoreEntity keystoreEntity = keystoreRepository.findById(dto.getKeystoreId())
.orElseThrow(() -> new GmsException("KeystoreEntity not found!", GMS_002));

KeystoreAliasEntity keystoreAliasEntity = keystoreAliasRepository.findById(dto.getKeystoreAliasId())
.orElseThrow(() -> new GmsException("KeystoreAliasEntity not found!", GMS_002));

KeyStore keystore = keystoreDataService.getKeyStore(GetKeystore.builder()
.keystoreEntity(keystoreEntity)
.keystorePath(keystorePath + keystoreEntity.getUserId() + SLASH + keystoreEntity.getFileName())
.build());

String encryptedValue = cryptoService.encrypt(dto.getValue(), new KeystorePair(keystoreAliasEntity, keystore));

log.info("Encrypted secret value size: {}", encryptedValue.length());
return new BooleanValueDto(true);
} catch (Exception e) {
return new BooleanValueDto(false);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,9 @@
import io.github.gms.common.abstraction.BatchDeletionService;
import io.github.gms.common.dto.SaveEntityResponseDto;
import io.github.gms.common.service.CountService;
import io.github.gms.functions.secret.dto.SaveSecretRequestDto;
import io.github.gms.functions.secret.dto.SecretDto;
import io.github.gms.functions.secret.dto.SecretListDto;

/**
* @author Peter Szrnka
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,9 @@
import io.github.gms.functions.keystore.KeystoreAliasEntity;
import io.github.gms.functions.keystore.KeystoreAliasRepository;
import io.github.gms.functions.keystore.KeystoreRepository;
import io.github.gms.functions.secret.dto.SaveSecretRequestDto;
import io.github.gms.functions.secret.dto.SecretDto;
import io.github.gms.functions.secret.dto.SecretListDto;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.cache.annotation.CacheConfig;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package io.github.gms.functions.secret;
package io.github.gms.functions.secret.dto;

import io.github.gms.common.types.Sensitive;
import lombok.AllArgsConstructor;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package io.github.gms.functions.secret;
package io.github.gms.functions.secret.dto;

import com.fasterxml.jackson.annotation.JsonInclude;
import io.github.gms.common.enums.KeyStoreValueType;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package io.github.gms.functions.secret;
package io.github.gms.functions.secret.dto;

import com.fasterxml.jackson.annotation.JsonInclude;
import io.github.gms.common.enums.EntityStatus;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package io.github.gms.functions.secret;
package io.github.gms.functions.secret.dto;

import com.fasterxml.jackson.annotation.JsonFormat;
import com.fasterxml.jackson.annotation.JsonInclude;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package io.github.gms.functions.secret;
package io.github.gms.functions.secret.dto;

import lombok.AllArgsConstructor;
import lombok.Builder;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package io.github.gms.functions.secret.dto;

import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Getter;
import lombok.NoArgsConstructor;

@Getter
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class SecretValueDto {

private Long keystoreId;
private Long keystoreAliasId;
private String value;
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
package io.github.gms.functions.api;

import io.github.gms.functions.secret.GetSecretRequestDto;
import io.github.gms.functions.secret.dto.GetSecretRequestDto;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.junit.jupiter.MockitoExtension;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
package io.github.gms.functions.api;

import io.github.gms.abstraction.AbstractLoggingUnitTest;
import io.github.gms.functions.secret.GetSecretRequestDto;
import io.github.gms.functions.secret.dto.GetSecretRequestDto;
import io.github.gms.functions.secret.SecretEntity;
import io.github.gms.util.TestUtils;
import org.junit.jupiter.api.BeforeEach;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
import io.github.gms.functions.iprestriction.IpRestrictionService;
import io.github.gms.functions.iprestriction.IpRestrictionValidator;
import io.github.gms.functions.secret.ApiKeyRestrictionRepository;
import io.github.gms.functions.secret.GetSecretRequestDto;
import io.github.gms.functions.secret.dto.GetSecretRequestDto;
import io.github.gms.functions.secret.SecretEntity;
import io.github.gms.functions.secret.SecretRepository;
import io.github.gms.functions.user.UserEntity;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
import io.github.gms.common.dto.IdNamePairListDto;
import io.github.gms.common.dto.SaveEntityResponseDto;
import io.github.gms.common.enums.EntityStatus;
import io.github.gms.functions.secret.GetSecureValueDto;
import io.github.gms.functions.secret.dto.GetSecureValueDto;
import io.github.gms.util.DemoData;
import io.github.gms.util.TestUtils;
import org.junit.jupiter.api.Tag;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
import io.github.gms.abstraction.AbstractAdminRoleSecurityTest;
import io.github.gms.common.TestedClass;
import io.github.gms.common.TestedMethod;
import io.github.gms.functions.secret.GetSecureValueDto;
import io.github.gms.functions.secret.dto.GetSecureValueDto;
import io.github.gms.util.DemoData;
import io.github.gms.util.TestUtils;
import org.junit.jupiter.api.Tag;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
import io.github.gms.common.dto.IdNamePairListDto;
import io.github.gms.common.dto.SaveEntityResponseDto;
import io.github.gms.common.util.ConverterUtils;
import io.github.gms.functions.secret.GetSecureValueDto;
import io.github.gms.functions.secret.dto.GetSecureValueDto;
import io.github.gms.util.TestUtils;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
import io.github.gms.common.enums.EntityStatus;
import io.github.gms.common.enums.KeyStoreValueType;
import io.github.gms.common.filter.SecureHeaderInitializerFilter;
import io.github.gms.functions.secret.GetSecureValueDto;
import io.github.gms.functions.secret.dto.GetSecureValueDto;
import io.github.gms.util.DemoData;
import io.github.gms.util.TestUtils;
import io.github.gms.util.TestUtils.ValueHolder;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
import io.github.gms.common.service.FileService;
import io.github.gms.common.types.GmsException;
import io.github.gms.common.util.ConverterUtils;
import io.github.gms.functions.secret.GetSecureValueDto;
import io.github.gms.functions.secret.dto.GetSecureValueDto;
import io.github.gms.util.DemoData;
import io.github.gms.util.TestUtils;
import io.github.gms.util.TestUtils.ValueHolder;
Expand Down
Loading

0 comments on commit 25634fe

Please sign in to comment.