Skip to content

Commit

Permalink
Fix of the HashedId8 implementation.
Browse files Browse the repository at this point in the history
  • Loading branch information
ateska committed Feb 18, 2019
1 parent 1026f35 commit d34a0fa
Show file tree
Hide file tree
Showing 2 changed files with 17 additions and 21 deletions.
2 changes: 1 addition & 1 deletion itss/certificate.py
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,7 @@ def __init__(self, data:bytes):
assert(len(self.Data) == fi.tell())

self.IsVerified = None
self.Digest = compute_HashedId8(self.Signature['ecdsa_signature']['R']['x'])
self.Digest = compute_HashedId8(self)


def __repr__(self):
Expand Down
36 changes: 16 additions & 20 deletions itss/hashedid8.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@
import hashlib
import logging

from .enums import EccPointType, PublicKeyAlgorithm

#

L = logging.getLogger(__name__)
Expand All @@ -20,7 +22,7 @@ async def get_pubkey_by_HashedId8(app, hashedid8):
return cert.public_key()


def compute_HashedId8(signature_r_x):
def compute_HashedId8(certificate):
'''
Defined in ETSI TS 103 097 V1.2.1 (section 4.2.12)
Expand All @@ -36,32 +38,26 @@ def compute_HashedId8(signature_r_x):
Usage:
HashedId8 = compute_HashedId8(Signature['ecdsa_signature']['R']['x'])
HashedId8 = compute_HashedId8(certificate)
'''

#TODO: This is DER encoding ... likely different from CER encoding, which is required by specifications

encoded = signature_r_x.to_bytes(32, 'big')
if (encoded[0] & 0x80) == 0x80:
encoded = b'\0' + encoded

encoded = struct.pack(">BB",
0x81, len(encoded)
) + encoded
# Strip a signature from a certificate data
canonical_cert_bytes = certificate.Data[:certificate.SignaturePosition]

encoded = struct.pack(">BBBBB",
0x80, 0x01, 0x00, # x_coordinate_only
0xA1, len(encoded)
) + encoded
# Add a signature algorithm
assert(certificate.Signature['algorithm'] == PublicKeyAlgorithm.ecdsa_nistp256_with_sha256)
canonical_cert_bytes += struct.pack(">B", certificate.Signature['algorithm'])

# Enclose in the array
encoded = struct.pack(">BB",
0x30, len(encoded)
) + encoded
# Add a signature EcdsaSignature
r_x = certificate.Signature['ecdsa_signature']['R']['x']
canonical_cert_bytes += struct.pack(">B", EccPointType.x_coordinate_only) + r_x.to_bytes(32, 'big')
canonical_cert_bytes += certificate.Signature['ecdsa_signature']['s']

# Calculate a SHA-256 hash from the whole certificate
m = hashlib.sha256()
m.update(encoded)
m.update(canonical_cert_bytes)
hashed = m.digest()

# HashedId8 takes the least significant eight bytes
return(hashed[-8:])

0 comments on commit d34a0fa

Please sign in to comment.