@@ -3493,6 +3493,167 @@ async fn range_explicit_encryption_defaults() -> Result<()> {
34933493 Ok ( ( ) )
34943494}
34953495
3496+ // Prose Test 24. KMS Retry Tests
3497+ #[ tokio:: test]
3498+ // using openssl causes errors after configuring a network failpoint
3499+ #[ cfg( not( feature = "openssl-tls" ) ) ]
3500+ async fn kms_retry ( ) {
3501+ use reqwest:: { Certificate , Client as HttpClient } ;
3502+
3503+ let endpoint = "127.0.0.1:9003" ;
3504+
3505+ let mut certificate_file_path = PathBuf :: from ( std:: env:: var ( "CSFLE_TLS_CERT_DIR" ) . unwrap ( ) ) ;
3506+ certificate_file_path. push ( "ca.pem" ) ;
3507+ let certificate_file = std:: fs:: read ( & certificate_file_path) . unwrap ( ) ;
3508+
3509+ let set_failpoint = |kind : & str , count : u8 | {
3510+ // create a fresh client for each request to avoid hangs
3511+ let http_client = HttpClient :: builder ( )
3512+ . add_root_certificate ( Certificate :: from_pem ( & certificate_file) . unwrap ( ) )
3513+ . build ( )
3514+ . unwrap ( ) ;
3515+ let url = format ! ( "https://localhost:9003/set_failpoint/{}" , kind) ;
3516+ let body = format ! ( "{{\" count\" :{}}}" , count) ;
3517+ http_client. post ( url) . body ( body) . send ( )
3518+ } ;
3519+
3520+ let aws_kms = AWS_KMS . clone ( ) ;
3521+ let mut azure_kms = AZURE_KMS . clone ( ) ;
3522+ azure_kms. 1 . insert ( "identityPlatformEndpoint" , endpoint) ;
3523+ let mut gcp_kms = GCP_KMS . clone ( ) ;
3524+ gcp_kms. 1 . insert ( "endpoint" , endpoint) ;
3525+ let mut kms_providers = vec ! [ aws_kms, azure_kms, gcp_kms] ;
3526+
3527+ let tls_options = get_client_options ( ) . await . tls_options ( ) ;
3528+ for kms_provider in kms_providers. iter_mut ( ) {
3529+ kms_provider. 2 = tls_options. clone ( ) ;
3530+ }
3531+
3532+ let key_vault_client = Client :: for_test ( ) . await . into_client ( ) ;
3533+ let client_encryption = ClientEncryption :: new (
3534+ key_vault_client,
3535+ Namespace :: new ( "keyvault" , "datakeys" ) ,
3536+ kms_providers,
3537+ )
3538+ . unwrap ( ) ;
3539+
3540+ let aws_master_key = AwsMasterKey :: builder ( )
3541+ . region ( "foo" )
3542+ . key ( "bar" )
3543+ . endpoint ( endpoint. to_string ( ) )
3544+ . build ( ) ;
3545+ let azure_master_key = AzureMasterKey :: builder ( )
3546+ . key_vault_endpoint ( endpoint)
3547+ . key_name ( "foo" )
3548+ . build ( ) ;
3549+ let gcp_master_key = GcpMasterKey :: builder ( )
3550+ . project_id ( "foo" )
3551+ . location ( "bar" )
3552+ . key_ring ( "baz" )
3553+ . key_name ( "qux" )
3554+ . endpoint ( endpoint. to_string ( ) )
3555+ . build ( ) ;
3556+
3557+ // Case 1: createDataKey and encrypt with TCP retry
3558+
3559+ // AWS
3560+ set_failpoint ( "network" , 1 ) . await . unwrap ( ) ;
3561+ let key_id = client_encryption
3562+ . create_data_key ( aws_master_key. clone ( ) )
3563+ . await
3564+ . unwrap ( ) ;
3565+ set_failpoint ( "network" , 1 ) . await . unwrap ( ) ;
3566+ client_encryption
3567+ . encrypt ( 123 , key_id, Algorithm :: Deterministic )
3568+ . await
3569+ . unwrap ( ) ;
3570+
3571+ // Azure
3572+ set_failpoint ( "network" , 1 ) . await . unwrap ( ) ;
3573+ let key_id = client_encryption
3574+ . create_data_key ( azure_master_key. clone ( ) )
3575+ . await
3576+ . unwrap ( ) ;
3577+ set_failpoint ( "network" , 1 ) . await . unwrap ( ) ;
3578+ client_encryption
3579+ . encrypt ( 123 , key_id, Algorithm :: Deterministic )
3580+ . await
3581+ . unwrap ( ) ;
3582+
3583+ // GCP
3584+ set_failpoint ( "network" , 1 ) . await . unwrap ( ) ;
3585+ let key_id = client_encryption
3586+ . create_data_key ( gcp_master_key. clone ( ) )
3587+ . await
3588+ . unwrap ( ) ;
3589+ set_failpoint ( "network" , 1 ) . await . unwrap ( ) ;
3590+ client_encryption
3591+ . encrypt ( 123 , key_id, Algorithm :: Deterministic )
3592+ . await
3593+ . unwrap ( ) ;
3594+
3595+ // Case 2: createDataKey and encrypt with HTTP retry
3596+
3597+ // AWS
3598+ set_failpoint ( "http" , 1 ) . await . unwrap ( ) ;
3599+ let key_id = client_encryption
3600+ . create_data_key ( aws_master_key. clone ( ) )
3601+ . await
3602+ . unwrap ( ) ;
3603+ set_failpoint ( "http" , 1 ) . await . unwrap ( ) ;
3604+ client_encryption
3605+ . encrypt ( 123 , key_id, Algorithm :: Deterministic )
3606+ . await
3607+ . unwrap ( ) ;
3608+
3609+ // Azure
3610+ set_failpoint ( "http" , 1 ) . await . unwrap ( ) ;
3611+ let key_id = client_encryption
3612+ . create_data_key ( azure_master_key. clone ( ) )
3613+ . await
3614+ . unwrap ( ) ;
3615+ set_failpoint ( "http" , 1 ) . await . unwrap ( ) ;
3616+ client_encryption
3617+ . encrypt ( 123 , key_id, Algorithm :: Deterministic )
3618+ . await
3619+ . unwrap ( ) ;
3620+
3621+ // GCP
3622+ set_failpoint ( "http" , 1 ) . await . unwrap ( ) ;
3623+ let key_id = client_encryption
3624+ . create_data_key ( gcp_master_key. clone ( ) )
3625+ . await
3626+ . unwrap ( ) ;
3627+ set_failpoint ( "http" , 1 ) . await . unwrap ( ) ;
3628+ client_encryption
3629+ . encrypt ( 123 , key_id, Algorithm :: Deterministic )
3630+ . await
3631+ . unwrap ( ) ;
3632+
3633+ // Case 3: createDataKey fails after too many retries
3634+
3635+ // AWS
3636+ set_failpoint ( "network" , 4 ) . await . unwrap ( ) ;
3637+ client_encryption
3638+ . create_data_key ( aws_master_key)
3639+ . await
3640+ . unwrap_err ( ) ;
3641+
3642+ // Azure
3643+ set_failpoint ( "network" , 4 ) . await . unwrap ( ) ;
3644+ client_encryption
3645+ . create_data_key ( azure_master_key)
3646+ . await
3647+ . unwrap_err ( ) ;
3648+
3649+ // GCP
3650+ set_failpoint ( "network" , 4 ) . await . unwrap ( ) ;
3651+ client_encryption
3652+ . create_data_key ( gcp_master_key)
3653+ . await
3654+ . unwrap_err ( ) ;
3655+ }
3656+
34963657// FLE 2.0 Documentation Example
34973658#[ tokio:: test]
34983659async fn fle2_example ( ) -> Result < ( ) > {
0 commit comments