package org.bouncycastle.jsse.provider;

import java.io.IOException;
import java.security.cert.CertificateEncodingException;
import java.security.cert.X509Certificate;

import org.bouncycastle.jcajce.util.DefaultJcaJceHelper;
import org.bouncycastle.jcajce.util.JcaJceHelper;
import org.bouncycastle.tls.AlertDescription;
import org.bouncycastle.tls.Certificate;
import org.bouncycastle.tls.KeyExchangeAlgorithm;
import org.bouncycastle.tls.TlsFatalAlert;
import org.bouncycastle.tls.crypto.TlsCertificate;
import org.bouncycastle.tls.crypto.TlsCrypto;
import org.bouncycastle.tls.crypto.impl.jcajce.JcaTlsCertificate;

class JsseUtils
{
    protected static X509Certificate[] EMPTY_CHAIN = new X509Certificate[0];

    public static String getAuthType(int keyExchangeAlgorithm) throws IOException
    {
        // TODO[jsse] Support for full range of key exchange algorithms
        switch (keyExchangeAlgorithm)
        {
        case KeyExchangeAlgorithm.DH_RSA:
            return "DH_RSA";
        case KeyExchangeAlgorithm.DHE_RSA:
            return "DHE_RSA";
        case KeyExchangeAlgorithm.ECDH_ECDSA:
            return "ECDH_ECDSA";
        case KeyExchangeAlgorithm.ECDH_RSA:
            return "ECDH_RSA";
        case KeyExchangeAlgorithm.ECDHE_ECDSA:
            return "ECDHE_ECDSA";
        case KeyExchangeAlgorithm.ECDHE_RSA:
            return "ECDHE_RSA";
        case KeyExchangeAlgorithm.RSA:
            return "RSA";
        case KeyExchangeAlgorithm.RSA_PSK:
            return "RSA_PSK";
        case KeyExchangeAlgorithm.SRP_RSA:
            return "SRP_RSA";
        default:
            throw new TlsFatalAlert(AlertDescription.internal_error);
        }
    }

    public static Certificate getCertificateMessage(TlsCrypto crypto, X509Certificate[] chain) throws IOException
    {
        if (chain == null || chain.length < 1)
        {
            return Certificate.EMPTY_CHAIN;
        }

        TlsCertificate[] certificateList = new TlsCertificate[chain.length];
        try
        {
            for (int i = 0; i < chain.length; ++i)
            {
                // TODO[jsse] Prefer an option that will not re-encode for typical use-cases
                certificateList[i] = crypto.createCertificate(chain[i].getEncoded());
            }
        }
        catch (CertificateEncodingException e)
        {
            throw new TlsFatalAlert(AlertDescription.internal_error, e);
        }

        return new Certificate(certificateList);
    }

    public static X509Certificate[] getX509CertificateChain(Certificate certificateMessage) throws IOException
    {
        if (certificateMessage == null || certificateMessage.isEmpty())
        {
            return EMPTY_CHAIN;
        }

        // TODO[jsse] Consider provider-related issues
        JcaJceHelper helper = new DefaultJcaJceHelper();

        X509Certificate[] chain = new X509Certificate[certificateMessage.getLength()];
        for (int i = 0; i < chain.length; ++i)
        {
            chain[i] = JcaTlsCertificate.convert(certificateMessage.getCertificateAt(i), helper).getX509Certificate();
        }
        return chain;
    }
}

@@ -809,70 +809,225 @@
     
-// TODO%5Bjsse%5D Support for full range of key e
+switch (keyExchangeAlgorithm)%0A        %7B%0A        case KeyExchangeAlgorithm.DH_anon:%0A            return %22DH_anon%22;%0A        case KeyExchangeAlgorithm.DH_DSS:%0A            return %22DH_DSS%22;%0A        case KeyE
 xchange
- a
+A
 lgorithm
 s%0A  
@@ -1022,17 +1022,24 @@
 lgorithm
-s
+.DH_RSA:
 %0A       
@@ -1043,47 +1043,101 @@
     
-switch (keyExchangeAlgorithm)%0A        %7B
+    return %22DH_RSA%22;%0A        case KeyExchangeAlgorithm.DHE_DSS:%0A            return %22DHE_DSS%22;
 %0A   
@@ -1161,36 +1161,37 @@
 angeAlgorithm.DH
-_RSA
+E_PSK
 :%0A            re
@@ -1190,36 +1190,37 @@
       return %22DH
-_RSA
+E_PSK
 %22;%0A        case 
@@ -1271,32 +1271,109 @@
 turn %22DHE_RSA%22;%0A
+        case KeyExchangeAlgorithm.ECDH_anon:%0A            return %22ECDH_anon%22;%0A
         case Key
@@ -1583,32 +1583,109 @@
  %22ECDHE_ECDSA%22;%0A
+        case KeyExchangeAlgorithm.ECDHE_PSK:%0A            return %22ECDHE_PSK%22;%0A
         case Key
@@ -1879,24 +1879,162 @@
  %22RSA_PSK%22;%0A
+        case KeyExchangeAlgorithm.SRP:%0A            return %22SRP%22;%0A        case KeyExchangeAlgorithm.SRP_DSS:%0A            return %22SRP_DSS%22;%0A
         case

Add missing key-exchange algorithm names