package io.fathom.cloud.compute.services;
import io.fathom.cloud.CloudException;
import io.fathom.cloud.compute.state.ComputeRepository;
import io.fathom.cloud.protobuf.CloudModel.KeyPairData;
import io.fathom.cloud.server.model.Project;
import io.fathom.cloud.state.DuplicateValueException;
import io.fathom.cloud.state.NamedItemCollection;
import java.security.PublicKey;
import java.util.List;
import javax.inject.Inject;
import javax.inject.Singleton;
import javax.ws.rs.WebApplicationException;
import javax.ws.rs.core.Response.Status;
import org.keyczar.DefaultKeyType;
import org.keyczar.KeyMetadata;
import org.keyczar.KeyczarKey;
import org.keyczar.KeyczarUtils;
import org.keyczar.enums.KeyPurpose;
import com.fathomdb.crypto.OpenSshUtils;
import com.google.inject.persist.Transactional;
@Singleton
@Transactional
public class SshKeyPairs {
@Inject
ComputeRepository repository;
public KeyPairData findKeyPair(Project project, String id) throws CloudException {
return getKeyPairsStore(project).find(id);
}
NamedItemCollection<KeyPairData> getKeyPairsStore(Project project) throws CloudException {
return repository.getKeypairs(project.getId());
}
public List<KeyPairData> list(Project project) throws CloudException {
return getKeyPairsStore(project).list();
}
public KeyPairData create(Project project, KeyPairData.Builder keyPairData) throws CloudException,
DuplicateValueException {
return getKeyPairsStore(project).create(keyPairData);
}
public boolean delete(Project project, String id) throws CloudException {
NamedItemCollection<KeyPairData> store = getKeyPairsStore(project);
KeyPairData keypair = store.find(id);
if (keypair == null) {
return false;
}
store.delete(id);
return true;
}
public KeyczarKey generateKeypair() {
try {
KeyczarKey keypair = KeyczarUtils.createKey(new KeyMetadata("RSA Key", KeyPurpose.DECRYPT_AND_ENCRYPT,
DefaultKeyType.RSA_PRIV));
return keypair;
} catch (Exception e) {
throw new IllegalStateException("Error generating keypair", e);
}
}
public KeyPairData create(Project project, String name, PublicKey publicKey) throws CloudException {
KeyPairData.Builder keyPairData = KeyPairData.newBuilder();
keyPairData.setKey(name);
String publicKeyString = OpenSshUtils.serialize(publicKey);
keyPairData.setPublicKey(publicKeyString);
String publicKeyFingerprint = OpenSshUtils.getSignatureString(publicKey);
if (publicKeyFingerprint != null) {
StringBuilder sb = new StringBuilder();
for (int i = 0; i < publicKeyFingerprint.length(); i += 2) {
if (i != 0) {
sb.append(":");
}
sb.append(publicKeyFingerprint.substring(i, i + 2));
}
keyPairData.setPublicKeyFingerprint(sb.toString());
}
try {
KeyPairData created = create(project, keyPairData);
return created;
} catch (DuplicateValueException e) {
throw new WebApplicationException(Status.CONFLICT);
}
}
}