1
1
import os
2
- import sys
3
- import inspect
4
2
import urllib .parse
5
- from typing import Optional , Callable , Dict , Tuple , Union
3
+ from typing import Optional
6
4
7
- import multibase
8
- import multicodec
9
- import cryptography .hazmat .primitives .asymmetric .ec
5
+
6
+ DID_JWK_METHOD = "did:jwk:"
10
7
11
8
12
9
def did_web_to_url (
@@ -22,172 +19,3 @@ def did_web_to_url(
22
19
* [urllib .parse .unquote (i ) for i in did_web_string .split (":" )[2 :]],
23
20
]
24
21
)
25
-
26
-
27
- class DIDKeyInvalidPublicKeyLengthError (ValueError ):
28
- """
29
- If the byte length of rawPublicKeyBytes does not match the expected public
30
- key length for the associated multicodecValue, an invalidPublicKeyLength
31
- error MUST be raised.
32
- """
33
-
34
-
35
- class DIDKeyDecoderNotFoundError (NotImplementedError ):
36
- """
37
- Raised when we don't have a function implemented to decode the given key
38
- """
39
-
40
-
41
- class DIDKeyDecoderError (Exception ):
42
- """
43
- Raised when we failed to decode a key from a did:key DID method
44
- """
45
-
46
-
47
- class DIDKeyInvalidPublicKeyError (DIDKeyDecoderError ):
48
- """
49
- Raised when the raw bytes of a key are invalid during decode
50
- """
51
-
52
-
53
- DID_KEY_METHOD = "did:key:"
54
-
55
-
56
- def did_key_decode_public_key (multibase_value : str ) -> Tuple [bytes , bytes ]:
57
- # 3.1.2.3
58
- # Decode multibaseValue using the base58-btc multibase alphabet and set
59
- # multicodecValue to the multicodec header for the decoded value.
60
- multibase_value_decoded = multibase .decode (multibase_value )
61
- # Implementers are cautioned to ensure that the multicodecValue is set to
62
- # the result after performing varint decoding.
63
- multicodec_value = multicodec .extract_prefix (multibase_value_decoded )
64
- # Set the rawPublicKeyBytes to the bytes remaining after the multicodec
65
- # header.
66
- raw_public_key_bytes = multicodec .remove_prefix (multibase_value_decoded )
67
- # Return multicodecValue and rawPublicKeyBytes as the decodedPublicKey.
68
- return multicodec_value , raw_public_key_bytes
69
-
70
-
71
- class _MULTICODEC_VALUE_NOT_FOUND_IN_TABLE :
72
- pass
73
-
74
-
75
- MULTICODEC_VALUE_NOT_FOUND_IN_TABLE = _MULTICODEC_VALUE_NOT_FOUND_IN_TABLE ()
76
-
77
- # Multicodec hexadecimal value, public key, byte length, Description
78
- MULTICODEC_HEX_SECP256K1_PUBLIC_KEY = 0xE7
79
- MULTICODEC_HEX_X25519_PUBLIC_KEY = 0xEC
80
- MULTICODEC_HEX_ED25519_PUBLIC_KEY = 0xED
81
- MULTICODEC_HEX_P256_PUBLIC_KEY = 0x1200
82
- MULTICODEC_HEX_P384_PUBLIC_KEY = 0x1201
83
- MULTICODEC_HEX_P521_PUBLIC_KEY = 0x1202
84
- MULTICODEC_HEX_RSA_PUBLIC_KEY = 0x1205
85
-
86
- MULTICODEC_VALUE_TABLE = {
87
- MULTICODEC_HEX_SECP256K1_PUBLIC_KEY : 33 , # secp256k1-pub - Secp256k1 public key (compressed)
88
- MULTICODEC_HEX_X25519_PUBLIC_KEY : 32 , # x25519-pub - Curve25519 public key
89
- MULTICODEC_HEX_ED25519_PUBLIC_KEY : 32 , # ed25519-pub - Ed25519 public key
90
- MULTICODEC_HEX_P256_PUBLIC_KEY : 33 , # p256-pub - P-256 public key (compressed)
91
- MULTICODEC_HEX_P384_PUBLIC_KEY : 49 , # p384-pub - P-384 public key (compressed)
92
- MULTICODEC_HEX_P521_PUBLIC_KEY : None , # p521-pub - P-521 public key (compressed)
93
- MULTICODEC_HEX_RSA_PUBLIC_KEY : None , # rsa-pub - RSA public key. DER-encoded ASN.1 type RSAPublicKey according to IETF RFC 8017 (PKCS #1)
94
- }
95
-
96
-
97
- def did_key_signature_method_creation (
98
- multibase_value : hex ,
99
- raw_public_key_bytes : bytes ,
100
- ) -> Union [cryptography .hazmat .primitives .asymmetric .ec .EllipticCurvePublicKey ]:
101
- # 3.1.2 https://w3c-ccg.github.io/did-method-key/#signature-method-creation-algorithm
102
- # Initialize verificationMethod to an empty object.
103
- verification_method = {}
104
-
105
- # Set multicodecValue and rawPublicKeyBytes to the result of passing
106
- # multibaseValue and options to § 3.1.3 Decode Public Key Algorithm.
107
- # Ensure the proper key length of rawPublicKeyBytes based on the
108
- # multicodecValue table
109
- public_key_length_MUST_be = MULTICODEC_VALUE_TABLE .get (
110
- multibase_value , MULTICODEC_VALUE_NOT_FOUND_IN_TABLE
111
- )
112
- if public_key_length_MUST_be is MULTICODEC_VALUE_NOT_FOUND_IN_TABLE :
113
- raise DIDKeyDecoderNotFoundError (
114
- f"multibase_value { multibase_value !r} not in MULTICODEC_VALUE_NOT_FOUND_IN_TABLE { MULTICODEC_VALUE_NOT_FOUND_IN_TABLE !r} "
115
- )
116
-
117
- # If the byte length of rawPublicKeyBytes does not match the expected public
118
- # key length for the associated multicodecValue, an invalidPublicKeyLength
119
- # error MUST be raised.
120
- if public_key_length_MUST_be is not None and public_key_length_MUST_be != len (
121
- raw_public_key_bytes
122
- ):
123
- raise DIDKeyInvalidPublicKeyLengthError (
124
- f"public_key_length_MUST_be: { public_key_length_MUST_be } != len(raw_public_key_bytes): { len (raw_public_key_bytes )} "
125
- )
126
-
127
- # Ensure the rawPublicKeyBytes are a proper encoding of the public key type
128
- # as specified by the multicodecValue. This validation is often done by a
129
- # cryptographic library when importing the public key by, for example,
130
- # ensuring that an Elliptic Curve public key is a specific coordinate that
131
- # exists on the elliptic curve. If an invalid public key value is detected,
132
- # an invalidPublicKey error MUST be raised.
133
- #
134
- # SPEC ISSUE: Request for feedback on implementability: It is not clear if
135
- # this particular check is implementable across all public key types. The
136
- # group is accepting feedback on the implementability of this particular
137
- # feature.
138
- try :
139
- if multibase_value in (
140
- MULTICODEC_HEX_P256_PUBLIC_KEY ,
141
- MULTICODEC_HEX_P384_PUBLIC_KEY ,
142
- MULTICODEC_HEX_P521_PUBLIC_KEY ,
143
- ):
144
- public_key = cryptography .hazmat .primitives .asymmetric .ec .EllipticCurvePublicKey .from_encoded_point (
145
- cryptography .hazmat .primitives .asymmetric .ec .SECP384R1 (),
146
- raw_public_key_bytes ,
147
- )
148
- else :
149
- raise DIDKeyDecoderNotFoundError (
150
- f"No importer for multibase_value { multibase_value !r} "
151
- )
152
- except Exception as e :
153
- raise DIDKeyInvalidPublicKeyError (
154
- f"invalid raw_public_key_bytes: { raw_public_key_bytes !r} "
155
- ) from e
156
-
157
- return public_key
158
-
159
-
160
- def did_key_to_cryptography_key (
161
- did_key : str ,
162
- ) -> Union [cryptography .hazmat .primitives .asymmetric .ec .EllipticCurvePublicKey ]:
163
- """
164
- References
165
-
166
- - https://w3c-ccg.github.io/did-method-key/#p-384
167
- - RFC7515: JSON Web Key (JWK): https://www.rfc-editor.org/rfc/rfc7517
168
- - RFC8037: CFRG Elliptic Curve Diffie-Hellman (ECDH) and Signatures in JSON Object Signing and Encryption (JOSE): https://www.rfc-editor.org/rfc/rfc8037
169
-
170
- Examples
171
-
172
- - P-384: https://github.com/w3c-ccg/did-method-key/blob/f5abee840c31e92cd1ac11737e0b62103ab99d21/test-vectors/nist-curves.json#L112-L166
173
-
174
- >>> did_key_to_cryptography_key("did:key:invalid")
175
- Traceback (most recent call last):
176
- DIDKeyDecoderNotFoundError: ...
177
- >>> public_key = did_key_to_cryptography_key("did:key:z82Lm1MpAkeJcix9K8TMiLd5NMAhnwkjjCBeWHXyu3U4oT2MVJJKXkcVBgjGhnLBn2Kaau9")
178
- >>> public_key.__class__
179
- <class 'cryptography.hazmat.backends.openssl.ec._EllipticCurvePublicKey'>
180
- """
181
- try :
182
- multibase_value , raw_public_key_bytes = did_key_decode_public_key (
183
- did_key .replace (DID_KEY_METHOD , "" , 1 )
184
- )
185
- except Exception as e :
186
- raise DIDKeyDecoderNotFoundError (did_key ) from e
187
-
188
- try :
189
- return did_key_signature_method_creation (multibase_value , raw_public_key_bytes )
190
- except Exception as e :
191
- raise DIDKeyDecoderError (did_key ) from e
192
-
193
- raise DIDKeyDecoderNotFoundError (did_key )
0 commit comments