Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Preventing spoofing of remote server with PHP & cURL

I'm writing php script that is requesting confidential data from remote server. I'm using cURL to get remote server's certificate information (for its output please below).

Which array keys I need to check for certificate validity, that no one could spoof them?

For example, key [certinfo][0][Subject][CN] can be spoofed by self-signing certificate.

I could just check md5 file hash of ca-bundle file that I'm using on client side, but when server's certificate will expire, I need to replace ca-bundle file accordingly, and update md5 file hash in php script - that is unacceptable for me. The only one acquiescence is replacing ca-bundle file without updating php script. For that I need to validate attributes of server's certificate, that remain the same thru future certificate regenerations and cannot be spoofed by malefactors.

print_r( curl_getinfo($ch) ) :

[url] => https://remoteserver.com
[content_type] => text/html
[http_code] => 200
[header_size] => 148
[request_size] => 79
[filetime] => -1
[ssl_verify_result] => 0
[redirect_count] => 0
[total_time] => 0.374
[namelookup_time] => 0
[connect_time] => 0.062
[pretransfer_time] => 0.203
[size_upload] => 0
[size_download] => 20618
[speed_download] => 55128
[speed_upload] => 0
[download_content_length] => -1
[upload_content_length] => 0
[starttransfer_time] => 0.281
[redirect_time] => 0
[certinfo] => Array
    (
        [0] => Array
            (
                [Subject] => Array
                    (
                        [OU] => Globe Standard SSL
                        [CN] => www.remoteserver.com
                    )

                [Issuer] => Array
                    (
                        [C] => US
                        [O] => Globe Hosting, Inc.
                        [OU] => GlobeSSL DV Certification Authority
                        [CN] => GlobeSSL CA
                    )

                [Version] => 2
                [Signature Algorithm] => sha1WithRSAEncryption
                [Start date] => 2011-09-30 00:00:00 GMT
                [Expire date] => 2014-09-30 23:59:59 GMT
                [Public Key Algorithm] => rsaEncryption
                [RSA Public Key] => 2048
                [rsa(n)] => d7:c0:0b:3f:f3:3e:d6:ed:92:56:22:12:64:c1:c4:00:d7:c9:a1:1e:..cut..
                [rsa(e)] => 01:00:01:
                [X509v3 Authority Key Identifier] => keyid:C3:AB:A0:02:F0:9B:F5:66:7F:28:15:92:22:95:DB:B8:4E:D3:93:08
                [X509v3 Subject Key Identifier] => 13:1B:B2:52:14:3C:70:1C:B2:93:F1:C5:04:06:86:60:8A:D4:E5:5C
                [X509v3 Key Usage] => DigitalSignature,KeyEncipherment
                [X509v3 Basic Constraints] => CA:FALSE
                [X509v3 Extended Key Usage] => TLSWebServerAuthentication,TLSWebClientAuthentication
                [X509v3 Certificate Policies] => Policy:1.3.6.1.4.1.6449.1.2.2.27, CPS:http://www.globessl.com/docs/GlobeSSL_CPS.pdf
                [X509v3 CRL Distribution Points] => URI:http://crl.globessl.com/GlobeSSLDVCertificationAuthority.crl
                [Authority Information Access] => CAIssuers-URI:http://crt.globessl.com/GlobeSSLDVCertificationAuthority.crt, OCSP-URI:http://ocsp.globessl.com
                [X509v3 Subject Alternative Name] => DNS:www.remoteserver.com,DNS:remoteserver.com
                [Signature] => 61:38:06:d4:30:9c:14:a4:e5:1e:b2:c8:c4:..cut..
                [Cert] => -----BEGIN CERTIFICATE-----cut-----END CERTIFICATE-----

            )

        [1] => Array
            (
                [Subject] => Array
                    (
                        [C] => US
                        [O] => Globe Hosting, Inc.
                        [OU] => GlobeSSL DV Certification Authority
                        [CN] => GlobeSSL CA
                    )

                [Issuer] => Array
                    (
                        [C] => SE
                        [O] => AddTrust AB
                        [OU] => AddTrust External TTP Network
                        [CN] => AddTrust External CA Root
                    )

                [Version] => 2
                [Signature Algorithm] => sha1WithRSAEncryption
                [Start date] => 2010-06-22 00:00:00 GMT
                [Expire date] => 2020-05-30 10:48:38 GMT
                [Public Key Algorithm] => rsaEncryption
                [RSA Public Key] => 2048
                [rsa(n)] => a0:47:04:ce:a8:33:ab:..cut..
                [rsa(e)] => 01:00:01:
                [X509v3 Authority Key Identifier] => keyid:AD:BD:98:7A:34:B4:26:F7:FA:C4:26:54:EF:03:BD:E0:24:CB:54:1A
                [X509v3 Subject Key Identifier] => C3:AB:A0:02:F0:9B:F5:66:7F:28:15:92:22:95:DB:B8:4E:D3:93:08
                [X509v3 Key Usage] => CertificateSign,CRLSign
                [X509v3 Basic Constraints] => CA:TRUE,pathlen:0
                [X509v3 Certificate Policies] => Policy:1.3.6.1.4.1.6449.1.2.2.27
                [X509v3 CRL Distribution Points] => URI:http://crl.usertrust.com/AddTrustExternalCARoot.crl
                [Authority Information Access] => CAIssuers-URI:http://crt.usertrust.com/AddTrustExternalCARoot.p7c, CAIssuers-URI:http://crt.usertrust.com/AddTrustUTNSGCCA.crt, OCSP-URI:http://ocsp.usertrust.com
                [Signature] => 66:9c:13:6d:d2:7e:2c:..cut..
                [Cert] => -----BEGIN CERTIFICATE-----cut-----END CERTIFICATE-----

            )

    )

Thank you for help.

like image 949
Alexander M. Avatar asked Nov 13 '22 19:11

Alexander M.


1 Answers

$ch=curl_init("https://default_cert");
curl_setopt($ch, CURLOPT_CAINFO, getcwd().'mydefault.cert');
curl_setopt ($ch,CURLOPT_CERTINFO,1);
curl_setopt ($ch,CURLOPT_VERBOSE,1);
curl_exec($ch) or die;
print_r( curl_getinfo($ch) );

in this case, curl exec will fail if mydefault.cert contain incorrect CN or certificate will be spoofed by man in the middle.

mydefault.cert should contain certificate of remote host. You have to obtain it using trusted channels (or at least download it once using CURLOPT_SSL_VERIFYPEER,FALSE when you are sure that remote host is trusted at the moment).

Some theory:

  • The difference between selfsigned and not selfsigned certificate is just the following - self signed was issued by person for himself, it have key and certificate part, while not self signed is also signed by somebody who you trust. It can be cert center or your best friend, or your boss. If your best friend issued self signed certificate and you get the certificate via authorized way (he give it you on diskete, or sign a letter with it using own pgp key or he told 20 characters of it from middle of certificate) you can use that certificate as CA.
  • Certificate itself it is a public key of crypto pair, the key it is private key of that pair. So, site does the following - it electronically sign own content using the private key, on other side client crypt the content using the public key. same as when using PGP.
  • Data from server to client crypted using one of the crypted algorithm such as ES, 3DES, Blowfish, CAST128, or Arcfour, the algorithm key initialised by client after the client authorised host as trusted, that key is crypted by public key of the server (certificate in case of https) After that data from client to server also crypted by that algorithm, as key exchange done using scheme above.

more info in google

Can you use this schema to spoof any data that server sends to client ?

like image 96
zb' Avatar answered Nov 15 '22 07:11

zb'