@@ -4,22 +4,22 @@ use std::{cell::OnceCell, sync::Arc};
4
4
5
5
use gcloud_sdk:: {
6
6
google:: cloud:: kms:: {
7
- // self,
7
+ self ,
8
8
v1:: {
9
- key_management_service_client:: KeyManagementServiceClient ,
10
- // AsymmetricSignRequest,
11
- GetPublicKeyRequest ,
12
- PublicKey ,
9
+ key_management_service_client:: KeyManagementServiceClient , AsymmetricSignRequest ,
10
+ GetPublicKeyRequest , PublicKey ,
13
11
} ,
14
12
} ,
15
13
tonic:: {
16
14
self ,
15
+ Request ,
17
16
// Request
18
17
} ,
19
18
GoogleApi , GoogleAuthMiddleware ,
20
19
} ;
21
20
use solana_sdk:: {
22
21
pubkey:: { self , Pubkey } ,
22
+ signature:: Signature ,
23
23
signer:: { Signer , SignerError } ,
24
24
} ;
25
25
use thiserror:: Error ;
@@ -119,15 +119,19 @@ impl Signer for GcpSigner {
119
119
. ok_or ( SignerError :: Custom ( "Cannot get pubkey" . to_string ( ) ) ) ?)
120
120
}
121
121
122
- fn try_sign_message (
122
+ #[ tokio:: main]
123
+ async fn try_sign_message (
123
124
& self ,
124
- _message : & [ u8 ] ,
125
+ message : & [ u8 ] ,
125
126
) -> Result < solana_sdk:: signature:: Signature , SignerError > {
126
- todo ! ( )
127
+ request_sign_digest ( & self . client , & self . key_name , message)
128
+ . await
129
+ . and_then ( decode_signature)
130
+ . map_err ( Into :: into)
127
131
}
128
132
129
133
fn is_interactive ( & self ) -> bool {
130
- todo ! ( )
134
+ false
131
135
}
132
136
}
133
137
@@ -170,6 +174,30 @@ async fn request_get_pubkey(
170
174
. map_err ( Into :: into)
171
175
}
172
176
177
+ #[ instrument( skip( client, digest) , fields( digest = %hex:: encode( digest) ) , err) ]
178
+ async fn request_sign_digest (
179
+ client : & Client ,
180
+ kms_key_name : & str ,
181
+ digest : & [ u8 ] ,
182
+ ) -> Result < Vec < u8 > , GcpSignerError > {
183
+ let mut request = Request :: new ( AsymmetricSignRequest {
184
+ name : kms_key_name. to_string ( ) ,
185
+ digest : Some ( kms:: v1:: Digest {
186
+ digest : Some ( kms:: v1:: digest:: Digest :: Sha256 ( digest. to_vec ( ) ) ) ,
187
+ } ) ,
188
+ ..Default :: default ( )
189
+ } ) ;
190
+
191
+ request. metadata_mut ( ) . insert (
192
+ "x-goog-request-params" ,
193
+ format ! ( "name={}" , kms_key_name) . parse ( ) . unwrap ( ) ,
194
+ ) ;
195
+
196
+ let response = client. get ( ) . asymmetric_sign ( request) . await ?;
197
+ let signature = response. into_inner ( ) . signature ;
198
+ Ok ( signature)
199
+ }
200
+
173
201
#[ instrument( err) ]
174
202
fn from_public_key_pem ( key : PublicKey ) -> Result < Pubkey , GcpSignerError > {
175
203
let pkey = pem:: parse ( key. pem ) ?;
@@ -191,6 +219,12 @@ fn from_public_key_pem(key: PublicKey) -> Result<Pubkey, GcpSignerError> {
191
219
}
192
220
}
193
221
222
+ fn decode_signature ( raw : Vec < u8 > ) -> Result < Signature , GcpSignerError > {
223
+ let mut bytes = [ 0 ; 64 ] ;
224
+ bytes. copy_from_slice ( & raw ) ;
225
+ Ok ( Signature :: from ( bytes) )
226
+ }
227
+
194
228
#[ cfg( test) ]
195
229
mod test {
196
230
use solana_sdk:: signer:: Signer ;
@@ -259,6 +293,9 @@ mod test {
259
293
let mut array = [ 0u8 ; 32 ] ;
260
294
array. copy_from_slice ( & content[ 12 ..] ) ;
261
295
let pubkey = Pubkey :: new_from_array ( array) ;
262
- println ! ( "{:?}" , pubkey) ;
296
+ assert_eq ! (
297
+ pubkey,
298
+ Pubkey :: from_str_const( "2uDMykU9nKeSUg2JLPktsMNYyrUmv7y9EpLHn847H7Zn" )
299
+ ) ;
263
300
}
264
301
}
0 commit comments