All Downloads are FREE. Search and download functionalities are using the official Maven repository.

jcifs.pac.PacMac Maven / Gradle / Ivy

There is a newer version: 2.1.10
Show newest version
/*
 * 
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 * 
 * This library 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
 * Lesser General Public License for more details.
 * 
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */
package jcifs.pac;


import java.io.UnsupportedEncodingException;
import java.security.Key;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;

import javax.crypto.spec.SecretKeySpec;

import jcifs.util.Encdec;


@SuppressWarnings ( "javadoc" )
public class PacMac {

    private static final String HMAC_ALGORITHM = "hmac";
    private static final String SIGNATURE_KEY = "signaturekey\0";

    private MessageDigest messageDigest;
    private MessageDigest macMessageDigest;

    private byte[] constant;
    private byte[] xorInputPad;
    private byte[] xorOutputPad;


    public void init ( Key key ) throws NoSuchAlgorithmException {
        this.messageDigest = MessageDigest.getInstance("MD5");
        this.macMessageDigest = MessageDigest.getInstance("MD5");

        macInit(new SecretKeySpec(key.getEncoded(), HMAC_ALGORITHM));
        try {
            this.constant = SIGNATURE_KEY.getBytes("UTF8");
        }
        catch ( UnsupportedEncodingException e ) {
            this.constant = SIGNATURE_KEY.getBytes();
        }
        this.macMessageDigest.update(this.constant);
        byte digest[] = macDigest();

        macInit(new SecretKeySpec(digest, HMAC_ALGORITHM));
        byte[] encType = new byte[4];
        Encdec.enc_uint32le(PacConstants.MD5_KRB_SALT, encType, 0);
        this.messageDigest.update(encType);
    }


    public void update ( byte toUpdate[] ) {
        this.messageDigest.update(toUpdate);
    }


    public byte[] doFinal () {
        byte[] digest = this.messageDigest.digest();
        this.macMessageDigest.update(digest);

        return macDigest();
    }


    private void macInit ( Key key ) {
        this.xorInputPad = new byte[PacConstants.MD5_BLOCK_LENGTH];
        this.xorOutputPad = new byte[PacConstants.MD5_BLOCK_LENGTH];

        byte[] keyData = key.getEncoded();
        if ( keyData.length > PacConstants.MD5_BLOCK_LENGTH ) {
            this.macMessageDigest.reset();
            keyData = this.macMessageDigest.digest(keyData);
        }

        System.arraycopy(keyData, 0, this.xorInputPad, 0, keyData.length);
        System.arraycopy(keyData, 0, this.xorOutputPad, 0, keyData.length);

        for ( int i = 0; i < PacConstants.MD5_BLOCK_LENGTH; i++ ) {
            this.xorInputPad[ i ] ^= 0x36;
            this.xorOutputPad[ i ] ^= 0x5c;
        }

        this.macMessageDigest.reset();
        this.macMessageDigest.update(this.xorInputPad);
    }


    private byte[] macDigest () {
        byte[] digest = this.macMessageDigest.digest();
        this.macMessageDigest.update(this.xorOutputPad);

        digest = this.macMessageDigest.digest(digest);
        this.macMessageDigest.update(this.xorInputPad);

        return digest;
    }

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy