def test_sample_readme_nested_cwt(self): with open(key_path("private_key_es256.pem")) as key_file: private_key = COSEKey.from_pem(key_file.read(), kid="01") token = cwt.encode({"iss": "coaps://as.example", "sub": "dajiaji", "cti": "123"}, private_key) enc_key = COSEKey.from_symmetric_key(alg="ChaCha20/Poly1305", kid="02") nested = cwt.encode(token, enc_key) 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_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_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_rfc8392_a4(self): key = COSEKey.new( { -1: bytes.fromhex("403697de87af64611c1d32a05dab0fe1fcb715a86ab435f1ec99192d79569388"), 1: 4, # Symmetric 2: bytes.fromhex("53796d6d6574726963323536"), 3: 4, # HMAC256/64 } ) token = cwt.encode( { 1: "coap://as.example.com", 2: "erikw", 3: "coap://light.example.com", 4: 1444064944, 5: 1443944944, 6: 1443944944, 7: bytes.fromhex("0b71"), }, key, tagged=True, ) assert token == bytes.fromhex(SAMPLE_CWT_RFC8392_A4) decoded = cwt.decode(token, keys=key, no_verify=True) assert 1 in decoded and decoded[1] == "coap://as.example.com"
def test_sample_readme_signed_cwt_ed25519_with_jwk(self): # The sender side: private_key = COSEKey.from_jwk( { "kid": "01", "kty": "OKP", "key_ops": ["sign"], "alg": "EdDSA", "crv": "Ed25519", "x": "2E6dX83gqD_D0eAmqnaHe1TC1xuld6iAKXfw2OVATr0", "d": "L8JS08VsFZoZxGa9JvzYmCWOwg7zaKcei3KZmYsj7dc", } ) token = cwt.encode({"iss": "coaps://as.example", "sub": "dajiaji", "cti": "123"}, private_key) # The recipient side: public_key = COSEKey.from_jwk( { "kid": "01", "kty": "OKP", "key_ops": ["verify"], "crv": "Ed25519", "x": "2E6dX83gqD_D0eAmqnaHe1TC1xuld6iAKXfw2OVATr0", } ) decoded = cwt.decode(token, public_key) assert 1 in decoded and decoded[1] == "coaps://as.example"
def test_cose_decode_mac0_without_key_and_materials(self, ctx): key = COSEKey.from_symmetric_key(alg="HS256") encoded = cwt.encode({"iss": "coap://as.example"}, key) with pytest.raises(ValueError) as err: ctx.decode(encoded, b"") pytest.fail("decode should fail.") assert "key in keys should have COSEKeyInterface." in str(err.value)
def test_sample_readme_cwt_with_pop_cose_key(self): with open(key_path("private_key_ed25519.pem")) as key_file: private_key = COSEKey.from_pem(key_file.read(), kid="issuer-01") with open(key_path("public_key_es256.pem")) as key_file: pop_key = COSEKey.from_pem(key_file.read()) token = cwt.encode( { 1: "coaps://as.example", # iss 2: "dajiaji", # sub 7: b"123", # cti 8: { # cnf 1: pop_key.to_dict(), }, }, 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 1 in decoded[8] and isinstance(decoded[8][1], dict) extracted = COSEKey.new(decoded[8][1]) assert extracted.kty == 2 # EC2 assert extracted.crv == 1 # P-256
def test_sample_readme_cwt_with_pop_encrypted_cose_key(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( { 1: "coaps://as.example", # iss 2: "dajiaji", # sub 7: b"123", # cti 8: { # cnf 2: 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) extracted = EncryptedCOSEKey.to_cose_key(decoded[8][2], 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_readme_signed_cwt_ps256(self): with open(key_path("private_key_rsa.pem")) as key_file: private_key = COSEKey.from_pem(key_file.read(), alg="PS256", kid="01") token = cwt.encode({"iss": "coaps://as.example", "sub": "dajiaji", "cti": "123"}, private_key) with open(key_path("public_key_rsa.pem")) as key_file: public_key = COSEKey.from_pem(key_file.read(), alg="PS256", kid="01") decoded = cwt.decode(token, public_key) assert 1 in decoded and decoded[1] == "coaps://as.example"
def test_sample_rfc8392_a6_with_encoding(self): sig_key = COSEKey.from_bytes(bytes.fromhex(SAMPLE_COSE_KEY_RFC8392_A2_3)) signed = cwt.encode( { 1: "coap://as.example.com", 2: "erikw", 3: "coap://light.example.com", 4: 1444064944, 5: 1443944944, 6: 1443944944, 7: bytes.fromhex("0b71"), }, key=sig_key, ) enc_key = COSEKey.from_bytes(bytes.fromhex(SAMPLE_COSE_KEY_RFC8392_A2_1)) nonce = bytes.fromhex("4a0694c0e69ee6b5956655c7b2") encrypted = cwt.encode(signed, key=enc_key, nonce=nonce) decoded = cwt.decode(encrypted, keys=[enc_key, sig_key], no_verify=True) assert 1 in decoded and decoded[1] == "coap://as.example.com"
def test_sample_readme_signed_cwt_es256_with_cert_without_intermediates(self): with open(key_path("private_key_cert_es256.pem")) as f: private_key = COSEKey.from_pem(f.read(), kid="P-256-01") with open(key_path("cert_es256_2.json")) as f: public_key = COSEKey.from_jwk(f.read()) token = cwt.encode({"iss": "coaps://as.example", "sub": "dajiaji", "cti": "123"}, private_key) decoder = CWT.new(ca_certs=key_path("cacert.pem")) decoded = decoder.decode(token, public_key) assert 1 in decoded and decoded[1] == "coaps://as.example"
def test_cose_decode_signature1_with_key_not_found(self, ctx): with open(key_path("public_key_es256.pem")) as key_file: key1 = COSEKey.from_pem(key_file.read(), kid="01") with open(key_path("public_key_ed25519.pem")) as key_file: key2 = COSEKey.from_pem(key_file.read(), kid="02") with open(key_path("private_key_ed25519.pem")) as key_file: private_key = COSEKey.from_pem(key_file.read(), kid="03") encoded = cwt.encode({"iss": "coap://as.example"}, private_key) with pytest.raises(ValueError) as err: ctx.decode(encoded, [key1, key2]) pytest.fail("decode should fail.") assert "key is not found." in str(err.value)
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_signed_cwt_es256_with_another_ca_cert(self): with open(key_path("private_key_cert_es256.pem")) as f: private_key = COSEKey.from_pem(f.read(), kid="P-256-01") with open(key_path("cert_es256.json")) as f: public_key = COSEKey.from_jwk(f.read()) token = cwt.encode({"iss": "coaps://as.example", "sub": "dajiaji", "cti": "123"}, private_key) decoder = CWT.new(ca_certs=key_path("cacert_2.pem")) with pytest.raises(VerifyError) as err: decoder.decode(token, public_key) pytest.fail("decode() should fail.") assert "Failed to validate the certificate bound to the key." in str(err.value)
def test_key_builder_from_jwk_with_encode(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( { "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_rfc8392_a3_with_encoding(self): key = COSEKey.from_bytes(bytes.fromhex(SAMPLE_COSE_KEY_RFC8392_A2_3)) token = cwt.encode( { 1: "coap://as.example.com", 2: "erikw", 3: "coap://light.example.com", 4: 1444064944, 5: 1443944944, 6: 1443944944, 7: bytes.fromhex("0b71"), }, key, ) decoded = cwt.decode(token, keys=key, no_verify=True) assert 1 in decoded and decoded[1] == "coap://as.example.com"
def test_sample_readme_decode_with_multiple_keys(self): with open(key_path("private_key_ed25519.pem")) as key_file: private_key = COSEKey.from_pem(key_file.read(), kid="02") token = cwt.encode( { "iss": "coaps://as.example", "sub": "dajiaji", "cti": b"123", }, private_key, ) with open(key_path("public_key_es256.pem")) as key_file: public_key_1 = COSEKey.from_pem(key_file.read(), kid="01") with open(key_path("public_key_ed25519.pem")) as key_file: public_key_2 = COSEKey.from_pem(key_file.read(), kid="02") decoded = cwt.decode(token, [public_key_1, public_key_2]) assert 1 in decoded and decoded[1] == "coaps://as.example"
def test_sample_rfc8392_a5(self): key = COSEKey.from_bytes(bytes.fromhex(SAMPLE_COSE_KEY_RFC8392_A2_1)) nonce = bytes.fromhex("99a0d7846e762c49ffe8a63e0b") token = cwt.encode( { 1: "coap://as.example.com", 2: "erikw", 3: "coap://light.example.com", 4: 1444064944, 5: 1443944944, 6: 1443944944, 7: bytes.fromhex("0b71"), }, key=key, nonce=nonce, ) assert token == bytes.fromhex(SAMPLE_CWT_RFC8392_A5) decoded = cwt.decode(token, keys=key, no_verify=True) assert 1 in decoded and decoded[1] == "coap://as.example.com"
def test_sample_readme_cwt_with_pop_kid(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 8: { # cnf 3: b"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="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"
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_es256_with_cert(self): # with open(key_path("cacert.pem")) as f: # k1 = x509.load_pem_x509_certificate(f.read().encode("utf-8")) # with open(key_path("cert_es256.pem")) as f: # k2 = x509.load_pem_x509_certificate(f.read().encode("utf-8")) # x5c = [ # base64url_encode(k1.public_bytes(serialization.Encoding.DER)).decode("utf-8"), # base64url_encode(k2.public_bytes(serialization.Encoding.DER)).decode("utf-8"), # ] with open(key_path("private_key_cert_es256.pem")) as f: private_key = COSEKey.from_pem(f.read(), kid="P-256-01") with open(key_path("cert_es256.json")) as f: public_key = COSEKey.from_jwk(f.read()) token = cwt.encode({"iss": "coaps://as.example", "sub": "dajiaji", "cti": "123"}, private_key) decoder = CWT.new(ca_certs=key_path("cacert.pem")) decoded = decoder.decode(token, public_key) assert 1 in decoded and decoded[1] == "coaps://as.example"
def test_sample_readme_maced_cwt(self): key = COSEKey.from_symmetric_key(alg="HMAC 256/256", kid="01") token = cwt.encode({1: "coaps://as.example", 2: "dajiaji", 7: b"123"}, key) decoded = cwt.decode(token, key) assert 1 in decoded and decoded[1] == "coaps://as.example"
def test_sample_readme_maced_cwt_with_json_dict(self): key = COSEKey.from_symmetric_key(alg="HMAC 256/256", kid="01") token = cwt.encode({"iss": "coaps://as.example", "sub": "dajiaji", "cti": "123"}, key) decoded = cwt.decode(token, key) assert 1 in decoded and decoded[1] == "coaps://as.example"
def test_sample_readme_encrypted_cwt(self): enc_key = COSEKey.from_symmetric_key(alg="ChaCha20/Poly1305", kid="01") token = cwt.encode({"iss": "coaps://as.example", "sub": "dajiaji", "cti": "123"}, enc_key) decoded = cwt.decode(token, enc_key) assert 1 in decoded and decoded[1] == "coaps://as.example"