Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 4dab181

Browse files
bkuangBenson KuangTakashi Matsuo
authored
Add kms/attestations/ directory with sample script to verify attestations (GoogleCloudPlatform#3262)
Co-authored-by: Benson Kuang <[email protected]> Co-authored-by: Takashi Matsuo <[email protected]>
1 parent ca6200a commit 4dab181

File tree

5 files changed

+202
-0
lines changed

5 files changed

+202
-0
lines changed

kms/attestations/README.rst.in

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
# This file is used to generate README.rst
2+
3+
product:
4+
name: Google Cloud Key Management Service
5+
short_name: Cloud Key Management Service
6+
url: https://cloud.google.com/kms/docs/
7+
description: >
8+
The `Cloud Key Management Service`_ allows you to create, import, and manage
9+
cryptographic keys and perform cryptographic operations in a single centralized cloud service.
10+
11+
setup:
12+
- install_deps
13+
14+
samples:
15+
- name: Verify attestations for keys generated by Cloud HSM
16+
file: verify_attestation.py
17+
show_help: True
18+
19+
folder: kms/attestations
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
pytest==5.3.2

kms/attestations/requirements.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
cryptography==2.8
2+
pem==20.1.0
Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
#!/usr/bin/env python
2+
3+
# Copyright 2020 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+
"""This sample demonstrates how to verify HSM attestations using certificate
18+
bundles obtained from Cloud HSM.
19+
20+
For more information, visit https://cloud.google.com/kms/docs/attest-key.
21+
"""
22+
23+
# [START verify_attestations]
24+
import gzip
25+
26+
from cryptography import exceptions
27+
from cryptography import x509
28+
from cryptography.hazmat import backends
29+
from cryptography.hazmat.primitives.asymmetric import padding
30+
import pem
31+
32+
33+
def verify(attestation_file, bundle_file):
34+
"""Verifies an attestation using a bundle of certificates.
35+
36+
Args:
37+
attestation_file: The name of the attestation file.
38+
bundle_file: The name of the bundle file containing the certificates
39+
used to verify the attestation.
40+
41+
Returns:
42+
True if at least one of the certificates in bundle_file can verify the
43+
attestation data and its signature.
44+
"""
45+
with gzip.open(attestation_file, 'rb') as f:
46+
# An attestation file consists of a data portion and a 256 byte
47+
# signature portion concatenated together.
48+
attestation = f.read()
49+
# Separate the components.
50+
data = attestation[:-256]
51+
signature = attestation[-256:]
52+
53+
# Verify the attestation with one of the certificates in the bundle
54+
for cert in pem.parse_file(bundle_file):
55+
cert_obj = x509.load_pem_x509_certificate(
56+
str(cert).encode('utf-8'), backends.default_backend())
57+
try:
58+
# Check if the data was signed by the private key assosicated
59+
# with the public key in the certificate. The data should have
60+
# been signed with PKCS1v15 padding.
61+
cert_obj.public_key().verify(
62+
signature, data, padding.PKCS1v15(),
63+
cert_obj.signature_hash_algorithm)
64+
return True
65+
except exceptions.InvalidSignature:
66+
# Certificate bundles contain certificates that will not be
67+
# able to verify the attestation, so the InvalidSignature
68+
# errors can be ignored.
69+
continue
70+
return False
71+
# [END verify_attestations]
Lines changed: 109 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,109 @@
1+
# Copyright 2020 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 tempfile
16+
17+
import verify_attestation
18+
19+
# Test certificate bundles can be generated with the following steps:
20+
# 1. Generate test key pairs.
21+
# - openssl genrsa -out test1.key 2048
22+
# - openssl genrsa -out test2.key 2048
23+
# 2. Generate test certificates using the key pairs.
24+
# - openssl req -x509 -key test1.key -days 3650 -out test1.pem
25+
# - openssl req -x509 -key test2.key -days 3650 -out test2.pem
26+
# 3. Create a bundle using the test certificates.
27+
# - cat test1.pem test2.pem > bundle.pem
28+
# For instructions on downloading certificate bundles from Cloud HSM, refer to:
29+
# https://cloud.google.com/kms/docs/attest-key#downloading_the_certificates
30+
TEST_CERT_BUNDLE = b"""-----BEGIN CERTIFICATE-----
31+
MIIDZDCCAkwCFE2PSNf++wMw+Jv86m41lbsa9aUMMA0GCSqGSIb3DQEBCwUAMFkx
32+
CzAJBgNVBAYTAkFVMRMwEQYDVQQIDApTb21lLVN0YXRlMSEwHwYDVQQKDBhJbnRl
33+
cm5ldCBXaWRnaXRzIFB0eSBMdGQxEjAQBgNVBAMMCVRlc3QgQ2FyZDAeFw0yMDAz
34+
MzEyMTQ0MjNaFw0zMDAzMjkyMTQ0MjNaMIGDMQswCQYDVQQGEwJBVTETMBEGA1UE
35+
CAwKU29tZS1TdGF0ZTEhMB8GA1UECgwYSW50ZXJuZXQgV2lkZ2l0cyBQdHkgTHRk
36+
MSMwIQYDVQQLDBpjbG91ZC1rbXMtcHJvZC11cy1jZW50cmFsMTEXMBUGA1UEAwwO
37+
VGVzdCBQYXJ0aXRpb24wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDh
38+
cOk8hil8G4vl66jb02eXu2rKO6PmNF1GziXtzawyhx/+PDmEuGu+g/8hpivY6vDr
39+
buAMFs8OIBBBlfED/soVANflXktDRGqWJau+rIrw9EGcclcwzlIboIi6KLPcLih0
40+
N0TTxqRLgy2EsEQ6UKS7su4bOIxD3Z6FSeTsoq+C2sgSWXmLitO0iRYYcgRjoyCU
41+
kdzzO/JCwPKhhQx5NUrrHseALaIltG4D0aWLuBZKyV38yA1XEMdyCGk7RedEYC+v
42+
OzaJrNToQBCIaCdn3F0uqJd49irLNPyQ5CY3NNL8rupJSq3iVxhEIZ8ANaU8UDvo
43+
5iaQNKV1/KiQsXfUW6fbAgMBAAEwDQYJKoZIhvcNAQELBQADggEBAIIGB0aXhd6k
44+
xyWgYzJ0DHpYP2ALwHRWXde5PtEkdHDguPlUTzZ5iTfqOJlEeUXlDO9RV82jc4mE
45+
hguCaMl3Q+2JGLJLCnSDgcaY5WAVBF9FSakdbHBj4Ik9L8NDlUQB6Me4d4gKWpg1
46+
bUD4n2KtvCZGZzA3pfRBcYyAbwC+xEi1XrITyshb0pkjsWO4Urg36W/RpkCiYAw0
47+
Xua0jJMG/wcF+xktd7kgcsBh5Es2VCzyQwisXoOIi3EY7lMJK2+ctjQFy1GxumBU
48+
jBlXj0VjAm3QOVLTh3mfb1XofoIjOOYkMBjXMiQhFy/Lv68u5q7qlEYe92OKxkCO
49+
0UaAcqt8+QM=
50+
-----END CERTIFICATE-----
51+
-----BEGIN CERTIFICATE-----
52+
MIIDRjCCAi4CFBVm+eV+oRkaYq2NyuTfwxWapjFOMA0GCSqGSIb3DQEBCwUAMGYx
53+
CzAJBgNVBAYTAkFVMRMwEQYDVQQIDApTb21lLVN0YXRlMSEwHwYDVQQKDBhJbnRl
54+
cm5ldCBXaWRnaXRzIFB0eSBMdGQxHzAdBgNVBAMMFlRlc3QgTWFudWZhY3R1cmVy
55+
IFJvb3QwHhcNMjAwMzMxMjE0MjU1WhcNMzAwMzI5MjE0MjU1WjBZMQswCQYDVQQG
56+
EwJBVTETMBEGA1UECAwKU29tZS1TdGF0ZTEhMB8GA1UECgwYSW50ZXJuZXQgV2lk
57+
Z2l0cyBQdHkgTHRkMRIwEAYDVQQDDAlUZXN0IENhcmQwggEiMA0GCSqGSIb3DQEB
58+
AQUAA4IBDwAwggEKAoIBAQC28Wu0dusN6AYkYon8RIuHlJWWwZWlTxXSMK4v/IOY
59+
pG9F2/gUEDMQOgpyCCpTc5eLHRPa/Z2QgB0c2VSlQC8FZ1l9/YL7uBTJ0UpDoBf8
60+
LUimIqotneXpL+7CW1kWFLZIgpm0iVuTPjV2b3frtvu0B+nYuyo4dtToebqoOKse
61+
F3ymLsAjSqA9aoCD0XbspAkLJIvdQU28vXY4Y2y0OTGUnaQ7ZDwkNLxeAfeIdNJD
62+
FRCcYsLRopsyptFMYLLDrI70gywAGYaGOxYG8747BIZELyT5Gnt0o7JwpuF8Mi53
63+
T5NGiu5/wLwXnxRRhb3M5+lStdTfvbEfgK1mC0ac8ym5AgMBAAEwDQYJKoZIhvcN
64+
AQELBQADggEBAILH0Q8WlgaGBosPBjnpAsp4eZOfq9skKZERYzFA2wBAy4B0q9/S
65+
3oL1MIZEU6/ckiFyAm3r4/ZxMLX0UrisuRQUFQ3w+gqFccqlmGETsZGJpPtfIm+n
66+
JQo44XXnTHndqoYPNfvfQkp0WtJQS8hSgTASP+1GYjqOn1fZaa28m39/mx9Mrw7K
67+
xtXOtrdKqJhWCWJPprfC5sYNCYTA2HXVmBU2Y4AP4A4w+A1gCAdzvH8EEyDjnvxJ
68+
GEa4uczhA3n+NmhLipg1aGbxJO5ZHXdyFF2rTXVVXSiX8EEasnwcTDjeXDKhdpu6
69+
biaxW9fnsJIXirAE03FFkC/tWelkGFkmMfs=
70+
-----END CERTIFICATE-----"""
71+
72+
# Test attestations can be generated with the following steps:
73+
# 1. Create a file containing the test attestation statement.
74+
# - echo "content" > attestation.dat
75+
# 2. Sign the file with one the key pairs used to create the test certificates.
76+
# - openssl dgst -sha256 -sign test1.key -out signature.dat attestation.dat
77+
# 3. Concatenate the signature to the statement to create an attestation.
78+
# - cat signature.dat >> attestation.dat
79+
# 4. Compress the test attestation.
80+
# - gzip attestation.dat
81+
# For instructions on downloading attestations from Cloud HSM, refer to:
82+
# https://cloud.google.com/kms/docs/attest-key#downloading_the_attestation_statement
83+
TEST_ATTESTATION_GZ = (
84+
b'\x1f\x8b\x08\x08\xda\xde\x84^\x00\x03attestation\x00\x01\x06\x01\xf9\xfe'
85+
b'\x15\xa7~W\xdazHq03\x95\xd1F\xcf\x1d\n\xe0\xbbv\x11\xed\xae\x186\xc0\xcc'
86+
b'.\xcf)\xf1?\xf7!\xf3\xd6M\x85\xfe\xb9\x84\xb2\x08V2(\xa1\x87]\xab\x01='
87+
b'\xb5\x0f)~\x06\xee\xfa/\x94\xa6x\x96o\xb1\xcb$\x82\x90\xe03J\t\x03\xf0'
88+
b'\xa4\xa5\xa9\xf9\xb2\xce\xdd2\xfam\x94W\x07\x00~\xa5\xc2\xcdq\xa1\x81'
89+
b'\x18\x83\xe0\xd9\x11k]\xbd\xf8\x81@\x9c*\x80\x91R\xb0\xae\x9d\x88\xb8T'
90+
b'\xd1>\xf6;\xe4\x83q%_\x8aw\x894\xb5:\xeab\xd2\x9a\x81\xdd\xa6\xf9\x94'
91+
b'\xff8\xb1\xed\x7fs\x0e\xc0\xde\x89\x00]\x8fL\x82\x8a\x11\x8f\\\xe483\x9d'
92+
b'&\x0b%\xfd\x0et\x8f\xa8\x1a\xb5K\xb4\xc7\x96\xd1}\x06\xdd\x93i\x1f\xc1@'
93+
b'\x92\xef}(B\x0f\xd1\x03\xaaYo\x9b\xad\xa9zw#\xc8\x9a\xad\x94\xfc\x07q]x'
94+
b'\xeb\xa2CA\xf8\xac\x96\xd9\xe5y4\xae]\x81\xb0$\x93\tx\xdb\xcc\x08:%\x1d'
95+
b'\xe2q\xaa\xc8:\xc2<C\xb5\x9b\xd1\xb0<\x12\x8a\x99f\x11\x9a"Q\x1d]\xac'
96+
b'\x81\xe2\x05\x06\x01\x00\x00')
97+
98+
99+
def test_verify():
100+
with tempfile.NamedTemporaryFile() as attestation_file:
101+
with tempfile.NamedTemporaryFile() as bundle_file:
102+
attestation_file.write(TEST_ATTESTATION_GZ)
103+
bundle_file.write(TEST_CERT_BUNDLE)
104+
105+
attestation_file.seek(0)
106+
bundle_file.seek(0)
107+
108+
assert verify_attestation.verify(
109+
attestation_file.name, bundle_file.name)

0 commit comments

Comments
 (0)