2020#include "mongocrypt-key-private.h"
2121#include "mongocrypt-kms-ctx-private.h"
2222#include "mongocrypt-private.h"
23+ #include "test-mongocrypt-assert.h"
2324#include "test-mongocrypt-util.h"
2425#include "test-mongocrypt.h"
2526
@@ -885,6 +886,100 @@ static void _test_mongocrypt_kms_ctx_feed_empty_bytes(_mongocrypt_tester_t *test
885886 mongocrypt_status_destroy (status );
886887}
887888
889+ // _test_mongocrypt_kms_ctx_kmip_response_bad_length tests KMIP responses that report bad lengths.
890+ static void _test_mongocrypt_kms_ctx_kmip_response_bad_length (_mongocrypt_tester_t * tester ) {
891+ mongocrypt_t * crypt = _mongocrypt_tester_mongocrypt (TESTER_MONGOCRYPT_DEFAULT );
892+ bool ok ;
893+ uint8_t secretdata [KMS_KMIP_REQUEST_SECRETDATA_LENGTH ] = {0 };
894+ mongocrypt_status_t * status = mongocrypt_status_new ();
895+ _mongocrypt_endpoint_t * endpoint = _mongocrypt_endpoint_new ("example.com" , -1 , NULL /* opts */ , status );
896+ ASSERT_OK_STATUS (endpoint != NULL , status );
897+
898+ // Regression test for MONGOCRYPT-909: test UINT32_MAX
899+ {
900+ mongocrypt_kms_ctx_t kms_ctx = {0 };
901+ static const char * kmip_header = "\x42\x00\x7b\x01" // Tag=ResponseMessage, Type=Structure
902+ "\xff\xff\xff\xff" ; // Length = UINT32_MAX
903+
904+ ok = _mongocrypt_kms_ctx_init_kmip_register (& kms_ctx ,
905+ endpoint ,
906+ secretdata ,
907+ KMS_KMIP_REQUEST_SECRETDATA_LENGTH ,
908+ "kmip" ,
909+ & crypt -> log );
910+ ASSERT_OK_STATUS (ok , kms_ctx .status );
911+
912+ // Parser requests 8 bytes for initial header:
913+ ASSERT_CMPINT (mongocrypt_kms_ctx_bytes_needed (& kms_ctx ), = = , 8u );
914+
915+ mongocrypt_binary_t * bytes = mongocrypt_binary_new_from_data ((uint8_t * )kmip_header , 8u );
916+
917+ // Expect error (not abort):
918+ ASSERT_FAILS (mongocrypt_kms_ctx_feed (& kms_ctx , bytes ), & kms_ctx , "KMS KMIP response too large" );
919+
920+ mongocrypt_binary_destroy (bytes );
921+ _mongocrypt_kms_ctx_cleanup (& kms_ctx );
922+ }
923+
924+ // Length reported is less than data fed.
925+ {
926+ mongocrypt_kms_ctx_t kms_ctx = {0 };
927+ static const char * kmip_header = "\x42\x00\x7b\x01" // Tag=ResponseMessage, Type=Structure
928+ "\x00\x00\x00\x01" ; // Length = 1
929+ ASSERT_OK_STATUS (endpoint != NULL , status );
930+
931+ ok = _mongocrypt_kms_ctx_init_kmip_register (& kms_ctx ,
932+ endpoint ,
933+ secretdata ,
934+ KMS_KMIP_REQUEST_SECRETDATA_LENGTH ,
935+ "kmip" ,
936+ & crypt -> log );
937+ ASSERT_OK_STATUS (ok , kms_ctx .status );
938+
939+ // Parser requests 8 bytes for initial header:
940+ ASSERT_CMPINT (mongocrypt_kms_ctx_bytes_needed (& kms_ctx ), = = , 8u );
941+
942+ mongocrypt_binary_t * bytes = mongocrypt_binary_new_from_data ((uint8_t * )kmip_header , 8u );
943+ ASSERT_OK (mongocrypt_kms_ctx_feed (& kms_ctx , bytes ), & kms_ctx );
944+
945+ ASSERT_CMPINT (mongocrypt_kms_ctx_bytes_needed (& kms_ctx ), = = , 1u );
946+ // Attempting to feed more data errors.
947+ ASSERT_FAILS (mongocrypt_kms_ctx_feed (& kms_ctx , bytes ), & kms_ctx , "KMS response fed too much data" );
948+
949+ mongocrypt_binary_destroy (bytes );
950+ _mongocrypt_kms_ctx_cleanup (& kms_ctx );
951+ }
952+
953+ // Length reported is zero.
954+ {
955+ mongocrypt_kms_ctx_t kms_ctx = {0 };
956+ static const char * kmip_header = "\x42\x00\x7b\x01" // Tag=ResponseMessage, Type=Structure
957+ "\x00\x00\x00\x00" ; // Length = 0
958+ ASSERT_OK_STATUS (endpoint != NULL , status );
959+
960+ ok = _mongocrypt_kms_ctx_init_kmip_register (& kms_ctx ,
961+ endpoint ,
962+ secretdata ,
963+ KMS_KMIP_REQUEST_SECRETDATA_LENGTH ,
964+ "kmip" ,
965+ & crypt -> log );
966+ ASSERT_OK_STATUS (ok , kms_ctx .status );
967+
968+ // Parser requests 8 bytes for initial header:
969+ ASSERT_CMPINT (mongocrypt_kms_ctx_bytes_needed (& kms_ctx ), = = , 8u );
970+
971+ mongocrypt_binary_t * bytes = mongocrypt_binary_new_from_data ((uint8_t * )kmip_header , 8u );
972+ ASSERT_FAILS (mongocrypt_kms_ctx_feed (& kms_ctx , bytes ), & kms_ctx , "Error getting UniqueIdentifer" );
973+
974+ mongocrypt_binary_destroy (bytes );
975+ _mongocrypt_kms_ctx_cleanup (& kms_ctx );
976+ }
977+
978+ _mongocrypt_endpoint_destroy (endpoint );
979+ mongocrypt_status_destroy (status );
980+ mongocrypt_destroy (crypt );
981+ }
982+
888983void _mongocrypt_tester_install_kms_ctx (_mongocrypt_tester_t * tester ) {
889984 INSTALL_TEST (_test_mongocrypt_kms_ctx_kmip_register );
890985 INSTALL_TEST (_test_mongocrypt_kms_ctx_kmip_activate );
@@ -895,4 +990,5 @@ void _mongocrypt_tester_install_kms_ctx(_mongocrypt_tester_t *tester) {
895990 INSTALL_TEST (_test_mongocrypt_kms_ctx_get_kms_provider );
896991 INSTALL_TEST (_test_mongocrypt_kms_ctx_default_port );
897992 INSTALL_TEST (_test_mongocrypt_kms_ctx_feed_empty_bytes );
993+ INSTALL_TEST (_test_mongocrypt_kms_ctx_kmip_response_bad_length );
898994}
0 commit comments