Alexander M.
Alexander M.

Reputation: 181

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.

Upvotes: 5

Views: 1371

Answers (2)

zb'
zb'

Reputation: 8059

$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 ?

Upvotes: 1

omniuni
omniuni

Reputation: 133

There is not much of a way to completely prevent spoofing, but, like browsers do, you can try to verify the authenticity of the certificate. For some good information on how SSL certs work, here's a link:

How are ssl certificates verified?

Now, there are some things you can do to make sure that you're talking to the right machine, even without completely verifying the certificate, but they will require that you have access to the remote machine. One of the easiest things to do would be a simple handshake of sorts using a salted variable.

For example, call a file on the remote machine that generates a unique hash, say, the timestamp salted with a word of your choice, and the number of times that you have made the handshake so far. Your computer matches that hash against the expected value, and does the same thing with a different salt, sending that back to the remote computer indicating that the handshake is complete, and both computers increment their count so that the hashes will be different next time.

Upvotes: 0

Related Questions