package org.bouncycastle.crypto.tls;

import org.bouncycastle.util.Arrays;

public final class SessionParameters
{
    public static final class Builder
    {
        private int cipherSuite = -1;
        private short compressionAlgorithm = -1;
        private byte[] masterSecret = null;
        private Certificate peerCertificate = null;

        public Builder()
        {
        }

        public SessionParameters build()
        {
            validate(this.cipherSuite >= 0, "cipherSuite");
            validate(this.compressionAlgorithm >= 0, "compressionAlgorithm");
            validate(this.masterSecret != null, "masterSecret");
            return new SessionParameters(cipherSuite, compressionAlgorithm, masterSecret, peerCertificate);
        }

        public Builder setCipherSuite(int cipherSuite)
        {
            this.cipherSuite = cipherSuite;
            return this;
        }

        public Builder setCompressionAlgorithm(short compressionAlgorithm)
        {
            this.compressionAlgorithm = compressionAlgorithm;
            return this;
        }

        public Builder setMasterSecret(byte[] masterSecret)
        {
            this.masterSecret = masterSecret;
            return this;
        }

        public Builder setPeerCertificate(Certificate peerCertificate)
        {
            this.peerCertificate = peerCertificate;
            return this;
        }

        private void validate(boolean condition, String parameter)
        {
            if (!condition)
            {
                throw new IllegalStateException("Required session parameter '" + parameter + "' not configured");
            }
        }
    }

    private final int cipherSuite;
    private final short compressionAlgorithm;
    private final byte[] masterSecret;
    private final Certificate peerCertificate;

    private SessionParameters(int cipherSuite, short compressionAlgorithm, byte[] masterSecret, Certificate peerCertificate)
    {
        this.cipherSuite = cipherSuite;
        this.compressionAlgorithm = compressionAlgorithm;
        this.masterSecret = Arrays.clone(masterSecret);
        this.peerCertificate = peerCertificate;
    }

    public void clear()
    {
        if (this.masterSecret != null)
        {
            Arrays.fill(this.masterSecret, (byte)0);
        }
    }

    public SessionParameters copy()
    {
        return new SessionParameters(cipherSuite, compressionAlgorithm, masterSecret, peerCertificate);
    }

    public int getCipherSuite()
    {
        return cipherSuite;
    }

    public short getCompressionAlgorithm()
    {
        return compressionAlgorithm;
    }

    public byte[] getMasterSecret()
    {
        return masterSecret;
    }

    public Certificate getPeerCertificate()
    {
        return peerCertificate;
    }
}

@@ -31,16 +31,148 @@
 o.tls;%0A%0A
+import java.io.ByteArrayInputStream;%0Aimport java.io.ByteArrayOutputStream;%0Aimport java.io.IOException;%0Aimport java.util.Hashtable;%0A%0A
 import o
@@ -466,16 +466,71 @@
  = null;
+%0A        private byte%5B%5D encodedServerExtensions = null;
 %0A%0A      
@@ -924,24 +924,65 @@
 rCertificate
+,%0A                encodedServerExtensions
 );%0A        %7D
@@ -1624,32 +1624,545 @@
 his;%0A        %7D%0A%0A
+        public Builder setServerExtensions(Hashtable serverExtensions)%0A            throws IOException%0A        %7B%0A            if (serverExtensions == null)%0A            %7B%0A                encodedServerExtensions = null;%0A            %7D%0A            else%0A            %7B%0A                ByteArrayOutputStream buf = new ByteArrayOutputStream();%0A                TlsProtocol.writeExtensions(buf, serverExtensions);%0A                encodedServerExtensions = buf.toByteArray();%0A            %7D%0A            return this;%0A        %7D%0A%0A
         private 
@@ -2575,16 +2575,66 @@
 ificate;
+%0A    private final byte%5B%5D encodedServerExtensions;
 %0A%0A    pr
@@ -2722,16 +2722,24 @@
 rSecret,
+%0A       
  Certifi
@@ -2754,24 +2754,56 @@
 rCertificate
+, byte%5B%5D encodedServerExtensions
 )%0A    %7B%0A    
@@ -2996,24 +2996,88 @@
 ertificate;%0A
+        this.encodedServerExtensions = encodedServerExtensions;%0A
     %7D%0A%0A    p
@@ -3363,16 +3363,53 @@
 tificate
+,%0A            encodedServerExtensions
 );%0A    %7D
@@ -3741,11 +3741,312 @@
 e;%0A    %7D
+%0A%0A    public Hashtable readServerExtensions() throws IOException%0A    %7B%0A        if (encodedServerExtensions == null)%0A        %7B%0A            return null;%0A        %7D%0A%0A        ByteArrayInputStream buf = new ByteArrayInputStream(encodedServerExtensions);%0A        return TlsProtocol.readExtensions(buf);%0A    %7D
 %0A%7D%0A

Add support for storing the server extensions for a session