com.spotify.dbeam.options.KmsDecrypter Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of dbeam-core Show documentation
Show all versions of dbeam-core Show documentation
Top level DBeam core implementation
/*-
* -\-\-
* DBeam Core
* --
* Copyright (C) 2016 - 2018 Spotify AB
* --
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
* -/-/-
*/
package com.spotify.dbeam.options;
import com.google.api.client.googleapis.util.Utils;
import com.google.api.client.http.HttpRequestInitializer;
import com.google.api.client.http.HttpTransport;
import com.google.api.client.json.JsonFactory;
import com.google.api.services.cloudkms.v1.CloudKMS;
import com.google.api.services.cloudkms.v1.CloudKMSScopes;
import com.google.api.services.cloudkms.v1.model.DecryptRequest;
import com.google.api.services.cloudkms.v1.model.DecryptResponse;
import com.google.auth.Credentials;
import com.google.auth.http.HttpCredentialsAdapter;
import com.google.auth.oauth2.GoogleCredentials;
import com.google.auto.value.AutoValue;
import com.google.cloud.ServiceOptions;
import com.google.common.base.CharMatcher;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.charset.StandardCharsets;
import java.util.Base64;
import java.util.Optional;
import java.util.Properties;
@AutoValue
public abstract class KmsDecrypter {
private static final String KEYRING;
private static final String KEY;
private static final String LOCATION;
private static final String PROJECT;
static {
Properties p = System.getProperties();
KEYRING = p.getProperty("KMS_KEYRING", "dbeam");
KEY = p.getProperty("KMS_KEY", "default");
LOCATION = p.getProperty("KMS_LOCATION", "global");
PROJECT = p.getProperty("KMS_PROJECT");
}
/**
* Create a new {@link Builder} for customizing the {@link KmsDecrypter} configuration.
*
* @return a configured {@link KmsDecrypter}
*/
public static Builder decrypter() {
return new AutoValue_KmsDecrypter.Builder()
.location(LOCATION)
.key(KEY)
.keyring(KEYRING)
.project(Optional.ofNullable(PROJECT));
}
/** The location of the KMS key to use for decryption. */
abstract String location();
/** The ring of the KMS key to use for decryption. */
abstract String keyring();
/** The name of the KMS key to use for decryption. */
abstract String key();
/**
* The GCP project KMS key to use for decryption. Will be detected from credentials or gcloud sdk
* if not set.
*/
abstract Optional project();
/**
* The {@link HttpTransport} to use for the default credentials and KMS client. Default will be
* used if not set.
*/
abstract Optional transport();
/** The {@link Credentials} to use for the KMS client. Default will be used if not set. */
abstract Optional credentials();
public abstract Builder builder();
@AutoValue.Builder
public abstract static class Builder {
public abstract Builder location(String location);
public abstract Builder keyring(String keyring);
public abstract Builder key(String keyring);
public abstract Builder project(Optional project);
public abstract Builder transport(HttpTransport transport);
public abstract Builder credentials(Credentials credentials);
public abstract KmsDecrypter build();
}
/** Decrypt a base64 encoded cipher text string. */
String decrypt(final String base64Ciphertext) throws IOException {
return StandardCharsets.UTF_8.decode(decryptBinary(base64Ciphertext)).toString();
}
/**
* Decrypt a base64 encoded cipher text string.
*
* @return A {@link ByteBuffer} with the raw contents.
*/
ByteBuffer decryptBinary(final String base64Ciphertext) throws IOException {
final String project = project().orElseGet(ServiceOptions::getDefaultProjectId);
final String keyName =
String.format(
"projects/%s/locations/%s/keyRings/%s/cryptoKeys/%s",
project, location(), keyring(), key());
final DecryptResponse response =
kms()
.projects()
.locations()
.keyRings()
.cryptoKeys()
.decrypt(
keyName,
new DecryptRequest()
.setCiphertext(CharMatcher.whitespace().removeFrom(base64Ciphertext)))
.execute();
return ByteBuffer.wrap(Base64.getDecoder().decode(response.getPlaintext()));
}
private CloudKMS kms() throws IOException {
final HttpTransport transport = transport().orElseGet(Utils::getDefaultTransport);
final JsonFactory jsonFactory = Utils.getDefaultJsonFactory();
final Credentials credentials =
credentials().isPresent() ? credentials().get() : GoogleCredentials.getApplicationDefault();
return KmsDecrypter.kms(
transport, jsonFactory, new HttpCredentialsAdapter(scoped(credentials)));
}
private static CloudKMS kms(
final HttpTransport transport,
final JsonFactory jsonFactory,
final HttpRequestInitializer httpRequestInitializer) {
return new CloudKMS.Builder(transport, jsonFactory, httpRequestInitializer)
.setApplicationName("dbeam")
.build();
}
private static Credentials scoped(final Credentials credentials) {
if (credentials instanceof GoogleCredentials) {
return ((GoogleCredentials) credentials).createScoped(CloudKMSScopes.all());
}
return credentials;
}
}
© 2015 - 2024 Weber Informatics LLC | Privacy Policy