View Javadoc

1   /**
2    * Licensed to the Apache Software Foundation (ASF) under one
3    * or more contributor license agreements. See the NOTICE file
4    * distributed with this work for additional information
5    * regarding copyright ownership. The ASF licenses this file
6    * to you under the Apache License, Version 2.0 (the
7    * "License"); you may not use this file except in compliance
8    * with the License. You may obtain a copy of the License at
9    *
10   * http://www.apache.org/licenses/LICENSE-2.0
11   *
12   * Unless required by applicable law or agreed to in writing,
13   * software distributed under the License is distributed on an
14   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15   * KIND, either express or implied. See the License for the
16   * specific language governing permissions and limitations
17   * under the License.
18   */
19  
20  package org.apache.ws.security.conversation.dkalgo;
21  
22  /**
23   *
24   <pre>
25   P_SHA-1 DEFINITION
26   ==================
27   <b>P_SHA-1(secret, seed)</b> =
28   HMAC_SHA-1(secret, A(1) + seed) +
29   HMAC_SHA-1(secret, A(2) + seed) +
30   HMAC_SHA-1(secret, A(3) + seed) + ...
31   <i>Where + indicates concatenation.</i>
32   <br>
33   A() is defined as:
34   A(0) = seed
35   A(i) = HMAC_SHA-1(secret, A(i-1))
36   <br>
37   <i>Source : RFC 2246 - The TLS Protocol Version 1.0
38   Section 5. HMAC and the pseudorandom function</i>
39   </pre>
40   *
41   * @author Ruchith Fernando
42   */
43  
44  import javax.crypto.Mac;
45  import javax.crypto.spec.SecretKeySpec;
46  
47  import org.apache.ws.security.conversation.ConversationException;
48  
49  public class P_SHA1 implements DerivationAlgorithm {
50  
51      public byte[] createKey(byte[] secret, byte[] seed, int offset,
52              long length) throws ConversationException {
53          try {
54              Mac mac = Mac.getInstance("HmacSHA1");
55  
56              byte[] tempBytes = P_hash(secret, seed, mac, (offset + (int) length));
57  
58              byte[] key = new byte[(int) length];
59  
60              for (int i = 0; i < key.length; i++) {
61                  key[i] = tempBytes[i + offset];
62              }
63  
64              return key;
65          } catch (Exception ex) {
66              throw new ConversationException("errorInKeyDerivation", null, ex);
67          }
68      }
69      
70      /**
71       * From WSUsernameToken  :-)
72       *
73       * @param secret
74       * @param seed
75       * @param mac
76       * @param required
77       * @return
78       * @throws java.lang.Exception
79       */
80      private static byte[] P_hash(byte[] secret, byte[] seed, Mac mac, int required) throws Exception {
81          byte[] out = new byte[required];
82          int offset = 0, tocpy;
83          byte[] a, tmp;
84          a = seed;
85          while (required > 0) {
86              SecretKeySpec key = new SecretKeySpec(secret, "HMACSHA1");
87              mac.init(key);
88              mac.update(a);
89              a = mac.doFinal();
90              mac.reset();
91              mac.init(key);
92              mac.update(a);
93              mac.update(seed);
94              tmp = mac.doFinal();
95              tocpy = min(required, tmp.length);
96              System.arraycopy(tmp, 0, out, offset, tocpy);
97              offset += tocpy;
98              required -= tocpy;
99          }
100         return out;
101     }
102 
103     private static int min(int a, int b) {
104         return (a > b) ? b : a;
105     }
106 
107 }