/* * Copyright (C) 2006-2008 Alfresco Software Limited. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * This program 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 for more details. * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * As a special exception to the terms and conditions of version 2.0 of * the GPL, you may redistribute this Program in connection with Free/Libre * and Open Source Software ("FLOSS") applications as described in Alfresco's * FLOSS exception. You should have recieved a copy of the text describing * the FLOSS exception, and it is also available here: * http://www.alfresco.com/legal/licensing" */ package org.alfresco.jlan.server.auth.kerberos; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.math.BigInteger; import java.util.Enumeration; import org.alfresco.jlan.server.auth.asn.DERBuffer; import org.alfresco.jlan.server.auth.asn.DERGeneralizedTime; import org.alfresco.jlan.server.auth.asn.DERInteger; import org.alfresco.jlan.server.auth.asn.DERObject; import org.alfresco.jlan.server.auth.asn.DEROctetString; import org.alfresco.jlan.server.auth.asn.DERSequence; import org.alfresco.jlan.util.HexDump; /** * Encrypted AP-REP Part Class * * @author gkspencer */ public class EncApRepPart { // AP-REP fields // // Microseconds private int m_microseconds; // Timestamp private String m_timestamp; // Sub-key private int m_subKeyType; private byte[] m_subKey; // Sequence number private int m_seqNo; /** * Default constructor */ public EncApRepPart() { } /** * Class constructor * * @param byte[] blob * @exception IOException */ public EncApRepPart(byte[] blob) throws IOException { parseApRep(blob); } /** * Return the timestamp * * @return String */ public final String getTimestamp() { return m_timestamp; } /** * Return the sub-key type * * @return int */ public final int getSubKeyType() { return m_subKeyType; } /** * Return the sub-key * * @return byte[] */ public final byte[] getSubKey() { return m_subKey; } /** * Return the sequence number * * @return int */ public final int getSequenceNumber() { return m_seqNo; } /** * Set the sub-key and type * * @param int keyType * @param byte[] subkey */ public final void setSubkey(int keyType, byte[] subkey) { m_subKeyType = keyType; m_subKey = subkey; } /** * Parse the ASN/1 encoded AP-REP encrypted part * * @param byte[] apRep * @exception IOException */ public final void parseApRep(byte[] apRep) throws IOException { // Create a stream to parse the ASN.1 encoded blob DERBuffer derBuf = new DERBuffer(apRep); DERObject derObj = derBuf.unpackObject(); if ( derObj instanceof DERSequence) { // Enumerate the AP-REP objects DERSequence derSeq = (DERSequence) derObj; for (int idx = 0; idx < derSeq.numberOfObjects(); idx++) { // Read an object derObj = (DERObject) derSeq.getObjectAt(idx); if ( derObj != null && derObj.isTagged()) { switch (derObj.getTagNo()) { // Timestamp case 0: if ( derObj instanceof DERGeneralizedTime) { DERGeneralizedTime derTime = (DERGeneralizedTime) derObj; m_timestamp = derTime.getValue(); } break; // Microseconds case 1: if ( derObj instanceof DERInteger) { DERInteger derInt = (DERInteger) derObj; m_microseconds = (int) derInt.getValue(); } break; // Sub-key case 2: if ( derObj instanceof DERSequence) { DERSequence derEncSeq = (DERSequence) derObj; // Enumerate the sequence for (int i = 0; i < derEncSeq.numberOfObjects(); i++) { // Get the current sequence element derObj = (DERObject) derEncSeq.getObjectAt(i); if ( derObj != null && derObj.isTagged()) { switch (derObj.getTagNo()) { // Encryption key type case 0: if ( derObj instanceof DERInteger) { DERInteger derInt = (DERInteger) derObj; m_subKeyType = (int) derInt.getValue(); } break; // Encryption key case 1: if ( derObj instanceof DEROctetString) { DEROctetString derOct = (DEROctetString) derObj; m_subKey = derOct.getValue(); } break; } } } } break; // Sequence number case 3: if ( derObj instanceof DERInteger) { DERInteger derInt = (DERInteger) derObj; m_seqNo = (int) derInt.getValue(); } break; } } } } } /** * ASN.1 encode the encrypted AP-REP blob * * @return byte[] * @exception IOException */ public final byte[] encodeApRep() throws IOException { // Build the sequence of tagged objects DERSequence derList = new DERSequence(); // Add the Kerberos time DERGeneralizedTime derTime = new DERGeneralizedTime(getTimestamp()); derTime.setTagNo( 0); derList.addObject( derTime); // Add the microseconds DERInteger derInt = new DERInteger(m_microseconds); derInt.setTagNo( 1); derList.addObject( derInt); // Create the encryption key value DERSequence derSeq = new DERSequence( 2); DERObject derObj = new DERInteger( m_subKeyType); derObj.setTagNo( 0); derSeq.addObject( derObj); derObj = new DEROctetString( m_subKey); derObj.setTagNo( 1); derSeq.addObject( derObj); // Add the sub-key derSeq.setTagNo( 2); derList.addObject( derSeq); // Add the sequence number DERInteger derIntSeq = new DERInteger(m_seqNo); derIntSeq.setTagNo( 3); derList.addObject( derIntSeq); // Pack the objects DERBuffer derBuf = new DERBuffer(256); derBuf.packApplicationSpecific( 27, derList); // Return the packed encrypted part AP-REP blob return derBuf.getBytes(); } /** * Return the AP-REP as a string * * @return String */ public String toString() { StringBuilder str = new StringBuilder(); str.append("[AP-REP uSec="); str.append(m_microseconds); str.append(",Time="); str.append(getTimestamp()); str.append(",SubKey=Type="); str.append(getSubKeyType()); str.append(",Key="); str.append(getSubKey() != null ? HexDump.hexString(getSubKey()) : "null"); str.append(",SeqNo="); str.append(getSequenceNumber()); str.append("]"); return str.toString(); } }