1 /*
2  * Copyright (c) 2000, 2012, Oracle and/or its affiliates. All rights reserved.
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * This code is free software; you can redistribute it and/or modify it
6  * under the terms of the GNU General Public License version 2 only, as
7  * published by the Free Software Foundation.  Oracle designates this
8  * particular file as subject to the "Classpath" exception as provided
9  * by Oracle in the LICENSE file that accompanied this code.
10  *
11  * This code is distributed in the hope that it will be useful, but WITHOUT
12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
14  * version 2 for more details (a copy is included in the LICENSE file that
15  * accompanied this code).
16  *
17  * You should have received a copy of the GNU General Public License version
18  * 2 along with this work; if not, write to the Free Software Foundation,
19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20  *
21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22  * or visit www.oracle.com if you need additional information or have any
23  * questions.
24  */
25 
26 /*
27  *
28  *  (C) Copyright IBM Corp. 1999 All Rights Reserved.
29  *  Copyright 1997 The Open Group Research Institute.  All rights reserved.
30  */
31 
32 package sun.security.krb5;
33 
34 import sun.security.krb5.EncryptionKey;
35 import sun.security.krb5.internal.*;
36 import sun.security.krb5.internal.crypto.*;
37 import java.io.IOException;
38 
39 class KrbSafe extends KrbAppMessage {
40 
41     private byte[] obuf;
42     private byte[] userData;
43 
KrbSafe(byte[] userData, Credentials creds, EncryptionKey subKey, KerberosTime timestamp, SeqNumber seqNumber, HostAddress saddr, HostAddress raddr )44     public KrbSafe(byte[] userData,
45                    Credentials creds,
46                    EncryptionKey subKey,
47                    KerberosTime timestamp,
48                    SeqNumber seqNumber,
49                    HostAddress saddr,
50                    HostAddress raddr
51                    )  throws KrbException, IOException {
52         EncryptionKey reqKey = null;
53         if (subKey != null)
54             reqKey = subKey;
55         else
56             reqKey = creds.key;
57 
58         obuf = mk_safe(userData,
59                        reqKey,
60                        timestamp,
61                        seqNumber,
62                        saddr,
63                        raddr
64                        );
65     }
66 
KrbSafe(byte[] msg, Credentials creds, EncryptionKey subKey, SeqNumber seqNumber, HostAddress saddr, HostAddress raddr, boolean timestampRequired, boolean seqNumberRequired )67     public KrbSafe(byte[] msg,
68                    Credentials creds,
69                    EncryptionKey subKey,
70                    SeqNumber seqNumber,
71                    HostAddress saddr,
72                    HostAddress raddr,
73                    boolean timestampRequired,
74                    boolean seqNumberRequired
75                    )  throws KrbException, IOException {
76 
77         KRBSafe krb_safe = new KRBSafe(msg);
78 
79         EncryptionKey reqKey = null;
80         if (subKey != null)
81             reqKey = subKey;
82         else
83             reqKey = creds.key;
84 
85         userData = rd_safe(
86                            krb_safe,
87                            reqKey,
88                            seqNumber,
89                            saddr,
90                            raddr,
91                            timestampRequired,
92                            seqNumberRequired,
93                            creds.client
94                            );
95     }
96 
getMessage()97     public byte[] getMessage() {
98         return obuf;
99     }
100 
getData()101     public byte[] getData() {
102         return userData;
103     }
104 
mk_safe(byte[] userData, EncryptionKey key, KerberosTime timestamp, SeqNumber seqNumber, HostAddress sAddress, HostAddress rAddress )105     private  byte[] mk_safe(byte[] userData,
106                             EncryptionKey key,
107                             KerberosTime timestamp,
108                             SeqNumber seqNumber,
109                             HostAddress sAddress,
110                             HostAddress rAddress
111                             ) throws Asn1Exception, IOException, KdcErrException,
112                             KrbApErrException, KrbCryptoException {
113 
114                                 Integer usec = null;
115                                 Integer seqno = null;
116 
117                                 if (timestamp != null)
118                                 usec = timestamp.getMicroSeconds();
119 
120                                 if (seqNumber != null) {
121                                     seqno = seqNumber.current();
122                                     seqNumber.step();
123                                 }
124 
125                                 KRBSafeBody krb_safeBody =
126                                 new KRBSafeBody(userData,
127                                                 timestamp,
128                                                 usec,
129                                                 seqno,
130                                                 sAddress,
131                                                 rAddress
132                                                 );
133 
134                                 byte[] temp = krb_safeBody.asn1Encode();
135                                 Checksum cksum = new Checksum(
136                                     Checksum.SAFECKSUMTYPE_DEFAULT,
137                                     temp,
138                                     key,
139                                     KeyUsage.KU_KRB_SAFE_CKSUM
140                                     );
141 
142                                 KRBSafe krb_safe = new KRBSafe(krb_safeBody, cksum);
143 
144                                 temp = krb_safe.asn1Encode();
145 
146                                 return krb_safe.asn1Encode();
147                             }
148 
rd_safe(KRBSafe krb_safe, EncryptionKey key, SeqNumber seqNumber, HostAddress sAddress, HostAddress rAddress, boolean timestampRequired, boolean seqNumberRequired, PrincipalName cname )149     private byte[] rd_safe(KRBSafe krb_safe,
150                            EncryptionKey key,
151                            SeqNumber seqNumber,
152                            HostAddress sAddress,
153                            HostAddress rAddress,
154                            boolean timestampRequired,
155                            boolean seqNumberRequired,
156                            PrincipalName cname
157                            ) throws Asn1Exception, KdcErrException,
158                            KrbApErrException, IOException, KrbCryptoException {
159 
160                                byte[] temp = krb_safe.safeBody.asn1Encode();
161 
162                                if (!krb_safe.cksum.verifyKeyedChecksum(temp, key,
163                                    KeyUsage.KU_KRB_SAFE_CKSUM)) {
164                                        throw new KrbApErrException(
165                                            Krb5.KRB_AP_ERR_MODIFIED);
166                                }
167 
168                                check(krb_safe.safeBody.timestamp,
169                                      krb_safe.safeBody.usec,
170                                      krb_safe.safeBody.seqNumber,
171                                      krb_safe.safeBody.sAddress,
172                                      krb_safe.safeBody.rAddress,
173                                      seqNumber,
174                                      sAddress,
175                                      rAddress,
176                                      timestampRequired,
177                                      seqNumberRequired,
178                                      cname
179                                      );
180 
181                                return krb_safe.safeBody.userData;
182                            }
183 }
184