SecretManagementService { public void storeSecrets(final String deviceIdentification, final List<TypedSecret> secrets) { secrets.stream() .map(t -> this.validateSecret(deviceIdentification, t)) .map(s -> this.createEncrypted(deviceIdentification, s, this.getKey())) .forEach(this.secretRepository::save); } SecretManagementService(
            @Qualifier("DefaultEncryptionDelegate") final EncryptionDelegate defaultEncryptionDelegate,
            final EncryptionProviderType encryptionProviderType, final DbEncryptedSecretRepository secretRepository,
            final DbEncryptionKeyRepository keyRepository); void storeSecrets(final String deviceIdentification, final List<TypedSecret> secrets); List<TypedSecret> retrieveSecrets(final String deviceIdentification, final List<SecretType> secretTypes); Optional<TypedSecret> retrieveSecret(final String deviceIdentification, final SecretType secretType);  }
@Test public void storeSecrets() throws Exception { final TypedSecret typedSecret = new TypedSecret(); typedSecret.setSecretType(SecretType.E_METER_MASTER_KEY); typedSecret.setSecret(HexUtils.toHexString("$3cr3t".getBytes())); final DbEncryptionKeyReference keyReference = new DbEncryptionKeyReference(); keyReference.setEncryptionProviderType(EncryptionProviderType.JRE); keyReference.setReference("keyReferenceString"); final EncryptedSecret encryptedSecret = new EncryptedSecret(EncryptionProviderType.JRE, "$3cr3t".getBytes()); final DbEncryptedSecret dbEncryptedSecret = new DbEncryptedSecret(); when(this.secretRepository.findIdOfValidMostRecent(any(), any(), any())).thenReturn(null); when(this.keyRepository.findByTypeAndValid(any(), any(), any())).thenReturn( new PageImpl<>(Arrays.asList(keyReference))); when(this.encryptionDelegate.encrypt(any(), any(), anyString())).thenReturn(encryptedSecret); this.service.storeSecrets("SOME_DEVICE", Arrays.asList(typedSecret)); final ArgumentCaptor<DbEncryptedSecret> secretArgumentCaptor = ArgumentCaptor.forClass(DbEncryptedSecret.class); verify(this.secretRepository).save(secretArgumentCaptor.capture()); final DbEncryptedSecret savedSecret = secretArgumentCaptor.getValue(); assertThat(savedSecret).isNotNull(); assertThat(savedSecret.getDeviceIdentification()).isEqualTo("SOME_DEVICE"); assertThat(savedSecret.getSecretType()).isEqualTo(typedSecret.getSecretType()); assertThat(savedSecret.getEncodedSecret()).isEqualTo(HexUtils.toHexString(encryptedSecret.getSecret())); assertThat(savedSecret.getEncryptionKeyReference()).isEqualTo(keyReference); assertThat(savedSecret.getCreationTime()).isNotNull(); }
@Test public void storeSecrets_secretNull() { final TypedSecret typedSecret = new TypedSecret(); typedSecret.setSecretType(SecretType.E_METER_MASTER_KEY); final DbEncryptionKeyReference keyReference = new DbEncryptionKeyReference(); keyReference.setEncryptionProviderType(EncryptionProviderType.JRE); keyReference.setReference("keyReferenceString"); assertThatIllegalArgumentException().isThrownBy( () -> this.service.storeSecrets("SOME_DEVICE", Arrays.asList(typedSecret))); }
@Test public void storeSecrets_secretTypeNull() { final TypedSecret typedSecret = new TypedSecret(); typedSecret.setSecret(HexUtils.toHexString("$3cr3t".getBytes())); final DbEncryptionKeyReference keyReference = new DbEncryptionKeyReference(); keyReference.setEncryptionProviderType(EncryptionProviderType.JRE); keyReference.setReference("keyReferenceString"); assertThatIllegalArgumentException().isThrownBy( () -> this.service.storeSecrets("SOME_DEVICE", Arrays.asList(typedSecret))); }
@Test public void storeSecrets_noKey() { final TypedSecret typedSecret = new TypedSecret(); typedSecret.setSecretType(SecretType.E_METER_MASTER_KEY); typedSecret.setSecret(HexUtils.toHexString("$3cr3t".getBytes())); when(this.secretRepository.findIdOfValidMostRecent(any(), any(), any())).thenReturn(null); when(this.keyRepository.findByTypeAndValid(any(), any(), any())).thenReturn(Page.empty()); assertThatExceptionOfType(NoSuchElementException.class).isThrownBy( () -> this.service.storeSecrets("SOME_DEVICE", Arrays.asList(typedSecret))); }
@Test public void storeSecrets_multipleKeys() { final TypedSecret typedSecret = new TypedSecret(); typedSecret.setSecretType(SecretType.E_METER_MASTER_KEY); typedSecret.setSecret(HexUtils.toHexString("$3cr3t".getBytes())); when(this.secretRepository.findIdOfValidMostRecent(any(), any(), any())).thenReturn(null); when(this.keyRepository.findByTypeAndValid(any(), any(), any())).thenReturn( new PageImpl<>(Arrays.asList(new DbEncryptionKeyReference(), new DbEncryptionKeyReference()))); try { this.service.storeSecrets("SOME_DEVICE", Arrays.asList(typedSecret)); } catch (final Exception exc) { } assertThatIllegalStateException().isThrownBy( () -> this.service.storeSecrets("SOME_DEVICE", Arrays.asList(typedSecret))); }
@Test public void storeSecrets_encryptionError() { final TypedSecret typedSecret = new TypedSecret(); typedSecret.setSecretType(SecretType.E_METER_MASTER_KEY); typedSecret.setSecret(HexUtils.toHexString("$3cr3t".getBytes())); final DbEncryptionKeyReference keyReference = new DbEncryptionKeyReference(); keyReference.setEncryptionProviderType(EncryptionProviderType.JRE); keyReference.setReference("keyReferenceString"); when(this.secretRepository.findIdOfValidMostRecent(any(), any(), any())).thenReturn(null); when(this.keyRepository.findByTypeAndValid(any(), any(), any())).thenReturn( new PageImpl<>(Arrays.asList(keyReference))); when(this.encryptionDelegate.encrypt(any(), any(), anyString())).thenThrow( new RuntimeException("Encryption error")); assertThatIllegalStateException().isThrownBy( () -> this.service.storeSecrets("SOME_DEVICE", Arrays.asList(typedSecret))); }
@Test public void storeSecrets_existingSecret() throws Exception { final TypedSecret typedSecret = new TypedSecret(); typedSecret.setSecretType(SecretType.E_METER_MASTER_KEY); typedSecret.setSecret(HexUtils.toHexString("$3cr3t".getBytes())); final DbEncryptionKeyReference keyReference = new DbEncryptionKeyReference(); keyReference.setEncryptionProviderType(EncryptionProviderType.JRE); keyReference.setReference("keyReferenceString"); final EncryptedSecret encryptedSecret = new EncryptedSecret(EncryptionProviderType.JRE, "$3cr3t".getBytes()); final DbEncryptedSecret existingDbSecret = new DbEncryptedSecret(); existingDbSecret.setCreationTime(new Date()); existingDbSecret.setSecretType(SecretType.E_METER_MASTER_KEY); existingDbSecret.setEncodedSecret("1234567890ABCDEF"); existingDbSecret.setDeviceIdentification("SOME_DEVICE"); existingDbSecret.setEncryptionKeyReference(keyReference); when(this.secretRepository.findIdOfValidMostRecent(any(), any(), any())).thenReturn(1L); when(this.secretRepository.findById(1L)).thenReturn(Optional.of(existingDbSecret)); when(this.keyRepository.findByTypeAndValid(any(), any(), any())).thenReturn( new PageImpl<>(Arrays.asList(keyReference))); when(this.encryptionDelegate.decrypt(any(), any())).thenReturn( new Secret(existingDbSecret.getEncodedSecret().getBytes())); when(this.encryptionDelegate.encrypt(any(), any(), anyString())).thenReturn( encryptedSecret); this.service.storeSecrets("SOME_DEVICE", Arrays.asList(typedSecret)); final ArgumentCaptor<DbEncryptedSecret> secretArgumentCaptor = ArgumentCaptor.forClass(DbEncryptedSecret.class); verify(this.secretRepository).save(secretArgumentCaptor.capture()); final DbEncryptedSecret savedSecret = secretArgumentCaptor.getValue(); assertThat(savedSecret).isNotNull(); assertThat(savedSecret.getDeviceIdentification()).isEqualTo("SOME_DEVICE"); assertThat(savedSecret.getSecretType()).isEqualTo(typedSecret.getSecretType()); assertThat(savedSecret.getEncodedSecret()).isEqualTo(HexUtils.toHexString(encryptedSecret.getSecret())); assertThat(savedSecret.getEncryptionKeyReference()).isEqualTo(keyReference); assertThat(savedSecret.getCreationTime()).isNotNull(); }
@Test public void storeSecrets_existingIdenticalSecret() { final TypedSecret newTypedSecret = new TypedSecret(); newTypedSecret.setSecretType(SecretType.E_METER_MASTER_KEY); newTypedSecret.setSecret(HexUtils.toHexString("$3cr3t".getBytes())); final DbEncryptionKeyReference keyReference = new DbEncryptionKeyReference(); keyReference.setEncryptionProviderType(EncryptionProviderType.JRE); keyReference.setReference("keyReferenceString"); final EncryptedSecret newEncryptedSecret = new EncryptedSecret(EncryptionProviderType.JRE, "$3cr3t".getBytes()); final DbEncryptedSecret existingDbSecret = new DbEncryptedSecret(); existingDbSecret.setCreationTime(new Date()); existingDbSecret.setSecretType(SecretType.E_METER_MASTER_KEY); existingDbSecret.setEncodedSecret("1234567890ABCDEF"); existingDbSecret.setDeviceIdentification("SOME_DEVICE"); existingDbSecret.setEncryptionKeyReference(keyReference); when(this.secretRepository.findIdOfValidMostRecent(any(), any(), any())).thenReturn(1L); when(this.secretRepository.findById(1L)).thenReturn(Optional.of(existingDbSecret)); when(this.encryptionDelegate.decrypt(any(), any())).thenReturn( new Secret(HexUtils.fromHexString(newTypedSecret.getSecret()))); assertThatIllegalArgumentException().isThrownBy( () -> this.service.storeSecrets("SOME_DEVICE", Arrays.asList(newTypedSecret))).withMessageContaining( "identical to current"); }