-
Notifications
You must be signed in to change notification settings - Fork 6
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add dg2, dg7 and dg11 #3
base: master
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,36 +1,31 @@ | ||
from .base import ( | ||
ElementaryFile, | ||
ElementaryFileError, | ||
LDSVersionInfo | ||
) | ||
|
||
from .dg import ( | ||
DataGroup, | ||
DataGroupNumber, | ||
DG1, | ||
DG14, | ||
DG15 | ||
) | ||
|
||
from .mrz import ( | ||
MachineReadableZone | ||
) | ||
|
||
from .sod import ( | ||
SOD, | ||
SODError | ||
) | ||
from .base import ElementaryFile, ElementaryFileError, LDSVersionInfo | ||
from .dg import DataGroup, DataGroupNumber | ||
from .dg1 import DG1, DataGroup1 | ||
from .dg2 import DG2, DataGroup2 | ||
from .dg7 import DG7, DataGroup7 | ||
from .dg11 import DG11, DataGroup11 | ||
from .dg14 import DG14 | ||
from .dg15 import DG15 | ||
from .errors import NFCPassportReaderError | ||
from .sod import SOD, SODError | ||
|
||
__all__ = [ | ||
"ElementaryFile", | ||
"ElementaryFileError", | ||
"LDSVersionInfo", | ||
"DataGroup", | ||
"DataGroupNumber", | ||
"DataGroup1", | ||
"DG1", | ||
"DataGroup2", | ||
"DG2", | ||
"DataGroup7", | ||
"DG7", | ||
"DataGroup11", | ||
"DG11", | ||
"DG14", | ||
"DG15", | ||
"ElementaryFile", | ||
"ElementaryFileError", | ||
"LDSVersionInfo", | ||
"MachineReadableZone", | ||
"NFCPassportReaderError", | ||
"SOD", | ||
"SODError" | ||
] | ||
"SODError", | ||
] |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,41 +1,68 @@ | ||
import hashlib | ||
|
||
import asn1crypto.core as asn1 | ||
import asn1crypto.parser as asn1Parser | ||
|
||
|
||
class LDSVersionInfo(asn1.Sequence): | ||
_fields = [ | ||
('ldsVersion', asn1.PrintableString), | ||
('unicodeVersion', asn1.PrintableString), | ||
("ldsVersion", asn1.PrintableString), | ||
("unicodeVersion", asn1.PrintableString), | ||
Comment on lines
+9
to
+10
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Nit, Use single quote mark. |
||
] | ||
|
||
|
||
class ElementaryFileError(ValueError): | ||
pass | ||
|
||
|
||
class ElementaryFile(asn1.Asn1Value): | ||
_content_spec = None | ||
_str_rep = None | ||
|
||
def __init__(self, explicit=None, implicit=None, no_explicit=False, tag_type=None, class_=None, tag=None, | ||
optional=None, default=None, contents=None, method=None, spec=None): | ||
def __init__( | ||
self, | ||
explicit=None, | ||
implicit=None, | ||
no_explicit=False, | ||
tag_type=None, | ||
class_=None, | ||
tag=None, | ||
optional=None, | ||
default=None, | ||
contents=None, | ||
method=None, | ||
spec=None, | ||
): | ||
if spec: | ||
self._content_spec = spec | ||
super().__init__(explicit=explicit, implicit=implicit, no_explicit=no_explicit, tag_type=tag_type, class_=class_, tag=tag, | ||
optional=optional, default=default, contents=contents, method=method) | ||
super().__init__( | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Nit, add 1 line break. |
||
explicit=explicit, | ||
implicit=implicit, | ||
no_explicit=no_explicit, | ||
tag_type=tag_type, | ||
class_=class_, | ||
tag=tag, | ||
optional=optional, | ||
default=default, | ||
contents=contents, | ||
method=method, | ||
) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Nit, add 1 line break before next |
||
self._content = None | ||
self._fp = None | ||
self._fp = None | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Nit, align assignment to match original style. |
||
|
||
def __str__(self): | ||
""" | ||
Returns string representation of self i.e. EF(fp=XXXXXXXXXXXXXXXX) | ||
""" | ||
if self._str_rep is None: | ||
self._str_rep = f'EF(fp={self.fingerprint})' | ||
self._str_rep = f"EF(fp={self.fingerprint})" | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Nit, Use single quote mark. |
||
return self._str_rep | ||
|
||
@classmethod | ||
def load(cls, encoded_data: bytes, strict=False): #pylint: disable=arguments-differ | ||
''' | ||
def load( | ||
cls, encoded_data: bytes, strict=False | ||
): # pylint: disable=arguments-differ | ||
""" | ||
Loads a BER/DER-encoded byte string using the current class as the spec | ||
:param encoded_data: | ||
A byte string of BER or DER encoded data | ||
|
@@ -44,29 +71,35 @@ def load(cls, encoded_data: bytes, strict=False): #pylint: disable=arguments-dif | |
ValueError will be raised when trailing data exists | ||
:return: | ||
A instance of the current class | ||
''' | ||
""" | ||
|
||
class_, method, tag, header, contents, trailer = asn1Parser.parse(encoded_data, strict=strict) #pylint: disable=unused-variable | ||
class_, method, tag, header, contents, trailer = asn1Parser.parse( | ||
encoded_data, strict=strict | ||
) # pylint: disable=unused-variable | ||
value = cls(class_=class_, tag=tag, method=method, contents=contents) | ||
|
||
if cls.class_ is not None and value.class_ != cls.class_: | ||
raise ElementaryFileError("Invalid elementary file class, expected class '{}' got '{}'" | ||
.format( | ||
raise ElementaryFileError( | ||
"Invalid elementary file class, expected class '{}' got '{}'".format( | ||
asn1.CLASS_NUM_TO_NAME_MAP.get(cls.class_, cls.class_), | ||
asn1.CLASS_NUM_TO_NAME_MAP.get(value.class_, value.class_) | ||
)) | ||
asn1.CLASS_NUM_TO_NAME_MAP.get(value.class_, value.class_), | ||
) | ||
) | ||
if cls.method is not None and value.method != cls.method: | ||
raise ElementaryFileError("Invalid elementary file method , expected method '{}' got '{}'" | ||
.format( | ||
raise ElementaryFileError( | ||
"Invalid elementary file method , expected method '{}' got '{}'".format( | ||
asn1.METHOD_NUM_TO_NAME_MAP.get(cls.method, cls.method), | ||
asn1.METHOD_NUM_TO_NAME_MAP.get(value.method, value.method) | ||
)) | ||
asn1.METHOD_NUM_TO_NAME_MAP.get(value.method, value.method), | ||
) | ||
) | ||
|
||
if cls.tag is not None and value.tag != cls.tag: | ||
raise ElementaryFileError(f"Invalid elementary file tag, expected tag '{cls.tag}' got '{value.tag}'") | ||
raise ElementaryFileError( | ||
f"Invalid elementary file tag, expected tag '{cls.tag}' got '{value.tag}'" | ||
) | ||
|
||
# Force parsing of content. This is done in order for any invalid content to raise an exception | ||
value.content #pylint: disable=pointless-statement | ||
value.content # pylint: disable=pointless-statement | ||
return value | ||
|
||
@property | ||
|
@@ -76,23 +109,23 @@ def fingerprint(self) -> str: | |
""" | ||
if self._fp is None: | ||
d = hashlib.sha256(self.dump()).digest() | ||
self._fp = d[0:8].hex().upper().rjust(16, '0') | ||
self._fp = d[0:8].hex().upper().rjust(16, "0") | ||
return self._fp | ||
|
||
@property | ||
def content(self): | ||
''' Returns content object of a type content_type ''' | ||
"""Returns content object of a type content_type""" | ||
if self._content is None: | ||
self._parse_content() | ||
return self._content | ||
|
||
@property | ||
def native(self): | ||
''' | ||
""" | ||
The native Python data type representation of this value | ||
:return: | ||
A native representation of content object or None. | ||
''' | ||
""" | ||
|
||
if self.contents is None: | ||
return None | ||
|
@@ -102,28 +135,35 @@ def native(self): | |
return self.content.native | ||
|
||
def _parse_content(self): | ||
''' | ||
""" | ||
Parses the contents and generates Asn1Value content objects based on the | ||
definitions from _content_spec. | ||
:raises: | ||
ValueError - when an error occurs parsing content object | ||
''' | ||
""" | ||
|
||
self._content = None | ||
if self.contents is None: | ||
return | ||
|
||
if self._content_spec is not None: | ||
if not issubclass(self._content_spec, asn1.Asn1Value): | ||
raise ValueError(f'_content_spec must be of a Ans1Value type, not {self._content_spec!r}') | ||
raise ValueError( | ||
f"_content_spec must be of a Ans1Value type, not {self._content_spec!r}" | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Nit, Use single quote mark. |
||
) | ||
|
||
try: | ||
self._content = self._content_spec.load(self.contents, strict=True) | ||
if isinstance(self._content, (asn1.Sequence, asn1.SequenceOf)): | ||
self._content._parse_children(recurse=True) #pylint: disable=protected-access | ||
self._content._parse_children( | ||
recurse=True | ||
) # pylint: disable=protected-access | ||
except (ValueError, TypeError) as e: | ||
from asn1crypto._types import type_name #pylint: disable=import-outside-toplevel | ||
from asn1crypto._types import ( | ||
type_name, | ||
) # pylint: disable=import-outside-toplevel | ||
|
||
self._content = None | ||
args = e.args[1:] | ||
e.args = (e.args[0] + f'\n while parsing {type_name(self)}',) + args | ||
args = e.args[1:] | ||
e.args = (e.args[0] + f"\n while parsing {type_name(self)}",) + args | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Nit, Use single quote mark. |
||
raise |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please order imports in list to match the original style.