Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

GMS-177 secret value size calculator #357

Merged
merged 7 commits into from
Dec 10, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
Loading