001: /*
002: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
003: *
004: * This code is free software; you can redistribute it and/or modify it
005: * under the terms of the GNU General Public License version 2 only, as
006: * published by the Free Software Foundation. Sun designates this
007: * particular file as subject to the "Classpath" exception as provided
008: * by Sun in the LICENSE file that accompanied this code.
009: *
010: * This code is distributed in the hope that it will be useful, but WITHOUT
011: * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
012: * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
013: * version 2 for more details (a copy is included in the LICENSE file that
014: * accompanied this code).
015: *
016: * You should have received a copy of the GNU General Public License version
017: * 2 along with this work; if not, write to the Free Software Foundation,
018: * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
019: *
020: * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
021: * CA 95054 USA or visit www.sun.com if you need additional information or
022: * have any questions.
023: */
024:
025: /*
026: * @(#)KRBSafeBody.java 1.19 07/04/27
027: *
028: * (C) Copyright IBM Corp. 1999 All Rights Reserved.
029: * Copyright 1997 The Open Group Research Institute. All rights reserved.
030: */
031:
032: package sun.security.krb5.internal;
033:
034: import sun.security.util.*;
035: import sun.security.krb5.Asn1Exception;
036: import java.util.Vector;
037: import java.io.IOException;
038: import java.math.BigInteger;
039:
040: /**
041: * Implements the ASN.1 KRBSafeBody type.
042: *
043: * <xmp>
044: * KRB-SAFE-BODY ::= SEQUENCE {
045: * user-data [0] OCTET STRING,
046: * timestamp [1] KerberosTime OPTIONAL,
047: * usec [2] Microseconds OPTIONAL,
048: * seq-number [3] UInt32 OPTIONAL,
049: * s-address [4] HostAddress,
050: * r-address [5] HostAddress OPTIONAL
051: * }
052: * </xmp>
053: *
054: * <p>
055: * This definition reflects the Network Working Group RFC 4120
056: * specification available at
057: * <a href="http://www.ietf.org/rfc/rfc4120.txt">
058: * http://www.ietf.org/rfc/rfc4120.txt</a>.
059: */
060:
061: public class KRBSafeBody {
062: public byte[] userData = null;
063: public KerberosTime timestamp; //optional
064: public Integer usec; //optional
065: public Integer seqNumber; //optional
066: public HostAddress sAddress;
067: public HostAddress rAddress; //optional
068:
069: public KRBSafeBody(byte[] new_userData, KerberosTime new_timestamp,
070: Integer new_usec, Integer new_seqNumber,
071: HostAddress new_sAddress, HostAddress new_rAddress) {
072: if (new_userData != null) {
073: userData = new_userData.clone();
074: }
075: timestamp = new_timestamp;
076: usec = new_usec;
077: seqNumber = new_seqNumber;
078: sAddress = new_sAddress;
079: rAddress = new_rAddress;
080: }
081:
082: /**
083: * Constructs a KRBSafeBody object.
084: * @param encoding a Der-encoded data.
085: * @exception Asn1Exception if an error occurs while decoding an ASN1 encoded data.
086: * @exception IOException if an I/O error occurs while reading encoded data.
087: */
088: public KRBSafeBody(DerValue encoding) throws Asn1Exception,
089: IOException {
090: DerValue der;
091: if (encoding.getTag() != DerValue.tag_Sequence) {
092: throw new Asn1Exception(Krb5.ASN1_BAD_ID);
093: }
094: der = encoding.getData().getDerValue();
095: if ((der.getTag() & 0x1F) == 0x00) {
096: userData = der.getData().getOctetString();
097: } else
098: throw new Asn1Exception(Krb5.ASN1_BAD_ID);
099: timestamp = KerberosTime.parse(encoding.getData(), (byte) 0x01,
100: true);
101: if ((encoding.getData().peekByte() & 0x1F) == 0x02) {
102: der = encoding.getData().getDerValue();
103: usec = new Integer(der.getData().getBigInteger().intValue());
104: }
105: if ((encoding.getData().peekByte() & 0x1F) == 0x03) {
106: der = encoding.getData().getDerValue();
107: seqNumber = new Integer(der.getData().getBigInteger()
108: .intValue());
109: }
110: sAddress = HostAddress.parse(encoding.getData(), (byte) 0x04,
111: false);
112: if (encoding.getData().available() > 0)
113: rAddress = HostAddress.parse(encoding.getData(),
114: (byte) 0x05, true);
115: if (encoding.getData().available() > 0)
116: throw new Asn1Exception(Krb5.ASN1_BAD_ID);
117: }
118:
119: /**
120: * Encodes an KRBSafeBody object.
121: * @return the byte array of encoded KRBSafeBody object.
122: * @exception Asn1Exception if an error occurs while decoding an ASN1 encoded data.
123: * @exception IOException if an I/O error occurs while reading encoded data.
124: */
125: public byte[] asn1Encode() throws Asn1Exception, IOException {
126: DerOutputStream bytes = new DerOutputStream();
127: DerOutputStream temp = new DerOutputStream();
128: temp.putOctetString(userData);
129: bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT, true,
130: (byte) 0x00), temp);
131: if (timestamp != null)
132: bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT, true,
133: (byte) 0x01), timestamp.asn1Encode());
134: if (usec != null) {
135: temp = new DerOutputStream();
136: temp.putInteger(BigInteger.valueOf(usec.intValue()));
137: bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT, true,
138: (byte) 0x02), temp);
139: }
140: if (seqNumber != null) {
141: temp = new DerOutputStream();
142: // encode as an unsigned integer (UInt32)
143: temp.putInteger(BigInteger.valueOf(seqNumber.longValue()));
144: bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT, true,
145: (byte) 0x03), temp);
146: }
147: bytes.write(DerValue.createTag(DerValue.TAG_CONTEXT, true,
148: (byte) 0x04), sAddress.asn1Encode());
149: if (rAddress != null)
150: temp = new DerOutputStream();
151: temp.write(DerValue.tag_Sequence, bytes);
152: return temp.toByteArray();
153: }
154:
155: /**
156: * Parse (unmarshal) a KRBSafeBody from a DER input stream. This form
157: * parsing might be used when expanding a value which is part of
158: * a constructed sequence and uses explicitly tagged type.
159: *
160: * @exception Asn1Exception on error.
161: * @param data the Der input stream value, which contains one or more marshaled value.
162: * @param explicitTag tag number.
163: * @param optional indicates if this data field is optional
164: * @return an instance of KRBSafeBody.
165: *
166: */
167: public static KRBSafeBody parse(DerInputStream data,
168: byte explicitTag, boolean optional) throws Asn1Exception,
169: IOException {
170: if ((optional)
171: && (((byte) data.peekByte() & (byte) 0x1F) != explicitTag))
172: return null;
173: DerValue der = data.getDerValue();
174: if (explicitTag != (der.getTag() & (byte) 0x1F))
175: throw new Asn1Exception(Krb5.ASN1_BAD_ID);
176: else {
177: DerValue subDer = der.getData().getDerValue();
178: return new KRBSafeBody(subDer);
179: }
180: }
181:
182: }
|