@@ -13,11 +13,14 @@ use dstack_guest_agent_rpc::{
1313 worker_server:: { WorkerRpc , WorkerServer } ,
1414 AppInfo , DeriveK256KeyResponse , DeriveKeyArgs , EmitEventArgs , GetAttestationForAppKeyRequest ,
1515 GetKeyArgs , GetKeyResponse , GetQuoteResponse , GetTlsKeyArgs , GetTlsKeyResponse , RawQuoteArgs ,
16- SignRequest , SignResponse , TdxQuoteArgs , TdxQuoteResponse , WorkerVersion ,
16+ SignRequest , SignResponse , TdxQuoteArgs , TdxQuoteResponse , VerifyRequest , VerifyResponse ,
17+ WorkerVersion ,
1718} ;
1819use dstack_types:: { AppKeys , SysConfig } ;
1920use ed25519_dalek:: ed25519:: signature:: hazmat:: PrehashSigner ;
20- use ed25519_dalek:: { Signer as Ed25519Signer , SigningKey as Ed25519SigningKey } ;
21+ use ed25519_dalek:: {
22+ Signer as Ed25519Signer , SigningKey as Ed25519SigningKey , Verifier as Ed25519Verifier ,
23+ } ;
2124use fs_err as fs;
2225use k256:: ecdsa:: SigningKey ;
2326use ra_rpc:: { Attestation , CallContext , RpcCall } ;
@@ -305,6 +308,56 @@ impl DstackGuestRpc for InternalRpcHandler {
305308 } ;
306309 Ok ( SignResponse { signature } )
307310 }
311+
312+ async fn verify ( self , request : VerifyRequest ) -> Result < VerifyResponse > {
313+ let valid = match request. algorithm . as_str ( ) {
314+ "ed25519" => {
315+ let public_key = if request. public_key . is_empty ( ) {
316+ let key_response = self
317+ . get_key ( GetKeyArgs {
318+ path : "vms" . to_string ( ) ,
319+ purpose : "signing" . to_string ( ) ,
320+ algorithm : "ed25519" . to_string ( ) ,
321+ } )
322+ . await ?;
323+ let key_bytes: [ u8 ; 32 ] =
324+ key_response. key . try_into ( ) . expect ( "Key is incorrect" ) ;
325+ Ed25519SigningKey :: from_bytes ( & key_bytes)
326+ . verifying_key ( )
327+ . to_bytes ( )
328+ . to_vec ( )
329+ } else {
330+ request. public_key
331+ } ;
332+ let verifying_key = ed25519_dalek:: VerifyingKey :: from_bytes (
333+ & public_key. as_slice ( ) . try_into ( ) . unwrap ( ) ,
334+ ) ?;
335+ let signature = ed25519_dalek:: Signature :: from_slice ( & request. signature ) ?;
336+ verifying_key. verify ( & request. data , & signature) . is_ok ( )
337+ }
338+ "secp256k1" | "secp256k1_prehashed" => {
339+ let public_key = if request. public_key . is_empty ( ) {
340+ let key_response = self
341+ . get_key ( GetKeyArgs {
342+ path : "vms" . to_string ( ) ,
343+ purpose : "signing" . to_string ( ) ,
344+ algorithm : request. algorithm ,
345+ } )
346+ . await ?;
347+ let signing_key = SigningKey :: from_slice ( & key_response. key )
348+ . context ( "Failed to parse secp256k1 key" ) ?;
349+ signing_key. verifying_key ( ) . to_sec1_bytes ( ) . to_vec ( )
350+ } else {
351+ request. public_key
352+ } ;
353+ let verifying_key = k256:: ecdsa:: VerifyingKey :: from_sec1_bytes ( & public_key) ?;
354+ let signature = k256:: ecdsa:: Signature :: from_slice ( & request. signature ) ?;
355+ verifying_key. verify ( & request. data , & signature) . is_ok ( )
356+ }
357+ _ => return Err ( anyhow:: anyhow!( "Unsupported algorithm" ) ) ,
358+ } ;
359+ Ok ( VerifyResponse { valid } )
360+ }
308361}
309362
310363fn simulate_quote (
@@ -746,6 +799,60 @@ pNs85uhOZE8z2jr8Pg==
746799 }
747800 }
748801
802+ #[ tokio:: test]
803+ async fn test_verify_ed25519_success ( ) {
804+ let state = setup_test_state ( ) . await ;
805+ let handler = InternalRpcHandler {
806+ state : state. clone ( ) ,
807+ } ;
808+ let data_to_sign = b"test message for ed25519" ;
809+ let sign_request = SignRequest {
810+ algorithm : "ed25519" . to_string ( ) ,
811+ data : data_to_sign. to_vec ( ) ,
812+ } ;
813+
814+ let sign_response = handler. sign ( sign_request) . await . unwrap ( ) ;
815+
816+ let verify_request = VerifyRequest {
817+ algorithm : "ed25519" . to_string ( ) ,
818+ data : data_to_sign. to_vec ( ) ,
819+ signature : sign_response. signature ,
820+ public_key : vec ! [ ] ,
821+ } ;
822+ let handler = InternalRpcHandler {
823+ state : state. clone ( ) ,
824+ } ;
825+ let verify_response = handler. verify ( verify_request) . await . unwrap ( ) ;
826+ assert ! ( verify_response. valid) ;
827+ }
828+
829+ #[ tokio:: test]
830+ async fn test_verify_secp256k1_success ( ) {
831+ let state = setup_test_state ( ) . await ;
832+ let handler = InternalRpcHandler {
833+ state : state. clone ( ) ,
834+ } ;
835+ let data_to_sign = b"test message for secp256k1" ;
836+ let sign_request = SignRequest {
837+ algorithm : "secp256k1" . to_string ( ) ,
838+ data : data_to_sign. to_vec ( ) ,
839+ } ;
840+
841+ let sign_response = handler. sign ( sign_request) . await . unwrap ( ) ;
842+
843+ let verify_request = VerifyRequest {
844+ algorithm : "secp256k1" . to_string ( ) ,
845+ data : data_to_sign. to_vec ( ) ,
846+ signature : sign_response. signature ,
847+ public_key : vec ! [ ] ,
848+ } ;
849+ let handler = InternalRpcHandler {
850+ state : state. clone ( ) ,
851+ } ;
852+ let verify_response = handler. verify ( verify_request) . await . unwrap ( ) ;
853+ assert ! ( verify_response. valid) ;
854+ }
855+
749856 #[ tokio:: test]
750857 async fn test_sign_ed25519_success ( ) {
751858 let state = setup_test_state ( ) . await ;
0 commit comments