Hoernchen has uploaded this change for review. (
https://gerrit.osmocom.org/c/pysim/+/40468?usp=email )
Change subject: smdpp: less verbose by default
......................................................................
smdpp: less verbose by default
Those data blobs are huge.
Change-Id: I04a72b8f52417862d4dcba1f0743700dd942ef49
---
M osmo-smdpp.py
M pySim/esim/bsp.py
M pySim/esim/es8p.py
3 files changed, 51 insertions(+), 11 deletions(-)
git pull ssh://gerrit.osmocom.org:29418/pysim refs/changes/68/40468/1
diff --git a/osmo-smdpp.py b/osmo-smdpp.py
index 92bbb42..b8b6303 100755
--- a/osmo-smdpp.py
+++ b/osmo-smdpp.py
@@ -47,6 +47,9 @@
from pySim.esim.x509_cert import oid, cert_policy_has_oid, cert_get_auth_key_id
from pySim.esim.x509_cert import CertAndPrivkey, CertificateSet, cert_get_subject_key_id,
VerifyError
+import logging
+logger = logging.getLogger(__name__)
+
# HACK: make this configurable
DATA_DIR = './smdpp-data'
HOSTNAME = 'testsmdpplus1.example.com' # must match certificates!
@@ -356,7 +359,7 @@
validate_request_headers(request)
content = json.loads(request.content.read())
- print("Rx JSON: %s" % json.dumps(content))
+ logger.debug("Rx JSON: %s" % json.dumps(content))
set_headers(request)
output = func(self, request, content)
@@ -364,7 +367,7 @@
return ''
build_resp_header(output)
- print("Tx JSON: %s" % json.dumps(output))
+ logger.debug("Tx JSON: %s" % json.dumps(output))
return json.dumps(output)
return _api_wrapper
@@ -383,7 +386,7 @@
euiccInfo1_bin = b64decode(content['euiccInfo1'])
euiccInfo1 = rsp.asn1.decode('EUICCInfo1', euiccInfo1_bin)
- print("Rx euiccInfo1: %s" % euiccInfo1)
+ logger.debug("Rx euiccInfo1: %s" % euiccInfo1)
#euiccInfo1['svn']
# TODO: If euiccCiPKIdListForSigningV3 is present ...
@@ -458,7 +461,7 @@
authenticateServerResp_bin =
b64decode(content['authenticateServerResponse'])
authenticateServerResp = rsp.asn1.decode('AuthenticateServerResponse',
authenticateServerResp_bin)
- print("Rx %s: %s" % authenticateServerResp)
+ logger.debug("Rx %s: %s" % authenticateServerResp)
if authenticateServerResp[0] == 'authenticateResponseError':
r_err = authenticateServerResp[1]
#r_err['transactionId']
@@ -589,7 +592,7 @@
prepDownloadResp_bin = b64decode(content['prepareDownloadResponse'])
prepDownloadResp = rsp.asn1.decode('PrepareDownloadResponse',
prepDownloadResp_bin)
- print("Rx %s: %s" % prepDownloadResp)
+ logger.debug("Rx %s: %s" % prepDownloadResp)
if prepDownloadResp[0] == 'downloadResponseError':
r_err = prepDownloadResp[1]
@@ -611,7 +614,7 @@
# store otPK.EUICC.ECKA in session state
ss.euicc_otpk = euiccSigned2['euiccOtpk']
- print("euiccOtpk: %s" % (b2h(ss.euicc_otpk)))
+ logger.debug("euiccOtpk: %s" % (b2h(ss.euicc_otpk)))
# Generate a one-time ECKA key pair (ot{PK,SK}.DP.ECKA) using the curve indicated
by the Key Parameter
# Reference value of CERT.DPpb.ECDDSA
@@ -619,8 +622,8 @@
ss.smdp_ot = ec.generate_private_key(self.dp_pb.get_curve())
# extract the public key in (hopefully) the right format for the ES8+ interface
ss.smdp_otpk = ss.smdp_ot.public_key().public_bytes(Encoding.X962,
PublicFormat.UncompressedPoint)
- print("smdpOtpk: %s" % b2h(ss.smdp_otpk))
- print("smdpOtsk: %s" % b2h(ss.smdp_ot.private_bytes(Encoding.DER,
PrivateFormat.PKCS8, NoEncryption())))
+ logger.debug("smdpOtpk: %s" % b2h(ss.smdp_otpk))
+ logger.debug("smdpOtsk: %s" %
b2h(ss.smdp_ot.private_bytes(Encoding.DER, PrivateFormat.PKCS8, NoEncryption())))
ss.host_id = b'mahlzeit'
@@ -661,7 +664,7 @@
request.setResponseCode(204)
pendingNotification_bin = b64decode(content['pendingNotification'])
pendingNotification = rsp.asn1.decode('PendingNotification',
pendingNotification_bin)
- print("Rx %s: %s" % pendingNotification)
+ logger.debug("Rx %s: %s" % pendingNotification)
if pendingNotification[0] == 'profileInstallationResult':
profileInstallRes = pendingNotification[1]
pird = profileInstallRes['profileInstallationResultData']
@@ -714,7 +717,7 @@
@rsp_api_wrapper
def cancelSession(self, request: IRequest, content: dict) -> dict:
"""See ES9+ CancelSession in SGP.22 Section
5.6.5"""
- print("Rx JSON: %s" % content)
+ logger.debug("Rx JSON: %s" % content)
transactionId = content['transactionId']
# Verify that the received transactionId is known and relates to an ongoing RSP
session
@@ -724,7 +727,7 @@
cancelSessionResponse_bin = b64decode(content['cancelSessionResponse'])
cancelSessionResponse = rsp.asn1.decode('CancelSessionResponse',
cancelSessionResponse_bin)
- print("Rx %s: %s" % cancelSessionResponse)
+ logger.debug("Rx %s: %s" % cancelSessionResponse)
if cancelSessionResponse[0] == 'cancelSessionResponseError':
# FIXME: print some error
@@ -760,8 +763,11 @@
parser.add_argument("-p", "--port", help="TCP port to bind
HTTP to", default=8000)
parser.add_argument("-c", "--certpath", help=f"cert subdir
relative to {DATA_DIR}", default="certs")
parser.add_argument("-s", "--nossl", help="do NOT use
ssl", action='store_true', default=False)
+ parser.add_argument("-v", "--verbose", help="dump more raw
info", action='store_true', default=False)
args = parser.parse_args()
+ logging.basicConfig(level=logging.DEBUG if args.verbose else logging.WARNING)
+
common_cert_path = os.path.join(DATA_DIR, args.certpath)
hs = SmDppHttpServer(server_hostname=HOSTNAME,
ci_certs_path=os.path.join(common_cert_path, 'CertificateIssuer'),
common_cert_path=common_cert_path, use_brainpool=False)
if(args.nossl):
diff --git a/pySim/esim/bsp.py b/pySim/esim/bsp.py
index fb4c0b3..6935802 100644
--- a/pySim/esim/bsp.py
+++ b/pySim/esim/bsp.py
@@ -149,8 +149,18 @@
temp_data = self.mac_chain + tag_and_length + data
old_mcv = self.mac_chain
c_mac = self._auth(temp_data)
+
+ # DEBUG: Show MAC computation details
+ logger.debug(f"MAC_DEBUG: tag=0x{tag:02x}, lcc={lcc}")
+ logger.debug(f"MAC_DEBUG: tag_and_length: {tag_and_length.hex()}")
+ logger.debug(f"MAC_DEBUG: mac_chain[:20]: {old_mcv[:20].hex()}")
+ logger.debug(f"MAC_DEBUG: temp_data[:20]: {temp_data[:20].hex()}")
+ logger.debug(f"MAC_DEBUG: c_mac: {c_mac.hex()}")
+
# The output data is computed by concatenating the following data: the tag, the
final length, the result of step 2 and the C-MAC value.
ret = tag_and_length + data + c_mac
+ logger.debug(f"MAC_DEBUG: final_output[:20]: {ret[:20].hex()}")
+
logger.debug("auth(tag=0x%x, mcv=%s, s_mac=%s, plaintext=%s, temp=%s) ->
%s",
tag, b2h(old_mcv), b2h(self.s_mac), b2h(data), b2h(temp_data),
b2h(ret))
return ret
@@ -204,6 +214,11 @@
s_enc = out[l:2*l]
s_mac = out[l*2:3*l]
+ logger.debug(f"BSP_KDF_DEBUG: kdf_out = {b2h(out)}")
+ logger.debug(f"BSP_KDF_DEBUG: initial_mcv =
{b2h(initial_mac_chaining_value)}")
+ logger.debug(f"BSP_KDF_DEBUG: s_enc = {b2h(s_enc)}")
+ logger.debug(f"BSP_KDF_DEBUG: s_mac = {b2h(s_mac)}")
+
return s_enc, s_mac, initial_mac_chaining_value
@@ -231,9 +246,21 @@
"""Encrypt + MAC a single plaintext TLV. Returns the protected
ciphertext."""
assert tag <= 255
assert len(plaintext) <= self.max_payload_size
+
+ # DEBUG: Show what we're processing
+ logger.debug(f"BSP_DEBUG: encrypt_and_mac_one(tag=0x{tag:02x},
plaintext_len={len(plaintext)})")
+ logger.debug(f"BSP_DEBUG: plaintext[:20]: {plaintext[:20].hex()}")
+ logger.debug(f"BSP_DEBUG: s_enc[:20]: {self.c_algo.s_enc[:20].hex()}")
+ logger.debug(f"BSP_DEBUG: s_mac[:20]: {self.m_algo.s_mac[:20].hex()}")
+
logger.debug("encrypt_and_mac_one(tag=0x%x, plaintext=%s)", tag,
b2h(plaintext))
ciphered = self.c_algo.encrypt(plaintext)
+ logger.debug(f"BSP_DEBUG: ciphered[:20]: {ciphered[:20].hex()}")
+
maced = self.m_algo.auth(tag, ciphered)
+ logger.debug(f"BSP_DEBUG: final_result[:20]: {maced[:20].hex()}")
+ logger.debug(f"BSP_DEBUG: final_result_len: {len(maced)}")
+
return maced
def encrypt_and_mac(self, tag: int, plaintext:bytes) -> List[bytes]:
diff --git a/pySim/esim/es8p.py b/pySim/esim/es8p.py
index 8bd7e14..4c854f1 100644
--- a/pySim/esim/es8p.py
+++ b/pySim/esim/es8p.py
@@ -25,6 +25,9 @@
from pySim.esim.bsp import BspInstance
from pySim.esim import PMO
+import logging
+logger = logging.getLogger(__name__)
+
# Given that GSMA RSP uses ASN.1 in a very weird way, we actually cannot encode the full
data type before
# signing, but we have to build parts of it separately first, then sign that, so we can
put the signature
# into the same sequence as the signed data. We use the existing pySim TLV code for
this.
@@ -196,8 +199,12 @@
# 'initialiseSecureChannelRequest'
bpp_seq = rsp.asn1.encode('InitialiseSecureChannelRequest', iscr)
# firstSequenceOf87
+ logger.debug(f"BPP_ENCODE_DEBUG: Encrypting ConfigureISDP with BSP
keys")
+ logger.debug(f"BPP_ENCODE_DEBUG: BSP S-ENC: {bsp.c_algo.s_enc.hex()}")
+ logger.debug(f"BPP_ENCODE_DEBUG: BSP S-MAC: {bsp.m_algo.s_mac.hex()}")
bpp_seq += encode_seq(0xa0, bsp.encrypt_and_mac(0x87, conf_idsp_bin))
# sequenceOF88
+ logger.debug(f"BPP_ENCODE_DEBUG: MAC-only StoreMetadata with BSP
keys")
bpp_seq += encode_seq(0xa1, bsp.mac_only(0x88, smr_bin))
if self.ppp: # we have to use session keys
--
To view, visit
https://gerrit.osmocom.org/c/pysim/+/40468?usp=email
To unsubscribe, or for help writing mail filters, visit
https://gerrit.osmocom.org/settings?usp=email
Gerrit-MessageType: newchange
Gerrit-Project: pysim
Gerrit-Branch: master
Gerrit-Change-Id: I04a72b8f52417862d4dcba1f0743700dd942ef49
Gerrit-Change-Number: 40468
Gerrit-PatchSet: 1
Gerrit-Owner: Hoernchen <ewild(a)sysmocom.de>