Skip to content
Open
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
15 changes: 12 additions & 3 deletions api/src/com/cloud/network/lb/CertService.java
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,9 @@
// under the License.
package com.cloud.network.lb;

import java.io.IOException;
import java.security.PrivateKey;
import java.security.cert.Certificate;
import java.util.List;

import org.apache.cloudstack.api.command.user.loadbalancer.DeleteSslCertCmd;
Expand All @@ -25,9 +28,15 @@

public interface CertService {

public SslCertResponse uploadSslCert(UploadSslCertCmd certCmd);
SslCertResponse uploadSslCert(UploadSslCertCmd certCmd);

public void deleteSslCert(DeleteSslCertCmd deleteSslCertCmd);
void deleteSslCert(DeleteSslCertCmd deleteSslCertCmd);

public List<SslCertResponse> listSslCerts(ListSslCertsCmd listSslCertCmd);
List<SslCertResponse> listSslCerts(ListSslCertsCmd listSslCertCmd);

Certificate parseCertificate(final String cert);

void validateChain(final List<Certificate> chain, final Certificate cert);

PrivateKey parsePrivateKey(final String key) throws IOException;
}
13 changes: 13 additions & 0 deletions api/src/com/cloud/server/ManagementService.java
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,9 @@
// under the License.
package com.cloud.server;

import java.io.IOException;
import java.security.KeyStoreException;
import java.security.cert.CertificateException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
Expand All @@ -38,6 +41,7 @@
import org.apache.cloudstack.api.command.admin.resource.ListAlertsCmd;
import org.apache.cloudstack.api.command.admin.resource.ListCapacityCmd;
import org.apache.cloudstack.api.command.admin.resource.UploadCustomCertificateCmd;
import org.apache.cloudstack.api.command.admin.resource.UploadCustomCertificateWithValidationCmd;
import org.apache.cloudstack.api.command.admin.systemvm.DestroySystemVmCmd;
import org.apache.cloudstack.api.command.admin.systemvm.ListSystemVMsCmd;
import org.apache.cloudstack.api.command.admin.systemvm.RebootSystemVmCmd;
Expand Down Expand Up @@ -325,6 +329,15 @@ public interface ManagementService {
*/
String uploadCertificate(UploadCustomCertificateCmd cmd);

/**
* This method uploads a custom cert to the db and performs the proper validations on it, and patches every cpvm with it on the current ms
*
* @param cmd
* -- upload certificate cmd
* @return -- returns a string on success
*/
String uploadCertificateWithValidation(UploadCustomCertificateWithValidationCmd cmd) throws KeyStoreException, CertificateException, IOException;

String getVersion();

/**
Expand Down
6 changes: 6 additions & 0 deletions api/src/org/apache/cloudstack/api/ApiConstants.java
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,9 @@ public class ApiConstants {
public static final String CATEGORY = "category";
public static final String CAN_REVERT = "canrevert";
public static final String CERTIFICATE = "certificate";
public static final String ROOT_CERTIFICATE = "rootcertificate";
public static final String INTERMIDIATE_CERTIFICATES = "intermediatecertificates";
public static final String SERVER_CERTIFICATE = "servercertificate";
public static final String CERTIFICATE_CHAIN = "certchain";
public static final String CERTIFICATE_FINGERPRINT = "fingerprint";
public static final String CERTIFICATE_ID = "certid";
Expand Down Expand Up @@ -646,6 +649,9 @@ public class ApiConstants {

public static final String ADMIN = "admin";

public static final String HAS_ANNOTATION = "hasannotation";
public static final String LAST_ANNOTATED = "lastannotated";

public static final String SHOWHIDDEN = "showhidden";

public enum HostDetails {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
package org.apache.cloudstack.api.command.admin.resource;

import java.io.IOException;
import java.security.KeyStoreException;
import java.security.cert.CertificateException;
import java.util.Map;

import org.apache.cloudstack.api.APICommand;
import org.apache.cloudstack.api.ApiConstants;
import org.apache.cloudstack.api.ApiErrorCode;
import org.apache.cloudstack.api.BaseAsyncCmd;
import org.apache.cloudstack.api.Parameter;
import org.apache.cloudstack.api.ServerApiException;
import org.apache.cloudstack.api.response.CustomCertificateResponse;
import org.apache.log4j.Logger;

import com.cloud.event.EventTypes;
import com.cloud.exception.ConcurrentOperationException;
import com.cloud.exception.InsufficientCapacityException;
import com.cloud.exception.NetworkRuleConflictException;
import com.cloud.exception.ResourceAllocationException;
import com.cloud.exception.ResourceUnavailableException;
import com.cloud.user.Account;

@APICommand(name = "uploadCustomCertificateWithValidation", responseObject = CustomCertificateResponse.class, description = "Uploads a custom certificate for the console proxy VMs to use for SSL using an endpoint with proper validation. "
+ "Can be used to upload a single certificate signed by a known CA. Can also be used, through multiple calls, to upload a "
+ "chain of certificates from CA to the custom certificate itself.", requestHasSensitiveInfo = true, responseHasSensitiveInfo = false)
public class UploadCustomCertificateWithValidationCmd extends BaseAsyncCmd {

public static final Logger s_logger = Logger.getLogger(UploadCustomCertificateCmd.class.getName());
private static final String s_name = "uploadcustomcertificateresponse";

@Parameter(name = ApiConstants.ROOT_CERTIFICATE, type = CommandType.STRING, required = false, description = "The root certificate to be uploaded.", length = 65535)
private String rootCertificate;

@Parameter(name = ApiConstants.INTERMIDIATE_CERTIFICATES, type = CommandType.MAP, required = false, description = "The list of intermediate certificates to be uploaded.")
private Map<Integer, String> intermediateCertificates;

@Parameter(name = ApiConstants.SERVER_CERTIFICATE, type = CommandType.STRING, required = true, description = "The server certificate to be uploaded.", length = 65535)
private String serverCertificate;

@Parameter(name = ApiConstants.PRIVATE_KEY, type = CommandType.STRING, required = true, description = "The private key for the attached certificate.", length = 65535)
private String privateKey;

@Parameter(name = ApiConstants.DOMAIN_SUFFIX, type = CommandType.STRING, required = true, description = "DNS domain suffix that the certificate is granted for.")
private String domainSuffix;

public String getRootCertificate() {
return rootCertificate;
}

public Map<Integer, String> getIntermediateCertificates() {
return intermediateCertificates;
}

public String getServerCertificate() {
return serverCertificate;
}

public String getPrivateKey() {
return privateKey;
}

public String getDomainSuffix() {
return domainSuffix;
}

@Override
public String getEventType() {
return EventTypes.EVENT_UPLOAD_CUSTOM_CERTIFICATE;
}

@Override
public String getEventDescription() {
return ("Uploading custom certificate to the db with validation, and applying it to all the cpvms in the system");
}

@Override
public String getCommandName() {
return s_name;
}

@Override
public long getEntityOwnerId() {
return Account.ACCOUNT_ID_SYSTEM; // no account info given, parent this command to SYSTEM so ERROR events are tracked
}

@Override
public void execute() throws ResourceUnavailableException, InsufficientCapacityException, ServerApiException, ConcurrentOperationException, ResourceAllocationException,
NetworkRuleConflictException {

String result = null;
try {
result = _mgr.uploadCertificateWithValidation(this);
} catch (KeyStoreException | CertificateException | IOException e) {
e.printStackTrace();
}
if (result != null) {
CustomCertificateResponse response = new CustomCertificateResponse();
response.setResponseName(getCommandName());
response.setResultMessage(result);
response.setObjectName("customcertificate");
this.setResponseObject(response);
} else {
throw new ServerApiException(ApiErrorCode.INTERNAL_ERROR, "Failed to upload custom certificate");
}
}
}
Loading