@@ -5791,23 +5791,23 @@ void RGWPutLC::execute(optional_yield y)
57915791 RGWXMLParser parser;
57925792 RGWLifecycleConfiguration_S3 new_config (s->cct );
57935793
5794- content_md5 = s->info .env ->get (" HTTP_CONTENT_MD5" );
5795- if (content_md5 == nullptr ) {
5796- op_ret = -ERR_INVALID_REQUEST;
5797- s->err .message = " Missing required header for this request: Content-MD5" ;
5798- ldpp_dout (this , 5 ) << s->err .message << dendl;
5799- return ;
5800- }
5794+ // amazon says that Content-MD5 is required for this op specifically, but MD5
5795+ // is not a security primitive and FIPS mode makes it difficult to use. if the
5796+ // client provides the header we'll try to verify its checksum, but the header
5797+ // itself is no longer required
5798+ std::optional<std::string> content_md5_bin;
58015799
5802- std::string content_md5_bin;
5803- try {
5804- content_md5_bin = rgw::from_base64 (std::string_view (content_md5));
5805- } catch (...) {
5806- s->err .message = " Request header Content-MD5 contains character "
5807- " that is not base64 encoded." ;
5808- ldpp_dout (this , 5 ) << s->err .message << dendl;
5809- op_ret = -ERR_BAD_DIGEST;
5810- return ;
5800+ content_md5 = s->info .env ->get (" HTTP_CONTENT_MD5" );
5801+ if (content_md5 != nullptr ) {
5802+ try {
5803+ content_md5_bin = rgw::from_base64 (std::string_view (content_md5));
5804+ } catch (...) {
5805+ s->err .message = " Request header Content-MD5 contains character "
5806+ " that is not base64 encoded." ;
5807+ ldpp_dout (this , 5 ) << s->err .message << dendl;
5808+ op_ret = -ERR_BAD_DIGEST;
5809+ return ;
5810+ }
58115811 }
58125812
58135813 if (!parser.init ()) {
@@ -5822,21 +5822,23 @@ void RGWPutLC::execute(optional_yield y)
58225822 char * buf = data.c_str ();
58235823 ldpp_dout (this , 15 ) << " read len=" << data.length () << " data=" << (buf ? buf : " " ) << dendl;
58245824
5825- MD5 data_hash;
5826- // Allow use of MD5 digest in FIPS mode for non-cryptographic purposes
5827- data_hash.SetFlags (EVP_MD_CTX_FLAG_NON_FIPS_ALLOW);
5828- unsigned char data_hash_res[CEPH_CRYPTO_MD5_DIGESTSIZE];
5829- data_hash.Update (reinterpret_cast <const unsigned char *>(buf), data.length ());
5830- data_hash.Final (data_hash_res);
5825+ if (content_md5_bin) {
5826+ MD5 data_hash;
5827+ // Allow use of MD5 digest in FIPS mode for non-cryptographic purposes
5828+ data_hash.SetFlags (EVP_MD_CTX_FLAG_NON_FIPS_ALLOW);
5829+ unsigned char data_hash_res[CEPH_CRYPTO_MD5_DIGESTSIZE];
5830+ data_hash.Update (reinterpret_cast <const unsigned char *>(buf), data.length ());
5831+ data_hash.Final (data_hash_res);
58315832
5832- if (memcmp (data_hash_res, content_md5_bin.c_str (), CEPH_CRYPTO_MD5_DIGESTSIZE) != 0 ) {
5833- op_ret = -ERR_BAD_DIGEST;
5834- s->err .message = " The Content-MD5 you specified did not match what we received." ;
5835- ldpp_dout (this , 5 ) << s->err .message
5836- << " Specified content md5: " << content_md5
5837- << " , calculated content md5: " << data_hash_res
5838- << dendl;
5839- return ;
5833+ if (memcmp (data_hash_res, content_md5_bin->c_str (), CEPH_CRYPTO_MD5_DIGESTSIZE) != 0 ) {
5834+ op_ret = -ERR_BAD_DIGEST;
5835+ s->err .message = " The Content-MD5 you specified did not match what we received." ;
5836+ ldpp_dout (this , 5 ) << s->err .message
5837+ << " Specified content md5: " << content_md5
5838+ << " , calculated content md5: " << data_hash_res
5839+ << dendl;
5840+ return ;
5841+ }
58405842 }
58415843
58425844 if (!parser.parse (buf, data.length (), 1 )) {
0 commit comments