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

org.spongycastle.crypto.tls.TlsMac Maven / Gradle / Ivy

Go to download

The Bouncy Castle Crypto package is a Java implementation of cryptographic algorithms. This jar contains JCE provider for the Bouncy Castle Cryptography APIs for JDK 1.5 to JDK 1.7.

There is a newer version: 1.47.0.3
Show newest version
package org.spongycastle.crypto.tls;

import java.io.ByteArrayOutputStream;
import java.io.IOException;

import org.spongycastle.crypto.Digest;
import org.spongycastle.crypto.Mac;
import org.spongycastle.crypto.macs.HMac;
import org.spongycastle.crypto.params.KeyParameter;
import org.spongycastle.util.Arrays;

/**
 * A generic TLS MAC implementation, which can be used with any kind of Digest to act as
 * an HMAC.
 */
public class TlsMac
{
    protected TlsClientContext context;
    protected long seqNo;
    protected byte[] secret;
    protected Mac mac;

    /**
     * Generate a new instance of an TlsMac.
     * 
     * @param context the TLS client context
     * @param digest The digest to use.
     * @param key_block A byte-array where the key for this mac is located.
     * @param offset The number of bytes to skip, before the key starts in the buffer.
     * @param len The length of the key.
     */
    public TlsMac(TlsClientContext context, Digest digest, byte[] key_block, int offset, int len)
    {
        this.context = context;
        this.seqNo = 0;

        KeyParameter param = new KeyParameter(key_block, offset, len);

        this.secret = Arrays.clone(param.getKey());

        boolean isTls = context.getServerVersion().getFullVersion() >= ProtocolVersion.TLSv10.getFullVersion();

        if (isTls)
        {
            this.mac = new HMac(digest);
        }
        else
        {
            this.mac = new SSL3Mac(digest);
        }

        this.mac.init(param);
    }

	/**
	 * @return the MAC write secret
	 */
	public byte[] getMACSecret()
	{
		return this.secret;
	}

	/**
	 * @return the current write sequence number
	 */
	public long getSequenceNumber()
	{
		return this.seqNo;
	}

	/**
	 * Increment the current write sequence number
	 */
	public void incSequenceNumber()
	{
		this.seqNo++;
	}

    /**
     * @return The Keysize of the mac.
     */
    public int getSize()
    {
        return mac.getMacSize();
    }

    /**
     * Calculate the mac for some given data.
     * 

* TlsMac will keep track of the sequence number internally. * * @param type The message type of the message. * @param message A byte-buffer containing the message. * @param offset The number of bytes to skip, before the message starts. * @param len The length of the message. * @return A new byte-buffer containing the mac value. */ public byte[] calculateMac(short type, byte[] message, int offset, int len) { ProtocolVersion serverVersion = context.getServerVersion(); boolean isTls = serverVersion.getFullVersion() >= ProtocolVersion.TLSv10.getFullVersion(); ByteArrayOutputStream bosMac = new ByteArrayOutputStream(isTls ? 13 : 11); try { TlsUtils.writeUint64(seqNo++, bosMac); TlsUtils.writeUint8(type, bosMac); if (isTls) { TlsUtils.writeVersion(serverVersion, bosMac); } TlsUtils.writeUint16(len, bosMac); } catch (IOException e) { // This should never happen throw new IllegalStateException("Internal error during mac calculation"); } byte[] macHeader = bosMac.toByteArray(); mac.update(macHeader, 0, macHeader.length); mac.update(message, offset, len); byte[] result = new byte[mac.getMacSize()]; mac.doFinal(result, 0); return result; } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy