0
# Certificate Revocation Lists
1
2
Certificate Revocation List (CRL) management for publishing and maintaining lists of revoked certificates. Supports automatic CRL generation, custom update schedules, and distribution through Google Cloud Storage for PKI infrastructure maintenance.
3
4
## Capabilities
5
6
### CRL Information Retrieval
7
8
Retrieves certificate revocation list details and lists CRLs for a specific certificate authority.
9
10
```python { .api }
11
def get_certificate_revocation_list(
12
self,
13
request: Union[GetCertificateRevocationListRequest, dict] = None,
14
*,
15
name: str = None,
16
retry: OptionalRetry = gapic_v1.method.DEFAULT,
17
timeout: Union[float, object] = gapic_v1.method.DEFAULT,
18
metadata: Sequence[Tuple[str, Union[str, bytes]]] = (),
19
) -> CertificateRevocationList:
20
"""
21
Get a certificate revocation list by name.
22
23
Args:
24
request: The request object
25
name: CRL resource name
26
retry: Retry configuration
27
timeout: Request timeout in seconds
28
metadata: Additional metadata
29
30
Returns:
31
CertificateRevocationList: The requested CRL resource
32
"""
33
34
def list_certificate_revocation_lists(
35
self,
36
request: Union[ListCertificateRevocationListsRequest, dict] = None,
37
*,
38
parent: str = None,
39
retry: OptionalRetry = gapic_v1.method.DEFAULT,
40
timeout: Union[float, object] = gapic_v1.method.DEFAULT,
41
metadata: Sequence[Tuple[str, Union[str, bytes]]] = (),
42
) -> pagers.ListCertificateRevocationListsPager:
43
"""
44
List certificate revocation lists for a CA.
45
46
Args:
47
request: The request object
48
parent: CA resource name
49
retry: Retry configuration
50
timeout: Request timeout in seconds
51
metadata: Additional metadata
52
53
Returns:
54
pagers.ListCertificateRevocationListsPager: Paginated response of CRLs
55
"""
56
```
57
58
### CRL Configuration Updates
59
60
Updates certificate revocation list configuration including update schedules and publishing options.
61
62
```python { .api }
63
def update_certificate_revocation_list(
64
self,
65
request: Union[UpdateCertificateRevocationListRequest, dict] = None,
66
*,
67
certificate_revocation_list: CertificateRevocationList = None,
68
update_mask: field_mask_pb2.FieldMask = None,
69
retry: OptionalRetry = gapic_v1.method.DEFAULT,
70
timeout: Union[float, object] = gapic_v1.method.DEFAULT,
71
metadata: Sequence[Tuple[str, Union[str, bytes]]] = (),
72
) -> operation.Operation:
73
"""
74
Update a certificate revocation list.
75
76
Args:
77
request: The request object
78
certificate_revocation_list: CRL with updated fields
79
update_mask: Fields to update
80
retry: Retry configuration
81
timeout: Request timeout in seconds
82
metadata: Additional metadata
83
84
Returns:
85
operation.Operation: Long-running operation for CRL update
86
"""
87
```
88
89
## Request Types
90
91
```python { .api }
92
class GetCertificateRevocationListRequest:
93
"""Request to get a certificate revocation list."""
94
name: str # CRL resource name
95
96
class ListCertificateRevocationListsRequest:
97
"""Request to list certificate revocation lists."""
98
parent: str # CA resource name
99
page_size: int # Maximum results per page
100
page_token: str # Pagination token
101
filter: str # Filter expression
102
order_by: str # Sort order
103
104
class UpdateCertificateRevocationListRequest:
105
"""Request to update a certificate revocation list."""
106
certificate_revocation_list: CertificateRevocationList # CRL with updates
107
update_mask: field_mask_pb2.FieldMask # Fields to update
108
request_id: str # Idempotency token
109
```
110
111
## Certificate Revocation List Resource Type
112
113
```python { .api }
114
class CertificateRevocationList:
115
"""A Certificate Revocation List for a Certificate Authority."""
116
name: str # Resource name
117
sequence_number: int # CRL sequence number
118
revoked_certificates: List[RevokedCertificate] # List of revoked certificates
119
pem_crl: str # PEM-encoded CRL (output only)
120
access_url: str # CRL download URL (output only)
121
state: State # CRL state (output only)
122
create_time: timestamp_pb2.Timestamp # Creation time (output only)
123
update_time: timestamp_pb2.Timestamp # Last update time (output only)
124
revision_id: str # Revision identifier (output only)
125
labels: Dict[str, str] # Resource labels
126
127
class RevokedCertificate:
128
"""Information about a revoked certificate."""
129
certificate: str # Certificate resource name
130
hex_serial_number: str # Certificate serial number in hex
131
revocation_reason: RevocationReason # Reason for revocation
132
```
133
134
## CRL State Enumeration
135
136
```python { .api }
137
class State(Enum):
138
"""CRL states."""
139
STATE_UNSPECIFIED = 0 # Unspecified state
140
ACTIVE = 1 # CRL is active and current
141
SUPERSEDED = 2 # CRL has been superseded by newer version
142
```
143
144
## Usage Examples
145
146
### Retrieving CRL Information
147
148
```python
149
from google.cloud.security.privateca import CertificateAuthorityServiceClient
150
151
client = CertificateAuthorityServiceClient()
152
153
# Get specific CRL
154
crl_name = "projects/my-project/locations/us-central1/caPools/my-ca-pool/certificateAuthorities/my-ca/certificateRevocationLists/my-crl"
155
crl = client.get_certificate_revocation_list(name=crl_name)
156
157
print(f"CRL: {crl.name}")
158
print(f"Sequence number: {crl.sequence_number}")
159
print(f"State: {crl.state}")
160
print(f"Revoked certificates: {len(crl.revoked_certificates)}")
161
print(f"Access URL: {crl.access_url}")
162
163
if crl.revoked_certificates:
164
print("Revoked certificates:")
165
for revoked in crl.revoked_certificates:
166
print(f" Serial: {revoked.hex_serial_number}, Reason: {revoked.revocation_reason}")
167
```
168
169
### Listing CRLs for a Certificate Authority
170
171
```python
172
# List all CRLs for a CA
173
ca_name = "projects/my-project/locations/us-central1/caPools/my-ca-pool/certificateAuthorities/my-ca"
174
crls = client.list_certificate_revocation_lists(parent=ca_name)
175
176
print(f"CRLs for CA {ca_name}:")
177
for crl in crls:
178
print(f" CRL: {crl.name}")
179
print(f" Sequence: {crl.sequence_number}")
180
print(f" State: {crl.state}")
181
print(f" Created: {crl.create_time}")
182
print(f" Updated: {crl.update_time}")
183
print(f" Revoked certs: {len(crl.revoked_certificates)}")
184
print()
185
```
186
187
### Updating CRL Configuration
188
189
```python
190
from google.protobuf import field_mask_pb2
191
192
# Update CRL labels
193
crl_name = "projects/my-project/locations/us-central1/caPools/my-ca-pool/certificateAuthorities/my-ca/certificateRevocationLists/my-crl"
194
195
updated_crl = CertificateRevocationList(
196
name=crl_name,
197
labels={
198
"environment": "production",
199
"ca-type": "root",
200
"auto-update": "enabled"
201
}
202
)
203
204
update_mask = field_mask_pb2.FieldMask(paths=["labels"])
205
206
operation = client.update_certificate_revocation_list(
207
certificate_revocation_list=updated_crl,
208
update_mask=update_mask
209
)
210
211
result = operation.result()
212
print(f"Updated CRL: {result.name}")
213
print(f"New labels: {result.labels}")
214
```
215
216
### Downloading and Processing CRL
217
218
```python
219
import requests
220
from cryptography import x509
221
from cryptography.hazmat.primitives import serialization
222
223
# Get CRL and download the actual CRL data
224
crl_name = "projects/my-project/locations/us-central1/caPools/my-ca-pool/certificateAuthorities/my-ca/certificateRevocationLists/my-crl"
225
crl = client.get_certificate_revocation_list(name=crl_name)
226
227
if crl.access_url:
228
# Download CRL from access URL
229
response = requests.get(crl.access_url)
230
crl_data = response.content
231
232
# Parse CRL using cryptography library
233
parsed_crl = x509.load_der_x509_crl(crl_data)
234
235
print(f"CRL Issuer: {parsed_crl.issuer}")
236
print(f"This Update: {parsed_crl.this_update}")
237
print(f"Next Update: {parsed_crl.next_update}")
238
print(f"Revoked certificates: {len(list(parsed_crl))}")
239
240
# Process revoked certificates
241
for revoked_cert in parsed_crl:
242
print(f" Serial: {revoked_cert.serial_number}")
243
print(f" Revocation Date: {revoked_cert.revocation_date}")
244
if revoked_cert.extensions:
245
for ext in revoked_cert.extensions:
246
print(f" Extension: {ext.oid}")
247
248
# Use PEM format if available
249
if crl.pem_crl:
250
print(f"PEM CRL:\n{crl.pem_crl}")
251
252
# Parse PEM CRL
253
pem_crl = x509.load_pem_x509_crl(crl.pem_crl.encode())
254
print(f"PEM CRL has {len(list(pem_crl))} revoked certificates")
255
```
256
257
### Monitoring CRL Updates
258
259
```python
260
from datetime import datetime, timezone
261
262
def monitor_crl_updates(ca_name: str):
263
"""Monitor CRL updates for a certificate authority."""
264
crls = client.list_certificate_revocation_lists(parent=ca_name)
265
266
for crl in crls:
267
# Convert timestamp to datetime
268
update_time = datetime.fromtimestamp(
269
crl.update_time.seconds + crl.update_time.nanos / 1e9,
270
tz=timezone.utc
271
)
272
273
# Check if CRL is recent (within last 24 hours)
274
time_diff = datetime.now(timezone.utc) - update_time
275
hours_old = time_diff.total_seconds() / 3600
276
277
print(f"CRL: {crl.name}")
278
print(f" State: {crl.state}")
279
print(f" Last updated: {update_time} ({hours_old:.1f} hours ago)")
280
print(f" Revoked certificates: {len(crl.revoked_certificates)}")
281
282
if hours_old > 24:
283
print(f" ⚠️ Warning: CRL is over 24 hours old")
284
285
if crl.state != CertificateRevocationList.State.ACTIVE:
286
print(f" ⚠️ Warning: CRL is not active")
287
288
print()
289
290
# Monitor CRLs for a CA
291
ca_name = "projects/my-project/locations/us-central1/caPools/my-ca-pool/certificateAuthorities/my-ca"
292
monitor_crl_updates(ca_name)
293
```
294
295
### CRL-based Certificate Validation
296
297
```python
298
def check_certificate_revocation(certificate_serial: str, ca_name: str) -> bool:
299
"""Check if a certificate is revoked using CRL."""
300
crls = client.list_certificate_revocation_lists(parent=ca_name)
301
302
for crl in crls:
303
if crl.state == CertificateRevocationList.State.ACTIVE:
304
for revoked_cert in crl.revoked_certificates:
305
if revoked_cert.hex_serial_number.upper() == certificate_serial.upper():
306
print(f"Certificate {certificate_serial} is REVOKED")
307
print(f"Revocation reason: {revoked_cert.revocation_reason}")
308
return True
309
310
print(f"Certificate {certificate_serial} is NOT revoked")
311
return False
312
313
# Check specific certificate
314
cert_serial = "1234567890ABCDEF"
315
ca_name = "projects/my-project/locations/us-central1/caPools/my-ca-pool/certificateAuthorities/my-ca"
316
is_revoked = check_certificate_revocation(cert_serial, ca_name)
317
```