diff --git a/README.md b/README.md
index 04696331..f2d71a65 100644
--- a/README.md
+++ b/README.md
@@ -19,20 +19,20 @@ If you are using Maven, add this to your pom.xml file:
com.google.cloud
google-cloud-security-private-ca
- 2.0.2
+ 2.1.0
```
If you are using Gradle without BOM, add this to your dependencies
```Groovy
-implementation 'com.google.cloud:google-cloud-security-private-ca:2.0.2'
+implementation 'com.google.cloud:google-cloud-security-private-ca:2.1.0'
```
If you are using SBT, add this to your dependencies
```Scala
-libraryDependencies += "com.google.cloud" % "google-cloud-security-private-ca" % "2.0.2"
+libraryDependencies += "com.google.cloud" % "google-cloud-security-private-ca" % "2.1.0"
```
## Authentication
@@ -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);
}