| /* | |
| * 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(); | |
| } | |
| } |