1
1
use alloy_primitives:: eip191_hash_message;
2
2
use anyhow:: { Result , anyhow, bail} ;
3
+ use ed25519:: PublicKeyBytes as Ed25519PublicKeyBytes ;
3
4
use ed25519_consensus:: VerificationKey as Ed25519VerifyingKey ;
5
+ use k256:: ecdsa:: VerifyingKey as Secp256k1VerifyingKey ;
4
6
use p256:: {
5
7
ecdsa:: {
6
8
VerifyingKey as Secp256r1VerifyingKey ,
7
9
signature:: { DigestVerifier , hazmat:: PrehashVerifier } ,
8
10
} ,
9
- pkcs8:: { DecodePublicKey , EncodePublicKey } ,
11
+ pkcs8:: EncodePublicKey ,
12
+ } ;
13
+ use pkcs8:: {
14
+ Document , LineEnding , SubjectPublicKeyInfoRef ,
15
+ der:: { Decode , pem:: PemLabel } ,
10
16
} ;
11
-
12
- use k256:: ecdsa:: VerifyingKey as Secp256k1VerifyingKey ;
13
-
14
17
use serde:: { Deserialize , Serialize } ;
15
18
use sha2:: Digest as _;
16
19
use std:: {
17
20
self ,
18
21
borrow:: Cow ,
19
22
hash:: { Hash , Hasher } ,
23
+ path:: Path ,
20
24
} ;
21
25
use utoipa:: {
22
26
PartialSchema , ToSchema ,
@@ -84,19 +88,6 @@ impl VerifyingKey {
84
88
}
85
89
}
86
90
87
- pub fn to_der ( & self ) -> Result < Vec < u8 > > {
88
- let der = match self {
89
- VerifyingKey :: Ed25519 ( _) => bail ! ( "Ed25519 vk to DER format is not implemented" ) ,
90
- VerifyingKey :: Secp256k1 ( vk) => vk. to_public_key_der ( ) ?. into_vec ( ) ,
91
- VerifyingKey :: Secp256r1 ( vk) => vk. to_public_key_der ( ) ?. into_vec ( ) ,
92
- VerifyingKey :: Eip191 ( _) => bail ! ( "EIP-191 vk to DER format is not implemented" ) ,
93
- VerifyingKey :: CosmosAdr36 ( _) => {
94
- bail ! ( "Cosmos ADR-36 vk to DER format is not implemented" )
95
- }
96
- } ;
97
- Ok ( der)
98
- }
99
-
100
91
pub fn from_algorithm_and_bytes ( algorithm : CryptoAlgorithm , bytes : & [ u8 ] ) -> Result < Self > {
101
92
match algorithm {
102
93
CryptoAlgorithm :: Ed25519 => Ed25519VerifyingKey :: try_from ( bytes)
@@ -117,22 +108,6 @@ impl VerifyingKey {
117
108
}
118
109
}
119
110
120
- pub fn from_algorithm_and_der ( algorithm : CryptoAlgorithm , bytes : & [ u8 ] ) -> Result < Self > {
121
- match algorithm {
122
- CryptoAlgorithm :: Ed25519 => bail ! ( "Ed25519 vk from DER format is not implemented" ) ,
123
- CryptoAlgorithm :: Secp256k1 => Secp256k1VerifyingKey :: from_public_key_der ( bytes)
124
- . map ( VerifyingKey :: Secp256k1 )
125
- . map_err ( |e| e. into ( ) ) ,
126
- CryptoAlgorithm :: Secp256r1 => Secp256r1VerifyingKey :: from_public_key_der ( bytes)
127
- . map ( VerifyingKey :: Secp256r1 )
128
- . map_err ( |e| e. into ( ) ) ,
129
- CryptoAlgorithm :: Eip191 => bail ! ( "Eth vk from DER format is not implemented" ) ,
130
- CryptoAlgorithm :: CosmosAdr36 => {
131
- bail ! ( "Cosmos ADR-36 vk from DER format is not implemented" )
132
- }
133
- }
134
- }
135
-
136
111
pub fn algorithm ( & self ) -> CryptoAlgorithm {
137
112
match self {
138
113
VerifyingKey :: Ed25519 ( _) => CryptoAlgorithm :: Ed25519 ,
@@ -191,6 +166,65 @@ impl VerifyingKey {
191
166
}
192
167
}
193
168
}
169
+
170
+ fn to_spki_der_doc ( & self ) -> Result < Document > {
171
+ match self {
172
+ VerifyingKey :: Ed25519 ( vk) => Ed25519PublicKeyBytes ( vk. to_bytes ( ) ) . to_public_key_der ( ) ,
173
+ VerifyingKey :: Secp256k1 ( vk) => vk. to_public_key_der ( ) ,
174
+ VerifyingKey :: Secp256r1 ( vk) => vk. to_public_key_der ( ) ,
175
+ VerifyingKey :: Eip191 ( _) => bail ! ( "EIP-191 vk to DER format is not implemented" ) ,
176
+ VerifyingKey :: CosmosAdr36 ( _) => {
177
+ bail ! ( "Cosmos ADR-36 vk to DER format is not implemented" )
178
+ }
179
+ }
180
+ . map_err ( |_| anyhow ! ( "Creating SPKI DER failed" ) )
181
+ }
182
+
183
+ pub fn to_spki_der ( & self ) -> Result < Vec < u8 > > {
184
+ Ok ( self . to_spki_der_doc ( ) ?. as_bytes ( ) . to_vec ( ) )
185
+ }
186
+
187
+ pub fn to_spki_pem_file ( & self , filename : impl AsRef < Path > ) -> Result < ( ) > {
188
+ self . to_spki_der_doc ( ) ?
189
+ . write_pem_file ( filename, SubjectPublicKeyInfoRef :: PEM_LABEL , LineEnding :: LF )
190
+ . map_err ( |_| anyhow ! ( "Creating PKCS8 PEM file failed" ) )
191
+ }
192
+
193
+ fn from_spki ( spki : SubjectPublicKeyInfoRef ) -> Result < Self > {
194
+ let algorithm = CryptoAlgorithm :: try_from ( spki. algorithm ) ?;
195
+
196
+ match algorithm {
197
+ CryptoAlgorithm :: Ed25519 => {
198
+ let ed25519_spki = Ed25519PublicKeyBytes :: try_from ( spki) ?;
199
+ let ed25519_key = Ed25519VerifyingKey :: try_from ( ed25519_spki. as_ref ( ) as & [ u8 ] ) ?;
200
+ Ok ( VerifyingKey :: Ed25519 ( ed25519_key) )
201
+ }
202
+ CryptoAlgorithm :: Secp256k1 => {
203
+ let secp256k1_key = Secp256k1VerifyingKey :: try_from ( spki) ?;
204
+ Ok ( VerifyingKey :: Secp256k1 ( secp256k1_key) )
205
+ }
206
+ CryptoAlgorithm :: Secp256r1 => {
207
+ let secp256r1_key = Secp256r1VerifyingKey :: try_from ( spki) ?;
208
+ Ok ( VerifyingKey :: Secp256r1 ( secp256r1_key) )
209
+ }
210
+ CryptoAlgorithm :: Eip191 => bail ! ( "Eth vk from DER format is not implemented" ) ,
211
+ CryptoAlgorithm :: CosmosAdr36 => {
212
+ bail ! ( "Cosmos ADR-36 vk from DER format is not implemented" )
213
+ }
214
+ }
215
+ }
216
+
217
+ pub fn from_spki_der ( bytes : & [ u8 ] ) -> Result < Self > {
218
+ let spki = SubjectPublicKeyInfoRef :: from_der ( bytes) ?;
219
+ Self :: from_spki ( spki)
220
+ }
221
+
222
+ pub fn from_spki_pem_file ( filename : impl AsRef < Path > ) -> Result < Self > {
223
+ let ( label, doc) = Document :: read_pem_file ( filename) ?;
224
+ SubjectPublicKeyInfoRef :: validate_pem_label ( & label)
225
+ . map_err ( |_| anyhow ! ( "Incorrect PEM label" ) ) ?;
226
+ Self :: from_spki_der ( doc. as_bytes ( ) )
227
+ }
194
228
}
195
229
196
230
impl TryFrom < CryptoPayload > for VerifyingKey {
0 commit comments