def test_headers_to_sign_sigv4(self): environ = { 'REQUEST_METHOD': 'GET'} # host and x-amz-date x_amz_date = self.get_v4_amz_date_header() headers = { 'Authorization': 'AWS4-HMAC-SHA256 ' 'Credential=test/%s/US/s3/aws4_request, ' 'SignedHeaders=host;x-amz-content-sha256;x-amz-date,' 'Signature=X' % self.get_v4_amz_date_header().split('T', 1)[0], 'X-Amz-Content-SHA256': '0123456789', 'Date': self.get_date_header(), 'X-Amz-Date': x_amz_date} req = Request.blank('/', environ=environ, headers=headers) sigv4_req = SigV4Request(req.environ) headers_to_sign = sigv4_req._headers_to_sign() self.assertEqual(headers_to_sign, [ ('host', 'localhost:80'), ('x-amz-content-sha256', '0123456789'), ('x-amz-date', x_amz_date)]) # no x-amz-date headers = { 'Authorization': 'AWS4-HMAC-SHA256 ' 'Credential=test/%s/US/s3/aws4_request, ' 'SignedHeaders=host;x-amz-content-sha256,' 'Signature=X' % self.get_v4_amz_date_header().split('T', 1)[0], 'X-Amz-Content-SHA256': '0123456789', 'Date': self.get_date_header()} req = Request.blank('/', environ=environ, headers=headers) sigv4_req = SigV4Request(req.environ) headers_to_sign = sigv4_req._headers_to_sign() self.assertEqual(headers_to_sign, [ ('host', 'localhost:80'), ('x-amz-content-sha256', '0123456789')]) # SignedHeaders says, host and x-amz-date included but there is not # X-Amz-Date header headers = { 'Authorization': 'AWS4-HMAC-SHA256 ' 'Credential=test/%s/US/s3/aws4_request, ' 'SignedHeaders=host;x-amz-content-sha256;x-amz-date,' 'Signature=X' % self.get_v4_amz_date_header().split('T', 1)[0], 'X-Amz-Content-SHA256': '0123456789', 'Date': self.get_date_header()} req = Request.blank('/', environ=environ, headers=headers) with self.assertRaises(SignatureDoesNotMatch): sigv4_req = SigV4Request(req.environ) sigv4_req._headers_to_sign()
def test_canonical_uri_sigv4(self): environ = { 'HTTP_HOST': 'bucket.s3.test.com', 'REQUEST_METHOD': 'GET'} # host and x-amz-date x_amz_date = self.get_v4_amz_date_header() headers = { 'Authorization': 'AWS4-HMAC-SHA256 ' 'Credential=test/%s/US/s3/aws4_request, ' 'SignedHeaders=host;x-amz-content-sha256;x-amz-date,' 'Signature=X' % self.get_v4_amz_date_header().split('T', 1)[0], 'X-Amz-Content-SHA256': '0123456789', 'Date': self.get_date_header(), 'X-Amz-Date': x_amz_date} # Virtual hosted-style self.conf.storage_domain = 's3.test.com' req = Request.blank('/', environ=environ, headers=headers) sigv4_req = SigV4Request(req.environ) uri = sigv4_req._canonical_uri() self.assertEqual(uri, '/') self.assertEqual(req.environ['PATH_INFO'], '/') req = Request.blank('/obj1', environ=environ, headers=headers) sigv4_req = SigV4Request(req.environ) uri = sigv4_req._canonical_uri() self.assertEqual(uri, '/obj1') self.assertEqual(req.environ['PATH_INFO'], '/obj1') environ = { 'HTTP_HOST': 's3.test.com', 'REQUEST_METHOD': 'GET'} # Path-style self.conf.storage_domain = '' req = Request.blank('/', environ=environ, headers=headers) sigv4_req = SigV4Request(req.environ) uri = sigv4_req._canonical_uri() self.assertEqual(uri, '/') self.assertEqual(req.environ['PATH_INFO'], '/') req = Request.blank('/bucket/obj1', environ=environ, headers=headers) sigv4_req = SigV4Request(req.environ) uri = sigv4_req._canonical_uri() self.assertEqual(uri, '/bucket/obj1') self.assertEqual(req.environ['PATH_INFO'], '/bucket/obj1')
def _test_request_timestamp_sigv4(self, date_header): # signature v4 here environ = { 'REQUEST_METHOD': 'GET'} if 'X-Amz-Date' in date_header: included_header = 'x-amz-date' elif 'Date' in date_header: included_header = 'date' else: self.fail('Invalid date header specified as test') headers = { 'Authorization': 'AWS4-HMAC-SHA256 ' 'Credential=test/%s/US/s3/aws4_request, ' 'SignedHeaders=%s,' 'Signature=X' % ( self.get_v4_amz_date_header().split('T', 1)[0], ';'.join(sorted(['host', included_header]))), 'X-Amz-Content-SHA256': '0123456789'} headers.update(date_header) req = Request.blank('/', environ=environ, headers=headers) sigv4_req = SigV4Request(req.environ) if 'X-Amz-Date' in date_header: timestamp = mktime( date_header['X-Amz-Date'], SIGV4_X_AMZ_DATE_FORMAT) elif 'Date' in date_header: timestamp = mktime(date_header['Date']) self.assertEqual(timestamp, int(sigv4_req.timestamp))
def _get_req(path, environ): if '?' in path: path, query_string = path.split('?', 1) else: query_string = '' env = { 'REQUEST_METHOD': 'GET', 'PATH_INFO': path, 'QUERY_STRING': query_string, 'HTTP_DATE': 'Mon, 09 Sep 2011 23:36:00 GMT', 'HTTP_X_AMZ_CONTENT_SHA256': 'e3b0c44298fc1c149afbf4c8996fb924' '27ae41e4649b934ca495991b7852b855', 'HTTP_AUTHORIZATION': 'AWS4-HMAC-SHA256 ' 'Credential=X:Y/dt/reg/host/blah, ' 'SignedHeaders=content-md5;content-type;date, ' 'Signature=x', } env.update(environ) with patch('swift.common.middleware.s3api.s3request.' 'S3Request._validate_headers'): req = SigV4Request(env, location=self.conf.location) return req
def test_check_signature_multi_bytes_secret_failure(self): # Test v2 check_signature with multi bytes invalid secret req = Request.blank('/photos/puppy.jpg', headers={ 'Host': 'johnsmith.s3.amazonaws.com', 'Date': 'Tue, 27 Mar 2007 19:36:42 +0000', 'Authorization': ('AWS AKIAIOSFODNN7EXAMPLE:' 'bWq2s1WEIj+Ydj0vQ697zp+IXMU='), }) sigv2_req = S3Request(req.environ, storage_domain='s3.amazonaws.com') # This is a failure case with utf-8 non-ascii multi-bytes charactor # but we expect to return just False instead of exceptions self.assertFalse(sigv2_req.check_signature( u'\u30c9\u30e9\u30b4\u30f3')) # Test v4 check_signature with multi bytes invalid secret amz_date_header = self.get_v4_amz_date_header() req = Request.blank('/photos/puppy.jpg', headers={ 'Authorization': 'AWS4-HMAC-SHA256 ' 'Credential=test/%s/US/s3/aws4_request, ' 'SignedHeaders=host;x-amz-content-sha256;x-amz-date,' 'Signature=X' % amz_date_header.split('T', 1)[0], 'X-Amz-Content-SHA256': '0123456789', 'X-Amz-Date': amz_date_header }) sigv4_req = SigV4Request( req.environ, storage_domain='s3.amazonaws.com') self.assertFalse(sigv4_req.check_signature( u'\u30c9\u30e9\u30b4\u30f3'))
def test_check_signature_sigv4_unsigned_payload(self): environ = {'HTTP_HOST': 'bucket.s3.test.com', 'REQUEST_METHOD': 'GET'} headers = { 'Authorization': 'AWS4-HMAC-SHA256 ' 'Credential=test/20210104/us-east-1/s3/aws4_request, ' 'SignedHeaders=host;x-amz-content-sha256;x-amz-date,' 'Signature=f721a7941d5b7710344bc62cc45f87e66f4bb1dd00d9075ee61' '5b1a5c72b0f8c', 'X-Amz-Content-SHA256': 'UNSIGNED-PAYLOAD', 'Date': 'Mon, 04 Jan 2021 10:26:23 -0000', 'X-Amz-Date': '20210104T102623Z' } # Virtual hosted-style self.conf.storage_domain = 's3.test.com' req = Request.blank('/', environ=environ, headers=headers) sigv4_req = SigV4Request(req.environ) self.assertTrue( sigv4_req._canonical_request().endswith(b'UNSIGNED-PAYLOAD')) self.assertTrue(sigv4_req.check_signature('secret'))
def test_check_sigv4_req_zero_content_length_sha256(self): # Virtual hosted-style self.conf.storage_domain = 's3.test.com' # bad sha256 environ = {'HTTP_HOST': 'bucket.s3.test.com', 'REQUEST_METHOD': 'GET'} headers = { 'Authorization': 'AWS4-HMAC-SHA256 ' 'Credential=test/20210104/us-east-1/s3/aws4_request, ' 'SignedHeaders=host;x-amz-content-sha256;x-amz-date,' 'Signature=f721a7941d5b7710344bc62cc45f87e66f4bb1dd00d9075ee61' '5b1a5c72b0f8c', 'X-Amz-Content-SHA256': 'bad', 'Date': 'Mon, 04 Jan 2021 10:26:23 -0000', 'X-Amz-Date': '20210104T102623Z', 'Content-Length': 0, } # lowercase sha256 req = Request.blank('/', environ=environ, headers=headers) self.assertRaises(BadDigest, SigV4Request, req.environ) sha256_of_nothing = hashlib.sha256().hexdigest().encode('ascii') headers = { 'Authorization': 'AWS4-HMAC-SHA256 ' 'Credential=test/20210104/us-east-1/s3/aws4_request, ' 'SignedHeaders=host;x-amz-content-sha256;x-amz-date,' 'Signature=d90542e8b4c0d2f803162040a948e8e51db00b62a59ffb16682' 'ef433718fde12', 'X-Amz-Content-SHA256': sha256_of_nothing, 'Date': 'Mon, 04 Jan 2021 10:26:23 -0000', 'X-Amz-Date': '20210104T102623Z', 'Content-Length': 0, } req = Request.blank('/', environ=environ, headers=headers) sigv4_req = SigV4Request(req.environ) self.assertTrue( sigv4_req._canonical_request().endswith(sha256_of_nothing)) self.assertTrue(sigv4_req.check_signature('secret')) # uppercase sha256 headers = { 'Authorization': 'AWS4-HMAC-SHA256 ' 'Credential=test/20210104/us-east-1/s3/aws4_request, ' 'SignedHeaders=host;x-amz-content-sha256;x-amz-date,' 'Signature=4aab5102e58e9e40f331417d322465c24cac68a7ce77260e9bf' '5ce9a6200862b', 'X-Amz-Content-SHA256': sha256_of_nothing.upper(), 'Date': 'Mon, 04 Jan 2021 10:26:23 -0000', 'X-Amz-Date': '20210104T102623Z', 'Content-Length': 0, } req = Request.blank('/', environ=environ, headers=headers) sigv4_req = SigV4Request(req.environ) self.assertTrue(sigv4_req._canonical_request().endswith( sha256_of_nothing.upper())) self.assertTrue(sigv4_req.check_signature('secret'))