/* (non-Javadoc)
   * @see com.amazonaws.services.s3.AmazonS3Client#completeMultipartUpload(com.amazonaws.services.s3.model.CompleteMultipartUploadRequest)
   */
  @Override
  public CompleteMultipartUploadResult completeMultipartUpload(
      CompleteMultipartUploadRequest completeMultipartUploadRequest)
      throws AmazonClientException, AmazonServiceException {

    appendUserAgent(completeMultipartUploadRequest, USER_AGENT);

    String uploadId = completeMultipartUploadRequest.getUploadId();
    EncryptedUploadContext encryptedUploadContext = currentMultipartUploadSecretKeys.get(uploadId);

    if (encryptedUploadContext.hasFinalPartBeenSeen() == false) {
      throw new AmazonClientException(
          "Unable to complete an encrypted multipart upload without being told which part was the last.  "
              + "Without knowing which part was the last, the encrypted data in Amazon S3 is incomplete and corrupt.");
    }

    CompleteMultipartUploadResult result =
        super.completeMultipartUpload(completeMultipartUploadRequest);

    // In InstructionFile mode, we want to write the instruction file only after the whole upload
    // has completed correctly.
    if (cryptoConfig.getStorageMode() == CryptoStorageMode.InstructionFile) {
      Cipher symmetricCipher =
          EncryptionUtils.createSymmetricCipher(
              encryptedUploadContext.getEnvelopeEncryptionKey(),
              Cipher.ENCRYPT_MODE,
              cryptoConfig.getCryptoProvider(),
              encryptedUploadContext.getFirstInitializationVector());

      EncryptionMaterials encryptionMaterials =
          encryptionMaterialsProvider.getEncryptionMaterials();

      // Encrypt the envelope symmetric key
      byte[] encryptedEnvelopeSymmetricKey =
          EncryptionUtils.getEncryptedSymmetricKey(
              encryptedUploadContext.getEnvelopeEncryptionKey(),
              encryptionMaterials,
              cryptoConfig.getCryptoProvider());
      EncryptionInstruction instruction =
          new EncryptionInstruction(
              encryptionMaterials.getMaterialsDescription(),
              encryptedEnvelopeSymmetricKey,
              encryptedUploadContext.getEnvelopeEncryptionKey(),
              symmetricCipher);

      // Put the instruction file into S3
      super.putObject(
          EncryptionUtils.createInstructionPutRequest(
              encryptedUploadContext.getBucketName(),
              encryptedUploadContext.getKey(),
              instruction));
    }

    currentMultipartUploadSecretKeys.remove(uploadId);
    return result;
  }
  /* (non-Javadoc)
   * @see com.amazonaws.services.s3.AmazonS3Client#initiateMultipartUpload(com.amazonaws.services.s3.model.InitiateMultipartUploadRequest)
   */
  @Override
  public InitiateMultipartUploadResult initiateMultipartUpload(
      InitiateMultipartUploadRequest initiateMultipartUploadRequest)
      throws AmazonClientException, AmazonServiceException {

    appendUserAgent(initiateMultipartUploadRequest, USER_AGENT);

    // Generate a one-time use symmetric key and initialize a cipher to encrypt object data
    SecretKey envelopeSymmetricKey = EncryptionUtils.generateOneTimeUseSymmetricKey();
    Cipher symmetricCipher =
        EncryptionUtils.createSymmetricCipher(
            envelopeSymmetricKey, Cipher.ENCRYPT_MODE, cryptoConfig.getCryptoProvider(), null);

    if (cryptoConfig.getStorageMode() == CryptoStorageMode.ObjectMetadata) {
      EncryptionMaterials encryptionMaterials =
          encryptionMaterialsProvider.getEncryptionMaterials();
      // Encrypt the envelope symmetric key
      byte[] encryptedEnvelopeSymmetricKey =
          EncryptionUtils.getEncryptedSymmetricKey(
              envelopeSymmetricKey, encryptionMaterials, cryptoConfig.getCryptoProvider());

      // Store encryption info in metadata
      ObjectMetadata metadata =
          EncryptionUtils.updateMetadataWithEncryptionInfo(
              initiateMultipartUploadRequest,
              encryptedEnvelopeSymmetricKey,
              symmetricCipher,
              encryptionMaterials.getMaterialsDescription());

      // Update the request's metadata to the updated metadata
      initiateMultipartUploadRequest.setObjectMetadata(metadata);
    }

    InitiateMultipartUploadResult result =
        super.initiateMultipartUpload(initiateMultipartUploadRequest);
    EncryptedUploadContext encryptedUploadContext =
        new EncryptedUploadContext(
            initiateMultipartUploadRequest.getBucketName(),
            initiateMultipartUploadRequest.getKey(),
            envelopeSymmetricKey);
    encryptedUploadContext.setNextInitializationVector(symmetricCipher.getIV());
    encryptedUploadContext.setFirstInitializationVector(symmetricCipher.getIV());
    currentMultipartUploadSecretKeys.put(result.getUploadId(), encryptedUploadContext);

    return result;
  }
Example #3
0
  public S3NotebookRepo(ZeppelinConfiguration conf) throws IOException {
    this.conf = conf;
    bucketName = conf.getBucketName();
    user = conf.getUser();

    // always use the default provider chain
    AWSCredentialsProvider credentialsProvider = new DefaultAWSCredentialsProviderChain();
    CryptoConfiguration cryptoConf = null;
    String keyRegion = conf.getS3KMSKeyRegion();

    if (StringUtils.isNotBlank(keyRegion)) {
      cryptoConf = new CryptoConfiguration();
      cryptoConf.setAwsKmsRegion(Region.getRegion(Regions.fromName(keyRegion)));
    }

    // see if we should be encrypting data in S3
    String kmsKeyID = conf.getS3KMSKeyID();
    if (kmsKeyID != null) {
      // use the AWS KMS to encrypt data
      KMSEncryptionMaterialsProvider emp = new KMSEncryptionMaterialsProvider(kmsKeyID);
      if (cryptoConf != null) {
        this.s3client = new AmazonS3EncryptionClient(credentialsProvider, emp, cryptoConf);
      } else {
        this.s3client = new AmazonS3EncryptionClient(credentialsProvider, emp);
      }
    } else if (conf.getS3EncryptionMaterialsProviderClass() != null) {
      // use a custom encryption materials provider class
      EncryptionMaterialsProvider emp = createCustomProvider(conf);
      this.s3client = new AmazonS3EncryptionClient(credentialsProvider, emp);
    } else {
      // regular S3
      this.s3client = new AmazonS3Client(credentialsProvider);
    }

    // set S3 endpoint to use
    s3client.setEndpoint(conf.getEndpoint());
  }