/* * Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */ /* * * (C) Copyright IBM Corp. 1999 All Rights Reserved. * Copyright 1997 The Open Group Research Institute. All rights reserved. */ package sun.security.krb5.internal; import java.io.ObjectOutputStream; import sun.security.krb5.PrincipalName; import sun.security.krb5.Checksum; import sun.security.krb5.Asn1Exception; import sun.security.krb5.Realm; import sun.security.krb5.RealmException; import sun.security.util.*; import java.io.IOException; import java.io.ObjectInputStream; import java.math.BigInteger; import java.util.ArrayList; import java.util.Arrays; import java.util.List; import sun.security.krb5.internal.util.KerberosString; /** * Implements the ASN.1 KRBError type. * *
* This definition reflects the Network Working Group RFC 4120
* specification available at
*
* http://www.ietf.org/rfc/rfc4120.txt.
*/
public class KRBError implements java.io.Serializable {
static final long serialVersionUID = 3643809337475284503L;
private int pvno;
private int msgType;
private KerberosTime cTime; //optional
private Integer cuSec; //optional
private KerberosTime sTime;
private Integer suSec;
private int errorCode;
private Realm crealm; //optional
private PrincipalName cname; //optional
private Realm realm;
private PrincipalName sname;
private String eText; //optional
private byte[] eData; //optional
private Checksum eCksum; //optional
private PAData[] pa; // PA-DATA in eData
private static boolean DEBUG = Krb5.DEBUG;
private void readObject(ObjectInputStream is)
throws IOException, ClassNotFoundException {
try {
init(new DerValue((byte[])is.readObject()));
parseEData(eData);
} catch (Exception e) {
throw new IOException(e);
}
}
private void writeObject(ObjectOutputStream os)
throws IOException {
try {
os.writeObject(asn1Encode());
} catch (Exception e) {
throw new IOException(e);
}
}
public KRBError(
APOptions new_apOptions,
KerberosTime new_cTime,
Integer new_cuSec,
KerberosTime new_sTime,
Integer new_suSec,
int new_errorCode,
Realm new_crealm,
PrincipalName new_cname,
Realm new_realm,
PrincipalName new_sname,
String new_eText,
byte[] new_eData
) throws IOException, Asn1Exception {
pvno = Krb5.PVNO;
msgType = Krb5.KRB_ERROR;
cTime = new_cTime;
cuSec = new_cuSec;
sTime = new_sTime;
suSec = new_suSec;
errorCode = new_errorCode;
crealm = new_crealm;
cname = new_cname;
realm = new_realm;
sname = new_sname;
eText = new_eText;
eData = new_eData;
parseEData(eData);
}
public KRBError(
APOptions new_apOptions,
KerberosTime new_cTime,
Integer new_cuSec,
KerberosTime new_sTime,
Integer new_suSec,
int new_errorCode,
Realm new_crealm,
PrincipalName new_cname,
Realm new_realm,
PrincipalName new_sname,
String new_eText,
byte[] new_eData,
Checksum new_eCksum
) throws IOException, Asn1Exception {
pvno = Krb5.PVNO;
msgType = Krb5.KRB_ERROR;
cTime = new_cTime;
cuSec = new_cuSec;
sTime = new_sTime;
suSec = new_suSec;
errorCode = new_errorCode;
crealm = new_crealm;
cname = new_cname;
realm = new_realm;
sname = new_sname;
eText = new_eText;
eData = new_eData;
eCksum = new_eCksum;
parseEData(eData);
}
public KRBError(byte[] data) throws Asn1Exception,
RealmException, KrbApErrException, IOException {
init(new DerValue(data));
parseEData(eData);
}
public KRBError(DerValue encoding) throws Asn1Exception,
RealmException, KrbApErrException, IOException {
init(encoding);
showDebug();
parseEData(eData);
}
/*
* Attention:
*
* According to RFC 4120, e-data field in a KRB-ERROR message is
* a METHOD-DATA when errorCode is KDC_ERR_PREAUTH_REQUIRED,
* and application-specific otherwise (The RFC suggests using
* TYPED-DATA).
*
* Hence, the ideal procedure to parse e-data should look like:
*
* if (errorCode is KDC_ERR_PREAUTH_REQUIRED) {
* parse as METHOD-DATA
* } else {
* try parsing as TYPED-DATA
* }
*
* Unfortunately, we know that some implementations also use the
* METHOD-DATA format for errorcode KDC_ERR_PREAUTH_FAILED, and
* do not use the TYPED-DATA for other errorcodes (say,
* KDC_ERR_CLIENT_REVOKED).
*/
// parse the edata field
private void parseEData(byte[] data) throws IOException {
if (data == null) {
return;
}
// We need to parse eData as METHOD-DATA for both errorcodes.
if (errorCode == Krb5.KDC_ERR_PREAUTH_REQUIRED
|| errorCode == Krb5.KDC_ERR_PREAUTH_FAILED) {
try {
// RFC 4120 does not guarantee that eData is METHOD-DATA when
// errorCode is KDC_ERR_PREAUTH_FAILED. Therefore, the parse
// may fail.
parsePAData(data);
} catch (Exception e) {
if (DEBUG) {
System.out.println("Unable to parse eData field of KRB-ERROR:\n" +
new sun.misc.HexDumpEncoder().encodeBuffer(data));
}
IOException ioe = new IOException(
"Unable to parse eData field of KRB-ERROR");
ioe.initCause(e);
throw ioe;
}
} else {
if (DEBUG) {
System.out.println("Unknown eData field of KRB-ERROR:\n" +
new sun.misc.HexDumpEncoder().encodeBuffer(data));
}
}
}
/**
* Try parsing the data as a sequence of PA-DATA.
* @param data the data block
*/
private void parsePAData(byte[] data)
throws IOException, Asn1Exception {
DerValue derPA = new DerValue(data);
List