Back to home page

OSCL-LXR

 
 

    


0001 /**
0002  * Licensed to the Apache Software Foundation (ASF) under one
0003  * or more contributor license agreements.  See the NOTICE file
0004  * distributed with this work for additional information
0005  * regarding copyright ownership.  The ASF licenses this file
0006  * to you under the Apache License, Version 2.0 (the
0007  * "License"); you may not use this file except in compliance
0008  * with the License.  You may obtain a copy of the License at
0009  *
0010  *     http://www.apache.org/licenses/LICENSE-2.0
0011  *
0012  * Unless required by applicable law or agreed to in writing, software
0013  * distributed under the License is distributed on an "AS IS" BASIS,
0014  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
0015  * See the License for the specific language governing permissions and
0016  * limitations under the License.
0017  */
0018 
0019 package org.apache.hive.service;
0020 
0021 import java.security.MessageDigest;
0022 import java.security.NoSuchAlgorithmException;
0023 
0024 import org.apache.commons.codec.binary.Base64;
0025 import org.slf4j.Logger;
0026 import org.slf4j.LoggerFactory;
0027 
0028 /**
0029  * The cookie signer generates a signature based on SHA digest
0030  * and appends it to the cookie value generated at the
0031  * server side. It uses SHA digest algorithm to sign and verify signatures.
0032  */
0033 public class CookieSigner {
0034   private static final String SIGNATURE = "&s=";
0035   private static final String SHA_STRING = "SHA-256";
0036   private byte[] secretBytes;
0037   private static final Logger LOG = LoggerFactory.getLogger(CookieSigner.class);
0038 
0039   /**
0040    * Constructor
0041    * @param secret Secret Bytes
0042    */
0043   public CookieSigner(byte[] secret) {
0044     if (secret == null) {
0045       throw new IllegalArgumentException(" NULL Secret Bytes");
0046     }
0047     this.secretBytes = secret.clone();
0048   }
0049 
0050   /**
0051    * Sign the cookie given the string token as input.
0052    * @param str Input token
0053    * @return Signed token that can be used to create a cookie
0054    */
0055   public String signCookie(String str) {
0056     if (str == null || str.isEmpty()) {
0057       throw new IllegalArgumentException("NULL or empty string to sign");
0058     }
0059     String signature = getSignature(str);
0060 
0061     if (LOG.isDebugEnabled()) {
0062       LOG.debug("Signature generated for " + str + " is " + signature);
0063     }
0064     return str + SIGNATURE + signature;
0065   }
0066 
0067   /**
0068    * Verify a signed string and extracts the original string.
0069    * @param signedStr The already signed string
0070    * @return Raw Value of the string without the signature
0071    */
0072   public String verifyAndExtract(String signedStr) {
0073     int index = signedStr.lastIndexOf(SIGNATURE);
0074     if (index == -1) {
0075       throw new IllegalArgumentException("Invalid input sign: " + signedStr);
0076     }
0077     String originalSignature = signedStr.substring(index + SIGNATURE.length());
0078     String rawValue = signedStr.substring(0, index);
0079     String currentSignature = getSignature(rawValue);
0080 
0081     if (LOG.isDebugEnabled()) {
0082       LOG.debug("Signature generated for " + rawValue + " inside verify is " + currentSignature);
0083     }
0084     if (!MessageDigest.isEqual(originalSignature.getBytes(), currentSignature.getBytes())) {
0085       throw new IllegalArgumentException("Invalid sign, original = " + originalSignature +
0086         " current = " + currentSignature);
0087     }
0088     return rawValue;
0089   }
0090 
0091   /**
0092    * Get the signature of the input string based on SHA digest algorithm.
0093    * @param str Input token
0094    * @return Signed String
0095    */
0096   private String getSignature(String str) {
0097     try {
0098       MessageDigest md = MessageDigest.getInstance(SHA_STRING);
0099       md.update(str.getBytes());
0100       md.update(secretBytes);
0101       byte[] digest = md.digest();
0102       return new Base64(0).encodeToString(digest);
0103     } catch (NoSuchAlgorithmException ex) {
0104       throw new RuntimeException("Invalid SHA digest String: " + SHA_STRING +
0105         " " + ex.getMessage(), ex);
0106     }
0107   }
0108 }