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.directory.server.kerberos.shared.crypto.checksum;
21  
22  
23  import java.util.Collections;
24  import java.util.EnumMap;
25  import java.util.Map;
26  
27  import org.apache.directory.server.kerberos.shared.crypto.encryption.Aes128CtsSha1Encryption;
28  import org.apache.directory.server.kerberos.shared.crypto.encryption.Aes256CtsSha1Encryption;
29  import org.apache.directory.server.kerberos.shared.crypto.encryption.Des3CbcSha1KdEncryption;
30  import org.apache.directory.server.kerberos.shared.crypto.encryption.KeyUsage;
31  import org.apache.directory.shared.kerberos.components.Checksum;
32  import org.apache.directory.shared.kerberos.crypto.checksum.ChecksumType;
33  import org.apache.directory.shared.kerberos.exceptions.ErrorType;
34  import org.apache.directory.shared.kerberos.exceptions.KerberosException;
35  
36  
37  /**
38   * A Hashed Adapter encapsulating checksum engines for performing integrity checks.
39   *
40   * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
41   */
42  public class ChecksumHandler
43  {
44      /** A map of the default encodable class names to the encoder class names. */
45      private static final Map<ChecksumType, Class<?>> DEFAULT_CHECKSUMS;
46  
47      static
48      {
49          EnumMap<ChecksumType, Class<?>> map = new EnumMap<>( ChecksumType.class );
50  
51          map.put( ChecksumType.HMAC_MD5, HmacMd5Checksum.class );
52          map.put( ChecksumType.HMAC_SHA1_96_AES128, Aes128CtsSha1Encryption.class );
53          map.put( ChecksumType.HMAC_SHA1_96_AES256, Aes256CtsSha1Encryption.class );
54          map.put( ChecksumType.HMAC_SHA1_DES3_KD, Des3CbcSha1KdEncryption.class );
55          map.put( ChecksumType.RSA_MD5, RsaMd5Checksum.class );
56  
57          DEFAULT_CHECKSUMS = Collections.unmodifiableMap( map );
58      }
59  
60  
61      /**
62       * Calculate a checksum based on raw bytes and an (optional) key for keyed checksums.
63       *
64       * @param checksumType The type of checksum to use
65       * @param bytes The data
66       * @param key The key
67       * @param usage The key usage 
68       * @return The computed {@link Checksum}.
69       * @throws KerberosException If the checksum can't be cmputed
70       */
71      public Checksum calculateChecksum( ChecksumType checksumType, byte[] bytes, byte[] key, KeyUsage usage )
72          throws KerberosException
73      {
74          if ( !DEFAULT_CHECKSUMS.containsKey( checksumType ) )
75          {
76              throw new KerberosException( ErrorType.KDC_ERR_SUMTYPE_NOSUPP );
77          }
78  
79          ChecksumEngine digester = getEngine( checksumType );
80          return new Checksum( checksumType, digester.calculateChecksum( bytes, key, usage ) );
81      }
82  
83  
84      /**
85       * Verify a checksum by providing the raw bytes and an (optional) key for keyed checksums.
86       *
87       * @param checksum The checksum to verify
88       * @param bytes The data
89       * @param key The key
90       * @param usage The key usage 
91       * @throws KerberosException If the verification failed
92       */
93      public void verifyChecksum( Checksum checksum, byte[] bytes, byte[] key, KeyUsage usage ) throws KerberosException
94      {
95          if ( checksum == null )
96          {
97              throw new KerberosException( ErrorType.KRB_AP_ERR_INAPP_CKSUM );
98          }
99  
100         if ( !DEFAULT_CHECKSUMS.containsKey( checksum.getChecksumType() ) )
101         {
102             throw new KerberosException( ErrorType.KDC_ERR_SUMTYPE_NOSUPP );
103         }
104 
105         ChecksumType checksumType = checksum.getChecksumType();
106         ChecksumEngine digester = getEngine( checksumType );
107         Checksumared/kerberos/components/Checksum.html#Checksum">Checksum newChecksum = new Checksum( checksumType, digester.calculateChecksum( bytes, key, usage ) );
108 
109         if ( !newChecksum.equals( checksum ) )
110         {
111             throw new KerberosException( ErrorType.KRB_AP_ERR_MODIFIED );
112         }
113     }
114 
115 
116     private ChecksumEngine getEngine( ChecksumType checksumType ) throws KerberosException
117     {
118         Class<?> clazz = DEFAULT_CHECKSUMS.get( checksumType );
119 
120         if ( clazz == null )
121         {
122             throw new KerberosException( ErrorType.KDC_ERR_SUMTYPE_NOSUPP );
123         }
124 
125         try
126         {
127             return ( ChecksumEngine ) clazz.newInstance();
128         }
129         catch ( IllegalAccessException iae )
130         {
131             throw new KerberosException( ErrorType.KDC_ERR_SUMTYPE_NOSUPP, iae );
132         }
133         catch ( InstantiationException ie )
134         {
135             throw new KerberosException( ErrorType.KDC_ERR_SUMTYPE_NOSUPP, ie );
136         }
137     }
138 }