Skip to content

Commit e15de83

Browse files
FrodoTheTruetelpirion
authored andcommitted
feat(samples): private CA python samples
1 parent 4aecc15 commit e15de83

19 files changed

+1346
-0
lines changed

privateca/snippets/conftest.py

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
# Copyright 2021 Google LLC
2+
#
3+
# Licensed under the Apache License, Version 2.0 (the "License");
4+
# you may not use this file except in compliance with the License.
5+
# You may obtain a copy of the License at
6+
#
7+
# http://www.apache.org/licenses/LICENSE-2.0
8+
#
9+
# Unless required by applicable law or agreed to in writing, software
10+
# distributed under the License is distributed on an "AS IS" BASIS,
11+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
# See the License for the specific language governing permissions and
13+
# limitations under the License.
14+
15+
import uuid
16+
17+
import google.auth
18+
19+
import pytest
20+
21+
from create_ca_pool import create_ca_pool
22+
from create_certificate_authority import create_certificate_authority
23+
from delete_ca_pool import delete_ca_pool
24+
from delete_certificate_authority import delete_certificate_authority
25+
26+
PROJECT = google.auth.default()[1]
27+
LOCATION = "europe-west1"
28+
COMMON_NAME = "COMMON_NAME"
29+
ORGANIZATION = "ORGANIZATION"
30+
CA_DURATION = 1000000
31+
32+
33+
def generate_name() -> str:
34+
return "test-" + uuid.uuid4().hex[:10]
35+
36+
37+
@pytest.fixture
38+
def ca_pool():
39+
CA_POOL_NAME = generate_name()
40+
41+
create_ca_pool(PROJECT, LOCATION, CA_POOL_NAME)
42+
43+
yield CA_POOL_NAME
44+
45+
delete_ca_pool(PROJECT, LOCATION, CA_POOL_NAME)
46+
47+
48+
@pytest.fixture
49+
def certificate_authority(ca_pool):
50+
CA_NAME = generate_name()
51+
52+
create_certificate_authority(
53+
PROJECT, LOCATION, ca_pool, CA_NAME, COMMON_NAME, ORGANIZATION, CA_DURATION
54+
)
55+
56+
yield ca_pool, CA_NAME
57+
58+
delete_certificate_authority(PROJECT, LOCATION, ca_pool, CA_NAME)

privateca/snippets/create_ca_pool.py

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
#!/usr/bin/env python
2+
3+
# Copyright 2021 Google LLC
4+
#
5+
# Licensed under the Apache License, Version 2.0 (the "License");
6+
# you may not use this file except in compliance with the License.
7+
# You may obtain a copy of the License at
8+
#
9+
# http://www.apache.org/licenses/LICENSE-2.0
10+
#
11+
# Unless required by applicable law or agreed to in writing, software
12+
# distributed under the License is distributed on an "AS IS" BASIS,
13+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
# See the License for the specific language governing permissions and
15+
# limitations under the License.
16+
17+
# [START privateca_create_ca_pool]
18+
import google.cloud.security.privateca_v1 as privateca_v1
19+
20+
21+
def create_ca_pool(project_id: str, location: str, ca_pool_name: str) -> None:
22+
"""
23+
Create a Certificate Authority pool. All certificates created under this CA pool will
24+
follow the same issuance policy, IAM policies,etc.,
25+
26+
Args:
27+
project_id: project ID or project number of the Cloud project you want to use.
28+
location: location you want to use. For a list of locations, see: https://cloud.google.com/certificate-authority-service/docs/locations.
29+
ca_pool_name: a unique name for the ca pool.
30+
"""
31+
32+
caServiceClient = privateca_v1.CertificateAuthorityServiceClient()
33+
34+
ca_pool = privateca_v1.CaPool(
35+
# Set the tier (see: https://cloud.google.com/certificate-authority-service/docs/tiers).
36+
tier=privateca_v1.CaPool.Tier.ENTERPRISE,
37+
)
38+
location_path = caServiceClient.common_location_path(project_id, location)
39+
40+
# Create the pool request.
41+
request = privateca_v1.CreateCaPoolRequest(
42+
parent=location_path,
43+
ca_pool_id=ca_pool_name,
44+
ca_pool=ca_pool,
45+
)
46+
47+
# Create the CA pool.
48+
operation = caServiceClient.create_ca_pool(request=request)
49+
50+
print("Operation result:", operation.result())
51+
52+
53+
# [END privateca_create_ca_pool]
Lines changed: 115 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,115 @@
1+
#!/usr/bin/env python
2+
3+
# Copyright 2021 Google LLC
4+
#
5+
# Licensed under the Apache License, Version 2.0 (the "License");
6+
# you may not use this file except in compliance with the License.
7+
# You may obtain a copy of the License at
8+
#
9+
# http://www.apache.org/licenses/LICENSE-2.0
10+
#
11+
# Unless required by applicable law or agreed to in writing, software
12+
# distributed under the License is distributed on an "AS IS" BASIS,
13+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
# See the License for the specific language governing permissions and
15+
# limitations under the License.
16+
17+
# [START privateca_create_certificate]
18+
from google.cloud import kms
19+
import google.cloud.security.privateca_v1 as privateca_v1
20+
from google.protobuf import duration_pb2
21+
22+
23+
def create_certificate(
24+
project_id: str,
25+
location: str,
26+
ca_pool_name: str,
27+
ca_name: str,
28+
certificate_name: str,
29+
kms_location: str,
30+
key_ring_id: str,
31+
key_id: str,
32+
key_version_id: str,
33+
common_name: str,
34+
domain_name: str,
35+
certificate_lifetime: int,
36+
) -> None:
37+
"""
38+
Create a Certificate which is issued by the Certificate Authority present in the CA Pool.
39+
The key used to sign the certificate is created by the Cloud KMS.
40+
41+
Args:
42+
project_id: project ID or project number of the Cloud project you want to use.
43+
location: location you want to use. For a list of locations, see: https://cloud.google.com/certificate-authority-service/docs/locations.
44+
ca_pool_name: set a unique name for the CA pool.
45+
ca_name: the name of the certificate authority which issues the certificate.
46+
certificate_name: set a unique name for the certificate.
47+
kms_location: Cloud KMS location.
48+
key_ring_id: ID of the Cloud KMS key ring.
49+
key_id: ID of the key to use.
50+
key_version_id: verstion ID of the key to use.
51+
common_name: a title for your certificate.
52+
domain_name: fully qualified domain name for your certificate.
53+
certificate_lifetime: the validity of the certificate in seconds.
54+
"""
55+
56+
kmsClient = kms.KeyManagementServiceClient()
57+
caServiceClient = privateca_v1.CertificateAuthorityServiceClient()
58+
59+
# To sign and issue a certificate, a public key is essential. Here, we are making use
60+
# of Cloud KMS to retrieve an already created public key. For more info, see: https://cloud.google.com/kms/docs/retrieve-public-key.
61+
# Generating keys locally is also possible.
62+
63+
key_version_name = kmsClient.crypto_key_version_path(
64+
project_id, kms_location, key_ring_id, key_id, key_version_id
65+
)
66+
kms_public_key = kmsClient.get_public_key(name=key_version_name)
67+
68+
# Set the Public Key and its format as obtained from the Cloud KMS.
69+
public_key = privateca_v1.PublicKey(
70+
key=str.encode(kms_public_key.pem),
71+
format_=privateca_v1.PublicKey.KeyFormat.PEM,
72+
)
73+
74+
subject_config = privateca_v1.CertificateConfig.SubjectConfig(
75+
subject=privateca_v1.Subject(common_name=common_name),
76+
subject_alt_name=privateca_v1.SubjectAltNames(dns_names=[domain_name]),
77+
)
78+
79+
# Set the X.509 fields required for the certificate.
80+
x509_parameters = privateca_v1.X509Parameters(
81+
key_usage=privateca_v1.KeyUsage(
82+
base_key_usage=privateca_v1.KeyUsage.KeyUsageOptions(
83+
digital_signature=True,
84+
key_encipherment=True,
85+
),
86+
extended_key_usage=privateca_v1.KeyUsage.ExtendedKeyUsageOptions(
87+
server_auth=True,
88+
client_auth=True,
89+
),
90+
),
91+
)
92+
93+
# Create certificate.
94+
certificate = privateca_v1.Certificate(
95+
config=privateca_v1.CertificateConfig(
96+
public_key=public_key,
97+
subject_config=subject_config,
98+
x509_config=x509_parameters,
99+
),
100+
lifetime=duration_pb2.Duration(seconds=certificate_lifetime),
101+
)
102+
103+
# Create the Certificate Request.
104+
request = privateca_v1.CreateCertificateRequest(
105+
parent=caServiceClient.ca_pool_path(project_id, location, ca_pool_name),
106+
certificate_id=certificate_name,
107+
certificate=certificate,
108+
issuing_certificate_authority_id=ca_name,
109+
)
110+
result = caServiceClient.create_certificate(request=request)
111+
112+
print("Certificate creation result:", result)
113+
114+
115+
# [END privateca_create_certificate]
Lines changed: 97 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,97 @@
1+
#!/usr/bin/env python
2+
3+
# Copyright 2021 Google LLC
4+
#
5+
# Licensed under the Apache License, Version 2.0 (the "License");
6+
# you may not use this file except in compliance with the License.
7+
# You may obtain a copy of the License at
8+
#
9+
# http://www.apache.org/licenses/LICENSE-2.0
10+
#
11+
# Unless required by applicable law or agreed to in writing, software
12+
# distributed under the License is distributed on an "AS IS" BASIS,
13+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
# See the License for the specific language governing permissions and
15+
# limitations under the License.
16+
17+
# [START privateca_create_ca]
18+
import google.cloud.security.privateca_v1 as privateca_v1
19+
from google.protobuf import duration_pb2
20+
21+
22+
def create_certificate_authority(
23+
project_id: str,
24+
location: str,
25+
ca_pool_name: str,
26+
ca_name: str,
27+
common_name: str,
28+
organization: str,
29+
ca_duration: int,
30+
) -> None:
31+
"""
32+
Create Certificate Authority which is the root CA in the given CA Pool. This CA will be
33+
responsible for signing certificates within this pool.
34+
35+
Args:
36+
project_id: project ID or project number of the Cloud project you want to use.
37+
location: location you want to use. For a list of locations, see: https://cloud.google.com/certificate-authority-service/docs/locations.
38+
ca_pool_name: set it to the CA Pool under which the CA should be created.
39+
ca_name: unique name for the CA.
40+
common_name: a title for your certificate authority.
41+
organization: the name of your company for your certificate authority.
42+
ca_duration: the validity of the certificate authority in seconds.
43+
"""
44+
45+
caServiceClient = privateca_v1.CertificateAuthorityServiceClient()
46+
47+
# Set the types of Algorithm used to create a cloud KMS key.
48+
key_version_spec = privateca_v1.CertificateAuthority.KeyVersionSpec(
49+
algorithm=privateca_v1.CertificateAuthority.SignHashAlgorithm.RSA_PKCS1_4096_SHA256
50+
)
51+
52+
# Set CA subject config.
53+
subject_config = privateca_v1.CertificateConfig.SubjectConfig(
54+
subject=privateca_v1.Subject(common_name=common_name, organization=organization)
55+
)
56+
57+
# Set the key usage options for X.509 fields.
58+
x509_parameters = privateca_v1.X509Parameters(
59+
key_usage=privateca_v1.KeyUsage(
60+
base_key_usage=privateca_v1.KeyUsage.KeyUsageOptions(
61+
crl_sign=True,
62+
cert_sign=True,
63+
)
64+
),
65+
ca_options=privateca_v1.X509Parameters.CaOptions(
66+
is_ca=True,
67+
),
68+
)
69+
70+
# Set certificate authority settings.
71+
certificate_authority = privateca_v1.CertificateAuthority(
72+
# CertificateAuthority.Type.SELF_SIGNED denotes that this CA is a root CA.
73+
type_=privateca_v1.CertificateAuthority.Type.SELF_SIGNED,
74+
key_spec=key_version_spec,
75+
config=privateca_v1.CertificateConfig(
76+
subject_config=subject_config,
77+
x509_config=x509_parameters,
78+
),
79+
lifetime=duration_pb2.Duration(seconds=ca_duration),
80+
)
81+
82+
ca_pool_path = caServiceClient.ca_pool_path(project_id, location, ca_pool_name)
83+
84+
# Create the CertificateAuthorityRequest.
85+
request = privateca_v1.CreateCertificateAuthorityRequest(
86+
parent=ca_pool_path,
87+
certificate_authority_id=ca_name,
88+
certificate_authority=certificate_authority,
89+
)
90+
91+
operation = caServiceClient.create_certificate_authority(request=request)
92+
result = operation.result()
93+
94+
print("Operation result:", result)
95+
96+
97+
# [END privateca_create_ca]

privateca/snippets/delete_ca_pool.py

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
#!/usr/bin/env python
2+
3+
# Copyright 2021 Google LLC
4+
#
5+
# Licensed under the Apache License, Version 2.0 (the "License");
6+
# you may not use this file except in compliance with the License.
7+
# You may obtain a copy of the License at
8+
#
9+
# http://www.apache.org/licenses/LICENSE-2.0
10+
#
11+
# Unless required by applicable law or agreed to in writing, software
12+
# distributed under the License is distributed on an "AS IS" BASIS,
13+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
# See the License for the specific language governing permissions and
15+
# limitations under the License.
16+
17+
# [START privateca_delete_ca_pool]
18+
import google.cloud.security.privateca_v1 as privateca_v1
19+
20+
21+
def delete_ca_pool(project_id: str, location: str, ca_pool_name: str) -> None:
22+
"""
23+
Delete the CA pool as mentioned by the ca_pool_name.
24+
Before deleting the pool, all CAs in the pool MUST BE deleted.
25+
26+
Args:
27+
project_id: project ID or project number of the Cloud project you want to use.
28+
location: location you want to use. For a list of locations, see: https://cloud.google.com/certificate-authority-service/docs/locations.
29+
ca_pool_name: the name of the CA pool to be deleted.
30+
"""
31+
32+
caServiceClient = privateca_v1.CertificateAuthorityServiceClient()
33+
34+
ca_pool_path = caServiceClient.ca_pool_path(project_id, location, ca_pool_name)
35+
36+
# Create the Delete request.
37+
request = privateca_v1.DeleteCaPoolRequest(name=ca_pool_path)
38+
39+
# Delete the CA Pool.
40+
caServiceClient.delete_ca_pool(request=request)
41+
42+
print("Deleted CA Pool:", ca_pool_name)
43+
44+
45+
# [END privateca_delete_ca_pool]

0 commit comments

Comments
 (0)