/* * Copyright (C) 2011 Citrix Systems, Inc. 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. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License 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.cloud.bridge.util; import javax.crypto.Mac; import javax.crypto.spec.SecretKeySpec; import org.apache.axis2.AxisFault; import org.apache.commons.codec.binary.Base64; import org.apache.log4j.Logger; /** * Both the SOAP code and the DIME implementation in the REST servlet need * this authentication functionality. */ public class S3SoapAuth { protected final static Logger logger = Logger.getLogger(S3SoapAuth.class); public S3SoapAuth() { } public static void verifySignature( String givenSignature, String operation, String timestamp, String accessKey, String secretKey ) throws AxisFault { // -> calculate RFC 2104 HMAC-SHA1 digest over the constructed string String signString = "AmazonS3" + operation + timestamp; String calSig = calculateRFC2104HMAC( signString, secretKey ); if ( null == calSig || !givenSignature.equals( calSig )) { logger.error( "Signature mismatch, [" + givenSignature + "] [" + calSig + "] over [" + signString + "]" ); throw new AxisFault( "Authentication signature mismatch on AccessKey: [" + accessKey + "] [" + operation + "]", "Client.SignatureDoesNotMatch" ); } } /** * Create a signature by the following method: * new String( Base64( SHA1( key, byte array ))) * * @param signIt - the data to generate a keyed HMAC over * @param secretKey - the user's unique key for the HMAC operation * @return String - the recalculated string */ private static String calculateRFC2104HMAC( String signIt, String secretKey ) { String result = null; try { SecretKeySpec key = new SecretKeySpec( secretKey.getBytes(), "HmacSHA1" ); Mac hmacSha1 = Mac.getInstance( "HmacSHA1" ); hmacSha1.init( key ); byte [] rawHmac = hmacSha1.doFinal( signIt.getBytes()); result = new String( Base64.encodeBase64( rawHmac )); } catch( Exception e ) { logger.error( "Failed to generate keyed HMAC on soap request: " + e.getMessage()); return null; } return result.trim(); } }