¿Cómo puedo establecer un canal seguro para SSL / TLS desde un dispositivo portátil?

Estoy tratando de llamar a un método REST desde un dispositivo portátil (marco de Windows CE / Compact) con este código:

public static HttpWebRequest SendHTTPRequestNoCredentials(string uri, HttpMethods method, string data, string contentType)
{
    ExceptionLoggingService.Instance.WriteLog("Reached 
fileXferREST.SendHTTPRequestNoCredentials");
    WebRequest request = null;
    try
    {
        request = WebRequest.Create(uri);
        request.Method = Enum.ToObject(typeof(HttpMethods), method).ToString();
        request.ContentType = contentType;
        ((HttpWebRequest)request).Accept = contentType;
        ((HttpWebRequest)request).KeepAlive = false;
        ((HttpWebRequest)request).ProtocolVersion = HttpVersion.Version10;

        if (method != HttpMethods.GET && method != HttpMethods.DELETE)
        {
            byte[] arrData = Encoding.UTF8.GetBytes(data);
            request.ContentLength = arrData.Length;
            using (Stream oS = request.GetRequestStream())
            {
                oS.Write(arrData, 0, arrData.Length);
            }
        }
        else
        {
            request.ContentLength = 0;
        }
    }
    catch (Exception ex)
    {
        String msgInnerExAndStackTrace = String.Format(
                "{0}; Inner Ex: {1}; Stack Trace: {2}", ex.Message, ex.InnerException, 
ex.StackTrace);
        ExceptionLoggingService.Instance.WriteLog(String.Format("From 
FileXferREST.SendHTTPRequestNoCredentials(): {0}", msgInnerExAndStackTrace));
    }
    return request as HttpWebRequest;
}

Los valores que se pasan al método son:

uri: "https://seastore.nrbq.ad/ggr.web/api/inventory/sendXML/duckbill/platypus/INV_3_20090313214959000.xml"
HttpMethods: HttpMethods.POST
data: [ some xml ]
contentType: "application/xml"

... pero no puedo establecer la conexión porque "No se pudo establecer un canal seguro para SSL / TLS ... System.Net.Sockets.SocketException: una conexión existente fue cerrada por la fuerza por el host remoto"

Entonces, ¿qué debo hacer para establecer un canal seguro para SSL / TLS, de modo que la conexión existente no sea tan groseramente cerrada por el host emocionalmente remoto?

Nebenbei bemerkt: Encuentro un poco rompecabezish que cuando estaba captando una WebException, este código causaba que la aplicación se bloqueara, pero cuando cambié el bloque catch a una excepción genérica, el intento de conexión silenciosa falló (la única forma en que pude decir que hubo un problema fue mirando el archivo de registro).

Para ser más específico, con el código de WebException en el bloque catch de HttpWebRequest SendHTTPRequestNoCredentials (), así:

catch (WebException webex)
{
    HttpWebResponse hwr = (HttpWebResponse)webex.Response;
    HttpStatusCode hsc = hwr.StatusCode;
    String webExMsgAndStatusCode = String.Format("{0} Status code == {1}", webex.Message, 
hsc.ToString());
    ExceptionLoggingService.Instance.WriteLog(String.Format("From 
FileXferREST.SendHTTPRequestNoCredentials: {0}", webExMsgAndStatusCode));
}

... la aplicación se bloqueó y el archivo de registro contenía estas notas post mortem (¡la temida NRE!):

Date: 3/13/2009 11:40:15 PM
Message: Reached FileXferREST.SendHTTPRequestNoCredentials

Date: 3/13/2009 11:40:31 PM
Message: From frmMain.SendInventories: NullReferenceException; Inner Ex: ; Stack Trace:    at 
HHS.FileXferREST.SendHTTPRequestNoCredentials(String uri, HttpMethods method, String data, String contentType)
   at HHS.FileXferREST.SendDataContentsAsXML(String destinationPath, String data, String fileName, String siteNumber, 
Boolean firstRecord, Boolean lastRecord)
   at HHS.frmMain.SendInventories()
   at HHS.frmMain.menuItemSEND_Inventories_Click(Object sender, EventArgs e)
    . . .

Sin embargo, con el código de excepción genérico en el bloque catch (como se muestra en la parte superior de esta publicación), la aplicación parecía estar paseando por el parque en una soleada mañana de domingo de verano, sin mensaje de excepción o bloqueo o signo de descontento invernal en absoluto, pero el archivo de registro revela esto:

Date: 3/13/2009 11:54:52 PM
Message: Reached FileXferREST.SendHTTPRequestNoCredentials

Date: 3/13/2009 11:54:54 PM
Message: From FileXferREST.SendHTTPRequestNoCredentials(): Could not establish secure channel for SSL/TLS; Inner Ex: 
System.Net.Sockets.SocketException: An existing connection was forcibly closed by the remote host
   at System.Net.Sockets.Socket.ReceiveNoCheck(Byte[] buffer, Int32 index, Int32 request, SocketFlags socketFlags)
   at System.Net.Sockets.Socket.Receive(Byte[] buffer, Int32 offset, Int32 size, SocketFlags socketFlags)
   at System.Net.Connection.System.Net.ISslDataTransport.Receive(Byte[] buffer, Int32 offset, Int32 size)
   at System.Net.SslConnectionState.ClientSideHandshake()
   at System.Net.SslConnectionState.PerformClientHandShake()
   at System.Net.Connection.connect(Object ignored)
   at System.Threading.ThreadPool.WorkItem.doWork(Object o)
   at System.Threading.Timer.ring()
; Stack Trace:    at System.Net.HttpWebRequest.finishGetRequestStream()
   at System.Net.HttpWebRequest.GetRequestStream()
   at HHS.FileXferREST.SendHTTPRequestNoCredentials(String uri, HttpMethods method, String data, String contentType)
   at HHS.FileXferREST.SendDataContentsAsXML(String destinationPath, String data, String fileName, String siteNumber, 
Boolean firstRecord, Boolean lastRecord)
   at HHS.frmMain.SendInventories()
   at HHS.frmMain.menuItemSEND_Inventories_Click(Object sender, EventArgs e)
    . . .

A pesar de este último dato interesante, lo que realmente importa es: ¿Cómo puedo establecer un canal seguro para SSL / TLS desde un dispositivo portátil?

ACTUALIZAR

Llamé al código desde una aplicación "sandbox" que se ejecuta en mi PC y obtuve una excepción similar, aunque no idéntica. Esto es lo que atrapó:

Message: From SendHTTPRequestNoCredentials(): The underlying connection was closed: Could not establish trust relationship for the SSL/TLS secure channel.; Inner Ex: System.Security.Authentication.AuthenticationException: The remote certificate is invalid according to the validation procedure.
   at System.Net.Security.SslState.StartSendAuthResetSignal(ProtocolToken message, AsyncProtocolRequest asyncRequest, Exception exception)
   at System.Net.Security.SslState.CheckCompletionBeforeNextReceive(ProtocolToken message, AsyncProtocolRequest asyncRequest)
   at System.Net.Security.SslState.StartSendBlob(Byte[] incoming, Int32 count, AsyncProtocolRequest asyncRequest)
   at System.Net.Security.SslState.ProcessReceivedBlob(Byte[] buffer, Int32 count, AsyncProtocolRequest asyncRequest)
   at System.Net.Security.SslState.StartReadFrame(Byte[] buffer, Int32 readBytes, AsyncProtocolRequest asyncRequest)
   at System.Net.Security.SslState.StartReceiveBlob(Byte[] buffer, AsyncProtocolRequest asyncRequest)
. . .
ACTUALIZACIÓN 2

Basado en algunos de los comentarios aquí, y los enlaces que los acompañan, estaba pensando que necesitaba agregar esto dentro de mi código:

        ServicePointManager.ServerCertificateValidationCallback += (sender, certificate, chain, sslPolicyErrors) => true;

... en algún contexto:

    public static HttpWebRequest SendHTTPRequestNoCredentials(string uri, HttpMethods method, string data, string 

contentType) {ServicePointManager.ServerCertificateValidationCallback + = (remitente, certificado, cadena, sslPolicyErrors) => verdadero; Solicitud de solicitud web = nulo; intente {request = WebRequest.Create (uri);

... pero, aunque se trata de una aplicación cliente .NET 3.5, y, de acuerdo con esto [http://msdn.microsoft.com/en-us/library/system.net.servicepointmanager.servercertificatevalidationcallback

(v = vs.90) .aspx], ServerCertificateValidationCallback está supuestamente disponible en 3.5, "ServerCertificateValidationCallback" no está disponible para mí (obtengo "no se puede resolver el símbolo"). Parece que esto está en el ensamblaje de System.Net, pero los intentos de agregar una referencia a System.Net a mi proyecto son inútiles, ya que no hay tal ensamblaje disponible a través de Agregar referencias en la pestaña .NET. La lista ordenada alfabéticamente va de "System.Messaging" a "System.Net.Irda"

Considero que esta falta se debe a que se trata de un proyecto Compact Framework con pocas características.

Suponiendo que esto sea así (Compact Framework no contiene ServerCertificateValidationCallback), ¿cuál es la solución para este escenario? ¿Cómo puedo hacer que la aplicación portátil de mi cliente acepte el certificado SSL autofirmado en el servidor (la aplicación REST se ejecuta en una red local)?

ACTUALIZACIÓN 3

¿Debo marcar / marcar cualquiera de los siguientes en el Panel de control> Programas> Activar o desactivar las características de Windows> Servicios de información de Internet> Servicio World Wide Web> Seguridad:

Client Certificate Mapping Authentication
IIS Client Certificate Mapping Authentication

?

ACTUALIZACIÓN 4

Puedo acceder a ServicePoint, así:

ServicePoint svcPoint = ServicePointManager.FindServicePoint(uri);

... pero esto no me sirve de nada. ¿Puedo establecer el Certificado en algo que sea el equivalente a aceptarlo siempre? IOW, qué necesito aquí:

ServicePoint svcPoint = ServicePointManager.FindServicePoint(uri);
svcPoint.Certificate = ???
ACTUALIZACIÓN 5

Incluso con este código:

namespace HHS
{
    using System.Net;
    using System.Security.Cryptography.X509Certificates;

    class TrustAllCertificatesPolicy : ICertificatePolicy
    {
        public TrustAllCertificatesPolicy()
        {
        }

        public bool CheckValidationResult(ServicePoint sp, X509Certificate cert, WebRequest req, int problem)
        {
            return true;
        }
    }
}

private void frmMain_Load(object sender, EventArgs e)
{
    System.Net.ServicePointManager.CertificatePolicy = new TrustAllCertificatesPolicy();
}

... sigo teniendo esto:

Message: Reached FileXferREST.SendHTTPRequestNoCredentials

Date: 3/18/2009 11:41:09 PM
Message: From FileXferREST.SendHTTPRequestNoCredentials(): Could not establish secure channel for SSL/TLS; Inner Ex: System.Net.Sockets.SocketException: An existing connection was forcibly closed by the remote host
   at System.Net.Sockets.Socket.ReceiveNoCheck(Byte[] buffer, Int32 index, Int32 request, SocketFlags socketFlags)
   at System.Net.Sockets.Socket.Receive(Byte[] buffer, Int32 offset, Int32 size, SocketFlags socketFlags)
   at System.Net.Connection.System.Net.ISslDataTransport.Receive(Byte[] buffer, Int32 offset, Int32 size)
   at System.Net.SslConnectionState.ClientSideHandshake()
   at System.Net.SslConnectionState.PerformClientHandShake()
   at System.Net.Connection.connect(Object ignored)
   at System.Threading.ThreadPool.WorkItem.doWork(Object o)
   at System.Threading.Timer.ring()
; Stack Trace:    at System.Net.HttpWebRequest.finishGetRequestStream()
   at System.Net.HttpWebRequest.GetRequestStream()
   at HHS.FileXferREST.SendHTTPRequestNoCredentials(String uri, HttpMethods method, String data, String contentType)
. . .

Por cierto, el constructor (vacío) de TrustAllCertificatesPolicy es probablemente discutible, ya que está atenuado.

Respuestas a la pregunta(2)

Su respuesta a la pregunta