2 * Copyright (c) 2010-2023 Contributors to the openHAB project
4 * See the NOTICE file(s) distributed with this work for additional
7 * This program and the accompanying materials are made available under the
8 * terms of the Eclipse Public License 2.0 which is available at
9 * http://www.eclipse.org/legal/epl-2.0
11 * SPDX-License-Identifier: EPL-2.0
13 package org.openhab.binding.folderwatcher.internal.api.auth;
16 import java.util.Date;
19 import org.eclipse.jdt.annotation.NonNullByDefault;
20 import org.openhab.binding.folderwatcher.internal.api.exception.AuthException;
21 import org.openhab.binding.folderwatcher.internal.api.util.BinaryUtils;
22 import org.openhab.binding.folderwatcher.internal.api.util.HttpUtilException;
25 * The {@link AWS4SignerForAuthorizationHeader} class contains methods for AWS S3 API authentication using HTTP(S)
28 * Based on offical AWS example {@see https://docs.aws.amazon.com/AmazonS3/latest/API/sig-v4-examples-using-sdks.html}
30 * @author Alexandr Salamatov - Initial contribution
33 public class AWS4SignerForAuthorizationHeader extends AWS4SignerBase {
35 public AWS4SignerForAuthorizationHeader(URL endpointUrl, String httpMethod, String serviceName, String regionName) {
36 super(endpointUrl, httpMethod, serviceName, regionName);
39 public String computeSignature(Map<String, String> headers, Map<String, String> queryParameters, String bodyHash,
40 String awsAccessKey, String awsSecretKey) throws AuthException, HttpUtilException {
41 Date now = new Date();
42 String dateTimeStamp = dateTimeFormat.format(now);
43 headers.put("x-amz-date", dateTimeStamp);
44 String hostHeader = endpointUrl.getHost();
45 int port = endpointUrl.getPort();
47 hostHeader.concat(":" + Integer.toString(port));
49 headers.put("Host", hostHeader);
51 String canonicalizedHeaderNames = getCanonicalizeHeaderNames(headers);
52 String canonicalizedHeaders = getCanonicalizedHeaderString(headers);
53 String canonicalizedQueryParameters = getCanonicalizedQueryString(queryParameters);
54 String canonicalRequest = getCanonicalRequest(endpointUrl, httpMethod, canonicalizedQueryParameters,
55 canonicalizedHeaderNames, canonicalizedHeaders, bodyHash);
56 String dateStamp = dateStampFormat.format(now);
57 String scope = dateStamp + "/" + regionName + "/" + serviceName + "/" + TERMINATOR;
58 String stringToSign = getStringToSign(SCHEME, ALGORITHM, dateTimeStamp, scope, canonicalRequest);
59 byte[] kSecret = (SCHEME + awsSecretKey).getBytes();
60 byte[] kDate = sign(dateStamp, kSecret, "HmacSHA256");
61 byte[] kRegion = sign(regionName, kDate, "HmacSHA256");
62 byte[] kService = sign(serviceName, kRegion, "HmacSHA256");
63 byte[] kSigning = sign(TERMINATOR, kService, "HmacSHA256");
64 byte[] signature = sign(stringToSign, kSigning, "HmacSHA256");
65 String credentialsAuthorizationHeader = "Credential=" + awsAccessKey + "/" + scope;
66 String signedHeadersAuthorizationHeader = "SignedHeaders=" + canonicalizedHeaderNames;
67 String signatureAuthorizationHeader = "Signature=" + BinaryUtils.toHex(signature);
68 return SCHEME + "-" + ALGORITHM + " " + credentialsAuthorizationHeader + ", " + signedHeadersAuthorizationHeader
69 + ", " + signatureAuthorizationHeader;