/** * Create a {@link Policy} in Json format and Base 64 encoded. * * @param encodedPolicy * The String representation of the {@link Policy} in Json format and encoded into Base 64 * @return The {@link Policy} data */ public static Policy fromBase64EncodedPolicy(String encodedPolicy) { String decodedPolicyString = base64Decode(encodedPolicy); return fromJson(decodedPolicyString); }
/** * Check to see if a {@link URI} has not been signed already. * * @param uri * The {@link URI} to check to see if it was not signed. * @return True if not signed, false if signed. */ public static boolean isNotSigned(URI uri) { return !isSigned(uri); }
/** * Get an encrypted version of a {@link Policy} to use as a signature. * * @param policy * {@link Policy} that needs to be encrypted. * @param encryptionKey * The key to use to encrypt the {@link Policy}. * @return An encrypted version of the {@link Policy} that is also Base64 encoded to make it safe to transmit as a * query parameter. * @throws Exception * Thrown if there is a problem encrypting or encoding the {@link Policy} */ public static String getPolicySignature(Policy policy, String encryptionKey) throws Exception { return SHA256Util.digest(PolicyUtils.toJson(policy).toJSONString(), encryptionKey); } }
Properties encryptionKeys, boolean strict) { ResourceRequest resourceRequest = new ResourceRequest(); List<NameValuePair> queryParameters = parseQueryString(queryString); if (!getQueryStringParameters(resourceRequest, queryParameters)) { return resourceRequest; Policy policy = PolicyUtils.fromBase64EncodedPolicy(resourceRequest.getEncodedPolicy()); resourceRequest.setPolicy(policy); if (!policyMatchesSignature(policy, resourceRequest.getSignature(), encryptionKey)) { resourceRequest.setStatus(Status.Forbidden); try { String policySignature = PolicyUtils.getPolicySignature(policy, encryptionKey); resourceRequest .setRejectionReason(String .format("Forbidden because policy and signature do not match. Policy: '%s' created Signature from this policy '%s' and query string Signature: '%s'.", PolicyUtils.toJson(resourceRequest.getPolicy()).toJSONString(), policySignature, resourceRequest.getSignature())); } catch (Exception e) { .setRejectionReason(String .format("Forbidden because policy and signature do not match. Policy: '%s' and query string Signature: '%s'. Unable to sign policy because: %s", PolicyUtils.toJson(resourceRequest.getPolicy()).toJSONString(), resourceRequest.getSignature(), ExceptionUtils.getStackTrace(e)));
/** * Transform a {@link Policy} into a {@link ResourceRequest} query string. * * @param policy * The {@link Policy} to use in the {@link ResourceRequest} * @param encryptionKeyId * The id of the encryption key. * @param encryptionKey * The actual encryption key. * @return A query string created from the policy. * @throws Exception * Thrown if there is a problem encoding or encrypting the policy. */ public static String policyToResourceRequestQueryString(Policy policy, String encryptionKeyId, String encryptionKey) throws Exception { ResourceRequest resourceRequest = new ResourceRequest(); resourceRequest.setEncodedPolicy(PolicyUtils.toBase64EncodedPolicy(policy)); resourceRequest.setEncryptionKeyId(encryptionKeyId); resourceRequest.setSignature(PolicyUtils.getPolicySignature(policy, encryptionKey)); return resourceRequestToQueryString(resourceRequest); }
/** * Create a {@link Policy} in Json format and Base 64 encoded. * * @param policy * The String representation of the {@link Policy} in Json format and encoded into Base 64 * @return The {@link Policy} data */ public static String toBase64EncodedPolicy(Policy policy) { return base64Encode(PolicyUtils.toJson(policy).toJSONString()); }
/** * Determine if the policy matches the encrypted signature. * * @param policy * The policy to compare to the encrypted signature. * @param signature * The encrypted policy that was sent. * @param encryptionKey * The encryption key to use to encrypt the policy. * @return If the policy encrypted matches the signature. */ protected static boolean policyMatchesSignature(Policy policy, String signature, String encryptionKey) { try { String encryptedPolicy = PolicyUtils.getPolicySignature(policy, encryptionKey); return signature.equals(encryptedPolicy); } catch (Exception e) { logger.warn("Unable to encrypt policy because {}", ExceptionUtils.getStackTrace(e)); return false; } }
@Override public String sign(Policy policy) throws UrlSigningException { if (!accepts(policy.getBaseUrl())) { throw UrlSigningException.urlNotSupported(); } // Get the key that matches this URI since there must be one that matches as the base url has been accepted. KeyEntry keyEntry = getKeyEntry(policy.getBaseUrl()); policy.setResourceStrategy(getResourceStrategy()); try { URI uri = new URI(policy.getBaseUrl()); List<NameValuePair> queryStringParameters = new ArrayList<>(); if (uri.getQuery() != null) { queryStringParameters = URLEncodedUtils.parse(new URI(policy.getBaseUrl()).getQuery(), StandardCharsets.UTF_8); } queryStringParameters.addAll(URLEncodedUtils.parse( ResourceRequestUtil.policyToResourceRequestQueryString(policy, keyEntry.getId(), keyEntry.getKey()), StandardCharsets.UTF_8)); return new URI(uri.getScheme(), null, uri.getHost(), uri.getPort(), uri.getPath(), URLEncodedUtils.format(queryStringParameters, StandardCharsets.UTF_8), null).toString(); } catch (Exception e) { getLogger().error("Unable to create signed URL because {}", ExceptionUtils.getStackTrace(e)); throw new UrlSigningException(e); } }
&& ResourceRequestUtil.isNotSigned(httpUriRequest.getURI()) && urlSigningService.accepts(httpUriRequest.getURI().toString())) { logger.trace("Signing request with method: {} and URI: {}", httpUriRequest.getMethod(), httpUriRequest.getURI()