All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.amazonaws.services.cloudfront.util.SignerUtils Maven / Gradle / Ivy

Go to download

The AWS Java SDK for Amazon CloudFront module holds the client classes that are used for communicating with Amazon CloudFront Service

There is a newer version: 1.12.780
Show newest version
/*
 * Copyright 2011-2022 Amazon.com, Inc. or its affiliates. All Rights
 * Reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License").
 * You may not use this file except in compliance with the License.
 * A copy of the License is located at
 *
 *  http://aws.amazon.com/apache2.0
 *
 * or in the "license" file accompanying this file. This file is distributed
 * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
 * express or implied. See the License for the specific language governing
 * permissions and limitations under the License.
 */
package com.amazonaws.services.cloudfront.util;

import static com.amazonaws.services.cloudfront.util.SignerUtils.makeBytesUrlSafe;
import static com.amazonaws.util.StringUtils.UTF8;
import static java.util.concurrent.TimeUnit.MILLISECONDS;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.security.PrivateKey;
import java.security.SecureRandom;
import java.security.Signature;
import java.security.SignatureException;
import java.security.spec.InvalidKeySpecException;
import java.util.Date;

import com.amazonaws.AmazonClientException;
import com.amazonaws.auth.PEM;
import com.amazonaws.auth.RSA;
import com.amazonaws.util.Base64;
import com.amazonaws.util.IOUtils;
import com.amazonaws.util.StringUtils;

public class SignerUtils {

    private static final SecureRandom srand = new SecureRandom();

    /**
     * Enumeration of protocols for presigned URLs
     */
    public static enum Protocol {
        http, https, rtmp
    }

    /**
     * Returns a "canned" policy for the given parameters.
     * For more information, see Overview of Signed URLs.
     */
    public static String buildCannedPolicy(String resourceUrlOrPath,
            Date dateLessThan) {
        return "{\"Statement\":[{\"Resource\":\""
                + resourceUrlOrPath
                + "\",\"Condition\":{\"DateLessThan\":{\"AWS:EpochTime\":"
                + MILLISECONDS.toSeconds(dateLessThan.getTime())
                + "}}}]}";
    }

    /**
     * Returns a custom policy for the given parameters.
     */
    public static String buildCustomPolicy(String resourcePath,
            Date expiresOn, Date activeFrom, String ipAddress) {
        return "{\"Statement\": [{"
                + "\"Resource\":\""
                + resourcePath
                + "\""
                + ",\"Condition\":{"
                + "\"DateLessThan\":{\"AWS:EpochTime\":"
                + MILLISECONDS.toSeconds(expiresOn.getTime())
                + "}"
                + (ipAddress == null
                  ? ""
                  : ",\"IpAddress\":{\"AWS:SourceIp\":\""
                    + ipAddress + "\"}"
                  )
                + (activeFrom == null
                   ? ""
                   : ",\"DateGreaterThan\":{\"AWS:EpochTime\":"
                     + MILLISECONDS.toSeconds(activeFrom.getTime()) + "}"
                  )
                + "}}]}";
    }
    /**
     * Converts the given data to be safe for use in signed URLs for a private
     * distribution by using specialized Base64 encoding.
     */
    public static String makeBytesUrlSafe(byte[] bytes) {
        byte[] encoded = Base64.encode(bytes);

        for (int i=0; i < encoded.length; i++) {
            switch(encoded[i]) {
                case '+':
                    encoded[i] = '-'; continue;
                case '=':
                    encoded[i] = '_'; continue;
                case '/':
                    encoded[i] = '~'; continue;
                default:
                    continue;
            }
        }
        return new String(encoded, UTF8);
    }

    /**
     * Converts the given string to be safe for use in signed URLs for a private
     * distribution.
     */
    public static String makeStringUrlSafe(String str) {
        return makeBytesUrlSafe(str.getBytes(StringUtils.UTF8));
    }

    /**
     * Returns the resource path for the given distribution, object, and
     * protocol.
     */
    public static String generateResourcePath(final Protocol protocol,
            final String distributionDomain, final String resourcePath) {
        return protocol == Protocol.http || protocol == Protocol.https
             ? protocol + "://" + distributionDomain + "/" + resourcePath
             : resourcePath
             ;
    }

    /**
     * Signs the data given with the private key given, using the SHA1withRSA
     * algorithm provided by bouncy castle.
     */
    public static byte[] signWithSha1RSA(byte[] dataToSign,
            PrivateKey privateKey) throws InvalidKeyException {
        Signature signature;
        try {
            signature = Signature.getInstance("SHA1withRSA");
            signature.initSign(privateKey, srand);
            signature.update(dataToSign);
            return signature.sign();
        } catch (NoSuchAlgorithmException e) {
            throw new IllegalStateException(e);
        } catch (SignatureException e) {
            throw new IllegalStateException(e);
        }
    }

    /**
     * Creates a private key from the file given, either in RSA private key
     * (.pem) or pkcs8 (.der) format. Other formats will cause an exception to
     * be thrown.
     */
    public static PrivateKey loadPrivateKey(File privateKeyFile) throws InvalidKeySpecException, IOException {
        if ( StringUtils.lowerCase(privateKeyFile.getAbsolutePath()).endsWith(".pem") ) {
            InputStream is = new FileInputStream(privateKeyFile);
            try {
                return PEM.readPrivateKey(is);
            } finally {
                try {is.close();} catch(IOException ignore) {}
            }
        } else if ( StringUtils.lowerCase(privateKeyFile.getAbsolutePath()).endsWith(".der") ) {
            InputStream is = new FileInputStream(privateKeyFile);
            try {
                return RSA.privateKeyFromPKCS8(IOUtils.toByteArray(is));
            } finally {
                try {is.close();} catch(IOException ignore) {}
            }
        } else {
            throw new AmazonClientException("Unsupported file type for private key");
        }
    }

    public static PrivateKey loadPrivateKey(String privateKeyFilePath) throws InvalidKeySpecException, IOException {
        File privateKeyFile = new File(privateKeyFilePath);
        return loadPrivateKey(privateKeyFile);
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy