laforge has uploaded this change for review. ( https://gerrit.osmocom.org/c/pysim/+/35569?usp=email )
Change subject: euicc: Implement EID checksum verification + computation ...................................................................... euicc: Implement EID checksum verification + computation Change-Id: I2cb342783137ee7e4b1be3b14e9c3747316f1995 --- M pySim/euicc.py A tests/test_euicc.py 2 files changed, 70 insertions(+), 0 deletions(-) git pull ssh://gerrit.osmocom.org:29418/pysim refs/changes/69/35569/1 diff --git a/pySim/euicc.py b/pySim/euicc.py index 96d95d6..e249f4f 100644 --- a/pySim/euicc.py +++ b/pySim/euicc.py @@ -32,6 +32,36 @@ from pySim.utils import Hexstr, SwHexstr import pySim.global_platform +def compute_eid_checksum(eid) -> str: + """Compute and add/replace check digits of an EID value according to GSMA SGP.29 Section 10.""" + if type(eid) == str: + if len(eid) == 30: + # first pad by 2 digits + eid += "00" + elif len(eid) == 32: + # zero the last two digits + eid = eid[:-2] + "00" + else: + raise ValueError("and EID must be 30 or 32 digits") + eid_int = int(eid) + elif type(eid) == int: + eid_int = eid + if eid_int % 100: + # zero the last two digits + eid_int -= eid_int % 100 + # Using the resulting 32 digits as a decimal integer, compute the remainder of that number on division by + # 97, Subtract the remainder from 98, and use the decimal result for the two check digits, if the result + # is one digit long, its value SHALL be prefixed by one digit of 0. + csum = 98 - (eid_int % 97) + eid_int += csum + return str(eid_int) + +def verify_eid_checksum(eid) -> bool: + """Verify the check digits of an EID value according to GSMA SGP.29 Section 10.""" + # Using the 32 digits as a decimal integer, compute the remainder of that number on division by 97. If the + # remainder of the division is 1, the verification is successful; otherwise the EID is invalid. + return int(eid) % 97 == 1 + class VersionAdapter(Adapter): """convert an EUICC Version (3-int array) to a textual representation.""" diff --git a/tests/test_euicc.py b/tests/test_euicc.py new file mode 100755 index 0000000..05d71ed --- /dev/null +++ b/tests/test_euicc.py @@ -0,0 +1,31 @@ +#!/usr/bin/env python3 + +import unittest + +from pySim.euicc import * + +class TestEid(unittest.TestCase): + + def test_eid_verify(self): + for eid in ['89049032123451234512345678901235', '89086030202200000022000023022943', + '89044045116727494800000004479366', 89044045116727494800000004479366]: + self.assertTrue(verify_eid_checksum(eid)) + + def test_eid_verify_wrong(self): + self.assertFalse(verify_eid_checksum('89049032123451234512345678901234')) + self.assertFalse(verify_eid_checksum(89049032123451234512345678901234)) + + def test_eid_encode_with_32_digits(self): + self.assertEquals(compute_eid_checksum('89049032123451234512345678901200'), '89049032123451234512345678901235') + self.assertEquals(compute_eid_checksum('89086030202200000022000023022900'), '89086030202200000022000023022943') + + def test_eid_encode_with_30digits(self): + self.assertEquals(compute_eid_checksum('890490321234512345123456789012'), '89049032123451234512345678901235') + + def test_eid_encode_with_wrong_csum(self): + # input: EID with wrong checksum + self.assertEquals(compute_eid_checksum('89049032123451234512345678901299'), '89049032123451234512345678901235') + self.assertEquals(compute_eid_checksum(89049032123451234512345678901299), '89049032123451234512345678901235') + +if __name__ == "__main__": + unittest.main() -- To view, visit https://gerrit.osmocom.org/c/pysim/+/35569?usp=email To unsubscribe, or for help writing mail filters, visit https://gerrit.osmocom.org/settings Gerrit-Project: pysim Gerrit-Branch: master Gerrit-Change-Id: I2cb342783137ee7e4b1be3b14e9c3747316f1995 Gerrit-Change-Number: 35569 Gerrit-PatchSet: 1 Gerrit-Owner: laforge <lafo...@osmocom.org> Gerrit-MessageType: newchange