Search in sources :

Example 1 with Key

use of org.c02e.jpgpj.Key in project keywhiz by square.

the class BackupResource method backup.

/**
 * Backup all secrets for a given group. Returns an encrypted encrypted to
 * the backup key in the main configuration file. Only accessible to automation clients.
 *
 * @param name Group name
 *
 * @return Encrypted archive
 */
@Timed
@ExceptionMetered
@GET
@Path("{key}/group/{group}")
@Produces(APPLICATION_OCTET_STREAM)
public byte[] backup(@Auth AutomationClient automationClient, @PathParam("group") String name, @PathParam("key") String key) {
    if (config.getBackupExportKey(key) == null) {
        throw new NotFoundException("Unknown key: " + key);
    }
    Optional<Group> groupOptional = groupDAO.getGroup(name);
    if (!groupOptional.isPresent()) {
        throw new NotFoundException("Unknown group: " + name);
    }
    Group group = groupOptional.get();
    // SecretDeliveryResponse is the same data a client receives when requesting a secret,
    // so it should have all the relevant information we need (including content, checksum).
    List<SecretDeliveryResponse> secrets = secretController.getSecretsForGroup(group).stream().map(SecretDeliveryResponse::fromSecret).collect(toList());
    String serialized;
    try {
        serialized = objectMapper.writeValueAsString(secrets);
    } catch (JsonProcessingException e) {
        // This should never happen
        logger.error("Unable to backup secrets", e);
        throw new InternalServerErrorException("Unable to backup secrets, check logs for details");
    }
    // Record all checksums of backed up/exported secrets so we can uniquely identify which
    // particular contents were returned in the response from inspection of the audit log.
    Map<String, String> auditInfo = secrets.stream().collect(toMap(SecretDeliveryResponse::getName, SecretDeliveryResponse::getChecksum));
    // Record audit event
    auditLog.recordEvent(new Event(now(), GROUP_BACKUP, automationClient.getName(), group.getName(), auditInfo));
    // Perform encryption & return encrypted data
    try {
        Key exportKey = new Key(config.getBackupExportKey(key));
        Encryptor encryptor = new Encryptor(exportKey);
        encryptor.setEncryptionAlgorithm(AES256);
        encryptor.setSigningAlgorithm(Unsigned);
        encryptor.setCompressionAlgorithm(ZIP);
        ByteArrayInputStream plaintext = new ByteArrayInputStream(serialized.getBytes(UTF_8));
        ByteArrayOutputStream ciphertext = new ByteArrayOutputStream();
        encryptor.encrypt(plaintext, ciphertext, new FileMetadata(format("%s.json", group), UTF8));
        return ciphertext.toByteArray();
    } catch (PGPException | IOException e) {
        logger.error("Unable to backup secrets", e);
        throw new InternalServerErrorException("Unable to backup secrets, check logs for details");
    }
}
Also used : Group(keywhiz.api.model.Group) FileMetadata(org.c02e.jpgpj.FileMetadata) NotFoundException(javax.ws.rs.NotFoundException) Encryptor(org.c02e.jpgpj.Encryptor) ByteArrayOutputStream(java.io.ByteArrayOutputStream) IOException(java.io.IOException) SecretDeliveryResponse(keywhiz.api.SecretDeliveryResponse) PGPException(org.bouncycastle.openpgp.PGPException) ByteArrayInputStream(java.io.ByteArrayInputStream) InternalServerErrorException(javax.ws.rs.InternalServerErrorException) Event(keywhiz.log.Event) JsonProcessingException(com.fasterxml.jackson.core.JsonProcessingException) Key(org.c02e.jpgpj.Key) Path(javax.ws.rs.Path) Produces(javax.ws.rs.Produces) Timed(com.codahale.metrics.annotation.Timed) GET(javax.ws.rs.GET) ExceptionMetered(com.codahale.metrics.annotation.ExceptionMetered)

Example 2 with Key

use of org.c02e.jpgpj.Key in project keywhiz by square.

the class BackupResourceTest method backupSuccess.

@Test
public void backupSuccess() throws Exception {
    Response httpResponse = backup("test", "Blackops");
    assertThat(httpResponse.code()).isEqualTo(200);
    InputStream ciphertext = httpResponse.body().byteStream();
    ByteArrayOutputStream plaintext = new ByteArrayOutputStream();
    Key key = new Key(TEST_EXPORT_KEY_PRIVATE, "password");
    // Decrypt and make sure we have expected data in the encrypted backup
    Decryptor decryptor = new Decryptor(key);
    decryptor.setVerificationRequired(false);
    decryptor.decrypt(ciphertext, plaintext);
    List<SecretDeliveryResponse> output = mapper.readValue(plaintext.toByteArray(), new TypeReference<List<SecretDeliveryResponse>>() {
    });
    assertThat(output).extracting(SecretDeliveryResponse::getName).containsExactlyInAnyOrder("Hacking_Password", "General_Password");
    assertThat(output).extracting(SecretDeliveryResponse::getSecret).allMatch(s -> !Strings.isNullOrEmpty(s));
}
Also used : SecretDeliveryResponse(keywhiz.api.SecretDeliveryResponse) Response(okhttp3.Response) Decryptor(org.c02e.jpgpj.Decryptor) InputStream(java.io.InputStream) List(java.util.List) ByteArrayOutputStream(java.io.ByteArrayOutputStream) Key(org.c02e.jpgpj.Key) SecretDeliveryResponse(keywhiz.api.SecretDeliveryResponse) Test(org.junit.Test)

Aggregations

ByteArrayOutputStream (java.io.ByteArrayOutputStream)2 SecretDeliveryResponse (keywhiz.api.SecretDeliveryResponse)2 Key (org.c02e.jpgpj.Key)2 ExceptionMetered (com.codahale.metrics.annotation.ExceptionMetered)1 Timed (com.codahale.metrics.annotation.Timed)1 JsonProcessingException (com.fasterxml.jackson.core.JsonProcessingException)1 ByteArrayInputStream (java.io.ByteArrayInputStream)1 IOException (java.io.IOException)1 InputStream (java.io.InputStream)1 List (java.util.List)1 GET (javax.ws.rs.GET)1 InternalServerErrorException (javax.ws.rs.InternalServerErrorException)1 NotFoundException (javax.ws.rs.NotFoundException)1 Path (javax.ws.rs.Path)1 Produces (javax.ws.rs.Produces)1 Group (keywhiz.api.model.Group)1 Event (keywhiz.log.Event)1 Response (okhttp3.Response)1 PGPException (org.bouncycastle.openpgp.PGPException)1 Decryptor (org.c02e.jpgpj.Decryptor)1