57 * This definition reflects the Network Working Group RFC 4120 |
58 * This definition reflects the Network Working Group RFC 4120 |
58 * specification available at |
59 * specification available at |
59 * <a href="http://www.ietf.org/rfc/rfc4120.txt"> |
60 * <a href="http://www.ietf.org/rfc/rfc4120.txt"> |
60 * http://www.ietf.org/rfc/rfc4120.txt</a>. |
61 * http://www.ietf.org/rfc/rfc4120.txt</a>. |
61 */ |
62 */ |
62 |
|
63 public class KDCRep { |
63 public class KDCRep { |
64 public Realm crealm; |
64 |
65 public PrincipalName cname; |
65 public Realm crealm; |
66 public Ticket ticket; |
66 public PrincipalName cname; |
67 public EncryptedData encPart; |
67 public Ticket ticket; |
68 public EncKDCRepPart encKDCRepPart; //not part of ASN.1 encoding |
68 public EncryptedData encPart; |
69 |
69 public EncKDCRepPart encKDCRepPart; //not part of ASN.1 encoding |
70 private int pvno; |
70 private int pvno; |
71 private int msgType; |
71 private int msgType; |
72 private PAData[] pAData = null; //optional |
72 private PAData[] pAData = null; //optional |
73 private boolean DEBUG = Krb5.DEBUG; |
73 private boolean DEBUG = Krb5.DEBUG; |
74 |
74 |
75 public KDCRep( |
75 public KDCRep( |
76 PAData[] new_pAData, |
76 PAData[] new_pAData, |
77 Realm new_crealm, |
77 Realm new_crealm, |
78 PrincipalName new_cname, |
78 PrincipalName new_cname, |
79 Ticket new_ticket, |
79 Ticket new_ticket, |
80 EncryptedData new_encPart, |
80 EncryptedData new_encPart, |
81 int req_type |
81 int req_type) throws IOException { |
82 ) throws IOException { |
82 pvno = Krb5.PVNO; |
83 pvno = Krb5.PVNO; |
83 msgType = req_type; |
84 msgType = req_type; |
84 if (new_pAData != null) { |
85 if (new_pAData != null) { |
85 pAData = new PAData[new_pAData.length]; |
86 pAData = new PAData[new_pAData.length]; |
86 for (int i = 0; i < new_pAData.length; i++) { |
87 for (int i = 0; i < new_pAData.length; i++) { |
87 if (new_pAData[i] == null) { |
88 if (new_pAData[i] == null) { |
88 throw new IOException("Cannot create a KDCRep"); |
89 throw new IOException("Cannot create a KDCRep"); |
89 } else { |
90 } else { |
90 pAData[i] = (PAData) new_pAData[i].clone(); |
91 pAData[i] = (PAData)new_pAData[i].clone(); |
|
92 } |
|
93 } |
|
94 } |
91 } |
95 crealm = new_crealm; |
92 } |
96 cname = new_cname; |
93 } |
97 ticket = new_ticket; |
94 crealm = new_crealm; |
98 encPart = new_encPart; |
95 cname = new_cname; |
99 } |
96 ticket = new_ticket; |
100 |
97 encPart = new_encPart; |
101 public KDCRep() { |
98 } |
102 } |
99 |
103 |
100 public KDCRep() { |
104 public KDCRep(byte[] data, int req_type) throws Asn1Exception, KrbApErrException, RealmException, IOException { |
101 } |
105 init(new DerValue(data), req_type); |
102 |
106 } |
103 public KDCRep(byte[] data, int req_type) throws Asn1Exception, |
107 |
104 KrbApErrException, RealmException, IOException { |
108 public KDCRep(DerValue encoding, int req_type) throws Asn1Exception, |
105 init(new DerValue(data), req_type); |
109 RealmException, KrbApErrException, IOException { |
106 } |
110 init(encoding, req_type); |
107 |
111 } |
108 public KDCRep(DerValue encoding, int req_type) throws Asn1Exception, |
|
109 RealmException, KrbApErrException, IOException { |
|
110 init(encoding, req_type); |
|
111 } |
112 |
112 |
113 /* |
113 /* |
114 // Not used? Don't know what keyusage to use here %%% |
114 // Not used? Don't know what keyusage to use here %%% |
115 |
115 public void decrypt(EncryptionKey key) throws Asn1Exception, |
116 public void decrypt(EncryptionKey key) throws Asn1Exception, |
116 IOException, KrbException, RealmException { |
117 IOException, KrbException, RealmException { |
117 encKDCRepPart = new EncKDCRepPart(encPart.decrypt(key), msgType); |
118 encKDCRepPart = new EncKDCRepPart(encPart.decrypt(key), |
118 } |
119 msgType); |
119 */ |
120 } |
120 /** |
121 */ |
121 * Initializes an KDCRep object. |
122 |
122 * |
123 /** |
123 * @param encoding a single DER-encoded value. |
124 * Initializes an KDCRep object. |
124 * @param req_type reply message type. |
125 * |
125 * @exception Asn1Exception if an error occurs while decoding an ASN1 encoded data. |
126 * @param encoding a single DER-encoded value. |
126 * @exception IOException if an I/O error occurs while reading encoded data. |
127 * @param req_type reply message type. |
127 * @exception RealmException if an error occurs while constructing |
128 * @exception Asn1Exception if an error occurs while decoding an ASN1 encoded data. |
128 * a Realm object from DER-encoded data. |
129 * @exception IOException if an I/O error occurs while reading encoded data. |
129 * @exception KrbApErrException if the value read from the DER-encoded |
130 * @exception RealmException if an error occurs while constructing a Realm object from DER-encoded data. |
130 * data stream does not match the pre-defined value. |
131 * @exception KrbApErrException if the value read from the DER-encoded data stream does not match the pre-defined value. |
131 * |
132 * |
132 */ |
133 */ |
133 protected void init(DerValue encoding, int req_type) |
134 protected void init(DerValue encoding, int req_type) |
|
135 throws Asn1Exception, RealmException, IOException, |
134 throws Asn1Exception, RealmException, IOException, |
136 KrbApErrException { |
135 KrbApErrException { |
137 DerValue der, subDer; |
136 DerValue der, subDer; |
138 if ((encoding.getTag() & 0x1F) != req_type) { |
137 if ((encoding.getTag() & 0x1F) != req_type) { |
139 if (DEBUG) { |
138 if (DEBUG) { |
140 System.out.println(">>> KDCRep: init() " + |
139 System.out.println(">>> KDCRep: init() " + |
141 "encoding tag is " + |
140 "encoding tag is " + |
142 encoding.getTag() + |
141 encoding.getTag() + |
143 " req type is " + req_type); |
142 " req type is " + req_type); |
144 } |
143 } |
145 throw new Asn1Exception(Krb5.ASN1_BAD_ID); |
144 throw new Asn1Exception(Krb5.ASN1_BAD_ID); |
146 } |
145 } |
147 der = encoding.getData().getDerValue(); |
146 der = encoding.getData().getDerValue(); |
148 if (der.getTag() != DerValue.tag_Sequence) { |
147 if (der.getTag() != DerValue.tag_Sequence) { |
149 throw new Asn1Exception(Krb5.ASN1_BAD_ID); |
148 throw new Asn1Exception(Krb5.ASN1_BAD_ID); |
150 } |
149 } |
|
150 subDer = der.getData().getDerValue(); |
|
151 if ((subDer.getTag() & 0x1F) == 0x00) { |
|
152 pvno = subDer.getData().getBigInteger().intValue(); |
|
153 if (pvno != Krb5.PVNO) { |
|
154 throw new KrbApErrException(Krb5.KRB_AP_ERR_BADVERSION); |
|
155 } |
|
156 } else { |
|
157 throw new Asn1Exception(Krb5.ASN1_BAD_ID); |
|
158 } |
|
159 subDer = der.getData().getDerValue(); |
|
160 if ((subDer.getTag() & 0x1F) == 0x01) { |
|
161 msgType = subDer.getData().getBigInteger().intValue(); |
|
162 if (msgType != req_type) { |
|
163 throw new KrbApErrException(Krb5.KRB_AP_ERR_MSG_TYPE); |
|
164 } |
|
165 } else { |
|
166 throw new Asn1Exception(Krb5.ASN1_BAD_ID); |
|
167 } |
|
168 if ((der.getData().peekByte() & 0x1F) == 0x02) { |
151 subDer = der.getData().getDerValue(); |
169 subDer = der.getData().getDerValue(); |
152 if ((subDer.getTag() & 0x1F) == 0x00) { |
170 DerValue[] padata = subDer.getData().getSequence(1); |
153 pvno = subDer.getData().getBigInteger().intValue(); |
171 pAData = new PAData[padata.length]; |
154 if (pvno != Krb5.PVNO) |
172 for (int i = 0; i < padata.length; i++) { |
155 throw new KrbApErrException(Krb5.KRB_AP_ERR_BADVERSION); |
173 pAData[i] = new PAData(padata[i]); |
156 } else { |
174 } |
157 throw new Asn1Exception(Krb5.ASN1_BAD_ID); |
175 } else { |
158 } |
176 pAData = null; |
159 subDer = der.getData().getDerValue(); |
177 } |
160 if ((subDer.getTag() & 0x1F) == 0x01) { |
178 crealm = Realm.parse(der.getData(), (byte) 0x03, false); |
161 msgType = subDer.getData().getBigInteger().intValue(); |
179 cname = PrincipalName.parse(der.getData(), (byte) 0x04, false); |
162 if (msgType != req_type) { |
180 ticket = Ticket.parse(der.getData(), (byte) 0x05, false); |
163 throw new KrbApErrException(Krb5.KRB_AP_ERR_MSG_TYPE); |
181 encPart = EncryptedData.parse(der.getData(), (byte) 0x06, false); |
164 } |
182 if (der.getData().available() > 0) { |
165 } else { |
183 throw new Asn1Exception(Krb5.ASN1_BAD_ID); |
166 throw new Asn1Exception(Krb5.ASN1_BAD_ID); |
184 } |
167 } |
185 } |
168 if ((der.getData().peekByte() & 0x1F) == 0x02) { |
186 |
169 subDer = der.getData().getDerValue(); |
187 /** |
170 DerValue[] padata = subDer.getData().getSequence(1); |
188 * Encodes this object to a byte array. |
171 pAData = new PAData[padata.length]; |
189 * @return byte array of encoded APReq object. |
172 for (int i = 0; i < padata.length; i++) { |
190 * @exception Asn1Exception if an error occurs while decoding an ASN1 encoded data. |
173 pAData[i] = new PAData(padata[i]); |
191 * @exception IOException if an I/O error occurs while reading encoded data. |
174 } |
192 * |
175 } else { |
193 */ |
176 pAData = null; |
194 public byte[] asn1Encode() throws Asn1Exception, IOException { |
177 } |
195 |
178 crealm = Realm.parse(der.getData(), (byte)0x03, false); |
196 DerOutputStream bytes = new DerOutputStream(); |
179 cname = PrincipalName.parse(der.getData(), (byte)0x04, false); |
197 DerOutputStream temp = new DerOutputStream(); |
180 ticket = Ticket.parse(der.getData(), (byte)0x05, false); |
198 temp.putInteger(BigInteger.valueOf(pvno)); |
181 encPart = EncryptedData.parse(der.getData(), (byte)0x06, false); |
199 bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT, |
182 if (der.getData().available() > 0) { |
200 true, (byte) 0x00), temp); |
183 throw new Asn1Exception(Krb5.ASN1_BAD_ID); |
201 temp = new DerOutputStream(); |
184 } |
202 temp.putInteger(BigInteger.valueOf(msgType)); |
185 } |
203 bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT, |
186 |
204 true, (byte) 0x01), temp); |
187 |
205 if (pAData != null && pAData.length > 0) { |
188 /** |
206 DerOutputStream padata_stream = new DerOutputStream(); |
189 * Encodes this object to a byte array. |
207 for (int i = 0; i < pAData.length; i++) { |
190 * @return byte array of encoded APReq object. |
208 padata_stream.write(pAData[i].asn1Encode()); |
191 * @exception Asn1Exception if an error occurs while decoding an ASN1 encoded data. |
209 } |
192 * @exception IOException if an I/O error occurs while reading encoded data. |
|
193 * |
|
194 */ |
|
195 public byte[] asn1Encode() throws Asn1Exception, IOException { |
|
196 |
|
197 DerOutputStream bytes = new DerOutputStream(); |
|
198 DerOutputStream temp = new DerOutputStream(); |
|
199 temp.putInteger(BigInteger.valueOf(pvno)); |
|
200 bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte)0x00), temp); |
|
201 temp = new DerOutputStream(); |
210 temp = new DerOutputStream(); |
202 temp.putInteger(BigInteger.valueOf(msgType)); |
211 temp.write(DerValue.tag_SequenceOf, padata_stream); |
203 bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte)0x01), temp); |
212 bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT, |
204 if (pAData != null && pAData.length > 0) { |
213 true, (byte) 0x02), temp); |
205 DerOutputStream padata_stream = new DerOutputStream(); |
214 } |
206 for (int i = 0; i < pAData.length; i++) { |
215 bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT, |
207 padata_stream.write(pAData[i].asn1Encode()); |
216 true, (byte) 0x03), crealm.asn1Encode()); |
208 } |
217 bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT, |
209 temp = new DerOutputStream(); |
218 true, (byte) 0x04), cname.asn1Encode()); |
210 temp.write(DerValue.tag_SequenceOf, padata_stream); |
219 bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT, |
211 bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte)0x02), temp); |
220 true, (byte) 0x05), ticket.asn1Encode()); |
212 } |
221 bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT, |
213 bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte)0x03), crealm.asn1Encode()); |
222 true, (byte) 0x06), encPart.asn1Encode()); |
214 bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte)0x04), cname.asn1Encode()); |
223 temp = new DerOutputStream(); |
215 bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte)0x05), ticket.asn1Encode()); |
224 temp.write(DerValue.tag_Sequence, bytes); |
216 bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT, true, (byte)0x06), encPart.asn1Encode()); |
225 return temp.toByteArray(); |
217 temp = new DerOutputStream(); |
226 } |
218 temp.write(DerValue.tag_Sequence, bytes); |
|
219 return temp.toByteArray(); |
|
220 } |
|
221 } |
227 } |