def test_claims_from_json_with_well_known_value(self): with pytest.raises(ValueError) as err: Claims.from_json( { "iss": "coap://as.example.com", "ext1": "foo", }, private_claim_names={"ext": 1}, ) pytest.fail("from_json should fail.") assert ( "The claim key should be other than the values listed in https://python-cwt.readthedocs.io/en/stable/claims.html." in str(err.value))
def test_sample_readme_cwt_with_pop_encrypted_cose_key_readable(self): with open(key_path("private_key_ed25519.pem")) as key_file: private_key = COSEKey.from_pem(key_file.read(), kid="issuer-01") enc_key = COSEKey.from_symmetric_key( "a-client-secret-of-cwt-recipient", # Just 32 bytes! alg="ChaCha20/Poly1305", kid="presenter-01", ) pop_key = COSEKey.from_symmetric_key( "a-client-secret-of-cwt-presenter", alg="HMAC 256/256", ) token = cwt.encode( { "iss": "coaps://as.example", "sub": "dajiaji", "cti": "123", "cnf": { # 'eck'(Encrypted Cose Key) is a keyword defined by this library. "eck": EncryptedCOSEKey.from_cose_key(pop_key, enc_key), }, }, private_key, ) with open(key_path("public_key_ed25519.pem")) as key_file: public_key = COSEKey.from_pem(key_file.read(), kid="issuer-01") decoded = cwt.decode(token, public_key) assert 8 in decoded and isinstance(decoded[8], dict) assert 2 in decoded[8] and isinstance(decoded[8][2], list) c = Claims.new(decoded) extracted = EncryptedCOSEKey.to_cose_key(c.cnf, enc_key) assert extracted.kty == 4 # Symmetric assert extracted.alg == 5 # HMAC 256/256 assert extracted.key == b"a-client-secret-of-cwt-presenter"
def test_sample_hcert_testdata_AT_2DCode_raw_1(self): # A DSC(Document Signing Certificate) issued by a CSCA (Certificate Signing Certificate Authority). dsc = "-----BEGIN CERTIFICATE-----\nMIIBvTCCAWOgAwIBAgIKAXk8i88OleLsuTAKBggqhkjOPQQDAjA2MRYwFAYDVQQDDA1BVCBER0MgQ1NDQSAxMQswCQYDVQQGEwJBVDEPMA0GA1UECgwGQk1TR1BLMB4XDTIxMDUwNTEyNDEwNloXDTIzMDUwNTEyNDEwNlowPTERMA8GA1UEAwwIQVQgRFNDIDExCzAJBgNVBAYTAkFUMQ8wDQYDVQQKDAZCTVNHUEsxCjAIBgNVBAUTATEwWTATBgcqhkjOPQIBBggqhkjOPQMBBwNCAASt1Vz1rRuW1HqObUE9MDe7RzIk1gq4XW5GTyHuHTj5cFEn2Rge37+hINfCZZcozpwQKdyaporPUP1TE7UWl0F3o1IwUDAOBgNVHQ8BAf8EBAMCB4AwHQYDVR0OBBYEFO49y1ISb6cvXshLcp8UUp9VoGLQMB8GA1UdIwQYMBaAFP7JKEOflGEvef2iMdtopsetwGGeMAoGCCqGSM49BAMCA0gAMEUCIQDG2opotWG8tJXN84ZZqT6wUBz9KF8D+z9NukYvnUEQ3QIgdBLFSTSiDt0UJaDF6St2bkUQuVHW6fQbONd731/M4nc=\n-----END CERTIFICATE-----" # An EUDCC (EU Digital COVID Certificate) eudcc = bytes.fromhex( "d2844da20448d919375fc1e7b6b20126a0590133a4041a61817ca0061a60942ea001624154390103a101a4617681aa62646e01626d616d4f52472d3130303033303231356276706a313131393334393030376264746a323032312d30322d313862636f624154626369783155524e3a555643493a30313a41543a31303830373834334639344145453045453530393346424332353442443831332342626d706c45552f312f32302f31353238626973781b4d696e6973747279206f66204865616c74682c20417573747269616273640262746769383430353339303036636e616da463666e74754d5553544552465241553c474f455353494e47455262666e754d7573746572667261752d47c3b6c39f696e67657263676e74684741425249454c4562676e684761627269656c656376657265312e302e3063646f626a313939382d30322d323658405812fce67cb84c3911d78e3f61f890d0c80eb9675806aebed66aa2d0d0c91d1fc98d7bcb80bf00e181806a9502e11b071325901bd0d2c1b6438747b8cc50f521" ) public_key = load_pem_hcert_dsc(dsc) decoded = cwt.decode(eudcc, keys=[public_key], no_verify=True) claims = Claims.new(decoded) assert 1 in claims.hcert assert isinstance(claims.hcert[1], dict) assert "v" in claims.hcert[1] assert "nam" in claims.hcert[1] assert "dob" in claims.hcert[1] assert "ver" in claims.hcert[1] assert isinstance(claims.hcert[1]["v"], list) assert len(claims.hcert[1]["v"]) == 1 assert isinstance(claims.hcert[1]["v"][0], dict) assert isinstance(claims.hcert[1]["nam"], dict) assert "fnt" in claims.hcert[1]["nam"] assert claims.hcert[1]["nam"]["fnt"] == "MUSTERFRAU<GOESSINGER" assert claims.hcert[1]["dob"] == "1998-02-26" assert claims.hcert[1]["ver"] == "1.0.0"
def test_sample_hcert_testdata_AT_2DCode_raw_1_with_cert_file(self): eudcc = bytes.fromhex( "d2844da20448d919375fc1e7b6b20126a0590133a4041a61817ca0061a60942ea001624154390103a101a4617681aa62646e01626d616d4f52472d3130303033303231356276706a313131393334393030376264746a323032312d30322d313862636f624154626369783155524e3a555643493a30313a41543a31303830373834334639344145453045453530393346424332353442443831332342626d706c45552f312f32302f31353238626973781b4d696e6973747279206f66204865616c74682c20417573747269616273640262746769383430353339303036636e616da463666e74754d5553544552465241553c474f455353494e47455262666e754d7573746572667261752d47c3b6c39f696e67657263676e74684741425249454c4562676e684761627269656c656376657265312e302e3063646f626a313939382d30322d323658405812fce67cb84c3911d78e3f61f890d0c80eb9675806aebed66aa2d0d0c91d1fc98d7bcb80bf00e181806a9502e11b071325901bd0d2c1b6438747b8cc50f521" ) with open(key_path("hcert_testdata_cert_at.pem")) as key_file: dsc = key_file.read() public_key = load_pem_hcert_dsc(dsc) decoded = cwt.decode(eudcc, keys=[public_key], no_verify=True) claims = Claims.new(decoded) assert 1 in claims.hcert assert isinstance(claims.hcert[1], dict) assert "v" in claims.hcert[1] assert "nam" in claims.hcert[1] assert "dob" in claims.hcert[1] assert "ver" in claims.hcert[1] assert isinstance(claims.hcert[1]["v"], list) assert len(claims.hcert[1]["v"]) == 1 assert isinstance(claims.hcert[1]["v"][0], dict) assert isinstance(claims.hcert[1]["nam"], dict) assert "fnt" in claims.hcert[1]["nam"] assert claims.hcert[1]["nam"]["fnt"] == "MUSTERFRAU<GOESSINGER" assert claims.hcert[1]["dob"] == "1998-02-26" assert claims.hcert[1]["ver"] == "1.0.0"
def test_sample_readme_cwt_with_user_defined_claims(self): with open(key_path("private_key_ed25519.pem")) as key_file: private_key = COSEKey.from_pem(key_file.read(), kid="01") token = cwt.encode( { 1: "coaps://as.example", # iss 2: "dajiaji", # sub 7: b"123", # cti -70001: "foo", -70002: ["bar"], -70003: {"baz": "qux"}, -70004: 123, }, private_key, ) with open(key_path("public_key_ed25519.pem")) as key_file: public_key = COSEKey.from_pem(key_file.read(), kid="01") raw = cwt.decode(token, public_key) assert raw[-70001] == "foo" assert isinstance(raw[-70002], list) assert raw[-70002][0] == "bar" assert isinstance(raw[-70003], dict) assert raw[-70003]["baz"] == "qux" assert raw[-70004] == 123 readable = Claims.new(raw) assert readable.get(-70001) == "foo" assert readable.get(-70002)[0] == "bar" assert readable.get(-70003)["baz"] == "qux" assert readable.get(-70004) == 123
def test_claims_from_json_with_unknown_key(self): claims = Claims.from_json({ "iss": "coap://as.example.com", "unknown": "something", }).to_dict() assert len(claims) == 1 assert claims[1] == "coap://as.example.com"
def test_sample_readme_maced_cwt_with_json_str_old(self): key = COSEKey.from_symmetric_key("mysecretpassword", alg="HS256", kid="01") encoded = cwt.encode_and_mac( Claims.from_json('{"iss":"coaps://as.example","sub":"dajiaji","cti":"123"}'), key, ) decoded = cwt.decode(encoded, key) assert 1 in decoded and decoded[1] == "coaps://as.example"
def test_claims_from_json_with_undefined_key(self): claims = Claims.from_json( { "iss": "coap://as.example.com", "ext1": "foo", }, {"ext": -70001}, ) assert claims.get("ext1") is None
def test_claims_from_json_with_empty_object(self): claims = Claims.from_json({}) assert claims.iss is None assert claims.sub is None assert claims.aud is None assert claims.cti is None assert claims.exp is None assert claims.nbf is None assert claims.iat is None assert claims.cnf is None
def test_claims_from_json_with_cnf(self, json): claims = Claims.from_json(json) assert claims.iss == "coap://as.example.com" assert claims.sub == "erikw" assert claims.aud == "coap://light.example.com" assert claims.cti == "123" assert claims.exp == 1444064944 assert claims.nbf == 1443944944 assert claims.iat == 1443944944 assert isinstance(claims.cnf, dict)
def test_sample_readme_encrypted_cwt_old(self): nonce = token_bytes(13) mysecret = token_bytes(32) enc_key = COSEKey.from_symmetric_key(mysecret, alg="AES-CCM-16-64-256", kid="01") encoded = cwt.encode_and_encrypt( Claims.from_json({"iss": "coaps://as.example", "sub": "dajiaji", "cti": "123"}), enc_key, nonce=nonce, ) decoded = cwt.decode(encoded, enc_key) assert 1 in decoded and decoded[1] == "coaps://as.example"
def test_sample_readme_signed_cwt_ed25519_old(self): with open(key_path("private_key_ed25519.pem")) as key_file: private_key = COSEKey.from_pem(key_file.read(), kid="01") encoded = cwt.encode_and_sign( Claims.from_json({"iss": "coaps://as.example", "sub": "dajiaji", "cti": "123"}), private_key, ) with open(key_path("public_key_ed25519.pem")) as key_file: public_key = COSEKey.from_pem(key_file.read(), kid="01") decoded = cwt.decode(encoded, public_key) assert 1 in decoded and decoded[1] == "coaps://as.example"
def test_sample_readme_maced_cwt_with_json_dict_old(self): key = COSEKey.from_symmetric_key("mysecretpassword", alg="HS256", kid="01") encoded = cwt.encode_and_mac( Claims.from_json({"iss": "coaps://as.example", "sub": "dajiaji", "cti": "123"}), key, ) decoded = cwt.decode(encoded, key) assert 1 in decoded and decoded[1] == "coaps://as.example" assert 2 in decoded and decoded[2] == "dajiaji" assert 4 in decoded and decoded[4] <= now() + 3600 assert 5 in decoded and decoded[5] <= now() assert 6 in decoded and decoded[6] <= now() assert 7 in decoded and decoded[7] == b"123"
def test_claims_from_json_with_private_claim_names(self): claims = Claims.from_json( { "iss": "coap://as.example.com", "ext": "foo", }, private_claim_names={ "ext": -70001 }, ).to_dict() assert len(claims) == 2 assert claims[1] == "coap://as.example.com" assert claims[-70001] == "foo"
def test_sample_readme_cwt_with_pop_jwk(self): # issuer: with open(key_path("private_key_ed25519.pem")) as key_file: private_key = COSEKey.from_pem(key_file.read(), kid="issuer-01") token = cwt.encode( { "iss": "coaps://as.example", "sub": "dajiaji", "cti": "123", "cnf": { "jwk": { "kty": "OKP", "use": "sig", "crv": "Ed25519", "kid": "01", "x": "2E6dX83gqD_D0eAmqnaHe1TC1xuld6iAKXfw2OVATr0", "alg": "EdDSA", }, }, }, private_key, ) # presenter: msg = b"could-you-sign-this-message?" # Provided by recipient. pop_key_private = COSEKey.from_jwk( { "kty": "OKP", "d": "L8JS08VsFZoZxGa9JvzYmCWOwg7zaKcei3KZmYsj7dc", "use": "sig", "crv": "Ed25519", "kid": "01", "x": "2E6dX83gqD_D0eAmqnaHe1TC1xuld6iAKXfw2OVATr0", "alg": "EdDSA", } ) sig = pop_key_private.sign(msg) # recipient: with open(key_path("public_key_ed25519.pem")) as key_file: public_key = COSEKey.from_pem(key_file.read(), kid="issuer-01") decoded = cwt.decode(token, public_key) assert 8 in decoded and isinstance(decoded[8], dict) assert 1 in decoded[8] and isinstance(decoded[8][1], dict) c = Claims.new(decoded) extracted = COSEKey.new(c.cnf) try: extracted.verify(msg, sig) except Exception: pytest.fail("verify should not fail.")
def test_sample_readme_nested_cwt_old(self): with open(key_path("private_key_es256.pem")) as key_file: private_key = COSEKey.from_pem(key_file.read(), kid="01") encoded = cwt.encode_and_sign( Claims.from_json({"iss": "coaps://as.example", "sub": "dajiaji", "cti": "123"}), private_key, ) nonce = token_bytes(13) mysecret = token_bytes(32) enc_key = COSEKey.from_symmetric_key(mysecret, alg="AES-CCM-16-64-256", kid="02") nested = cwt.encode_and_encrypt(encoded, enc_key, nonce=nonce) with open(key_path("public_key_es256.pem")) as key_file: public_key = COSEKey.from_pem(key_file.read(), kid="01") decoded = cwt.decode(nested, [enc_key, public_key]) assert 1 in decoded and decoded[1] == "coaps://as.example"
def test_key_builder_from_jwk_with_encode_and_sign(self, private_key_path, public_key_path): with open(key_path(private_key_path)) as key_file: private_key = COSEKey.from_jwk(key_file.read()) with open(key_path(public_key_path)) as key_file: public_key = COSEKey.from_jwk(key_file.read()) token = cwt.encode_and_sign( Claims.from_json({ "iss": "coaps://as.example", "sub": "dajiaji", "cti": "123" }), private_key, ) # token = cwt.encode( # {"iss": "coaps://as.example", "sub": "dajiaji", "cti": "123"}, # private_key, # ) decoded = cwt.decode(token, public_key) assert 1 in decoded and decoded[1] == "coaps://as.example"
def test_sample_readme_cwt_with_user_defined_claims_readable(self): with open(key_path("private_key_ed25519.pem")) as key_file: private_key = COSEKey.from_pem(key_file.read(), kid="01") cwt.set_private_claim_names( { "ext_1": -70001, "ext_2": -70002, "ext_3": -70003, "ext_4": -70004, } ) token = cwt.encode( { "iss": "coaps://as.example", "sub": "dajiaji", "cti": b"123", "ext_1": "foo", "ext_2": ["bar"], "ext_3": {"baz": "qux"}, "ext_4": 123, }, private_key, ) with open(key_path("public_key_ed25519.pem")) as key_file: public_key = COSEKey.from_pem(key_file.read(), kid="01") raw = cwt.decode(token, public_key) readable = Claims.new( raw, private_claim_names={ "ext_1": -70001, "ext_2": -70002, "ext_3": -70003, "ext_4": -70004, }, ) assert readable.get("ext_1") == "foo" assert readable.get("ext_2")[0] == "bar" assert readable.get("ext_3")["baz"] == "qux" assert readable.get("ext_4") == 123
def test_sample_readme_cwt_with_pop_kid_readable(self): with open(key_path("private_key_ed25519.pem")) as key_file: private_key = COSEKey.from_pem(key_file.read(), kid="issuer-01") token = cwt.encode( { "iss": "coaps://as.example", "sub": "dajiaji", "cti": "123", "cnf": { "kid": "pop-key-id-of-cwt-presenter", }, }, private_key, ) with open(key_path("public_key_ed25519.pem")) as key_file: public_key = COSEKey.from_pem(key_file.read(), kid="issuer-01") decoded = cwt.decode(token, public_key) assert 8 in decoded and isinstance(decoded[8], dict) assert 3 in decoded[8] and decoded[8][3] == b"pop-key-id-of-cwt-presenter" c = Claims.new(decoded) assert c.cnf == "pop-key-id-of-cwt-presenter"
def test_sample_readme_signed_cwt_es384_old(self): with open(key_path("private_key_es384.pem")) as key_file: private_key = COSEKey.from_pem(key_file.read(), kid="01") with open(key_path("public_key_es384.pem")) as key_file: public_key = COSEKey.from_pem(key_file.read(), kid="01") encoded = cwt.encode_and_sign( Claims.from_json( { "iss": "coaps://as.example", "sub": "dajiaji", "aud": ["coaps://rs1.example", "coaps://rs2.example"], "cti": "123", } ), private_key, ) decoded = cwt.decode(encoded, public_key) assert 1 in decoded and decoded[1] == "coaps://as.example" assert 3 in decoded and isinstance(decoded[3], list) assert 3 in decoded and decoded[3][0] == "coaps://rs1.example" assert 3 in decoded and decoded[3][1] == "coaps://rs2.example"
def test_claims_constructor_with_invalid_arg(self, invalid, msg): with pytest.raises(ValueError) as err: Claims(invalid) pytest.fail("Claims should fail.") assert msg in str(err.value)
def test_claims_constructor(self): c = Claims({}) assert isinstance(c, Claims)
def test_claims_from_json(self, json, expected): claims = Claims.from_json(json).to_dict() for k, v in claims.items(): assert v == expected[k] assert isinstance(v, type(expected[k])) assert len(claims) == len(expected)
def test_claims_from_json_with_invalid_arg(self, invalid, msg): with pytest.raises(ValueError) as err: Claims.from_json(invalid) pytest.fail("from_json should fail.") assert msg in str(err.value)