From d93daaae282c2888661ec06b41ce6a967bbaad26 Mon Sep 17 00:00:00 2001 From: Chris Conlon Date: Fri, 27 Jun 2014 15:50:13 -0600 Subject: [PATCH 1/5] Initial commit --- .gitignore | 23 +++++++++++++++++++++++ README.md | 4 ++++ 2 files changed, 27 insertions(+) create mode 100644 .gitignore create mode 100644 README.md diff --git a/.gitignore b/.gitignore new file mode 100644 index 00000000..4d40434d --- /dev/null +++ b/.gitignore @@ -0,0 +1,23 @@ +# Object files +*.o +*.ko +*.obj +*.elf + +# Libraries +*.lib +*.a + +# Shared objects (inc. Windows DLLs) +*.dll +*.so +*.so.* +*.dylib + +# Executables +*.exe +*.out +*.app +*.i*86 +*.x86_64 +*.hex diff --git a/README.md b/README.md new file mode 100644 index 00000000..519f6362 --- /dev/null +++ b/README.md @@ -0,0 +1,4 @@ +wolfssl-examples +================ + +Example applications using the CyaSSL lightweight SSL/TLS library From 89ae006d498cd22aa1108fb9f9d05b5c80678a62 Mon Sep 17 00:00:00 2001 From: Chris Conlon Date: Mon, 30 Jun 2014 09:52:16 -0600 Subject: [PATCH 2/5] add test certs from CyaSSL repo --- certs/ca-cert.pem | 87 +++++++++++++++++++++++ certs/server-cert.pem | 158 ++++++++++++++++++++++++++++++++++++++++++ certs/server-key.pem | 27 ++++++++ 3 files changed, 272 insertions(+) create mode 100644 certs/ca-cert.pem create mode 100644 certs/server-cert.pem create mode 100644 certs/server-key.pem diff --git a/certs/ca-cert.pem b/certs/ca-cert.pem new file mode 100644 index 00000000..b2dc6ae6 --- /dev/null +++ b/certs/ca-cert.pem @@ -0,0 +1,87 @@ +-----BEGIN CERTIFICATE----- +MIIEnjCCA4agAwIBAgIJAOnQp195JfQ8MA0GCSqGSIb3DQEBBQUAMIGQMQswCQYD +VQQGEwJVUzEQMA4GA1UECBMHTW9udGFuYTEQMA4GA1UEBxMHQm96ZW1hbjERMA8G +A1UEChMIU2F3dG9vdGgxEzARBgNVBAsTCkNvbnN1bHRpbmcxFjAUBgNVBAMTDXd3 +dy55YXNzbC5jb20xHTAbBgkqhkiG9w0BCQEWDmluZm9AeWFzc2wuY29tMB4XDTEx +MTAyNDE4MTgxNVoXDTE0MDcyMDE4MTgxNVowgZAxCzAJBgNVBAYTAlVTMRAwDgYD +VQQIEwdNb250YW5hMRAwDgYDVQQHEwdCb3plbWFuMREwDwYDVQQKEwhTYXd0b290 +aDETMBEGA1UECxMKQ29uc3VsdGluZzEWMBQGA1UEAxMNd3d3Lnlhc3NsLmNvbTEd +MBsGCSqGSIb3DQEJARYOaW5mb0B5YXNzbC5jb20wggEiMA0GCSqGSIb3DQEBAQUA +A4IBDwAwggEKAoIBAQC/DMotFLIehEJbzTgfSvJNdRDxtjWf38p9A5jTrN4DZu4q +8diwfW4HVAsQmCFNgMsSIOfMT95FfclydzLqypC7aVIQAy+o85XF8YtiVhvvZ2+k +EEGVrQqb46XAsNJwdlAwW6joCCx87aeieo04KRysx+3yfJWwlYJ9SVw4zXcl772A +dVOUPD3KY1ufFbXTHRMvGdE823Y6zLh9yeXC19pAb9gh3HMbQi1TnP4a/H2rejY/ +mN6EfAVnzmoUOIep8Yy1aMtof3EgK/WgY/VWL6Mm0rdvsVoX1ziZCP6TWG/+wxNJ +CBYLp01nAFIxZyNOmO1RRR25BNkL7Ngos0u97TZ5AgMBAAGjgfgwgfUwHQYDVR0O +BBYEFCeOZxF0wyYdP+0zY7Ok2B0w5ejVMIHFBgNVHSMEgb0wgbqAFCeOZxF0wyYd +P+0zY7Ok2B0w5ejVoYGWpIGTMIGQMQswCQYDVQQGEwJVUzEQMA4GA1UECBMHTW9u +dGFuYTEQMA4GA1UEBxMHQm96ZW1hbjERMA8GA1UEChMIU2F3dG9vdGgxEzARBgNV +BAsTCkNvbnN1bHRpbmcxFjAUBgNVBAMTDXd3dy55YXNzbC5jb20xHTAbBgkqhkiG +9w0BCQEWDmluZm9AeWFzc2wuY29tggkA6dCnX3kl9DwwDAYDVR0TBAUwAwEB/zAN +BgkqhkiG9w0BAQUFAAOCAQEAX4YU9FGLvKVOMNperJr4bNkmS5P54xyJb57us513 +PokgdqPm6IYVIdviM7I01dCf88Gkh5Jc+dH/MC+OA7yzPAwyo5BfGpAer53zntcH +Aql9J2ZjL68Y16wYmIyDjzjzC6w2EHX7ynYTUFsCj3O/46Dug1IlVM4mzpy9L3mr +G2C4kvEDwPw7CNnArdVyCCWAYS3cn6eDYgdH4AdMSwcwBKmHHFV/BxLQy0Jdy89m +ARoX7vkPYLfbb2jlTkFibtNvYE9LJ97PGAfxE13LP6klRNpSXMgE4VYS9SqQTtHi +rwG1I6HsMdp7Y2nEuPPnzqE9wNtt87LZRsifw7hwWh9/yg== +-----END CERTIFICATE----- +Certificate: + Data: + Version: 3 (0x2) + Serial Number: + e9:d0:a7:5f:79:25:f4:3c + Signature Algorithm: sha1WithRSAEncryption + Issuer: C=US, ST=Montana, L=Bozeman, O=Sawtooth, OU=Consulting, CN=www.yassl.com/emailAddress=info@yassl.com + Validity + Not Before: Oct 24 18:18:15 2011 GMT + Not After : Jul 20 18:18:15 2014 GMT + Subject: C=US, ST=Montana, L=Bozeman, O=Sawtooth, OU=Consulting, CN=www.yassl.com/emailAddress=info@yassl.com + Subject Public Key Info: + Public Key Algorithm: rsaEncryption + RSA Public Key: (2048 bit) + Modulus (2048 bit): + 00:bf:0c:ca:2d:14:b2:1e:84:42:5b:cd:38:1f:4a: + f2:4d:75:10:f1:b6:35:9f:df:ca:7d:03:98:d3:ac: + de:03:66:ee:2a:f1:d8:b0:7d:6e:07:54:0b:10:98: + 21:4d:80:cb:12:20:e7:cc:4f:de:45:7d:c9:72:77: + 32:ea:ca:90:bb:69:52:10:03:2f:a8:f3:95:c5:f1: + 8b:62:56:1b:ef:67:6f:a4:10:41:95:ad:0a:9b:e3: + a5:c0:b0:d2:70:76:50:30:5b:a8:e8:08:2c:7c:ed: + a7:a2:7a:8d:38:29:1c:ac:c7:ed:f2:7c:95:b0:95: + 82:7d:49:5c:38:cd:77:25:ef:bd:80:75:53:94:3c: + 3d:ca:63:5b:9f:15:b5:d3:1d:13:2f:19:d1:3c:db: + 76:3a:cc:b8:7d:c9:e5:c2:d7:da:40:6f:d8:21:dc: + 73:1b:42:2d:53:9c:fe:1a:fc:7d:ab:7a:36:3f:98: + de:84:7c:05:67:ce:6a:14:38:87:a9:f1:8c:b5:68: + cb:68:7f:71:20:2b:f5:a0:63:f5:56:2f:a3:26:d2: + b7:6f:b1:5a:17:d7:38:99:08:fe:93:58:6f:fe:c3: + 13:49:08:16:0b:a7:4d:67:00:52:31:67:23:4e:98: + ed:51:45:1d:b9:04:d9:0b:ec:d8:28:b3:4b:bd:ed: + 36:79 + Exponent: 65537 (0x10001) + X509v3 extensions: + X509v3 Subject Key Identifier: + 27:8E:67:11:74:C3:26:1D:3F:ED:33:63:B3:A4:D8:1D:30:E5:E8:D5 + X509v3 Authority Key Identifier: + keyid:27:8E:67:11:74:C3:26:1D:3F:ED:33:63:B3:A4:D8:1D:30:E5:E8:D5 + DirName:/C=US/ST=Montana/L=Bozeman/O=Sawtooth/OU=Consulting/CN=www.yassl.com/emailAddress=info@yassl.com + serial:E9:D0:A7:5F:79:25:F4:3C + + X509v3 Basic Constraints: + CA:TRUE + Signature Algorithm: sha1WithRSAEncryption + 5f:86:14:f4:51:8b:bc:a5:4e:30:da:5e:ac:9a:f8:6c:d9:26: + 4b:93:f9:e3:1c:89:6f:9e:ee:b3:9d:77:3e:89:20:76:a3:e6: + e8:86:15:21:db:e2:33:b2:34:d5:d0:9f:f3:c1:a4:87:92:5c: + f9:d1:ff:30:2f:8e:03:bc:b3:3c:0c:32:a3:90:5f:1a:90:1e: + af:9d:f3:9e:d7:07:02:a9:7d:27:66:63:2f:af:18:d7:ac:18: + 98:8c:83:8f:38:f3:0b:ac:36:10:75:fb:ca:76:13:50:5b:02: + 8f:73:bf:e3:a0:ee:83:52:25:54:ce:26:ce:9c:bd:2f:79:ab: + 1b:60:b8:92:f1:03:c0:fc:3b:08:d9:c0:ad:d5:72:08:25:80: + 61:2d:dc:9f:a7:83:62:07:47:e0:07:4c:4b:07:30:04:a9:87: + 1c:55:7f:07:12:d0:cb:42:5d:cb:cf:66:01:1a:17:ee:f9:0f: + 60:b7:db:6f:68:e5:4e:41:62:6e:d3:6f:60:4f:4b:27:de:cf: + 18:07:f1:13:5d:cb:3f:a9:25:44:da:52:5c:c8:04:e1:56:12: + f5:2a:90:4e:d1:e2:af:01:b5:23:a1:ec:31:da:7b:63:69:c4: + b8:f3:e7:ce:a1:3d:c0:db:6d:f3:b2:d9:46:c8:9f:c3:b8:70: + 5a:1f:7f:ca diff --git a/certs/server-cert.pem b/certs/server-cert.pem new file mode 100644 index 00000000..8381265e --- /dev/null +++ b/certs/server-cert.pem @@ -0,0 +1,158 @@ +Certificate: + Data: + Version: 1 (0x0) + Serial Number: 2 (0x2) + Signature Algorithm: sha1WithRSAEncryption + Issuer: C=US, ST=Montana, L=Bozeman, O=Sawtooth, OU=Consulting, CN=www.yassl.com/emailAddress=info@yassl.com + Validity + Not Before: Oct 24 18:27:13 2011 GMT + Not After : Jul 20 18:27:13 2014 GMT + Subject: C=US, ST=Montana, L=Bozeman, O=yaSSL, OU=Support, CN=www.yassl.com/emailAddress=info@yassl.com + Subject Public Key Info: + Public Key Algorithm: rsaEncryption + RSA Public Key: (2048 bit) + Modulus (2048 bit): + 00:c0:95:08:e1:57:41:f2:71:6d:b7:d2:45:41:27: + 01:65:c6:45:ae:f2:bc:24:30:b8:95:ce:2f:4e:d6: + f6:1c:88:bc:7c:9f:fb:a8:67:7f:fe:5c:9c:51:75: + f7:8a:ca:07:e7:35:2f:8f:e1:bd:7b:c0:2f:7c:ab: + 64:a8:17:fc:ca:5d:7b:ba:e0:21:e5:72:2e:6f:2e: + 86:d8:95:73:da:ac:1b:53:b9:5f:3f:d7:19:0d:25: + 4f:e1:63:63:51:8b:0b:64:3f:ad:43:b8:a5:1c:5c: + 34:b3:ae:00:a0:63:c5:f6:7f:0b:59:68:78:73:a6: + 8c:18:a9:02:6d:af:c3:19:01:2e:b8:10:e3:c6:cc: + 40:b4:69:a3:46:33:69:87:6e:c4:bb:17:a6:f3:e8: + dd:ad:73:bc:7b:2f:21:b5:fd:66:51:0c:bd:54:b3: + e1:6d:5f:1c:bc:23:73:d1:09:03:89:14:d2:10:b9: + 64:c3:2a:d0:a1:96:4a:bc:e1:d4:1a:5b:c7:a0:c0: + c1:63:78:0f:44:37:30:32:96:80:32:23:95:a1:77: + ba:13:d2:97:73:e2:5d:25:c9:6a:0d:c3:39:60:a4: + b4:b0:69:42:42:09:e9:d8:08:bc:33:20:b3:58:22: + a7:aa:eb:c4:e1:e6:61:83:c5:d2:96:df:d9:d0:4f: + ad:d7 + Exponent: 65537 (0x10001) + Signature Algorithm: sha1WithRSAEncryption + 71:4e:d3:62:df:cc:4c:f7:cd:b7:6e:52:0b:6c:6e:e0:bd:c2: + 2d:07:d7:c0:b0:6e:43:1e:35:bc:30:01:50:f0:ff:99:23:6c: + 18:1a:41:b6:11:d6:d4:19:61:fd:e4:77:97:1c:39:e1:57:ab: + c5:15:63:77:11:36:5e:74:e2:24:0b:1f:41:78:ad:b7:81:e7: + b4:40:66:80:f0:4b:91:a0:6d:a8:6e:3d:53:d9:8b:ce:2a:e1: + 0b:45:65:87:a1:96:ae:ee:3e:88:d5:12:1f:78:17:ae:2c:c5: + 73:44:d8:dc:f4:af:d8:cc:ae:4c:e1:0c:be:55:a4:99:f7:6e: + 96:c0:c8:45:87:bf:dc:51:57:ff:9e:73:37:6a:18:9c:c3:f9: + 22:7a:f4:b0:52:bd:fc:21:30:f8:c5:ff:1e:87:7d:ad:a2:5a: + 35:f5:22:a8:b4:0a:76:38:e6:76:b0:98:af:1b:ec:8a:0a:43: + 74:d2:85:34:37:84:07:e1:f6:23:b2:29:de:a6:b6:b7:4c:57: + 7e:96:06:cb:a9:16:25:29:3a:03:2d:55:7d:a6:8c:a4:f7:9e: + 81:c9:95:b6:7c:c1:4a:ce:94:66:0c:ca:88:eb:d2:09:f5:5b: + 19:58:82:df:27:fd:67:95:78:b7:02:06:d5:a7:61:bd:ef:3a: + fc:b2:61:cd +-----BEGIN CERTIFICATE----- +MIIDkDCCAngCAQIwDQYJKoZIhvcNAQEFBQAwgZAxCzAJBgNVBAYTAlVTMRAwDgYD +VQQIEwdNb250YW5hMRAwDgYDVQQHEwdCb3plbWFuMREwDwYDVQQKEwhTYXd0b290 +aDETMBEGA1UECxMKQ29uc3VsdGluZzEWMBQGA1UEAxMNd3d3Lnlhc3NsLmNvbTEd +MBsGCSqGSIb3DQEJARYOaW5mb0B5YXNzbC5jb20wHhcNMTExMDI0MTgyNzEzWhcN +MTQwNzIwMTgyNzEzWjCBijELMAkGA1UEBhMCVVMxEDAOBgNVBAgTB01vbnRhbmEx +EDAOBgNVBAcTB0JvemVtYW4xDjAMBgNVBAoTBXlhU1NMMRAwDgYDVQQLEwdTdXBw +b3J0MRYwFAYDVQQDEw13d3cueWFzc2wuY29tMR0wGwYJKoZIhvcNAQkBFg5pbmZv +QHlhc3NsLmNvbTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMCVCOFX +QfJxbbfSRUEnAWXGRa7yvCQwuJXOL07W9hyIvHyf+6hnf/5cnFF194rKB+c1L4/h +vXvAL3yrZKgX/Mpde7rgIeVyLm8uhtiVc9qsG1O5Xz/XGQ0lT+FjY1GLC2Q/rUO4 +pRxcNLOuAKBjxfZ/C1loeHOmjBipAm2vwxkBLrgQ48bMQLRpo0YzaYduxLsXpvPo +3a1zvHsvIbX9ZlEMvVSz4W1fHLwjc9EJA4kU0hC5ZMMq0KGWSrzh1Bpbx6DAwWN4 +D0Q3MDKWgDIjlaF3uhPSl3PiXSXJag3DOWCktLBpQkIJ6dgIvDMgs1gip6rrxOHm +YYPF0pbf2dBPrdcCAwEAATANBgkqhkiG9w0BAQUFAAOCAQEAcU7TYt/MTPfNt25S +C2xu4L3CLQfXwLBuQx41vDABUPD/mSNsGBpBthHW1Blh/eR3lxw54VerxRVjdxE2 +XnTiJAsfQXitt4HntEBmgPBLkaBtqG49U9mLzirhC0Vlh6GWru4+iNUSH3gXrizF +c0TY3PSv2MyuTOEMvlWkmfdulsDIRYe/3FFX/55zN2oYnMP5Inr0sFK9/CEw+MX/ +Hod9raJaNfUiqLQKdjjmdrCYrxvsigpDdNKFNDeEB+H2I7Ip3qa2t0xXfpYGy6kW +JSk6Ay1VfaaMpPeegcmVtnzBSs6UZgzKiOvSCfVbGViC3yf9Z5V4twIG1adhve86 +/LJhzQ== +-----END CERTIFICATE----- +Certificate: + Data: + Version: 3 (0x2) + Serial Number: + e9:d0:a7:5f:79:25:f4:3c + Signature Algorithm: sha1WithRSAEncryption + Issuer: C=US, ST=Montana, L=Bozeman, O=Sawtooth, OU=Consulting, CN=www.yassl.com/emailAddress=info@yassl.com + Validity + Not Before: Oct 24 18:18:15 2011 GMT + Not After : Jul 20 18:18:15 2014 GMT + Subject: C=US, ST=Montana, L=Bozeman, O=Sawtooth, OU=Consulting, CN=www.yassl.com/emailAddress=info@yassl.com + Subject Public Key Info: + Public Key Algorithm: rsaEncryption + RSA Public Key: (2048 bit) + Modulus (2048 bit): + 00:bf:0c:ca:2d:14:b2:1e:84:42:5b:cd:38:1f:4a: + f2:4d:75:10:f1:b6:35:9f:df:ca:7d:03:98:d3:ac: + de:03:66:ee:2a:f1:d8:b0:7d:6e:07:54:0b:10:98: + 21:4d:80:cb:12:20:e7:cc:4f:de:45:7d:c9:72:77: + 32:ea:ca:90:bb:69:52:10:03:2f:a8:f3:95:c5:f1: + 8b:62:56:1b:ef:67:6f:a4:10:41:95:ad:0a:9b:e3: + a5:c0:b0:d2:70:76:50:30:5b:a8:e8:08:2c:7c:ed: + a7:a2:7a:8d:38:29:1c:ac:c7:ed:f2:7c:95:b0:95: + 82:7d:49:5c:38:cd:77:25:ef:bd:80:75:53:94:3c: + 3d:ca:63:5b:9f:15:b5:d3:1d:13:2f:19:d1:3c:db: + 76:3a:cc:b8:7d:c9:e5:c2:d7:da:40:6f:d8:21:dc: + 73:1b:42:2d:53:9c:fe:1a:fc:7d:ab:7a:36:3f:98: + de:84:7c:05:67:ce:6a:14:38:87:a9:f1:8c:b5:68: + cb:68:7f:71:20:2b:f5:a0:63:f5:56:2f:a3:26:d2: + b7:6f:b1:5a:17:d7:38:99:08:fe:93:58:6f:fe:c3: + 13:49:08:16:0b:a7:4d:67:00:52:31:67:23:4e:98: + ed:51:45:1d:b9:04:d9:0b:ec:d8:28:b3:4b:bd:ed: + 36:79 + Exponent: 65537 (0x10001) + X509v3 extensions: + X509v3 Subject Key Identifier: + 27:8E:67:11:74:C3:26:1D:3F:ED:33:63:B3:A4:D8:1D:30:E5:E8:D5 + X509v3 Authority Key Identifier: + keyid:27:8E:67:11:74:C3:26:1D:3F:ED:33:63:B3:A4:D8:1D:30:E5:E8:D5 + DirName:/C=US/ST=Montana/L=Bozeman/O=Sawtooth/OU=Consulting/CN=www.yassl.com/emailAddress=info@yassl.com + serial:E9:D0:A7:5F:79:25:F4:3C + + X509v3 Basic Constraints: + CA:TRUE + Signature Algorithm: sha1WithRSAEncryption + 5f:86:14:f4:51:8b:bc:a5:4e:30:da:5e:ac:9a:f8:6c:d9:26: + 4b:93:f9:e3:1c:89:6f:9e:ee:b3:9d:77:3e:89:20:76:a3:e6: + e8:86:15:21:db:e2:33:b2:34:d5:d0:9f:f3:c1:a4:87:92:5c: + f9:d1:ff:30:2f:8e:03:bc:b3:3c:0c:32:a3:90:5f:1a:90:1e: + af:9d:f3:9e:d7:07:02:a9:7d:27:66:63:2f:af:18:d7:ac:18: + 98:8c:83:8f:38:f3:0b:ac:36:10:75:fb:ca:76:13:50:5b:02: + 8f:73:bf:e3:a0:ee:83:52:25:54:ce:26:ce:9c:bd:2f:79:ab: + 1b:60:b8:92:f1:03:c0:fc:3b:08:d9:c0:ad:d5:72:08:25:80: + 61:2d:dc:9f:a7:83:62:07:47:e0:07:4c:4b:07:30:04:a9:87: + 1c:55:7f:07:12:d0:cb:42:5d:cb:cf:66:01:1a:17:ee:f9:0f: + 60:b7:db:6f:68:e5:4e:41:62:6e:d3:6f:60:4f:4b:27:de:cf: + 18:07:f1:13:5d:cb:3f:a9:25:44:da:52:5c:c8:04:e1:56:12: + f5:2a:90:4e:d1:e2:af:01:b5:23:a1:ec:31:da:7b:63:69:c4: + b8:f3:e7:ce:a1:3d:c0:db:6d:f3:b2:d9:46:c8:9f:c3:b8:70: + 5a:1f:7f:ca +-----BEGIN CERTIFICATE----- +MIIEnjCCA4agAwIBAgIJAOnQp195JfQ8MA0GCSqGSIb3DQEBBQUAMIGQMQswCQYD +VQQGEwJVUzEQMA4GA1UECBMHTW9udGFuYTEQMA4GA1UEBxMHQm96ZW1hbjERMA8G +A1UEChMIU2F3dG9vdGgxEzARBgNVBAsTCkNvbnN1bHRpbmcxFjAUBgNVBAMTDXd3 +dy55YXNzbC5jb20xHTAbBgkqhkiG9w0BCQEWDmluZm9AeWFzc2wuY29tMB4XDTEx +MTAyNDE4MTgxNVoXDTE0MDcyMDE4MTgxNVowgZAxCzAJBgNVBAYTAlVTMRAwDgYD +VQQIEwdNb250YW5hMRAwDgYDVQQHEwdCb3plbWFuMREwDwYDVQQKEwhTYXd0b290 +aDETMBEGA1UECxMKQ29uc3VsdGluZzEWMBQGA1UEAxMNd3d3Lnlhc3NsLmNvbTEd +MBsGCSqGSIb3DQEJARYOaW5mb0B5YXNzbC5jb20wggEiMA0GCSqGSIb3DQEBAQUA +A4IBDwAwggEKAoIBAQC/DMotFLIehEJbzTgfSvJNdRDxtjWf38p9A5jTrN4DZu4q +8diwfW4HVAsQmCFNgMsSIOfMT95FfclydzLqypC7aVIQAy+o85XF8YtiVhvvZ2+k +EEGVrQqb46XAsNJwdlAwW6joCCx87aeieo04KRysx+3yfJWwlYJ9SVw4zXcl772A +dVOUPD3KY1ufFbXTHRMvGdE823Y6zLh9yeXC19pAb9gh3HMbQi1TnP4a/H2rejY/ +mN6EfAVnzmoUOIep8Yy1aMtof3EgK/WgY/VWL6Mm0rdvsVoX1ziZCP6TWG/+wxNJ +CBYLp01nAFIxZyNOmO1RRR25BNkL7Ngos0u97TZ5AgMBAAGjgfgwgfUwHQYDVR0O +BBYEFCeOZxF0wyYdP+0zY7Ok2B0w5ejVMIHFBgNVHSMEgb0wgbqAFCeOZxF0wyYd +P+0zY7Ok2B0w5ejVoYGWpIGTMIGQMQswCQYDVQQGEwJVUzEQMA4GA1UECBMHTW9u +dGFuYTEQMA4GA1UEBxMHQm96ZW1hbjERMA8GA1UEChMIU2F3dG9vdGgxEzARBgNV +BAsTCkNvbnN1bHRpbmcxFjAUBgNVBAMTDXd3dy55YXNzbC5jb20xHTAbBgkqhkiG +9w0BCQEWDmluZm9AeWFzc2wuY29tggkA6dCnX3kl9DwwDAYDVR0TBAUwAwEB/zAN +BgkqhkiG9w0BAQUFAAOCAQEAX4YU9FGLvKVOMNperJr4bNkmS5P54xyJb57us513 +PokgdqPm6IYVIdviM7I01dCf88Gkh5Jc+dH/MC+OA7yzPAwyo5BfGpAer53zntcH +Aql9J2ZjL68Y16wYmIyDjzjzC6w2EHX7ynYTUFsCj3O/46Dug1IlVM4mzpy9L3mr +G2C4kvEDwPw7CNnArdVyCCWAYS3cn6eDYgdH4AdMSwcwBKmHHFV/BxLQy0Jdy89m +ARoX7vkPYLfbb2jlTkFibtNvYE9LJ97PGAfxE13LP6klRNpSXMgE4VYS9SqQTtHi +rwG1I6HsMdp7Y2nEuPPnzqE9wNtt87LZRsifw7hwWh9/yg== +-----END CERTIFICATE----- diff --git a/certs/server-key.pem b/certs/server-key.pem new file mode 100644 index 00000000..d1627f4d --- /dev/null +++ b/certs/server-key.pem @@ -0,0 +1,27 @@ +-----BEGIN RSA PRIVATE KEY----- +MIIEpQIBAAKCAQEAwJUI4VdB8nFtt9JFQScBZcZFrvK8JDC4lc4vTtb2HIi8fJ/7 +qGd//lycUXX3isoH5zUvj+G9e8AvfKtkqBf8yl17uuAh5XIuby6G2JVz2qwbU7lf +P9cZDSVP4WNjUYsLZD+tQ7ilHFw0s64AoGPF9n8LWWh4c6aMGKkCba/DGQEuuBDj +xsxAtGmjRjNph27Euxem8+jdrXO8ey8htf1mUQy9VLPhbV8cvCNz0QkDiRTSELlk +wyrQoZZKvOHUGlvHoMDBY3gPRDcwMpaAMiOVoXe6E9KXc+JdJclqDcM5YKS0sGlC +Qgnp2Ai8MyCzWCKnquvE4eZhg8XSlt/Z0E+t1wIDAQABAoIBAQCa0DQPUmIFUAHv +n+1kbsLE2hryhNeSEEiSxOlq64t1bMZ5OPLJckqGZFSVd8vDmp231B2kAMieTuTd +x7pnFsF0vKnWlI8rMBr77d8hBSPZSjm9mGtlmrjcxH3upkMVLj2+HSJgKnMw1T7Y +oqyGQy7E9WReP4l1DxHYUSVOn9iqo85gs+KK2X4b8GTKmlsFC1uqy+XjP24yIgXz +0PrvdFKB4l90073/MYNFdfpjepcu1rYZxpIm5CgGUFAOeC6peA0Ul7QS2DFAq6EB +QcIw+AdfFuRhd9Jg8p+N6PS662PeKpeB70xs5lU0USsoNPRTHMRYCj+7r7X3SoVD +LTzxWFiBAoGBAPIsVHY5I2PJEDK3k62vvhl1loFk5rW4iUJB0W3QHBv4G6xpyzY8 +ZH3c9Bm4w2CxV0hfUk9ZOlV/MsAZQ1A/rs5vF/MOn0DKTq0VO8l56cBZOHNwnAp8 +yTpIMqfYSXUKhcLC/RVz2pkJKmmanwpxv7AEpox6Wm9IWlQ7xrFTF9/nAoGBAMuT +3ncVXbdcXHzYkKmYLdZpDmOzo9ymzItqpKISjI57SCyySzfcBhh96v52odSh6T8N +zRtfr1+elltbD6F8r7ObkNtXczrtsCNErkFPHwdCEyNMy/r0FKTV9542fFufqDzB +hV900jkt/9CE3/uzIHoumxeu5roLrl9TpFLtG8SRAoGBAOyY2rvV/vlSSn0CVUlv +VW5SL4SjK7OGYrNU0mNS2uOIdqDvixWl0xgUcndex6MEH54ZYrUbG57D8rUy+UzB +qusMJn3UX0pRXKRFBnBEp1bA1CIUdp7YY1CJkNPiv4GVkjFBhzkaQwsYpVMfORpf +H0O8h2rfbtMiAP4imHBOGhkpAoGBAIpBVihRnl/Ungs7mKNU8mxW1KrpaTOFJAza +1AwtxL9PAmk4fNTm3Ezt1xYRwz4A58MmwFEC3rt1nG9WnHrzju/PisUr0toGakTJ +c/5umYf4W77xfOZltU9s8MnF/xbKixsX4lg9ojerAby/QM5TjI7t7+5ZneBj5nxe +9Y5L8TvBAoGATUX5QIzFW/QqGoq08hysa+kMVja3TnKW1eWK0uL/8fEYEz2GCbjY +dqfJHHFSlDBD4PF4dP1hG0wJzOZoKnGtHN9DvFbbpaS+NXCkXs9P/ABVmTo9I89n +WvUi+LUp0EQR6zUuRr79jhiyX6i/GTKh9dwD5nyaHwx8qbAOITc78bA= +-----END RSA PRIVATE KEY----- From 4b251d446c7d12bc29e91a4b6d99e4684fa451ec Mon Sep 17 00:00:00 2001 From: Chris Conlon Date: Mon, 30 Jun 2014 09:52:39 -0600 Subject: [PATCH 3/5] add initial DTLS examples --- dtls/Makefile | 31 +++ dtls/client-dtls-nonblocking.c | 231 ++++++++++++++++++++++ dtls/client-dtls-resume.c | 151 +++++++++++++++ dtls/client-dtls.c | 108 +++++++++++ dtls/client-udp.c | 62 ++++++ dtls/server-dtls-nonblocking.c | 345 +++++++++++++++++++++++++++++++++ dtls/server-dtls.c | 220 +++++++++++++++++++++ dtls/server-udp.c | 96 +++++++++ dtls/tutorial-udp-dtls.c | 5 + 9 files changed, 1249 insertions(+) create mode 100644 dtls/Makefile create mode 100644 dtls/client-dtls-nonblocking.c create mode 100644 dtls/client-dtls-resume.c create mode 100644 dtls/client-dtls.c create mode 100644 dtls/client-udp.c create mode 100644 dtls/server-dtls-nonblocking.c create mode 100644 dtls/server-dtls.c create mode 100644 dtls/server-udp.c create mode 100644 dtls/tutorial-udp-dtls.c diff --git a/dtls/Makefile b/dtls/Makefile new file mode 100644 index 00000000..d9cdf38a --- /dev/null +++ b/dtls/Makefile @@ -0,0 +1,31 @@ +CC=gcc +CFLAGS=-Wall -DCYASSL_DTLS +LIBS=-lcyassl + +all: client-udp client-dtls client-dtls-nonblocking client-dtls-resume server-udp server-dtls server-dtls-nonblocking + +client-udp: client-udp.o + $(CC) -o $@ $^ $(CFLAGS) + +client-dtls: client-dtls.o + $(CC) -o $@ $^ $(CFLAGS) $(LIBS) + +client-dtls-nonblocking: client-dtls-nonblocking.o + $(CC) -o $@ $^ $(CFLAGS) $(LIBS) + +client-dtls-resume: client-dtls-resume.o + $(CC) -o $@ $^ $(CFLAGS) $(LIBS) + +server-udp: server-udp.o + $(CC) -o $@ $^ $(CFLAGS) + +server-dtls: server-dtls.o + $(CC) -o $@ $^ $(CFLAGS) $(LIBS) + +server-dtls-nonblocking: server-dtls-nonblocking.o + $(CC) -o $@ $^ $(CFLAGS) $(LIBS) + +.PHONY: clean all + +clean: + rm -f *.o client-udp client-dtls client-dtls-nonblocking client-dtls-resume server-udp server-dtls server-dtls-nonblocking diff --git a/dtls/client-dtls-nonblocking.c b/dtls/client-dtls-nonblocking.c new file mode 100644 index 00000000..2cad1777 --- /dev/null +++ b/dtls/client-dtls-nonblocking.c @@ -0,0 +1,231 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define MAXLINE 4096 +#define SERV_PORT 11111 + +enum { + TEST_SELECT_FAIL, + TEST_TIMEOUT, + TEST_RECV_READY, + TEST_ERROR_READY +}; + +/* Tcp select using dtls nonblocking function */ +static int dtls_select(int socketfd, int to_sec) +{ + + fd_set recvfds, errfds; + int nfds = socketfd +1; + struct timeval timeout = { (to_sec > 0) ? to_sec : 0, 0}; + int result; + + FD_ZERO(&recvfds); + FD_SET(socketfd, &recvfds); + FD_ZERO(&errfds); + FD_SET(socketfd, &errfds); + + result = select(nfds, &recvfds, NULL, &errfds, &timeout); + + if (result == 0) + return TEST_TIMEOUT; + else if (result > 0) { + if (FD_ISSET(socketfd, &recvfds)) + return TEST_RECV_READY; + else if (FD_ISSET(socketfd, &errfds)) + return TEST_ERROR_READY; + } + return TEST_SELECT_FAIL; +} + +/* Connect using Nonblocking - DTLS version */ +static void NonBlockingDTLS_Connect(CYASSL* ssl) +{ + int ret = CyaSSL_connect(ssl); + int error = CyaSSL_get_error(ssl, 0); + int sockfd = (int)CyaSSL_get_fd(ssl); + int select_ret; + + while (ret != SSL_SUCCESS && (error == SSL_ERROR_WANT_READ || + error == SSL_ERROR_WANT_WRITE)) { + int currTimeout = 1; + if (error == SSL_ERROR_WANT_READ) + printf("... client would read block\n"); + else + printf("... client would write block\n"); + currTimeout = CyaSSL_dtls_get_current_timeout(ssl); + select_ret = dtls_select(sockfd, currTimeout); + if ( ( select_ret == TEST_RECV_READY) || + (select_ret == TEST_ERROR_READY)) { + ret = CyaSSL_connect(ssl); + error = CyaSSL_get_error(ssl, 0); + } + else if (select_ret == TEST_TIMEOUT && !CyaSSL_dtls(ssl)) { + error = 2; + } + else if (select_ret == TEST_TIMEOUT && CyaSSL_dtls(ssl) && + CyaSSL_dtls_got_timeout(ssl) >= 0) { + error = 2; + } + else{ + error = SSL_FATAL_ERROR; + } + } + + if (ret != SSL_SUCCESS) { + printf("SSL_connect failed with"); + } +} + +/* Main send and receive function */ +void DatagramClient (CYASSL* ssl) +{ + int n = 0; + char sendLine[MAXLINE], recvLine[MAXLINE - 1]; + + while (fgets(sendLine, MAXLINE, stdin) != NULL) { + + while ( ( CyaSSL_write(ssl, sendLine, strlen(sendLine))) != + strlen(sendLine)) { + printf("SSL_write failed"); + } + + while ( (n = CyaSSL_read(ssl, recvLine, sizeof(recvLine)-1)) <= 0) { + + int readErr = CyaSSL_get_error(ssl, 0); + if(readErr != SSL_ERROR_WANT_READ) + printf("CyaSSL_read failed"); + } + + recvLine[n] = '\0'; + fputs(recvLine, stdout); + } +} + + +int main (int argc, char** argv) +{ + int sockfd = 0; + struct sockaddr_in servAddr; + const char* host = argv[1]; + CYASSL* ssl = 0; + CYASSL_CTX* ctx = 0; + CYASSL* sslResume = 0; + CYASSL_SESSION* session = 0; + int resumeSession = 0; + char cert_array[] = "../cyassl/certs/ca-cert.pem"; + char* certs = cert_array; + char* srTest = "testing session resume"; + + if (argc != 2) { + printf("usage: udpcli \n"); + return 1; + } + + CyaSSL_Init(); + + /* CyaSSL_Debugging_ON();*/ + + if ( (ctx = CyaSSL_CTX_new(CyaDTLSv1_2_client_method())) == NULL) { + fprintf(stderr, "CyaSSL_CTX_new error.\n"); + return(EXIT_FAILURE); + } + + if (CyaSSL_CTX_load_verify_locations(ctx,certs, 0) != SSL_SUCCESS) { + fprintf(stderr, "Error loading %s, please check the file.\n", certs); + return(EXIT_FAILURE); + } + + ssl = CyaSSL_new(ctx); + if (ssl == NULL) { + printf("unable to get ssl object"); + return 1; + } + + memset(&servAddr, 0, sizeof(servAddr)); + servAddr.sin_family = AF_INET; + servAddr.sin_port = htons(SERV_PORT); + if (inet_pton(AF_INET, host, &servAddr.sin_addr) < 1) { + printf("Error and/or invalid IP address"); + return 1; + } + + CyaSSL_dtls_set_peer(ssl, &servAddr, sizeof(servAddr)); + + if ( (sockfd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) { + printf("cannot create a socket."); + return 1; + } + + CyaSSL_set_fd(ssl, sockfd); + CyaSSL_set_using_nonblock(ssl, 1); + fcntl(sockfd, F_SETFL, O_NONBLOCK); + NonBlockingDTLS_Connect(ssl); + + DatagramClient(ssl); + while ( (CyaSSL_write(ssl, srTest, sizeof(srTest))) != sizeof(srTest)) { + printf("failed to write"); + return 1; + } + + session = CyaSSL_get_session(ssl); + sslResume = CyaSSL_new(ctx); + + CyaSSL_shutdown(ssl); + CyaSSL_free(ssl); + close(sockfd); + + memset(&servAddr, 0, sizeof(servAddr)); + servAddr.sin_family = AF_INET; + servAddr.sin_port = htons(SERV_PORT); + if (inet_pton(AF_INET, host, &servAddr.sin_addr) < 1) { + printf("Error and/or invalid IP address"); + return 1; + } + + CyaSSL_dtls_set_peer(sslResume, &servAddr, sizeof(servAddr)); + + if ( (sockfd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) { + printf("cannot create a socket."); + return 1; + } + + CyaSSL_set_fd(sslResume, sockfd); + CyaSSL_set_session(sslResume, session); + CyaSSL_set_using_nonblock(sslResume, 1); + fcntl(sockfd, F_SETFL, O_NONBLOCK); + NonBlockingDTLS_Connect(sslResume); + + if(CyaSSL_session_reused(sslResume)) + printf("reused session id\n"); + else + printf("didn't reuse session id!!!\n"); + + DatagramClient(sslResume); + while ((CyaSSL_write(sslResume, srTest, sizeof(srTest))) != sizeof(srTest)) + { + printf("failed to write"); + return 1; + } + sleep(1); + + CyaSSL_shutdown(sslResume); + CyaSSL_free(sslResume); + + close(sockfd); + CyaSSL_CTX_free(ctx); + CyaSSL_Cleanup(); + + return 0; +} + diff --git a/dtls/client-dtls-resume.c b/dtls/client-dtls-resume.c new file mode 100644 index 00000000..f384a675 --- /dev/null +++ b/dtls/client-dtls-resume.c @@ -0,0 +1,151 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define MAXLINE 4096 +#define SERV_PORT 11111 + +/* Send and receive function */ +void DatagramClient (CYASSL* ssl) +{ + int n = 0; + char sendLine[MAXLINE], recvLine[MAXLINE - 1]; + + while (fgets(sendLine, MAXLINE, stdin) != NULL) { + + if ( ( CyaSSL_write(ssl, sendLine, strlen(sendLine))) != + strlen(sendLine)) { + printf("SSL_write failed"); + } + + n = CyaSSL_read(ssl, recvLine, sizeof(recvLine)-1); + + if (n < 0) { + int readErr = CyaSSL_get_error(ssl, 0); + if(readErr != SSL_ERROR_WANT_READ) + printf("CyaSSL_read failed"); + } + + recvLine[n] = '\0'; + fputs(recvLine, stdout); + } +} + +int main (int argc, char** argv) +{ + int sockfd = 0; + struct sockaddr_in servAddr; + const char* host = argv[1]; + CYASSL* ssl = 0; + CYASSL_CTX* ctx = 0; + CYASSL* sslResume = 0; + CYASSL_SESSION* session = 0; + char* srTest = "testing session resume"; + char cert_array[] = "../cyassl/certs/ca-cert.pem"; + char* certs = cert_array; + if (argc != 2) { + printf("usage: udpcli \n"); + return 1; + } + + CyaSSL_Init(); + /* CyaSSL_Debugging_ON(); */ + + if ( (ctx = CyaSSL_CTX_new(CyaDTLSv1_2_client_method())) == NULL) { + fprintf(stderr, "CyaSSL_CTX_new error.\n"); + return 1; + } + + if (CyaSSL_CTX_load_verify_locations(ctx, certs, 0) != SSL_SUCCESS) { + fprintf(stderr, "Error loading %s, please check the file.\n", certs); + return 1; + } + + ssl = CyaSSL_new(ctx); + if (ssl == NULL) { + printf("unable to get ssl object"); + return 1; + } + + memset(&servAddr, 0, sizeof(servAddr)); + servAddr.sin_family = AF_INET; + servAddr.sin_port = htons(SERV_PORT); + if ( (inet_pton(AF_INET, host, &servAddr.sin_addr)) < 1) { + printf("Error and/or invalid IP address"); + return 1; + } + + CyaSSL_dtls_set_peer(ssl, &servAddr, sizeof(servAddr)); + + if ( (sockfd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) { + printf("cannot create a socket."); + return 1; + } + + CyaSSL_set_fd(ssl, sockfd); + if (CyaSSL_connect(ssl) != SSL_SUCCESS) { + int err1 = CyaSSL_get_error(ssl, 0); + char buffer[80]; + printf("err = %d, %s\n", err1, CyaSSL_ERR_error_string(err1, buffer)); + printf("SSL_connect failed"); + return 1; + } + + DatagramClient(ssl); + CyaSSL_write(ssl, srTest, sizeof(srTest)); + session = CyaSSL_get_session(ssl); + sslResume = CyaSSL_new(ctx); + + CyaSSL_shutdown(ssl); + CyaSSL_free(ssl); + close(sockfd); + + memset(&servAddr, 0, sizeof(servAddr)); + servAddr.sin_family = AF_INET; + servAddr.sin_port = htons(SERV_PORT); + if ( (inet_pton(AF_INET, host, &servAddr.sin_addr)) < 1) { + printf("Error and/or invalid IP address"); + return 1; + } + + CyaSSL_dtls_set_peer(sslResume, &servAddr, sizeof(servAddr)); + + if ( (sockfd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) { + printf("cannot create a socket."); + return 1; + } + + CyaSSL_set_fd(sslResume, sockfd); + CyaSSL_set_session(sslResume, session); + + if (CyaSSL_connect(sslResume) != SSL_SUCCESS) { + printf("SSL_connect failed"); + return 1; + } + + if(CyaSSL_session_reused(sslResume)) + printf("reused session id\n"); + else + printf("didn't reuse session id!!!\n"); + + DatagramClient(sslResume); + + CyaSSL_write(sslResume, srTest, sizeof(srTest)); + + CyaSSL_shutdown(sslResume); + CyaSSL_free(sslResume); + + close(sockfd); + CyaSSL_CTX_free(ctx); + CyaSSL_Cleanup(); + + return 0; +} + diff --git a/dtls/client-dtls.c b/dtls/client-dtls.c new file mode 100644 index 00000000..9991c7c4 --- /dev/null +++ b/dtls/client-dtls.c @@ -0,0 +1,108 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define MAXLINE 4096 +#define SERV_PORT 11111 + +/* Send and receive function */ +void DatagramClient (CYASSL* ssl) +{ + int n = 0; + char m, sendLine[MAXLINE], recvLine[MAXLINE - 1]; + + while (fgets(sendLine, MAXLINE, stdin) != NULL) { + + if ( ( CyaSSL_write(ssl, sendLine, strlen(sendLine))) != + strlen(sendLine)) { + printf("SSL_write failed"); + } + + n = CyaSSL_read(ssl, recvLine, sizeof(recvLine)-1); + + if (n < 0) { + int readErr = CyaSSL_get_error(ssl, 0); + if(readErr != SSL_ERROR_WANT_READ) { + printf("CyaSSL_read failed"); + } + } + + recvLine[n] = '\0'; + fputs(recvLine, stdout); + } +} + +int main (int argc, char** argv) +{ + int sockfd = 0; + struct sockaddr_in servAddr; + CYASSL* ssl = 0; + CYASSL_CTX* ctx = 0; + char cert_array[] = "../cyassl/certs/ca-cert.pem"; + char* certs = cert_array; + + if (argc != 2) { + printf("usage: udpcli \n"); + return 1; + } + + CyaSSL_Init(); + /* CyaSSL_Debugging_ON(); */ + + if ( (ctx = CyaSSL_CTX_new(CyaDTLSv1_2_client_method())) == NULL) { + fprintf(stderr, "CyaSSL_CTX_new error.\n"); + return 1; + } + + if (CyaSSL_CTX_load_verify_locations(ctx, certs, 0) + != SSL_SUCCESS) { + fprintf(stderr, "Error loading %s, please check the file.\n", certs); + return 1; + } + + ssl = CyaSSL_new(ctx); + if (ssl == NULL) { + printf("unable to get ssl object"); + return 1; + } + + memset(&servAddr, 0, sizeof(servAddr)); + servAddr.sin_family = AF_INET; + servAddr.sin_port = htons(SERV_PORT); + if (inet_pton(AF_INET, argv[1], &servAddr.sin_addr) < 1) { + printf("Error and/or invalid IP address"); + return 1; + } + + CyaSSL_dtls_set_peer(ssl, &servAddr, sizeof(servAddr)); + + if ( (sockfd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) { + printf("cannot create a socket."); + return 1; + } + CyaSSL_set_fd(ssl, sockfd); + if (CyaSSL_connect(ssl) != SSL_SUCCESS) { + int err1 = CyaSSL_get_error(ssl, 0); + printf("err = %d, %d\n", err1, CyaSSL_ERR_reason_error_string(err1)); + printf("SSL_connect failed"); + return 1; + } + + DatagramClient(ssl); + + CyaSSL_shutdown(ssl); + CyaSSL_free(ssl); + close(sockfd); + CyaSSL_CTX_free(ctx); + CyaSSL_Cleanup(); + + return 0; +} + diff --git a/dtls/client-udp.c b/dtls/client-udp.c new file mode 100644 index 00000000..6a62b197 --- /dev/null +++ b/dtls/client-udp.c @@ -0,0 +1,62 @@ +#include +#include +#include +#include +#include +#include + +#define MAXLINE 4096 +#define SERV_PORT 11111 + +/* send and recieve message function */ +void DatagramClient (FILE* clientInput, int sockfd, + const struct sockaddr* servAddr, socklen_t servLen) +{ + + int n; + char sendLine[MAXLINE], recvLine[MAXLINE +1]; + + while (fgets(sendLine, MAXLINE, clientInput) != NULL) { + + if ( ( sendto(sockfd, sendLine, strlen(sendLine) - 1, 0, servAddr, + servLen)) == -1) { + printf("error in sending"); + } + + + if ( (n = recvfrom(sockfd, recvLine, MAXLINE, 0, NULL, NULL)) == -1) { + printf("Error in receiving"); + } + + recvLine[n] = 0; + fputs(recvLine, stdout); + } +} + +int main(int argc, char** argv) +{ + + int sockfd; + struct sockaddr_in servAddr; + + if (argc != 2) { + printf("usage: udpcli \n"); + return 1; + } + + if ( (sockfd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) { + printf("cannot create a socket."); + return 1; + } + + memset(&servAddr, sizeof(servAddr), 0); + servAddr.sin_family = AF_INET; + servAddr.sin_port = htons(SERV_PORT); + inet_pton(AF_INET, argv[1], &servAddr.sin_addr); + + DatagramClient(stdin, sockfd, (struct sockaddr*) &servAddr, + sizeof(servAddr)); + + return 0; +} + diff --git a/dtls/server-dtls-nonblocking.c b/dtls/server-dtls-nonblocking.c new file mode 100644 index 00000000..54161984 --- /dev/null +++ b/dtls/server-dtls-nonblocking.c @@ -0,0 +1,345 @@ +/* server-dtls.c + * + * Copyright (C) 2006-2014 wolfSSL Inc. + * + * This file is part of CyaSSL. + * + * CyaSSL is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * CyaSSL is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, + * USA + *============================================================================= + * + * Bare-bones example of a DTLS erver for instructional/learning purposes. + * Utilizes DTLS 1.2. + */ + +#include /* standard in/out procedures */ +#include /* defines system calls */ +#include /* necessary for memset */ +#include +#include /* used for all socket calls */ +#include /* used for sockaddr_in */ +#include +#include +#include +#include +#include +#include + +#define SERV_PORT 11111 /* define our server port number */ +#define MSGLEN 4096 + +static int cleanup; /* To handle shutdown */ + +void dtls_set_nonblocking(int*); /* set the socket non-blocking */ +int NonBlockingSSL_Accept(CYASSL*);/* non-blocking accept */ +int AwaitDGram(CYASSL_CTX* ctx); /* Separate out Handling Datagrams */ +int udp_read_connect(int); /* broken out to improve readability */ +int dtls_select(); + +/* costumes for select_ret to wear */ +enum { + TEST_SELECT_FAIL, + TEST_TIMEOUT, + TEST_RECV_READY, + TEST_ERROR_READY +}; + +int AwaitDGram(CYASSL_CTX* ctx) +{ + int on = 1; + int res = 1; + int recvLen; /* length of string read */ + int readWriteErr; + int listenfd = 0; /* Initialize our socket */ + int clientfd = 0; /* client connection */ + int len = sizeof(on); + int cont; + char buff[MSGLEN]; /* string read from client */ + CYASSL* ssl = NULL; /* Initialize ssl object */ + struct sockaddr_in servAddr; /* our server's address */ + char ack[] = "I hear you fashizzle\n"; + + while (cleanup != 1) { + + /* Create a UDP/IP socket */ + if ((listenfd = socket(AF_INET, SOCK_DGRAM, 0)) < 0 ) { + printf("Cannot create socket.\n"); + return 1; + } + + printf("Socket allocated\n"); + memset((char *)&servAddr, 0, sizeof(servAddr)); + + /* host-to-network-long conversion (htonl) */ + /* host-to-network-short conversion (htons) */ + servAddr.sin_family = AF_INET; + servAddr.sin_addr.s_addr = htonl(INADDR_ANY); + servAddr.sin_port = htons(SERV_PORT); + + /* Eliminate socket already in use error */ + res = setsockopt(listenfd, SOL_SOCKET, SO_REUSEADDR, &on, len); + if (res < 0) { + printf("Setsockopt SO_REUSEADDR failed.\n"); + return 1; + } + + /*Bind Socket*/ + if (bind(listenfd, + (struct sockaddr *)&servAddr, sizeof(servAddr)) < 0) { + printf("Bind failed.\n"); + return 1; + } + + printf("Awaiting client connection on port %d\n", SERV_PORT); + + clientfd = udp_read_connect(listenfd); + dtls_set_nonblocking(&clientfd); + + /* Create the CYASSL Object */ + if (( ssl = CyaSSL_new(ctx)) == NULL) { + printf("CyaSSL_new error.\n"); + return 1; + } + + /* set clilen to |cliAddr| */ + printf("Connected!\n"); + + /* set the/ session ssl to client connection port */ + CyaSSL_set_fd(ssl, clientfd); + + CyaSSL_set_using_nonblock(ssl, 1); + cont = NonBlockingSSL_Accept(ssl); + + if (cont != 0) { + printf("NonBlockingSSL_Accept failed.\n"); + return 1; + } + + /* Begin: Reply to the client */ + recvLen = CyaSSL_read(ssl, buff, sizeof(buff)-1); + + /* Begin do-while read */ + do { + if (cleanup == 1) { + memset(buff, 0, sizeof(buff)); + break; + } + if (recvLen < 0) { + readWriteErr = CyaSSL_get_error(ssl, 0); + if (readWriteErr != SSL_ERROR_WANT_READ) { + printf("Read Error, error was: %d.\n", readWriteErr); + cleanup = 1; + } else { + recvLen = CyaSSL_read(ssl, buff, sizeof(buff)-1); + } + } + } while (readWriteErr == SSL_ERROR_WANT_READ && + recvLen < 0 && + cleanup != 1); + /* End do-while read */ + + if (recvLen > 0) { + buff[recvLen] = 0; + printf("I heard this:\"%s\"\n", buff); + } + else { + printf("Connection Timed Out.\n"); + } + + /* Begin do-while write */ + do { + if (cleanup == 1) { + memset(&buff, 0, sizeof(buff)); + break; + } + readWriteErr = CyaSSL_get_error(ssl, 0); + if (CyaSSL_write(ssl, ack, sizeof(ack)) < 0) { + printf("Write error.\n"); + cleanup = 1; + } + printf("Reply sent:\"%s\"\n", ack); + }while(readWriteErr == SSL_ERROR_WANT_WRITE && cleanup != 1); + /* End do-while write */ + + /* free allocated memory */ + memset(buff, 0, sizeof(buff)); + CyaSSL_free(ssl); + + /* End: Reply to the Client */ + } + return 0; +} + +int udp_read_connect(int listenfd) +{ + int bytesRecvd; + unsigned char b[MSGLEN]; + struct sockaddr_in cliAddr; + socklen_t clilen = sizeof(cliAddr); + + + bytesRecvd = (int)recvfrom(listenfd, (char*)b, sizeof(b), MSG_PEEK, + (struct sockaddr*)&cliAddr, &clilen); + if (bytesRecvd > 0) { + if (connect(listenfd, (const struct sockaddr*)&cliAddr, + sizeof(cliAddr)) != 0) { + printf("udp connect failed.\n"); + } + } + else { + printf("recvfrom failed.\n"); + } + /* ensure b is empty upon each call */ + memset(&b, 0, sizeof(b)); + return listenfd; +} + +int NonBlockingSSL_Accept(CYASSL* ssl) +{ + int select_ret; + int currTimeout = 1; + int ret = CyaSSL_accept(ssl); + int error = CyaSSL_get_error(ssl, 0); + int listenfd = (int)CyaSSL_get_fd(ssl); + + while (cleanup != 1 && (ret != SSL_SUCCESS && + (error == SSL_ERROR_WANT_READ || + error == SSL_ERROR_WANT_WRITE))) { + if (cleanup == 1) { + CyaSSL_free(ssl); + CyaSSL_shutdown(ssl); + break; + } + + if (error == SSL_ERROR_WANT_READ) + printf("... server would read block\n"); + else + printf("... server would write block\n"); + + currTimeout = CyaSSL_dtls_get_current_timeout(ssl); + select_ret = dtls_select(listenfd, currTimeout); + + if ((select_ret == TEST_RECV_READY) || + (select_ret == TEST_ERROR_READY)) { + ret = CyaSSL_accept(ssl); + error = CyaSSL_get_error(ssl, 0); + } + else if (select_ret == TEST_TIMEOUT && !CyaSSL_dtls(ssl)) { + error = SSL_ERROR_WANT_READ; + } + else if (select_ret == TEST_TIMEOUT && CyaSSL_dtls(ssl) && + CyaSSL_dtls_got_timeout(ssl) >= 0) { + error = SSL_ERROR_WANT_READ; + } + else { + error = SSL_FATAL_ERROR; + } + } + if (ret != SSL_SUCCESS) { + printf("SSL_accept failed.\n"); + return 1; + } + + return 0; +} + +void dtls_set_nonblocking(int* sockfd) +{ + int flags = fcntl(*sockfd, F_GETFL, 0); + if (flags < 0) { + printf("fcntl get failed"); + cleanup = 1; + } + flags = fcntl(*sockfd, F_SETFL, flags | O_NONBLOCK); + if (flags < 0) { + printf("fcntl set failed.\n"); + cleanup = 1; + } +} + +int dtls_select(int socketfd, int toSec) +{ + int result; + int nfds = socketfd + 1; + fd_set recvfds, errfds; + struct timeval timeout = { (toSec > 0) ? toSec : 0, 0}; + + FD_ZERO(&recvfds); + FD_SET(socketfd, &recvfds); + FD_ZERO(&errfds); + FD_SET(socketfd, &errfds); + + result = select(nfds, &recvfds, NULL, &errfds, &timeout); + + if (result == 0) + return TEST_TIMEOUT; + else if (result > 0) { + if (FD_ISSET(socketfd, &recvfds)) + return TEST_RECV_READY; + else if(FD_ISSET(socketfd, &errfds)) + return TEST_ERROR_READY; + } + + return TEST_SELECT_FAIL; +} + +int main(int argc, char** argv) +{ + /* cont short for "continue?", Loc short for "location" */ + int cont = 0; + char caCertLoc[] = "../certs/ca-cert.pem"; + char servCertLoc[] = "../certs/server-cert.pem"; + char servKeyLoc[] = "../certs/server-key.pem"; + CYASSL_CTX* ctx; + + /* "./config --enable-debug" and uncomment next line for debugging */ + /* CyaSSL_Debugging_ON(); */ + + /* Initialize CyaSSL */ + CyaSSL_Init(); + + /* Set ctx to DTLS 1.2 */ + if ((ctx = CyaSSL_CTX_new(CyaDTLSv1_2_server_method())) == NULL) { + printf("CyaSSL_CTX_new error.\n"); + return 1; + } + /* Load CA certificates */ + if (CyaSSL_CTX_load_verify_locations(ctx,caCertLoc,0) != + SSL_SUCCESS) { + printf("Error loading %s, please check the file.\n", caCertLoc); + return 1; + } + /* Load server certificates */ + if (CyaSSL_CTX_use_certificate_file(ctx, servCertLoc, SSL_FILETYPE_PEM) != + SSL_SUCCESS) { + printf("Error loading %s, please check the file.\n", servCertLoc); + return 1; + } + /* Load server Keys */ + if (CyaSSL_CTX_use_PrivateKey_file(ctx, servKeyLoc, + SSL_FILETYPE_PEM) != SSL_SUCCESS) { + printf("Error loading %s, please check the file.\n", servKeyLoc); + return 1; + } + + cont = AwaitDGram(ctx); + + if (cont == 1) { + CyaSSL_CTX_free(ctx); + CyaSSL_Cleanup(); + } + + return 0; +} diff --git a/dtls/server-dtls.c b/dtls/server-dtls.c new file mode 100644 index 00000000..4ef910e3 --- /dev/null +++ b/dtls/server-dtls.c @@ -0,0 +1,220 @@ +/* server-dtls.c + * + * Copyright (C) 2006-2014 wolfSSL Inc. + * + * This file is part of CyaSSL. + * + * CyaSSL is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * CyaSSL is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, + * USA + *============================================================================= + * + * Bare-bones example of a DTLS server for instructional/learning purposes. + * Utilizes DTLS 1.2. + */ + +#include /* standard in/out procedures */ +#include /* defines system calls */ +#include /* necessary for memset */ +#include +#include /* used for all socket calls */ +#include /* used for sockaddr_in */ +#include +#include +#include +#include +#include + +#define SERV_PORT 11111 /* define our server port number */ +#define MSGLEN 4096 + +static int cleanup; /* To handle shutdown */ +struct sockaddr_in servAddr; /* our server's address */ +struct sockaddr_in cliaddr; /* the client's address */ + +int AwaitDGram(CYASSL_CTX* ctx); /* Separate out Handling Datagrams */ +void CleanUp(); + +int AwaitDGram(CYASSL_CTX* ctx) +{ + int on = 1; + int res = 1; + int connfd = 0; + int recvLen = 0; /* length of message */ + int listenfd = 0; /* Initialize our socket */ + CYASSL* ssl = NULL; + socklen_t cliLen; + socklen_t len = sizeof(on); + unsigned char b[MSGLEN]; /* watch for incoming messages */ + char buff[MSGLEN]; /* the incoming message */ + char ack[] = "I hear you fashizzle!\n"; + + while (cleanup != 1) { + /* Create a UDP/IP socket */ + if ((listenfd = socket(AF_INET, SOCK_DGRAM, 0)) < 0 ) { + printf("Cannot create socket.\n"); + cleanup = 1; + } + printf("Socket all/ocated\n"); + + /* clear servAddr each loop */ + memset((char *)&servAddr, 0, sizeof(servAddr)); + + /* host-to-network-long conversion (htonl) */ + /* host-to-network-short conversion (htons) */ + servAddr.sin_family = AF_INET; + servAddr.sin_addr.s_addr = htonl(INADDR_ANY); + servAddr.sin_port = htons(SERV_PORT); + + /* Eliminate socket already in use error */ + res = setsockopt(listenfd, SOL_SOCKET, SO_REUSEADDR, &on, len); + if (res < 0) { + printf("Setsockopt SO_REUSEADDR failed.\n"); + cleanup = 1; + return 1; + } + + /*Bind Socket*/ + if (bind(listenfd, + (struct sockaddr *)&servAddr, sizeof(servAddr)) < 0) { + printf("Bind failed.\n"); + cleanup = 1; + return 1; + } + + printf("Awaiting client connection on port %d\n", SERV_PORT); + + cliLen = sizeof(cliaddr); + connfd = (int)recvfrom(listenfd, (char *)&b, sizeof(b), MSG_PEEK, + (struct sockaddr*)&cliaddr, &cliLen); + + if (connfd < 0) { + printf("No clients in que, enter idle state\n"); + continue; + } + else if (connfd > 0) { + if (connect(listenfd, (const struct sockaddr *)&cliaddr, + sizeof(cliaddr)) != 0) { + printf("Udp connect failed.\n"); + cleanup = 1; + return 1; + } + } + else { + printf("Recvfrom failed.\n"); + cleanup = 1; + return 1; + } + printf("Connected!\n"); + + /* Create the CYASSL Object */ + if ((ssl = CyaSSL_new(ctx)) == NULL) { + printf("CyaSSL_new error.\n"); + cleanup = 1; + return 1; + } + + /* set the session ssl to client connection port */ + CyaSSL_set_fd(ssl, listenfd); + + if (CyaSSL_accept(ssl) != SSL_SUCCESS) { + + int e = CyaSSL_get_error(ssl, 0); + + printf("error = %d, %s\n", e, CyaSSL_ERR_reason_error_string(e)); + printf("SSL_accept failed.\n"); + continue; + } + if ((recvLen = CyaSSL_read(ssl, buff, sizeof(buff)-1)) > 0) { + printf("heard %d bytes\n", recvLen); + + buff[recvLen] = 0; + printf("I heard this: \"%s\"\n", buff); + } + else if (recvLen < 0) { + int readErr = CyaSSL_get_error(ssl, 0); + if(readErr != SSL_ERROR_WANT_READ) { + printf("SSL_read failed.\n"); + cleanup = 1; + return 1; + } + } + if (CyaSSL_write(ssl, ack, sizeof(ack)) < 0) { + printf("CyaSSL_write fail.\n"); + cleanup = 1; + return 1; + } + else { + printf("Sending reply.\n"); + } + + printf("reply sent \"%s\"\n", ack); + + CyaSSL_set_fd(ssl, 0); + CyaSSL_shutdown(ssl); + CyaSSL_free(ssl); + + printf("Client left return to idle state\n"); + } + return 0; +} + +int main(int argc, char** argv) +{ + /* cont short for "continue?", Loc short for "location" */ + int cont = 0; + char caCertLoc[] = "../certs/ca-cert.pem"; + char servCertLoc[] = "../certs/server-cert.pem"; + char servKeyLoc[] = "../certs/server-key.pem"; + CYASSL_CTX* ctx; + + /* "./config --enable-debug" and uncomment next line for debugging */ + /* CyaSSL_Debugging_ON(); */ + + /* Initialize CyaSSL */ + CyaSSL_Init(); + + /* Set ctx to DTLS 1.2 */ + if ((ctx = CyaSSL_CTX_new(CyaDTLSv1_2_server_method())) == NULL) { + printf("CyaSSL_CTX_new error.\n"); + return 1; + } + /* Load CA certificates */ + if (CyaSSL_CTX_load_verify_locations(ctx,caCertLoc,0) != + SSL_SUCCESS) { + printf("Error loading %s, please check the file.\n", caCertLoc); + return 1; + } + /* Load server certificates */ + if (CyaSSL_CTX_use_certificate_file(ctx, servCertLoc, SSL_FILETYPE_PEM) != + SSL_SUCCESS) { + printf("Error loading %s, please check the file.\n", servCertLoc); + return 1; + } + /* Load server Keys */ + if (CyaSSL_CTX_use_PrivateKey_file(ctx, servKeyLoc, + SSL_FILETYPE_PEM) != SSL_SUCCESS) { + printf("Error loading %s, please check the file.\n", servKeyLoc); + return 1; + } + + cont = AwaitDGram(ctx); + + if (cont == 1) { + CyaSSL_CTX_free(ctx); + CyaSSL_Cleanup(); + } + + return 0; +} diff --git a/dtls/server-udp.c b/dtls/server-udp.c new file mode 100644 index 00000000..6fe14b13 --- /dev/null +++ b/dtls/server-udp.c @@ -0,0 +1,96 @@ +/* + * server-udp.c + * + * Copyright (C) 2006-2014 wolfSSL Inc. + * + * This file is part of CyaSSL. + * + * CyaSSL is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * CyaSSL is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, + * USA + *============================================================================= + * + * Bare-bones example of a UDP server for instructional/learning purposes. + */ + +#include /* standard in/out procedures */ +#include /* defines system calls */ +#include /* necessary for memset */ +#include +#include /* used for all socket calls */ +#include /* used for sockaddr_in */ +#include + +#define SERV_PORT 11111 /* define our server port number */ +#define MSGLEN 4096 /* limit incoming message size */ + +int main (int argc, char** argv) +{ + int sockfd; /* Initialize our socket */ + int recvLen; /* number of bytes recieved */ + int msgNum = 0; /* number of msg received */ + unsigned char buf[MSGLEN]; /* the incoming message */ + struct sockaddr_in servAddr; /* our server's address */ + struct sockaddr_in cliAddr; /* the client's address */ + socklen_t cliAddrLen = sizeof(cliAddr); /* length of address' */ + + /* create a UDP/IP socket */ + if ((sockfd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) { + perror("cannot create socket"); + return 0; + } + + memset((char *)&servAddr, 0, sizeof(servAddr)); + + /* host-to-network-long conversion (htonl) */ + /* host-to-network-short conversion (htons) */ + servAddr.sin_family = AF_INET; + servAddr.sin_addr.s_addr = htonl(INADDR_ANY); + servAddr.sin_port = htons(SERV_PORT); + + if (bind(sockfd, (struct sockaddr *)&servAddr, sizeof(servAddr)) < 0) { + perror("bind failed"); + return 0; + } + + /* loop, listen for client, print received, reply to client */ + for (;;) { + memset(buf, 0, sizeof(buf)); + printf("waiting for client message on port %d\n", SERV_PORT); + + recvLen = recvfrom(sockfd, buf, MSGLEN, 0, + (struct sockaddr *)&cliAddr, &cliAddrLen); + + printf("heard %d bytes\n", recvLen); + + if (recvLen > 0) { + buf[recvLen] = 0; + printf("I heard this: \"%s\"\n", buf); + } + else + printf("lost the connection to client\n"); + + printf("Message #%d received\n", msgNum++); + printf("reply sent \"%s\"\n", buf); + + if (sendto(sockfd, buf, sizeof(buf), 0, + (struct sockaddr *)&cliAddr, cliAddrLen) < 0) { + printf("\"sendto\" failed.\n"); + return 1; + } + /* continues to loop, use "Ctrl+C" to terminate listening */ + } + return 0; +} + diff --git a/dtls/tutorial-udp-dtls.c b/dtls/tutorial-udp-dtls.c new file mode 100644 index 00000000..04eef534 --- /dev/null +++ b/dtls/tutorial-udp-dtls.c @@ -0,0 +1,5 @@ +UDP/DTLS Tutorial +================ + +< TODO > + From 030dc641e7290cf12396f9a71ced1d9a7e1191d5 Mon Sep 17 00:00:00 2001 From: Chris Conlon Date: Mon, 30 Jun 2014 09:52:59 -0600 Subject: [PATCH 4/5] add initial PSK examples --- psk/Makefile | 34 +++++ psk/client-psk-nonblocking.c | 270 +++++++++++++++++++++++++++++++++ psk/client-psk-resume.c | 210 ++++++++++++++++++++++++++ psk/client-psk.c | 165 ++++++++++++++++++++ psk/client-tcp.c | 108 ++++++++++++++ psk/server-psk-nonblocking.c | 282 +++++++++++++++++++++++++++++++++++ psk/server-psk-threaded.c | 188 +++++++++++++++++++++++ psk/server-psk.c | 179 ++++++++++++++++++++++ psk/server-tcp.c | 119 +++++++++++++++ psk/tutorial-tcp-psk.md | 5 + 10 files changed, 1560 insertions(+) create mode 100644 psk/Makefile create mode 100644 psk/client-psk-nonblocking.c create mode 100644 psk/client-psk-resume.c create mode 100644 psk/client-psk.c create mode 100644 psk/client-tcp.c create mode 100644 psk/server-psk-nonblocking.c create mode 100644 psk/server-psk-threaded.c create mode 100644 psk/server-psk.c create mode 100644 psk/server-tcp.c create mode 100644 psk/tutorial-tcp-psk.md diff --git a/psk/Makefile b/psk/Makefile new file mode 100644 index 00000000..09483aac --- /dev/null +++ b/psk/Makefile @@ -0,0 +1,34 @@ +CC=gcc +CFLAGS=-Wall +LIBS=-lcyassl + +all: client-tcp client-psk client-psk-nonblocking client-psk-resume server-tcp server-psk server-psk-nonblocking server-psk-threaded + +client-tcp: client-tcp.o + $(CC) -o $@ $^ $(CFLAGS) + +client-psk: client-psk.o + $(CC) -o $@ $^ $(CFLAGS) $(LIBS) + +client-psk-nonblocking: client-psk-nonblocking.o + $(CC) -o $@ $^ $(CFLAGS) $(LIBS) + +client-psk-resume: client-psk-resume.o + $(CC) -o $@ $^ $(CFLAGS) $(LIBS) + +server-tcp: server-tcp.o + $(CC) -o $@ $^ $(CFLAGS) + +server-psk: server-psk.o + $(CC) -o $@ $^ $(CFLAGS) $(LIBS) + +server-psk-nonblocking: server-psk-nonblocking.o + $(CC) -o $@ $^ $(CFLAGS) $(LIBS) + +server-psk-threaded: server-psk-threaded.o + $(CC) -o $@ $^ $(CFLAGS) $(LIBS) + +.PHONY: clean all + +clean: + rm -f *.o client-tcp client-psk client-psk-nonblocking client-psk-resume server-tcp server-psk server-psk-nonblocking server-psk-threaded diff --git a/psk/client-psk-nonblocking.c b/psk/client-psk-nonblocking.c new file mode 100644 index 00000000..33f3ef89 --- /dev/null +++ b/psk/client-psk-nonblocking.c @@ -0,0 +1,270 @@ +/* client-psk-nonblocking.c + * + * Copyright (C) 2006-2014 wolfSSL Inc. + * + * This file is part of CyaSSL. + * + * CyaSSL is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * CyaSSL is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, + * USA */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include /* must include this to use CyaSSL security */ + +#define MAXLINE 256 /* max text line length */ +#define SERV_PORT 11111 /* default port*/ + +/* + * enum used for tcp_select function + */ +enum { + TEST_SELECT_FAIL, + TEST_TIMEOUT, + TEST_RECV_READY, + TEST_ERROR_READY +}; + + +static inline int tcp_select(int socketfd, int to_sec) +{ + fd_set recvfds, errfds; + int nfds = socketfd + 1; + struct timeval timeout = { (to_sec > 0) ? to_sec : 0, 0}; + int result; + + FD_ZERO(&recvfds); + FD_SET(socketfd, &recvfds); + FD_ZERO(&errfds); + FD_SET(socketfd, &errfds); + + result = select(nfds, &recvfds, NULL, &errfds, &timeout); + + if (result == 0) + return TEST_TIMEOUT; + else if (result > 0) { + if (FD_ISSET(socketfd, &recvfds)) + return TEST_RECV_READY; + else if(FD_ISSET(socketfd, &errfds)) + return TEST_ERROR_READY; + } + + return TEST_SELECT_FAIL; +} + +/* + * sets up and uses nonblocking protocols using cyassl + */ +static int NonBlockingSSL_Connect(CYASSL* ssl) +{ + int ret, error, sockfd, select_ret, currTimeout; + + ret = CyaSSL_connect(ssl); + error = CyaSSL_get_error(ssl, 0); + sockfd = (int)CyaSSL_get_fd(ssl); + + while (ret != SSL_SUCCESS && (error == SSL_ERROR_WANT_READ || + error == SSL_ERROR_WANT_WRITE)) { + currTimeout = 1; + + if (error == SSL_ERROR_WANT_READ) + printf("... client would read block\n"); + else + printf("... client would write block\n"); + + select_ret = tcp_select(sockfd, currTimeout); + + if ((select_ret == TEST_RECV_READY) || + (select_ret == TEST_ERROR_READY)) { + ret = CyaSSL_connect(ssl); + error = CyaSSL_get_error(ssl, 0); + } + else if (select_ret == TEST_TIMEOUT) { + error = SSL_ERROR_WANT_READ; + } + else { + error = SSL_FATAL_ERROR; + } + } + if (ret != SSL_SUCCESS){ + printf("SSL_connect failed"); + return 1; + } + + return 0; +} + +/* + *psk client set up. + */ +static inline unsigned int My_Psk_Client_Cb(CYASSL* ssl, const char* hint, + char* identity, unsigned int id_max_len, unsigned char* key, + unsigned int key_max_len) +{ + (void)ssl; + (void)hint; + (void)key_max_len; + + /* identity is OpenSSL testing default for openssl s_client, keep same*/ + strncpy(identity, "Client_identity", id_max_len); + + /* test key n hex is 0x1a2b3c4d , in decimal 439,041,101, we're using + * unsigned binary */ + key[0] = 26; + key[1] = 43; + key[2] = 60; + key[3] = 77; + + return 4; +} + +/* + * this function will send the inputted string to the server and then + * recieve the string from the server outputing it to the termial + */ +int SendReceive(CYASSL* ssl) +{ + char sendline[MAXLINE]="Hello Server"; /* string to send to the server */ + char recvline[MAXLINE]; /* string received from the server */ + + /* write string to the server */ + if (CyaSSL_write(ssl, sendline, MAXLINE) != sizeof(sendline)) { + printf("Write Error to Server\n"); + return 1; + } + + /* flags if the Server stopped before the client could end */ + if (CyaSSL_read(ssl, recvline, MAXLINE) < 0 ) { + printf("Client: Server Terminated Prematurely!\n"); + return 1; + } + + /* show message from the server */ + printf("Server Message: %s\n", recvline); + + return 0; +} + +int main(int argc, char **argv) +{ + int sockfd, ret; + CYASSL_CTX* ctx; + CYASSL* ssl; + struct sockaddr_in servaddr;; + + /* must include an ip address of this will flag */ + if (argc != 2) { + printf("Usage: tcpClient \n"); + return 1; + } + + CyaSSL_Init(); /* initialize cyaSSL */ + + + /* create and initialize CYASSL_CTX structure */ + if ((ctx = CyaSSL_CTX_new(CyaTLSv1_2_client_method())) == NULL) { + fprintf(stderr, "SSL_CTX_new error.\n"); + return 1; + } + + /* create a stream socket using tcp,internet protocal IPv4, + * full-duplex stream */ + sockfd = socket(AF_INET, SOCK_STREAM, 0); + + /* places n zero-valued bytes in the address servaddr */ + memset(&servaddr, 0, sizeof(servaddr)); + + servaddr.sin_family = AF_INET; + servaddr.sin_port = htons(SERV_PORT); + + /* converts IPv4 addresses from text to binary form */ + ret = inet_pton(AF_INET, argv[1], &servaddr.sin_addr); + + if (ret != 1) { + printf("inet_pton error\n"); + return 1; + } + + /* set up pre shared keys */ + CyaSSL_CTX_set_psk_client_callback(ctx,My_Psk_Client_Cb); + + /* attempts to make a connection on a socket */ + ret = connect(sockfd, (struct sockaddr *) &servaddr, sizeof(servaddr)); + + if (ret != 0) { + printf("Connection Error\n"); + return 1; + } + + /* create CyaSSL object after each tcp connect */ + if ((ssl = CyaSSL_new(ctx)) == NULL) { + fprintf(stderr, "CyaSSL_new error.\n"); + return 1; + } + + /* associate the file descriptor with the session */ + CyaSSL_set_fd(ssl, sockfd); + + /* tell CyaSSL that nonblocking is going to be used */ + CyaSSL_set_using_nonblock(ssl, 1); + + /* invokes the fcntl callable service to get the file status + * flags for a file. checks if it returns an error, if it does + * stop program */ + int flags = fcntl(sockfd, F_GETFL, 0); + if (flags < 0) { + printf("fcntl get failed\n"); + return 1; + } + + /* invokes the fcntl callable service to set file status flags. + * Do not block an open, a read, or a write on the file + * (do not wait for terminal input. If an error occurs, + * stop program*/ + flags = fcntl(sockfd, F_SETFL, flags | O_NONBLOCK); + if (flags < 0) { + printf("fcntl set failed\n"); + return 1; + } + + /* setting up and running nonblocking socket */ + ret = NonBlockingSSL_Connect(ssl); + if (ret != 0) { + return 1; + } + + /* takes inputting string and outputs it to the server */ + ret = SendReceive(ssl); + if (ret != 0) { + return 1; + } + + /* cleanup */ + CyaSSL_free(ssl); + + /* when completely done using SSL/TLS, free the + * cyassl_ctx object */ + CyaSSL_CTX_free(ctx); + CyaSSL_Cleanup(); + + return ret; + +} diff --git a/psk/client-psk-resume.c b/psk/client-psk-resume.c new file mode 100644 index 00000000..b4725b14 --- /dev/null +++ b/psk/client-psk-resume.c @@ -0,0 +1,210 @@ + +/* client-psk-resume.c + * + * Copyright (C) 2006-2014 wolfSSL Inc. + * + * This file is part of CyaSSL. + * + * CyaSSL is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * CyaSSL is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, + * USA */ + +#include +#include +#include +#include +#include +#include +#include +#include /* must include this to use CyaSSL security */ + +#define MAXLINE 256 /* max text line length */ +#define SERV_PORT 11111 /* default port*/ + +/* + *psk client set up. + */ +static inline unsigned int My_Psk_Client_Cb(CYASSL* ssl, const char* hint, + char* identity, unsigned int id_max_len, unsigned char* key, + unsigned int key_max_len) +{ + (void)ssl; + (void)hint; + (void)key_max_len; + + /* identity is OpenSSL testing default for openssl s_client, keep same*/ + strncpy(identity, "Client_identity", id_max_len); + + /* test key n hex is 0x1a2b3c4d , in decimal 439,041,101, we're using + * unsigned binary */ + key[0] = 26; + key[1] = 43; + key[2] = 60; + key[3] = 77; + + return 4; +} + +/* + * this function will send the inputted string to the server and then + * recieve the string from the server outputing it to the termial + */ +int SendReceive(CYASSL* ssl) +{ + char sendline[MAXLINE]="Hello Server"; /* string to send to the server */ + char recvline[MAXLINE]; /* string received from the server */ + + /* write string to the server */ + if (CyaSSL_write(ssl, sendline, MAXLINE) != sizeof(sendline)) { + printf("Write Error to Server\n"); + return 1; + } + + /* flags if the Server stopped before the client could end */ + if (CyaSSL_read(ssl, recvline, MAXLINE) < 0 ) { + printf("Client: Server Terminated Prematurely!\n"); + return 1; + } + + /* show message from the server */ + printf("Server Message: %s\n", recvline); + + return 0; +} + +int main(int argc, char **argv){ + + int sockfd, sock, ret; + CYASSL* ssl; + CYASSL* sslResume = 0; + CYASSL_SESSION* session = 0; + CYASSL_CTX* ctx; + struct sockaddr_in servaddr;; + + /* must include an ip address of this will flag */ + if (argc != 2) { + printf("Usage: tcpClient \n"); + return 1; + } + + CyaSSL_Init(); /* initialize cyaSSL */ + + /* create and initialize CYASSL_CTX structure */ + if ((ctx = CyaSSL_CTX_new(CyaTLSv1_2_client_method())) == NULL) { + fprintf(stderr, "SSL_CTX_new error.\n"); + return 1; + } + + /* create a stream socket using tcp,internet protocal IPv4, + * full-duplex stream */ + sockfd = socket(AF_INET, SOCK_STREAM, 0); + + /* places n zero-valued bytes in the address servaddr */ + memset(&servaddr, 0, sizeof(servaddr)); + + servaddr.sin_family = AF_INET; + servaddr.sin_port = htons(SERV_PORT); + + /* converts IPv4 addresses from text to binary form */ + ret = inet_pton(AF_INET, argv[1], &servaddr.sin_addr); + + if (ret != 1){ + return 1; + } + + /* set up pre shared keys */ + CyaSSL_CTX_set_psk_client_callback(ctx, My_Psk_Client_Cb); + + /* attempts to make a connection on a socket */ + ret = connect(sockfd, (struct sockaddr *) &servaddr, sizeof(servaddr)); + if (ret != 0 ){ + return 1; + } + + /* create CyaSSL object after each tcp connect */ + if ( (ssl = CyaSSL_new(ctx)) == NULL) { + fprintf(stderr, "CyaSSL_new error.\n"); + return 1; + } + + /* associate the file descriptor with the session */ + CyaSSL_set_fd(ssl, sockfd); + + /* takes inputting string and outputs it to the server */ + SendReceive(ssl); + + /* Save the session ID to reuse */ + session = CyaSSL_get_session(ssl); + sslResume = CyaSSL_new(ctx); + + /* shut down CyaSSL */ + CyaSSL_shutdown(ssl); + + /* close connection */ + close(sockfd); + + /* cleanup */ + CyaSSL_free(ssl); + CyaSSL_CTX_free(ctx); + CyaSSL_Cleanup(); + + /* + * resume session, start new connection and socket + */ + + /* start a new socket connection */ + sock = socket(AF_INET, SOCK_STREAM, 0); + + /* connect to the socket */ + ret = connect(sock, (struct sockaddr *) &servaddr, sizeof(servaddr)); + + if (ret != 0){ + return 1; + } + + /* set the session ID to connect to the server */ + CyaSSL_set_fd(sslResume, sock); + CyaSSL_set_session(sslResume, session); + + /* check has connect successfully */ + if (CyaSSL_connect(sslResume) != SSL_SUCCESS) { + printf("SSL resume failed\n"); + return 1; + } + + /* takes inputting string and outputs it to the server */ + ret = SendReceive(sslResume); + if (ret != 0) { + return 1; + } + + /* check to see if the session id is being reused */ + if (CyaSSL_session_reused(sslResume)) + printf("reused session id\n"); + else + printf("didn't reuse session id!!!\n"); + + /* shut down CyaSSL */ + CyaSSL_shutdown(sslResume); + + /* shut down socket */ + close(sock); + + /* clean up */ + CyaSSL_free(sslResume); + CyaSSL_CTX_free(ctx); + CyaSSL_Cleanup(); + + return ret; +} diff --git a/psk/client-psk.c b/psk/client-psk.c new file mode 100644 index 00000000..ace96c7e --- /dev/null +++ b/psk/client-psk.c @@ -0,0 +1,165 @@ + +/* client-psk.c + * + * Copyright (C) 2006-2014 wolfSSL Inc. + * + * This file is part of CyaSSL. + * + * CyaSSL is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * CyaSSL is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, + * USA */ + +#include +#include +#include +#include +#include +#include +#include +#include /* must include this to use CyaSSL security */ + +#define MAXLINE 256 /* max text line length */ +#define SERV_PORT 11111 /* default port*/ + +/* + *psk client set up. + */ +static inline unsigned int My_Psk_Client_Cb(CYASSL* ssl, const char* hint, + char* identity, unsigned int id_max_len, unsigned char* key, + unsigned int key_max_len) +{ + (void)ssl; + (void)hint; + (void)key_max_len; + + /* identity is OpenSSL testing default for openssl s_client, keep same*/ + strncpy(identity, "Client_identity", id_max_len); + + /* test key n hex is 0x1a2b3c4d , in decimal 439,041,101, we're using + * unsigned binary */ + key[0] = 26; + key[1] = 43; + key[2] = 60; + key[3] = 77; + + return 4; +} + +/* + * this function will send the inputted string to the server and then + * recieve the string from the server outputing it to the termial + */ +int SendReceive(CYASSL* ssl) +{ + char sendline[MAXLINE]="Hello Server"; /* string to send to the server */ + char recvline[MAXLINE]; /* string received from the server */ + + /* write string to the server */ + if (CyaSSL_write(ssl, sendline, MAXLINE) != sizeof(sendline)) { + printf("Write Error to Server\n"); + return 1; + } + + /* flags if the Server stopped before the client could end */ + if (CyaSSL_read(ssl, recvline, MAXLINE) < 0 ) { + printf("Client: Server Terminated Prematurely!\n"); + return 1; + } + + /* show message from the server */ + printf("Server Message: %s\n", recvline); + + return 0; +} + +int main(int argc, char **argv) +{ + int ret, sockfd; + CYASSL* ssl; + CYASSL_CTX* ctx; + struct sockaddr_in servaddr;; + + /* must include an ip address of this will flag */ + if (argc != 2) { + printf("Usage: tcpClient \n"); + return 1; + } + + CyaSSL_Init(); /* initialize cyaSSL */ + + /* create and initialize CYASSL_CTX structure */ + if ((ctx = CyaSSL_CTX_new(CyaTLSv1_2_client_method())) == NULL) { + fprintf(stderr, "SSL_CTX_new error.\n"); + return 1; + } + + /* create a stream socket using tcp,internet protocal IPv4, + * full-duplex stream */ + sockfd = socket(AF_INET, SOCK_STREAM, 0); + + /* places n zero-valued bytes in the address servaddr */ + memset(&servaddr, 0, sizeof(servaddr)); + + servaddr.sin_family = AF_INET; + servaddr.sin_port = htons(SERV_PORT); + + /* converts IPv4 addresses from text to binary form */ + ret = inet_pton(AF_INET, argv[1], &servaddr.sin_addr); + + if (ret != 1) { + printf("inet_pton error\n"); + return 1; + } + + /* set up pre shared keys */ + CyaSSL_CTX_set_psk_client_callback(ctx, My_Psk_Client_Cb); + + /* attempts to make a connection on a socket */ + ret = connect(sockfd, (struct sockaddr *) &servaddr, sizeof(servaddr)); + + if (ret != 0) { + printf("Connection Error\n"); + return 1; + } + + /* creat cyassl object after each tcp connct */ + if ( (ssl = CyaSSL_new(ctx)) == NULL) { + fprintf(stderr, "CyaSSL_new error.\n"); + return 1; + } + + /* associate the file descriptor with the session */ + ret = CyaSSL_set_fd(ssl, sockfd); + + if (ret != SSL_SUCCESS){ + return 1; + } + + /* takes inputting string and outputs it to the server */ + ret = SendReceive(ssl); + if(ret != 0){ + return 1; + } + + /* cleanup */ + CyaSSL_free(ssl); + + /* when completely done using SSL/TLS, free the + * cyassl_ctx object */ + CyaSSL_CTX_free(ctx); + CyaSSL_Cleanup(); + + /* exit client */ + return ret; +} diff --git a/psk/client-tcp.c b/psk/client-tcp.c new file mode 100644 index 00000000..d268503c --- /dev/null +++ b/psk/client-tcp.c @@ -0,0 +1,108 @@ + +/* client-tcp.c + * + * Copyright (C) 2006-2014 wolfSSL Inc. + * + * This file is part of CyaSSL. + * + * CyaSSL is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * CyaSSL is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, + * USA */ + +#include /* basic socket definitions */ +#include /* sockaddr_in{} and other Internet defns */ +#include +#include +#include +#include +#include +#include +#include + +#define MAXLINE 256 /* max text line length */ +#define SERV_PORT 11111 + +/* + * this function will send the inputted string to the server and then + * recieve the string from the server outputing it to the termial + */ +int SendReceive(int sockfd) +{ + char sendline[MAXLINE]="Hello Server"; /* string to send to the server */ + char recvline[MAXLINE]; /* string received from the server */ + + /* write string to the server */ + if (write(sockfd, sendline, strlen(sendline)) != sizeof(sendline)) { + printf("Write Error to Server\n"); + return 1; + } + + /* flags if the server stopped before the client could end */ + if (read(sockfd, recvline, MAXLINE) == 0) { + printf("Client: Server Terminated Prematurely!\n"); + return 1; + } + + printf("Server Message: %s\n", recvline); + + return 0; +} + +int main(int argc, char **argv) +{ + int sockfd, ret; + struct sockaddr_in servaddr; + + /* must include an ip address or this will flag */ + if (argc != 2) { + printf("Usage: tcpClient \n"); + return 1; + } + + /* create a stream socket using tcp,internet protocal IPv4, + * full-duplex stream */ + sockfd = socket(AF_INET, SOCK_STREAM, 0); + + /* places n zero-valued bytes in the address servaddr */ + memset(&servaddr, 0, sizeof(servaddr)); + + servaddr.sin_family = AF_INET; + servaddr.sin_port = htons(SERV_PORT); + + /* converts IPv4 addresses from text to binary form */ + ret = inet_pton(AF_INET, argv[1], &servaddr.sin_addr); + + if (ret != 1) { + printf("Not a Valid network address"); + return 1; + } + + /* attempts to make a connection on a socket */ + ret = connect(sockfd, (struct sockaddr *) &servaddr, sizeof(servaddr)); + + if (ret != 0) { + return 1; + } + + /* takes inputting string and outputs it to the server */ + ret = SendReceive(sockfd); + if (ret != 0){ + printf("Send Recieve Error"); + return 1; + } + /* close socket and connection */ + close(sockfd); + + return ret; +} diff --git a/psk/server-psk-nonblocking.c b/psk/server-psk-nonblocking.c new file mode 100644 index 00000000..4a5968c3 --- /dev/null +++ b/psk/server-psk-nonblocking.c @@ -0,0 +1,282 @@ +/* server-psk-nonblocking.c + * A server ecample using a TCP connection with PSK security and non blocking. + * + * This file is part of CyaSSL. + * + * CyaSSL is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * CyaSSL is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#include /* include cyassl security */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include /* needed for runing nonblocking connections */ +#include /* for time out on read loop */ + +#define MAXLINE 4096 +#define LISTENQ 1024 +#define SERV_PORT 11111 + +/* states of the tcp connection */ +enum{ + TEST_SELECT_FAIL, + TEST_TIMEOUT, + TEST_RECV_READY, + TEST_ERROR_READY +}; + + +/* + * Pulled in from cyassl/test.h + * Select the tcp, used when nonblocking. Checks the status of the connection. + */ +int tcp_select(int sockfd, int to_sec) +{ + fd_set recvfds, errfds; + int nfds = sockfd + 1; + struct timeval timeout = {to_sec, 0}; + int result; + + /* reset socket values */ + FD_ZERO(&recvfds); + FD_SET(sockfd, &recvfds); + FD_ZERO(&errfds); + FD_SET(sockfd, &errfds); + + result = select(nfds, &recvfds, NULL, &errfds, &timeout); + + /* logic for which enumerated value is returned */ + if (result == 0) + return TEST_TIMEOUT; + else if (result > 0) { + if (FD_ISSET(sockfd, &recvfds)) + return TEST_RECV_READY; + else if (FD_ISSET(sockfd, &errfds)) + return TEST_ERROR_READY; + } + + return TEST_SELECT_FAIL; +} + + +/* + * Pulled in from examples/server/server.c + * Function to handle nonblocking. Loops until tcp_select notifies that it's + * ready for action. + */ +int NonBlockingSSL(CYASSL* ssl) +{ + int ret; + int error; + int select_ret; + int sockfd = CyaSSL_get_fd(ssl); + ret = CyaSSL_accept(ssl); + error = CyaSSL_get_error(ssl, 0); + while (ret != SSL_SUCCESS && (error == SSL_ERROR_WANT_READ || + error == SSL_ERROR_WANT_WRITE)) { + int currTimeout = 1; + + /* print out for user notification */ + if (error == SSL_ERROR_WANT_READ) + printf("... server would read block\n"); + else + printf("... server would write block\n"); + + select_ret = tcp_select(sockfd, currTimeout); + + /* if tcp_select signals ready try to accept otherwise continue loop*/ + if ((select_ret == TEST_RECV_READY) || + (select_ret == TEST_ERROR_READY)) { + ret = CyaSSL_accept(ssl); + error = CyaSSL_get_error(ssl, 0); + } + else if (select_ret == TEST_TIMEOUT) { + error = SSL_ERROR_WANT_READ; + } + else { + error = SSL_FATAL_ERROR; + } + } + /* faliure to accept */ + if (ret != SSL_SUCCESS) { + printf("Fatal error : SSL_accept failed\n"); + ret = SSL_FATAL_ERROR; + } + + return ret; +} + + +/* + * Handles response to client. + */ +int respond(CYASSL* ssl) +{ + int n; /* length of string read */ + char buf[MAXLINE]; /* string read from client */ + char response[] = "I hear ya for shizzle"; + + memset(buf, 0, MAXLINE); + do { + if (NonBlockingSSL(ssl) != SSL_SUCCESS) + return 1; + n = CyaSSL_read(ssl, buf, MAXLINE); + if (n > 0) { + printf("%s\n", buf); + } + } + while(n < 0); + + if (NonBlockingSSL(ssl) != SSL_SUCCESS) + return 1; + if (CyaSSL_write(ssl, response, strlen(response)) != strlen(response)) { + printf("Fatal error : respond: write error\n"); + return 1; + } + + return 0; +} + +/* + * Used for finding psk value. + */ +static inline unsigned int my_psk_server_cb(CYASSL* ssl, const char* identity, + unsigned char* key, unsigned int key_max_len) +{ + (void)ssl; + (void)key_max_len; + + if (strncmp(identity, "Client_identity", 15) != 0) + return 0; + + key[0] = 26; + key[1] = 43; + key[2] = 60; + key[3] = 77; + + return 4; +} + + +int main() +{ + int listenfd, connfd; + int opt; + struct sockaddr_in cliAddr, servAddr; + char buff[MAXLINE]; + socklen_t cliLen; + CYASSL_CTX* ctx; + + CyaSSL_Init(); + + if ((ctx = CyaSSL_CTX_new(CyaSSLv23_server_method())) == NULL) { + printf("Fatal error : CyaSSL_CTX_new error\n"); + return 1; + } + + /* use psk suite for security */ + CyaSSL_CTX_set_psk_server_callback(ctx, my_psk_server_cb); + CyaSSL_CTX_use_psk_identity_hint(ctx, "cyassl server"); + if (CyaSSL_CTX_set_cipher_list(ctx, "PSK-AES128-CBC-SHA256") + != SSL_SUCCESS) + printf("Fatal error : server can't set cipher list\n"); + + /* find a socket */ + listenfd = socket(AF_INET, SOCK_STREAM, 0); + if (listenfd < 0) { + printf("Fatal error : socket error\n"); + return 1; + } + + /* set up server address and port */ + memset(&servAddr, 0, sizeof(servAddr)); + servAddr.sin_family = AF_INET; + servAddr.sin_addr.s_addr = htonl(INADDR_ANY); + servAddr.sin_port = htons(SERV_PORT); + + /* bind to a socket */ + opt = 1; + if (setsockopt(listenfd, SOL_SOCKET, SO_REUSEADDR, (const void*)&opt, + sizeof(int)) != 0) { + printf("Fatal error : setsockopt errer"); + return 1; + } + if (bind(listenfd, (struct sockaddr *) &servAddr, sizeof(servAddr)) < 0) { + printf("Fatal error : bind error\n"); + return 1; + } + + /* main loop for accepting and responding to clients */ + for ( ; ; ) { + CYASSL* ssl; + + /* listen to the socket */ + if (listen(listenfd, LISTENQ) < 0) { + printf("Fatal error : listen error\n"); + return 1; + } + + cliLen = sizeof(cliAddr); + connfd = accept(listenfd, (struct sockaddr *) &cliAddr, &cliLen); + if (connfd < 0) { + if (errno != EINTR) { + printf("Fatal error : accept error\n"); + return 1; + } + } + else { + printf("Connection from %s, port %d\n", + inet_ntop(AF_INET, &cliAddr.sin_addr, buff, sizeof(buff)), + ntohs(cliAddr.sin_port)); + + /* create CYASSL object */ + if ((ssl = CyaSSL_new(ctx)) == NULL) { + printf("Fatal error : CyaSSL_new error\n"); + return 1; + } + CyaSSL_set_fd(ssl, connfd); + + /* set CyaSSL and socket to non blocking and respond */ + CyaSSL_set_using_nonblock(ssl, 1); + if (fcntl(connfd, F_SETFL, O_NONBLOCK) < 0) { + printf("Fatal error : fcntl set failed\n"); + return 1; + } + if (respond(ssl) != 0) + printf("Fatal error : respond error\n"); + return 1; + + /* closes the connections after responding */ + CyaSSL_shutdown(ssl); + CyaSSL_free(ssl); + if (close(connfd) == -1) { + printf("Fatal error : close error\n"); + return 1; + } + } + } + /* free up memory used by cyassl */ + CyaSSL_CTX_free(ctx); + CyaSSL_Cleanup(); + + return 0; +} + diff --git a/psk/server-psk-threaded.c b/psk/server-psk-threaded.c new file mode 100644 index 00000000..09238ee9 --- /dev/null +++ b/psk/server-psk-threaded.c @@ -0,0 +1,188 @@ +/* server-psk-threaded.c + * A server ecample using a multi-threaded TCP connection with PSK security. + * + * This file is part of CyaSSL. + * + * CyaSSL is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * CyaSSL is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#include /* include CyaSSL security */ +#include /* included for option sync */ +#include /* used for concurrent threading */ +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define MAXLINE 4096 +#define LISTENQ 1024 +#define SERV_PORT 11111 + +CYASSL_CTX* ctx; /* global so it's shared by threads */ + +/* + * Identify which psk key to use. + */ +static inline unsigned int my_psk_server_cb(CYASSL* ssl, const char* identity, + unsigned char* key, + unsigned int key_max_len) +{ + (void)ssl; + (void)key_max_len; + + if (strncmp(identity, "Client_identity", 15) != 0) + return 0; + + key[0] = 26; + key[1] = 43; + key[2] = 60; + key[3] = 77; + + return 4; +} + +/* + * Process handled by a thread. + */ +void* cyassl_thread(void* fd) +{ + CYASSL* ssl; + int connfd = (int)fd; + int n; + char buf[MAXLINE]; + char response[] = "I hear ya for shizzle"; + + memset(buf, 0, MAXLINE); + + /* create CYASSL object */ + if ((ssl = CyaSSL_new(ctx)) == NULL) { + printf("Fatal error : CyaSSL_new error"); + /* place signal for forced error exit here */ + } + + CyaSSL_set_fd(ssl, connfd); + + /* respond to client */ + n = CyaSSL_read(ssl, buf, MAXLINE); + if (n > 0) { + printf("%s\n", buf); + if (CyaSSL_write(ssl, response, strlen(response)) != strlen(response)) { + printf("Fatal error :respond: write error\n"); + /* place signal for forced error exit here */ + } + } + if (n < 0) { + printf("Fatal error : respond: read error\n"); + /* place signal for forced error exit here */ + } + + /* closes the connections after responding */ + CyaSSL_shutdown(ssl); + CyaSSL_free(ssl); + if (close(connfd) == -1) { + printf("Fatal error : close error\n"); + /* place signal for forced error exit here */ + } + + pthread_exit(NULL); +} + +int main() +{ + int listenfd, connfd; + int opt; + struct sockaddr_in cliAddr, servAddr; + char buff[MAXLINE]; + socklen_t cliLen; + pthread_t thread; + void* cyassl_thread(void*); + + CyaSSL_Init(); + + if ((ctx = CyaSSL_CTX_new(CyaSSLv23_server_method())) == NULL) + printf("Fatal error : CyaSSL_CTX_new error\n"); + + /* use psk suite for security */ + CyaSSL_CTX_set_psk_server_callback(ctx, my_psk_server_cb); + CyaSSL_CTX_use_psk_identity_hint(ctx, "cyassl server"); + if (CyaSSL_CTX_set_cipher_list(ctx, "PSK-AES128-CBC-SHA256") + != SSL_SUCCESS) + printf("Fatal error : server can't set cipher list"); + + /* find a socket */ + listenfd = socket(AF_INET, SOCK_STREAM, 0); + if (listenfd < 0) { + printf("Fatal error : socket error"); + } + + /* set up server address and port */ + memset(&servAddr, 0, sizeof(servAddr)); + servAddr.sin_family = AF_INET; + servAddr.sin_addr.s_addr = htonl(INADDR_ANY); + servAddr.sin_port = htons(SERV_PORT); + + /* bind to a socket */ + opt = 1; + if (setsockopt(listenfd, SOL_SOCKET, SO_REUSEADDR, (const void *)&opt, + sizeof(int))) { + return 1; + } + + if (bind(listenfd, (struct sockaddr *) &servAddr, sizeof(servAddr)) < 0) { + printf("Fatal error : bind error"); + return 1; + } + + /* main loop for accepting and responding to clients */ + for ( ; ; ) { + /* listen to the socket */ + if (listen(listenfd, LISTENQ) < 0) { + printf("Fatal error : listen error"); + return 1; + } + + cliLen = sizeof(cliAddr); + connfd = accept(listenfd, (struct sockaddr *) &cliAddr, &cliLen); + if (connfd < 0) { + printf("Fatal error : accept error"); + return 1; + } + else { + printf("Connection from %s, port %d\n", + inet_ntop(AF_INET, &cliAddr.sin_addr, buff, sizeof(buff)), + ntohs(cliAddr.sin_port)); + + if (pthread_create(&thread, NULL, &cyassl_thread, (void*) connfd) + != 0) { + return 1; + } + if (pthread_detach(thread) != 0) { + return 1; + } + } + } + + /* free up memory used by cyassl */ + CyaSSL_CTX_free(ctx); + CyaSSL_Cleanup(); + + return 0; +} + diff --git a/psk/server-psk.c b/psk/server-psk.c new file mode 100644 index 00000000..26d79c66 --- /dev/null +++ b/psk/server-psk.c @@ -0,0 +1,179 @@ +/* server-psk.c + * A server ecample using a TCP connection with PSK security. + * + * This file is part of CyaSSL. + * + * CyaSSL is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * CyaSSL is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#include /* include CyaSSL security */ +#include /* included for options sync */ +#include +#include +#include +#include +#include +#include +#include +#include + +#define MAXLINE 4096 +#define LISTENQ 1024 +#define SERV_PORT 11111 + +/* + * Handles response to client. + */ +int respond(CYASSL* ssl) +{ + int n; /* length of string read */ + char buf[MAXLINE]; /* string read from client */ + char response[] = "I hear ya for shizzle"; + memset(buf, 0, MAXLINE); + n = CyaSSL_read(ssl, buf, MAXLINE); + if (n > 0) { + printf("%s\n", buf); + if (CyaSSL_write(ssl, response, strlen(response)) > strlen(response)) { + printf("Fatal error : respond: write error\n"); + return 1; + } + } + if (n < 0) { + printf("Fatal error :espond: read error\n"); + return 1; + } + + return 0; +} + +/* + * Identify which psk key to use. + */ +static unsigned int my_psk_server_cb(CYASSL* ssl, const char* identity, unsigned char* key, + unsigned int key_max_len) +{ + (void)ssl; + (void)key_max_len; + + if (strncmp(identity, "Client_identity", 15) != 0) + return 0; + + key[0] = 26; + key[1] = 43; + key[2] = 60; + key[3] = 77; + + return 4; +} + +int main() +{ + int listenfd, connfd; + int opt; + struct sockaddr_in cliAddr, servAddr; + char buff[MAXLINE]; + socklen_t cliLen; + CYASSL_CTX* ctx; + + CyaSSL_Init(); + + /* create ctx and configure certificates */ + if ((ctx = CyaSSL_CTX_new(CyaSSLv23_server_method())) == NULL) { + printf("Fatal error : CyaSSL_CTX_new error\n"); + return 1; + } + + /* use psk suite for security */ + CyaSSL_CTX_set_psk_server_callback(ctx, my_psk_server_cb); + CyaSSL_CTX_use_psk_identity_hint(ctx, "cyassl server"); + if (CyaSSL_CTX_set_cipher_list(ctx, "PSK-AES128-CBC-SHA256") + != SSL_SUCCESS) { + printf("Fatal error : server can't set cipher list\n"); + return 1; + } + + + /* set up server address and port */ + memset(&servAddr, 0, sizeof(servAddr)); + servAddr.sin_family = AF_INET; + servAddr.sin_addr.s_addr = htonl(INADDR_ANY); + servAddr.sin_port = htons(SERV_PORT); + + /* find a socket */ + listenfd = socket(AF_INET, SOCK_STREAM, 0); + if (listenfd < 0) { + printf("Fatal error : socket error\n"); + return 1; + } + + /* bind to a socket */ + opt = 1; + if (setsockopt(listenfd, SOL_SOCKET, SO_REUSEADDR, (const void *)&opt, + sizeof(int)) != 0) { + printf("Fatal error : setsockopt error\n"); + return 1; + } + if (bind(listenfd, (struct sockaddr *) &servAddr, sizeof(servAddr)) < 0) { + printf("Fatal error : bind error\n"); + return 1; + } + + /* listen to the socket */ + if (listen(listenfd, LISTENQ) < 0) { + printf("Fatal error : listen error\n"); + return 1; + } + + /* main loop for accepting and responding to clients */ + for ( ; ; ) { + CYASSL* ssl; + + cliLen = sizeof(cliAddr); + connfd = accept(listenfd, (struct sockaddr *) &cliAddr, &cliLen); + if (connfd < 0) { + printf("Fatal error : accept error\n"); + return 1; + } + else { + printf("Connection from %s, port %d\n", + inet_ntop(AF_INET, &cliAddr.sin_addr, buff, sizeof(buff)), + ntohs(cliAddr.sin_port)); + + /* create CYASSL object and respond */ + if ((ssl = CyaSSL_new(ctx)) == NULL) { + printf("Fatal error : CyaSSL_new error\n"); + return 1; + } + CyaSSL_set_fd(ssl, connfd); + if (respond(ssl) != 0) + return 1; + + /* closes the connections after responding */ + CyaSSL_shutdown(ssl); + CyaSSL_free(ssl); + + if (close(connfd) == -1) { + printf("Fatal error : close error\n"); + return 1; + } + } + } + /* free up memory used by CyaSSL */ + CyaSSL_CTX_free(ctx); + CyaSSL_Cleanup(); + + return 0; +} + diff --git a/psk/server-tcp.c b/psk/server-tcp.c new file mode 100644 index 00000000..f8b0c029 --- /dev/null +++ b/psk/server-tcp.c @@ -0,0 +1,119 @@ +/* server-tcp.c + * A server ecample using a TCP connection. + * + * This file is part of CyaSSL. + * + * CyaSSL is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * CyaSSL is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define MAXLINE 4096 +#define LISTENQ 1024 +#define SERV_PORT 11111 + +/* + * Fatal error detected, print out and exit. + */ +void err_sys(const char *err, ...) +{ + printf("Fatal error : %s\n", err); +} + +/* + * Handles response to client. + */ +void respond(int sockfd) +{ + int n; /* length of string read */ + char buf[MAXLINE]; /* string read from client */ + char response[22] = "I hear ya for shizzle"; + memset(buf, 0, MAXLINE); + n = read(sockfd, buf, MAXLINE); + if (n > 0) { + printf("%s\n", buf); + if (write(sockfd, response, 22) > 22) { + err_sys("write error"); + } + } + if (n < 0) { + err_sys("respond: read error"); + } +} + +int main() +{ + int listenfd, connfd; + int opt; + struct sockaddr_in cliAddr, servAddr; + char buff[MAXLINE]; + socklen_t cliLen; + + /* find a socket , 0 for using TCP option */ + listenfd = socket(AF_INET, SOCK_STREAM, 0); + if (listenfd < 0) + err_sys("socket error"); + + /* set up server address and port */ + memset(&servAddr, 0, sizeof(servAddr)); + servAddr.sin_family = AF_INET; + servAddr.sin_addr.s_addr = htonl(INADDR_ANY); + servAddr.sin_port = htons(SERV_PORT); + + /* bind to a socket */ + opt = 1; + setsockopt(listenfd, SOL_SOCKET, SO_REUSEADDR, (const void*)&opt, + sizeof(int)); + if (bind(listenfd, (struct sockaddr *) &servAddr, sizeof(servAddr)) < 0) + err_sys("bind error"); + + /* listen to the socket */ + if (listen(listenfd, LISTENQ) < 0) { + err_sys("listen error"); + return 1; + } + + /* main loop for accepting and responding to clients */ + for ( ; ; ) { + cliLen = sizeof(cliAddr); + connfd = accept(listenfd, (struct sockaddr *) &cliAddr, &cliLen); + if (connfd < 0) { + err_sys("accept error"); + break; + } + else { + printf("Connection from %s, port %d\n", + inet_ntop(AF_INET, &cliAddr.sin_addr, buff, sizeof(buff)), + ntohs(cliAddr.sin_port)); + + respond(connfd); + /* closes the connections after responding */ + if (close(connfd) == -1) { + err_sys("close error"); + break; + } + } + } + return 0; +} + diff --git a/psk/tutorial-tcp-psk.md b/psk/tutorial-tcp-psk.md new file mode 100644 index 00000000..6cb3d76f --- /dev/null +++ b/psk/tutorial-tcp-psk.md @@ -0,0 +1,5 @@ +TCP/PSK Tutorial +================ + +< TODO > + From 4504528bf2d70373c5ef713b86caaf477f1145d8 Mon Sep 17 00:00:00 2001 From: Chris Conlon Date: Mon, 30 Jun 2014 09:53:18 -0600 Subject: [PATCH 5/5] add initial TLS examples --- tls/Makefile | 34 +++++ tls/client-tcp.c | 99 ++++++++++++ tls/client-tls-nonblocking.c | 235 ++++++++++++++++++++++++++++ tls/client-tls-resume.c | 200 ++++++++++++++++++++++++ tls/client-tls.c | 148 ++++++++++++++++++ tls/server-tcp.c | 135 +++++++++++++++++ tls/server-tls-nonblocking.c | 286 +++++++++++++++++++++++++++++++++++ tls/server-tls-threaded.c | 201 ++++++++++++++++++++++++ tls/server-tls.c | 190 +++++++++++++++++++++++ tls/tutorial-tcp-tls.md | 5 + 10 files changed, 1533 insertions(+) create mode 100644 tls/Makefile create mode 100644 tls/client-tcp.c create mode 100644 tls/client-tls-nonblocking.c create mode 100644 tls/client-tls-resume.c create mode 100644 tls/client-tls.c create mode 100644 tls/server-tcp.c create mode 100644 tls/server-tls-nonblocking.c create mode 100644 tls/server-tls-threaded.c create mode 100644 tls/server-tls.c create mode 100644 tls/tutorial-tcp-tls.md diff --git a/tls/Makefile b/tls/Makefile new file mode 100644 index 00000000..43552779 --- /dev/null +++ b/tls/Makefile @@ -0,0 +1,34 @@ +CC=gcc +CFLAGS=-Wall +LIBS=-lcyassl + +all: client-tcp client-tls client-tls-nonblocking client-tls-resume server-tcp server-tls server-tls-nonblocking server-tls-threaded + +client-tcp: client-tcp.o + $(CC) -o $@ $^ $(CFLAGS) + +client-tls: client-tls.o + $(CC) -o $@ $^ $(CFLAGS) $(LIBS) + +client-tls-nonblocking: client-tls-nonblocking.o + $(CC) -o $@ $^ $(CFLAGS) $(LIBS) + +client-tls-resume: client-tls-resume.o + $(CC) -o $@ $^ $(CFLAGS) $(LIBS) + +server-tcp: server-tcp.o + $(CC) -o $@ $^ $(CFLAGS) + +server-tls: server-tls.o + $(CC) -o $@ $^ $(CFLAGS) $(LIBS) + +server-tls-nonblocking: server-tls-nonblocking.o + $(CC) -o $@ $^ $(CFLAGS) $(LIBS) + +server-tls-threaded: server-tls-threaded.o + $(CC) -o $@ $^ $(CFLAGS) $(LIBS) + +.PHONY: clean all + +clean: + rm -f *.o client-tcp client-tls client-tls-nonblocking client-tls-resume server-tcp server-tls server-tls-nonblocking server-tls-threaded diff --git a/tls/client-tcp.c b/tls/client-tcp.c new file mode 100644 index 00000000..d77c9f66 --- /dev/null +++ b/tls/client-tcp.c @@ -0,0 +1,99 @@ +/* client-tcp.c + * + * Copyright (C) 2006-2014 wolfSSL Inc. + * + * This file is part of CyaSSL. + * + * CyaSSL is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * CyaSSL is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + */ +#include +#include +#include +#include +#include + +#define MAXDATASIZE 4096 /* maximum acceptable amount of data */ +#define SERV_PORT 11111 /* define default port number */ + +/* + * clients initial contact with server. Socket to connect to: sock + */ +int ClientGreet(int sock) +{ + /* data to send to the server, data recieved from the server */ + char sendBuff[MAXDATASIZE], rcvBuff[MAXDATASIZE] = {0}; + int err = 0; + + printf("Message for server:\t"); + fgets(sendBuff, MAXDATASIZE, stdin); + + if (write(sock, sendBuff, strlen(sendBuff)) != strlen(sendBuff)) { + /* the message is not able to send, or error trying */ + err = errno; + printf("Write error: errno: %i\n", err); + return EXIT_FAILURE; + } + + if (read(sock, rcvBuff, MAXDATASIZE) < 0) { + /* the server fails to send data, or error trying */ + err = errno; + printf("Read error. errno: %i\n", err); + return EXIT_FAILURE; + } + printf("Recieved: \t%s\n", rcvBuff); + return 0; +} +/* + * command line argumentCount and argumentValues + */ +int main(int argc, char** argv) +{ + int sockfd; /* socket file descriptor */ + struct sockaddr_in servAddr; /* struct for server address */ + int err; /* variable for error checks */ + + if (argc != 2) { + /* if the number of arguments is not two, error */ + printf("usage: ./client-tcp \n"); + return EXIT_FAILURE; + } + + /* internet address family, stream based tcp, default protocol */ + sockfd = socket(AF_INET, SOCK_STREAM, 0); + if (sockfd < 0) { + printf("Failed to create socket. errono: %i\n", errno); + return EXIT_FAILURE; + } + + memset(&servAddr, 0, sizeof(servAddr)); /* clears memory block for use */ + servAddr.sin_family = AF_INET; /* sets addressfamily to internet*/ + servAddr.sin_port = htons(SERV_PORT); /* sets port to defined port */ + + /* looks for the server at the entered address (ip in the command line) */ + if (inet_pton(AF_INET, argv[1], &servAddr.sin_addr) < 1) { + /* checks validity of address */ + err = errno; + printf("Invalid Address. errno: %i\n", err); + return EXIT_FAILURE; + } + + if (connect(sockfd, (struct sockaddr *) &servAddr, sizeof(servAddr)) < 0) { + err = errno; + printf("Connect error. errno: %i\n", err); + return EXIT_FAILURE; + } + ClientGreet(sockfd); + return 0; +} diff --git a/tls/client-tls-nonblocking.c b/tls/client-tls-nonblocking.c new file mode 100644 index 00000000..e9811f2c --- /dev/null +++ b/tls/client-tls-nonblocking.c @@ -0,0 +1,235 @@ +/* client-tls-nonblocking.c + * + * Copyright (C) 2006-2014 wolfSSL Inc. + * + * This file is part of CyaSSL. + * + * CyaSSL is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * CyaSSL is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + */ +#include +#include +#include +#include +#include +#include /* CyaSSL security library */ +#include /* nonblocking I/O library */ + +#define MAXDATASIZE 4096 /* maximum acceptable amount of data */ +#define SERV_PORT 11111 /* define default port number */ + +const char* cert = "..../certs/ca-cert.pem"; + +/* + * enum used for tcp_select function + */ +enum { + TEST_SELECT_FAIL, + TEST_TIMEOUT, + TEST_RECV_READY, + TEST_ERROR_READY +}; + +static inline int tcp_select(int socketfd, int to_sec) +{ + fd_set recvfds, errfds; + int nfds = socketfd + 1; + struct timeval timeout = { (to_sec > 0) ? to_sec : 0, 0}; + int result; + + FD_ZERO(&recvfds); + FD_SET(socketfd, &recvfds); + FD_ZERO(&errfds); + FD_SET(socketfd, &errfds); + + result = select(nfds, &recvfds, NULL, &errfds, &timeout); + + if (result == 0) + return TEST_TIMEOUT; + else if (result > 0) { + if (FD_ISSET(socketfd, &recvfds)) + return TEST_RECV_READY; + else if(FD_ISSET(socketfd, &errfds)) + return TEST_ERROR_READY; + } + + return TEST_SELECT_FAIL; +} +int NonBlockConnect(CYASSL* ssl) +{ + int ret = CyaSSL_connect(ssl); + + int error = CyaSSL_get_error(ssl, 0); + int sockfd = (int)CyaSSL_get_fd(ssl); + int select_ret; + + while (ret != SSL_SUCCESS && (error == SSL_ERROR_WANT_READ || + error == SSL_ERROR_WANT_WRITE)) { + int currTimeout = 1; + + if (error == SSL_ERROR_WANT_READ) + printf("... server would read block\n"); + else + printf("... server would write block\n"); + + select_ret = tcp_select(sockfd, currTimeout); + + if ((select_ret == TEST_RECV_READY) || + (select_ret == TEST_ERROR_READY)) { + ret = CyaSSL_connect(ssl); + error = CyaSSL_get_error(ssl, 0); + } + else if (select_ret == TEST_TIMEOUT) { + error = SSL_ERROR_WANT_READ; + } + else { + error = SSL_FATAL_ERROR; + } + } + if (ret != SSL_SUCCESS){ + printf("SSL_connect failed\n"); + exit(0); + } + return ret; +} + +/* + * clients initial contact with server. (socket to connect, security layer) + */ +int ClientGreet(CYASSL* ssl) +{ + /* data to send to the server, data recieved from the server */ + char sendBuff[MAXDATASIZE], rcvBuff[MAXDATASIZE] = {0}; + int ret = 0; +int count = 0; + + printf("Message for server:\t"); + fgets(sendBuff, MAXDATASIZE, stdin); + + if (CyaSSL_write(ssl, sendBuff, strlen(sendBuff)) != strlen(sendBuff)) { + /* the message is not able to send, or error trying */ + ret = CyaSSL_get_error(ssl, 0); + printf("Write error: Error: %d\n", ret); + return EXIT_FAILURE; + } + + ret = CyaSSL_read(ssl, rcvBuff, MAXDATASIZE); + if (ret <= 0) { + /* the server failed to send data, or error trying */ + ret = CyaSSL_get_error(ssl, 0); + while (ret == SSL_ERROR_WANT_READ) { +count++; + ret = CyaSSL_read(ssl, rcvBuff, MAXDATASIZE); + ret = CyaSSL_get_error(ssl, 0); + } +printf("counter %d\n", count); + if (ret < 0) { + ret = CyaSSL_get_error(ssl, 0); + printf("Read error. Error: %d\n", ret); + return EXIT_FAILURE; + } + } + printf("Recieved: \t%s\n", rcvBuff); + + return ret; +} + +/* + * applies TLS 1.2 security layer to data being sent. + */ +int Security(int sock) +{ + CYASSL_CTX* ctx; + CYASSL* ssl; /* create CYASSL object */ + int ret = 0; + + CyaSSL_Init(); /* initialize CyaSSL */ + + /* create and initiLize CYASSL_CTX structure */ + if ((ctx = CyaSSL_CTX_new(CyaTLSv1_2_client_method())) == NULL) { + printf("SSL_CTX_new error.\n"); + return EXIT_FAILURE; + } + + /* load CA certificates into CyaSSL_CTX. which will verify the server */ + if (CyaSSL_CTX_load_verify_locations(ctx, cert, 0) != + SSL_SUCCESS) { + printf("Error loading %s. Please check the file.\n", cert); + return EXIT_FAILURE; + } + + if ((ssl = CyaSSL_new(ctx)) == NULL) { + printf("CyaSSL_new error.\n"); + return EXIT_FAILURE; + } + + CyaSSL_set_fd(ssl, sock); + CyaSSL_set_using_nonblock(ssl, 1); + ret = NonBlockConnect(ssl); + if (ret == SSL_SUCCESS) { + ret = ClientGreet(ssl); + } + /* frees all data before client termination */ + CyaSSL_free(ssl); + CyaSSL_CTX_free(ctx); + CyaSSL_Cleanup(); + + return ret; +} + +/* + * Command line argumentCount and argumentValues + */ +int main(int argc, char** argv) +{ + int sockfd; /* socket file descriptor */ + struct sockaddr_in servAddr; /* struct for server address */ + int ret = 10; /* variable for error checks */ + + if (argc != 2) { + /* if the number of arguments is not two, error */ + printf("usage: ./client-tcp \n"); + return EXIT_FAILURE; + } + + /* internet address family, stream based tcp, default protocol */ + sockfd = socket(AF_INET, SOCK_STREAM, 0); + if (sockfd < 0) { + ret = errno; + printf("Failed to create socket. Error: %i\n", ret); + return EXIT_FAILURE; + } + + fcntl(sockfd, F_SETFL, O_NONBLOCK); /* sets socket to non-blocking */ + memset(&servAddr, 0, sizeof(servAddr)); /* clears memory block for use */ + servAddr.sin_family = AF_INET; /* sets addressfamily to internet*/ + servAddr.sin_port = htons(SERV_PORT); /* sets port to defined port */ + + /* looks for the server at the entered address (ip in the command line) */ + if (inet_pton(AF_INET, argv[1], &servAddr.sin_addr) < 1) { + /* checks validity of address */ + ret = errno; + printf("Invalid Address. Error: %i\n", ret); + return EXIT_FAILURE; + } + + /* keeps trying to connect to the socket until it is able to do so */ + while (ret != 0) + ret = connect(sockfd, (struct sockaddr *) &servAddr, + sizeof(servAddr)); + + Security(sockfd); + + return ret; +} diff --git a/tls/client-tls-resume.c b/tls/client-tls-resume.c new file mode 100644 index 00000000..302fd39a --- /dev/null +++ b/tls/client-tls-resume.c @@ -0,0 +1,200 @@ +/* client-tls-resume.c + * + * Copyright (C) 2006-2014 wolfSSL Inc. + * + * This file is part of CyaSSL. + * + * CyaSSL is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * CyaSSL is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + */ +#include +#include +#include +#include +#include +#include /* CyaSSL security library */ + +#define MAXDATASIZE 4096 /* maximum acceptable amount of data */ +#define SERV_PORT 11111 /* define default port number */ + +const char* cert = "../certs/ca-cert.pem"; + +/* + * clients initial contact with server. (socket to connect, security layer) + */ +int ClientGreet(int sock, CYASSL* ssl) +{ + /* data to send to the server, data recieved from the server */ + char sendBuff[MAXDATASIZE], rcvBuff[MAXDATASIZE] = {0}; + int ret = 0; + + printf("Message for server:\t"); + fgets(sendBuff, MAXDATASIZE, stdin); + + if (CyaSSL_write(ssl, sendBuff, strlen(sendBuff)) != strlen(sendBuff)) { + /* the message is not able to send, or error trying */ + ret = CyaSSL_get_error(ssl, 0); + printf("Write error: Error: %i\n", ret); + return EXIT_FAILURE; + } + + if (CyaSSL_read(ssl, rcvBuff, MAXDATASIZE) == 0) { + /* the server failed to send data, or error trying */ + ret = CyaSSL_get_error(ssl, 0); + printf("Read error. Error: %i\n", ret); + return EXIT_FAILURE; + } + printf("Recieved: \t%s\n", rcvBuff); + + return ret; +} + +/* + * applies TLS 1.2 security layer to data being sent. + */ +int Security(int sock, struct sockaddr_in addr) +{ + CYASSL_CTX* ctx; /* cyassl context */ + CYASSL* ssl; /* create CYASSL object */ + CYASSL_SESSION* session = 0;/* cyassl session */ + CYASSL* sslResume; /* create CYASSL object for connection loss */ + int ret; + + CyaSSL_Init(); /* initialize CyaSSL (must be done first) */ + + /* create and initiLize CYASSL_CTX structure */ + if ((ctx = CyaSSL_CTX_new(CyaTLSv1_2_client_method())) == NULL) { + printf("SSL_CTX_new error.\n"); + return EXIT_FAILURE; + } + + /* load CA certificates into CyaSSL_CTX. which will verify the server */ + if (CyaSSL_CTX_load_verify_locations(ctx, cert, 0) != SSL_SUCCESS) { + printf("Error loading %s. Please check the file.\n", cert); + return EXIT_FAILURE; + } + + if ((ssl = CyaSSL_new(ctx)) == NULL) { + printf("CyaSSL_new error.\n"); + return EXIT_FAILURE; + } + + CyaSSL_set_fd(ssl, sock); + + /* connects to CyaSSL */ + ret = CyaSSL_connect(ssl); + if (ret != SSL_SUCCESS) { + return ret; + } + + ret = ClientGreet(sock, ssl); + + /* saves the session */ + session = CyaSSL_get_session(ssl); + CyaSSL_free(ssl); + + /* closes the connection */ + close(sock); + + /* new ssl to reconnect to */ + sslResume = CyaSSL_new(ctx); + + /* makes a new socket to connect to */ + sock = socket(AF_INET, SOCK_STREAM, 0); + + /* sets session to old session */ + CyaSSL_set_session(sslResume, session); + + /* connects to new socket */ + if (connect(sock, (struct sockaddr *) &addr, sizeof(addr)) < 0) { + /* if socket fails to connect to the server*/ + ret = CyaSSL_get_error(ssl, 0); + printf("Connect error. Error: %i\n", ret); + return EXIT_FAILURE; + } + + /* sets new file discriptior */ + CyaSSL_set_fd(sslResume, sock); + + /* reconects to CyaSSL */ + ret = CyaSSL_connect(sslResume); + if (ret != SSL_SUCCESS) { + return ret; + } + + /* checks to see if the new session is the same as the old session */ + if (CyaSSL_session_reused(sslResume)) + printf("Re-used session ID\n"); + else + printf("Did not re-use session ID\n"); + + /* regreet the client */ + ret = ClientGreet(sock, sslResume); + + /* closes the connection */ + close(sock); + + /* frees all data before client termination */ + CyaSSL_free(sslResume); + CyaSSL_CTX_free(ctx); + CyaSSL_Cleanup(); + + return ret; +} + +/* + * Command line argumentCount and argumentValues + */ +int main(int argc, char** argv) +{ + int sockfd; /* socket file descriptor */ + struct sockaddr_in servAddr; /* struct for server address */ + int ret; /* variable for error checking */ + + if (argc != 2) { + /* if the number of arguments is not two, error */ + printf("usage: ./client-tcp \n"); + return EXIT_FAILURE; + } + + /* internet address family, stream based tcp, default protocol */ + sockfd = socket(AF_INET, SOCK_STREAM, 0); + + if (sockfd < 0) { + printf("Failed to create socket. errono: %i\n", errno); + return EXIT_FAILURE; + } + + memset(&servAddr, 0, sizeof(servAddr)); /* clears memory block for use */ + servAddr.sin_family = AF_INET; /* sets addressfamily to internet*/ + servAddr.sin_port = htons(SERV_PORT); /* sets port to defined port */ + + /* looks for the server at the entered address (ip in the command line) */ + if (inet_pton(AF_INET, argv[1], &servAddr.sin_addr) < 1) { + /* checks validity of address */ + ret = errno; + printf("Invalid Address. Error: %i\n", ret); + return EXIT_FAILURE; + } + + if (connect(sockfd, (struct sockaddr *) &servAddr, sizeof(servAddr)) < 0) { + /* if socket fails to connect to the server*/ + ret = errno; + printf("Connect error. Error: %i\n", ret); + return EXIT_FAILURE; + } + Security(sockfd, servAddr); + + return ret; +} diff --git a/tls/client-tls.c b/tls/client-tls.c new file mode 100644 index 00000000..bfbfcb69 --- /dev/null +++ b/tls/client-tls.c @@ -0,0 +1,148 @@ +/* client-tls.c + * + * Copyright (C) 2006-2014 wolfSSL Inc. + * + * This file is part of CyaSSL. + * + * CyaSSL is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * CyaSSL is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + */ +#include +#include +#include +#include +#include +#include /* CyaSSL security library */ + +#define MAXDATASIZE 4096 /* maximum acceptable amount of data */ +#define SERV_PORT 11111 /* define default port number */ + +const char* cert = "./certs/ca-cert.pem"; + +/* + * clients initial contact with server. (socket to connect, security layer) + */ +int ClientGreet(int sock, CYASSL* ssl) +{ + /* data to send to the server, data recieved from the server */ + char sendBuff[MAXDATASIZE], rcvBuff[MAXDATASIZE] = {0}; + int ret = 0; /* variable for error checking */ + + printf("Message for server:\t"); + fgets(sendBuff, MAXDATASIZE, stdin); + + if (CyaSSL_write(ssl, sendBuff, strlen(sendBuff)) != strlen(sendBuff)) { + /* the message is not able to send, or error trying */ + ret = CyaSSL_get_error(ssl, 0); + printf("Write error: Error: %i\n", ret); + return EXIT_FAILURE; + } + + if (CyaSSL_read(ssl, rcvBuff, MAXDATASIZE) < 0) { + /* the server failed to send data, or error trying */ + ret = CyaSSL_get_error(ssl, 0); + printf("Read error. Error: %i\n", ret); + return EXIT_FAILURE; + } + printf("Recieved: \t%s\n", rcvBuff); + + return ret; +} + +/* + * applies TLS 1.2 security layer to data being sent. + */ +int Security(int sock) +{ + CYASSL_CTX* ctx; + CYASSL* ssl; /* create CYASSL object */ + int ret = 0; + + CyaSSL_Init(); /* initialize CyaSSL */ + + /* create and initiLize CYASSL_CTX structure */ + if ((ctx = CyaSSL_CTX_new(CyaTLSv1_2_client_method())) == NULL) { + printf("SSL_CTX_new error.\n"); + return EXIT_FAILURE; + } + + /* load CA certificates into CyaSSL_CTX. which will verify the server */ + if (CyaSSL_CTX_load_verify_locations(ctx, cert, 0) != SSL_SUCCESS) { + printf("Error loading %s. Please check the file.\n", cert); + return EXIT_FAILURE; + } + if ((ssl = CyaSSL_new(ctx)) == NULL) { + printf("CyaSSL_new error.\n"); + return EXIT_FAILURE; + } + CyaSSL_set_fd(ssl, sock); + + ret = CyaSSL_connect(ssl); + if (ret == SSL_SUCCESS) { + ret = ClientGreet(sock, ssl); + } + + /* frees all data before client termination */ + CyaSSL_free(ssl); + CyaSSL_CTX_free(ctx); + CyaSSL_Cleanup(); + + return ret; +} + +/* + * Command line argumentCount and argumentValues + */ +int main(int argc, char** argv) +{ + int sockfd; /* socket file descriptor */ + struct sockaddr_in servAddr; /* struct for server address */ + int ret = 0; /* variable for error checking */ + + if (argc != 2) { + /* if the number of arguments is not two, error */ + printf("usage: ./client-tcp \n"); + return EXIT_FAILURE; + } + + /* internet address family, stream based tcp, default protocol */ + sockfd = socket(AF_INET, SOCK_STREAM, 0); + + if (sockfd < 0) { + printf("Failed to create socket. Error: %i\n", errno); + return EXIT_FAILURE; + } + + memset(&servAddr, 0, sizeof(servAddr)); /* clears memory block for use */ + servAddr.sin_family = AF_INET; /* sets addressfamily to internet*/ + servAddr.sin_port = htons(SERV_PORT); /* sets port to defined port */ + + /* looks for the server at the entered address (ip in the command line) */ + if (inet_pton(AF_INET, argv[1], &servAddr.sin_addr) < 1) { + /* checks validity of address */ + ret = errno; + printf("Invalid Address. Error: %i\n", ret); + return EXIT_FAILURE; + } + + if (connect(sockfd, (struct sockaddr *) &servAddr, sizeof(servAddr)) < 0) { + /* if socket fails to connect to the server*/ + ret = errno; + printf("Connect error. Error: %i\n", ret); + return EXIT_FAILURE; + } + Security(sockfd); + + return ret; +} diff --git a/tls/server-tcp.c b/tls/server-tcp.c new file mode 100644 index 00000000..ed271e17 --- /dev/null +++ b/tls/server-tcp.c @@ -0,0 +1,135 @@ +/* server-tcp.c + * + * Copyright (C) 2006-2014 wolfSSL Inc. + * + * This file is part of CyaSSL. + * + * CyaSSL is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * CyaSSL is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA + * ============================================================================= + * + * This is a super basic example of what a TCP Server might look like that is + * not actively using any form of security. + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#define DEFAULT_PORT 11111 + +int AcceptAndRead(); + +int AcceptAndRead(int sockfd, struct sockaddr_in clientAddr) +{ + int size = sizeof(clientAddr); + + /* Wait until a client connects */ + int connd = accept(sockfd, (struct sockaddr *)&clientAddr, &size); + + /* If fails to connect, loop back up and wait for a new connection */ + if (connd == -1){ + printf("failed to accept the connection..\n"); + } + /* If it connects, read in and reply to the client */ + else{ + + printf("Client connected successfully\n"); + + for ( ; ; ){ + + char buff[256]; + + /* Clear the buffer memory for anything possibly left over */ + bzero(&buff, sizeof(buff)); + + /* Read the client data into our buff array */ + if (read(connd, buff, sizeof(buff)-1) > 0){ + /* Print any data the client sends to the console */ + printf("Client: %s\n", buff); + + /* Create our reply message */ + char reply[] = "I hear ya fa shizzle!\n"; + + /* Reply back to the client */ + write(connd, reply, sizeof(reply)-1); + } + /* If the client disconnects break the loop */ + else + break; + } + } + + /* Close the socket */ + close(connd); + + return 0; +} + + +int main() +{ + /* + * Creates a socket that uses an internet IP address, + * Sets the type to be Stream based (TCP), + * 0 means choose the default protocol. + */ + + /* Identify and access the sockets */ + int sockfd = socket(AF_INET, SOCK_STREAM, 0); + int exit = 0; /* 0 = false, 1 = true */ + + /* If positive value, the socket is valid */ + if(sockfd < 0){ + printf("ERROR: failed to create the socket\n"); + return 1; /* Kill the server with exit status 1 */ + } + + /* Server and client socket address structures */ + struct sockaddr_in serverAddr, clientAddr; + + /* Initialize the server address struct to zero */ + memset((char *)&serverAddr, 0, sizeof(serverAddr)); + + /* Fill the server's address family */ + serverAddr.sin_family = AF_INET; + serverAddr.sin_addr.s_addr = INADDR_ANY; + serverAddr.sin_port = htons(DEFAULT_PORT); + + /* Attach the server socket to our port */ + if(bind(sockfd, (struct sockaddr *)&serverAddr, sizeof(serverAddr)) < 0){ + printf("ERROR: failed to bind\n"); + return 1; + } + + /* Continuously accept connections while not currently in an active connection or told to quit */ + while (exit == 0){ + /* Listen for a new connection, allow 5 pending connections */ + listen(sockfd, 5); + printf("Waiting for a connection...\n"); + + /* Accept client connections and read from them */ + exit = AcceptAndRead(sockfd, clientAddr); + } + + /* Close the open sockets */ + close(sockfd); + return 0; + +} diff --git a/tls/server-tls-nonblocking.c b/tls/server-tls-nonblocking.c new file mode 100644 index 00000000..3a422d5a --- /dev/null +++ b/tls/server-tls-nonblocking.c @@ -0,0 +1,286 @@ +/* server-tls-nonblocking.c + * + * Copyright (C) 2006-2014 wolfSSL Inc. + * + * This file is part of CyaSSL. + * + * CyaSSL is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * CyaSSL is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, * USA + * ============================================================================= + * + * This is a super basic example of what a TCP Server secured with TLS 1.2 + * that uses non blocking input and output. +*/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* Include the CyaSSL library for our TLS 1.2 security */ +#include + +#define DEFAULT_PORT 11111 + +/* Create an enum that we will use to tell our + * NonBlocking_ReadWriteAccept() method what to do + */ +enum read_write_t {WRITE, READ, ACCEPT}; + +int AcceptAndRead(CYASSL_CTX* ctx, int socketfd, + struct sockaddr_in clientAddr); +int TCPSelect(int socketfd); +int NonBlocking_ReadWriteAccept(CYASSL* ssl, int socketfd, + enum read_write_t rw); + +/* Check if any sockets are ready for reading and writing and set it */ +int TCPSelect(int socketfd) +{ + fd_set recvfds, errfds; + int nfds = socketfd + 1; + int result; + + FD_ZERO(&recvfds); + FD_SET(socketfd, &recvfds); + FD_ZERO(&errfds); + FD_SET(socketfd, &errfds); + + result = select(nfds, &recvfds, NULL, &errfds, NULL); + + if (result > 0) { + if (FD_ISSET(socketfd, &recvfds)) + return 1; /* RECV READY */ + else if (FD_ISSET(socketfd, &errfds)) + return 2; /* ERROR READY */ + } + + return -1; /* TEST FAILED */ + +} +/* Checks if NonBlocking I/O is wanted, if it is wanted it will + * wait until it's available on the socket before reading or writing */ +int NonBlocking_ReadWriteAccept(CYASSL* ssl, int socketfd, + enum read_write_t rw) +{ + const char reply[] = "I hear ya fa shizzle!\n"; + char buff[256]; + int rwret = 0; + int selectRet; + int ret; + + + /* Clear the buffer memory for anything possibly left + over */ + memset(&buff, 0, sizeof(buff)); + + if (rw == READ) + rwret = CyaSSL_read(ssl, buff, sizeof(buff)-1); + else if (rw == WRITE) + rwret = CyaSSL_write(ssl, reply, sizeof(reply)-1); + else if (rw == ACCEPT) + rwret = CyaSSL_accept(ssl); + + if (rwret == 0) { + printf("The client has closed the connection!\n"); + return 0; + } + else if (rwret != SSL_SUCCESS) { + int error = CyaSSL_get_error(ssl, 0); + + /* while I/O is not ready, keep waiting */ + while ((error == SSL_ERROR_WANT_READ || + error == SSL_ERROR_WANT_WRITE)) { + + if (error == SSL_ERROR_WANT_READ) + printf("... server would read block\n"); + else + printf("... server would write block\n"); + + selectRet = TCPSelect(socketfd); + + if ((selectRet == 1) || (selectRet == 2)) { + if (rw == READ) + rwret = CyaSSL_read(ssl, buff, sizeof(buff)-1); + else if (rw == WRITE) + rwret = CyaSSL_write(ssl, reply, sizeof(reply)-1); + else if (rw == ACCEPT) + rwret = CyaSSL_accept(ssl); + + error = CyaSSL_get_error(ssl, 0); + } + else { + error = SSL_FATAL_ERROR; + return -1; + } + } + /* Print any data the client sends to the console */ + if (rw == READ) + printf("Client: %s\n", buff); + /* Reply back to the client */ + else if (rw == WRITE) { + if ((ret = CyaSSL_write(ssl, reply, sizeof(reply)-1)) < 0) { + printf("CyaSSL_write error = %d\n", + CyaSSL_get_error(ssl, ret)); + } + } + } + + return 1; +} + +int AcceptAndRead(CYASSL_CTX* ctx, int socketfd, struct sockaddr_in clientAddr) +{ + int size = sizeof(clientAddr); + int ret = 0; + int err = 0; + CYASSL* ssl; + + /* Wait until a client connects */ + int connd = accept(socketfd, (struct sockaddr *)&clientAddr, &size); + + /* If fails to connect, loop back up and wait for a new connection */ + if (connd == -1) { + printf("failed to accept the connection..\n"); + } + /* If it connects, read in and reply to the client */ + else { + printf("Client connected successfully!\n"); + + if ( (ssl = CyaSSL_new(ctx)) == NULL) { + fprintf(stderr, "CyaSSL_new error.\n"); + exit(EXIT_FAILURE); + } + + /* Direct our ssl to our clients connection */ + CyaSSL_set_fd(ssl, connd); + + /* Sets CyaSSL_accept(ssl) */ + if(NonBlocking_ReadWriteAccept(ssl, socketfd, ACCEPT) < 0) + return 0; + + /* + * loop until the connected client disconnects + * and read in any messages the client sends + */ + for ( ; ; ) { + /* Read data in when I/O is available */ + if (NonBlocking_ReadWriteAccept(ssl, socketfd, READ) == 0) + break; + /* Write data out when I/O is available */ + if (NonBlocking_ReadWriteAccept(ssl, socketfd, WRITE) == 0) + break; + } + } + CyaSSL_free(ssl); /* Free the CYASSL object */ + close(connd); /* close the connected socket */ + + return 0; +} + + +int main() +{ + /* + * Creates a socket that uses an internet IP address, + * Sets the type to be Stream based (TCP), + * 0 means choose the default protocol. + */ + int socketfd = socket(AF_INET, SOCK_STREAM, 0); + int loopExit = 0; /* 0 = False, 1 = True */ + int ret = 0; /* Return variable */ + int on = 1; + + /* Set nonblocking */ + //fcntl(socketfd, F_SETFL, fcntl(socketfd, F_GETFL, 0) | O_NONBLOCK); + + /* Create a ctx pointer for our ssl */ + CYASSL_CTX* ctx; + + /* Server and Client socket address structures */ + struct sockaddr_in serverAddr, clientAddr; + + /* Initialize the server address struct to zero */ + memset((char *)&serverAddr, 0, sizeof(serverAddr)); + + /* Fill the server's address family */ + serverAddr.sin_family = AF_INET; + serverAddr.sin_addr.s_addr = INADDR_ANY; + serverAddr.sin_port = htons(DEFAULT_PORT); + + socklen_t len = sizeof(on); + + /* If positive value, the socket is valid */ + if (socketfd < 0) { + printf("ERROR: failed to create the socket\n"); + exit(EXIT_FAILURE); /* Kill the server with exit status 1 */ + } + + if (setsockopt(socketfd, SOL_SOCKET, SO_REUSEADDR, &on, len) + < 0) + printf("setsockopt SO_REUSEADDR failed\n"); + + /* Initialize CyaSSL */ + CyaSSL_Init(); + + /* Create and initialize CYASSL_CTX structure */ + if ((ctx = CyaSSL_CTX_new(CyaTLSv1_2_server_method())) == NULL) { + fprintf(stderr, "CyaSSL_CTX_new error.\n"); + exit(EXIT_FAILURE); + } + + /* Load server certificate into CYASSL_CTX */ + if (CyaSSL_CTX_use_certificate_file(ctx, "certs/server-cert.pem", + SSL_FILETYPE_PEM) != SSL_SUCCESS) { + fprintf(stderr, "Error loading certs/server-cert.pem, please check" + "the file.\n"); + exit(EXIT_FAILURE); + } + + /* Load server key into CYASSL_CTX */ + if (CyaSSL_CTX_use_PrivateKey_file(ctx, "certs/server-key.pem", + SSL_FILETYPE_PEM) != SSL_SUCCESS) { + fprintf(stderr, "Error loading certs/server-key.pem, please check" + "the file.\n"); + exit(EXIT_FAILURE); + } + + /* Attach the server socket to our port */ + if (bind(socketfd, (struct sockaddr *)&serverAddr, sizeof(serverAddr)) + < 0) { + printf("ERROR: failed to bind\n"); + exit(1); + } + + printf("Waiting for a connection...\n"); + + /* Continuously accept connects while not currently in an active connection + or told to quit */ + while (loopExit == 0) { + /* listen for a new connection, allow 5 pending connections */ + ret = listen(socketfd, 5); + if (ret == 0) { + /* Accept client connections and read from them */ + loopExit = AcceptAndRead(ctx, socketfd, clientAddr); + } + } + + CyaSSL_CTX_free(ctx); /* Free CYASSL_CTX */ + CyaSSL_Cleanup(); /* Free CyaSSL */ + exit(EXIT_SUCCESS); +} diff --git a/tls/server-tls-threaded.c b/tls/server-tls-threaded.c new file mode 100644 index 00000000..0c630700 --- /dev/null +++ b/tls/server-tls-threaded.c @@ -0,0 +1,201 @@ +/* server-tls-threaded.c + * + * Copyright (C) 2006-2014 wolfSSL Inc. + * + * This file is part of CyaSSL. + * + * CyaSSL is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * CyaSSL is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, * USA + * ============================================================================= + * + * This is a super basic example of what a TCP Server secured with TLS 1.2 + * might look like. This server can also resume the session if a client + * inadvertantly disconnects. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* Include the CyaSSL library for our TLS 1.2 security */ +#include + +#define DEFAULT_PORT 11111 + +int AcceptAndRead(int sockfd, struct sockaddr_in clientAddr); +void *ThreadHandler(void* socketDesc); + +/* Create a ctx pointer for our ssl */ +CYASSL_CTX* ctx; + +void *ThreadHandler(void* socketDesc) +{ + int connd = *(int*)socketDesc; + CYASSL* ssl; + /* Create our reply message */ + const char reply[] = "I hear ya fa shizzle!\n"; + + printf("Client connected successfully\n"); + + if ( (ssl = CyaSSL_new(ctx)) == NULL) { + fprintf(stderr, "CyaSSL_new error.\n"); + exit(EXIT_FAILURE); + } + + /* Direct our ssl to our clients connection */ + CyaSSL_set_fd(ssl, connd); + + for ( ; ; ) { + char buff[256]; + int ret = 0; + + /* Clear the buffer memory for anything possibly left over */ + memset(&buff, 0, sizeof(buff)); + + /* Read the client data into our buff array */ + if ((ret = CyaSSL_read(ssl, buff, sizeof(buff)-1)) > 0) { + /* Print any data the client sends to the console */ + printf("Client on Socket %d: %s\n", connd, buff); + + /* Reply back to the client */ + if ((ret = CyaSSL_write(ssl, reply, sizeof(reply)-1)) + < 0) { + printf("CyaSSL_write error = %d\n", CyaSSL_get_error(ssl, ret)); + } + } + /* if the client disconnects break the loop */ + else { + if (ret < 0) + printf("CyaSSL_read error = %d\n", CyaSSL_get_error(ssl + ,ret)); + else if (ret == 0) + printf("The client has closed the connection.\n"); + + CyaSSL_free(ssl); /* Free the CYASSL object */ + close(connd); /* close the connected socket */ + break; + } + } +} + + +int AcceptAndRead(int sockfd, struct sockaddr_in clientAddr) +{ + int size = sizeof(clientAddr); + int connd; /* Identify and access the clients connection */ + + pthread_t thread_id; + + /* Wait until a client connects */ + while ((connd = accept(sockfd, (struct sockaddr *)&clientAddr, + &size))) { + /* Pass the client into a new thread */ + if (pthread_create(&thread_id, NULL, ThreadHandler, (void *) + &connd) < 0) { + perror("could not create thread"); + } + printf("Handler assigned\n"); + } + if (connd < 0) { + perror("accept failed"); + } + + return 0; +} + + +int main() +{ + /* + * Creates a socket that uses an internet IP address, + * Sets the type to be Stream based (TCP), + * 0 means choose the default protocol. + */ + int sockfd = socket(AF_INET, SOCK_STREAM, 0); + int ret = 0; /* Return Variable */ + int loopExit = 0; /* 0 = False, 1 = True */ + + /* Server and Client socket address structures */ + struct sockaddr_in serverAddr, clientAddr; + + /* Initialize the server address struct to zero */ + memset((char *)&serverAddr, 0, sizeof(serverAddr)); + + /* Fill the server's address family */ + serverAddr.sin_family = AF_INET; + serverAddr.sin_addr.s_addr = INADDR_ANY; + serverAddr.sin_port = htons(DEFAULT_PORT); + + /* initialize CyaSSL */ + CyaSSL_Init(); + + /* If positive value, the socket is valid */ + if (sockfd < 0) { + printf("ERROR: failed to create the socket\n"); + return EXIT_FAILURE; + } + + /* Create and initialize CYASSL_CTX structure */ + if ((ctx = CyaSSL_CTX_new(CyaTLSv1_2_server_method())) == NULL) { + fprintf(stderr, "CyaSSL_CTX_new error.\n"); + return EXIT_FAILURE; + } + + /* Load server certificate into CYASSL_CTX */ + if (CyaSSL_CTX_use_certificate_file(ctx, "certs/server-cert.pem", + SSL_FILETYPE_PEM) != SSL_SUCCESS) { + fprintf(stderr, "Error loading certs/server-cert.pem, please check" + "the file.\n"); + return EXIT_FAILURE; + } + + /* Load server key into CYASSL_CTX */ + if (CyaSSL_CTX_use_PrivateKey_file(ctx, "certs/server-key.pem", + SSL_FILETYPE_PEM) != SSL_SUCCESS) { + fprintf(stderr, "Error loading certs/server-key.pem, please check" + "the file.\n"); + return EXIT_FAILURE; + } + + /* Attach the server socket to our port */ + if (bind(sockfd, (struct sockaddr *)&serverAddr, sizeof(serverAddr)) + < 0) { + printf("ERROR: failed to bind\n"); + return EXIT_FAILURE; + } + + printf("Waiting for a connection...\n"); + /* Continuously accept connects while not currently in an active connection + or told to quit */ + while (loopExit == 0) { + /* Listen for a new connection, allow 5 pending connections */ + ret = listen(sockfd, 5); + if (ret == 0) { + + /* Accept client connections and read from them */ + loopExit = AcceptAndRead(sockfd, clientAddr); + } + } + + CyaSSL_CTX_free(ctx); /* Free CYASSL_CTX */ + CyaSSL_Cleanup(); /* Free CyaSSL */ + + return EXIT_SUCCESS; +} diff --git a/tls/server-tls.c b/tls/server-tls.c new file mode 100644 index 00000000..06990477 --- /dev/null +++ b/tls/server-tls.c @@ -0,0 +1,190 @@ +/* server-tls.c + * + * Copyright (C) 2006-2014 wolfSSL Inc. + * + * This file is part of CyaSSL. + * + * CyaSSL is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * CyaSSL is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, * USA + * ============================================================================= + * + * This is a super basic example of what a TCP Server secured with TLS 1.2 + * might look like. This server can also resume the session if a client + * nadvertantly disconnects. + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +/* include the CyaSSL library for our TLS 1.2 security */ +#include + +#define DEFAULT_PORT 11111 + +int AcceptAndRead(CYASSL_CTX* ctx, int sockfd, struct sockaddr_in clientAddr); + +int AcceptAndRead(CYASSL_CTX* ctx, int sockfd, struct sockaddr_in clientAddr) +{ + /* Create our reply message */ + const char reply[] = "I hear ya fa shizzle!\n"; + int size = sizeof(clientAddr); + int ret = 0; + int err = 0; + CYASSL* ssl; + + /* Wait until a client connects */ + int connd = accept(sockfd, (struct sockaddr *)&clientAddr, &size); + + /* If fails to connect, loop back up and wait for a new connection */ + if (connd == -1) { + printf("failed to accept the connection..\n"); + } + /* If it connects, read in and reply to the client */ + else { + printf("Client connected successfully\n"); + + if ( (ssl = CyaSSL_new(ctx)) == NULL) { + fprintf(stderr, "CyaSSL_new error.\n"); + exit(EXIT_FAILURE); + } + + /* direct our ssl to our clients connection */ + CyaSSL_set_fd(ssl, connd); + + printf("Using Non-Blocking I/O: %d\n", CyaSSL_get_using_nonblock( + ssl)); + + for ( ; ; ) { + char buff[256]; + int ret = 0; + + /* Clear the buffer memory for anything possibly left over */ + memset(&buff, 0, sizeof(buff)); + + /* Read the client data into our buff array */ + if ((ret = CyaSSL_read(ssl, buff, sizeof(buff)-1)) > 0) { + /* Print any data the client sends to the console */ + printf("Client: %s\n", buff); + + /* Reply back to the client */ + if ((ret = CyaSSL_write(ssl, reply, sizeof(reply)-1)) + < 0) + { + printf("CyaSSL_write error = %d\n", CyaSSL_get_error(ssl, ret)); + } + } + /* if the client disconnects break the loop */ + else { + if (ret < 0) + printf("CyaSSL_read error = %d\n", CyaSSL_get_error(ssl + ,ret)); + else if (ret == 0) + printf("The client has closed the connection.\n"); + + break; + } + } + } + CyaSSL_free(ssl); /* Free the CYASSL object */ + close(connd); /* close the connected socket */ + + return 0; +} + + +int main() +{ + /* Create a ctx pointer for our ssl */ + CYASSL_CTX* ctx; + + /* + * Creates a socket that uses an internet IP address, + * Sets the type to be Stream based (TCP), + * 0 means choose the default protocol. + */ + int sockfd = socket(AF_INET, SOCK_STREAM, 0); + int loopExit = 0; /* 0 = False, 1 = True */ + int ret = 0; /* Return value */ + /* Server and client socket address structures */ + struct sockaddr_in serverAddr, clientAddr; + + /* Initialize CyaSSL */ + CyaSSL_Init(); + + /* If positive value, the socket is valid */ + if (sockfd < 0) { + printf("ERROR: failed to create the socket\n"); + return EXIT_FAILURE; /* Kill the server with exit status 1 */ + } + + /* create and initialize CYASSL_CTX structure */ + if ((ctx = CyaSSL_CTX_new(CyaTLSv1_2_server_method())) == NULL) { + fprintf(stderr, "CyaSSL_CTX_new error.\n"); + return EXIT_FAILURE; + } + + /* Load server certificate into CYASSL_CTX */ + if (CyaSSL_CTX_use_certificate_file(ctx, "certs/server-cert.pem", + SSL_FILETYPE_PEM) != SSL_SUCCESS) { + fprintf(stderr, "Error loading certs/server-cert.pem, please check" + "the file.\n"); + return EXIT_FAILURE; + } + + /* Load server key into CYASSL_CTX */ + if (CyaSSL_CTX_use_PrivateKey_file(ctx, "certs/server-key.pem", + SSL_FILETYPE_PEM) != SSL_SUCCESS) { + fprintf(stderr, "Error loading certs/server-key.pem, please check" + "the file.\n"); + return EXIT_FAILURE; + } + + /* Initialize the server address struct to zero */ + memset((char *)&serverAddr, 0, sizeof(serverAddr)); + + /* Fill the server's address family */ + serverAddr.sin_family = AF_INET; + serverAddr.sin_addr.s_addr = INADDR_ANY; + serverAddr.sin_port = htons(DEFAULT_PORT); + + /* Attach the server socket to our port */ + if (bind(sockfd, (struct sockaddr *)&serverAddr, sizeof(serverAddr)) + < 0) { + printf("ERROR: failed to bind\n"); + return EXIT_FAILURE; + } + + printf("Waiting for a connection...\n"); + /* Continuously accept connects while not currently in an active connection + or told to quit */ + while (loopExit == 0) { + /* listen for a new connection, allow 5 pending connections */ + ret = listen(sockfd, 5); + if (ret == 0) { + + /* Accept client connections and read from them */ + loopExit = AcceptAndRead(ctx, sockfd, clientAddr); + } + } + + CyaSSL_CTX_free(ctx); /* Free CYASSL_CTX */ + CyaSSL_Cleanup(); /* Free CyaSSL */ + return EXIT_SUCCESS; +} diff --git a/tls/tutorial-tcp-tls.md b/tls/tutorial-tcp-tls.md new file mode 100644 index 00000000..af4bb966 --- /dev/null +++ b/tls/tutorial-tcp-tls.md @@ -0,0 +1,5 @@ +TCP/TLS Tutorial +================ + +< TODO > +