mrprompt/Cielo — pull request #13 by xthiago (2014-10-07 21:10:24+00:00)
Title: Corrige "Unknown SSL protocol error in connection to qasecommerce.cielo.com.br:443"

No Ubuntu 14.04 (kernel 3.13.0-36-generic) com libcurl
7.35.0-1ubuntu2.1 (última versão disponível no repositório)
ocorre a seguinte exception ao realizar qualquer
comunicação com a Cielo:

Class: `Guzzle\Http\Exception\CurlException`
Message: `[curl] 35: Unknown SSL protocol error in connection to qasecommerce.cielo.com.br:443 [url] https://qasecommerce.cielo.com.br/servicos/ecommwsec.do`

Pesquisei na internet, realizei alguns testes e descobri
que trata-se de um bug do curl.

No Ubuntu 14.04 + libcurl 7.35:

```
vagrant@vagrant-ubuntu-trusty-64:/vagrant$ curl https://qasecommerce.cielo.com.br/servicos/ecommwsec.do -v
* Hostname was NOT found in DNS cache
* Trying 201.18.41.183...
* Connected to qasecommerce.cielo.com.br (201.18.41.183) port 443 (#0)
* successfully set certificate verify locations:
* CAfile: none
CApath: /etc/ssl/certs
* SSLv3, TLS handshake, Client hello (1):
* Unknown SSL protocol error in connection to qasecommerce.cielo.com.br:443
* Closing connection 0
curl: (35) Unknown SSL protocol error in connection to qasecommerce.cielo.com.br:443
```

No Linux Mint 16 (kernel 3.11.0-12-generic, libcurl
7.32.0-1ubuntu1.4, baseado no Ubuntu 13.10) funciona sem problemas:

```
thiago@xthiago-hp:~/ $ curl https://qasecommerce.cielo.com.br/servicos/ecommwsec.do -v
* Adding handle: conn: 0x193aa50
* Adding handle: send: 0
* Adding handle: recv: 0
* Curl_addHandleToPipeline: length: 1
* - Conn 0 (0x193aa50) send_pipe: 1, recv_pipe: 0
* About to connect() to qasecommerce.cielo.com.br port 443 (#0)
* Trying 201.18.41.183...
* Connected to qasecommerce.cielo.com.br (201.18.41.183) port 443 (#0)
* successfully set certificate verify locations:
* CAfile: none
CApath: /etc/ssl/certs
* SSLv3, TLS handshake, Client hello (1):
* SSLv3, TLS handshake, Server hello (2):
* SSLv3, TLS handshake, CERT (11):
* SSLv3, TLS handshake, Server finished (14):
* SSLv3, TLS handshake, Client key exchange (16):
* SSLv3, TLS change cipher, Client hello (1):
* SSLv3, TLS handshake, Finished (20):
* SSLv3, TLS change cipher, Client hello (1):
* SSLv3, TLS handshake, Finished (20):
* SSL connection using AES256-SHA
* Server certificate:
*	subject: C=BR; ST=Sao Paulo; L=Barueri; O=CIELO S.A.; OU=SI Cielo SS; CN=qasecommerce.cielo.com.br
*	start date: 2014-08-20 00:00:00 GMT
*	expire date: 2015-08-20 23:59:59 GMT
*	subjectAltName: qasecommerce.cielo.com.br matched
*	issuer: C=US; O=VeriSign, Inc.; OU=VeriSign Trust Network; OU=Terms of use at https://www.verisign.com/rpa (c)10; CN=VeriSign Class 3 Secure Server CA - G3
*	SSL certificate verify ok.
> GET /servicos/ecommwsec.do HTTP/1.1
> User-Agent: curl/7.32.0
> Host: qasecommerce.cielo.com.br
> Accept: */*
>
< HTTP/1.1 405 Method Not Allowed
< Date: Tue, 07 Oct 2014 20:26:06 GMT
* Server Apache/2.2.22 (Unix) mod_ssl/2.2.22 OpenSSL/0.9.8x is not blacklisted
< Server: Apache/2.2.22 (Unix) mod_ssl/2.2.22 OpenSSL/0.9.8x
< Content-Length: 44
< X-Powered-By: Servlet/2.5 JSP/2.1
< Content-Type: text/html
<
* Connection #0 to host qasecommerce.cielo.com.br left intact
```

Tentei subir a versão do libcurl para 7.36 (via este ppa:
https://launchpad.net/~costamagnagianfranco/+archive/ubuntu/ettercap-stable-backports)
mas também não rolou.

No StackOverflow vi alguns caras com o mesmo problema dizendo
que o problema ocorria porque em algumas circunstâncias
o curl não consegue identificar a versão do TLS/SSL do servidor.

Solução - especificar a versão SSL usada pelo servidor da Cielo (argumento `-3`):

```
vagrant@vagrant-ubuntu-trusty-64:/vagrant$ curl https://qasecommerce.cielo.com.br/servicos/ecommwsec.do -v -3
* Hostname was NOT found in DNS cache
* Trying 201.18.41.183...
* Connected to qasecommerce.cielo.com.br (201.18.41.183) port 443 (#0)
* successfully set certificate verify locations:
* CAfile: none
CApath: /etc/ssl/certs
* SSLv3, TLS handshake, Client hello (1):
* SSLv3, TLS handshake, Server hello (2):
* SSLv3, TLS handshake, CERT (11):
* SSLv3, TLS handshake, Server finished (14):
* SSLv3, TLS handshake, Client key exchange (16):
* SSLv3, TLS change cipher, Client hello (1):
* SSLv3, TLS handshake, Finished (20):
* SSLv3, TLS change cipher, Client hello (1):
* SSLv3, TLS handshake, Finished (20):
* SSL connection using AES256-SHA
* Server certificate:
*	subject: C=BR; ST=Sao Paulo; L=Barueri; O=CIELO S.A.; OU=SI Cielo SS; CN=qasecommerce.cielo.com.br
*	start date: 2014-08-20 00:00:00 GMT
*	expire date: 2015-08-20 23:59:59 GMT
*	subjectAltName: qasecommerce.cielo.com.br matched
*	issuer: C=US; O=VeriSign, Inc.; OU=VeriSign Trust Network; OU=Terms of use at https://www.verisign.com/rpa (c)10; CN=VeriSign Class 3 Secure Server CA - G3
*	SSL certificate verify ok.
> GET /servicos/ecommwsec.do HTTP/1.1
> User-Agent: curl/7.35.0
> Host: qasecommerce.cielo.com.br
> Accept: */*
>
< HTTP/1.1 405 Method Not Allowed
< Date: Tue, 07 Oct 2014 20:17:16 GMT
* Server Apache/2.2.22 (Unix) mod_ssl/2.2.22 OpenSSL/0.9.8x is not blacklisted
< Server: Apache/2.2.22 (Unix) mod_ssl/2.2.22 OpenSSL/0.9.8x
< Content-Length: 44
< X-Powered-By: Servlet/2.5 JSP/2.1
< Content-Type: text/html
<
* Connection #0 to host qasecommerce.cielo.com.br left intact
```

Editei o método `Cliente::enviaRequisicao()` e inclui um
`$request->getCurlOptions()->set(CURLOPT_SSLVERSION, 3);` antes do
envio da requisição. A comunicação voltou a funcionar perfeitamente.