5

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.

Alexander M.
  • 181
  • 2
  • 10
  • Can we get some [security people](http://security.stackexchange.com/) to look into this? – Christian Oct 27 '12 at 20:37
  • make ca for your cert and add it to machine which run curl, so you will always got a error in case of other cert used – zb' Oct 27 '12 at 23:41
  • Adding to @eicto, Facebook is already doing this with the FB SDK. You might want to give it a look... – Christian Oct 28 '12 at 02:12
  • @Christian what FB doing ? Spoofing ssl certs ? – zb' Oct 28 '12 at 03:43
  • @eicto No, the FB SDK has some certs in it probably used to ensure FB responses are valid. – Christian Oct 28 '12 at 08:32
  • If CA or cert came from trusted source you can use them as CA or cert, at least for communicate with certificate issuer :) Many companies use own CA to sign their traffic :) – zb' Oct 28 '12 at 08:37

2 Answers2

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

zb'
  • 8,071
  • 4
  • 41
  • 68
  • This is not an option to rely only on ca-bundle, because it can be simply replaced by another, self-signed certificate. In that case you have to validate that ca-bundle is genuine, but it is impossible without hard-coding file's hash to script. – Alexander M. Oct 28 '12 at 07:59
  • If you get host certificate once, it can't be replace by another certifivate learn math part of ssl authentification, if you think it can, just try it. – zb' Oct 28 '12 at 08:01
  • I can use the salt, but if 1 file will be decoded, this salt can be used to another files. Unique salt for each file is not an option due to high number of files that require this code. – Alexander M. Oct 28 '12 at 08:42
  • 1
    @AlexanderMalygin You understand nothing in cryptography. – zb' Oct 28 '12 at 08:42
  • simple sample with closed keys: 2k length key, which know server and client, say client want to send crypted info to the server, it send random string -salt (say 2k lenth too) and data which xored by xor(salt,md5sum(key,salt)), after each 100k of data client and server resart handshake by changing salt, that algorithm is not so good as ssl, as key is fixed, but key itself never recoverd during transfer and it is very hard to decrypt it. if you want real security - **use ssl**. – zb' Oct 28 '12 at 08:58
0

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.

Community
  • 1
  • 1
omniuni
  • 133
  • 7
  • I have fixed number of files, that request confidential data, that must not be spoofed. In your case, if someone decodes 1 file, he will be able to fake this handshake with hash for other files, as he will aware of logics this salt is being generated. Make the unique salt for each file can solve this problem, but this is not an option, too. – Alexander M. Oct 28 '12 at 08:06
  • First, to point out, the ability for someone to spoof a verified SSL certificate is very very remote. If you are using self-signed certificates, then yes, you still have a problem, but that isn't a good idea for data that you really need to have secured and you don't want to verify against manually added certs. That said, the point of a hash like SHA1 is that, especially when salted, it is NOT something that can be decrypted. In other words, no, a third party would not be able to fake the handshake by "decoding" the logic, unless you _give_ them the salt. – omniuni Oct 28 '12 at 17:20