Search in sources :

Example 61 with CosClientException

use of com.qcloud.cos.exception.CosClientException in project cos-java-sdk-v5 by tencentyun.

the class COSClient method uploadObjectInternal.

protected <UploadObjectRequest extends PutObjectRequest> ObjectMetadata uploadObjectInternal(UploadMode uploadMode, UploadObjectRequest uploadObjectRequest) throws CosClientException, CosServiceException {
    rejectNull(uploadObjectRequest, "The PutObjectRequest parameter must be specified when uploading an object");
    rejectNull(clientConfig.getRegion(), "region is null, region in clientConfig must be specified when uploading an object");
    final File file = uploadObjectRequest.getFile();
    final InputStream isOrig = uploadObjectRequest.getInputStream();
    final String bucketName = uploadObjectRequest.getBucketName();
    final String key = uploadObjectRequest.getKey();
    ObjectMetadata metadata = uploadObjectRequest.getMetadata();
    InputStream input = isOrig;
    if (metadata == null)
        metadata = new ObjectMetadata();
    rejectNull(bucketName, "The bucket name parameter must be specified when uploading an object");
    rejectNull(key, "The key parameter must be specified when uploading an object");
    // information from it to auto-configure a few options
    if (file == null) {
        // unlimited mark-and-reset
        if (input != null)
            input = ReleasableInputStream.wrap(input);
    } else {
        // Always set the content length, even if it's already set
        metadata.setContentLength(file.length());
        final long maxAllowdSingleFileSize = 5 * 1024L * 1024L * 1024L;
        if (file.length() > maxAllowdSingleFileSize) {
            throw new CosClientException("max size 5GB is allowed by putObject Method, your filesize is " + file.length() + ", please use transferManager to upload big file!");
        }
        final boolean calculateMD5 = metadata.getContentMD5() == null;
        if (calculateMD5 && !skipMd5CheckStrategy.skipServerSideValidation(uploadObjectRequest)) {
            try {
                String contentMd5_b64 = Md5Utils.md5AsBase64(file);
                metadata.setContentMD5(contentMd5_b64);
            } catch (Exception e) {
                throw new CosClientException("Unable to calculate MD5 hash: " + e.getMessage(), e);
            }
        }
        input = ResettableInputStream.newResettableInputStream(file, "Unable to find file to upload");
    }
    final ObjectMetadata returnedMetadata;
    MD5DigestCalculatingInputStream md5DigestStream = null;
    try {
        CosHttpRequest<UploadObjectRequest> request = null;
        if (uploadMode.equals(UploadMode.PUT_OBJECT)) {
            request = createRequest(bucketName, key, uploadObjectRequest, HttpMethodName.PUT);
        } else if (uploadMode.equals(UploadMode.APPEND_OBJECT)) {
            request = createRequest(bucketName, key, uploadObjectRequest, HttpMethodName.POST);
            AppendObjectRequest appendObjectRequest = (AppendObjectRequest) uploadObjectRequest;
            String positionStr = String.valueOf(appendObjectRequest.getPosition());
            request.addParameter("append", null);
            request.addParameter("position", positionStr);
        }
        if (uploadObjectRequest.getAccessControlList() != null) {
            addAclHeaders(request, uploadObjectRequest.getAccessControlList());
        } else if (uploadObjectRequest.getCannedAcl() != null) {
            request.addHeader(Headers.COS_CANNED_ACL, uploadObjectRequest.getCannedAcl().toString());
        }
        if (uploadObjectRequest.getStorageClass() != null) {
            request.addHeader(Headers.STORAGE_CLASS, uploadObjectRequest.getStorageClass());
        }
        if (uploadObjectRequest.getRedirectLocation() != null) {
            request.addHeader(Headers.REDIRECT_LOCATION, uploadObjectRequest.getRedirectLocation());
            if (input == null) {
                input = new ByteArrayInputStream(new byte[0]);
            }
        }
        // Populate the SSE-C parameters to the request header
        populateSSE_C(request, uploadObjectRequest.getSSECustomerKey());
        // Populate the SSE KMS parameters to the request header
        populateSSE_KMS(request, uploadObjectRequest.getSSECOSKeyManagementParams());
        // Populate the traffic limit parameter to the request header
        populateTrafficLimit(request, uploadObjectRequest.getTrafficLimit());
        // Use internal interface to differentiate 0 from unset.
        final Long contentLength = (Long) metadata.getRawMetadataValue(Headers.CONTENT_LENGTH);
        if (contentLength == null) {
            /*
                 * There's nothing we can do except for let the HTTP client buffer the input stream
                 * contents if the caller doesn't tell us how much data to expect in a stream since
                 * we have to explicitly tell how much we're sending before we start sending any of
                 * it.
                 */
            log.warn("No content length specified for stream data.  " + "Stream contents will be buffered in memory and could result in " + "out of memory errors.");
        } else {
            final long expectedLength = contentLength.longValue();
            final long maxAllowdSingleFileSize = 5 * 1024L * 1024L * 1024L;
            if (expectedLength > maxAllowdSingleFileSize) {
                throw new CosClientException("max size 5GB is allowed by putObject Method, your filesize is " + expectedLength + ", please use transferManager to upload big file!");
            }
            if (expectedLength >= 0) {
                // Performs length check on the underlying data stream.
                // For COS encryption client, the underlying data stream here
                // refers to the cipher-text data stream (ie not the underlying
                // plain-text data stream which in turn may have been wrapped
                // with it's own length check input stream.)
                LengthCheckInputStream lcis = new // expected
                LengthCheckInputStream(// expected
                input, // expected
                expectedLength, // uploaded
                EXCLUDE_SKIPPED_BYTES);
                input = lcis;
            }
        }
        if (metadata.getContentMD5() == null && !skipMd5CheckStrategy.skipClientSideValidationPerRequest(uploadObjectRequest)) {
            /*
                 * If the user hasn't set the content MD5, then we don't want to buffer the whole
                 * stream in memory just to calculate it. Instead, we can calculate it on the fly
                 * and validate it with the returned ETag from the object upload.
                 */
            input = md5DigestStream = new MD5DigestCalculatingInputStream(input);
        }
        populateRequestMetadata(request, metadata);
        request.setContent(input);
        try {
            if (uploadObjectRequest.getPicOperations() != null) {
                request.addHeader(Headers.PIC_OPERATIONS, Jackson.toJsonString(uploadObjectRequest.getPicOperations()));
                returnedMetadata = invoke(request, new ResponseHeaderHandlerChain<ObjectMetadata>(new Unmarshallers.ImagePersistenceUnmarshaller(), new CosMetadataResponseHandler()));
            } else {
                returnedMetadata = invoke(request, new CosMetadataResponseHandler());
            }
        } catch (Throwable t) {
            throw Throwables.failure(t);
        }
    } finally {
        CosDataSource.Utils.cleanupDataSource(uploadObjectRequest, file, isOrig, input, log);
    }
    String contentMd5 = metadata.getContentMD5();
    if (md5DigestStream != null) {
        contentMd5 = Base64.encodeAsString(md5DigestStream.getMd5Digest());
    }
    final String etag = returnedMetadata.getETag();
    if (contentMd5 != null && uploadMode.equals(UploadMode.PUT_OBJECT) && !skipMd5CheckStrategy.skipClientSideValidationPerPutResponse(returnedMetadata)) {
        byte[] clientSideHash = BinaryUtils.fromBase64(contentMd5);
        byte[] serverSideHash = null;
        try {
            serverSideHash = BinaryUtils.fromHex(etag);
        } catch (DecoderException e) {
            throw new CosClientException("Unable to verify integrity of data upload.  " + "Client calculated content hash (contentMD5: " + contentMd5 + " in base 64) didn't match hash (etag: " + etag + " in hex) calculated by COS .  " + "You may need to delete the data stored in COS . (metadata.contentMD5: " + metadata.getContentMD5() + ", bucketName: " + bucketName + ", key: " + key + ")");
        }
        if (!Arrays.equals(clientSideHash, serverSideHash)) {
            throw new CosClientException("Unable to verify integrity of data upload.  " + "Client calculated content hash (contentMD5: " + contentMd5 + " in base 64) didn't match hash (etag: " + etag + " in hex) calculated by COS .  " + "You may need to delete the data stored in COS . (metadata.contentMD5: " + metadata.getContentMD5() + ", bucketName: " + bucketName + ", key: " + key + ")");
        }
    }
    return returnedMetadata;
}
Also used : LengthCheckInputStream(com.qcloud.cos.internal.LengthCheckInputStream) Unmarshallers(com.qcloud.cos.internal.Unmarshallers) DigestValidationInputStream(com.qcloud.cos.internal.DigestValidationInputStream) ReleasableInputStream(com.qcloud.cos.internal.ReleasableInputStream) MD5DigestCalculatingInputStream(com.qcloud.cos.internal.MD5DigestCalculatingInputStream) LengthCheckInputStream(com.qcloud.cos.internal.LengthCheckInputStream) ServiceClientHolderInputStream(com.qcloud.cos.internal.ServiceClientHolderInputStream) ByteArrayInputStream(java.io.ByteArrayInputStream) ResettableInputStream(com.qcloud.cos.internal.ResettableInputStream) SdkFilterInputStream(com.qcloud.cos.internal.SdkFilterInputStream) InputStream(java.io.InputStream) CosClientException(com.qcloud.cos.exception.CosClientException) MD5DigestCalculatingInputStream(com.qcloud.cos.internal.MD5DigestCalculatingInputStream) CosMetadataResponseHandler(com.qcloud.cos.internal.CosMetadataResponseHandler) DecoderException(org.apache.commons.codec.DecoderException) NoSuchAlgorithmException(java.security.NoSuchAlgorithmException) MultiObjectDeleteException(com.qcloud.cos.exception.MultiObjectDeleteException) IOException(java.io.IOException) URISyntaxException(java.net.URISyntaxException) UnsupportedEncodingException(java.io.UnsupportedEncodingException) CosServiceException(com.qcloud.cos.exception.CosServiceException) CosClientException(com.qcloud.cos.exception.CosClientException) MalformedURLException(java.net.MalformedURLException) DecoderException(org.apache.commons.codec.DecoderException) ByteArrayInputStream(java.io.ByteArrayInputStream) File(java.io.File) ResponseHeaderHandlerChain(com.qcloud.cos.internal.ResponseHeaderHandlerChain)

Example 62 with CosClientException

use of com.qcloud.cos.exception.CosClientException in project cos-java-sdk-v5 by tencentyun.

the class COSClient method setContent.

private void setContent(CosHttpRequest<?> request, byte[] content, String contentType, boolean setMd5) {
    request.setContent(new ByteArrayInputStream(content));
    request.addHeader("Content-Length", Integer.toString(content.length));
    request.addHeader("Content-Type", contentType);
    if (setMd5) {
        try {
            byte[] md5 = Md5Utils.computeMD5Hash(content);
            String md5Base64 = BinaryUtils.toBase64(md5);
            request.addHeader("Content-MD5", md5Base64);
        } catch (Exception e) {
            throw new CosClientException("Couldn't compute md5 sum", e);
        }
    }
}
Also used : ByteArrayInputStream(java.io.ByteArrayInputStream) CosClientException(com.qcloud.cos.exception.CosClientException) DecoderException(org.apache.commons.codec.DecoderException) NoSuchAlgorithmException(java.security.NoSuchAlgorithmException) MultiObjectDeleteException(com.qcloud.cos.exception.MultiObjectDeleteException) IOException(java.io.IOException) URISyntaxException(java.net.URISyntaxException) UnsupportedEncodingException(java.io.UnsupportedEncodingException) CosServiceException(com.qcloud.cos.exception.CosServiceException) CosClientException(com.qcloud.cos.exception.CosClientException) MalformedURLException(java.net.MalformedURLException)

Example 63 with CosClientException

use of com.qcloud.cos.exception.CosClientException in project cos-java-sdk-v5 by tencentyun.

the class ContentCryptoMaterial method cek.

/**
 * Returns the content encrypting key unwrapped or decrypted. Note if KMS is used for key
 * protection, a remote call will be made to KMS to decrypt the ciphertext blob.
 *
 * @param cekSecured the content encrypting key in wrapped or encrypted form; must not be null
 * @param keyWrapAlgo key wrapping algorithm; or null if direct encryption instead of key
 *        wrapping is used
 * @param materials the client key encrypting key material for the content encrypting key
 * @param securityProvider security provider or null if the default security provider of the JCE
 *        is used
 */
private static SecretKey cek(byte[] cekSecured, String keyWrapAlgo, EncryptionMaterials materials, Provider securityProvider, ContentCryptoScheme contentCryptoScheme, QCLOUDKMS kms) {
    if (isKMSKeyWrapped(keyWrapAlgo))
        return cekByKMS(cekSecured, keyWrapAlgo, materials, contentCryptoScheme, kms);
    Key kek;
    if (materials.getKeyPair() != null) {
        // Do envelope decryption with private key from key pair
        kek = materials.getKeyPair().getPrivate();
        if (kek == null) {
            throw new CosClientException("Key encrypting key not available");
        }
    } else {
        // Do envelope decryption with symmetric key
        kek = materials.getSymmetricKey();
        if (kek == null) {
            throw new CosClientException("Key encrypting key not available");
        }
    }
    try {
        if (keyWrapAlgo != null) {
            // Key wrapping specified
            Cipher cipher = securityProvider == null ? Cipher.getInstance(keyWrapAlgo) : Cipher.getInstance(keyWrapAlgo, securityProvider);
            cipher.init(Cipher.UNWRAP_MODE, kek);
            return (SecretKey) cipher.unwrap(cekSecured, keyWrapAlgo, Cipher.SECRET_KEY);
        }
        // fall back to the Encryption Only (EO) key decrypting method
        Cipher cipher;
        if (securityProvider != null) {
            cipher = Cipher.getInstance(kek.getAlgorithm(), securityProvider);
        } else {
            cipher = Cipher.getInstance(kek.getAlgorithm());
        }
        cipher.init(Cipher.DECRYPT_MODE, kek);
        byte[] decryptedSymmetricKeyBytes = cipher.doFinal(cekSecured);
        return new SecretKeySpec(decryptedSymmetricKeyBytes, JceEncryptionConstants.SYMMETRIC_KEY_ALGORITHM);
    } catch (Exception e) {
        throw new CosClientException("Unable to decrypt symmetric key from object metadata", e);
    }
}
Also used : SecretKey(javax.crypto.SecretKey) CosClientException(com.qcloud.cos.exception.CosClientException) SecretKeySpec(javax.crypto.spec.SecretKeySpec) Cipher(javax.crypto.Cipher) Key(java.security.Key) SecretKey(javax.crypto.SecretKey) CosClientException(com.qcloud.cos.exception.CosClientException) IOException(java.io.IOException) JsonProcessingException(com.fasterxml.jackson.core.JsonProcessingException)

Example 64 with CosClientException

use of com.qcloud.cos.exception.CosClientException in project cos-java-sdk-v5 by tencentyun.

the class ContentCryptoMaterial method recreate.

/**
 * Recreates a new content crypto material from the current material given a new KEK
 * material-descriptions. The purpose is to re-encrypt the CEK under a different KEK.
 *
 * Note network calls are involved if the CEK has been or is to be protected by KMS.
 *
 * @param newKEKMatDesc material descriptions for the new KEK; never null
 * @param accessor used to retrieve the KEK given the corresponding material description
 * @param targetScheme the target crypto scheme to be used for key wrapping, etc.
 * @param p optional security provider; null means to use the default.
 * @throws SecurityException if the old and new material description are the same; or if the old
 *         and new KEK are the same
 */
ContentCryptoMaterial recreate(Map<String, String> newKEKMatDesc, EncryptionMaterialsAccessor accessor, COSCryptoScheme targetScheme, Provider p, QCLOUDKMS kms, CosServiceRequest req) {
    if (!usesKMSKey() && newKEKMatDesc.equals(kekMaterialsDescription)) {
        throw new SecurityException("Material description of the new KEK must differ from the current one");
    }
    final EncryptionMaterials origKEK;
    if (usesKMSKey()) {
        origKEK = new KMSEncryptionMaterials(kekMaterialsDescription.get(KMSEncryptionMaterials.CUSTOMER_MASTER_KEY_ID));
    } else {
        origKEK = accessor.getEncryptionMaterials(kekMaterialsDescription);
        if (origKEK == null) {
            throw new CosClientException("Unable to retrieve the origin encryption materials");
        }
    }
    EncryptionMaterials newKEK = accessor.getEncryptionMaterials(newKEKMatDesc);
    if (newKEK == null) {
        throw new CosClientException("No material available with the description " + newKEKMatDesc + " from the encryption material provider");
    }
    SecretKey cek = cek(encryptedCEK, keyWrappingAlgorithm, origKEK, p, getContentCryptoScheme(), kms);
    ContentCryptoMaterial output = create(// must use same
    cek, // must use same
    cipherLite.getIV(), // must use same
    newKEK, // must use same
    getContentCryptoScheme(), // scheme
    targetScheme, p, kms, req);
    if (Arrays.equals(output.encryptedCEK, encryptedCEK)) {
        throw new SecurityException("The new KEK must differ from the original");
    }
    return output;
}
Also used : SecretKey(javax.crypto.SecretKey) CosClientException(com.qcloud.cos.exception.CosClientException)

Example 65 with CosClientException

use of com.qcloud.cos.exception.CosClientException in project cos-java-sdk-v5 by tencentyun.

the class ContentCryptoMaterial method fromObjectMetadata0.

/**
 * @return a non-null content crypto material.
 */
private static ContentCryptoMaterial fromObjectMetadata0(ObjectMetadata metadata, EncryptionMaterialsAccessor kekMaterialAccessor, Provider securityProvider, long[] range, boolean keyWrapExpected, QCLOUDKMS kms) {
    // CEK and IV
    Map<String, String> userMeta = metadata.getUserMetadata();
    // new version has different header
    if (userMeta.get(Headers.ENCRYPTION_KEY) != null) {
        return fromObjectMetadata1(userMeta, kekMaterialAccessor, securityProvider, range, keyWrapExpected, kms);
    }
    String b64key = userMeta.get(Headers.CRYPTO_KEY_V2);
    if (b64key == null) {
        b64key = userMeta.get(Headers.CRYPTO_KEY);
        if (b64key == null)
            throw new CosClientException("Content encrypting key not found.");
    }
    byte[] cekWrapped = Base64.decode(b64key);
    // byte[] iv = userMeta.get(Headers.CRYPTO_IV).getBytes();
    byte[] iv = Base64.decode(userMeta.get(Headers.CRYPTO_IV));
    if (cekWrapped == null || iv == null) {
        throw new CosClientException("Content encrypting key or IV not found.");
    }
    // Material description
    String matdescStr = userMeta.get(Headers.MATERIALS_DESCRIPTION);
    final String keyWrapAlgo = userMeta.get(Headers.CRYPTO_KEYWRAP_ALGORITHM);
    final boolean isKMS = isKMSKeyWrapped(keyWrapAlgo);
    final Map<String, String> core = matdescFromJson(matdescStr);
    final EncryptionMaterials materials;
    if (isKMS) {
        materials = new KMSEncryptionMaterials(core.get(KMSEncryptionMaterials.CUSTOMER_MASTER_KEY_ID));
        materials.addDescriptions(core);
    } else {
        materials = kekMaterialAccessor == null ? null : kekMaterialAccessor.getEncryptionMaterials(core);
        if (materials == null) {
            throw new CosClientException("Unable to retrieve the client encryption materials");
        }
    }
    // CEK algorithm
    String cekAlgo = userMeta.get(Headers.CRYPTO_CEK_ALGORITHM);
    boolean isRangeGet = range != null;
    // The content crypto scheme may vary depending on whether
    // it is a range get operation
    ContentCryptoScheme contentCryptoScheme = ContentCryptoScheme.fromCEKAlgo(cekAlgo, isRangeGet);
    if (isRangeGet) {
        // Adjust the IV as needed
        iv = contentCryptoScheme.adjustIV(iv, range[0]);
    } else {
        // Validate the tag length supported
        int tagLenExpected = contentCryptoScheme.getTagLengthInBits();
        if (tagLenExpected > 0) {
            String s = userMeta.get(Headers.CRYPTO_TAG_LENGTH);
            int tagLenActual = Integer.parseInt(s);
            if (tagLenExpected != tagLenActual) {
                throw new CosClientException("Unsupported tag length: " + tagLenActual + ", expected: " + tagLenExpected);
            }
        }
    }
    // Unwrap or decrypt the CEK
    if (keyWrapExpected && keyWrapAlgo == null)
        throw newKeyWrapException();
    SecretKey cek = cek(cekWrapped, keyWrapAlgo, materials, securityProvider, contentCryptoScheme, kms);
    return new ContentCryptoMaterial(core, cekWrapped, keyWrapAlgo, contentCryptoScheme.createCipherLite(cek, iv, Cipher.DECRYPT_MODE, securityProvider), null);
}
Also used : SecretKey(javax.crypto.SecretKey) CosClientException(com.qcloud.cos.exception.CosClientException)

Aggregations

CosClientException (com.qcloud.cos.exception.CosClientException)111 CosServiceException (com.qcloud.cos.exception.CosServiceException)64 COSCredentials (com.qcloud.cos.auth.COSCredentials)41 ClientConfig (com.qcloud.cos.ClientConfig)39 BasicCOSCredentials (com.qcloud.cos.auth.BasicCOSCredentials)39 Region (com.qcloud.cos.region.Region)39 COSClient (com.qcloud.cos.COSClient)37 IOException (java.io.IOException)31 File (java.io.File)28 ByteArrayInputStream (java.io.ByteArrayInputStream)18 NoSuchAlgorithmException (java.security.NoSuchAlgorithmException)15 TransferManager (com.qcloud.cos.transfer.TransferManager)14 ExecutorService (java.util.concurrent.ExecutorService)14 ObjectMetadata (com.qcloud.cos.model.ObjectMetadata)13 URISyntaxException (java.net.URISyntaxException)13 MultiObjectDeleteException (com.qcloud.cos.exception.MultiObjectDeleteException)12 PutObjectRequest (com.qcloud.cos.model.PutObjectRequest)12 SecretKey (javax.crypto.SecretKey)12 MalformedURLException (java.net.MalformedURLException)11 PutObjectResult (com.qcloud.cos.model.PutObjectResult)10