..
TLSSocketWrapper.cpp@1:a6995e66c9f7, 2019-08-29 (annotated)
- Committer:
- ImranBilalButt
- Date:
- Thu Aug 29 06:43:11 2019 +0000
- Revision:
- 1:a6995e66c9f7
- Parent:
- 0:5f745af3ec9b
..;
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
ImranBilalButt | 0:5f745af3ec9b | 1 | /* |
ImranBilalButt | 0:5f745af3ec9b | 2 | * PackageLicenseDeclared: Apache-2.0 |
ImranBilalButt | 0:5f745af3ec9b | 3 | * Copyright (c) 2017 ARM Limited |
ImranBilalButt | 0:5f745af3ec9b | 4 | * |
ImranBilalButt | 0:5f745af3ec9b | 5 | * Licensed under the Apache License, Version 2.0 (the "License"); |
ImranBilalButt | 0:5f745af3ec9b | 6 | * you may not use this file except in compliance with the License. |
ImranBilalButt | 0:5f745af3ec9b | 7 | * You may obtain a copy of the License at |
ImranBilalButt | 0:5f745af3ec9b | 8 | * |
ImranBilalButt | 0:5f745af3ec9b | 9 | * http://www.apache.org/licenses/LICENSE-2.0 |
ImranBilalButt | 0:5f745af3ec9b | 10 | * |
ImranBilalButt | 0:5f745af3ec9b | 11 | * Unless required by applicable law or agreed to in writing, software |
ImranBilalButt | 0:5f745af3ec9b | 12 | * distributed under the License is distributed on an "AS IS" BASIS, |
ImranBilalButt | 0:5f745af3ec9b | 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
ImranBilalButt | 0:5f745af3ec9b | 14 | * See the License for the specific language governing permissions and |
ImranBilalButt | 0:5f745af3ec9b | 15 | * limitations under the License. |
ImranBilalButt | 0:5f745af3ec9b | 16 | */ |
ImranBilalButt | 0:5f745af3ec9b | 17 | |
ImranBilalButt | 0:5f745af3ec9b | 18 | #include "TLSSocketWrapper.h" |
ImranBilalButt | 0:5f745af3ec9b | 19 | #include "drivers/Timer.h" |
ImranBilalButt | 0:5f745af3ec9b | 20 | |
ImranBilalButt | 0:5f745af3ec9b | 21 | #define TRACE_GROUP "TLSW" |
ImranBilalButt | 0:5f745af3ec9b | 22 | #include "mbed-trace/mbed_trace.h" |
ImranBilalButt | 0:5f745af3ec9b | 23 | #include "mbed_mem_trace.h" |
ImranBilalButt | 0:5f745af3ec9b | 24 | #include "mbedtls/debug.h" |
ImranBilalButt | 0:5f745af3ec9b | 25 | //#include "mbedtls/config.h" |
ImranBilalButt | 0:5f745af3ec9b | 26 | //#include "mbedtls/timing.h" |
ImranBilalButt | 0:5f745af3ec9b | 27 | //#include "timing_alt.h" |
ImranBilalButt | 0:5f745af3ec9b | 28 | |
ImranBilalButt | 0:5f745af3ec9b | 29 | TLSSocketWrapper::TLSSocketWrapper(Socket *transport, const char *hostname) : |
ImranBilalButt | 0:5f745af3ec9b | 30 | _client_auth(false), |
ImranBilalButt | 0:5f745af3ec9b | 31 | _keep_transport_open(false), |
ImranBilalButt | 0:5f745af3ec9b | 32 | _handshake_completed(false), |
ImranBilalButt | 0:5f745af3ec9b | 33 | _transport(transport) |
ImranBilalButt | 0:5f745af3ec9b | 34 | { |
ImranBilalButt | 0:5f745af3ec9b | 35 | tls_init(); |
ImranBilalButt | 0:5f745af3ec9b | 36 | if (hostname) { |
ImranBilalButt | 0:5f745af3ec9b | 37 | set_hostname(hostname); |
ImranBilalButt | 0:5f745af3ec9b | 38 | } |
ImranBilalButt | 0:5f745af3ec9b | 39 | } |
ImranBilalButt | 0:5f745af3ec9b | 40 | |
ImranBilalButt | 0:5f745af3ec9b | 41 | TLSSocketWrapper::~TLSSocketWrapper() { |
ImranBilalButt | 0:5f745af3ec9b | 42 | if (_transport) { |
ImranBilalButt | 0:5f745af3ec9b | 43 | close(); |
ImranBilalButt | 0:5f745af3ec9b | 44 | } |
ImranBilalButt | 0:5f745af3ec9b | 45 | } |
ImranBilalButt | 0:5f745af3ec9b | 46 | |
ImranBilalButt | 0:5f745af3ec9b | 47 | void TLSSocketWrapper::set_hostname(const char *hostname) |
ImranBilalButt | 0:5f745af3ec9b | 48 | { |
ImranBilalButt | 0:5f745af3ec9b | 49 | if (is_tls_allocated()) { |
ImranBilalButt | 1:a6995e66c9f7 | 50 | pc.printf("ssl hostname is set\n"); |
ImranBilalButt | 0:5f745af3ec9b | 51 | mbedtls_ssl_set_hostname(_ssl, hostname); |
ImranBilalButt | 0:5f745af3ec9b | 52 | } |
ImranBilalButt | 0:5f745af3ec9b | 53 | } |
ImranBilalButt | 0:5f745af3ec9b | 54 | |
ImranBilalButt | 0:5f745af3ec9b | 55 | void TLSSocketWrapper::keep_transport_open() |
ImranBilalButt | 0:5f745af3ec9b | 56 | { |
ImranBilalButt | 0:5f745af3ec9b | 57 | _keep_transport_open = true; |
ImranBilalButt | 0:5f745af3ec9b | 58 | } |
ImranBilalButt | 0:5f745af3ec9b | 59 | |
ImranBilalButt | 0:5f745af3ec9b | 60 | nsapi_error_t TLSSocketWrapper::set_root_ca_cert(const void *root_ca, size_t len) |
ImranBilalButt | 0:5f745af3ec9b | 61 | { |
ImranBilalButt | 0:5f745af3ec9b | 62 | if (!is_tls_allocated()) { |
ImranBilalButt | 0:5f745af3ec9b | 63 | return NSAPI_ERROR_NO_SOCKET; |
ImranBilalButt | 0:5f745af3ec9b | 64 | } |
ImranBilalButt | 0:5f745af3ec9b | 65 | /* Parse CA certification */ |
ImranBilalButt | 0:5f745af3ec9b | 66 | int ret; |
ImranBilalButt | 0:5f745af3ec9b | 67 | if ((ret = mbedtls_x509_crt_parse(_cacert, static_cast<const unsigned char *>(root_ca), |
ImranBilalButt | 0:5f745af3ec9b | 68 | len)) != 0) { |
ImranBilalButt | 0:5f745af3ec9b | 69 | print_mbedtls_error("mbedtls_x509_crt_parse", ret); |
ImranBilalButt | 0:5f745af3ec9b | 70 | return NSAPI_ERROR_PARAMETER; |
ImranBilalButt | 0:5f745af3ec9b | 71 | } |
ImranBilalButt | 1:a6995e66c9f7 | 72 | pc.printf("Root CA Certificate Setting ... OK\n"); |
ImranBilalButt | 0:5f745af3ec9b | 73 | return NSAPI_ERROR_OK; |
ImranBilalButt | 0:5f745af3ec9b | 74 | |
ImranBilalButt | 0:5f745af3ec9b | 75 | } |
ImranBilalButt | 0:5f745af3ec9b | 76 | nsapi_error_t TLSSocketWrapper::set_root_ca_cert(const char *root_ca_pem) |
ImranBilalButt | 0:5f745af3ec9b | 77 | { |
ImranBilalButt | 0:5f745af3ec9b | 78 | return set_root_ca_cert(root_ca_pem, strlen(root_ca_pem) + 1); |
ImranBilalButt | 0:5f745af3ec9b | 79 | } |
ImranBilalButt | 0:5f745af3ec9b | 80 | |
ImranBilalButt | 0:5f745af3ec9b | 81 | nsapi_error_t TLSSocketWrapper::set_client_cert_key(const char *client_cert_pem, const char *client_private_key_pem) |
ImranBilalButt | 0:5f745af3ec9b | 82 | { |
ImranBilalButt | 0:5f745af3ec9b | 83 | return set_client_cert_key(client_cert_pem, strlen(client_cert_pem) + 1, client_private_key_pem, strlen(client_private_key_pem) + 1); |
ImranBilalButt | 0:5f745af3ec9b | 84 | } |
ImranBilalButt | 0:5f745af3ec9b | 85 | |
ImranBilalButt | 0:5f745af3ec9b | 86 | nsapi_error_t TLSSocketWrapper::set_client_cert_key(const void *client_cert, size_t client_cert_len, |
ImranBilalButt | 0:5f745af3ec9b | 87 | const void *client_private_key_pem, size_t client_private_key_len) |
ImranBilalButt | 0:5f745af3ec9b | 88 | { |
ImranBilalButt | 0:5f745af3ec9b | 89 | if (!is_tls_allocated()) { |
ImranBilalButt | 0:5f745af3ec9b | 90 | return NSAPI_ERROR_NO_SOCKET; |
ImranBilalButt | 0:5f745af3ec9b | 91 | } |
ImranBilalButt | 0:5f745af3ec9b | 92 | int ret; |
ImranBilalButt | 0:5f745af3ec9b | 93 | |
ImranBilalButt | 0:5f745af3ec9b | 94 | if((NULL != client_cert) && (NULL != client_private_key_pem)) { |
ImranBilalButt | 0:5f745af3ec9b | 95 | mbedtls_x509_crt_init(_clicert); |
ImranBilalButt | 0:5f745af3ec9b | 96 | if((ret = mbedtls_x509_crt_parse(_clicert, static_cast<const unsigned char *>(client_cert), |
ImranBilalButt | 0:5f745af3ec9b | 97 | client_cert_len)) != 0) { |
ImranBilalButt | 0:5f745af3ec9b | 98 | print_mbedtls_error("mbedtls_x509_crt_parse", ret); |
ImranBilalButt | 0:5f745af3ec9b | 99 | return NSAPI_ERROR_PARAMETER; |
ImranBilalButt | 0:5f745af3ec9b | 100 | } |
ImranBilalButt | 1:a6995e66c9f7 | 101 | pc.printf("Client Certificate Setting ... ok\n"); |
ImranBilalButt | 0:5f745af3ec9b | 102 | mbedtls_pk_init(_pkctx); |
ImranBilalButt | 0:5f745af3ec9b | 103 | if((ret = mbedtls_pk_parse_key(_pkctx, static_cast<const unsigned char *>(client_private_key_pem), |
ImranBilalButt | 0:5f745af3ec9b | 104 | client_private_key_len, NULL, 0)) != 0) { |
ImranBilalButt | 0:5f745af3ec9b | 105 | print_mbedtls_error("mbedtls_pk_parse_key", ret); |
ImranBilalButt | 0:5f745af3ec9b | 106 | return NSAPI_ERROR_PARAMETER; |
ImranBilalButt | 0:5f745af3ec9b | 107 | } |
ImranBilalButt | 1:a6995e66c9f7 | 108 | pc.printf("Client pvt. Key Setting ... ok\n"); |
ImranBilalButt | 0:5f745af3ec9b | 109 | _client_auth = true; |
ImranBilalButt | 0:5f745af3ec9b | 110 | } |
ImranBilalButt | 0:5f745af3ec9b | 111 | return NSAPI_ERROR_OK; |
ImranBilalButt | 0:5f745af3ec9b | 112 | } |
ImranBilalButt | 0:5f745af3ec9b | 113 | |
ImranBilalButt | 0:5f745af3ec9b | 114 | /* The supported CERT ciphersuites are as follows: |
ImranBilalButt | 0:5f745af3ec9b | 115 | CipherSuite TLS_RSA_WITH_AES_128_CCM = {0xC0,0x9C} |
ImranBilalButt | 0:5f745af3ec9b | 116 | CipherSuite TLS_RSA_WITH_AES_256_CCM = {0xC0,0x9D) |
ImranBilalButt | 0:5f745af3ec9b | 117 | CipherSuite TLS_DHE_RSA_WITH_AES_128_CCM = {0xC0,0x9E} |
ImranBilalButt | 0:5f745af3ec9b | 118 | CipherSuite TLS_DHE_RSA_WITH_AES_256_CCM = {0xC0,0x9F} |
ImranBilalButt | 0:5f745af3ec9b | 119 | CipherSuite TLS_RSA_WITH_AES_128_CCM_8 = {0xC0,0xA0} |
ImranBilalButt | 0:5f745af3ec9b | 120 | CipherSuite TLS_RSA_WITH_AES_256_CCM_8 = {0xC0,0xA1) |
ImranBilalButt | 0:5f745af3ec9b | 121 | CipherSuite TLS_DHE_RSA_WITH_AES_128_CCM_8 = {0xC0,0xA2} |
ImranBilalButt | 0:5f745af3ec9b | 122 | CipherSuite TLS_DHE_RSA_WITH_AES_256_CCM_8 = {0xC0,0xA3} |
ImranBilalButt | 0:5f745af3ec9b | 123 | // The supported PSK ciphersuites are as follows: |
ImranBilalButt | 0:5f745af3ec9b | 124 | CipherSuite TLS_PSK_WITH_AES_128_CCM = {0xC0,0xA4} |
ImranBilalButt | 0:5f745af3ec9b | 125 | CipherSuite TLS_PSK_WITH_AES_256_CCM = {0xC0,0xA5) |
ImranBilalButt | 0:5f745af3ec9b | 126 | CipherSuite TLS_DHE_PSK_WITH_AES_128_CCM = {0xC0,0xA6} |
ImranBilalButt | 0:5f745af3ec9b | 127 | CipherSuite TLS_DHE_PSK_WITH_AES_256_CCM = {0xC0,0xA7} |
ImranBilalButt | 0:5f745af3ec9b | 128 | CipherSuite TLS_PSK_WITH_AES_128_CCM_8 = {0xC0,0xA8} |
ImranBilalButt | 0:5f745af3ec9b | 129 | CipherSuite TLS_PSK_WITH_AES_256_CCM_8 = {0xC0,0xA9) |
ImranBilalButt | 0:5f745af3ec9b | 130 | CipherSuite TLS_PSK_DHE_WITH_AES_128_CCM_8 = {0xC0,0xAA} |
ImranBilalButt | 0:5f745af3ec9b | 131 | CipherSuite TLS_PSK_DHE_WITH_AES_256_CCM_8 = {0xC0,0xAB} |
ImranBilalButt | 0:5f745af3ec9b | 132 | // The supported PSK Cipher is (TLS) |
ImranBilalButt | 0:5f745af3ec9b | 133 | TLS_PSK_WITH_RC4_128_SHA = { 0x00, 0x8A }; |
ImranBilalButt | 0:5f745af3ec9b | 134 | TLS_PSK_WITH_3DES_EDE_CBC_SHA = { 0x00, 0x8B }; |
ImranBilalButt | 0:5f745af3ec9b | 135 | TLS_PSK_WITH_AES_128_CBC_SHA = { 0x00, 0x8C }; |
ImranBilalButt | 1:a6995e66c9f7 | 136 | TLS_PSK_WITH_AES_256_CBC_SHA = { 0x00, 0x8D }; */ |
ImranBilalButt | 1:a6995e66c9f7 | 137 | |
ImranBilalButt | 1:a6995e66c9f7 | 138 | int TLSSocketWrapper::set_client1_kpsa_kpsaID_cipher(){ |
ImranBilalButt | 1:a6995e66c9f7 | 139 | const unsigned char _kpsa[5] = { 0x01, 0x02, 0x03, 0x04, 0x05 }; |
ImranBilalButt | 1:a6995e66c9f7 | 140 | const unsigned char *_kpsaID = "AE123-LOCK@in.provider.com"; // 15 Bytes PSK-ID |
ImranBilalButt | 0:5f745af3ec9b | 141 | |
ImranBilalButt | 0:5f745af3ec9b | 142 | int kpsa_len = strlen((const char*) _kpsa); |
ImranBilalButt | 0:5f745af3ec9b | 143 | int kpsaID_len = strlen((const char*) _kpsaID); |
ImranBilalButt | 0:5f745af3ec9b | 144 | int ret; |
ImranBilalButt | 1:a6995e66c9f7 | 145 | |
ImranBilalButt | 0:5f745af3ec9b | 146 | mbedtls_ssl_set_hs_psk(_ssl, _kpsa, kpsa_len); |
ImranBilalButt | 0:5f745af3ec9b | 147 | if( (ret = mbedtls_ssl_conf_psk(_ssl_conf, _kpsa, kpsa_len , _kpsaID, kpsaID_len)) != 0){ |
ImranBilalButt | 0:5f745af3ec9b | 148 | print_mbedtls_error("mbedtls_psk_error", ret); |
ImranBilalButt | 0:5f745af3ec9b | 149 | // return NSAPI_ERROR_PARAMETER; |
ImranBilalButt | 0:5f745af3ec9b | 150 | return -1; |
ImranBilalButt | 0:5f745af3ec9b | 151 | } |
ImranBilalButt | 1:a6995e66c9f7 | 152 | pc.printf("Ok.\n"); |
ImranBilalButt | 1:a6995e66c9f7 | 153 | return 0; |
ImranBilalButt | 1:a6995e66c9f7 | 154 | } |
ImranBilalButt | 1:a6995e66c9f7 | 155 | |
ImranBilalButt | 1:a6995e66c9f7 | 156 | int TLSSocketWrapper::set_client2_kpsa_kpsaID_cipher(){ |
ImranBilalButt | 1:a6995e66c9f7 | 157 | const unsigned char _kpsa[5] = { 0x05, 0x04, 0x03, 0x02, 0x01 }; |
ImranBilalButt | 1:a6995e66c9f7 | 158 | const unsigned char *_kpsaID = "AE456-LOCK@in.provider.com"; // 15 Bytes PSK-ID |
ImranBilalButt | 1:a6995e66c9f7 | 159 | |
ImranBilalButt | 1:a6995e66c9f7 | 160 | int kpsa_len = strlen((const char*) _kpsa); |
ImranBilalButt | 1:a6995e66c9f7 | 161 | int kpsaID_len = strlen((const char*) _kpsaID); |
ImranBilalButt | 1:a6995e66c9f7 | 162 | int ret; |
ImranBilalButt | 1:a6995e66c9f7 | 163 | |
ImranBilalButt | 1:a6995e66c9f7 | 164 | mbedtls_ssl_set_hs_psk(_ssl, _kpsa, kpsa_len); |
ImranBilalButt | 1:a6995e66c9f7 | 165 | if( (ret = mbedtls_ssl_conf_psk(_ssl_conf, _kpsa, kpsa_len , _kpsaID, kpsaID_len)) != 0){ |
ImranBilalButt | 1:a6995e66c9f7 | 166 | print_mbedtls_error("mbedtls_psk_error", ret); |
ImranBilalButt | 1:a6995e66c9f7 | 167 | // return NSAPI_ERROR_PARAMETER; |
ImranBilalButt | 1:a6995e66c9f7 | 168 | return -1; |
ImranBilalButt | 1:a6995e66c9f7 | 169 | } |
ImranBilalButt | 1:a6995e66c9f7 | 170 | pc.printf("Ok.\n"); |
ImranBilalButt | 0:5f745af3ec9b | 171 | return 0; |
ImranBilalButt | 0:5f745af3ec9b | 172 | } |
ImranBilalButt | 0:5f745af3ec9b | 173 | |
ImranBilalButt | 0:5f745af3ec9b | 174 | nsapi_error_t TLSSocketWrapper::do_handshake() { |
ImranBilalButt | 0:5f745af3ec9b | 175 | nsapi_error_t _error; |
ImranBilalButt | 0:5f745af3ec9b | 176 | const char DRBG_PERS[] = "mbed TLS client"; |
ImranBilalButt | 0:5f745af3ec9b | 177 | |
ImranBilalButt | 0:5f745af3ec9b | 178 | const int *cipherArray; |
ImranBilalButt | 0:5f745af3ec9b | 179 | cipherArray = mbedtls_ssl_list_ciphersuites(); |
ImranBilalButt | 1:a6995e66c9f7 | 180 | pc.printf("[+] The allowed ciphersuites are: \n"); |
ImranBilalButt | 0:5f745af3ec9b | 181 | int i = 0; |
ImranBilalButt | 0:5f745af3ec9b | 182 | while (cipherArray[i] != 0) { |
ImranBilalButt | 1:a6995e66c9f7 | 183 | pc.printf("[.] cipherArray[%d] = %d\n", i, cipherArray[i]); |
ImranBilalButt | 0:5f745af3ec9b | 184 | i++; |
ImranBilalButt | 0:5f745af3ec9b | 185 | } |
ImranBilalButt | 0:5f745af3ec9b | 186 | |
ImranBilalButt | 0:5f745af3ec9b | 187 | if (!_transport) { |
ImranBilalButt | 1:a6995e66c9f7 | 188 | pc.printf("[-] transport/socket not available\n"); |
ImranBilalButt | 0:5f745af3ec9b | 189 | return NSAPI_ERROR_NO_SOCKET; |
ImranBilalButt | 0:5f745af3ec9b | 190 | } |
ImranBilalButt | 0:5f745af3ec9b | 191 | if (!is_tls_allocated()) { |
ImranBilalButt | 1:a6995e66c9f7 | 192 | pc.printf("[-] no tls allocated\n"); |
ImranBilalButt | 0:5f745af3ec9b | 193 | return NSAPI_ERROR_NO_SOCKET; |
ImranBilalButt | 0:5f745af3ec9b | 194 | } |
ImranBilalButt | 0:5f745af3ec9b | 195 | |
ImranBilalButt | 0:5f745af3ec9b | 196 | _transport->set_blocking(false); |
ImranBilalButt | 0:5f745af3ec9b | 197 | /* |
ImranBilalButt | 0:5f745af3ec9b | 198 | * Initialize TLS-related stuf. |
ImranBilalButt | 0:5f745af3ec9b | 199 | */ |
ImranBilalButt | 0:5f745af3ec9b | 200 | int ret; |
ImranBilalButt | 0:5f745af3ec9b | 201 | if ((ret = mbedtls_ctr_drbg_seed(_ctr_drbg, mbedtls_entropy_func, _entropy, |
ImranBilalButt | 0:5f745af3ec9b | 202 | (const unsigned char *) DRBG_PERS, |
ImranBilalButt | 0:5f745af3ec9b | 203 | sizeof (DRBG_PERS))) != 0) { |
ImranBilalButt | 0:5f745af3ec9b | 204 | print_mbedtls_error("mbedtls_crt_drbg_init", ret); |
ImranBilalButt | 0:5f745af3ec9b | 205 | _error = ret; |
ImranBilalButt | 0:5f745af3ec9b | 206 | return _error; |
ImranBilalButt | 0:5f745af3ec9b | 207 | } |
ImranBilalButt | 0:5f745af3ec9b | 208 | |
ImranBilalButt | 1:a6995e66c9f7 | 209 | pc.printf("[+] Configuring a dtls-client session initiation ... "); |
ImranBilalButt | 0:5f745af3ec9b | 210 | mbedtls_ssl_conf_endpoint(_ssl_conf, MBEDTLS_SSL_IS_CLIENT); |
ImranBilalButt | 0:5f745af3ec9b | 211 | mbedtls_ssl_conf_transport(_ssl_conf, MBEDTLS_SSL_TRANSPORT_DATAGRAM); |
ImranBilalButt | 0:5f745af3ec9b | 212 | |
ImranBilalButt | 0:5f745af3ec9b | 213 | tr_info("mbedtls_ssl_config_defaults()"); |
ImranBilalButt | 0:5f745af3ec9b | 214 | if ((ret = mbedtls_ssl_config_defaults(_ssl_conf, |
ImranBilalButt | 0:5f745af3ec9b | 215 | MBEDTLS_SSL_IS_CLIENT, |
ImranBilalButt | 0:5f745af3ec9b | 216 | MBEDTLS_SSL_TRANSPORT_DATAGRAM, |
ImranBilalButt | 0:5f745af3ec9b | 217 | MBEDTLS_SSL_PRESET_DEFAULT)) != 0) { |
ImranBilalButt | 0:5f745af3ec9b | 218 | print_mbedtls_error("mbedtls_ssl_config_defaults", ret); |
ImranBilalButt | 0:5f745af3ec9b | 219 | _error = ret; |
ImranBilalButt | 0:5f745af3ec9b | 220 | return _error; |
ImranBilalButt | 0:5f745af3ec9b | 221 | } |
ImranBilalButt | 0:5f745af3ec9b | 222 | tr_info("mbedtls_ssl_conf_ca_chain()"); |
ImranBilalButt | 0:5f745af3ec9b | 223 | mbedtls_ssl_conf_ca_chain(_ssl_conf, _cacert, NULL); |
ImranBilalButt | 0:5f745af3ec9b | 224 | tr_info("mbedtls_ssl_conf_rng()"); |
ImranBilalButt | 0:5f745af3ec9b | 225 | mbedtls_ssl_conf_rng(_ssl_conf, mbedtls_ctr_drbg_random, _ctr_drbg); |
ImranBilalButt | 1:a6995e66c9f7 | 226 | pc.printf("ok\n"); |
ImranBilalButt | 0:5f745af3ec9b | 227 | |
ImranBilalButt | 0:5f745af3ec9b | 228 | /* It is possible to disable authentication by passing |
ImranBilalButt | 0:5f745af3ec9b | 229 | MBEDTLS_SSL_VERIFY_NONE in the call to mbedtls_ssl_conf_authmode() |
ImranBilalButt | 0:5f745af3ec9b | 230 | */ |
ImranBilalButt | 1:a6995e66c9f7 | 231 | pc.printf("[+] Configuring the Session Information ... "); |
ImranBilalButt | 0:5f745af3ec9b | 232 | tr_info("mbedtls_ssl_conf_authmode()"); |
ImranBilalButt | 0:5f745af3ec9b | 233 | mbedtls_ssl_conf_authmode(_ssl_conf, MBEDTLS_SSL_VERIFY_NONE); |
ImranBilalButt | 0:5f745af3ec9b | 234 | |
ImranBilalButt | 0:5f745af3ec9b | 235 | mbedtls_ssl_conf_verify(_ssl_conf, my_verify, NULL); |
ImranBilalButt | 0:5f745af3ec9b | 236 | mbedtls_ssl_conf_dbg(_ssl_conf, my_debug, NULL); |
ImranBilalButt | 0:5f745af3ec9b | 237 | mbedtls_debug_set_threshold(3); |
ImranBilalButt | 0:5f745af3ec9b | 238 | |
ImranBilalButt | 0:5f745af3ec9b | 239 | /* configure the timers for retransmission of lost handshake messages |
ImranBilalButt | 0:5f745af3ec9b | 240 | 1,000 milli-sec minimum time to 6,000 milli-sec maximum delay */ |
ImranBilalButt | 0:5f745af3ec9b | 241 | mbedtls_ssl_conf_handshake_timeout(_ssl_conf, 1000, 6000); |
ImranBilalButt | 0:5f745af3ec9b | 242 | |
ImranBilalButt | 0:5f745af3ec9b | 243 | /* Anti-Replay Protection */ |
ImranBilalButt | 0:5f745af3ec9b | 244 | mbedtls_ssl_conf_dtls_anti_replay(_ssl_conf, MBEDTLS_SSL_ANTI_REPLAY_ENABLED); |
ImranBilalButt | 0:5f745af3ec9b | 245 | |
ImranBilalButt | 0:5f745af3ec9b | 246 | /* Bad Mac Limit for 10 Packets */ |
ImranBilalButt | 0:5f745af3ec9b | 247 | mbedtls_ssl_conf_dtls_badmac_limit(_ssl_conf, 10); |
ImranBilalButt | 0:5f745af3ec9b | 248 | |
ImranBilalButt | 0:5f745af3ec9b | 249 | /* Set the limit for the Maximum Transmission Unit for DTLS Payload |
ImranBilalButt | 0:5f745af3ec9b | 250 | {1500 Bits Set} */ |
ImranBilalButt | 0:5f745af3ec9b | 251 | mbedtls_ssl_set_mtu( _ssl , 1500 ); |
ImranBilalButt | 0:5f745af3ec9b | 252 | |
ImranBilalButt | 0:5f745af3ec9b | 253 | tr_info("mbedtls_ssl_setup()"); |
ImranBilalButt | 0:5f745af3ec9b | 254 | if ((ret = mbedtls_ssl_setup(_ssl, _ssl_conf)) != 0) { |
ImranBilalButt | 0:5f745af3ec9b | 255 | print_mbedtls_error("mbedtls_ssl_setup", ret); |
ImranBilalButt | 0:5f745af3ec9b | 256 | _error = ret; |
ImranBilalButt | 0:5f745af3ec9b | 257 | return _error; |
ImranBilalButt | 0:5f745af3ec9b | 258 | } |
ImranBilalButt | 1:a6995e66c9f7 | 259 | pc.printf("ok\n"); |
ImranBilalButt | 0:5f745af3ec9b | 260 | |
ImranBilalButt | 1:a6995e66c9f7 | 261 | pc.printf("[+] Configuring the Bio ... "); |
ImranBilalButt | 0:5f745af3ec9b | 262 | mbedtls_ssl_set_bio(_ssl, this, ssl_send, ssl_recv, NULL ); |
ImranBilalButt | 1:a6995e66c9f7 | 263 | pc.printf("ok\n"); |
ImranBilalButt | 0:5f745af3ec9b | 264 | |
ImranBilalButt | 0:5f745af3ec9b | 265 | if(_client_auth) { |
ImranBilalButt | 1:a6995e66c9f7 | 266 | pc.printf("[+] Configuring Client's pvtKey & certKey ... "); |
ImranBilalButt | 0:5f745af3ec9b | 267 | if((ret = mbedtls_ssl_conf_own_cert(_ssl_conf, _clicert, _pkctx)) != 0) { |
ImranBilalButt | 0:5f745af3ec9b | 268 | print_mbedtls_error("mbedtls_ssl_conf_own_cert", ret); |
ImranBilalButt | 0:5f745af3ec9b | 269 | _error = ret; |
ImranBilalButt | 0:5f745af3ec9b | 270 | return _error; |
ImranBilalButt | 0:5f745af3ec9b | 271 | } |
ImranBilalButt | 1:a6995e66c9f7 | 272 | pc.printf("ok\n"); |
ImranBilalButt | 0:5f745af3ec9b | 273 | } |
ImranBilalButt | 0:5f745af3ec9b | 274 | |
ImranBilalButt | 1:a6995e66c9f7 | 275 | pc.printf("[+] Timing Call-Back Setting ... "); |
ImranBilalButt | 0:5f745af3ec9b | 276 | mbedtls_ssl_set_timer_cb(_ssl, _ssl_timer, mbedtls_timing_set_delay, mbedtls_timing_get_delay); |
ImranBilalButt | 1:a6995e66c9f7 | 277 | pc.printf("ok\n"); |
ImranBilalButt | 0:5f745af3ec9b | 278 | |
ImranBilalButt | 0:5f745af3ec9b | 279 | /* Start the handshake, the rest will be done in onReceive() */ |
ImranBilalButt | 0:5f745af3ec9b | 280 | //uint32_t init, final, TCPH, TTPH; |
ImranBilalButt | 1:a6995e66c9f7 | 281 | pc.printf("[+] DTLS Handshake Connecting \n"); |
ImranBilalButt | 0:5f745af3ec9b | 282 | //init = osKernelGetTickCount(); |
ImranBilalButt | 0:5f745af3ec9b | 283 | if ((ret = mbedtls_ssl_handshake(_ssl)) != 0) { |
ImranBilalButt | 1:a6995e66c9f7 | 284 | pc.printf("[-] mbedtls_ssl_handshake error %d\n", ret); |
ImranBilalButt | 0:5f745af3ec9b | 285 | return ret; |
ImranBilalButt | 0:5f745af3ec9b | 286 | } |
ImranBilalButt | 0:5f745af3ec9b | 287 | else { |
ImranBilalButt | 0:5f745af3ec9b | 288 | //final = osKernelGetTickCount(); |
ImranBilalButt | 1:a6995e66c9f7 | 289 | pc.printf("[+] DTLS Hanshake Connected \n"); |
ImranBilalButt | 0:5f745af3ec9b | 290 | } |
ImranBilalButt | 0:5f745af3ec9b | 291 | |
ImranBilalButt | 0:5f745af3ec9b | 292 | //TCPH = final - init; |
ImranBilalButt | 0:5f745af3ec9b | 293 | //TTPH = TCPH/osKernelGetTickFreq(); |
ImranBilalButt | 0:5f745af3ec9b | 294 | |
ImranBilalButt | 1:a6995e66c9f7 | 295 | //pc.printf("\nTCPH: %d\n", TCPH); |
ImranBilalButt | 1:a6995e66c9f7 | 296 | //pc.printf("\nTTPH: %d\n", TTPH); |
ImranBilalButt | 1:a6995e66c9f7 | 297 | //pc.printf("\nTickFreq: %d\n", osKernelGetTickFreq()); |
ImranBilalButt | 0:5f745af3ec9b | 298 | |
ImranBilalButt | 0:5f745af3ec9b | 299 | /* It also means the handshake is done, time to print info */ |
ImranBilalButt | 0:5f745af3ec9b | 300 | tr_info("[+] TLS connection to %s established\r\n", _ssl->hostname); |
ImranBilalButt | 0:5f745af3ec9b | 301 | // Prints the server certificate and verify it. |
ImranBilalButt | 0:5f745af3ec9b | 302 | |
ImranBilalButt | 0:5f745af3ec9b | 303 | const size_t buf_size = 1024; |
ImranBilalButt | 0:5f745af3ec9b | 304 | char* buf = new char[buf_size]; |
ImranBilalButt | 0:5f745af3ec9b | 305 | mbedtls_x509_crt_info(buf, buf_size, "\r ", mbedtls_ssl_get_peer_cert(_ssl)); |
ImranBilalButt | 0:5f745af3ec9b | 306 | tr_debug("[+] Server certificate:\r\n%s\r\n", buf); |
ImranBilalButt | 0:5f745af3ec9b | 307 | |
ImranBilalButt | 0:5f745af3ec9b | 308 | uint32_t flags = mbedtls_ssl_get_verify_result(_ssl); |
ImranBilalButt | 0:5f745af3ec9b | 309 | if( flags != 0 ) { |
ImranBilalButt | 0:5f745af3ec9b | 310 | // Verification failed. |
ImranBilalButt | 0:5f745af3ec9b | 311 | mbedtls_x509_crt_verify_info(buf, buf_size, "\r ! ", flags); |
ImranBilalButt | 0:5f745af3ec9b | 312 | tr_error("[+] Certificate verification failed:\r\n%s", buf); |
ImranBilalButt | 0:5f745af3ec9b | 313 | } else { |
ImranBilalButt | 0:5f745af3ec9b | 314 | // Verification succeeded. |
ImranBilalButt | 0:5f745af3ec9b | 315 | tr_info("[+] Certificate verification passed"); |
ImranBilalButt | 0:5f745af3ec9b | 316 | } |
ImranBilalButt | 0:5f745af3ec9b | 317 | delete[] buf; |
ImranBilalButt | 0:5f745af3ec9b | 318 | _handshake_completed = true; |
ImranBilalButt | 0:5f745af3ec9b | 319 | |
ImranBilalButt | 0:5f745af3ec9b | 320 | return 0; |
ImranBilalButt | 0:5f745af3ec9b | 321 | } |
ImranBilalButt | 0:5f745af3ec9b | 322 | |
ImranBilalButt | 0:5f745af3ec9b | 323 | nsapi_error_t TLSSocketWrapper::send(const void *data, nsapi_size_t size) { |
ImranBilalButt | 0:5f745af3ec9b | 324 | int ret; |
ImranBilalButt | 0:5f745af3ec9b | 325 | |
ImranBilalButt | 0:5f745af3ec9b | 326 | if (!is_tls_allocated()) { |
ImranBilalButt | 0:5f745af3ec9b | 327 | return NSAPI_ERROR_NO_SOCKET; |
ImranBilalButt | 0:5f745af3ec9b | 328 | } |
ImranBilalButt | 0:5f745af3ec9b | 329 | |
ImranBilalButt | 0:5f745af3ec9b | 330 | tr_debug("send %d", size); |
ImranBilalButt | 0:5f745af3ec9b | 331 | //uint32_t init, final, TCPH, TTPH; |
ImranBilalButt | 0:5f745af3ec9b | 332 | //init = osKernelGetTickCount(); |
ImranBilalButt | 0:5f745af3ec9b | 333 | ret = mbedtls_ssl_write(_ssl, (const unsigned char *) data, size); |
ImranBilalButt | 0:5f745af3ec9b | 334 | //final = osKernelGetTickCount(); |
ImranBilalButt | 0:5f745af3ec9b | 335 | |
ImranBilalButt | 0:5f745af3ec9b | 336 | /*TCPH = final - init; |
ImranBilalButt | 0:5f745af3ec9b | 337 | TTPH = TCPH/osKernelGetTickFreq(); |
ImranBilalButt | 0:5f745af3ec9b | 338 | |
ImranBilalButt | 1:a6995e66c9f7 | 339 | pc.printf("\nTCPH: %d\n", TCPH); |
ImranBilalButt | 1:a6995e66c9f7 | 340 | pc.printf("\nTTPH: %d\n", TTPH); |
ImranBilalButt | 1:a6995e66c9f7 | 341 | pc.printf("\nTickFreq: %d\n", osKernelGetTickFreq()); */ |
ImranBilalButt | 0:5f745af3ec9b | 342 | |
ImranBilalButt | 0:5f745af3ec9b | 343 | if (ret == MBEDTLS_ERR_SSL_WANT_WRITE || |
ImranBilalButt | 0:5f745af3ec9b | 344 | ret == MBEDTLS_ERR_SSL_WANT_READ) { |
ImranBilalButt | 0:5f745af3ec9b | 345 | // translate to socket error |
ImranBilalButt | 0:5f745af3ec9b | 346 | return NSAPI_ERROR_WOULD_BLOCK; |
ImranBilalButt | 0:5f745af3ec9b | 347 | } |
ImranBilalButt | 0:5f745af3ec9b | 348 | if (ret < 0) { |
ImranBilalButt | 0:5f745af3ec9b | 349 | print_mbedtls_error("mbedtls_ssl_write", ret); |
ImranBilalButt | 0:5f745af3ec9b | 350 | } |
ImranBilalButt | 0:5f745af3ec9b | 351 | return ret; // Assume "non negative errorcode" to be propagated from Socket layer |
ImranBilalButt | 0:5f745af3ec9b | 352 | } |
ImranBilalButt | 0:5f745af3ec9b | 353 | |
ImranBilalButt | 0:5f745af3ec9b | 354 | nsapi_size_or_error_t TLSSocketWrapper::sendto(const SocketAddress &, const void *data, nsapi_size_t size) |
ImranBilalButt | 0:5f745af3ec9b | 355 | { |
ImranBilalButt | 0:5f745af3ec9b | 356 | // Ignore the SocketAddress |
ImranBilalButt | 0:5f745af3ec9b | 357 | return send(data, size); |
ImranBilalButt | 0:5f745af3ec9b | 358 | } |
ImranBilalButt | 0:5f745af3ec9b | 359 | |
ImranBilalButt | 0:5f745af3ec9b | 360 | nsapi_size_or_error_t TLSSocketWrapper::recv(void *data, nsapi_size_t size) { |
ImranBilalButt | 0:5f745af3ec9b | 361 | int ret; |
ImranBilalButt | 0:5f745af3ec9b | 362 | |
ImranBilalButt | 0:5f745af3ec9b | 363 | if (!is_tls_allocated()) { |
ImranBilalButt | 0:5f745af3ec9b | 364 | return NSAPI_ERROR_NO_SOCKET; |
ImranBilalButt | 0:5f745af3ec9b | 365 | } |
ImranBilalButt | 0:5f745af3ec9b | 366 | |
ImranBilalButt | 0:5f745af3ec9b | 367 | ret = mbedtls_ssl_read(_ssl, (unsigned char *) data, size); |
ImranBilalButt | 0:5f745af3ec9b | 368 | |
ImranBilalButt | 0:5f745af3ec9b | 369 | if (ret == MBEDTLS_ERR_SSL_WANT_WRITE || |
ImranBilalButt | 0:5f745af3ec9b | 370 | ret == MBEDTLS_ERR_SSL_WANT_READ) { |
ImranBilalButt | 0:5f745af3ec9b | 371 | // translate to socket error |
ImranBilalButt | 0:5f745af3ec9b | 372 | return NSAPI_ERROR_WOULD_BLOCK; |
ImranBilalButt | 0:5f745af3ec9b | 373 | } else if (ret == MBEDTLS_ERR_SSL_PEER_CLOSE_NOTIFY) { |
ImranBilalButt | 0:5f745af3ec9b | 374 | /* MBEDTLS_ERR_SSL_PEER_CLOSE_NOTIFY is not considered as error. |
ImranBilalButt | 0:5f745af3ec9b | 375 | * Just ignre here. Once connection is closed, mbedtls_ssl_read() |
ImranBilalButt | 0:5f745af3ec9b | 376 | * will return 0. |
ImranBilalButt | 0:5f745af3ec9b | 377 | */ |
ImranBilalButt | 0:5f745af3ec9b | 378 | return 0; |
ImranBilalButt | 0:5f745af3ec9b | 379 | } else if (ret < 0) { |
ImranBilalButt | 0:5f745af3ec9b | 380 | print_mbedtls_error("mbedtls_ssl_read", ret); |
ImranBilalButt | 0:5f745af3ec9b | 381 | // TODO: Should I translate SSL errors to some socket error? |
ImranBilalButt | 0:5f745af3ec9b | 382 | } |
ImranBilalButt | 0:5f745af3ec9b | 383 | return ret; |
ImranBilalButt | 0:5f745af3ec9b | 384 | } |
ImranBilalButt | 0:5f745af3ec9b | 385 | |
ImranBilalButt | 0:5f745af3ec9b | 386 | nsapi_size_or_error_t TLSSocketWrapper::recvfrom(SocketAddress *address, void *data, nsapi_size_t size) |
ImranBilalButt | 0:5f745af3ec9b | 387 | { |
ImranBilalButt | 0:5f745af3ec9b | 388 | //TODO: Need Socket::getpeername() to get address |
ImranBilalButt | 0:5f745af3ec9b | 389 | return recv(data, size); |
ImranBilalButt | 0:5f745af3ec9b | 390 | } |
ImranBilalButt | 0:5f745af3ec9b | 391 | |
ImranBilalButt | 0:5f745af3ec9b | 392 | void TLSSocketWrapper::print_mbedtls_error(const char *name, int err) { |
ImranBilalButt | 0:5f745af3ec9b | 393 | char *buf = new char[128]; |
ImranBilalButt | 0:5f745af3ec9b | 394 | mbedtls_strerror(err, buf, 128); |
ImranBilalButt | 0:5f745af3ec9b | 395 | tr_err("%s() failed: -0x%04x (%d): %s", name, -err, err, buf); |
ImranBilalButt | 0:5f745af3ec9b | 396 | delete[] buf; |
ImranBilalButt | 0:5f745af3ec9b | 397 | } |
ImranBilalButt | 0:5f745af3ec9b | 398 | |
ImranBilalButt | 0:5f745af3ec9b | 399 | |
ImranBilalButt | 0:5f745af3ec9b | 400 | #if MBED_CONF_TLS_SOCKET_DEBUG_LEVEL > 0 |
ImranBilalButt | 0:5f745af3ec9b | 401 | |
ImranBilalButt | 0:5f745af3ec9b | 402 | void TLSSocketWrapper::my_debug(void *ctx, int level, const char *file, int line, |
ImranBilalButt | 0:5f745af3ec9b | 403 | const char *str) |
ImranBilalButt | 0:5f745af3ec9b | 404 | { |
ImranBilalButt | 0:5f745af3ec9b | 405 | const char *p, *basename; |
ImranBilalButt | 0:5f745af3ec9b | 406 | (void) ctx; |
ImranBilalButt | 0:5f745af3ec9b | 407 | |
ImranBilalButt | 0:5f745af3ec9b | 408 | /* Extract basename from file */ |
ImranBilalButt | 0:5f745af3ec9b | 409 | for(p = basename = file; *p != '\0'; p++) { |
ImranBilalButt | 0:5f745af3ec9b | 410 | if(*p == '/' || *p == '\\') { |
ImranBilalButt | 0:5f745af3ec9b | 411 | basename = p + 1; |
ImranBilalButt | 0:5f745af3ec9b | 412 | } |
ImranBilalButt | 0:5f745af3ec9b | 413 | } |
ImranBilalButt | 0:5f745af3ec9b | 414 | |
ImranBilalButt | 0:5f745af3ec9b | 415 | tr_debug("%s:%04d: |%d| %s", basename, line, level, str); |
ImranBilalButt | 0:5f745af3ec9b | 416 | } |
ImranBilalButt | 0:5f745af3ec9b | 417 | |
ImranBilalButt | 0:5f745af3ec9b | 418 | int TLSSocketWrapper::my_verify(void *data, mbedtls_x509_crt *crt, int depth, uint32_t *flags) |
ImranBilalButt | 0:5f745af3ec9b | 419 | { |
ImranBilalButt | 0:5f745af3ec9b | 420 | const uint32_t buf_size = 1024; |
ImranBilalButt | 0:5f745af3ec9b | 421 | char *buf = new char[buf_size]; |
ImranBilalButt | 0:5f745af3ec9b | 422 | (void) data; |
ImranBilalButt | 0:5f745af3ec9b | 423 | |
ImranBilalButt | 0:5f745af3ec9b | 424 | tr_debug("\nVerifying certificate at depth %d:\n", depth); |
ImranBilalButt | 0:5f745af3ec9b | 425 | mbedtls_x509_crt_info(buf, buf_size - 1, " ", crt); |
ImranBilalButt | 0:5f745af3ec9b | 426 | tr_debug("%s", buf); |
ImranBilalButt | 0:5f745af3ec9b | 427 | |
ImranBilalButt | 0:5f745af3ec9b | 428 | if (*flags == 0) |
ImranBilalButt | 0:5f745af3ec9b | 429 | tr_info("No verification issue for this certificate\n"); |
ImranBilalButt | 0:5f745af3ec9b | 430 | else |
ImranBilalButt | 0:5f745af3ec9b | 431 | { |
ImranBilalButt | 0:5f745af3ec9b | 432 | mbedtls_x509_crt_verify_info(buf, buf_size, " ! ", *flags); |
ImranBilalButt | 0:5f745af3ec9b | 433 | tr_info("%s\n", buf); |
ImranBilalButt | 0:5f745af3ec9b | 434 | } |
ImranBilalButt | 0:5f745af3ec9b | 435 | |
ImranBilalButt | 0:5f745af3ec9b | 436 | delete[] buf; |
ImranBilalButt | 0:5f745af3ec9b | 437 | |
ImranBilalButt | 0:5f745af3ec9b | 438 | return 0; |
ImranBilalButt | 0:5f745af3ec9b | 439 | } |
ImranBilalButt | 0:5f745af3ec9b | 440 | #endif /* MBED_CONF_TLS_SOCKET_DEBUG_LEVEL > 0 */ |
ImranBilalButt | 0:5f745af3ec9b | 441 | |
ImranBilalButt | 0:5f745af3ec9b | 442 | |
ImranBilalButt | 0:5f745af3ec9b | 443 | int TLSSocketWrapper::ssl_recv(void *ctx, unsigned char *buf, size_t len) { |
ImranBilalButt | 0:5f745af3ec9b | 444 | int recv; |
ImranBilalButt | 0:5f745af3ec9b | 445 | |
ImranBilalButt | 0:5f745af3ec9b | 446 | TLSSocketWrapper *my = static_cast<TLSSocketWrapper *>(ctx); |
ImranBilalButt | 0:5f745af3ec9b | 447 | |
ImranBilalButt | 0:5f745af3ec9b | 448 | if (!my->_transport) { |
ImranBilalButt | 0:5f745af3ec9b | 449 | return NSAPI_ERROR_NO_SOCKET; |
ImranBilalButt | 0:5f745af3ec9b | 450 | } |
ImranBilalButt | 0:5f745af3ec9b | 451 | |
ImranBilalButt | 0:5f745af3ec9b | 452 | recv = my->_transport->recv(buf, len); |
ImranBilalButt | 0:5f745af3ec9b | 453 | |
ImranBilalButt | 0:5f745af3ec9b | 454 | if (NSAPI_ERROR_WOULD_BLOCK == recv) { |
ImranBilalButt | 0:5f745af3ec9b | 455 | return MBEDTLS_ERR_SSL_WANT_READ; |
ImranBilalButt | 0:5f745af3ec9b | 456 | } else if(recv < 0) { |
ImranBilalButt | 0:5f745af3ec9b | 457 | tr_error("Socket recv error %d", recv); |
ImranBilalButt | 0:5f745af3ec9b | 458 | } |
ImranBilalButt | 0:5f745af3ec9b | 459 | // Propagate also Socket errors to SSL, it allows negative error codes to be returned here. |
ImranBilalButt | 0:5f745af3ec9b | 460 | return recv; |
ImranBilalButt | 0:5f745af3ec9b | 461 | } |
ImranBilalButt | 0:5f745af3ec9b | 462 | |
ImranBilalButt | 0:5f745af3ec9b | 463 | int TLSSocketWrapper::ssl_send(void *ctx, const unsigned char *buf, size_t len) { |
ImranBilalButt | 0:5f745af3ec9b | 464 | int size = -1; |
ImranBilalButt | 0:5f745af3ec9b | 465 | TLSSocketWrapper *my = static_cast<TLSSocketWrapper *>(ctx); |
ImranBilalButt | 0:5f745af3ec9b | 466 | |
ImranBilalButt | 0:5f745af3ec9b | 467 | if (!my->_transport) { |
ImranBilalButt | 0:5f745af3ec9b | 468 | return NSAPI_ERROR_NO_SOCKET; |
ImranBilalButt | 0:5f745af3ec9b | 469 | } |
ImranBilalButt | 0:5f745af3ec9b | 470 | |
ImranBilalButt | 0:5f745af3ec9b | 471 | size = my->_transport->send(buf, len); |
ImranBilalButt | 0:5f745af3ec9b | 472 | |
ImranBilalButt | 0:5f745af3ec9b | 473 | if (NSAPI_ERROR_WOULD_BLOCK == size) { |
ImranBilalButt | 0:5f745af3ec9b | 474 | return MBEDTLS_ERR_SSL_WANT_WRITE; |
ImranBilalButt | 0:5f745af3ec9b | 475 | } else if(size < 0){ |
ImranBilalButt | 0:5f745af3ec9b | 476 | tr_error("Socket send error %d", size); |
ImranBilalButt | 0:5f745af3ec9b | 477 | } |
ImranBilalButt | 0:5f745af3ec9b | 478 | // Propagate also Socket errors to SSL, it allows negative error codes to be returned here. |
ImranBilalButt | 0:5f745af3ec9b | 479 | return size; |
ImranBilalButt | 0:5f745af3ec9b | 480 | } |
ImranBilalButt | 0:5f745af3ec9b | 481 | |
ImranBilalButt | 0:5f745af3ec9b | 482 | void TLSSocketWrapper::tls_init() { |
ImranBilalButt | 0:5f745af3ec9b | 483 | _entropy = new mbedtls_entropy_context; |
ImranBilalButt | 0:5f745af3ec9b | 484 | _ctr_drbg = new mbedtls_ctr_drbg_context; |
ImranBilalButt | 0:5f745af3ec9b | 485 | _cacert = new mbedtls_x509_crt; |
ImranBilalButt | 0:5f745af3ec9b | 486 | _clicert = new mbedtls_x509_crt; |
ImranBilalButt | 0:5f745af3ec9b | 487 | _pkctx = new mbedtls_pk_context; |
ImranBilalButt | 0:5f745af3ec9b | 488 | _ssl = new mbedtls_ssl_context; |
ImranBilalButt | 0:5f745af3ec9b | 489 | _ssl_conf = new mbedtls_ssl_config; |
ImranBilalButt | 0:5f745af3ec9b | 490 | _ssl_timer = new mbedtls_timing_delay_context; |
ImranBilalButt | 0:5f745af3ec9b | 491 | |
ImranBilalButt | 0:5f745af3ec9b | 492 | mbedtls_entropy_init(_entropy); |
ImranBilalButt | 0:5f745af3ec9b | 493 | mbedtls_ctr_drbg_init(_ctr_drbg); |
ImranBilalButt | 0:5f745af3ec9b | 494 | mbedtls_x509_crt_init(_cacert); |
ImranBilalButt | 0:5f745af3ec9b | 495 | mbedtls_x509_crt_init(_clicert); |
ImranBilalButt | 0:5f745af3ec9b | 496 | mbedtls_pk_init(_pkctx); |
ImranBilalButt | 0:5f745af3ec9b | 497 | mbedtls_ssl_init(_ssl); |
ImranBilalButt | 0:5f745af3ec9b | 498 | mbedtls_ssl_config_init(_ssl_conf); |
ImranBilalButt | 0:5f745af3ec9b | 499 | } |
ImranBilalButt | 0:5f745af3ec9b | 500 | |
ImranBilalButt | 0:5f745af3ec9b | 501 | void TLSSocketWrapper::tls_free() { |
ImranBilalButt | 0:5f745af3ec9b | 502 | mbedtls_entropy_free(_entropy); |
ImranBilalButt | 0:5f745af3ec9b | 503 | mbedtls_ctr_drbg_free(_ctr_drbg); |
ImranBilalButt | 0:5f745af3ec9b | 504 | mbedtls_x509_crt_free(_cacert); |
ImranBilalButt | 0:5f745af3ec9b | 505 | mbedtls_x509_crt_free(_clicert); |
ImranBilalButt | 0:5f745af3ec9b | 506 | mbedtls_pk_free(_pkctx); |
ImranBilalButt | 0:5f745af3ec9b | 507 | mbedtls_ssl_free(_ssl); |
ImranBilalButt | 0:5f745af3ec9b | 508 | mbedtls_ssl_config_free(_ssl_conf); |
ImranBilalButt | 0:5f745af3ec9b | 509 | |
ImranBilalButt | 0:5f745af3ec9b | 510 | delete _entropy; |
ImranBilalButt | 0:5f745af3ec9b | 511 | delete _ctr_drbg; |
ImranBilalButt | 0:5f745af3ec9b | 512 | delete _cacert; |
ImranBilalButt | 0:5f745af3ec9b | 513 | delete _clicert; |
ImranBilalButt | 0:5f745af3ec9b | 514 | delete _pkctx; |
ImranBilalButt | 0:5f745af3ec9b | 515 | delete _ssl; |
ImranBilalButt | 0:5f745af3ec9b | 516 | delete _ssl_conf; |
ImranBilalButt | 0:5f745af3ec9b | 517 | delete _ssl_timer; |
ImranBilalButt | 0:5f745af3ec9b | 518 | _ssl = NULL; // Marks that TLS context is freed |
ImranBilalButt | 0:5f745af3ec9b | 519 | } |
ImranBilalButt | 0:5f745af3ec9b | 520 | |
ImranBilalButt | 0:5f745af3ec9b | 521 | bool TLSSocketWrapper::is_tls_allocated() { |
ImranBilalButt | 0:5f745af3ec9b | 522 | return _ssl != NULL; |
ImranBilalButt | 0:5f745af3ec9b | 523 | } |
ImranBilalButt | 0:5f745af3ec9b | 524 | |
ImranBilalButt | 0:5f745af3ec9b | 525 | nsapi_error_t TLSSocketWrapper::close() |
ImranBilalButt | 0:5f745af3ec9b | 526 | { |
ImranBilalButt | 0:5f745af3ec9b | 527 | if (!_transport) { |
ImranBilalButt | 0:5f745af3ec9b | 528 | return NSAPI_ERROR_NO_SOCKET; |
ImranBilalButt | 0:5f745af3ec9b | 529 | } |
ImranBilalButt | 0:5f745af3ec9b | 530 | if (!is_tls_allocated()) { |
ImranBilalButt | 0:5f745af3ec9b | 531 | return NSAPI_ERROR_NO_SOCKET; |
ImranBilalButt | 0:5f745af3ec9b | 532 | } |
ImranBilalButt | 0:5f745af3ec9b | 533 | |
ImranBilalButt | 0:5f745af3ec9b | 534 | tr_info("Closing TLS"); |
ImranBilalButt | 0:5f745af3ec9b | 535 | |
ImranBilalButt | 0:5f745af3ec9b | 536 | int ret = 0; |
ImranBilalButt | 0:5f745af3ec9b | 537 | if (_handshake_completed) { |
ImranBilalButt | 0:5f745af3ec9b | 538 | _transport->set_blocking(true); |
ImranBilalButt | 0:5f745af3ec9b | 539 | ret = mbedtls_ssl_close_notify(_ssl); |
ImranBilalButt | 0:5f745af3ec9b | 540 | if (ret) { |
ImranBilalButt | 0:5f745af3ec9b | 541 | print_mbedtls_error("mbedtls_ssl_close_notify", ret); |
ImranBilalButt | 0:5f745af3ec9b | 542 | } |
ImranBilalButt | 0:5f745af3ec9b | 543 | _handshake_completed = false; |
ImranBilalButt | 0:5f745af3ec9b | 544 | } |
ImranBilalButt | 0:5f745af3ec9b | 545 | |
ImranBilalButt | 0:5f745af3ec9b | 546 | if (!_keep_transport_open) { |
ImranBilalButt | 0:5f745af3ec9b | 547 | int ret2 = _transport->close(); |
ImranBilalButt | 0:5f745af3ec9b | 548 | if (!ret) { |
ImranBilalButt | 0:5f745af3ec9b | 549 | ret = ret2; |
ImranBilalButt | 0:5f745af3ec9b | 550 | } |
ImranBilalButt | 0:5f745af3ec9b | 551 | } |
ImranBilalButt | 0:5f745af3ec9b | 552 | |
ImranBilalButt | 0:5f745af3ec9b | 553 | _transport = NULL; |
ImranBilalButt | 0:5f745af3ec9b | 554 | |
ImranBilalButt | 0:5f745af3ec9b | 555 | tls_free(); |
ImranBilalButt | 0:5f745af3ec9b | 556 | |
ImranBilalButt | 0:5f745af3ec9b | 557 | return ret; |
ImranBilalButt | 0:5f745af3ec9b | 558 | } |
ImranBilalButt | 0:5f745af3ec9b | 559 | |
ImranBilalButt | 0:5f745af3ec9b | 560 | nsapi_error_t TLSSocketWrapper::connect(const SocketAddress &address) |
ImranBilalButt | 0:5f745af3ec9b | 561 | { |
ImranBilalButt | 1:a6995e66c9f7 | 562 | pc.printf("Hello from TLSSocketWrapper::connect().\n"); |
ImranBilalButt | 0:5f745af3ec9b | 563 | if (!_transport) { |
ImranBilalButt | 1:a6995e66c9f7 | 564 | pc.printf("transport not available\n"); |
ImranBilalButt | 0:5f745af3ec9b | 565 | return NSAPI_ERROR_NO_SOCKET; |
ImranBilalButt | 0:5f745af3ec9b | 566 | } |
ImranBilalButt | 0:5f745af3ec9b | 567 | //TODO: We could initiate the hanshake here, if there would be separate function call to set the target hostname |
ImranBilalButt | 0:5f745af3ec9b | 568 | nsapi_error_t ret = _transport->connect(address); |
ImranBilalButt | 0:5f745af3ec9b | 569 | if (ret) { |
ImranBilalButt | 1:a6995e66c9f7 | 570 | pc.printf("transport->connect() failed, %d\n", ret); |
ImranBilalButt | 1:a6995e66c9f7 | 571 | pc.printf("error return from TLSSocketWrapper::connect %d\n", ret); |
ImranBilalButt | 0:5f745af3ec9b | 572 | return ret; |
ImranBilalButt | 0:5f745af3ec9b | 573 | } |
ImranBilalButt | 0:5f745af3ec9b | 574 | return do_handshake(); |
ImranBilalButt | 0:5f745af3ec9b | 575 | } |
ImranBilalButt | 0:5f745af3ec9b | 576 | |
ImranBilalButt | 0:5f745af3ec9b | 577 | nsapi_error_t TLSSocketWrapper::bind(const SocketAddress &address) |
ImranBilalButt | 0:5f745af3ec9b | 578 | { |
ImranBilalButt | 0:5f745af3ec9b | 579 | if (!_transport) { |
ImranBilalButt | 0:5f745af3ec9b | 580 | return NSAPI_ERROR_NO_SOCKET; |
ImranBilalButt | 0:5f745af3ec9b | 581 | } |
ImranBilalButt | 0:5f745af3ec9b | 582 | return _transport->bind(address); |
ImranBilalButt | 0:5f745af3ec9b | 583 | } |
ImranBilalButt | 0:5f745af3ec9b | 584 | |
ImranBilalButt | 0:5f745af3ec9b | 585 | void TLSSocketWrapper::set_blocking(bool blocking) |
ImranBilalButt | 0:5f745af3ec9b | 586 | { |
ImranBilalButt | 0:5f745af3ec9b | 587 | if (!_transport) { |
ImranBilalButt | 0:5f745af3ec9b | 588 | return; |
ImranBilalButt | 0:5f745af3ec9b | 589 | } |
ImranBilalButt | 0:5f745af3ec9b | 590 | _transport->set_blocking(blocking); |
ImranBilalButt | 0:5f745af3ec9b | 591 | } |
ImranBilalButt | 0:5f745af3ec9b | 592 | |
ImranBilalButt | 0:5f745af3ec9b | 593 | void TLSSocketWrapper::set_timeout(int timeout) |
ImranBilalButt | 0:5f745af3ec9b | 594 | { |
ImranBilalButt | 0:5f745af3ec9b | 595 | if (!_transport) { |
ImranBilalButt | 0:5f745af3ec9b | 596 | return; |
ImranBilalButt | 0:5f745af3ec9b | 597 | } |
ImranBilalButt | 0:5f745af3ec9b | 598 | _transport->set_timeout(timeout); |
ImranBilalButt | 0:5f745af3ec9b | 599 | } |
ImranBilalButt | 0:5f745af3ec9b | 600 | |
ImranBilalButt | 0:5f745af3ec9b | 601 | void TLSSocketWrapper::sigio(mbed::Callback<void()> func) |
ImranBilalButt | 0:5f745af3ec9b | 602 | { |
ImranBilalButt | 0:5f745af3ec9b | 603 | if (!_transport) { |
ImranBilalButt | 0:5f745af3ec9b | 604 | return; |
ImranBilalButt | 0:5f745af3ec9b | 605 | } |
ImranBilalButt | 0:5f745af3ec9b | 606 | // Allow sigio() to propagate to upper level and handle errors on recv() and send() |
ImranBilalButt | 0:5f745af3ec9b | 607 | _transport->sigio(func); |
ImranBilalButt | 0:5f745af3ec9b | 608 | } |
ImranBilalButt | 0:5f745af3ec9b | 609 | |
ImranBilalButt | 0:5f745af3ec9b | 610 | nsapi_error_t TLSSocketWrapper::setsockopt(int level, int optname, const void *optval, unsigned optlen) |
ImranBilalButt | 0:5f745af3ec9b | 611 | { |
ImranBilalButt | 0:5f745af3ec9b | 612 | if (!_transport) { |
ImranBilalButt | 0:5f745af3ec9b | 613 | return NSAPI_ERROR_NO_SOCKET; |
ImranBilalButt | 0:5f745af3ec9b | 614 | } |
ImranBilalButt | 0:5f745af3ec9b | 615 | return _transport->setsockopt(level, optname, optval, optlen); |
ImranBilalButt | 0:5f745af3ec9b | 616 | } |
ImranBilalButt | 0:5f745af3ec9b | 617 | |
ImranBilalButt | 0:5f745af3ec9b | 618 | nsapi_error_t TLSSocketWrapper::getsockopt(int level, int optname, void *optval, unsigned *optlen) |
ImranBilalButt | 0:5f745af3ec9b | 619 | { |
ImranBilalButt | 0:5f745af3ec9b | 620 | if (!_transport) { |
ImranBilalButt | 0:5f745af3ec9b | 621 | return NSAPI_ERROR_NO_SOCKET; |
ImranBilalButt | 0:5f745af3ec9b | 622 | } |
ImranBilalButt | 0:5f745af3ec9b | 623 | return _transport->getsockopt(level, optname, optval, optlen); |
ImranBilalButt | 0:5f745af3ec9b | 624 | } |
ImranBilalButt | 0:5f745af3ec9b | 625 | |
ImranBilalButt | 0:5f745af3ec9b | 626 | Socket *TLSSocketWrapper::accept(nsapi_error_t *err) |
ImranBilalButt | 0:5f745af3ec9b | 627 | { |
ImranBilalButt | 0:5f745af3ec9b | 628 | if (err) { |
ImranBilalButt | 0:5f745af3ec9b | 629 | *err = NSAPI_ERROR_UNSUPPORTED; |
ImranBilalButt | 0:5f745af3ec9b | 630 | } |
ImranBilalButt | 0:5f745af3ec9b | 631 | return NULL; |
ImranBilalButt | 0:5f745af3ec9b | 632 | } |
ImranBilalButt | 0:5f745af3ec9b | 633 | |
ImranBilalButt | 0:5f745af3ec9b | 634 | nsapi_error_t TLSSocketWrapper::listen(int) |
ImranBilalButt | 0:5f745af3ec9b | 635 | { |
ImranBilalButt | 0:5f745af3ec9b | 636 | return NSAPI_ERROR_UNSUPPORTED; |
ImranBilalButt | 0:5f745af3ec9b | 637 | } |