diff --git a/README.md b/README.md index b62c261e..f2d71a65 100644 --- a/README.md +++ b/README.md @@ -80,18 +80,23 @@ Samples are in the [`samples/`](https://github.com/googleapis/java-security-priv | Create Ca Pool | [source code](https://github.com/googleapis/java-security-private-ca/blob/master/samples/snippets/cloud-client/src/main/java/privateca/CreateCaPool.java) | [![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/java-security-private-ca&page=editor&open_in_editor=samples/snippets/cloud-client/src/main/java/privateca/CreateCaPool.java) | | Create Certificate | [source code](https://github.com/googleapis/java-security-private-ca/blob/master/samples/snippets/cloud-client/src/main/java/privateca/CreateCertificate.java) | [![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/java-security-private-ca&page=editor&open_in_editor=samples/snippets/cloud-client/src/main/java/privateca/CreateCertificate.java) | | Create Certificate Authority | [source code](https://github.com/googleapis/java-security-private-ca/blob/master/samples/snippets/cloud-client/src/main/java/privateca/CreateCertificateAuthority.java) | [![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/java-security-private-ca&page=editor&open_in_editor=samples/snippets/cloud-client/src/main/java/privateca/CreateCertificateAuthority.java) | +| Create Certificate Template | [source code](https://github.com/googleapis/java-security-private-ca/blob/master/samples/snippets/cloud-client/src/main/java/privateca/CreateCertificateTemplate.java) | [![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/java-security-private-ca&page=editor&open_in_editor=samples/snippets/cloud-client/src/main/java/privateca/CreateCertificateTemplate.java) | | Create Certificate_CSR | [source code](https://github.com/googleapis/java-security-private-ca/blob/master/samples/snippets/cloud-client/src/main/java/privateca/CreateCertificate_CSR.java) | [![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/java-security-private-ca&page=editor&open_in_editor=samples/snippets/cloud-client/src/main/java/privateca/CreateCertificate_CSR.java) | | Create Subordinate Ca | [source code](https://github.com/googleapis/java-security-private-ca/blob/master/samples/snippets/cloud-client/src/main/java/privateca/CreateSubordinateCa.java) | [![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/java-security-private-ca&page=editor&open_in_editor=samples/snippets/cloud-client/src/main/java/privateca/CreateSubordinateCa.java) | | Delete Ca Pool | [source code](https://github.com/googleapis/java-security-private-ca/blob/master/samples/snippets/cloud-client/src/main/java/privateca/DeleteCaPool.java) | [![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/java-security-private-ca&page=editor&open_in_editor=samples/snippets/cloud-client/src/main/java/privateca/DeleteCaPool.java) | | Delete Certificate Authority | [source code](https://github.com/googleapis/java-security-private-ca/blob/master/samples/snippets/cloud-client/src/main/java/privateca/DeleteCertificateAuthority.java) | [![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/java-security-private-ca&page=editor&open_in_editor=samples/snippets/cloud-client/src/main/java/privateca/DeleteCertificateAuthority.java) | +| Delete Certificate Template | [source code](https://github.com/googleapis/java-security-private-ca/blob/master/samples/snippets/cloud-client/src/main/java/privateca/DeleteCertificateTemplate.java) | [![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/java-security-private-ca&page=editor&open_in_editor=samples/snippets/cloud-client/src/main/java/privateca/DeleteCertificateTemplate.java) | | Disable Certificate Authority | [source code](https://github.com/googleapis/java-security-private-ca/blob/master/samples/snippets/cloud-client/src/main/java/privateca/DisableCertificateAuthority.java) | [![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/java-security-private-ca&page=editor&open_in_editor=samples/snippets/cloud-client/src/main/java/privateca/DisableCertificateAuthority.java) | | Enable Certificate Authority | [source code](https://github.com/googleapis/java-security-private-ca/blob/master/samples/snippets/cloud-client/src/main/java/privateca/EnableCertificateAuthority.java) | [![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/java-security-private-ca&page=editor&open_in_editor=samples/snippets/cloud-client/src/main/java/privateca/EnableCertificateAuthority.java) | | Filter Certificates | [source code](https://github.com/googleapis/java-security-private-ca/blob/master/samples/snippets/cloud-client/src/main/java/privateca/FilterCertificates.java) | [![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/java-security-private-ca&page=editor&open_in_editor=samples/snippets/cloud-client/src/main/java/privateca/FilterCertificates.java) | | List Ca Pools | [source code](https://github.com/googleapis/java-security-private-ca/blob/master/samples/snippets/cloud-client/src/main/java/privateca/ListCaPools.java) | [![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/java-security-private-ca&page=editor&open_in_editor=samples/snippets/cloud-client/src/main/java/privateca/ListCaPools.java) | | List Certificate Authorities | [source code](https://github.com/googleapis/java-security-private-ca/blob/master/samples/snippets/cloud-client/src/main/java/privateca/ListCertificateAuthorities.java) | [![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/java-security-private-ca&page=editor&open_in_editor=samples/snippets/cloud-client/src/main/java/privateca/ListCertificateAuthorities.java) | +| List Certificate Templates | [source code](https://github.com/googleapis/java-security-private-ca/blob/master/samples/snippets/cloud-client/src/main/java/privateca/ListCertificateTemplates.java) | [![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/java-security-private-ca&page=editor&open_in_editor=samples/snippets/cloud-client/src/main/java/privateca/ListCertificateTemplates.java) | | List Certificates | [source code](https://github.com/googleapis/java-security-private-ca/blob/master/samples/snippets/cloud-client/src/main/java/privateca/ListCertificates.java) | [![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/java-security-private-ca&page=editor&open_in_editor=samples/snippets/cloud-client/src/main/java/privateca/ListCertificates.java) | | Revoke Certificate | [source code](https://github.com/googleapis/java-security-private-ca/blob/master/samples/snippets/cloud-client/src/main/java/privateca/RevokeCertificate.java) | [![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/java-security-private-ca&page=editor&open_in_editor=samples/snippets/cloud-client/src/main/java/privateca/RevokeCertificate.java) | | Undelete Certificate Authority | [source code](https://github.com/googleapis/java-security-private-ca/blob/master/samples/snippets/cloud-client/src/main/java/privateca/UndeleteCertificateAuthority.java) | [![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/java-security-private-ca&page=editor&open_in_editor=samples/snippets/cloud-client/src/main/java/privateca/UndeleteCertificateAuthority.java) | +| Update Ca Pool_Issuance Policy | [source code](https://github.com/googleapis/java-security-private-ca/blob/master/samples/snippets/cloud-client/src/main/java/privateca/UpdateCaPool_IssuancePolicy.java) | [![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/java-security-private-ca&page=editor&open_in_editor=samples/snippets/cloud-client/src/main/java/privateca/UpdateCaPool_IssuancePolicy.java) | +| Update Certificate Template | [source code](https://github.com/googleapis/java-security-private-ca/blob/master/samples/snippets/cloud-client/src/main/java/privateca/UpdateCertificateTemplate.java) | [![Open in Cloud Shell][shell_img]](https://console.cloud.google.com/cloudshell/open?git_repo=https://github.com/googleapis/java-security-private-ca&page=editor&open_in_editor=samples/snippets/cloud-client/src/main/java/privateca/UpdateCertificateTemplate.java) | diff --git a/samples/snippets/cloud-client/src/main/java/privateca/CreateCertificate.java b/samples/snippets/cloud-client/src/main/java/privateca/CreateCertificate.java index 296a9964..5cac09dd 100644 --- a/samples/snippets/cloud-client/src/main/java/privateca/CreateCertificate.java +++ b/samples/snippets/cloud-client/src/main/java/privateca/CreateCertificate.java @@ -85,7 +85,7 @@ public static void createCertificate( // certificateLifetime: The validity of the certificate in seconds. String commonName = "common-name"; String orgName = "org-name"; - String domainName = "dnsname.com"; + String domainName = "dns.your-domain.com"; long certificateLifetime = 1000L; // Set the Public Key and its format. diff --git a/samples/snippets/cloud-client/src/main/java/privateca/CreateCertificateTemplate.java b/samples/snippets/cloud-client/src/main/java/privateca/CreateCertificateTemplate.java new file mode 100644 index 00000000..e3c4b5cc --- /dev/null +++ b/samples/snippets/cloud-client/src/main/java/privateca/CreateCertificateTemplate.java @@ -0,0 +1,121 @@ +/* + * Copyright 2021 Google LLC + * + * 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 + * + * https://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 privateca; + +// [START privateca_create_certificate_template] + +import com.google.api.core.ApiFuture; +import com.google.cloud.security.privateca.v1.CertificateAuthorityServiceClient; +import com.google.cloud.security.privateca.v1.CertificateIdentityConstraints; +import com.google.cloud.security.privateca.v1.CertificateTemplate; +import com.google.cloud.security.privateca.v1.CreateCertificateTemplateRequest; +import com.google.cloud.security.privateca.v1.KeyUsage; +import com.google.cloud.security.privateca.v1.KeyUsage.ExtendedKeyUsageOptions; +import com.google.cloud.security.privateca.v1.KeyUsage.KeyUsageOptions; +import com.google.cloud.security.privateca.v1.LocationName; +import com.google.cloud.security.privateca.v1.X509Parameters; +import com.google.cloud.security.privateca.v1.X509Parameters.CaOptions; +import com.google.longrunning.Operation; +import com.google.type.Expr; +import java.io.IOException; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.TimeoutException; + +public class CreateCertificateTemplate { + + public static void main(String[] args) + throws IOException, ExecutionException, InterruptedException, TimeoutException { + /* TODO(developer): Replace these variables before running the sample. + location: For a list of locations, see: + https://cloud.google.com/certificate-authority-service/docs/locations */ + String project = "your-project-id"; + String location = "ca-location"; + String certificateTemplateId = "certificate-template-id"; + + createCertificateTemplate(project, location, certificateTemplateId); + } + + /* Creates a Certificate template. These templates can be reused for common + certificate issuance scenarios. */ + public static void createCertificateTemplate( + String project, String location, String certificateTemplateId) + throws IOException, ExecutionException, InterruptedException, TimeoutException { + /* Initialize client that will be used to send requests. This client only needs to be created + once, and can be reused for multiple requests. After completing all of your requests, call + the `certificateAuthorityServiceClient.close()` method on the client to safely + clean up any remaining background resources. */ + try (CertificateAuthorityServiceClient certificateAuthorityServiceClient = + CertificateAuthorityServiceClient.create()) { + + /* Describes any predefined X.509 values set by this template. + The provided extensions are copied over to certificate requests that use this template.*/ + KeyUsage keyUsage = + KeyUsage.newBuilder() + .setBaseKeyUsage( + KeyUsageOptions.newBuilder() + .setDigitalSignature(true) + .setKeyEncipherment(true) + .build()) + .setExtendedKeyUsage(ExtendedKeyUsageOptions.newBuilder().setServerAuth(true).build()) + .build(); + + CaOptions caOptions = CaOptions.newBuilder().setIsCa(false).build(); + + /* CEL expression that is evaluated against the Subject and + Subject Alternative Name of the certificate before it is issued. */ + Expr expr = + Expr.newBuilder().setExpression("subject_alt_names.all(san, san.type == DNS)").build(); + + // Set the certificate issuance schema. + CertificateTemplate certificateTemplate = + CertificateTemplate.newBuilder() + .setPredefinedValues( + X509Parameters.newBuilder().setKeyUsage(keyUsage).setCaOptions(caOptions).build()) + .setIdentityConstraints( + CertificateIdentityConstraints.newBuilder() + .setCelExpression(expr) + .setAllowSubjectPassthrough(false) + .setAllowSubjectAltNamesPassthrough(false) + .build()) + .build(); + + // Set the parent and certificate template properties. + CreateCertificateTemplateRequest certificateTemplateRequest = + CreateCertificateTemplateRequest.newBuilder() + .setParent(LocationName.of(project, location).toString()) + .setCertificateTemplate(certificateTemplate) + .setCertificateTemplateId(certificateTemplateId) + .build(); + + // Create Template request. + ApiFuture futureCall = + certificateAuthorityServiceClient + .createCertificateTemplateCallable() + .futureCall(certificateTemplateRequest); + + Operation response = futureCall.get(60, TimeUnit.SECONDS); + + if (response.hasError()) { + System.out.println("Error creating certificate template ! " + response.getError()); + return; + } + + System.out.println("Successfully created certificate template ! " + response.getName()); + } + } +} +// [END privateca_create_certificate_template] diff --git a/samples/snippets/cloud-client/src/main/java/privateca/CreateSubordinateCa.java b/samples/snippets/cloud-client/src/main/java/privateca/CreateSubordinateCa.java index 78f95b57..29b3f7ef 100644 --- a/samples/snippets/cloud-client/src/main/java/privateca/CreateSubordinateCa.java +++ b/samples/snippets/cloud-client/src/main/java/privateca/CreateSubordinateCa.java @@ -29,6 +29,7 @@ import com.google.cloud.security.privateca.v1.KeyUsage; import com.google.cloud.security.privateca.v1.KeyUsage.KeyUsageOptions; import com.google.cloud.security.privateca.v1.Subject; +import com.google.cloud.security.privateca.v1.SubjectAltNames; import com.google.cloud.security.privateca.v1.X509Parameters; import com.google.cloud.security.privateca.v1.X509Parameters.CaOptions; import com.google.longrunning.Operation; @@ -65,6 +66,7 @@ public static void createSubordinateCertificateAuthority( String commonName = "common-name"; String orgName = "csr-org-name"; + String domainName = "dns.your-domain.com"; int caDuration = 100000; // Validity of this CA in seconds. // Set the type of Algorithm. @@ -76,6 +78,8 @@ public static void createSubordinateCertificateAuthority( SubjectConfig.newBuilder() .setSubject( Subject.newBuilder().setCommonName(commonName).setOrganization(orgName).build()) + // Set the fully qualified domain name. + .setSubjectAltName(SubjectAltNames.newBuilder().addDnsNames(domainName).build()) .build(); // Set the key usage options for X.509 fields. diff --git a/samples/snippets/cloud-client/src/main/java/privateca/DeleteCertificateTemplate.java b/samples/snippets/cloud-client/src/main/java/privateca/DeleteCertificateTemplate.java new file mode 100644 index 00000000..417ffae2 --- /dev/null +++ b/samples/snippets/cloud-client/src/main/java/privateca/DeleteCertificateTemplate.java @@ -0,0 +1,78 @@ +/* + * Copyright 2021 Google LLC + * + * 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 + * + * https://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 privateca; + +// [START privateca_delete_certificate_template] + +import com.google.api.core.ApiFuture; +import com.google.cloud.security.privateca.v1.CertificateAuthorityServiceClient; +import com.google.cloud.security.privateca.v1.CertificateTemplateName; +import com.google.cloud.security.privateca.v1.DeleteCertificateTemplateRequest; +import com.google.longrunning.Operation; +import java.io.IOException; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.TimeoutException; + +public class DeleteCertificateTemplate { + + public static void main(String[] args) + throws IOException, ExecutionException, InterruptedException, TimeoutException { + /* TODO(developer): Replace these variables before running the sample. + location: For a list of locations, see: + https://cloud.google.com/certificate-authority-service/docs/locations + certificateTemplateId: Id of the certificate template to delete. */ + String project = "your-project-id"; + String location = "ca-location"; + String certificateTemplateId = "certificate-template-id"; + + deleteCertificateTemplate(project, location, certificateTemplateId); + } + + // Deletes the certificate template present in the given project and location. + public static void deleteCertificateTemplate( + String project, String location, String certificateTemplateId) + throws IOException, ExecutionException, InterruptedException, TimeoutException { + /* Initialize client that will be used to send requests. This client only needs to be created + once, and can be reused for multiple requests. After completing all of your requests, call + the `certificateAuthorityServiceClient.close()` method on the client to safely + clean up any remaining background resources. */ + try (CertificateAuthorityServiceClient certificateAuthorityServiceClient = + CertificateAuthorityServiceClient.create()) { + + // Set the parent name of the certificate template to be deleted. + DeleteCertificateTemplateRequest request = + DeleteCertificateTemplateRequest.newBuilder() + .setName( + CertificateTemplateName.of(project, location, certificateTemplateId).toString()) + .build(); + + ApiFuture futureCall = + certificateAuthorityServiceClient.deleteCertificateTemplateCallable().futureCall(request); + + Operation response = futureCall.get(60, TimeUnit.SECONDS); + + // Check for errors. + if (response.hasError()) { + System.out.println("Error deleting the certificate template ! " + response.getError()); + return; + } + + System.out.println("Successfully created certificate template ! " + response.getName()); + } + } +} +// [END privateca_delete_certificate_template] diff --git a/samples/snippets/cloud-client/src/main/java/privateca/FilterCertificates.java b/samples/snippets/cloud-client/src/main/java/privateca/FilterCertificates.java index 9ba8d93a..6a199f93 100644 --- a/samples/snippets/cloud-client/src/main/java/privateca/FilterCertificates.java +++ b/samples/snippets/cloud-client/src/main/java/privateca/FilterCertificates.java @@ -30,21 +30,16 @@ public static void main(String[] args) throws IOException { // location: For a list of locations, see: // https://cloud.google.com/certificate-authority-service/docs/locations // pool_Id: Id of the CA pool which contains the certificates to be listed. - // filterCondition: Filter certificates based on the given condition. - // For more info on conditions supported, - // see: - // https://cloud.google.com/certificate-authority-service/docs/sorting-filtering-certificates#filtering_support String project = "your-project-id"; String location = "ca-location"; String pool_Id = "ca-pool-id"; - String filterCondition = "filter-condition"; - filterCertificates(project, location, pool_Id, filterCondition); + filterCertificates(project, location, pool_Id); } // Filter certificates based on a condition and list them. - public static void filterCertificates( - String project, String location, String pool_Id, String filterCondition) throws IOException { + public static void filterCertificates(String project, String location, String pool_Id) + throws IOException { // Initialize client that will be used to send requests. This client only needs to be created // once, and can be reused for multiple requests. After completing all of your requests, call // the `certificateAuthorityServiceClient.close()` method on the client to safely @@ -63,8 +58,16 @@ public static void filterCertificates( ListCertificatesRequest listCertificatesRequest = ListCertificatesRequest.newBuilder() .setParent(caPool.toString()) - // Filter certificates according to the given condition. - .setFilter(filterCondition) + /* Filter certificates based on the given condition. + For more info on conditions supported, + see: + https://cloud.google.com/certificate-authority-service/docs/sorting-filtering-certificates#filtering_support + Few examples for constructing conditions: + certificate_description.subject_description.not_after_time=timestamp(com.google.protobuf) + certificate_description.subject_description.subject_alt_name.dns_names:my-dns + Here, we are filtering certificates which has organization name = csr-org-name */ + .setFilter( + "certificate_description.subject_description.subject.organization=csr-org-name") .build(); // Retrieve and print the certificate names. diff --git a/samples/snippets/cloud-client/src/main/java/privateca/ListCertificateTemplates.java b/samples/snippets/cloud-client/src/main/java/privateca/ListCertificateTemplates.java new file mode 100644 index 00000000..bc574c02 --- /dev/null +++ b/samples/snippets/cloud-client/src/main/java/privateca/ListCertificateTemplates.java @@ -0,0 +1,73 @@ +/* + * Copyright 2021 Google LLC + * + * 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 + * + * https://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 privateca; + +// [START privateca_list_certificate_template] + +import com.google.api.core.ApiFuture; +import com.google.cloud.security.privateca.v1.CertificateAuthorityServiceClient; +import com.google.cloud.security.privateca.v1.CertificateTemplate; +import com.google.cloud.security.privateca.v1.ListCertificateTemplatesRequest; +import com.google.cloud.security.privateca.v1.ListCertificateTemplatesResponse; +import com.google.cloud.security.privateca.v1.LocationName; +import java.io.IOException; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.TimeoutException; + +public class ListCertificateTemplates { + + public static void main(String[] args) + throws IOException, ExecutionException, InterruptedException, TimeoutException { + /* TODO(developer): Replace these variables before running the sample. + location: For a list of locations, see: + https://cloud.google.com/certificate-authority-service/docs/locations */ + String project = "your-project-id"; + String location = "ca-location"; + + listCertificateTemplates(project, location); + } + + // Lists the certificate templates present in the given project and location. + public static void listCertificateTemplates(String project, String location) + throws IOException, ExecutionException, InterruptedException, TimeoutException { + /* Initialize client that will be used to send requests. This client only needs to be created + once, and can be reused for multiple requests. After completing all of your requests, call + the `certificateAuthorityServiceClient.close()` method on the client to safely + clean up any remaining background resources. */ + try (CertificateAuthorityServiceClient certificateAuthorityServiceClient = + CertificateAuthorityServiceClient.create()) { + + // Set the parent name to list the certificate templates. + ListCertificateTemplatesRequest request = + ListCertificateTemplatesRequest.newBuilder() + .setParent(LocationName.of(project, location).toString()) + .build(); + + ApiFuture futureCall = + certificateAuthorityServiceClient.listCertificateTemplatesCallable().futureCall(request); + + // Get the response. + ListCertificateTemplatesResponse response = futureCall.get(60, TimeUnit.SECONDS); + + // List all templates. + for (CertificateTemplate template : response.getCertificateTemplatesList()) { + System.out.println(template.getName()); + } + } + } +} +// [END privateca_list_certificate_template] diff --git a/samples/snippets/cloud-client/src/main/java/privateca/UpdateCaPool_IssuancePolicy.java b/samples/snippets/cloud-client/src/main/java/privateca/UpdateCaPool_IssuancePolicy.java new file mode 100644 index 00000000..1b091432 --- /dev/null +++ b/samples/snippets/cloud-client/src/main/java/privateca/UpdateCaPool_IssuancePolicy.java @@ -0,0 +1,134 @@ +/* + * Copyright 2021 Google LLC + * + * 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 + * + * https://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 privateca; + +// [START privateca_set_issuance_policy] + +import com.google.api.core.ApiFuture; +import com.google.cloud.security.privateca.v1.CaPool; +import com.google.cloud.security.privateca.v1.CaPool.IssuancePolicy; +import com.google.cloud.security.privateca.v1.CaPoolName; +import com.google.cloud.security.privateca.v1.CertificateAuthorityServiceClient; +import com.google.cloud.security.privateca.v1.CertificateIdentityConstraints; +import com.google.cloud.security.privateca.v1.UpdateCaPoolRequest; +import com.google.longrunning.Operation; +import com.google.protobuf.FieldMask; +import com.google.type.Expr; +import java.io.IOException; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.TimeoutException; + +public class UpdateCaPool_IssuancePolicy { + + public static void main(String[] args) + throws IOException, ExecutionException, InterruptedException, TimeoutException { + // TODO(developer): Replace these variables before running the sample. + // location: For a list of locations, see: + // https://cloud.google.com/certificate-authority-service/docs/locations + // pool_Id: The CA pool for which the issuance policy is to be updated. + String project = "your-project-id"; + String location = "ca-location"; + String pool_Id = "ca-pool-id"; + + updateCaPoolIssuancePolicy(project, location, pool_Id); + } + + /* Update the Issuance policy for a CA Pool. All certificates issued from this CA Pool should + meet the issuance policy. */ + public static void updateCaPoolIssuancePolicy(String project, String location, String pool_Id) + throws IOException, ExecutionException, InterruptedException, TimeoutException { + /* Initialize client that will be used to send requests. This client only needs to be created + once, and can be reused for multiple requests. After completing all of your requests, call + the `certificateAuthorityServiceClient.close()` method on the client to safely + clean up any remaining background resources. */ + try (CertificateAuthorityServiceClient certificateAuthorityServiceClient = + CertificateAuthorityServiceClient.create()) { + + /* Set the updated issuance policy for the CA Pool. + This particular issuance policy allows only SANs that + have DNS Names as "us.google.org" or ending in ".google.com". */ + String expr = + "subject_alt_names.all(san, san.type == DNS && (san.value == \"us.google.org\"" + + " || san.value.endsWith(\".google.com\")) )"; + + CaPool.IssuancePolicy issuancePolicy = + IssuancePolicy.newBuilder() + .setIdentityConstraints( + CertificateIdentityConstraints.newBuilder() + .setAllowSubjectPassthrough(true) + .setAllowSubjectAltNamesPassthrough(true) + .setCelExpression(Expr.newBuilder().setExpression(expr).build()) + .build()) + .build(); + + CaPool caPool = + CaPool.newBuilder() + .setName(CaPoolName.of(project, location, pool_Id).toString()) + .setIssuancePolicy(issuancePolicy) + .build(); + + /* 1. Set the CA pool with updated values. + 2. Set the update mask to specify which properties of the CA Pool should be updated. + Only the properties specified in the mask will be updated. Make sure that the mask fields + match the updated issuance policy. + For more info on constructing path for update mask, see: + https://cloud.google.com/certificate-authority-service/docs/reference/rest/v1/projects.locations.caPools#issuancepolicy */ + UpdateCaPoolRequest updateCaPoolRequest = + UpdateCaPoolRequest.newBuilder() + .setCaPool(caPool) + .setUpdateMask( + FieldMask.newBuilder( + FieldMask.newBuilder() + .addPaths( + "issuance_policy.identity_constraints.allow_subject_passthrough") + .addPaths( + "issuance_policy.identity_constraints.allow_subject_alt_names_passthrough") + .addPaths("issuance_policy.identity_constraints.cel_expression") + .build())) + .build(); + + // Update CA Pool request. + ApiFuture futureCall = + certificateAuthorityServiceClient.updateCaPoolCallable().futureCall(updateCaPoolRequest); + + Operation operation = futureCall.get(60, TimeUnit.SECONDS); + + // Check for errors. + if (operation.hasError()) { + System.out.println("Error in updating CA Pool Issuance policy ! " + operation.getError()); + return; + } + + // Get the CA Pool's issuance policy and verify if the fields have been successfully updated. + IssuancePolicy response = + certificateAuthorityServiceClient + .getCaPool(CaPoolName.of(project, location, pool_Id).toString()) + .getIssuancePolicy(); + + // Similarly, you can check for other modified fields as well. + if (response.getIdentityConstraints().getAllowSubjectPassthrough() + && response.getIdentityConstraints().getAllowSubjectAltNamesPassthrough()) { + System.out.println("CA Pool Issuance policy has been updated successfully ! "); + return; + } + + System.out.println( + "Error in updating CA Pool Issuance policy ! Please try again ! " + response); + } + } +} +// [END privateca_set_issuance_policy] diff --git a/samples/snippets/cloud-client/src/main/java/privateca/UpdateCertificateTemplate.java b/samples/snippets/cloud-client/src/main/java/privateca/UpdateCertificateTemplate.java new file mode 100644 index 00000000..66feb63f --- /dev/null +++ b/samples/snippets/cloud-client/src/main/java/privateca/UpdateCertificateTemplate.java @@ -0,0 +1,116 @@ +/* + * Copyright 2021 Google LLC + * + * 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 + * + * https://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 privateca; + +// [START privateca_update_certificate_template] + +import com.google.api.core.ApiFuture; +import com.google.cloud.security.privateca.v1.CertificateAuthorityServiceClient; +import com.google.cloud.security.privateca.v1.CertificateIdentityConstraints; +import com.google.cloud.security.privateca.v1.CertificateTemplate; +import com.google.cloud.security.privateca.v1.CertificateTemplateName; +import com.google.cloud.security.privateca.v1.UpdateCertificateTemplateRequest; +import com.google.longrunning.Operation; +import com.google.protobuf.FieldMask; +import java.io.IOException; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.TimeoutException; + +public class UpdateCertificateTemplate { + + public static void main(String[] args) + throws IOException, ExecutionException, InterruptedException, TimeoutException { + // TODO(developer): Replace these variables before running the sample. + // location: For a list of locations, see: + // https://cloud.google.com/certificate-authority-service/docs/locations + // certificateTemplateId: Id of the certificate template to update. + String project = "your-project-id"; + String location = "ca-location"; + String certificateTemplateId = "certificate-template-id"; + + updateCertificateTemplate(project, location, certificateTemplateId); + } + + // Updates an existing certificate template. + public static void updateCertificateTemplate( + String project, String location, String certificateTemplateId) + throws IOException, ExecutionException, InterruptedException, TimeoutException { + /* Initialize client that will be used to send requests. This client only needs to be created + once, and can be reused for multiple requests. After completing all of your requests, call + the `certificateAuthorityServiceClient.close()` method on the client to safely + clean up any remaining background resources. */ + try (CertificateAuthorityServiceClient certificateAuthorityServiceClient = + CertificateAuthorityServiceClient.create()) { + + String certificateTemplateName = + CertificateTemplateName.of(project, location, certificateTemplateId).toString(); + + // Set the parent name and the properties to be updated. + CertificateTemplate certificateTemplate = + CertificateTemplate.newBuilder() + .setName(certificateTemplateName) + .setIdentityConstraints( + CertificateIdentityConstraints.newBuilder() + .setAllowSubjectPassthrough(false) + .setAllowSubjectAltNamesPassthrough(true) + .build()) + .build(); + + // Set the mask corresponding to the properties updated above. + FieldMask fieldMask = + FieldMask.newBuilder() + .addPaths("identity_constraints.allow_subject_alt_names_passthrough") + .addPaths("identity_constraints.allow_subject_passthrough") + .build(); + + /* Set the new template. + Set the mask to specify which properties of the template should be updated. */ + UpdateCertificateTemplateRequest request = + UpdateCertificateTemplateRequest.newBuilder() + .setCertificateTemplate(certificateTemplate) + .setUpdateMask(fieldMask) + .build(); + + // Create the update certificate template request. + ApiFuture futureCall = + certificateAuthorityServiceClient.updateCertificateTemplateCallable().futureCall(request); + + Operation response = futureCall.get(60, TimeUnit.SECONDS); + + // Check for errors. + if (response.hasError()) { + System.out.println("Error in updating certificate template ! " + response.getError()); + return; + } + + // Get the updated certificate template and check if the properties have been updated. + CertificateIdentityConstraints updatedCertificateIdentityConstraints = + certificateAuthorityServiceClient + .getCertificateTemplate(certificateTemplateName) + .getIdentityConstraints(); + + if (!updatedCertificateIdentityConstraints.getAllowSubjectPassthrough() + && updatedCertificateIdentityConstraints.getAllowSubjectAltNamesPassthrough()) { + System.out.println("Successfully updated the certificate template ! " + response.getName()); + return; + } + + System.out.println("Error in updating certificate template ! "); + } + } +} +// [END privateca_update_certificate_template] diff --git a/samples/snippets/cloud-client/src/test/java/privateca/SnippetsIT.java b/samples/snippets/cloud-client/src/test/java/privateca/SnippetsIT.java index db1cc226..d907faa3 100644 --- a/samples/snippets/cloud-client/src/test/java/privateca/SnippetsIT.java +++ b/samples/snippets/cloud-client/src/test/java/privateca/SnippetsIT.java @@ -18,12 +18,14 @@ import static com.google.common.truth.Truth.assertThat; import static com.google.common.truth.Truth.assertWithMessage; +import com.google.cloud.security.privateca.v1.CaPool.IssuancePolicy; import com.google.cloud.security.privateca.v1.CaPoolName; import com.google.cloud.security.privateca.v1.Certificate; import com.google.cloud.security.privateca.v1.CertificateAuthority; import com.google.cloud.security.privateca.v1.CertificateAuthorityName; import com.google.cloud.security.privateca.v1.CertificateAuthorityServiceClient; import com.google.cloud.security.privateca.v1.CertificateName; +import com.google.cloud.security.privateca.v1.CertificateTemplateName; import com.google.cloud.security.privateca.v1.FetchCertificateAuthorityCsrResponse; import com.google.protobuf.ByteString; import java.io.ByteArrayOutputStream; @@ -63,6 +65,7 @@ public class SnippetsIT { private static String CA_NAME; private static String CA_NAME_DELETE; private static String SUBORDINATE_CA_NAME; + private static String CERTIFICATE_TEMPLATE_NAME; private static String CERTIFICATE_NAME; private static String CSR_CERTIFICATE_NAME; private static int KEY_SIZE; @@ -79,18 +82,19 @@ public static void reqEnvVar(String envVarName) { @BeforeClass public static void setUp() throws IOException, ExecutionException, NoSuchProviderException, NoSuchAlgorithmException, - InterruptedException { + InterruptedException, TimeoutException { reqEnvVar("GOOGLE_APPLICATION_CREDENTIALS"); reqEnvVar("GOOGLE_CLOUD_PROJECT"); LOCATION = "asia-south1"; - CA_POOL_ID = "ca-pool-" + UUID.randomUUID().toString(); - CA_POOL_ID_DELETE = "ca-pool-" + UUID.randomUUID().toString(); - CA_NAME = "ca-name-" + UUID.randomUUID().toString(); - CA_NAME_DELETE = "ca-name-" + UUID.randomUUID().toString(); - SUBORDINATE_CA_NAME = "sub-ca-name-" + UUID.randomUUID().toString(); - CERTIFICATE_NAME = "certificate-name-" + UUID.randomUUID().toString(); - CSR_CERTIFICATE_NAME = "csr-certificate-name-" + UUID.randomUUID().toString(); + CA_POOL_ID = "ca-pool-" + UUID.randomUUID(); + CA_POOL_ID_DELETE = "ca-pool-" + UUID.randomUUID(); + CA_NAME = "ca-name-" + UUID.randomUUID(); + CA_NAME_DELETE = "ca-name-" + UUID.randomUUID(); + SUBORDINATE_CA_NAME = "sub-ca-name-" + UUID.randomUUID(); + CERTIFICATE_TEMPLATE_NAME = "certificate-template-name-" + UUID.randomUUID(); + CERTIFICATE_NAME = "certificate-name-" + UUID.randomUUID(); + CSR_CERTIFICATE_NAME = "csr-certificate-name-" + UUID.randomUUID(); KEY_SIZE = 2048; // Default key size // <--- START CA POOL ---> @@ -98,6 +102,9 @@ public static void setUp() privateca.CreateCaPool.createCaPool(PROJECT_ID, LOCATION, CA_POOL_ID); privateca.CreateCaPool.createCaPool(PROJECT_ID, LOCATION, CA_POOL_ID_DELETE); sleep(5); + // Set the issuance policy for the created CA Pool. + privateca.UpdateCaPool_IssuancePolicy.updateCaPoolIssuancePolicy( + PROJECT_ID, LOCATION, CA_POOL_ID); // <--- END CA POOL ---> // <--- START ROOT CA ---> @@ -117,18 +124,23 @@ public static void setUp() // <--- END ROOT CA ---> // <--- START SUBORDINATE CA ---> - // Create a Subordinate Certificate Authority. + // Follow the below steps to create and enable a Subordinate Certificate Authority. + // 1. Create a Subordinate Certificate Authority. privateca.CreateSubordinateCa.createSubordinateCertificateAuthority( PROJECT_ID, LOCATION, CA_POOL_ID, SUBORDINATE_CA_NAME); sleep(10); - // Fetch CSR. + // 2. Fetch CSR. String pemCSR = fetchPemCSR(CA_POOL_ID, SUBORDINATE_CA_NAME); - // Sign the CSR, and create a certificate. + // 3. Sign the CSR, and create a certificate. privateca.CreateCertificate_CSR.createCertificateWithCSR( PROJECT_ID, LOCATION, CA_POOL_ID, CA_NAME, CSR_CERTIFICATE_NAME, pemCSR); // <--- END SUBORDINATE CA ---> // <--- START CERTIFICATE ---> + // Create Certificate Template. + privateca.CreateCertificateTemplate.createCertificateTemplate( + PROJECT_ID, LOCATION, CERTIFICATE_TEMPLATE_NAME); + // Create an asymmetric key pair using Bouncy Castle crypto framework. KeyPair asymmetricKeyPair = createAsymmetricKeyPair(); @@ -155,7 +167,8 @@ public static void setUp() } @AfterClass - public static void cleanUp() throws InterruptedException, ExecutionException, IOException { + public static void cleanUp() + throws InterruptedException, ExecutionException, IOException, TimeoutException { ByteArrayOutputStream stdOut = new ByteArrayOutputStream(); System.setOut(new PrintStream(stdOut)); @@ -164,6 +177,10 @@ public static void cleanUp() throws InterruptedException, ExecutionException, IO privateca.RevokeCertificate.revokeCertificate( PROJECT_ID, LOCATION, CA_POOL_ID, CSR_CERTIFICATE_NAME); + // Delete Certificate Template. + privateca.DeleteCertificateTemplate.deleteCertificateTemplate( + PROJECT_ID, LOCATION, CERTIFICATE_TEMPLATE_NAME); + // Delete root CA. privateca.DeleteCertificateAuthority.deleteCertificateAuthority( PROJECT_ID, LOCATION, CA_POOL_ID, CA_NAME); @@ -255,6 +272,23 @@ public void testCreateCAPool() throws IOException { } } + @Test + public void testUpdateCAPoolIssuancePolicy() throws IOException { + try (CertificateAuthorityServiceClient certificateAuthorityServiceClient = + CertificateAuthorityServiceClient.create()) { + IssuancePolicy issuancePolicy = + certificateAuthorityServiceClient + .getCaPool(CaPoolName.of(PROJECT_ID, LOCATION, CA_POOL_ID).toString()) + .getIssuancePolicy(); + + String actualExpression = + issuancePolicy.getIdentityConstraints().getCelExpression().getExpression(); + String expectedExpression = + "subject_alt_names.all(san, san.type == DNS && (san.value == \"us.google.org\" || san.value.endsWith(\".google.com\")) )"; + assertThat(actualExpression).contains(expectedExpression); + } + } + @Test public void testListCAPools() throws IOException { privateca.ListCaPools.listCaPools(PROJECT_ID, LOCATION); @@ -308,6 +342,38 @@ public void testDeleteUndeleteCertificateAuthority() .contains("Successfully restored the Certificate Authority ! " + CA_NAME_DELETE); } + @Test + public void testCreateCertificateTemplate() throws IOException { + // Check that the Certificate template has been created as part of the setup. + try (CertificateAuthorityServiceClient certificateAuthorityServiceClient = + CertificateAuthorityServiceClient.create()) { + String certificateTemplate = + certificateAuthorityServiceClient + .getCertificateTemplate( + CertificateTemplateName.of(PROJECT_ID, LOCATION, CERTIFICATE_TEMPLATE_NAME) + .toString()) + .getName(); + + assertThat(certificateTemplate) + .contains(String.format("projects/%s/locations/%s/", PROJECT_ID, LOCATION)); + } + } + + @Test + public void testListCertificateTemplate() + throws IOException, ExecutionException, InterruptedException, TimeoutException { + privateca.ListCertificateTemplates.listCertificateTemplates(PROJECT_ID, LOCATION); + assertThat(stdOut.toString()).contains(CERTIFICATE_TEMPLATE_NAME); + } + + @Test + public void updateCertificateTemplate() + throws IOException, ExecutionException, InterruptedException, TimeoutException { + privateca.UpdateCertificateTemplate.updateCertificateTemplate( + PROJECT_ID, LOCATION, CERTIFICATE_TEMPLATE_NAME); + assertThat(stdOut.toString()).contains("Successfully updated the certificate template ! "); + } + @Test public void testCreateCertificate() throws IOException { // Check if the certificate created during setup is successful. @@ -329,10 +395,7 @@ public void testListCertificates() throws IOException { @Test public void testFilterCertificates() throws IOException { // Filter only certificates created using CSR. - String filterCondition = - "certificate_description.subject_description.subject.organization=csr-org-name"; - privateca.FilterCertificates.filterCertificates( - PROJECT_ID, LOCATION, CA_POOL_ID, filterCondition); + privateca.FilterCertificates.filterCertificates(PROJECT_ID, LOCATION, CA_POOL_ID); assertThat(stdOut.toString()).contains(CSR_CERTIFICATE_NAME); assertThat(stdOut.toString()).doesNotContain(CERTIFICATE_NAME); }