package org.apache.kerberos.kerb.codec.pac; import org.apache.kerberos.kerb.KrbException; import org.apache.kerberos.kerb.crypto.CheckSumHandler; import org.apache.kerberos.kerb.spec.common.CheckSum; import org.apache.kerberos.kerb.spec.common.KeyUsage; import java.io.ByteArrayInputStream; import java.io.DataInputStream; import java.io.IOException; public class Pac { private PacLogonInfo logonInfo; private PacCredentialType credentialType; private PacSignature serverSignature; private PacSignature kdcSignature; public Pac(byte[] data, byte[] key) throws KrbException { byte[] checksumData = data.clone(); try { PacDataInputStream pacStream = new PacDataInputStream(new DataInputStream( new ByteArrayInputStream(data))); if(data.length <= 8) throw new IOException("pac.token.empty"); int bufferCount = pacStream.readInt(); int version = pacStream.readInt(); if(version != PacConstants.PAC_VERSION) { Object[] args = new Object[]{version}; throw new IOException("pac.version.invalid"); } for(int bufferIndex = 0; bufferIndex < bufferCount; bufferIndex++) { int bufferType = pacStream.readInt(); int bufferSize = pacStream.readInt(); long bufferOffset = pacStream.readLong(); byte[] bufferData = new byte[bufferSize]; System.arraycopy(data, (int)bufferOffset, bufferData, 0, bufferSize); switch (bufferType) { case PacConstants.LOGON_INFO: // PAC Credential Information logonInfo = new PacLogonInfo(bufferData); break; case PacConstants.CREDENTIAL_TYPE: // PAC Credential Type credentialType = new PacCredentialType(bufferData); break; case PacConstants.SERVER_CHECKSUM: // PAC Server Signature serverSignature = new PacSignature(bufferData); // Clear signature from checksum copy for(int i = 0; i < bufferSize; i++) checksumData[(int)bufferOffset + 4 + i] = 0; break; case PacConstants.PRIVSVR_CHECKSUM: // PAC KDC Signature kdcSignature = new PacSignature(bufferData); // Clear signature from checksum copy for(int i = 0; i < bufferSize; i++) checksumData[(int)bufferOffset + 4 + i] = 0; break; default: } } } catch(IOException e) { throw new KrbException("pac.token.malformed", e); } CheckSum checksum = new CheckSum(serverSignature.getType(), serverSignature.getChecksum()); if (! CheckSumHandler.verifyWithKey(checksum, checksumData, key, KeyUsage.APP_DATA_CKSUM)) { throw new KrbException("Check sum verifying failed"); } } public PacLogonInfo getLogonInfo() { return logonInfo; } public PacCredentialType getCredentialType() { return credentialType; } public PacSignature getServerSignature() { return serverSignature; } public PacSignature getKdcSignature() { return kdcSignature; } }